1 /*
2
3 Copyright (C) 2015-2018 Night Dive Studios, LLC.
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 */
19 /*
20 * $Source: r:/prj/lib/src/ui/RCS/gadgets.c $
21 * $Revision: 1.44 $
22 * $Author: kaboom $
23 * $Date: 1994/08/10 18:43:13 $
24 */
25
26 // Source code to implement all these goofy gadgets
27 // using the region system.
28
29 #include <string.h>
30 #include <stdio.h>
31
32 #include "lg.h"
33 #include "gadgets.h"
34 #include "event.h"
35 #include "mouse.h"
36 #include "2d.h"
37 #include "dbg.h"
38 //#include <_ui.h>
39 #include "rect.h"
40 #include "error.h"
41 #include "kbcook.h"
42 #include "2dres.h"
43 //#include <lgsprntf.h>
44
45
46 //---------------------------------------------------------------
47 // Defines and Globals
48 //---------------------------------------------------------------
49 #define NUM_RESOURCE_FILES 1
50
51 uchar gadget_initialization = FALSE;
52 uchar initialize_2d = FALSE;
53
54
55 //---------------------------------------------------------------
56 // Internal Prototypes
57 //---------------------------------------------------------------
58 errtype draw_resource_bm(Ref id, int x, int y);
59 errtype gad_Mac_init(Gadget *g, LGPoint extent);
60 uchar gad_Mac_blank_expose(LGRegion *reg, LGRect *r);
61 errtype gadget_initialize_system(void);
62 uchar gadget_frob_canvas(LGRegion *reg, void *data);
63 uchar gadget_tng_mouse_move_handler(uiEvent *e, LGRegion *r, intptr_t state);
64
65
66 //---------------------------------------------------------------
67 // Device-Specific Stuff
68 //---------------------------------------------------------------
69 // For Mac version: Set up graphics for Mac screen.
70
71 /*
72 errtype gad_vga_init(Gadget *g, LGPoint extent)
73 {
74 // grs_screen *screen;
75
76 // Spew(DSRC_UI_Gadget, ("GAD_VGA_INIT!! %s, (%d, %d)\n",GD_NAME(g->rep), extent.x, extent.y));
77 if (!initialize_2d)
78 {
79 #ifdef WOW_WHAT_A_TOTAL_HACK
80 gr_init();
81 gr_set_mode(GRM_320X200X8, TRUE);
82 screen = gr_alloc_screen(extent.x,extent.y);
83 gr_set_screen(screen);
84 #endif
85 initialize_2d = TRUE;
86 }
87 g->device_data = (grs_canvas *)Malloc(sizeof(grs_canvas));
88 gr_init_sub_canvas(dr_scr_canv, g->device_data, 0, 0, extent.x, extent.y);
89 return (OK);
90 }
91
92 errtype gad_modex_init(Gadget *g, LGPoint extent)
93 {
94 grs_screen *screen;
95
96 // Spew(DSRC_UI_Gadget, ("GAD_MODEX_INIT!! %s, (%d, %d)\n",GD_NAME(g->rep), extent.x, extent.y));
97 if (!initialize_2d)
98 {
99 gr_init();
100 gr_set_mode(GRM_320X200X8, TRUE);
101 screen = gr_alloc_screen(extent.x,extent.y);
102 gr_set_screen(screen);
103 initialize_2d = TRUE;
104 }
105
106 g->device_data = (grs_canvas *)Malloc(sizeof(grs_canvas));
107 gr_init_sub_canvas(dr_scr_canv, g->device_data, 0, 0, extent.x, extent.y);
108 return (OK);
109 }
110
111 errtype gad_svga_init(Gadget *g, LGPoint extent)
112 {
113 grs_screen *screen;
114
115 // Spew(DSRC_UI_Gadget, ("GAD_VGA_INIT!! %s, (%d, %d)\n",GD_NAME(g->rep), extent.x, extent.y));
116 if (!initialize_2d)
117 {
118 gr_init();
119 gr_set_mode(GRM_320X200X8, TRUE);
120 screen = gr_alloc_screen(extent.x,extent.y);
121 gr_set_screen(screen);
122 initialize_2d = TRUE;
123 }
124
125 g->device_data = (grs_canvas *)Malloc(sizeof(grs_canvas));
126 gr_init_sub_canvas(dr_scr_canv, g->device_data, 0, 0, extent.x, extent.y);
127 return (OK);
128 }
129
130 errtype gad_mono_init(Gadget *g, LGPoint extent)
131 {
132 Gadget *dummy;
133 LGPoint dummy2;
134 dummy = g; dummy2 = extent;
135
136 return (OK);
137 }
138 */
139
gad_Mac_init(Gadget * g,LGPoint extent)140 errtype gad_Mac_init(Gadget *g, LGPoint extent)
141 {
142 grs_screen *screen;
143
144 if (!initialize_2d)
145 {
146 gr_init();
147 gr_set_mode(GRM_640x480x8, TRUE);
148 screen = gr_alloc_screen(extent.x,extent.y);
149 gr_set_screen(screen);
150 initialize_2d = TRUE;
151 }
152
153 g->device_data = (grs_canvas *)malloc(sizeof(grs_canvas));
154 gr_init_sub_canvas(dr_scr_canv, (grs_canvas *)g->device_data, 0, 0, extent.x, extent.y);
155 return (OK);
156 }
157
158 /*
159 uchar gad_vga_blank_expose(LGRegion *reg, LGRect *r)
160 {
161 LGRect nrect;
162
163 region_abs_rect(reg, r, &nrect);
164 SCALE_RECT(&nrect, GD_GADG(reg)->conversion);
165 // Spew(DSRC_UI_Gadget, ("GAD_VGA_BLANK_EXPOSE!! %s, (%d, %d)(%d, %d)\n",GD_NAME(reg), RECT_EXPAND_ARGS(&nrect)));
166 if (GD_CANV(reg) == NULL)
167 // Spew(DSRC_UI_Gadget, ("Perhaps we have a problem here...\n"));
168 gr_set_canvas(GD_CANV(reg));
169 gr_set_fcolor(0x00);
170 gr_rect(RECT_EXPAND_ARGS(&nrect));
171 // Spew(DSRC_UI_Gadget, ("after the 2d part of that...\n"));
172 return(0);
173 }
174
175 uchar gad_mono_blank_expose(LGRegion *reg, LGRect *r)
176 {
177 LGRegion *dummy;
178 LGRect *dummy2;
179 dummy = reg; dummy2 = r;
180
181 return (0);
182 }
183 */
184
gad_Mac_blank_expose(LGRegion * reg,LGRect * r)185 uchar gad_Mac_blank_expose(LGRegion *reg, LGRect *r)
186 {
187 LGRect nrect;
188
189 region_abs_rect(reg, r, &nrect);
190 SCALE_RECT(&nrect, GD_GADG(reg)->conversion);
191 gr_set_canvas((grs_canvas *)GD_CANV(reg));
192 gr_set_fcolor(0x00);
193 gr_rect(RECT_EXPAND_ARGS(&nrect));
194 return(0);
195 }
196
197
draw_resource_bm(Ref id,int x,int y)198 errtype draw_resource_bm(Ref id, int x, int y)
199 {
200 FrameDesc *f;
201 int a1,a2,a3,a4;
202 short *ppall;
203
204 STORE_CLIP(a1,a2,a3,a4);
205 // Spew(DSRC_UI_Utilities, ("cliprect = (%d, %d)(%d, %d)\n",a1,a2,a3,a4));
206 // Spew(DSRC_UI_Utilities, ("drawing bitmap to (%d, %d)\n",x,y));
207 f = FrameLock(id);
208
209 // Set the palette right
210 /*¥¥¥ Ignore for now
211 if (f->pallOff)
212 {
213 ppall = (short *) (((uchar *) RefGet(id)) + f->pallOff);
214 // Spew(DSRC_UI_Utilities, ("ppall = %d *ppall + 1 = %d\n",*ppall, *(ppall + 1)));
215 gr_set_pal(*ppall,*(ppall + 1),(uchar *)(ppall + 2));
216 }
217 */
218 f->bm.bits = (uchar *)(f+1);
219 gr_bitmap(&f->bm, x, y);
220 RefUnlock(id);
221 return (OK);
222 }
223
resource_bm_width(Ref id)224 int resource_bm_width(Ref id)
225 {
226 FrameDesc *f;
227 int n;
228
229 f = FrameLock(id);
230 n = f->bm.w;
231 // Spew(DSRC_UI_Utilities, ("resource_bm_width = %d\n",n));
232 RefUnlock(id);
233 return (n);
234 }
235
resource_bm_height(Ref id)236 int resource_bm_height(Ref id)
237 {
238 FrameDesc *f;
239 int n;
240
241 f = FrameLock(id);
242 n = f->bm.h;
243 // Spew(DSRC_UI_Utilities, ("resource_bm_height = %d\n",n));
244 RefUnlock(id);
245 return (n);
246 }
247
248 // Initialize the overall gadget system. Should be called once, when the first gadget_init is
249 // triggered
gadget_initialize_system(void)250 errtype gadget_initialize_system(void)
251 {
252 #ifdef INIT_RESOURCES_HERE
253 ResInit();
254 ResAddPath(RESPATH);
255 for (i = 0; i < NUM_RESOURCE_FILES; i++)
256 ResOpenFile(resource_files[i]);
257 #endif
258 return(OK);
259 }
260
261 // Initialize a gadget system for a particular display type. Returns the gadget that is the "root" gadget
262 // for that display.
gadget_init(int display_type,LGPoint extent)263 Gadget *gadget_init(int display_type, LGPoint extent)
264 {
265 Gadget *retgad;
266 GadgetData *gd;
267 RectCallback fn;
268 LGRect r;
269
270 // if ((extent.x <= 0) || (extent.y <= 0))
271 // Spew(DSRC_UI_Bounds, ("Nonpositive extent in gadget_init!\n"));
272 if (!gadget_initialization)
273 {
274 gadget_initialization = TRUE;
275 gadget_initialize_system();
276 }
277
278 // Make a rectangle out of the extent
279 r.ul.x = 0; r.ul.y = 0;
280 r.lr = extent;
281
282 // Make the basic gadget
283 retgad = (Gadget *)malloc(sizeof(Gadget));
284 retgad->gclass = CLASS_ROOT;
285 retgad->tng_data = NULL;
286 retgad->draw_parts = TNG_ALLPARTS;
287 retgad->handler_id = -1;
288 retgad->destroy_func = NULL;
289 retgad->conversion.x = extent.x / BASELINE_X;
290 retgad->conversion.y = extent.y / BASELINE_Y;
291
292 // Fill out the user data structure
293 gd = (GadgetData *)malloc(sizeof(GadgetData));
294 gd->g = retgad;
295 gd->name = (char *)malloc(8 * sizeof(char));
296 // lg_sprintf(gd->name, "root%d\0", display_type);
297 sprintf(gd->name, "root%d", display_type);
298
299 // Set the right kind o' callback
300 switch (display_type)
301 {
302 /* case DISPLAY_VGA:
303 case DISPLAY_SVGA:
304 case DISPLAY_MODEX:
305 fn = &gad_vga_blank_expose;
306 break;
307 case DISPLAY_MONO:
308 fn = &gad_mono_blank_expose;
309 break; */
310 case DISPLAY_MAC:
311 fn = &gad_Mac_blank_expose;
312 break;
313 }
314
315 // Create that durned rep
316
317 retgad->rep = (LGRegion *)malloc(sizeof(LGRegion));
318 region_create(NULL, retgad->rep, &r, 0, 0, REG_AUTOMATIC, NULL, NULL, NULL, gd);
319 retgad->rep->expose = fn;
320 retgad->rep->device_type = display_type;
321
322 switch (display_type)
323 {
324 /* case DISPLAY_VGA:
325 gad_vga_init(retgad, extent);
326 break;
327 case DISPLAY_MODEX:
328 gad_modex_init(retgad, extent);
329 break;
330 case DISPLAY_SVGA:
331 gad_svga_init(retgad, extent);
332 break;
333 case DISPLAY_MONO:
334 gad_mono_init(retgad, extent);
335 break; */
336 case DISPLAY_MAC:
337 gad_Mac_init(retgad, extent);
338 break;
339 }
340
341 return(retgad);
342 }
343
344 // Forces a gadget to display itself
gadget_display(Gadget * g,LGRect * r)345 errtype gadget_display(Gadget *g, LGRect *r)
346 {
347 return(gadget_display_part(g,r,TNG_ALLPARTS));
348 }
349
gadget_display_part(Gadget * g,LGRect * r,ushort partmask)350 errtype gadget_display_part(Gadget *g, LGRect *r, ushort partmask)
351 {
352 g->draw_parts = partmask;
353 if (r == NULL)
354 region_expose(g->rep, g->rep->r);
355 else
356 region_expose(g->rep, r);
357 return(OK);
358 }
359
gadget_shutdown()360 errtype gadget_shutdown()
361 {
362 gr_close();
363 return(OK);
364 }
365
366
367 // Destroys the gadget and any children gadgets
368 uchar in_destroy = FALSE;
gadget_destroy(Gadget ** pvic)369 errtype gadget_destroy(Gadget **pvic)
370 {
371 LGRegion *curp, *nextp;
372 Gadget *victim;
373 uchar inner_destroy;
374
375 victim = *pvic;
376
377 inner_destroy = in_destroy;
378 if (!inner_destroy)
379 in_destroy = TRUE;
380 /*
381 if (victim->rep != NULL)
382 {
383 Spew(DSRC_UI_Gadget, ("Destroying %s!\n",GD_NAME(victim->rep)));
384 if (victim->rep->user_data == NULL)
385 Warning(("Attempting to destroy gadget with no user_data!\n"));
386 }
387 else
388 Spew(DSRC_UI_Gadget, ("rep is NULL!\n"));
389 */
390 if (victim == NULL)
391 {
392 // Spew(DSRC_UI_Bounds, ("Attempted to destroy null gadget!\n"));
393 return(ERR_NULL);
394 }
395
396 if (victim->rep != NULL)
397 {
398 curp = victim->rep->sub_region;
399 while (curp != NULL)
400 {
401 nextp = curp->next_region;
402
403 // Is this thing a gadget, or a region hung off of us?
404 if (curp->user_data != NULL)
405 gadget_destroy(&(GD_GADG(curp)));
406 else
407 region_destroy(curp, FALSE);
408 curp = nextp;
409 }
410 region_destroy(victim->rep, !inner_destroy);
411 }
412
413 if (victim->destroy_func != NULL)
414 victim->destroy_func(victim, NULL);
415 free(*pvic);
416 *pvic = NULL;
417
418 if (!inner_destroy)
419 {
420 in_destroy = FALSE;
421 }
422 return (OK);
423 }
424
425 // Moves the gadget to a new x, y, z coordinate (relative)
gadget_frob_canvas(LGRegion * reg,void * data)426 uchar gadget_frob_canvas(LGRegion *reg, void *data)
427 {
428 LGPoint delta;
429 Gadget *g;
430 // Spew(DSRC_UI_Gadget, ("Tippie-top of frob!\n"));
431 delta = *((LGPoint *)(data));
432 g = GD_GADG(reg);
433 // Spew(DSRC_UI_Gadget, ("Frobbing canvas on %s: Delta = (%d,%d)\n",GD_NAME(g->rep),delta.x,delta.y));
434 gr_init_sub_canvas((grs_canvas *)g->parent->device_data, (grs_canvas *)g->device_data,
435 g->rep->r->ul.x + delta.x, g->rep->r->ul.y + delta.y,
436 RectWidth(g->rep->r), RectHeight(g->rep->r));
437 ((LGPoint *)(data))->x = 0;
438 ((LGPoint *)(data))->y = 0;
439 return(FALSE);
440 }
441
gadget_move(Gadget * g,LGPoint coord,int z)442 errtype gadget_move(Gadget *g, LGPoint coord, int z)
443 {
444 LGPoint delta;
445
446 if (g == NULL)
447 {
448 // Spew(DSRC_UI_Bounds, ("Attempted to move null gadget!\n"));
449 return(ERR_NULL);
450 }
451 if ((coord.x < 0) || (coord.y < 0))
452 {
453 // Spew(DSRC_UI_Bounds, ("Attempted to move gadget to negative point!\n"));
454 return(ERR_RANGE);
455 }
456 delta.x = coord.x - g->rep->r->ul.x;
457 delta.y = coord.y - g->rep->r->ul.y;
458 // region_traverse(g->rep, &gadget_frob_canvas, BOTTOM_TO_TOP, &delta);
459 region_move(g->rep, coord.x, coord.y, z);
460 return (OK);
461 }
462
gadget_resize(Gadget * g,int xsize,int ysize)463 errtype gadget_resize(Gadget* g, int xsize, int ysize)
464 {
465 if (g == NULL)
466 {
467 // Spew(DSRC_UI_Bounds, ("Attempted to resize null gadget!\n"));
468 return(ERR_NULL);
469 }
470 if ((xsize < 0) || (ysize < 0))
471 {
472 // Spew(DSRC_UI_Bounds, ("Attempted to give region negative size\n"));
473 return(ERR_RANGE);
474 }
475 region_resize(g->rep, xsize, ysize);
476 return (OK);
477 }
478
479
gad_callback_install(Gadget * g,ushort event_type,ushort condition,TNGCallback tngcb,intptr_t user_data,int * id)480 errtype gad_callback_install(Gadget *g, ushort event_type, ushort condition, TNGCallback tngcb, intptr_t user_data, int *id)
481 {
482 return(tng_install_callback(g->tng_data, event_type, condition, tngcb, user_data, id));
483 }
484
gad_callback_uninstall(Gadget * g,int id)485 errtype gad_callback_uninstall(Gadget *g, int id)
486 {
487 return(tng_uninstall_callback(g->tng_data,id));
488 }
489
490 /*
491 uchar gadget_tng_mono_expose(LGRegion *reg, LGRect *r)
492 {
493 LGRegion *dummy;
494 LGRect *dummy2;
495 dummy = reg;
496 dummy2 = r;
497
498 return (FALSE);
499 }
500
501 uchar gadget_tng_vga_expose(LGRegion *reg, LGRect *r)
502 {
503 ushort partmask;
504 LGRect nrect;
505 int c1,c2,c3,c4;
506 LGPoint loc;
507 Gadget *g;
508
509 g = GD_GADG(reg);
510 partmask = g->draw_parts;
511 if (GD_CANV(reg) != NULL)
512 {
513 gr_set_canvas(GD_CANV(reg));
514 region_abs_rect(reg, r, &nrect);
515 // Spew(DSRC_UI_Gadget, ("About to draw gadget %s\n",GD_NAME(reg)));
516 // Spew(DSRC_UI_Gadget, ("r = (%d,%d)(%d,%d)\n",RECT_EXPAND_ARGS(r)));
517 // Spew(DSRC_UI_Gadget, ("nrect = (%d,%d)(%d,%d)\n",RECT_EXPAND_ARGS(&nrect)));
518 STORE_CLIP(c1,c2,c3,c4);
519 gr_set_cliprect(nrect.ul.x, nrect.ul.y, nrect.lr.x , nrect.lr.y);
520 loc.x = g->rep->abs_x; loc.y = g->rep->abs_y;
521 // Spew(DSRC_UI_Gadget, ("abs_x = %d abs_y = %d\n",loc.x, loc.y));
522 g->tng_data->draw_func(g->tng_data, partmask, loc);
523 RESTORE_CLIP(c1,c2,c3,c4);
524 }
525 else
526 // Spew(DSRC_UI_Gadget, ("Got a NULL canvas here, buddy...region %s\n",GD_NAME(reg)));
527 return(OK);
528 }
529 */
gadget_tng_Mac_expose(LGRegion * reg,LGRect * r)530 uchar gadget_tng_Mac_expose(LGRegion *reg, LGRect *r)
531 {
532 ushort partmask;
533 LGRect nrect;
534 int c1,c2,c3,c4;
535 LGPoint loc;
536 Gadget *g;
537
538 g = GD_GADG(reg);
539 partmask = g->draw_parts;
540 if (GD_CANV(reg) != NULL)
541 {
542 gr_set_canvas((grs_canvas *)GD_CANV(reg));
543 region_abs_rect(reg, r, &nrect);
544 STORE_CLIP(c1,c2,c3,c4);
545 gr_set_cliprect(nrect.ul.x, nrect.ul.y, nrect.lr.x , nrect.lr.y);
546 loc.x = g->rep->abs_x; loc.y = g->rep->abs_y;
547 g->tng_data->draw_func(g->tng_data, partmask, loc);
548 RESTORE_CLIP(c1,c2,c3,c4);
549 }
550 return(OK);
551 }
552
gadget_tng_mouse_handler(uiEvent * e,LGRegion * r,intptr_t state)553 uchar gadget_tng_mouse_handler(uiEvent *e, LGRegion *r, intptr_t state)
554 {
555 Gadget *g;
556 uiMouseEvent *mickey;
557 LGPoint rel;
558 intptr_t dummy;
559 dummy = state;
560
561 mickey = (uiMouseEvent *)e;
562 g = GD_GADG(r);
563 rel.x = mickey->pos.x - r->abs_x;
564 rel.y = mickey->pos.y - r->abs_y;
565 return(g->tng_data->mousebutt(g->tng_data, mickey->action, rel));
566 }
567
gadget_tng_mouse_move_handler(uiEvent * e,LGRegion * r,intptr_t state)568 uchar gadget_tng_mouse_move_handler(uiEvent *e, LGRegion *r, intptr_t state)
569 {
570 Gadget *g;
571 uiMouseEvent *mickey;
572 LGPoint rel;
573 intptr_t dummy;
574 dummy = state;
575
576 mickey = (uiMouseEvent *)e;
577 g = GD_GADG(r);
578 rel.x = mickey->pos.x - r->abs_x;
579 rel.y = mickey->pos.y - r->abs_y;
580 return(g->tng_data->mousemove(g->tng_data, rel));
581 }
582
gadget_tng_keyboard_handler(uiEvent * e,LGRegion * r,intptr_t state)583 uchar gadget_tng_keyboard_handler(uiEvent *e, LGRegion *r, intptr_t state)
584 {
585 Gadget *g;
586 uiCookedKeyEvent *cke;
587 intptr_t dummy;
588 dummy = state;
589
590 if ((e->type != UI_EVENT_KBD_COOKED) || !(e->subtype & KB_FLAG_DOWN))
591 return FALSE;
592 cke = (uiCookedKeyEvent *)e;
593 g = GD_GADG(r);
594 return(g->tng_data->keycooked(g->tng_data, cke->code));
595 }
596
gadget_create_setup(Gadget ** pg,Gadget * parent,GadgetClass cl,LGRect * dim,int z,char * name)597 errtype gadget_create_setup(Gadget **pg, Gadget *parent, GadgetClass cl, LGRect *dim, int z, char *name)
598 {
599 Gadget *retgad;
600 GadgetData *gd;
601 TNG *pb_tng;
602 RectCallback fn;
603
604 if ((RectWidth(dim) < 1) || (RectHeight(dim) < 1))
605 {
606 // Spew(DSRC_UI_Bounds, ("Nonpositive dimension of created gadget!\n"));
607 return 0;
608 }
609
610 // Do those yummy mallocs
611 retgad = (Gadget *)malloc(sizeof(Gadget));
612 gd = (GadgetData *)malloc(sizeof(GadgetData));
613 pb_tng = (TNG *)malloc(sizeof(TNG));
614
615 switch (parent->rep->device_type)
616 {
617 /* case DISPLAY_VGA:
618 case DISPLAY_SVGA:
619 case DISPLAY_MODEX:
620 fn = &gadget_tng_vga_expose;
621 break;
622 case DISPLAY_MONO:
623 fn = &gadget_tng_mono_expose;
624 break; */
625 case DISPLAY_MAC:
626 fn = &gadget_tng_Mac_expose;
627 break;
628 }
629
630 // Fill out basic gadgety info
631 retgad->tng_data = pb_tng;
632 retgad->draw_parts = TNG_ALLPARTS;
633 retgad->gclass = cl;
634 retgad->parent = parent;
635 // retgad->device_data = gr_alloc_sub_canvas(parent->device_data, dim->ul.x, dim->ul.y, RectWidth(dim), RectHeight(dim));
636 retgad->device_data = parent->device_data;
637 retgad->conversion = parent->conversion;
638 retgad->handler_id = -1;
639 retgad->destroy_func = NULL;
640
641 // Fill in the gadget data info
642 gd->name = (char *)malloc((strlen(name) + 1) * sizeof(char));
643 strcpy(gd->name, name);
644 gd->g = retgad;
645
646 // Create that durned rep
647 retgad->rep = (LGRegion *)malloc(sizeof(LGRegion));
648 region_create(parent->rep, retgad->rep, dim, z, 0,
649 REG_USER_CONTROLLED | AUTOMANAGE_FLAG | STENCIL_CLIPPING | OBSCURATION_CHECK,
650 fn, NULL, NULL, gd);
651
652 // Install the general pushbutton handler
653 uiInstallRegionHandler(retgad->rep, UI_EVENT_MOUSE_MOVE, &gadget_tng_mouse_move_handler, (intptr_t) retgad, &(retgad->handler_id));
654 uiInstallRegionHandler(retgad->rep, UI_EVENT_MOUSE, &gadget_tng_mouse_handler, (intptr_t) retgad, &(retgad->handler_id));
655 uiInstallRegionHandler(retgad->rep, UI_EVENT_KBD_COOKED, &gadget_tng_keyboard_handler, (intptr_t) retgad, &(retgad->handler_id));
656
657 *pg = retgad;
658 return(OK);
659 }
660
gadget_change_flags(Gadget * g,ulong flags,uchar on,uchar children)661 errtype gadget_change_flags(Gadget *g, ulong flags, uchar on, uchar children)
662 {
663 LGRegion *cur_child;
664 if (on)
665 g->rep->status_flags |= flags;
666 else
667 g->rep->status_flags &= ~flags;
668 if (children)
669 {
670 cur_child = g->rep->sub_region;
671 while (cur_child != NULL)
672 {
673 gadget_change_flags(GD_GADG(cur_child), flags, on, children);
674 cur_child = cur_child->next_region;
675 }
676 }
677 return(OK);
678 }
679