1 /* This is a small demo of the high-performance GUIX graphics framework. */
2 
3 #include <stdio.h>
4 #include <string.h>
5 #include "gx_api.h"
6 
7 /* Define constants for the GUIX Win32 demo.  */
8 
9 /* Define constants specific to this implemenation.  */
10 
11 #define DEMO_DISPLAY_WIDTH                         640
12 #define DEMO_DISPLAY_HEIGHT                        480
13 
14 /* User-defined color ID */
15 #define GX_1BPP_BLACK    0x00
16 #define GX_1BPP_WHITE    0x01
17 
18 
19 /* User-defined color table. */
20 static GX_COLOR demo_color_table[] =
21 {
22     GX_1BPP_BLACK,
23     GX_1BPP_WHITE,
24 };
25 
26 extern GX_FONT _gx_system_font_mono;
27 GX_FONT *demo_font_table[] =
28 {
29     &_gx_system_font_mono,
30     &_gx_system_font_mono,
31     &_gx_system_font_mono,
32     &_gx_system_font_mono
33 };
34 
35 extern GX_PIXELMAP PRIMARY_CHECKBOX_ON_pixelmap;
36 extern GX_PIXELMAP PRIMARY_CHECKBOX_OFF_pixelmap;
37 
38 GX_PIXELMAP *demo_pixelmap_table[] = {
39     NULL,
40     NULL,
41     NULL,
42     &PRIMARY_CHECKBOX_ON_pixelmap,
43     &PRIMARY_CHECKBOX_OFF_pixelmap,
44 };
45 
46 #define PRIMARY_PIXELMAP_TABLE_SIZE GX_DEFAULT_PIXELMAP_COUNT
47 
48 #define DEFAULT_CANVAS_PIXELS     (DEMO_DISPLAY_WIDTH * DEMO_DISPLAY_HEIGHT)
49 
50 /* Define the ThreadX demo thread control block and stack.  */
51 
52 TX_THREAD          demo_thread;
53 
54 /* Define the stack for the demo thread. */
55 ULONG              demo_thread_stack[4096 / sizeof(ULONG)];
56 
57 /* Define the GUIX resources for this demo.  */
58 GX_CANVAS         default_canvas;
59 
60 GX_DISPLAY        demo_display;
61 GX_WINDOW_ROOT    demo_root_window;
62 
63 
64 
65 GX_WINDOW   line_window;
66 INT         line_x1;
67 INT         line_y1;
68 INT         line_x2;
69 INT         line_y2;
70 INT         line_width;
71 INT         line_pattern;
72 GX_COLOR    line_color;
73 INT         line_angle;
74 GX_BOOL     is_round;
75 GX_PROMPT   width_label;
76 GX_PROMPT   angle_label;
77 GX_PROMPT   width_prompt;
78 GX_PROMPT   angle_prompt;
79 GX_SLIDER   width_slider;
80 GX_SLIDER   angle_slider;
81 GX_CHECKBOX round_box;
82 GX_CHECKBOX pattern_box;
83 
84 #define LINE_WINDOW_COLOR 0x000000
85 #define LINE_WINDOW_LINE_LENGTH 80
86 #define LINE_CENTER_X_OFFSET 180
87 #define LINE_CENTER_Y_OFFSET 180
88 
89 /* Define GUIX canvas for this demo.  */
90 
91 ULONG default_canvas_memory[DEFAULT_CANVAS_PIXELS/sizeof(ULONG)];
92 
93 /* Define GUIX strings and string IDs for this demo.  */
94 
95 enum demo_string_ids
96 {
97     SID_WIDTH = 1,
98     SID_ANGLE,
99     SID_ROUND,
100     SID_PATTERN,
101     STRING_TABLE_MAX
102 };
103 
104 GX_CONST GX_CHAR string_Line_Width[] = "Line Width";
105 GX_CONST GX_CHAR string_Line_Angle[] = "Line Angle";
106 GX_CONST GX_CHAR string_Round_End[] = "Round End";
107 GX_CONST GX_CHAR string_Pattern_line[] = "Pattern line";
108 
109 GX_CONST GX_STRING demo_strings[] = {
110     {NULL ,0},
111     {string_Line_Width, sizeof(string_Line_Width) - 1},
112     {string_Line_Angle, sizeof(string_Line_Angle) - 1},
113     {string_Round_End, sizeof(string_Round_End) - 1},
114     {string_Pattern_line, sizeof(string_Pattern_line) - 1},
115 };
116 
117 GX_CONST GX_STRING *language_table[1] =
118 {
119     demo_strings
120 };
121 
122 /* widget id values used by this demo */
123 enum demo_widget_ids {
124     ID_WIDTH_SLIDER = 1,
125     ID_ANGLE_SLIDER,
126     BID_ROUND,
127     BID_PATTERN
128 };
129 
130 /* Define prototypes.   */
131 
132 VOID  demo_thread_entry(ULONG thread_input);
133 
134 UINT  line_win_event_handler(GX_WIDGET *me, GX_EVENT *myevent);
135 VOID  line_win_draw(GX_WIDGET *me);
136 VOID  calculate_line_ends();
137 extern UINT win32_graphics_driver_setup_monochrome(GX_DISPLAY *display);
138 
main(int argc,char ** argv)139 int main(int argc, char ** argv)
140 {
141     tx_kernel_enter();
142     return(0);
143 }
144 
tx_application_define(void * first_unused_memory)145 VOID tx_application_define(void *first_unused_memory)
146 {
147 
148     /* Create the main demo thread.  */
149     tx_thread_create(&demo_thread, "GUIX Demo Thread", demo_thread_entry, 0,
150                      demo_thread_stack, sizeof(demo_thread_stack),
151                      1, 1, TX_NO_TIME_SLICE, TX_AUTO_START);
152 }
153 
demo_thread_entry(ULONG thread_input)154 VOID  demo_thread_entry(ULONG thread_input)
155 {
156 
157 GX_RECTANGLE    size;
158 GX_SLIDER_INFO  info;
159 GX_STRING       str;
160 
161     /* Initialize GUIX.  */
162     gx_system_initialize();
163 
164     /* Create the demo display and associated driver.  */
165     gx_display_create(&demo_display, "demo display", win32_graphics_driver_setup_monochrome,
166                       DEMO_DISPLAY_WIDTH, DEMO_DISPLAY_HEIGHT);
167 
168     /* Install the demo string table.  */
169     gx_display_language_table_set_ext(&demo_display, language_table, 1, STRING_TABLE_MAX);
170     gx_system_active_language_set(0);
171 
172     gx_display_color_table_set(&demo_display, demo_color_table, sizeof(demo_color_table) / sizeof(GX_COLOR));
173 
174     gx_display_font_table_set(&demo_display, demo_font_table, sizeof(demo_font_table) / sizeof(GX_FONT *));
175 
176     /* Set pixelmap table.  */
177     gx_display_pixelmap_table_set(&demo_display, demo_pixelmap_table, PRIMARY_PIXELMAP_TABLE_SIZE);
178 
179     /* Create the default canvas, painted on by the graphics driver.  */
180     gx_canvas_create(&default_canvas, "demo canvas", &demo_display,
181                      GX_CANVAS_MANAGED | GX_CANVAS_VISIBLE,
182                      DEMO_DISPLAY_WIDTH, DEMO_DISPLAY_HEIGHT,
183                      default_canvas_memory, sizeof(default_canvas_memory));
184 
185     /* Create a background root window and attach to the background canvas.  */
186 
187     gx_utility_rectangle_define(&size, 0, 0, DEMO_DISPLAY_WIDTH - 1, DEMO_DISPLAY_HEIGHT - 1);
188     gx_window_root_create(&demo_root_window, "demo root window", &default_canvas,
189                           GX_STYLE_BORDER_NONE, GX_ID_NONE, &size);
190     gx_widget_fill_color_set(&demo_root_window, GX_1BPP_WHITE, GX_1BPP_WHITE, GX_1BPP_WHITE);
191 
192     /* create the main window on which we will draw the lines: */
193     gx_utility_rectangle_define(&size, 20, 20, 400, 460);
194     gx_window_create(&line_window, NULL, &demo_root_window, GX_STYLE_BORDER_THICK, GX_ID_NONE, &size);
195     is_round = GX_FALSE;
196     line_angle = 0;
197     line_width = 1;
198     line_color = GX_1BPP_BLACK;
199     line_window.gx_widget_normal_fill_color = GX_1BPP_WHITE;
200     line_window.gx_widget_selected_fill_color = GX_1BPP_WHITE;
201     line_window.gx_widget_disabled_fill_color = GX_1BPP_WHITE;
202     calculate_line_ends();
203 
204     gx_widget_draw_set(&line_window, line_win_draw);
205     gx_widget_event_process_set(&demo_root_window, line_win_event_handler);
206 
207     /* add width adjustment children */
208     gx_utility_rectangle_define(&size, 460, 40, 560, 60);
209     memset(&info, 0, sizeof(GX_SLIDER_INFO));
210 
211     info.gx_slider_info_current_val = 1;
212     info.gx_slider_info_min_val = 1;
213     info.gx_slider_info_max_val = 10;
214     info.gx_slider_info_increment = 1;
215     info.gx_slider_info_needle_inset = 4;
216     info.gx_slider_info_needle_height = 12;
217     info.gx_slider_info_min_travel = 10;
218     info.gx_slider_info_max_travel = 10;
219 
220     gx_slider_create(&width_slider, NULL, &demo_root_window,
221                      10, &info, GX_STYLE_ENABLED|GX_STYLE_SHOW_TICKMARKS|GX_STYLE_SHOW_NEEDLE|GX_STYLE_BORDER_RAISED,
222                      ID_WIDTH_SLIDER, &size);
223     width_slider.gx_widget_normal_fill_color = GX_1BPP_WHITE;
224     width_slider.gx_widget_selected_fill_color = GX_1BPP_WHITE;
225     width_slider.gx_slider_tick_color = GX_1BPP_BLACK;
226 
227     gx_utility_rectangle_define(&size, 580, 40, 620, 60);
228     gx_prompt_create(&width_prompt, NULL, &demo_root_window, 0,
229         GX_STYLE_BORDER_THIN, GX_ID_NONE, &size);
230     width_prompt.gx_widget_status = GX_STATUS_VISIBLE;
231     str.gx_string_ptr = "1";
232     str.gx_string_length = 1;
233     gx_prompt_text_set_ext(&width_prompt, &str);
234     gx_prompt_text_color_set(&width_prompt, GX_1BPP_BLACK, GX_1BPP_BLACK, GX_1BPP_BLACK);
235     gx_widget_fill_color_set(&width_prompt, GX_1BPP_WHITE, GX_1BPP_WHITE, GX_1BPP_WHITE);
236 
237     /* add angle adjustment children */
238     gx_utility_rectangle_define(&size, 460, 80, 560, 100);
239     memset(&info, 0, sizeof(GX_SLIDER_INFO));
240 
241     info.gx_slider_info_current_val = 0;
242     info.gx_slider_info_min_val = -360;
243     info.gx_slider_info_max_val = 360;
244     info.gx_slider_info_increment = 1;
245     info.gx_slider_info_needle_inset = 4;
246     info.gx_slider_info_needle_height = 12;
247     info.gx_slider_info_min_travel = 10;
248     info.gx_slider_info_max_travel = 10;
249 
250     gx_slider_create(&angle_slider, NULL, &demo_root_window,
251                      10, &info, GX_STYLE_ENABLED|GX_STYLE_SHOW_TICKMARKS|GX_STYLE_SHOW_NEEDLE|GX_STYLE_BORDER_RAISED,
252                      ID_ANGLE_SLIDER, &size);
253     angle_slider.gx_widget_normal_fill_color = GX_1BPP_WHITE;
254     angle_slider.gx_widget_selected_fill_color = GX_1BPP_WHITE;
255     angle_slider.gx_slider_tick_color = GX_1BPP_BLACK;
256 
257     gx_utility_rectangle_define(&size, 580, 80, 620, 100);
258     gx_prompt_create(&angle_prompt, NULL, &demo_root_window, 0,
259                      GX_STYLE_BORDER_THIN, GX_ID_NONE, &size);
260     str.gx_string_ptr = "0";
261     str.gx_string_length = 1;
262     gx_prompt_text_set_ext(&angle_prompt, &str);
263     gx_prompt_text_color_set(&angle_prompt, GX_1BPP_BLACK, GX_1BPP_BLACK, GX_1BPP_BLACK);
264     gx_widget_fill_color_set(&angle_prompt, GX_1BPP_WHITE, GX_1BPP_WHITE, GX_1BPP_WHITE);
265 
266     /* add round-end checkbox */
267     gx_utility_rectangle_define(&size, 460, 160, 600, 180);
268     gx_checkbox_create(&round_box, "round_box", &demo_root_window, SID_ROUND,
269                        GX_STYLE_TRANSPARENT|GX_STYLE_TEXT_LEFT| GX_STYLE_ENABLED, BID_ROUND, &size);
270     gx_checkbox_pixelmap_set(&round_box, GX_PIXELMAP_ID_CHECKBOX_OFF, GX_PIXELMAP_ID_CHECKBOX_ON, GX_PIXELMAP_ID_CHECKBOX_OFF, GX_PIXELMAP_ID_CHECKBOX_ON);
271 
272 
273     /* add round-end checkbox */
274     gx_utility_rectangle_define(&size, 460, 200, 600, 220);
275     gx_checkbox_create(&pattern_box, "pattern_box", &demo_root_window, SID_PATTERN,
276         GX_STYLE_TRANSPARENT | GX_STYLE_TEXT_LEFT | GX_STYLE_ENABLED, BID_PATTERN, &size);
277     gx_checkbox_pixelmap_set(&pattern_box, GX_PIXELMAP_ID_CHECKBOX_OFF, GX_PIXELMAP_ID_CHECKBOX_ON, GX_PIXELMAP_ID_CHECKBOX_OFF, GX_PIXELMAP_ID_CHECKBOX_ON);
278 
279 
280     /* Add a slider for line width */
281     /* Show the root window.  */
282     gx_widget_show(&demo_root_window);
283 
284 
285 #if defined(GUIX_VALIDATION)
286     /* do_validation(); */
287 #endif
288 
289     /* let GUIX run */
290     gx_system_start();
291 }
292 
calculate_line_ends(VOID)293 VOID calculate_line_ends(VOID)
294 {
295     INT scaled_angle;
296     INT x_dist;
297     INT y_dist;
298 
299     INT x_center = line_window.gx_widget_size.gx_rectangle_left + LINE_CENTER_X_OFFSET;
300     INT y_center = line_window.gx_widget_size.gx_rectangle_top + LINE_CENTER_Y_OFFSET;
301 
302     scaled_angle = GX_FIXED_VAL_MAKE(line_angle);
303     x_dist = GX_FIXED_VAL_TO_INT(gx_utility_math_cos(scaled_angle) * LINE_WINDOW_LINE_LENGTH);
304     y_dist = GX_FIXED_VAL_TO_INT(gx_utility_math_sin(scaled_angle) * LINE_WINDOW_LINE_LENGTH);
305 
306     line_x1 = x_center - x_dist;
307     line_x2 = x_center + x_dist;
308     line_y1 = y_center - y_dist;
309     line_y2 = y_center + y_dist;
310 }
311 
update_width_prompt(VOID)312 VOID update_width_prompt(VOID)
313 {
314     static CHAR width_val[10];
315     GX_STRING str;
316 
317     gx_utility_ltoa(line_width, width_val, 10);
318     str.gx_string_ptr = width_val;
319     str.gx_string_length = strnlen(width_val, sizeof(width_val));
320     gx_prompt_text_set_ext(&width_prompt, &str);
321 }
322 
update_angle_prompt(VOID)323 VOID update_angle_prompt(VOID)
324 {
325     static CHAR angle_val[10];
326     GX_STRING str;
327 
328     gx_utility_ltoa(line_angle, angle_val, 10);
329     str.gx_string_ptr = angle_val;
330     str.gx_string_length = strnlen(angle_val, sizeof(angle_val));
331     gx_prompt_text_set_ext(&angle_prompt, &str);
332 }
333 
line_win_event_handler(GX_WIDGET * widget,GX_EVENT * myevent)334 UINT line_win_event_handler(GX_WIDGET *widget, GX_EVENT *myevent)
335 {
336 UINT status = 0;
337 GX_WINDOW *window = (GX_WINDOW*)widget;
338 
339     switch(myevent -> gx_event_type)
340     {
341     case GX_SIGNAL(ID_WIDTH_SLIDER, GX_EVENT_SLIDER_VALUE):
342         line_width = myevent ->gx_event_payload.gx_event_longdata;
343         update_width_prompt();
344 
345         /* kgm FIXME- should really just mark the line area as dirty */
346         gx_system_dirty_mark(widget);
347         break;
348 
349     case GX_SIGNAL(ID_ANGLE_SLIDER, GX_EVENT_SLIDER_VALUE):
350         line_angle = myevent ->gx_event_payload.gx_event_longdata;
351         update_angle_prompt();
352         calculate_line_ends();
353         /* kgm FIXME- should really just mark the line area as dirty */
354         gx_system_dirty_mark(widget);
355         break;
356 
357     case GX_SIGNAL(BID_ROUND, GX_EVENT_TOGGLE_ON):
358         is_round = GX_TRUE;
359         gx_system_dirty_mark(widget);
360         break;
361 
362     case GX_SIGNAL(BID_ROUND, GX_EVENT_TOGGLE_OFF):
363         is_round = GX_FALSE;
364         gx_system_dirty_mark(widget);
365         break;
366 
367     case GX_SIGNAL(BID_PATTERN, GX_EVENT_TOGGLE_ON):
368         line_pattern = 0x0f0f0f0f;
369         gx_system_dirty_mark(widget);
370         break;
371 
372     case GX_SIGNAL(BID_PATTERN, GX_EVENT_TOGGLE_OFF):
373         line_pattern = 0;
374         gx_system_dirty_mark(widget);
375         break;
376 
377     default:
378         status = gx_window_event_process(window, myevent);
379         break;
380     }
381     return status;
382 }
383 
384 
385 
line_win_draw(GX_WIDGET * widget)386 VOID line_win_draw(GX_WIDGET *widget)
387 {
388 ULONG brush_style = 0;
389 GX_BRUSH *brush = GX_NULL;
390 
391     gx_window_draw((GX_WINDOW*)widget);
392 
393     if (is_round)
394     {
395         brush_style |= GX_BRUSH_ROUND;
396     }
397 
398     gx_context_brush_width_set(line_width);
399     gx_context_raw_brush_define(0x0, 0xffffff, brush_style);
400 
401     gx_context_brush_get(&brush);
402 
403     if (brush)
404     {
405         brush -> gx_brush_line_pattern = line_pattern;
406         gx_context_brush_set(brush);
407 
408         /* calculate the line end points */
409         gx_canvas_line_draw(line_x1, line_y1, line_x2, line_y2);
410     }
411 
412 }
413 
414