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