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