1 /*************************************<+>*************************************
2  *****************************************************************************
3  **
4  **   File:        Primitive.c
5  **
6  **   Project:     X Widgets
7  **
8  **   Description: This file contains source for the Primitive Meta Widget.
9  **
10  *****************************************************************************
11  **
12  **   Copyright (c) 1988 by Hewlett-Packard Company
13  **   Copyright (c) 1988 by the Massachusetts Institute of Technology
14  **
15  **   Permission to use, copy, modify, and distribute this software
16  **   and its documentation for any purpose and without fee is hereby
17  **   granted, provided that the above copyright notice appear in all
18  **   copies and that both that copyright notice and this permission
19  **   notice appear in supporting documentation, and that the names of
20  **   Hewlett-Packard or  M.I.T.  not be used in advertising or publicity
21  **   pertaining to distribution of the software without specific, written
22  **   prior permission.
23  **
24  *****************************************************************************
25  *************************************<+>*************************************/
26 
27 
28 #include <stdio.h>
29 #include <string.h>
30 #include <ctype.h>
31 #include <X11/IntrinsicP.h>
32 #include <X11/Intrinsic.h>
33 #include <Xw/Xw.h>
34 #include <Xw/XwP.h>
35 #include <Xw/MenuBtn.h>
36 #include <X11/StringDefs.h>
37 
38 
39 
40 /*************************************<->*************************************
41  *
42  *
43  *   Description:  default translation table for class: Primitive.
44  *   -----------
45  *
46  *   These translations will be compiled at class initialize.  When
47  *   a subclass of primitive is created then these translations will
48  *   be used to augment the translations of the subclass IFF
49  *   traversal is on.  The SetValues routine will also augment
50  *   a subclass's translations table IFF traversal goes from off to on.
51  *   Since we are augmenting it should not be a problem when
52  *   traversal goes from off to on to off and on again.
53  *
54  *************************************<->***********************************/
55 
56 static char defaultTranslations[] =
57    "<FocusIn>:              focusIn() \n\
58     <FocusOut>:             focusOut() \n\
59     <Visible>:         visibility() \n\
60     <Unmap>:           unmap()";
61 
62 
63 /*************************************<->*************************************
64  *
65  *
66  *   Description:  action list for class: Primtive
67  *   -----------
68  *   Used to provide actions for subclasses with traversal on.
69  *
70  *************************************<->***********************************/
71 
72 static XtActionsRec actionsList[] =
73 {
74   {"focusIn", (XtActionProc) _XwPrimitiveFocusIn},
75   {"focusOut", (XtActionProc) _XwPrimitiveFocusOut},
76   {"visibility", (XtActionProc) _XwPrimitiveVisibility},
77   {"unmap", (XtActionProc) _XwPrimitiveUnmap},
78 };
79 
80 
81 /*  Resource definitions for Subclasses of Primitive */
82 
83 static Cursor defaultCursor = None;
84 
85 static XtResource resources[] =
86 {
87    {
88      XtNforeground, XtCForeground, XtRPixel, sizeof (Pixel),
89      XtOffset (XwPrimitiveWidget, primitive.foreground),
90      XtRString, "XtDefaultForeground"
91    },
92 
93    {
94      XtNbackgroundTile, XtCBackgroundTile, XtRTileType, sizeof (int),
95      XtOffset (XwPrimitiveWidget, primitive.background_tile),
96      XtRString, "background"
97    },
98 
99    {
100      XtNcursor, XtCCursor, XtRCursor, sizeof (Cursor),
101      XtOffset (XwPrimitiveWidget, primitive.cursor),
102      XtRCursor, (caddr_t) &defaultCursor
103    },
104 
105    {
106      XtNtraversalType, XtCTraversalType, XtRTraversalType, sizeof (int),
107      XtOffset (XwPrimitiveWidget, primitive.traversal_type),
108      XtRString, "highlight_off"
109    },
110 
111    {
112      XtNhighlightThickness, XtCHighlightThickness, XtRInt, sizeof (int),
113      XtOffset (XwPrimitiveWidget, primitive.highlight_thickness),
114      XtRString, "0"
115    },
116 
117    {
118      XtNhighlightStyle, XtCHighlightStyle, XtRHighlightStyle, sizeof (int),
119      XtOffset (XwPrimitiveWidget, primitive.highlight_style),
120      XtRString, "pattern_border"
121    },
122 
123    {
124      XtNhighlightColor, XtCForeground, XtRPixel, sizeof (Pixel),
125      XtOffset (XwPrimitiveWidget, primitive.highlight_color),
126      XtRString, "Black"
127    },
128 
129    {
130      XtNhighlightTile, XtCHighlightTile, XtRTileType, sizeof (int),
131      XtOffset (XwPrimitiveWidget, primitive.highlight_tile),
132      XtRString, "foreground"
133    },
134 
135    {
136      XtNrecomputeSize, XtCRecomputeSize, XtRBoolean, sizeof(Boolean),
137      XtOffset (XwPrimitiveWidget, primitive.recompute_size),
138      XtRString, "True"
139    },
140 
141    {
142      XtNselect, XtCCallback, XtRCallback, sizeof(caddr_t),
143      XtOffset (XwPrimitiveWidget, primitive.select),
144      XtRPointer, (caddr_t) NULL
145    },
146 
147    {
148      XtNrelease, XtCCallback, XtRCallback, sizeof(caddr_t),
149      XtOffset (XwPrimitiveWidget, primitive.release),
150      XtRPointer, (caddr_t) NULL
151    },
152 };
153 
154 
155 
156 /*  Routine definiton used for initializing the class record.  */
157 
158 static void              ClassInitialize();
159 static void   ClassPartInitialize();
160 static void          Initialize();
161 static void        Realize();
162 static void        Destroy();
163 static Boolean     SetValues();
164 
165 static void GetHighlightGC();
166 
167 
168 
169 /*  The primitive class record definition  */
170 
171 XwPrimitiveClassRec XwprimitiveClassRec =
172 {
173    {
174       (WidgetClass) &widgetClassRec,    /* superclass	         */
175       "XwPrimitive",                    /* class_name	         */
176       sizeof(XwPrimitiveRec),           /* widget_size	         */
177       (XtProc) ClassInitialize,         /* class_initialize      */
178       (XtWidgetClassProc) ClassPartInitialize, /* class_part_initialize */
179       FALSE,                            /* class_inited          */
180       (XtInitProc) Initialize,          /* initialize	         */
181       NULL,                             /* initialize_hook       */
182       (XtRealizeProc) Realize,          /* realize	         */
183       actionsList,                      /* actions               */
184       XtNumber(actionsList),            /* num_actions	         */
185       resources,                        /* resources	         */
186       XtNumber(resources),              /* num_resources         */
187       NULLQUARK,                        /* xrm_class	         */
188       TRUE,                             /* compress_motion       */
189       TRUE,                             /* compress_exposure     */
190       TRUE,                             /* compress_enterleave   */
191       FALSE,                            /* visible_interest      */
192       (XtWidgetProc) Destroy,           /* destroy               */
193       NULL,                             /* resize                */
194       NULL,                             /* expose                */
195       (XtSetValuesFunc) SetValues,      /* set_values	         */
196       NULL,                             /* set_values_hook       */
197       XtInheritSetValuesAlmost,         /* set_values_almost     */
198       NULL,                             /* get_values_hook       */
199       NULL,                             /* accept_focus	         */
200       XtVersion,                        /* version               */
201       NULL,                             /* callback private      */
202       NULL,                             /* tm_table              */
203       NULL,                             /* query_geometry        */
204     /* display_accelerator	*/	XtInheritDisplayAccelerator,
205     /* extension		*/	NULL
206    },
207 
208    {
209       NULL,         /* Primitive border_highlight   */
210       NULL,         /* Primitive border_unhighlight */
211       NULL,         /* Primitive select_proc        */
212       NULL,         /* Primitive release_proc       */
213       NULL,         /* Primitive toggle_proc        */
214       NULL,         /* default translations         */
215    }
216 };
217 
218 WidgetClass XwprimitiveWidgetClass = (WidgetClass) &XwprimitiveClassRec;
219 
220 
221 
222 /************************************************************************
223  *
224  *  ClassInitialize
225  *    Initialize the primitive class structure.  This is called only
226  *    the first time a primitive widget is created.  It registers the
227  *    resource type converters unique to this class.
228  *
229  *
230  * After class init, the "translations" variable will contain the compiled
231  * translations to be used to augment a widget's translation
232  * table if they wish to have keyboard traversal on.
233  *
234  ************************************************************************/
235 
ClassInitialize()236 static void ClassInitialize()
237 {
238    XwRegisterConverters();
239    XwprimitiveClassRec.primitive_class.translations =
240      XtParseTranslationTable(defaultTranslations);
241 }
242 
243 
244 
245 
246 /************************************************************************
247  *
248  *  ClassPartInitialize
249  *    Set up the inheritance mechanism for the routines exported by
250  *    primitives class part.
251  *
252  ************************************************************************/
253 
ClassPartInitialize(w)254 static void ClassPartInitialize (w)
255 WidgetClass w;
256 
257 {
258     register XwPrimitiveWidgetClass wc = (XwPrimitiveWidgetClass) w;
259     register XwPrimitiveWidgetClass super =
260 	    (XwPrimitiveWidgetClass) wc->core_class.superclass;
261 
262     if (wc -> primitive_class.border_highlight == XtInheritBorderHighlight)
263 	wc -> primitive_class.border_highlight =
264 	   super -> primitive_class.border_highlight;
265 
266     if (wc->primitive_class.border_unhighlight == XtInheritBorderUnhighlight)
267 	wc -> primitive_class.border_unhighlight =
268 	   super -> primitive_class.border_unhighlight;
269 
270     if (wc -> primitive_class.select_proc == XtInheritSelectProc)
271 	wc -> primitive_class.select_proc =
272 	   super -> primitive_class.select_proc;
273 
274     if (wc -> primitive_class.release_proc == XtInheritReleaseProc)
275 	wc -> primitive_class.release_proc =
276 	   super -> primitive_class.release_proc;
277 
278     if (wc -> primitive_class.toggle_proc == XtInheritToggleProc)
279 	wc -> primitive_class.toggle_proc =
280 	   super -> primitive_class.toggle_proc;
281 }
282 
283 
284 
285 
286 
287 /************************************************************************
288  *
289  *  GetHighlightGC
290  *     Get the graphics context used for drawing the border.
291  *
292  ************************************************************************/
293 
GetHighlightGC(pw)294 static void GetHighlightGC (pw)
295 XwPrimitiveWidget pw;
296 
297 {
298    XGCValues values;
299    XtGCMask  valueMask;
300 
301    valueMask = GCForeground | GCBackground;
302    values.foreground = pw -> primitive.highlight_color;
303    values.background = pw -> core.background_pixel;
304 
305    if (pw -> primitive.highlight_tile == XwBACKGROUND)
306    {
307       values.foreground = pw -> core.background_pixel;
308       values.background = pw -> primitive.highlight_color;
309    }
310 
311    pw -> primitive.highlight_GC = XtGetGC ((Widget) pw, valueMask, &values);
312 }
313 
314 
315 
316 
317 
318 /************************************************************************
319  *
320  *  Initialize
321  *     The main widget instance initialization routine.
322  *
323  ************************************************************************/
324 
Initialize(request,new)325 static void Initialize (request, new)
326 XwPrimitiveWidget request, new;
327 
328 {
329    XwPrimitiveWidget pw = (XwPrimitiveWidget) new;
330    Arg args[1];
331 
332 
333    /* initialize traversal flag */
334 
335    pw->primitive.I_have_traversal = FALSE;
336 
337 
338    /*  Check the pw widget for invalid data  */
339 
340    if (pw -> primitive.traversal_type != XwHIGHLIGHT_OFF      &&
341        pw -> primitive.traversal_type != XwHIGHLIGHT_ENTER    &&
342        pw -> primitive.traversal_type != XwHIGHLIGHT_TRAVERSAL)
343    {
344       XtWarning ("Primitive: Incorrect traversal type");
345       pw -> primitive.traversal_type = XwHIGHLIGHT_OFF;
346    }
347 
348    if (pw -> primitive.highlight_style != XwPATTERN_BORDER &&
349        pw -> primitive.highlight_style != XwWIDGET_DEFINED)
350    {
351       XtWarning("Primitive: Incorrect highlight style.");
352       pw -> primitive.highlight_style = XwPATTERN_BORDER;
353    }
354 
355    if (pw -> primitive.highlight_tile != XwFOREGROUND)
356    {
357       XtWarning("Primitive: Incorrect highlight tile.");
358       pw -> primitive.highlight_tile = XwFOREGROUND;
359    }
360 
361    if (pw -> primitive.highlight_thickness < 0)
362    {
363       XtWarning("Primitive: Invalid highlight thickness.");
364       pw -> primitive.highlight_thickness = 0;
365    }
366 
367    if (pw -> primitive.background_tile != XwBACKGROUND)
368    {
369       XtWarning("Primitive: Incorrect background tile.");
370       pw -> primitive.background_tile = XwBACKGROUND;
371    }
372 
373 
374    /*  Check the geometry information for the widget  */
375 
376    if (request -> core.width == 0)
377       pw -> core.width += pw -> primitive.highlight_thickness * 2;
378    else if (request -> core.width < pw -> primitive.highlight_thickness * 2)
379    {
380       pw -> primitive.highlight_thickness = request -> core.width / 2;
381    }
382 
383    if (request -> core.height == 0)
384       pw -> core.height += pw -> primitive.highlight_thickness * 2;
385    else if (request -> core.height < pw -> primitive.highlight_thickness * 2)
386    {
387       pw -> primitive.highlight_thickness = request -> core.height / 2;
388    }
389 
390 
391    /*  Get the graphics contexts for the border drawing  */
392 
393    GetHighlightGC (pw);
394 
395    /*  Set some additional fields of the widget  */
396 
397    pw -> primitive.display_sensitive = FALSE;
398    pw -> primitive.highlighted = FALSE;
399    pw -> primitive.display_highlighted = FALSE;
400 
401    /* If this widget is requesting traversal then augment its
402     * translation table with some additional events.
403     */
404    if (pw->primitive.traversal_type == XwHIGHLIGHT_TRAVERSAL)
405      {
406       XtAugmentTranslations((Widget) pw,
407 			    XwprimitiveClassRec.primitive_class.translations);
408       pw->core.widget_class->core_class.visible_interest = True;
409     }
410 
411 }
412 
413 
414 
415 /************************************************************************
416  *
417  *  Realize
418  *
419  ************************************************************************/
420 
Realize(widget,value_mask,attributes)421 static void Realize (widget, value_mask, attributes)
422     Widget		 widget;
423     Mask		 *value_mask;
424     XSetWindowAttributes *attributes;
425 {
426     XwPrimitiveWidget pw = (XwPrimitiveWidget) widget;
427 
428     if (pw -> primitive.cursor != None) *value_mask |= CWCursor;
429 
430     attributes->cursor = pw->primitive.cursor;
431 
432     XtCreateWindow(widget, (unsigned int) InputOutput,
433 		   (Visual *) CopyFromParent, *value_mask, attributes);
434 }
435 
436 
437 /************************************************************************
438  *
439  *  Destroy
440  *	Clean up allocated resources when the widget is destroyed.
441  *
442  ************************************************************************/
443 
Destroy(pw)444 static void Destroy (pw)
445 XwPrimitiveWidget pw;
446 {
447    XwManagerWidget parent;
448 
449    XtRemoveCallbacks ((Widget)pw, XtNselect, pw -> primitive.select);
450    XtRemoveCallbacks ((Widget)pw, XtNrelease, pw -> primitive.release);
451    if (pw->primitive.I_have_traversal)
452       XwProcessTraversal (pw, XwTRAVERSE_HOME, TRUE);
453    else if ((XtIsSubclass((Widget)(parent = (XwManagerWidget)XtParent(pw)),
454             XwmanagerWidgetClass)) &&
455            (parent->manager.traversal_on) &&
456            (parent->manager.active_child == (Widget)pw))
457    {
458       parent->manager.active_child = NULL;
459 
460       /* Find the top most manager */
461       while ((parent->core.parent != NULL) &&
462              (XtIsSubclass(parent->core.parent, XwmanagerWidgetClass)))
463          parent = (XwManagerWidget)parent->core.parent;
464 
465       /* Clear the toolkit kbd focus from us */
466       XtSetKeyboardFocus((Widget)parent, NULL);
467    }
468 }
469 
470 
471 
472 
473 /************************************************************************
474  *
475  *  SetValues
476  *     Perform and updating necessary for a set values call.
477  *
478  ************************************************************************/
479 
SetValues(current,request,new)480 static Boolean SetValues (current, request, new)
481 Widget current, request, new;
482 
483 {
484    Boolean tempSensitive, tempAnSensitive;
485    int tempTrav;
486 
487    XwPrimitiveWidget curpw = (XwPrimitiveWidget) current;
488    XwPrimitiveWidget reqpw = (XwPrimitiveWidget) request;
489    XwPrimitiveWidget newpw = (XwPrimitiveWidget) new;
490    Boolean returnFlag = FALSE;
491    int     difference;
492 
493 
494    /*  Verify correct new values.  */
495 
496    if (newpw->primitive.traversal_type != XwHIGHLIGHT_OFF      &&
497        newpw->primitive.traversal_type != XwHIGHLIGHT_ENTER    &&
498        newpw->primitive.traversal_type != XwHIGHLIGHT_TRAVERSAL)
499    {
500       XtWarning("Primitive: Incorrect traversal type.");
501       newpw->primitive.traversal_type = curpw->primitive.traversal_type;
502    }
503 
504 
505    /*  If traversal has been turned on, then augment the translations  */
506    /*  of the new widget.                                              */
507 
508    if ((newpw->primitive.traversal_type != curpw->primitive.traversal_type)
509         && (newpw->primitive.traversal_type == XwHIGHLIGHT_TRAVERSAL))
510      {
511          /* XXX this was a hard bug!  where were the XXX's?
512           *
513           * In R2 we could not pass newpw to this toolkit call!  But I
514           * have found the bug!!!!  In R2 it was a temporary structure (stack)
515           * but now curmw is the temporary one and newpw is real!
516           * I can see why they were worried before.  Now there is no worry.
517           * Go ahead and pass newpw!
518           */
519          XtAugmentTranslations((Widget) newpw,
520 		 XwprimitiveClassRec.primitive_class.translations);
521 	 newpw->core.widget_class->core_class.visible_interest = True;
522      }
523 
524 
525    /* IF we have the traversal and something is happening to
526     * make that not possible then move it somewhere else!
527     */
528 
529      if (((curpw->core.sensitive != newpw->core.sensitive) ||
530         (curpw->core.ancestor_sensitive != newpw->core.ancestor_sensitive) ||
531         (newpw->primitive.traversal_type != curpw->primitive.traversal_type))
532         && (curpw->primitive.I_have_traversal))
533      {
534           newpw->primitive.highlighted = FALSE;
535 
536           tempTrav= curpw->primitive.traversal_type;
537           tempSensitive = curpw->core.sensitive;
538           tempAnSensitive = curpw->core.ancestor_sensitive;
539 
540           curpw->primitive.traversal_type = newpw->primitive.traversal_type;
541           curpw->core.ancestor_sensitive = newpw->core.ancestor_sensitive;
542           curpw->core.sensitive = newpw->core.sensitive;
543 
544           XwProcessTraversal (curpw, XwTRAVERSE_HOME, FALSE);
545 
546           curpw->primitive.traversal_type = tempTrav;
547           curpw->core.sensitive = tempSensitive;
548           curpw->core.ancestor_sensitive = tempAnSensitive;
549 
550         returnFlag = TRUE;
551      }
552 
553 
554    if (newpw->primitive.highlight_style != XwPATTERN_BORDER &&
555        newpw->primitive.highlight_style != XwWIDGET_DEFINED)
556    {
557       XtWarning ("Primitive: Incorrect highlight style.");
558       newpw->primitive.highlight_style = curpw->primitive.highlight_style;
559    }
560 
561    if (newpw -> primitive.highlight_tile != XwFOREGROUND)
562    {
563       XtWarning ("Primitive: Incorrect highlight tile.");
564       newpw->primitive.highlight_tile = curpw->primitive.highlight_tile;
565    }
566 
567    if (newpw->primitive.highlight_thickness < 0)
568    {
569       XtWarning ("Primtive: Invalid highlight thickness.");
570       newpw -> primitive.highlight_thickness =
571 	 curpw -> primitive.highlight_thickness;
572    }
573 
574 
575    if (newpw -> primitive.background_tile != XwBACKGROUND)
576    {
577       XtWarning("Primitive: Incorrect background tile.");
578       newpw -> primitive.background_tile =
579          curpw -> primitive.background_tile;
580    }
581 
582 
583    /*  Set the widgets background tile  */
584 
585    if (newpw -> primitive.background_tile !=
586        curpw -> primitive.background_tile     ||
587        newpw -> primitive.foreground !=
588        curpw -> primitive.foreground          ||
589        newpw -> core.background_pixel !=
590        curpw -> core.background_pixel)
591    {
592       Mask valueMask;
593       XSetWindowAttributes attributes;
594 
595       if (newpw -> primitive.background_tile == XwFOREGROUND)
596       {
597          valueMask = CWBackPixel;
598          attributes.background_pixel = newpw -> primitive.foreground;
599       }
600       else
601       {
602          valueMask = CWBackPixel;
603          attributes.background_pixel = newpw -> core.background_pixel;
604       }
605 
606       if (XtIsRealized ((Widget)newpw))
607          XChangeWindowAttributes (XtDisplay(newpw), newpw -> core.window,
608                                   valueMask, &attributes);
609 
610       returnFlag = TRUE;
611    }
612 
613    if (newpw -> primitive.cursor != curpw -> primitive.cursor) {
614        Mask valueMask = 0;
615        XSetWindowAttributes attributes;
616 
617        if (newpw->primitive.cursor != None) valueMask = CWCursor;
618        attributes.cursor = newpw->primitive.cursor;
619 
620        if (XtIsRealized ((Widget)newpw))
621 	   XChangeWindowAttributes (XtDisplay(newpw), newpw -> core.window,
622 				    valueMask, &attributes);
623 
624        returnFlag = TRUE;
625    }
626 
627    /*  Check the geometry in relationship to the highlight thickness  */
628 
629    if (reqpw -> core.width == 0)
630       if (curpw -> core.width == 0)
631          newpw -> core.width += newpw -> primitive.highlight_thickness * 2;
632    else if (reqpw -> core.width < newpw -> primitive.highlight_thickness * 2)
633    {
634       newpw -> primitive.highlight_thickness = reqpw -> core.width / 2;
635    }
636 
637    if (reqpw -> core.height == 0)
638       if (curpw -> core.height == 0)
639          newpw -> core.height += newpw -> primitive.highlight_thickness * 2;
640    else if (reqpw -> core.height < newpw -> primitive.highlight_thickness * 2)
641    {
642       XtWarning("Primitive: The highlight thickness is too large.");
643       newpw -> primitive.highlight_thickness = reqpw -> core.height / 2;
644    }
645 
646 
647    /*  If the highlight color, traversal type, highlight tile or highlight */
648    /*  thickness has changed, regenerate the GC's.                         */
649 
650    if (curpw->primitive.highlight_color != newpw->primitive.highlight_color ||
651        curpw->primitive.highlight_thickness !=
652        newpw->primitive.highlight_thickness                                 ||
653        curpw->primitive.highlight_style != newpw->primitive.highlight_style ||
654        curpw->primitive.highlight_tile != newpw->primitive.highlight_tile)
655    {
656       XtDestroyGC (newpw -> primitive.highlight_GC);
657 
658       GetHighlightGC (newpw);
659 
660       returnFlag = TRUE;
661    }
662 
663 
664    /*  Return a flag which may indicate that a redraw needs to occur.  */
665 
666    return (returnFlag);
667 }
668 
669 
670 
671 /************************************************************************
672  *
673  *  The traversal event processing routines.
674  *    The following set of routines are the entry points invoked from
675  *    each primitive widget when one of the traversal event conditions
676  *    occur.  These routines are externed in Xw.h.
677  *
678  ************************************************************************/
679 
_XwTraverseLeft(w,event)680 void _XwTraverseLeft (w, event)
681 Widget w;
682 XEvent * event;
683 
684 {
685    XwProcessTraversal (w, XwTRAVERSE_LEFT, TRUE);
686 }
687 
688 
_XwTraverseRight(w,event)689 void _XwTraverseRight (w, event)
690 Widget w;
691 XEvent * event;
692 
693 {
694    XwProcessTraversal (w, XwTRAVERSE_RIGHT, TRUE);
695 }
696 
697 
_XwTraverseUp(w,event)698 void _XwTraverseUp (w, event)
699 Widget w;
700 XEvent * event;
701 
702 {
703    XwProcessTraversal (w, XwTRAVERSE_UP, TRUE);
704 }
705 
706 
_XwTraverseDown(w,event)707 void _XwTraverseDown (w, event)
708 Widget w;
709 XEvent * event;
710 
711 {
712    XwProcessTraversal (w, XwTRAVERSE_DOWN, TRUE);
713 }
714 
715 
_XwTraverseNext(w,event)716 void _XwTraverseNext (w, event)
717 Widget w;
718 XEvent * event;
719 
720 {
721    XwProcessTraversal (w, XwTRAVERSE_NEXT, TRUE);
722 }
723 
724 
_XwTraversePrev(w,event)725 void _XwTraversePrev (w, event)
726 Widget w;
727 XEvent * event;
728 
729 {
730    XwProcessTraversal (w, XwTRAVERSE_PREV, TRUE);
731 }
732 
733 
_XwTraverseHome(w,event)734 void _XwTraverseHome (w, event)
735 Widget w;
736 XEvent * event;
737 
738 {
739    XwProcessTraversal (w, XwTRAVERSE_HOME, TRUE);
740 }
741 
742 
_XwTraverseNextTop(w,event)743 void _XwTraverseNextTop (w, event)
744 Widget w;
745 XEvent * event;
746 
747 {
748    XwProcessTraversal (w, XwTRAVERSE_NEXT_TOP, TRUE);
749 }
750 
751 
752 
753 /************************************************************************
754  *
755  *  XwProcessTraversal
756  *     This function handles all of the directional traversal conditions.
757  *     It first verifies that traversal is active, and then searches up
758  *     the widget hierarchy until a composite widget class is found.
759  *     If this widget also contains a ManagerWidgetClass, it invokes
760  *     the class's traversal handler giving the widget and direction.
761  *     If not a ManagerWidgetClass, it invokes the composits
762  *     move_focus_to_next or move_focus_to_prev functions for directions
763  *     of TRAVERSE_NEXT and TRAVERSE_PREV respectively.
764  *
765  ************************************************************************/
766 
XwProcessTraversal(w,dir,check)767 void XwProcessTraversal (w, dir, check)
768 Widget w;
769 int    dir;
770 Boolean check;
771 
772 {
773    Widget tw;
774    XPoint ul, lr;
775    XwPrimitiveWidget pw = (XwPrimitiveWidget) w;
776 
777    if (check && (pw -> primitive.traversal_type != XwHIGHLIGHT_TRAVERSAL))
778           return;
779 
780    /* Initialize the traversal checklist */
781    _XwInitCheckList();
782 
783    tw = w -> core.parent;
784 
785    ul.x = w -> core.x;
786    ul.y = w -> core.y;
787    lr.x = ul.x + w->core.width - 1;
788    lr.y = ul.y + w->core.height - 1;
789 
790    if (XtIsSubclass (tw, XwmanagerWidgetClass))
791    {
792        (*(((XwManagerWidgetClass) (tw -> core.widget_class)) ->
793                                    manager_class.traversal_handler))
794                                       (tw, ul, lr, dir);
795    }
796 /* *** R3
797    else if (dir == XwTRAVERSE_NEXT &&
798            ((CompositeWidgetClass)(tw -> core.widget_class)) ->
799                                    composite_class.move_focus_to_next != NULL)
800    {
801       (*(((CompositeWidgetClass) tw -> core.widget_class) ->
802                                  composite_class.move_focus_to_next))(w);
803    }
804 
805    else if (dir == XwTRAVERSE_PREV &&
806            ((CompositeWidgetClass)(tw -> core.widget_class)) ->
807                                    composite_class.move_focus_to_prev != NULL)
808    {
809       (*(((CompositeWidgetClass) tw -> core.widget_class) ->
810                                  composite_class.move_focus_to_prev))(w);
811    }
812    *** R3 */
813 }
814 
815 
816 
817 /************************************************************************
818  *
819  *  The border highlighting and unhighlighting routines.
820  *
821  *  These routines are called through primitive widget translations and
822  *  by primitive widget redisplay routines.  They provide for the border
823  *  drawing for active and inactive cases.
824  *
825  ************************************************************************/
826 
_XwHighlightBorder(pw)827 void _XwHighlightBorder (pw)
828 XwPrimitiveWidget pw;
829 
830 {
831    if ((pw -> primitive.highlight_thickness == 0
832         ) && (!XtIsSubclass ((Widget)pw, XwmenubuttonWidgetClass)))
833       return;
834 
835    pw -> primitive.highlighted = TRUE;
836    pw -> primitive.display_highlighted = TRUE;
837 
838    switch (pw -> primitive.highlight_style)
839    {
840 
841       case XwWIDGET_DEFINED:
842       {
843          if (((XwPrimitiveWidgetClass) (pw -> core.widget_class)) ->
844  	      primitive_class.border_highlight != NULL)
845          (*(((XwPrimitiveWidgetClass) (pw -> core.widget_class)) ->
846 	    primitive_class.border_highlight))((Widget)pw);
847       }
848       break;
849 
850       case XwPATTERN_BORDER:
851       {
852          XRectangle rect[4];
853          int windowWidth = pw -> core.width;
854          int windowHeight = pw -> core.height;
855          int highlightWidth = pw -> primitive.highlight_thickness;
856 
857          rect[0].x = 0;
858          rect[0].y = 0;
859          rect[0].width = windowWidth;
860          rect[0].height = highlightWidth;
861 
862          rect[1].x = 0;
863          rect[1].y = 0;
864          rect[1].width = highlightWidth;
865          rect[1].height = windowHeight;
866 
867          rect[2].x = windowWidth - highlightWidth;
868          rect[2].y = 0;
869          rect[2].width = highlightWidth;
870          rect[2].height = windowHeight;
871 
872          rect[3].x = 0;
873          rect[3].y = windowHeight - highlightWidth;
874          rect[3].width = windowWidth;
875          rect[3].height = highlightWidth;
876 
877          XFillRectangles (XtDisplay (pw), XtWindow (pw),
878                           pw -> primitive.highlight_GC, &rect[0], 4);
879       }
880       break;
881    }
882 }
883 
884 
885 
886 
_XwUnhighlightBorder(pw)887 void _XwUnhighlightBorder (pw)
888 XwPrimitiveWidget pw;
889 
890 {
891    if ((pw -> primitive.highlight_thickness == 0
892         ) && (!XtIsSubclass ((Widget)pw, XwmenubuttonWidgetClass)))
893       return;
894 
895 
896    pw -> primitive.highlighted = FALSE;
897    pw -> primitive.display_highlighted = FALSE;
898 
899    switch (pw -> primitive.highlight_style)
900    {
901       case XwWIDGET_DEFINED:
902       {
903          if (((XwPrimitiveWidgetClass) (pw -> core.widget_class)) ->
904  	      primitive_class.border_unhighlight != NULL)
905             (*(((XwPrimitiveWidgetClass) (pw -> core.widget_class)) ->
906                primitive_class.border_unhighlight))((Widget)pw);
907       }
908       break;
909 
910 
911       case XwPATTERN_BORDER:
912       {
913          int windowWidth = pw -> core.width;
914          int windowHeight = pw -> core.height;
915          int highlightWidth = pw -> primitive.highlight_thickness;
916 
917 
918          XClearArea (XtDisplay (pw), XtWindow (pw),
919                      0, 0, windowWidth, highlightWidth, False);
920 
921          XClearArea (XtDisplay (pw), XtWindow (pw),
922                      0, 0, highlightWidth, windowHeight, False);
923 
924          XClearArea (XtDisplay (pw), XtWindow (pw),
925                      windowWidth - highlightWidth, 0,
926 		     highlightWidth, windowHeight, False);
927 
928          XClearArea (XtDisplay (pw), XtWindow (pw),
929                      0, windowHeight - highlightWidth,
930                      windowWidth, highlightWidth, False);
931       }
932       break;
933    }
934 }
935 
936 
937 
938 
939 /************************************************************************
940  *
941  *  Enter & Leave
942  *      Enter and leave event processing routines.  Handle border
943  *      highlighting and dehighlighting.
944  *
945  ************************************************************************/
946 
_XwPrimitiveEnter(pw,event)947 void _XwPrimitiveEnter (pw, event)
948 XwPrimitiveWidget pw;
949 XEvent * event;
950 
951 {
952   if (pw -> primitive.traversal_type == XwHIGHLIGHT_ENTER)
953      _XwHighlightBorder (pw);
954 }
955 
956 
_XwPrimitiveLeave(pw,event)957 void _XwPrimitiveLeave (pw, event)
958 XwPrimitiveWidget pw;
959 XEvent * event;
960 
961 {
962   if (pw -> primitive.traversal_type == XwHIGHLIGHT_ENTER)
963      _XwUnhighlightBorder (pw);
964 }
965 
966 
967 /************************************************************************
968  *
969  * Visibility
970  *      Track whether a widget is visible.
971  *
972  ***********************************************************************/
_XwPrimitiveVisibility(pw,event)973 void _XwPrimitiveVisibility (pw, event)
974   XwPrimitiveWidget pw;
975   XEvent * event;
976 {
977   XVisibilityEvent * vEvent = (XVisibilityEvent *)event;
978 
979   if (vEvent->state == VisibilityFullyObscured)
980     {
981       pw->core.visible = False;
982       if (pw->primitive.I_have_traversal)
983        XwProcessTraversal (pw, XwTRAVERSE_HOME, FALSE);
984      }
985   else
986     pw->core.visible = True;
987 
988 
989 }
990 
991 
992 
993 /************************************************************************
994  *
995  * Unmap
996  *      Track whether a widget is visible.
997  *
998  ***********************************************************************/
_XwPrimitiveUnmap(pw,event)999 void _XwPrimitiveUnmap (pw, event)
1000   XwPrimitiveWidget pw;
1001   XEvent * event;
1002 {
1003    pw->core.visible = False;
1004    if (pw->primitive.I_have_traversal)
1005        XwProcessTraversal (pw, XwTRAVERSE_HOME, FALSE);
1006 
1007 }
1008 
1009 /************************************************************************
1010  *
1011  *  Focus In & Out
1012  *      Handle border highlighting and dehighlighting.
1013  *
1014  ************************************************************************/
1015 
_XwPrimitiveFocusIn(pw,event)1016 void _XwPrimitiveFocusIn (pw, event)
1017 XwPrimitiveWidget pw;
1018 XEvent * event;
1019 
1020 {
1021    int widgetType;
1022 
1023 
1024    /*  SET THE FOCUS PATH DOWN TO THIS WIDGET.  */
1025 
1026    XwSetFocusPath((Widget)pw);
1027 
1028 
1029    /*  IF THE SPECIFIED WIDGET CANNOT BE TRAVERSED TO, THEN INVOKE  */
1030    /*  MANAGER'S TRAVERSAL HANDLER WITH DIRECTION = HOME.           */
1031 
1032    if (! XwTestTraversability((Widget)pw, &widgetType))
1033      XwProcessTraversal (pw, XwTRAVERSE_HOME, FALSE);
1034    else
1035    {
1036       _XwHighlightBorder (pw);
1037       pw->primitive.I_have_traversal = TRUE;
1038    }
1039 }
1040 
1041 
_XwPrimitiveFocusOut(pw,event)1042 void _XwPrimitiveFocusOut (pw, event)
1043 XwPrimitiveWidget pw;
1044 XEvent * event;
1045 
1046 {
1047    if (pw -> primitive.traversal_type == XwHIGHLIGHT_TRAVERSAL)
1048    {
1049       _XwUnhighlightBorder (pw);
1050       pw->primitive.I_have_traversal = FALSE;
1051    }
1052 }
1053 
1054 
XwSetFocusPath(w)1055 void XwSetFocusPath(w)
1056 Widget w;
1057 
1058 {
1059    XwManagerWidget mw;
1060    Widget tempoldActive, oldActive;
1061 
1062 
1063    /*  IF THE PARENT OF THIS WIDGET IS NOT A MANAGER THEN THERE'S NO  */
1064    /*  PATH TO SET, SO RETURN.                                        */
1065 
1066    if (! XtIsSubclass(w->core.parent, XwmanagerWidgetClass)) return;
1067 
1068    mw = (XwManagerWidget)w->core.parent;
1069 
1070 
1071    /*  IF THIS WIDGET IS ALREADY THE ACTIVE CHID THEN THERE'S NOTHING  */
1072    /*  TO DO.                                                          */
1073 
1074    if (mw->manager.active_child == w) return;
1075 
1076    oldActive = mw->manager.active_child;
1077    mw->manager.active_child = w;
1078    XwProcessTraversal (w, XwTRAVERSE_CURRENT, FALSE);
1079 
1080 
1081    /*  TRAVERSE DOWN THE OTHER BRANCH OF TREE TO CLEAN UP ACTIVE CHILD  */
1082    /*  PATH.                                                            */
1083 
1084    while (oldActive != NULL)
1085    {
1086       if (! XtIsSubclass(oldActive, XwmanagerWidgetClass))
1087          oldActive = NULL;
1088       else
1089       {
1090          tempoldActive = ((XwManagerWidget)oldActive)->manager.active_child;
1091          ((XwManagerWidget)oldActive)->manager.active_child = NULL;
1092          oldActive=tempoldActive;
1093       }
1094    }
1095 
1096    XwSetFocusPath((Widget)mw);
1097 }
1098 
1099 
1100 
1101 
1102 
1103 
1104 /************************************************************************
1105  *
1106  *  _XwDrawBox
1107  *	Draw the bordering on the drawable d, thick pixels wide,
1108  *      using the provided GC and rectangle.
1109  *
1110  ************************************************************************/
1111 
_XwDrawBox(display,d,normal_GC,thick,x,y,width,height)1112 void _XwDrawBox (display, d, normal_GC, thick, x, y, width, height)
1113 Display * display;
1114 Drawable d;
1115 GC normal_GC;
1116 register int thick;
1117 register int x;
1118 register int y;
1119 register int width;
1120 register int height;
1121 
1122 {
1123    XRectangle rect[4];
1124 
1125    rect[0].x = x;		/*  top   */
1126    rect[0].y = y;
1127    rect[0].width = width;
1128    rect[0].height = 2;
1129 
1130    rect[1].x = x;		/*  left  */
1131    rect[1].y = y + 2;
1132    rect[1].width = 2;
1133    rect[1].height = height - 4;
1134 
1135    rect[2].x = x;		/*  bottom  */
1136    rect[2].y = y + height - 2;
1137    rect[2].width = width;
1138    rect[2].height = 2;
1139 
1140    rect[3].x = x + width - 2;	/*  Right two segments  */
1141    rect[3].y = y + 2;
1142    rect[3].width = 2;
1143    rect[3].height = height - 4;
1144 
1145    XFillRectangles (display, d, normal_GC, &rect[0], 4);
1146 }
1147