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