1 /***************************************************************************/
2 /* This code is part of X-toolkit widget library called Nws */
3 /* Copyright (c) 1997,1998,1999 Ondrejicka Stefan */
4 /* (ondrej@idata.sk) */
5 /* Distributed under GPL 2 or later */
6 /***************************************************************************/
7
8 #include <X11/IntrinsicP.h>
9 #include <X11/StringDefs.h>
10 #include <X11/extensions/shape.h>
11
12 #include "MwPopText.h"
13 #include "MwBaseCompP.h"
14 #include "MwBaseConstP.h"
15 #include "MwNws.h"
16 #include "MwTraverse.h"
17 #include <stdio.h>
18 #include "MwUtils.h"
19
20 #define offset(field) XtOffsetOf(MwBaseCompRec, baseComp.field)
21
22 static XtResource resources[] = {
23 {
24 XtNfont,
25 XtCFont,
26 XtRFontStruct ,
27 sizeof(XFontStruct *) ,
28 offset(font) ,
29 XtRString ,
30 (XtPointer) XtDefaultFont
31 },
32 {
33 XtNforeground,
34 XtCForeground,
35 XtRPixel,
36 sizeof(Pixel),
37 offset(foreground),
38 XtRString,
39 (XtPointer) XtDefaultForeground
40 },
41 {
42 XtNhelp_text,
43 XtCHelp_text,
44 XtRString,
45 sizeof(String),
46 offset(help_text),
47 XtRImmediate,
48 (XtPointer) NULL
49 },
50 {
51 XtNlabel,
52 XtCLabel,
53 XtRString,
54 sizeof(String),
55 offset(label),
56 XtRImmediate,
57 (XtPointer) NULL
58 },
59 {
60 XtNjustify,
61 XtCJustify,
62 XtRNwsJustify,
63 sizeof(int),
64 offset(justify),
65 XtRImmediate,
66 (XtPointer) XtCcenter
67 },
68 {
69 XtNcursor,
70 XtCCursor,
71 XtRCursor,
72 sizeof(Cursor),
73 offset(cursor),
74 XtRString,
75 (XtPointer) None
76 },
77 {
78 XtNbox_type,
79 XtCBox_type,
80 XtRBox_type,
81 sizeof(int),
82 offset(box_type),
83 XtRImmediate,
84 (XtPointer) XtCsimple_box
85 },
86 {
87 XtNbox_width,
88 XtCBox_width,
89 XtRInt,
90 sizeof(int),
91 offset(box_width),
92 XtRImmediate,
93 (XtPointer) 2
94 },
95 {
96 XtNbox_intensity,
97 XtCBox_intensity,
98 XtRInt,
99 sizeof(int),
100 offset(box_intensity),
101 XtRImmediate,
102 (XtPointer) 10000
103 },
104 {
105 XtNbox_color,
106 XtCBox_color,
107 XtRPixel,
108 sizeof(Pixel),
109 offset(box_color),
110 XtRString,
111 (XtPointer) XtDefaultForeground
112 },
113 {
114 XtNborderWidth,
115 XtCBorderWidth,
116 XtRDimension,
117 sizeof(Dimension),
118 XtOffsetOf(MwBaseCompRec , core.border_width),
119 XtRImmediate,
120 (XtPointer) 0
121 },
122 {
123 XtNhighlight_on_enter,
124 XtCHighlight_on_enter,
125 XtRBoolean,
126 sizeof(Boolean),
127 offset(highlight_on_enter),
128 XtRImmediate,
129 (XtPointer) False
130 },
131 {
132 XtNhelp_show_delay,
133 XtCHelp_show_delay,
134 XtRInt,
135 sizeof(int),
136 offset(help_show_delay),
137 XtRImmediate,
138 (XtPointer) 500
139 },
140 {
141 XtNbd_width ,
142 XtCBd_width ,
143 XtRInt ,
144 sizeof(int) ,
145 offset(bd_width) ,
146 XtRImmediate ,
147 (XtPointer) 0 ,
148 },
149 {
150 XtNbd_color ,
151 XtCBd_color ,
152 XtRPixel ,
153 sizeof(Pixel),
154 offset(bd_color),
155 XtRString,
156 (XtPointer) XtDefaultForeground
157 },
158 {
159 XtNtraverse ,
160 XtCTraverse ,
161 XtRBoolean ,
162 sizeof(Boolean) ,
163 offset(traverse) ,
164 XtRImmediate ,
165 (XtPointer) True ,
166 },
167 {
168 XtNtopShadowContrast,
169 XtCTopShadowContrast,
170 XtRInt,
171 sizeof(int),
172 offset(top_shadow_contrast),
173 XtRImmediate,
174 (XtPointer)20
175 },
176 {
177 XtNbottomShadowContrast,
178 XtCBottomShadowContrast,
179 XtRInt,
180 sizeof(int),
181 offset(bot_shadow_contrast),
182 XtRImmediate,
183 (XtPointer)40
184 },
185 };
186
187 static void Initialize (Widget, Widget, ArgList, Cardinal *);
188 static Boolean SetValues (Widget, Widget, Widget, ArgList, Cardinal *);
189 static void Redisplay (Widget, XEvent *, Region);
190 static void Destroy (Widget);
191 static void Realize (Widget, Mask *, XSetWindowAttributes *);
192 static void ClassInitialize(void);
193 static void ResolveInheritance(WidgetClass);
194 static void Resize (Widget);
195 static Boolean AcceptFocus(Widget, Time *);
196
197 static void GetInternalDimension(Widget,Position *,Position *,Dimension *,Dimension *);
198 static void SetInternalDimension(Widget,Dimension,Dimension);
199
200 static Widget Traverse(Widget, int, Time *);
201 static void TraverseTo(Widget, Widget, Time *);
202 static void TraverseOut(Widget);
203 static Widget TraverseInside(Widget, int, Time *);
204 static void ShowHelp(Widget, XEvent *, String *, Cardinal *);
205 static void HideHelp(Widget, XEvent *, String *, Cardinal *);
206 static void _ShowHelp(XtPointer, XtIntervalId *);
207 static void _FocusIn(Widget, XEvent *, String *, Cardinal *);
208 static void _FocusOut(Widget, XEvent *, String *, Cardinal *);
209 static void HighlightBorder(Widget);
210 static void UnhighlightBorder(Widget);
211 static void TraverseForward(Widget, XEvent *, String *, Cardinal *);
212 static void TraverseBackward(Widget, XEvent *, String *, Cardinal *);
213 static void FocusCurrent(Widget, XEvent *, String *, Cardinal *);
214 static void ChangeManaged(Widget);
215
216 static XtActionsRec action [] = {
217 {"show_help",ShowHelp},
218 {"hide_help",HideHelp},
219 {"focusIn",_FocusIn},
220 {"focusOut",_FocusOut},
221 {"focusCurrent" , FocusCurrent},
222 {"traverseForward" , TraverseForward},
223 {"traverseBackward" , TraverseBackward},
224 };
225
226 static char trans_tab [] =
227 "<Enter>: show_help()\n\
228 <Leave>: hide_help()\n\
229 ~Shift<Key>Tab: traverseForward()\n\
230 Shift<Key>Tab: traverseBackward()\n\
231 <FocusIn>: focusIn()\n\
232 <FocusOut>: focusOut()\n\
233 <BtnDown>: hide_help() focusCurrent()\n\
234 <KeyDown>: hide_help()";
235
236 MwBaseCompClassRec mwBaseCompClassRec = {
237 /* core */
238 {
239 /* superclass */ (WidgetClass) &compositeClassRec,
240 /* class_name */ "MwBaseComp",
241 /* widget_size */ sizeof(MwBaseCompRec),
242 /* class_initialize */ ClassInitialize,
243 /* class_part_initialize */ ResolveInheritance,
244 /* class_inited */ FALSE,
245 /* initialize */ (XtInitProc) Initialize,
246 /* initialize_hook */ NULL,
247 /* realize */ Realize,
248 /* actions */ action,
249 /* num_actions */ XtNumber(action),
250 /* resources */ resources,
251 /* num_resources */ XtNumber(resources),
252 /* xrm_class */ NULLQUARK,
253 /* compress_motion */ False,
254 /* compress_exposure */ False,
255 /* compress_enterleave */ False,
256 /* visible_interest */ FALSE,
257 /* destroy */ Destroy,
258 /* resize */ Resize,
259 /* expose */ Redisplay,
260 /* set_values */ (XtSetValuesFunc) SetValues,
261 /* set_values_hook */ NULL,
262 /* set_values_almost */ XtInheritSetValuesAlmost,
263 /* get_values_hook */ NULL,
264 /* accept_focus */ AcceptFocus,
265 /* version */ XtVersion,
266 /* callback_private */ NULL,
267 /* tm_table */ trans_tab,
268 /* query_geometry */ XtInheritQueryGeometry,
269 /* display_accelerator */ XtInheritDisplayAccelerator,
270 /* extension */ NULL
271 },
272 /* composite */
273 {
274 /* geometry_manager */ XtInheritGeometryManager,
275 /* change_managed */ ChangeManaged,
276 /* insert_child */ XtInheritInsertChild,
277 /* delete_child */ XtInheritDeleteChild,
278 /* extension */ NULL
279 },
280 /* baseComp */
281 {
282 /* get_internal_dimension */ GetInternalDimension,
283 /* set_internal_dimension */ SetInternalDimension,
284 /* traverse */ Traverse,
285 /* traverseTo */ TraverseTo,
286 /* traverseOut */ TraverseOut,
287 /* traverseInside */ TraverseInside,
288 /* highlightBorder */ HighlightBorder,
289 /* unhighlightBorder */ UnhighlightBorder,
290 },
291 };
292
293 WidgetClass mwBaseCompWidgetClass = (WidgetClass) &mwBaseCompClassRec;
294
295 #define ForAllChildren(cw, child) \
296 for ( (child) = (cw)->composite.children ; \
297 (child) < ((cw)->composite.children + \
298 (cw)->composite.num_children ) ; \
299 (child)++ )
300
ClassInitialize(void)301 static void ClassInitialize(void)
302 {
303 _InitializeWidgetSet();
304
305 XtSetTypeConverter(XtRString , XtRBox_type , cvtStringToBoxType ,
306 NULL , 0 , XtCacheNone , NULL);
307
308 XtSetTypeConverter(XtRBox_type , XtRString , cvtBoxTypeToString ,
309 NULL , 0 , XtCacheNone , NULL);
310
311 XtSetTypeConverter(XtRString , XtRNwsJustify , cvtStringToJustify ,
312 NULL , 0 , XtCacheNone , NULL);
313
314 }
315
ResolveInheritance(WidgetClass class)316 static void ResolveInheritance(WidgetClass class)
317 {
318 MwBaseCompWidgetClass c = (MwBaseCompWidgetClass) class;
319 MwBaseCompWidgetClass super;
320 static CompositeClassExtensionRec extension_rec = {
321 NULL, NULLQUARK, XtCompositeExtensionVersion,
322 sizeof(CompositeClassExtensionRec), True};
323 CompositeClassExtensionRec *ext;
324
325 ext = MwMalloc(sizeof(*ext));
326 *ext = extension_rec;
327 ext->next_extension = c->composite_class.extension;
328 c->composite_class.extension = ext;
329
330 if (class == mwBaseCompWidgetClass) return;
331 super = (MwBaseCompWidgetClass)class->core_class.superclass;
332
333 if (c->baseComp_class.get_internal_dimension == XtInheritGetInternalDimension)
334 c->baseComp_class.get_internal_dimension =
335 super->baseComp_class.get_internal_dimension;
336
337 if (c->baseComp_class.set_internal_dimension == XtInheritSetInternalDimension)
338 c->baseComp_class.set_internal_dimension =
339 super->baseComp_class.set_internal_dimension;
340
341 if (c->baseComp_class.traverse == XtInheritTraverse)
342 c->baseComp_class.traverse =
343 super->baseComp_class.traverse;
344
345 if (c->baseComp_class.traverseTo == XtInheritTraverseTo)
346 c->baseComp_class.traverseTo =
347 super->baseComp_class.traverseTo;
348
349 if (c->baseComp_class.traverseOut == XtInheritTraverseOut)
350 c->baseComp_class.traverseOut =
351 super->baseComp_class.traverseOut;
352
353 if (c->baseComp_class.traverseInside == XtInheritTraverseInside)
354 c->baseComp_class.traverseInside =
355 super->baseComp_class.traverseInside;
356
357 if (c->baseComp_class.highlightBorder == XtInheritHighlightBorder)
358 c->baseComp_class.highlightBorder =
359 super->baseComp_class.highlightBorder;
360
361 if (c->baseComp_class.unhighlightBorder == XtInheritUnhighlightBorder)
362 c->baseComp_class.unhighlightBorder =
363 super->baseComp_class.unhighlightBorder;
364
365 }
366
Initialize(Widget req_widget,Widget new_widget,ArgList args,Cardinal * num_args)367 static void Initialize(Widget req_widget, Widget new_widget,
368 ArgList args, Cardinal *num_args)
369 {
370 MwBaseCompWidget nw = (MwBaseCompWidget) new_widget;
371 XColor dark,light,bg;
372 Display *dpy=XtDisplay(new_widget);
373 XGCValues gc_res;
374 XtGCMask gc_mask;
375
376 bg.pixel = nw->baseComp.box_color;
377
378 XQueryColor(dpy,DefaultColormap(dpy,DefaultScreen(dpy)),&bg);
379
380 LightColor2(new_widget, light, nw->baseComp.top_shadow_contrast);
381 DarkColor2(new_widget, dark, nw->baseComp.bot_shadow_contrast);
382
383 nw->baseComp.light = light.pixel;
384 nw->baseComp.dark = dark.pixel;
385
386 gc_res.foreground = nw->baseComp.box_color;
387 gc_res.font = nw->baseComp.font->fid;
388
389 gc_mask = GCForeground | GCFont;
390
391 nw->baseComp.gc = XCreateGC(dpy,DefaultRootWindow(dpy),
392 gc_mask, &gc_res);
393
394 if (nw->baseComp.help_text)
395 {
396 nw->baseComp.help_text = MwStrdup(nw->baseComp.help_text);
397 nw->baseComp.hlp = XtVaCreatePopupShell("___help" , mwPopTextWidgetClass ,
398 new_widget , XtNtext , nw->baseComp.help_text,NULL);
399 }
400
401 if (nw->baseComp.label) nw->baseComp.label = MwStrdup(nw->baseComp.label);
402
403 if (nw->baseComp.box_type == XtCshadow_box)
404 {
405 nw->baseComp.have_shape = True;
406 }
407 else
408 {
409 nw->baseComp.have_shape = False;
410 }
411 nw->baseComp.timer = (XtIntervalId) 0;
412 nw->baseComp.current_focused = NULL;
413 nw->baseComp.focused = False;
414 nw->baseComp.traverse_direction = MW_TRAVERSE_FIRST;
415
416 }
417
Realize(Widget w,Mask * valueMask,XSetWindowAttributes * attributes)418 static void Realize(Widget w, Mask *valueMask, XSetWindowAttributes *attributes)
419 {
420 MwBaseCompWidget cw = (MwBaseCompWidget) w;
421
422 if ((attributes->cursor = cw->baseComp.cursor) != None)
423 *valueMask |= CWCursor;
424
425 compositeClassRec.core_class.realize(w,valueMask,attributes);
426
427 if (cw->baseComp.box_type == XtCshadow_box)
428 {
429 Region region;
430 XPoint points[8];
431
432 points[0].x = 0;
433 points[0].y = 0;
434 points[1].x = cw->core.width - 2 * cw->baseComp.box_width;
435 points[1].y = 0;
436 points[2].x = cw->core.width - 2 * cw->baseComp.box_width;
437 points[2].y = 2 * cw->baseComp.box_width;
438 points[3].x = cw->core.width;
439 points[3].y = 2 * cw->baseComp.box_width;
440 points[4].x = cw->core.width;
441 points[4].y = cw->core.height;
442 points[5].x = 2 * cw->baseComp.box_width;
443 points[5].y = cw->core.height;
444 points[6].x = 2 * cw->baseComp.box_width;
445 points[6].y = cw->core.height - 2 * cw->baseComp.box_width;
446 points[7].x = 0;
447 points[7].y = cw->core.height - 2 * cw->baseComp.box_width;
448
449
450 region = XPolygonRegion(points , XtNumber(points) , EvenOddRule);
451
452 XShapeCombineRegion(XtDisplay(w) , XtWindow(w) , ShapeBounding ,
453 0 , 0 , region , ShapeSet);
454
455 XDestroyRegion(region);
456 }
457 }
458
Destroy(Widget w)459 static void Destroy(Widget w)
460 {
461 MwBaseCompWidget cw = (MwBaseCompWidget) w;
462
463 if (cw->baseComp.help_text)
464 MwFree(cw->baseComp.help_text);
465
466 XFreeGC(XtDisplay(w),cw->baseComp.gc);
467 }
468
Redisplay(Widget w,XEvent * event,Region region)469 static void Redisplay(Widget w, XEvent *event, Region region)
470 {
471 MwBaseCompWidget cw = (MwBaseCompWidget) w;
472 Display *dpy = XtDisplay(w);
473 Window win = XtWindow (w);
474 cw->core.border_width=0;
475 if (cw->baseComp.label &&
476 (cw->baseComp.box_type == XtCno_box ||
477 cw->baseComp.box_type == XtCsimple_box ||
478 cw->baseComp.box_type == XtCup_box ||
479 cw->baseComp.box_type == XtCdown_box ||
480 cw->baseComp.box_type == XtCshadow_box ))
481
482 {
483 Position x;
484
485 switch(cw->baseComp.justify)
486 {
487 case XtCleft:
488 x = 4 * cw->baseComp.box_width + cw->baseComp.bd_width;
489 break;
490
491 case XtCright:
492 x = cw->core.width - cw->baseComp.bd_width -
493 XTextWidth(cw->baseComp.font ,
494 cw->baseComp.label , strlen(cw->baseComp.label))
495 - 4 * cw->baseComp.box_width -
496 (cw->baseComp.box_type == XtCshadow_box ?
497 2 * cw->baseComp.box_width : 0);
498 break;
499
500 case XtCcenter:
501 default:
502 x = (cw->core.width - 2 * cw->baseComp.bd_width -
503 XTextWidth(cw->baseComp.font ,
504 cw->baseComp.label ,
505 strlen(cw->baseComp.label))) / 2;
506 break;
507
508
509 }
510 XSetForeground(dpy , cw->baseComp.gc , cw->baseComp.box_color);
511 XSetBackground(dpy , cw->baseComp.gc , cw->baseComp.box_color);
512 XFillRectangle(dpy , win , cw->baseComp.gc ,
513 cw->baseComp.bd_width , cw->baseComp.bd_width ,
514 cw->core.width - cw->baseComp.bd_width,
515 cw->baseComp.font->max_bounds.descent +
516 cw->baseComp.font->max_bounds.ascent +
517 2 * cw->baseComp.box_width );
518
519 XSetForeground(dpy , cw->baseComp.gc , cw->baseComp.foreground);
520 XDrawImageString(dpy , win , cw->baseComp.gc , x ,
521 cw->baseComp.font->max_bounds.ascent +
522 cw->baseComp.box_width + cw->baseComp.bd_width,
523 cw->baseComp.label , strlen(cw->baseComp.label));
524 }
525 switch (cw->baseComp.box_type)
526 {
527 case XtCno_box:
528 break;
529
530 case XtCsimple_box:
531 X_DrawSimpleRawFrame(dpy , win , cw->baseComp.bd_width ,
532 cw->baseComp.bd_width ,
533 cw->core.width - 2 * cw->baseComp.bd_width,
534 cw->core.height - 2 * cw->baseComp.bd_width ,
535 cw->baseComp.box_width ,
536 cw->baseComp.box_color);
537 break;
538
539 case XtCup_box:
540 X_DrawSimple3DFrame(dpy , win , cw->baseComp.bd_width ,
541 cw->baseComp.bd_width ,
542 cw->core.width - 2 * cw->baseComp.bd_width ,
543 cw->core.height - 2 * cw->baseComp.bd_width ,
544 cw->baseComp.box_width ,
545 cw->baseComp.light , cw->baseComp.dark);
546 break;
547
548 case XtCdown_box:
549 X_DrawSimple3DFrame(dpy , win , cw->baseComp.bd_width ,
550 cw->baseComp.bd_width ,
551 cw->core.width - 2 * cw->baseComp.bd_width,
552 cw->core.height - 2 * cw->baseComp.bd_width ,
553 cw->baseComp.box_width ,
554 cw->baseComp.dark , cw->baseComp.light);
555 break;
556
557 case XtCframein_box:
558 if (cw->baseComp.label )
559 {
560 Position x;
561 char *p = MwMalloc(strlen(cw->baseComp.label)+3);
562 sprintf(p , " %s " ,cw->baseComp.label);
563
564 switch(cw->baseComp.justify)
565 {
566 case XtCleft:
567 x = 4 * cw->baseComp.box_width +
568 cw->baseComp.bd_width;
569 break;
570
571 case XtCright:
572 x = cw->core.width - cw->baseComp.bd_width -
573 XTextWidth(cw->baseComp.font ,
574 p , strlen(p)) -
575 4 * cw->baseComp.box_width;
576 break;
577
578 case XtCcenter:
579 default:
580 x = (cw->core.width - 2 * cw->baseComp.bd_width -
581 XTextWidth(cw->baseComp.font ,
582 p , strlen(p))) / 2;
583 break;
584
585 }
586
587 X_DrawSimple3DFrame(dpy , win , cw->baseComp.bd_width ,
588 (cw->baseComp.box_width +
589 cw->baseComp.font->max_bounds.descent +
590 cw->baseComp.font->max_bounds.ascent) / 2 +
591 cw->baseComp.bd_width,
592 cw->core.width - 2 * cw->baseComp.bd_width ,
593 cw->core.height - (cw->baseComp.box_width +
594 cw->baseComp.font->max_bounds.descent +
595 cw->baseComp.font->max_bounds.ascent) / 2
596 - 2 * cw->baseComp.bd_width,
597 cw->baseComp.box_width / 2 ,
598 cw->baseComp.dark , cw->baseComp.light);
599
600 X_DrawSimple3DFrame(dpy , win ,
601 cw->baseComp.box_width / 2 + cw->baseComp.bd_width,
602 cw->baseComp.box_width / 2 +
603 (cw->baseComp.box_width +
604 cw->baseComp.font->max_bounds.descent +
605 cw->baseComp.font->max_bounds.ascent) / 2 +
606 cw->baseComp.bd_width,
607 cw->core.width - 2 * (cw->baseComp.box_width / 2)
608 - 2 * cw->baseComp.bd_width,
609 cw->core.height - 2 * (cw->baseComp.box_width / 2) -
610 (cw->baseComp.box_width +
611 cw->baseComp.font->max_bounds.descent +
612 cw->baseComp.font->max_bounds.ascent) / 2
613 - 2 * cw->baseComp.bd_width,
614 cw->baseComp.box_width / 2 ,
615 cw->baseComp.light , cw->baseComp.dark);
616
617 XSetForeground(dpy , cw->baseComp.gc , cw->baseComp.foreground);
618 XSetBackground(dpy , cw->baseComp.gc , cw->core.background_pixel);
619 XDrawImageString(dpy , win , cw->baseComp.gc ,
620 x ,
621 cw->baseComp.box_width +
622 cw->baseComp.font->max_bounds.ascent +
623 cw->baseComp.bd_width,
624 p , strlen(p));
625
626 MwFree(p);
627 }
628 else
629 {
630 X_DrawSimple3DFrame(dpy , win , cw->baseComp.bd_width ,
631 cw->baseComp.bd_width ,
632 cw->core.width - 2 * cw->baseComp.bd_width,
633 cw->core.height - 2 * cw->baseComp.bd_width ,
634 cw->baseComp.box_width / 2 ,
635 cw->baseComp.dark , cw->baseComp.light);
636
637 X_DrawSimple3DFrame(dpy , win ,
638 cw->baseComp.box_width / 2 + cw->baseComp.bd_width,
639 cw->baseComp.box_width / 2 + cw->baseComp.bd_width,
640 cw->core.width - 2 * (cw->baseComp.box_width / 2)
641 - 2 * cw->baseComp.bd_width,
642 cw->core.height - 2 * (cw->baseComp.box_width / 2)
643 - 2 * cw->baseComp.bd_width,
644 cw->baseComp.box_width / 2 ,
645 cw->baseComp.light , cw->baseComp.dark);
646 }
647 break;
648
649 case XtCframeout_box:
650 if (cw->baseComp.label )
651 {
652 Position x;
653 char *p = MwMalloc(strlen(cw->baseComp.label)+3);
654 sprintf(p , " %s " ,cw->baseComp.label);
655
656 switch(cw->baseComp.justify)
657 {
658 case XtCleft:
659 x = 4 * cw->baseComp.box_width + cw->baseComp.bd_width;
660 break;
661
662 case XtCright:
663 x = cw->core.width - cw->baseComp.bd_width -
664 XTextWidth(cw->baseComp.font ,
665 p , strlen(p)) -
666 4 * cw->baseComp.box_width;
667 break;
668
669 case XtCcenter:
670 default:
671 x = (cw->core.width - 2 * cw->baseComp.bd_width -
672 XTextWidth(cw->baseComp.font ,
673 p , strlen(p))) / 2;
674 break;
675
676 }
677
678
679 X_DrawSimple3DFrame(dpy , win , cw->baseComp.bd_width ,
680 (cw->baseComp.box_width +
681 cw->baseComp.font->max_bounds.descent +
682 cw->baseComp.font->max_bounds.ascent) / 2 + cw->baseComp.bd_width,
683 cw->core.width - 2 * cw->baseComp.bd_width,
684 cw->core.height - (cw->baseComp.box_width +
685 cw->baseComp.font->max_bounds.descent +
686 cw->baseComp.font->max_bounds.ascent) / 2
687 - 2 * cw->baseComp.bd_width ,
688 cw->baseComp.box_width / 2 ,
689 cw->baseComp.light , cw->baseComp.dark);
690
691 X_DrawSimple3DFrame(dpy , win ,
692 cw->baseComp.box_width / 2 + cw->baseComp.bd_width,
693 cw->baseComp.box_width / 2 +
694 (cw->baseComp.box_width +
695 cw->baseComp.font->max_bounds.descent +
696 cw->baseComp.font->max_bounds.ascent) / 2 +
697 cw->baseComp.bd_width,
698 cw->core.width - 2 * (cw->baseComp.box_width / 2)
699 - 2 * cw->baseComp.bd_width,
700 cw->core.height - 2 * (cw->baseComp.box_width / 2) -
701 (cw->baseComp.box_width +
702 cw->baseComp.font->max_bounds.descent +
703 cw->baseComp.font->max_bounds.ascent) / 2
704 - 2 * cw->baseComp.bd_width,
705 cw->baseComp.box_width / 2 ,
706 cw->baseComp.dark , cw->baseComp.light);
707
708 XSetForeground(dpy , cw->baseComp.gc , cw->baseComp.foreground);
709 XSetBackground(dpy , cw->baseComp.gc , cw->core.background_pixel);
710 XDrawImageString(dpy , win , cw->baseComp.gc ,
711 x , cw->baseComp.box_width +
712 cw->baseComp.font->max_bounds.ascent +
713 cw->baseComp.bd_width,
714 p , strlen(p));
715
716 MwFree(p);
717 }
718 else
719 {
720 X_DrawSimple3DFrame(dpy , win , cw->baseComp.bd_width ,
721 cw->baseComp.bd_width ,
722 cw->core.width - 2 * cw->baseComp.bd_width,
723 cw->core.height - 2 * cw->baseComp.bd_width ,
724 cw->baseComp.box_width / 2 ,
725 cw->baseComp.light , cw->baseComp.dark);
726 X_DrawSimple3DFrame(dpy , win ,
727 cw->baseComp.box_width / 2 + cw->baseComp.bd_width ,
728 cw->baseComp.box_width / 2 + cw->baseComp.bd_width ,
729 cw->core.width - 2 * (cw->baseComp.box_width / 2)
730 - 2 * cw->baseComp.bd_width,
731 cw->core.height - 2 * (cw->baseComp.box_width / 2)
732 - 2 * cw->baseComp.bd_width,
733 cw->baseComp.box_width / 2 ,
734 cw->baseComp.dark , cw->baseComp.light);
735 }
736 break;
737
738 case XtCshadow_box:
739 {
740 XPoint points[6];
741
742 points[0].x = 2 * cw->baseComp.box_width + cw->baseComp.bd_width;
743 points[0].y = cw->core.height - cw->baseComp.bd_width;
744 points[1].x = 2 * cw->baseComp.box_width + cw->baseComp.bd_width;
745 points[1].y = cw->core.height - 2 * cw->baseComp.box_width - cw->baseComp.bd_width;
746 points[2].x = cw->core.width - 2 * cw->baseComp.box_width - cw->baseComp.bd_width;
747 points[2].y = cw->core.height - 2 * cw->baseComp.box_width - cw->baseComp.bd_width;
748 points[3].x = cw->core.width - 2 * cw->baseComp.box_width - cw->baseComp.bd_width;
749 points[3].y = 2 * cw->baseComp.box_width + cw->baseComp.bd_width;
750 points[4].x = cw->core.width - cw->baseComp.bd_width;
751 points[4].y = 2 * cw->baseComp.box_width + cw->baseComp.bd_width;
752 points[5].x = cw->core.width - cw->baseComp.bd_width;
753 points[5].y = cw->core.height - cw->baseComp.bd_width;
754
755 X_DrawSimpleRawFrame (dpy , win , cw->baseComp.bd_width ,
756 cw->baseComp.bd_width ,
757 cw->core.width - (2 * cw->baseComp.box_width)
758 - 2 * cw->baseComp.bd_width,
759 cw->core.height - (2 * cw->baseComp.box_width)
760 - 2 * cw->baseComp.bd_width,
761 cw->baseComp.box_width , cw->baseComp.box_color );
762
763 XSetForeground(dpy , cw->baseComp.gc , cw->baseComp.dark);
764
765 XFillPolygon(dpy , win , cw->baseComp.gc , points ,
766 XtNumber(points),Nonconvex , CoordModeOrigin);
767
768 break;
769 }
770 }
771
772 if (cw->baseComp.focused)
773 ((MwBaseCompWidgetClass)w->core.widget_class)
774 ->baseComp_class.highlightBorder(w);
775
776 if (!XtIsSensitive(w)) Xt_SetInsensitive(w);
777 }
778
Resize(Widget w)779 static void Resize(Widget w)
780 {
781 MwBaseCompWidget cw = (MwBaseCompWidget) w;
782
783 if (!XtIsRealized(w)) return;
784
785 if (cw->baseComp.have_shape)
786 {
787 if (cw->baseComp.box_type == XtCshadow_box)
788 {
789 Region region;
790 XPoint points[8];
791
792 points[0].x = 0;
793 points[0].y = 0;
794 points[1].x = cw->core.width - 2 * cw->baseComp.box_width;
795 points[1].y = 0;
796 points[2].x = cw->core.width - 2 * cw->baseComp.box_width;
797 points[2].y = 2 * cw->baseComp.box_width;
798 points[3].x = cw->core.width;
799 points[3].y = 2 * cw->baseComp.box_width;
800 points[4].x = cw->core.width;
801 points[4].y = cw->core.height;
802 points[5].x = 2 * cw->baseComp.box_width;
803 points[5].y = cw->core.height;
804 points[6].x = 2 * cw->baseComp.box_width;
805 points[6].y = cw->core.height - 2 * cw->baseComp.box_width;
806 points[7].x = 0;
807 points[7].y = cw->core.height - 2 * cw->baseComp.box_width;
808
809 region = XPolygonRegion(points , XtNumber(points) , EvenOddRule);
810
811 XShapeCombineRegion(XtDisplay(w) , XtWindow(w) , ShapeBounding ,
812 0 , 0 , region , ShapeSet);
813
814 XDestroyRegion(region);
815
816 } else {
817 Region region;
818 XPoint points[4];
819
820 points[0].x = 0;
821 points[0].y = 0;
822 points[1].x = cw->core.width;
823 points[1].y = 0;
824 points[2].x = cw->core.width;
825 points[2].y = cw->core.height;
826 points[3].x = 0;
827 points[3].y = cw->core.height;
828
829 region = XPolygonRegion(points , XtNumber(points) , EvenOddRule);
830
831 XShapeCombineRegion(XtDisplay(w) , XtWindow(w) , ShapeBounding ,
832 0 , 0 , region , ShapeSet);
833
834 XDestroyRegion(region);
835 }
836 }
837 }
838
839
840 #define WidgetValuesDiffer(w1,w2,component) (w1 -> baseComp.component != \
841 w2 -> baseComp.component)
842
SetValues(Widget current,Widget request,Widget new_widget,ArgList args,Cardinal * num_args)843 static Boolean SetValues(Widget current, Widget request, Widget new_widget,
844 ArgList args, Cardinal *num_args)
845 {
846 MwBaseCompWidget cw = (MwBaseCompWidget) current;
847 MwBaseCompWidget nw = (MwBaseCompWidget) new_widget;
848 Widget w = (Widget) new_widget;
849 Boolean redraw=False;
850
851 if WidgetValuesDiffer( cw , nw , cursor)
852 {
853 XDefineCursor(XtDisplay(current),XtWindow(current),nw->baseComp.cursor);
854 }
855
856 if (WidgetValuesDiffer( cw , nw , box_type) ||
857 WidgetValuesDiffer( cw , nw , box_width))
858 {
859 if (cw->baseComp.box_type == XtCshadow_box &&
860 nw->baseComp.box_type != XtCshadow_box)
861 {
862 Region region;
863 XPoint points[4];
864
865 points[0].x = 0;
866 points[0].y = 0;
867 points[1].x = cw->core.width;
868 points[1].y = 0;
869 points[2].x = cw->core.width;
870 points[2].y = cw->core.height;
871 points[3].x = 0;
872 points[3].y = cw->core.height;
873
874 region = XPolygonRegion(points , XtNumber(points) , EvenOddRule);
875
876 XShapeCombineRegion(XtDisplay(w) , XtWindow(w) , ShapeBounding ,
877 0 , 0 , region , ShapeSet);
878
879 XDestroyRegion(region);
880
881 }
882 if (nw->baseComp.box_type == XtCshadow_box &&
883 cw->baseComp.box_type != XtCshadow_box)
884 {
885 Region region;
886 XPoint points[8];
887
888 points[0].x = 0;
889 points[0].y = 0;
890 points[1].x = cw->core.width - 2 * cw->baseComp.box_width;
891 points[1].y = 0;
892 points[2].x = cw->core.width - 2 * cw->baseComp.box_width;
893 points[2].y = 2 * cw->baseComp.box_width;
894 points[3].x = cw->core.width;
895 points[3].y = 2 * cw->baseComp.box_width;
896 points[4].x = cw->core.width;
897 points[4].y = cw->core.height;
898 points[5].x = 2 * cw->baseComp.box_width;
899 points[5].y = cw->core.height;
900 points[6].x = 2 * cw->baseComp.box_width;
901 points[6].y = cw->core.height - 2 * cw->baseComp.box_width;
902 points[7].x = 0;
903 points[7].y = cw->core.height - 2 * cw->baseComp.box_width;
904
905 region = XPolygonRegion(points , XtNumber(points) , EvenOddRule);
906
907 XShapeCombineRegion(XtDisplay(w) , XtWindow(w) , ShapeBounding ,
908 0 , 0 , region , ShapeSet);
909
910 XDestroyRegion(region);
911
912 nw->baseComp.have_shape=True;
913
914 }
915 redraw = True;
916 }
917
918 if WidgetValuesDiffer( cw , nw , help_text)
919 {
920 if (cw->baseComp.help_text)
921 {
922 MwFree(cw->baseComp.help_text);
923 cw->baseComp.help_text = NULL;
924 XtDestroyWidget(cw->baseComp.hlp);
925 }
926 if (nw->baseComp.help_text)
927 {
928 nw->baseComp.help_text = MwStrdup(nw->baseComp.help_text);
929 nw->baseComp.hlp = XtVaCreatePopupShell("___help" , mwPopTextWidgetClass ,
930 new_widget , XtNtext , nw->baseComp.help_text,NULL);
931 }
932 }
933
934
935 if WidgetValuesDiffer( cw , nw , label )
936 {
937 if (cw->baseComp.label)
938 {
939 MwFree(cw->baseComp.label);
940 cw->baseComp.label = NULL;
941 }
942 if (nw->baseComp.label)
943 nw->baseComp.label = MwStrdup(nw->baseComp.label);
944
945 redraw = True;
946 }
947
948 if WidgetValuesDiffer( cw , nw , font )
949 {
950 XSetFont(XtDisplay(w) , nw->baseComp.gc , nw->baseComp.font->fid);
951
952 redraw = True;
953 }
954
955 return redraw;
956 }
957
ChangeManaged(Widget w)958 static void ChangeManaged(Widget w)
959 {
960 MwBaseCompWidget cw = (MwBaseCompWidget) w;
961 Widget *child;
962
963 if (constraintClassRec.composite_class.change_managed)
964 constraintClassRec.composite_class.change_managed(w);
965
966 if (cw->baseComp.current_focused)
967 {
968 ForAllChildren(cw , child)
969 {
970 if (!XtIsManaged(*child) &&
971 *child == cw->baseComp.current_focused)
972 {
973 ((MwBaseCompWidgetClass)w->core.widget_class)
974 ->baseComp_class.traverseOut(w);
975 }
976 }
977 }
978
979 }
980
981
GetInternalDimension(Widget w,Position * x,Position * y,Dimension * width,Dimension * height)982 static void GetInternalDimension(Widget w, Position *x, Position *y,
983 Dimension *width, Dimension *height)
984 {
985 MwBaseCompWidget cw = (MwBaseCompWidget) w;
986
987 switch (cw->baseComp.box_type)
988 {
989 case XtCno_box:
990 *x = cw->baseComp.bd_width;
991 *width = cw->core.width - 2 * cw->baseComp.bd_width;
992 *y = cw->baseComp.bd_width;
993 *height = cw->core.height - 2 * cw->baseComp.bd_width;
994 break;
995
996 case XtCsimple_box:
997 case XtCup_box:
998 case XtCdown_box:
999 *x = cw->baseComp.box_width + cw->baseComp.bd_width;
1000 *width = cw->core.width - 2 * cw->baseComp.box_width
1001 - 2 * cw->baseComp.bd_width;
1002 *y = cw->baseComp.box_width + cw->baseComp.bd_width;
1003 *height = cw->core.height - 2 * cw->baseComp.box_width
1004 - 2 * cw->baseComp.bd_width;
1005 break;
1006
1007 case XtCframein_box:
1008 case XtCframeout_box:
1009 *x = 2 * (cw->baseComp.box_width / 2) + cw->baseComp.bd_width;
1010 *y = 2 * (cw->baseComp.box_width / 2) + cw->baseComp.bd_width;
1011 *width = cw->core.width - 4 * (cw->baseComp.box_width /2)
1012 - 2 * cw->baseComp.bd_width;
1013 *height = cw->core.height - 4 * (cw->baseComp.box_width /2)
1014 - 2 * cw->baseComp.bd_width;
1015 break;
1016
1017 case XtCshadow_box:
1018 *x = cw->baseComp.box_width + cw->baseComp.bd_width;
1019 *y = cw->baseComp.box_width + cw->baseComp.bd_width;
1020 *width = cw->core.width - 4 * cw->baseComp.box_width
1021 - 2 * cw->baseComp.bd_width;
1022 *height = cw->core.height - 4 * cw->baseComp.box_width
1023 - 2 * cw->baseComp.bd_width;
1024 break;
1025 }
1026
1027 if (cw->baseComp.label)
1028 {
1029 *y += cw->baseComp.font->max_bounds.descent +
1030 cw->baseComp.font->max_bounds.ascent;
1031
1032 *height -= cw->baseComp.font->max_bounds.descent +
1033 cw->baseComp.font->max_bounds.ascent;
1034 }
1035 }
1036
SetInternalDimension(Widget w,Dimension width,Dimension height)1037 static void SetInternalDimension(Widget w, Dimension width, Dimension height)
1038 {
1039 MwBaseCompWidget cw = (MwBaseCompWidget) w;
1040
1041 switch (cw->baseComp.box_type)
1042 {
1043 case XtCno_box:
1044 cw->core.width = width + 2 * cw->baseComp.bd_width;
1045 cw->core.height = height + 2 * cw->baseComp.bd_width;
1046 break;
1047
1048 case XtCsimple_box:
1049 case XtCup_box:
1050 case XtCdown_box:
1051 cw->core.width = width + 2 * cw->baseComp.box_width
1052 + 2 * cw->baseComp.bd_width;
1053 cw->core.height = height + 2 * cw->baseComp.box_width
1054 + 2 * cw->baseComp.bd_width;
1055 break;
1056
1057 case XtCframein_box:
1058 case XtCframeout_box:
1059 cw->core.width = width + 4 * (cw->baseComp.box_width /2)
1060 + 2 * cw->baseComp.bd_width;
1061 cw->core.height = height + 4 * (cw->baseComp.box_width /2)
1062 + 2 * cw->baseComp.bd_width;
1063 break;
1064
1065 case XtCshadow_box:
1066 cw->core.width = width + 4 * cw->baseComp.box_width
1067 + 2 * cw->baseComp.bd_width;
1068 cw->core.height = height + 4 * cw->baseComp.box_width
1069 + 2 * cw->baseComp.bd_width;
1070 break;
1071 }
1072 if (cw->baseComp.label)
1073 {
1074 cw->core.height = cw->core.height +
1075 cw->baseComp.font->max_bounds.descent +
1076 cw->baseComp.font->max_bounds.ascent +
1077 2 * cw->baseComp.box_width;
1078 }
1079 }
1080
1081
ShowHelp(Widget w,XEvent * event,String * params,Cardinal * num_params)1082 static void ShowHelp(Widget w, XEvent *event,
1083 String *params, Cardinal *num_params)
1084 {
1085 MwBaseCompWidget cw = (MwBaseCompWidget) w;
1086
1087 if (cw->baseComp.help_text)
1088 {
1089 cw->baseComp.timer = XtAppAddTimeOut(XtWidgetToApplicationContext(
1090 (Widget)w),cw->baseComp.help_show_delay ,
1091 _ShowHelp , w);
1092 }
1093 }
1094
_ShowHelp(XtPointer client_data,XtIntervalId * timer)1095 static void _ShowHelp(XtPointer client_data, XtIntervalId *timer)
1096 {
1097 MwBaseCompWidget cw = (MwBaseCompWidget) client_data;
1098 Position x,y;
1099 Display *dpy = XtDisplay((Widget) cw);
1100 Dimension width,height,
1101 dwidth = DisplayWidth(dpy,DefaultScreen(dpy)) ,
1102 dheight = DisplayHeight(dpy,DefaultScreen(dpy)) ;
1103
1104 cw->baseComp.timer = (XtIntervalId) 0;
1105
1106 XtVaGetValues(cw->baseComp.hlp , XtNwidth , &width , XtNheight , &height , NULL);
1107
1108 XtTranslateCoords((Widget) cw , cw->core.width / 2 ,
1109 cw->core.height , &x ,&y);
1110
1111 if ( (x + width) > dwidth ) x = x - width;
1112
1113 if ( (y + height + 5) > dheight ) y = y - cw->core.height - 5 - height;
1114 else y = y + 5;
1115
1116 XtVaSetValues(cw->baseComp.hlp,XtNx,x,XtNy,y,NULL);
1117
1118 XtPopup(cw->baseComp.hlp,XtGrabNone);
1119
1120 }
1121
HideHelp(Widget w,XEvent * event,String * params,Cardinal * num_params)1122 static void HideHelp(Widget w, XEvent *event,
1123 String *params, Cardinal *num_params)
1124 {
1125 MwBaseCompWidget cw = (MwBaseCompWidget) w;
1126
1127 if (cw->baseComp.help_text)
1128 {
1129 XtPopdown(cw->baseComp.hlp);
1130 if (cw->baseComp.timer)
1131 XtRemoveTimeOut(cw->baseComp.timer);
1132 cw->baseComp.timer = (XtIntervalId) 0;
1133
1134 }
1135 }
1136
TraverseInside(Widget w,int where,Time * time)1137 static Widget TraverseInside(Widget w , int where , Time *time)
1138 {
1139 MwBaseCompWidget cw = (MwBaseCompWidget) w;
1140 int i;
1141
1142 switch (where)
1143 {
1144 case MW_TRAVERSE_FIRST:
1145 cw->baseComp.current_focused = NULL;
1146 for(i = 0 ; i < cw->composite.num_children ; i++)
1147 {
1148 MwSetTraverseDirection(cw->composite.children[i] , where);
1149 if (XtCallAcceptFocus(cw->composite.children[i] , time))
1150 {
1151 cw->baseComp.current_focused =
1152 cw->composite.children[i];
1153 break;
1154 }
1155 }
1156 break;
1157 case MW_TRAVERSE_LAST:
1158 cw->baseComp.current_focused = NULL;
1159 for(i = cw->composite.num_children - 1 ; i >= 0 ; i--)
1160 {
1161 MwSetTraverseDirection(cw->composite.children[i] , where);
1162 if (XtCallAcceptFocus(cw->composite.children[i] , time))
1163 {
1164 cw->baseComp.current_focused =
1165 cw->composite.children[i];
1166 break;
1167 }
1168 }
1169 break;
1170 case MW_TRAVERSE_PREV:
1171 if (cw->composite.num_children)
1172 {
1173 for(i = 0 ; (i < cw->composite.num_children) &&
1174 (cw->baseComp.current_focused !=
1175 cw->composite.children[i]) ; i++);
1176
1177 if (!(i < cw->composite.num_children) ||
1178 !cw->baseComp.current_focused)
1179 {
1180 cw->baseComp.current_focused = NULL;
1181 for(i = cw->composite.num_children - 1 ; i >= 0 ; i--)
1182 {
1183 MwSetTraverseDirection(cw->composite.children[i] , where);
1184 if (XtCallAcceptFocus(cw->composite.children[i] , time))
1185 {
1186 cw->baseComp.current_focused =
1187 cw->composite.children[i];
1188 break;
1189 }
1190 }
1191 }
1192 else
1193 {
1194 cw->baseComp.current_focused = NULL;
1195 for( i = i - 1 ; i >= 0 ; i--)
1196 {
1197 MwSetTraverseDirection(cw->composite.children[i] , where);
1198 if (XtCallAcceptFocus(cw->composite.children[i] , time))
1199 {
1200 cw->baseComp.current_focused =
1201 cw->composite.children[i];
1202 break;
1203 }
1204 }
1205 }
1206 }
1207 else
1208 {
1209 cw->baseComp.current_focused = NULL;
1210 }
1211 break;
1212 case MW_TRAVERSE_NEXT:
1213 if (cw->composite.num_children)
1214 {
1215 for(i = 0 ; (i < cw->composite.num_children) &&
1216 (cw->baseComp.current_focused !=
1217 cw->composite.children[i]) ; i++);
1218
1219 if (!(i < cw->composite.num_children) ||
1220 !cw->baseComp.current_focused)
1221 {
1222 cw->baseComp.current_focused = NULL;
1223 for(i = 0 ; i < cw->composite.num_children ; i++)
1224 {
1225 MwSetTraverseDirection(cw->composite.children[i] , where);
1226 if (XtCallAcceptFocus(cw->composite.children[i] , time))
1227 {
1228 cw->baseComp.current_focused =
1229 cw->composite.children[i];
1230 break;
1231 }
1232 }
1233 }
1234 else
1235 {
1236 cw->baseComp.current_focused = NULL;
1237 for ( i = i + 1 ; i < cw->composite.num_children ; i++)
1238 {
1239 MwSetTraverseDirection(cw->composite.children[i] , where);
1240 if (XtCallAcceptFocus(cw->composite.children[i] , time))
1241 {
1242 cw->baseComp.current_focused =
1243 cw->composite.children[i];
1244 break;
1245 }
1246 }
1247 }
1248 }
1249 else
1250 {
1251 cw->baseComp.current_focused = NULL;
1252 }
1253 break;
1254 case MW_TRAVERSE_ACTUAL:
1255 if (cw->composite.num_children)
1256 {
1257 for(i = 0 ; i < cw->composite.num_children &&
1258 cw->baseComp.current_focused !=
1259 cw->composite.children[i] ; i++);
1260
1261 if (i < cw->composite.num_children &&
1262 cw->baseComp.current_focused)
1263 {
1264 MwSetTraverseDirection(cw->composite.children[i] , where);
1265 XtCallAcceptFocus(cw->composite.children[i] , time);
1266 }
1267 }
1268 else
1269 {
1270 cw->baseComp.current_focused = NULL;
1271 }
1272 break;
1273 default: XtWarning("Unknown direction");
1274 }
1275
1276 return cw->baseComp.current_focused;
1277 }
1278
Traverse(Widget w,int where,Time * time)1279 static Widget Traverse(Widget w , int where , Time *time)
1280 {
1281 MwBaseCompWidget cw = (MwBaseCompWidget) w;
1282 Widget parent = XtParent(w);
1283 Widget cld;
1284
1285 cld = ((MwBaseCompWidgetClass)w->core.widget_class)->
1286 baseComp_class.traverseInside(w , where , time);
1287
1288 if (cld)
1289 {
1290 TraverseTo(w , cld , time);
1291 }
1292 else
1293 {
1294 switch (where)
1295 {
1296 case MW_TRAVERSE_FIRST:
1297 if (XtIsSubclass(parent, mwBaseCompWidgetClass))
1298 ((MwBaseCompWidgetClass)parent->core.widget_class)->
1299 baseComp_class.traverse(parent ,
1300 MW_TRAVERSE_PREV , time);
1301 else if (XtIsSubclass(parent, mwBaseConstWidgetClass))
1302 ((MwBaseConstWidgetClass)parent->core.widget_class)->
1303 baseConst_class.traverse(parent ,
1304 MW_TRAVERSE_PREV , time);
1305 break;
1306 case MW_TRAVERSE_LAST:
1307 if (XtIsSubclass(parent, mwBaseCompWidgetClass))
1308 ((MwBaseCompWidgetClass)parent->core.widget_class)->
1309 baseComp_class.traverse(parent ,
1310 MW_TRAVERSE_NEXT , time);
1311 else if (XtIsSubclass(parent, mwBaseConstWidgetClass))
1312 ((MwBaseConstWidgetClass)parent->core.widget_class)->
1313 baseConst_class.traverse(parent ,
1314 MW_TRAVERSE_NEXT , time);
1315 break;
1316 case MW_TRAVERSE_PREV:
1317 if (XtIsSubclass(parent, mwBaseCompWidgetClass))
1318 ((MwBaseCompWidgetClass)parent->core.widget_class)->
1319 baseComp_class.traverse(parent ,
1320 MW_TRAVERSE_PREV , time);
1321 else if (XtIsSubclass(parent, mwBaseConstWidgetClass))
1322 ((MwBaseConstWidgetClass)parent->core.widget_class)->
1323 baseConst_class.traverse(parent ,
1324 MW_TRAVERSE_PREV , time);
1325 else ((MwBaseCompWidgetClass)cw->core.widget_class)->
1326 baseComp_class.traverse(w ,
1327 MW_TRAVERSE_LAST , time);
1328 break;
1329 case MW_TRAVERSE_NEXT:
1330 if (XtIsSubclass(parent, mwBaseCompWidgetClass))
1331 ((MwBaseCompWidgetClass)parent->core.widget_class)->
1332 baseComp_class.traverse(parent ,
1333 MW_TRAVERSE_NEXT , time);
1334 else if (XtIsSubclass(parent, mwBaseConstWidgetClass))
1335 ((MwBaseConstWidgetClass)parent->core.widget_class)->
1336 baseConst_class.traverse(parent ,
1337 MW_TRAVERSE_NEXT , time);
1338 else ((MwBaseCompWidgetClass)cw->core.widget_class)->
1339 baseComp_class.traverse(w ,
1340 MW_TRAVERSE_FIRST , time);
1341 break;
1342 case MW_TRAVERSE_ACTUAL:
1343 break;
1344 default: XtWarning("Unknown direction");
1345 }
1346 }
1347
1348 return cw->baseComp.current_focused;
1349 }
1350
TraverseTo(Widget w,Widget child,Time * time)1351 static void TraverseTo(Widget w , Widget child , Time *time)
1352 {
1353 MwBaseCompWidget cw = (MwBaseCompWidget) w;
1354 Widget parent = XtParent(w);
1355 Widget cld = cw->baseComp.current_focused;
1356
1357 cw->baseComp.current_focused = child;
1358
1359 if (cld != child)
1360 {
1361 if (cld)
1362 {
1363 if (XtIsSubclass(cld , mwBaseCompWidgetClass))
1364 ((MwBaseCompWidgetClass)cld->core.widget_class)->
1365 baseComp_class.traverseOut(cld);
1366 else if (XtIsSubclass(cld , mwBaseConstWidgetClass))
1367 ((MwBaseConstWidgetClass)cld->core.widget_class)->
1368 baseConst_class.traverseOut(cld);
1369 }
1370 }
1371
1372 if (XtIsSubclass(parent, mwBaseCompWidgetClass))
1373 ((MwBaseCompWidgetClass)parent->core.widget_class)->baseComp_class.
1374 traverseTo(parent , w , time);
1375 else if (XtIsSubclass(parent, mwBaseConstWidgetClass))
1376 ((MwBaseConstWidgetClass)parent->core.widget_class)->baseConst_class.
1377 traverseTo(parent , w , time);
1378
1379 }
1380
TraverseOut(Widget w)1381 static void TraverseOut(Widget w)
1382 {
1383 MwBaseCompWidget cw = (MwBaseCompWidget) w;
1384 Widget cld = cw->baseComp.current_focused;
1385
1386
1387 if (cld)
1388 {
1389 if (XtIsSubclass(cld , mwBaseCompWidgetClass))
1390 ((MwBaseCompWidgetClass)cld->core.widget_class)->
1391 baseComp_class.traverseOut(cld);
1392 else if (XtIsSubclass(cld, mwBaseConstWidgetClass))
1393 ((MwBaseConstWidgetClass)cld->core.widget_class)->
1394 baseConst_class.traverseOut(cld);
1395 }
1396
1397 cw->baseComp.current_focused = NULL;
1398 }
1399
1400
AcceptFocus(Widget w,Time * time)1401 static Boolean AcceptFocus(Widget w , Time *time)
1402 {
1403 MwBaseCompWidget cw = (MwBaseCompWidget) w;
1404
1405 if (!XtIsRealized(w) || !XtIsSensitive(w) || !cw->core.visible ||
1406 !cw->core.ancestor_sensitive || cw->core.being_destroyed ||
1407 !XtIsManaged(w))
1408 return False;
1409
1410 if (cw->baseComp.traverse)
1411 {
1412 if (cw->baseComp.current_focused)
1413 {
1414 return (((MwBaseCompWidgetClass)cw->core.widget_class)->
1415 baseComp_class.traverseInside(w , MW_TRAVERSE_ACTUAL , time) != NULL);
1416 }
1417 else
1418 {
1419 return (((MwBaseCompWidgetClass)cw->core.widget_class)->
1420 baseComp_class.traverseInside(w ,
1421 cw->baseComp.traverse_direction , time) != NULL);
1422 }
1423 }
1424 else
1425 {
1426 if (Xt_IsUp(w))
1427 {
1428 XSetInputFocus(XtDisplay(w), XtWindow(w), RevertToParent , *time);
1429 ((MwBaseCompWidgetClass)cw->core.widget_class)
1430 ->baseComp_class.highlightBorder(w);
1431 }
1432 return True;
1433 }
1434 }
1435
1436 #define focus_detail(detail) (detail ==NotifyAncestor ?"NotifyAncestor":detail ==NotifyVirtual ?"NotifyVirtual":detail ==NotifyInferior ?"NotifyInferior":detail ==NotifyNonlinear ?"NotifyNonlinear":detail ==NotifyNonlinearVirtual ?"NotifyNonlinearVirtual":detail ==NotifyPointer ?"NotifyPointer":detail ==NotifyPointerRoot ?"NotifyPointerRoot":detail ==NotifyDetailNone ?"NotifyDetailNone":"???")
1437
_FocusIn(Widget w,XEvent * event,String * params,Cardinal * num_params)1438 static void _FocusIn(Widget w, XEvent *event,
1439 String *params, Cardinal *num_params)
1440 {
1441 MwBaseCompWidget cw = (MwBaseCompWidget) w;
1442 MwBaseCompWidgetClass wclass = (MwBaseCompWidgetClass) cw->core.widget_class;
1443 Time time = CurrentTime;
1444
1445 if (event->xfocus.detail == NotifyNonlinear ||
1446 event->xfocus.detail == NotifyAncestor ||
1447 event->xfocus.detail == NotifyInferior)
1448 {
1449 if (cw->baseComp.traverse)
1450 {
1451 if (cw->baseComp.current_focused)
1452 {
1453 ((MwBaseCompWidgetClass)cw->core.widget_class)->
1454 baseComp_class.
1455 traverseInside(w , MW_TRAVERSE_ACTUAL , &time);
1456 }
1457 else
1458 {
1459 ((MwBaseCompWidgetClass)cw->core.widget_class)->
1460 baseComp_class.traverseInside(w ,
1461 cw->baseComp.traverse_direction , &time);
1462 }
1463 }
1464 else
1465 {
1466 wclass->baseComp_class.highlightBorder(w);
1467 cw->baseComp.focused = True;
1468 }
1469 }
1470 }
1471
_FocusOut(Widget w,XEvent * event,String * params,Cardinal * num_params)1472 static void _FocusOut(Widget w, XEvent *event,
1473 String *params, Cardinal *num_params)
1474 {
1475 MwBaseCompWidget cw = (MwBaseCompWidget) w;
1476 MwBaseCompWidgetClass wclass = (MwBaseCompWidgetClass) cw->core.widget_class;
1477
1478 if (cw->baseComp.focused)
1479 {
1480 wclass->baseComp_class.unhighlightBorder(w);
1481 cw->baseComp.focused = False;
1482 }
1483
1484 }
1485
HighlightBorder(Widget w)1486 static void HighlightBorder(Widget w)
1487 {
1488 MwBaseCompWidget cw = (MwBaseCompWidget) w;
1489
1490 X_DrawSimpleRawFrame(XtDisplay(w) , XtWindow(w) , 0 , 0 , cw->core.width ,
1491 cw->core.height , cw->baseComp.bd_width , cw->baseComp.bd_color);
1492 }
1493
UnhighlightBorder(Widget w)1494 static void UnhighlightBorder(Widget w)
1495 {
1496 MwBaseCompWidget cw = (MwBaseCompWidget) w;
1497
1498 X_DrawSimpleRawFrame(XtDisplay(w) , XtWindow(w) , 0 , 0 , cw->core.width ,
1499 cw->core.height , cw->baseComp.bd_width , cw->core.background_pixel);
1500 }
1501
FocusCurrent(Widget w,XEvent * event,String * params,Cardinal * num_params)1502 static void FocusCurrent(Widget w, XEvent *event,
1503 String *params, Cardinal *num_params)
1504 {
1505 MwBaseCompWidget cw = (MwBaseCompWidget) w;
1506 Widget parent = XtParent(w);
1507
1508 if (cw->baseComp.focused) return;
1509
1510 if (XtCallAcceptFocus(w , &event->xbutton.time))
1511 {
1512 if (XtIsSubclass(parent, mwBaseCompWidgetClass))
1513 ((MwBaseCompWidgetClass)parent->core.widget_class)->baseComp_class.
1514 traverseTo(parent , w , &event->xbutton.time);
1515 else if (XtIsSubclass(parent, mwBaseConstWidgetClass))
1516 ((MwBaseConstWidgetClass)parent->core.widget_class)->baseConst_class.
1517 traverseTo(parent , w , &event->xbutton.time);
1518 }
1519 }
1520
TraverseForward(Widget w,XEvent * event,String * params,Cardinal * num_params)1521 static void TraverseForward(Widget w, XEvent *event,
1522 String *params, Cardinal *num_params)
1523 {
1524 Widget parent = XtParent(w);
1525
1526 if (XtIsSubclass(parent, mwBaseCompWidgetClass))
1527 ((MwBaseCompWidgetClass)parent->core.widget_class)->baseComp_class.
1528 traverse(parent , MW_TRAVERSE_NEXT , &event->xkey.time);
1529 else if (XtIsSubclass(parent, mwBaseConstWidgetClass))
1530 ((MwBaseConstWidgetClass)parent->core.widget_class)->baseConst_class.
1531 traverse(parent , MW_TRAVERSE_NEXT , &event->xkey.time);
1532
1533 }
1534
TraverseBackward(Widget w,XEvent * event,String * params,Cardinal * num_params)1535 static void TraverseBackward(Widget w, XEvent *event,
1536 String *params, Cardinal *num_params)
1537 {
1538 Widget parent = XtParent(w);
1539
1540 if (XtIsSubclass(parent, mwBaseCompWidgetClass))
1541 ((MwBaseCompWidgetClass)parent->core.widget_class)->baseComp_class.
1542 traverse(parent , MW_TRAVERSE_PREV , &event->xkey.time);
1543 else if (XtIsSubclass(parent, mwBaseConstWidgetClass))
1544 ((MwBaseConstWidgetClass)parent->core.widget_class)->baseConst_class.
1545 traverse(parent , MW_TRAVERSE_PREV , &event->xkey.time);
1546 }
1547