One more check on valid display which is known to be in the startup
[xcircuit.git] / Xw / Primitive.c
blob89a8b2c9dc67d0dde190c71c2a2b33132a8b29a6
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 *************************************<+>*************************************/
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>
40 /*************************************<->*************************************
43 * Description: default translation table for class: Primitive.
44 * -----------
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.
54 *************************************<->***********************************/
56 static char defaultTranslations[] =
57 "<FocusIn>: focusIn() \n\
58 <FocusOut>: focusOut() \n\
59 <Visible>: visibility() \n\
60 <Unmap>: unmap()";
63 /*************************************<->*************************************
66 * Description: action list for class: Primtive
67 * -----------
68 * Used to provide actions for subclasses with traversal on.
70 *************************************<->***********************************/
72 static XtActionsRec actionsList[] =
74 {"focusIn", (XtActionProc) _XwPrimitiveFocusIn},
75 {"focusOut", (XtActionProc) _XwPrimitiveFocusOut},
76 {"visibility", (XtActionProc) _XwPrimitiveVisibility},
77 {"unmap", (XtActionProc) _XwPrimitiveUnmap},
81 /* Resource definitions for Subclasses of Primitive */
83 static Cursor defaultCursor = None;
85 static XtResource resources[] =
88 XtNforeground, XtCForeground, XtRPixel, sizeof (Pixel),
89 XtOffset (XwPrimitiveWidget, primitive.foreground),
90 XtRString, "XtDefaultForeground"
94 XtNbackgroundTile, XtCBackgroundTile, XtRTileType, sizeof (int),
95 XtOffset (XwPrimitiveWidget, primitive.background_tile),
96 XtRString, "background"
100 XtNcursor, XtCCursor, XtRCursor, sizeof (Cursor),
101 XtOffset (XwPrimitiveWidget, primitive.cursor),
102 XtRCursor, (caddr_t) &defaultCursor
106 XtNtraversalType, XtCTraversalType, XtRTraversalType, sizeof (int),
107 XtOffset (XwPrimitiveWidget, primitive.traversal_type),
108 XtRString, "highlight_off"
112 XtNhighlightThickness, XtCHighlightThickness, XtRInt, sizeof (int),
113 XtOffset (XwPrimitiveWidget, primitive.highlight_thickness),
114 XtRString, "0"
118 XtNhighlightStyle, XtCHighlightStyle, XtRHighlightStyle, sizeof (int),
119 XtOffset (XwPrimitiveWidget, primitive.highlight_style),
120 XtRString, "pattern_border"
124 XtNhighlightColor, XtCForeground, XtRPixel, sizeof (Pixel),
125 XtOffset (XwPrimitiveWidget, primitive.highlight_color),
126 XtRString, "Black"
130 XtNhighlightTile, XtCHighlightTile, XtRTileType, sizeof (int),
131 XtOffset (XwPrimitiveWidget, primitive.highlight_tile),
132 XtRString, "foreground"
136 XtNrecomputeSize, XtCRecomputeSize, XtRBoolean, sizeof(Boolean),
137 XtOffset (XwPrimitiveWidget, primitive.recompute_size),
138 XtRString, "True"
142 XtNselect, XtCCallback, XtRCallback, sizeof(caddr_t),
143 XtOffset (XwPrimitiveWidget, primitive.select),
144 XtRPointer, (caddr_t) NULL
148 XtNrelease, XtCCallback, XtRCallback, sizeof(caddr_t),
149 XtOffset (XwPrimitiveWidget, primitive.release),
150 XtRPointer, (caddr_t) NULL
156 /* Routine definiton used for initializing the class record. */
158 static void ClassInitialize();
159 static void ClassPartInitialize();
160 static void Initialize();
161 static void Realize();
162 static void Destroy();
163 static Boolean SetValues();
165 static void GetHighlightGC();
169 /* The primitive class record definition */
171 XwPrimitiveClassRec XwprimitiveClassRec =
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
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 */
218 WidgetClass XwprimitiveWidgetClass = (WidgetClass) &XwprimitiveClassRec;
222 /************************************************************************
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.
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.
234 ************************************************************************/
236 static void ClassInitialize()
238 XwRegisterConverters();
239 XwprimitiveClassRec.primitive_class.translations =
240 XtParseTranslationTable(defaultTranslations);
246 /************************************************************************
248 * ClassPartInitialize
249 * Set up the inheritance mechanism for the routines exported by
250 * primitives class part.
252 ************************************************************************/
254 static void ClassPartInitialize (w)
255 WidgetClass w;
258 register XwPrimitiveWidgetClass wc = (XwPrimitiveWidgetClass) w;
259 register XwPrimitiveWidgetClass super =
260 (XwPrimitiveWidgetClass) wc->core_class.superclass;
262 if (wc -> primitive_class.border_highlight == XtInheritBorderHighlight)
263 wc -> primitive_class.border_highlight =
264 super -> primitive_class.border_highlight;
266 if (wc->primitive_class.border_unhighlight == XtInheritBorderUnhighlight)
267 wc -> primitive_class.border_unhighlight =
268 super -> primitive_class.border_unhighlight;
270 if (wc -> primitive_class.select_proc == XtInheritSelectProc)
271 wc -> primitive_class.select_proc =
272 super -> primitive_class.select_proc;
274 if (wc -> primitive_class.release_proc == XtInheritReleaseProc)
275 wc -> primitive_class.release_proc =
276 super -> primitive_class.release_proc;
278 if (wc -> primitive_class.toggle_proc == XtInheritToggleProc)
279 wc -> primitive_class.toggle_proc =
280 super -> primitive_class.toggle_proc;
287 /************************************************************************
289 * GetHighlightGC
290 * Get the graphics context used for drawing the border.
292 ************************************************************************/
294 static void GetHighlightGC (pw)
295 XwPrimitiveWidget pw;
298 XGCValues values;
299 XtGCMask valueMask;
301 valueMask = GCForeground | GCBackground;
302 values.foreground = pw -> primitive.highlight_color;
303 values.background = pw -> core.background_pixel;
305 if (pw -> primitive.highlight_tile == XwBACKGROUND)
307 values.foreground = pw -> core.background_pixel;
308 values.background = pw -> primitive.highlight_color;
311 pw -> primitive.highlight_GC = XtGetGC ((Widget) pw, valueMask, &values);
318 /************************************************************************
320 * Initialize
321 * The main widget instance initialization routine.
323 ************************************************************************/
325 static void Initialize (request, new)
326 XwPrimitiveWidget request, new;
329 XwPrimitiveWidget pw = (XwPrimitiveWidget) new;
330 Arg args[1];
333 /* initialize traversal flag */
335 pw->primitive.I_have_traversal = FALSE;
338 /* Check the pw widget for invalid data */
340 if (pw -> primitive.traversal_type != XwHIGHLIGHT_OFF &&
341 pw -> primitive.traversal_type != XwHIGHLIGHT_ENTER &&
342 pw -> primitive.traversal_type != XwHIGHLIGHT_TRAVERSAL)
344 XtWarning ("Primitive: Incorrect traversal type");
345 pw -> primitive.traversal_type = XwHIGHLIGHT_OFF;
348 if (pw -> primitive.highlight_style != XwPATTERN_BORDER &&
349 pw -> primitive.highlight_style != XwWIDGET_DEFINED)
351 XtWarning("Primitive: Incorrect highlight style.");
352 pw -> primitive.highlight_style = XwPATTERN_BORDER;
355 if (pw -> primitive.highlight_tile != XwFOREGROUND)
357 XtWarning("Primitive: Incorrect highlight tile.");
358 pw -> primitive.highlight_tile = XwFOREGROUND;
361 if (pw -> primitive.highlight_thickness < 0)
363 XtWarning("Primitive: Invalid highlight thickness.");
364 pw -> primitive.highlight_thickness = 0;
367 if (pw -> primitive.background_tile != XwBACKGROUND)
369 XtWarning("Primitive: Incorrect background tile.");
370 pw -> primitive.background_tile = XwBACKGROUND;
374 /* Check the geometry information for the widget */
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)
380 pw -> primitive.highlight_thickness = request -> core.width / 2;
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)
387 pw -> primitive.highlight_thickness = request -> core.height / 2;
391 /* Get the graphics contexts for the border drawing */
393 GetHighlightGC (pw);
395 /* Set some additional fields of the widget */
397 pw -> primitive.display_sensitive = FALSE;
398 pw -> primitive.highlighted = FALSE;
399 pw -> primitive.display_highlighted = FALSE;
401 /* If this widget is requesting traversal then augment its
402 * translation table with some additional events.
404 if (pw->primitive.traversal_type == XwHIGHLIGHT_TRAVERSAL)
406 XtAugmentTranslations((Widget) pw,
407 XwprimitiveClassRec.primitive_class.translations);
408 pw->core.widget_class->core_class.visible_interest = True;
415 /************************************************************************
417 * Realize
419 ************************************************************************/
421 static void Realize (widget, value_mask, attributes)
422 Widget widget;
423 Mask *value_mask;
424 XSetWindowAttributes *attributes;
426 XwPrimitiveWidget pw = (XwPrimitiveWidget) widget;
428 if (pw -> primitive.cursor != None) *value_mask |= CWCursor;
430 attributes->cursor = pw->primitive.cursor;
432 XtCreateWindow(widget, (unsigned int) InputOutput,
433 (Visual *) CopyFromParent, *value_mask, attributes);
437 /************************************************************************
439 * Destroy
440 * Clean up allocated resources when the widget is destroyed.
442 ************************************************************************/
444 static void Destroy (pw)
445 XwPrimitiveWidget pw;
447 XwManagerWidget parent;
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))
458 parent->manager.active_child = NULL;
460 /* Find the top most manager */
461 while ((parent->core.parent != NULL) &&
462 (XtIsSubclass(parent->core.parent, XwmanagerWidgetClass)))
463 parent = (XwManagerWidget)parent->core.parent;
465 /* Clear the toolkit kbd focus from us */
466 XtSetKeyboardFocus((Widget)parent, NULL);
473 /************************************************************************
475 * SetValues
476 * Perform and updating necessary for a set values call.
478 ************************************************************************/
480 static Boolean SetValues (current, request, new)
481 Widget current, request, new;
484 Boolean tempSensitive, tempAnSensitive;
485 int tempTrav;
487 XwPrimitiveWidget curpw = (XwPrimitiveWidget) current;
488 XwPrimitiveWidget reqpw = (XwPrimitiveWidget) request;
489 XwPrimitiveWidget newpw = (XwPrimitiveWidget) new;
490 Boolean returnFlag = FALSE;
491 int difference;
494 /* Verify correct new values. */
496 if (newpw->primitive.traversal_type != XwHIGHLIGHT_OFF &&
497 newpw->primitive.traversal_type != XwHIGHLIGHT_ENTER &&
498 newpw->primitive.traversal_type != XwHIGHLIGHT_TRAVERSAL)
500 XtWarning("Primitive: Incorrect traversal type.");
501 newpw->primitive.traversal_type = curpw->primitive.traversal_type;
505 /* If traversal has been turned on, then augment the translations */
506 /* of the new widget. */
508 if ((newpw->primitive.traversal_type != curpw->primitive.traversal_type)
509 && (newpw->primitive.traversal_type == XwHIGHLIGHT_TRAVERSAL))
511 /* XXX this was a hard bug! where were the XXX's?
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!
519 XtAugmentTranslations((Widget) newpw,
520 XwprimitiveClassRec.primitive_class.translations);
521 newpw->core.widget_class->core_class.visible_interest = True;
525 /* IF we have the traversal and something is happening to
526 * make that not possible then move it somewhere else!
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))
534 newpw->primitive.highlighted = FALSE;
536 tempTrav= curpw->primitive.traversal_type;
537 tempSensitive = curpw->core.sensitive;
538 tempAnSensitive = curpw->core.ancestor_sensitive;
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;
544 XwProcessTraversal (curpw, XwTRAVERSE_HOME, FALSE);
546 curpw->primitive.traversal_type = tempTrav;
547 curpw->core.sensitive = tempSensitive;
548 curpw->core.ancestor_sensitive = tempAnSensitive;
550 returnFlag = TRUE;
554 if (newpw->primitive.highlight_style != XwPATTERN_BORDER &&
555 newpw->primitive.highlight_style != XwWIDGET_DEFINED)
557 XtWarning ("Primitive: Incorrect highlight style.");
558 newpw->primitive.highlight_style = curpw->primitive.highlight_style;
561 if (newpw -> primitive.highlight_tile != XwFOREGROUND)
563 XtWarning ("Primitive: Incorrect highlight tile.");
564 newpw->primitive.highlight_tile = curpw->primitive.highlight_tile;
567 if (newpw->primitive.highlight_thickness < 0)
569 XtWarning ("Primtive: Invalid highlight thickness.");
570 newpw -> primitive.highlight_thickness =
571 curpw -> primitive.highlight_thickness;
575 if (newpw -> primitive.background_tile != XwBACKGROUND)
577 XtWarning("Primitive: Incorrect background tile.");
578 newpw -> primitive.background_tile =
579 curpw -> primitive.background_tile;
583 /* Set the widgets background tile */
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)
592 Mask valueMask;
593 XSetWindowAttributes attributes;
595 if (newpw -> primitive.background_tile == XwFOREGROUND)
597 valueMask = CWBackPixel;
598 attributes.background_pixel = newpw -> primitive.foreground;
600 else
602 valueMask = CWBackPixel;
603 attributes.background_pixel = newpw -> core.background_pixel;
606 if (XtIsRealized ((Widget)newpw))
607 XChangeWindowAttributes (XtDisplay(newpw), newpw -> core.window,
608 valueMask, &attributes);
610 returnFlag = TRUE;
613 if (newpw -> primitive.cursor != curpw -> primitive.cursor) {
614 Mask valueMask = 0;
615 XSetWindowAttributes attributes;
617 if (newpw->primitive.cursor != None) valueMask = CWCursor;
618 attributes.cursor = newpw->primitive.cursor;
620 if (XtIsRealized ((Widget)newpw))
621 XChangeWindowAttributes (XtDisplay(newpw), newpw -> core.window,
622 valueMask, &attributes);
624 returnFlag = TRUE;
627 /* Check the geometry in relationship to the highlight thickness */
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)
634 newpw -> primitive.highlight_thickness = reqpw -> core.width / 2;
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)
642 XtWarning("Primitive: The highlight thickness is too large.");
643 newpw -> primitive.highlight_thickness = reqpw -> core.height / 2;
647 /* If the highlight color, traversal type, highlight tile or highlight */
648 /* thickness has changed, regenerate the GC's. */
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)
656 XtDestroyGC (newpw -> primitive.highlight_GC);
658 GetHighlightGC (newpw);
660 returnFlag = TRUE;
664 /* Return a flag which may indicate that a redraw needs to occur. */
666 return (returnFlag);
671 /************************************************************************
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.
678 ************************************************************************/
680 void _XwTraverseLeft (w, event)
681 Widget w;
682 XEvent * event;
685 XwProcessTraversal (w, XwTRAVERSE_LEFT, TRUE);
689 void _XwTraverseRight (w, event)
690 Widget w;
691 XEvent * event;
694 XwProcessTraversal (w, XwTRAVERSE_RIGHT, TRUE);
698 void _XwTraverseUp (w, event)
699 Widget w;
700 XEvent * event;
703 XwProcessTraversal (w, XwTRAVERSE_UP, TRUE);
707 void _XwTraverseDown (w, event)
708 Widget w;
709 XEvent * event;
712 XwProcessTraversal (w, XwTRAVERSE_DOWN, TRUE);
716 void _XwTraverseNext (w, event)
717 Widget w;
718 XEvent * event;
721 XwProcessTraversal (w, XwTRAVERSE_NEXT, TRUE);
725 void _XwTraversePrev (w, event)
726 Widget w;
727 XEvent * event;
730 XwProcessTraversal (w, XwTRAVERSE_PREV, TRUE);
734 void _XwTraverseHome (w, event)
735 Widget w;
736 XEvent * event;
739 XwProcessTraversal (w, XwTRAVERSE_HOME, TRUE);
743 void _XwTraverseNextTop (w, event)
744 Widget w;
745 XEvent * event;
748 XwProcessTraversal (w, XwTRAVERSE_NEXT_TOP, TRUE);
753 /************************************************************************
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.
765 ************************************************************************/
767 void XwProcessTraversal (w, dir, check)
768 Widget w;
769 int dir;
770 Boolean check;
773 Widget tw;
774 XPoint ul, lr;
775 XwPrimitiveWidget pw = (XwPrimitiveWidget) w;
777 if (check && (pw -> primitive.traversal_type != XwHIGHLIGHT_TRAVERSAL))
778 return;
780 /* Initialize the traversal checklist */
781 _XwInitCheckList();
783 tw = w -> core.parent;
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;
790 if (XtIsSubclass (tw, XwmanagerWidgetClass))
792 (*(((XwManagerWidgetClass) (tw -> core.widget_class)) ->
793 manager_class.traversal_handler))
794 (tw, ul, lr, dir);
796 /* *** R3
797 else if (dir == XwTRAVERSE_NEXT &&
798 ((CompositeWidgetClass)(tw -> core.widget_class)) ->
799 composite_class.move_focus_to_next != NULL)
801 (*(((CompositeWidgetClass) tw -> core.widget_class) ->
802 composite_class.move_focus_to_next))(w);
805 else if (dir == XwTRAVERSE_PREV &&
806 ((CompositeWidgetClass)(tw -> core.widget_class)) ->
807 composite_class.move_focus_to_prev != NULL)
809 (*(((CompositeWidgetClass) tw -> core.widget_class) ->
810 composite_class.move_focus_to_prev))(w);
812 *** R3 */
817 /************************************************************************
819 * The border highlighting and unhighlighting routines.
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.
825 ************************************************************************/
827 void _XwHighlightBorder (pw)
828 XwPrimitiveWidget pw;
831 if ((pw -> primitive.highlight_thickness == 0
832 ) && (!XtIsSubclass ((Widget)pw, XwmenubuttonWidgetClass)))
833 return;
835 pw -> primitive.highlighted = TRUE;
836 pw -> primitive.display_highlighted = TRUE;
838 switch (pw -> primitive.highlight_style)
841 case XwWIDGET_DEFINED:
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);
848 break;
850 case XwPATTERN_BORDER:
852 XRectangle rect[4];
853 int windowWidth = pw -> core.width;
854 int windowHeight = pw -> core.height;
855 int highlightWidth = pw -> primitive.highlight_thickness;
857 rect[0].x = 0;
858 rect[0].y = 0;
859 rect[0].width = windowWidth;
860 rect[0].height = highlightWidth;
862 rect[1].x = 0;
863 rect[1].y = 0;
864 rect[1].width = highlightWidth;
865 rect[1].height = windowHeight;
867 rect[2].x = windowWidth - highlightWidth;
868 rect[2].y = 0;
869 rect[2].width = highlightWidth;
870 rect[2].height = windowHeight;
872 rect[3].x = 0;
873 rect[3].y = windowHeight - highlightWidth;
874 rect[3].width = windowWidth;
875 rect[3].height = highlightWidth;
877 XFillRectangles (XtDisplay (pw), XtWindow (pw),
878 pw -> primitive.highlight_GC, &rect[0], 4);
880 break;
887 void _XwUnhighlightBorder (pw)
888 XwPrimitiveWidget pw;
891 if ((pw -> primitive.highlight_thickness == 0
892 ) && (!XtIsSubclass ((Widget)pw, XwmenubuttonWidgetClass)))
893 return;
896 pw -> primitive.highlighted = FALSE;
897 pw -> primitive.display_highlighted = FALSE;
899 switch (pw -> primitive.highlight_style)
901 case XwWIDGET_DEFINED:
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);
908 break;
911 case XwPATTERN_BORDER:
913 int windowWidth = pw -> core.width;
914 int windowHeight = pw -> core.height;
915 int highlightWidth = pw -> primitive.highlight_thickness;
918 XClearArea (XtDisplay (pw), XtWindow (pw),
919 0, 0, windowWidth, highlightWidth, False);
921 XClearArea (XtDisplay (pw), XtWindow (pw),
922 0, 0, highlightWidth, windowHeight, False);
924 XClearArea (XtDisplay (pw), XtWindow (pw),
925 windowWidth - highlightWidth, 0,
926 highlightWidth, windowHeight, False);
928 XClearArea (XtDisplay (pw), XtWindow (pw),
929 0, windowHeight - highlightWidth,
930 windowWidth, highlightWidth, False);
932 break;
939 /************************************************************************
941 * Enter & Leave
942 * Enter and leave event processing routines. Handle border
943 * highlighting and dehighlighting.
945 ************************************************************************/
947 void _XwPrimitiveEnter (pw, event)
948 XwPrimitiveWidget pw;
949 XEvent * event;
952 if (pw -> primitive.traversal_type == XwHIGHLIGHT_ENTER)
953 _XwHighlightBorder (pw);
957 void _XwPrimitiveLeave (pw, event)
958 XwPrimitiveWidget pw;
959 XEvent * event;
962 if (pw -> primitive.traversal_type == XwHIGHLIGHT_ENTER)
963 _XwUnhighlightBorder (pw);
967 /************************************************************************
969 * Visibility
970 * Track whether a widget is visible.
972 ***********************************************************************/
973 void _XwPrimitiveVisibility (pw, event)
974 XwPrimitiveWidget pw;
975 XEvent * event;
977 XVisibilityEvent * vEvent = (XVisibilityEvent *)event;
979 if (vEvent->state == VisibilityFullyObscured)
981 pw->core.visible = False;
982 if (pw->primitive.I_have_traversal)
983 XwProcessTraversal (pw, XwTRAVERSE_HOME, FALSE);
985 else
986 pw->core.visible = True;
993 /************************************************************************
995 * Unmap
996 * Track whether a widget is visible.
998 ***********************************************************************/
999 void _XwPrimitiveUnmap (pw, event)
1000 XwPrimitiveWidget pw;
1001 XEvent * event;
1003 pw->core.visible = False;
1004 if (pw->primitive.I_have_traversal)
1005 XwProcessTraversal (pw, XwTRAVERSE_HOME, FALSE);
1009 /************************************************************************
1011 * Focus In & Out
1012 * Handle border highlighting and dehighlighting.
1014 ************************************************************************/
1016 void _XwPrimitiveFocusIn (pw, event)
1017 XwPrimitiveWidget pw;
1018 XEvent * event;
1021 int widgetType;
1024 /* SET THE FOCUS PATH DOWN TO THIS WIDGET. */
1026 XwSetFocusPath((Widget)pw);
1029 /* IF THE SPECIFIED WIDGET CANNOT BE TRAVERSED TO, THEN INVOKE */
1030 /* MANAGER'S TRAVERSAL HANDLER WITH DIRECTION = HOME. */
1032 if (! XwTestTraversability((Widget)pw, &widgetType))
1033 XwProcessTraversal (pw, XwTRAVERSE_HOME, FALSE);
1034 else
1036 _XwHighlightBorder (pw);
1037 pw->primitive.I_have_traversal = TRUE;
1042 void _XwPrimitiveFocusOut (pw, event)
1043 XwPrimitiveWidget pw;
1044 XEvent * event;
1047 if (pw -> primitive.traversal_type == XwHIGHLIGHT_TRAVERSAL)
1049 _XwUnhighlightBorder (pw);
1050 pw->primitive.I_have_traversal = FALSE;
1055 void XwSetFocusPath(w)
1056 Widget w;
1059 XwManagerWidget mw;
1060 Widget tempoldActive, oldActive;
1063 /* IF THE PARENT OF THIS WIDGET IS NOT A MANAGER THEN THERE'S NO */
1064 /* PATH TO SET, SO RETURN. */
1066 if (! XtIsSubclass(w->core.parent, XwmanagerWidgetClass)) return;
1068 mw = (XwManagerWidget)w->core.parent;
1071 /* IF THIS WIDGET IS ALREADY THE ACTIVE CHID THEN THERE'S NOTHING */
1072 /* TO DO. */
1074 if (mw->manager.active_child == w) return;
1076 oldActive = mw->manager.active_child;
1077 mw->manager.active_child = w;
1078 XwProcessTraversal (w, XwTRAVERSE_CURRENT, FALSE);
1081 /* TRAVERSE DOWN THE OTHER BRANCH OF TREE TO CLEAN UP ACTIVE CHILD */
1082 /* PATH. */
1084 while (oldActive != NULL)
1086 if (! XtIsSubclass(oldActive, XwmanagerWidgetClass))
1087 oldActive = NULL;
1088 else
1090 tempoldActive = ((XwManagerWidget)oldActive)->manager.active_child;
1091 ((XwManagerWidget)oldActive)->manager.active_child = NULL;
1092 oldActive=tempoldActive;
1096 XwSetFocusPath((Widget)mw);
1104 /************************************************************************
1106 * _XwDrawBox
1107 * Draw the bordering on the drawable d, thick pixels wide,
1108 * using the provided GC and rectangle.
1110 ************************************************************************/
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;
1123 XRectangle rect[4];
1125 rect[0].x = x; /* top */
1126 rect[0].y = y;
1127 rect[0].width = width;
1128 rect[0].height = 2;
1130 rect[1].x = x; /* left */
1131 rect[1].y = y + 2;
1132 rect[1].width = 2;
1133 rect[1].height = height - 4;
1135 rect[2].x = x; /* bottom */
1136 rect[2].y = y + height - 2;
1137 rect[2].width = width;
1138 rect[2].height = 2;
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;
1145 XFillRectangles (display, d, normal_GC, &rect[0], 4);