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