1 /*************************************<+>*************************************
2  *****************************************************************************
3  **
4  **   File:        Toggle.c
5  **
6  **   Project:     X Widgets
7  **
8  **   Description: Contains code for primitive widget class: Toggle
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 files & Static Routine Definitions
29  */
30 
31 
32 #include <stdio.h>
33 #include <string.h>
34 #include <ctype.h>
35 #include <X11/Intrinsic.h>
36 #include <X11/IntrinsicP.h>
37 #include <Xw/Xw.h>
38 #include <Xw/XwP.h>
39 #include <Xw/ToggleP.h>
40 #include <Xw/Toggle.h>
41 #include <X11/StringDefs.h>
42 #include <X11/keysymdef.h>
43 
44 #define SPACE_FACTOR 3
45 #define T_BW 2
46 
47 static void Redisplay();
48 static Boolean SetValues();
49 static void ClassInitialize();
50 static void Initialize();
51 static void Destroy();
52 static void Toggle();
53 static void Select();
54 static void Unselect();
55 static void DrawToggle();
56 static void Resize();
57 static void DrawDiamondButton();
58 static void GetSelectGC();
59 
60 
61 
62 /*************************************<->*************************************
63  *
64  *
65  *   Description:  default translation table for class: Toggle
66  *   -----------
67  *
68  *   Matches events with string descriptors for internal routines.
69  *
70  *************************************<->***********************************/
71 
72 
73 static char defaultTranslations[] =
74    "<EnterWindow>:          enter() \n\
75     <LeaveWindow>:          leave() \n\
76     <Btn1Down>:             toggle() \n\
77     <Key>Select:            toggle()";
78 
79 
80 
81 /*************************************<->*************************************
82  *
83  *
84  *   Description:  action list for class: Toggle
85  *   -----------
86  *
87  *   Matches string descriptors with internal routines.
88  *
89  *************************************<->***********************************/
90 
91 static XtActionsRec actionsList[] =
92 {
93   {"toggle", (XtActionProc) Toggle},
94   {"select", (XtActionProc) Select},
95   {"unselect", (XtActionProc) Unselect},
96   {"enter", (XtActionProc) _XwPrimitiveEnter},
97   {"leave", (XtActionProc) _XwPrimitiveLeave},
98 };
99 
100 
101 
102 
103 /*************************************<->*************************************
104  *
105  *
106  *   Description:  resource list for class: Toggle
107  *   -----------
108  *
109  *   Provides default resource settings for instances of this class.
110  *   To get full set of default settings, examine resouce list of super
111  *   classes of this class.
112  *
113  *************************************<->***********************************/
114 
115 static XtResource resources[] =
116 {
117    {
118       XtNsquare, XtCSquare, XtRBoolean, sizeof (Boolean),
119       XtOffset (XwToggleWidget, toggle.square),
120       XtRString, "True"
121    },
122 
123    {
124       XtNselectColor, XtCForeground, XtRPixel, sizeof (Pixel),
125       XtOffset (XwToggleWidget, toggle.select_color),
126       XtRString, "Black"
127    }
128 };
129 
130 
131 
132 /*************************************<->*************************************
133  *
134  *
135  *   Description:  global class record for instances of class: Toggle
136  *   -----------
137  *
138  *   Defines default field settings for this class record.
139  *
140  *************************************<->***********************************/
141 
142 XwToggleClassRec XwtoggleClassRec = {
143   {
144 /* core_class fields */
145     /* superclass	  */	(WidgetClass) &XwbuttonClassRec,
146     /* class_name	  */	"Toggle",
147     /* widget_size	  */	sizeof(XwToggleRec),
148     /* class_initialize   */    ClassInitialize,
149     /* class_part_init    */    NULL,
150     /* class_inited       */	FALSE,
151     /* initialize	  */	Initialize,
152     /* initialize_hook    */    NULL,
153     /* realize		  */	_XwRealize,
154     /* actions		  */	actionsList,
155     /* num_actions	  */	XtNumber(actionsList),
156     /* resources	  */	resources,
157     /* num_resources	  */	XtNumber(resources),
158     /* xrm_class	  */	NULLQUARK,
159     /* compress_motion	  */	TRUE,
160     /* compress_exposure  */	TRUE,
161     /* compress_enterlv   */    TRUE,
162     /* visible_interest	  */	FALSE,
163     /* destroy		  */	Destroy,
164     /* resize		  */	Resize,
165     /* expose		  */	Redisplay,
166     /* set_values	  */	SetValues,
167     /* set_values_hook    */    NULL,
168     /* set_values_almost  */    XtInheritSetValuesAlmost,
169     /* get_values_hook  */	NULL,
170     /* accept_focus     */      NULL,
171     /* version          */	XtVersion,
172     /* callback_private */      NULL,
173     /* tm_table         */      defaultTranslations,
174     /* query_geometry   */	NULL,
175     /* display_accelerator	*/	XtInheritDisplayAccelerator,
176     /* extension		*/	NULL
177    }
178 };
179 WidgetClass XwtoggleWidgetClass = (WidgetClass)&XwtoggleClassRec;
180 
181 /*************************************<->*************************************
182  *
183  *  ComputeSpace (w, redisplay)
184  *
185  *   Description:
186  *   -----------
187  *     Compute allowable space to display label and/or toggle.
188  *     If this function is used in redisplay (i.e. redisplay
189  *     flag is true), compute space for label as well as toggle.
190  *     Compute for toggle only if redisplay flag is FALSE.
191  *
192  *   Inputs:
193  *   ------
194  *     w           =   widget instance that was selected.
195  *     redisplay   =   flag indicating routine is called from Redisplay()
196  *
197  *   Outputs:
198  *   -------
199  *
200  *   Procedures Called
201  *   -----------------
202  *   XClearArea()
203  *   _XwHighlightBorder()
204  *   _XwUnhighlightBorder()
205  *************************************<->***********************************/
ComputeSpace(w,redisplay)206 static void ComputeSpace(w, redisplay)
207      Widget w;
208      Boolean redisplay;
209 {
210    XwToggleWidget cbox = (XwToggleWidget)w;
211    Boolean clipHeight, clipWidth;
212    int x, available_width, available_height;
213 
214   /* COMPUTE SPACE FOR DRAWING TOGGLE */
215 
216    if (redisplay)
217       {
218          available_width = Max(0, (int)cbox->core.width - 2*
219                                  ((int)cbox->button.internal_width +
220 	  		               cbox->primitive.highlight_thickness));
221 
222         /* SEE IF WE NEED TO CLIP THIS LABEL ON RIGHT */
223 
224          if (((int)cbox->button.label_width +
225               (int)cbox->button.label_height +
226               (int)cbox->button.label_height/SPACE_FACTOR)  > available_width)
227                 clipWidth = True;
228          else
229                 clipWidth = False;
230 
231       }
232    else
233       {
234          available_width = Max(0,((int)cbox->core.width - 2*
235                                  ((int)cbox->button.internal_width +
236 	           		       cbox->primitive.highlight_thickness) -
237                                   (int)cbox->button.label_width -
238                                   (int)cbox->button.label_height/SPACE_FACTOR));
239 
240         /* SEE IF WE NEED TO CLIP THIS LABEL ON RIGHT */
241 
242          if ((int)cbox->button.label_height > available_width)
243              clipWidth = True;
244          else
245              clipWidth = False;
246       }
247 
248    available_height = Max(0, (int)cbox->core.height - 2*
249                             ((int)cbox->button.internal_height +
250 				  cbox->primitive.highlight_thickness));
251 
252 
253   /* SEE IF WE NEED TO CLIP THIS LABEL ON TOP AND/OR BOTTOM */
254 
255     if ((int)cbox->button.label_height > available_height)
256         clipHeight = True;
257     else
258         clipHeight = False;
259 
260     if (clipWidth)
261        {
262           x = (int)cbox->core.width - cbox->primitive.highlight_thickness -
263               (int)cbox->button.internal_width;
264 
265           if ((cbox->button.label_location != XwRIGHT) && redisplay)
266              x -= Min((int)cbox->button.label_height,
267                       Max(0, (int)cbox->core.height -
268 		      2*(cbox->primitive.highlight_thickness +
269                       (int)cbox->button.internal_height)));
270 
271 
272           XClearArea (XtDisplay(w), XtWindow(w), x, 0,
273  		      ((int)cbox->core.width - x), cbox->core.height, FALSE);
274        }
275 
276     if (clipHeight)
277        {
278            XClearArea (XtDisplay(w), XtWindow(w), 0,0, cbox->core.width,
279 		       (cbox->primitive.highlight_thickness +
280 		         cbox->button.internal_height), FALSE);
281            XClearArea (XtDisplay(w), XtWindow(w), 0,
282 		       ((int)cbox->core.height -
283                         cbox->primitive.highlight_thickness -
284 		         (int)cbox->button.internal_height), cbox->core.width,
285 		       (cbox->primitive.highlight_thickness +
286 		         cbox->button.internal_height), FALSE);
287        }
288 
289     if (cbox->primitive.highlighted)
290          _XwHighlightBorder(w);
291     else if (cbox->primitive.display_highlighted)
292          _XwUnhighlightBorder(w);
293 
294     /* REDRAW THE TOGGLE ON LABEL LOCATION LEFT CONDITIONS AND RECURSIVELY
295        CALL THIS FUNCTION.  THIS ENSURES VISIBILITY OF THE TOGGLE */
296     if ((cbox->button.label_location != XwRIGHT) && redisplay)
297       {
298   	DrawToggle(w, FALSE);
299   	ComputeSpace(w, FALSE);
300       }
301 
302 } /* ComputeSpace */
303 
304 
305 /*************************************<->*************************************
306  *
307  *  Toggle (w, event)                  PRIVATE
308  *
309  *   Description:
310  *   -----------
311  *     When this Toggle is selected, toggle the activation state
312  *     (i.e., draw it as active if it was not active and draw it as
313  *     inactive if it was active).  Generate the correct callbacks
314  *     in response.
315  *
316  *     NOTE: this code assumes that instances do not receive selection
317  *           events when insensitive.
318  *
319  *   Inputs:
320  *   ------
321  *     w           =   widget instance that was selected.
322  *     event       =   event record
323  *
324  *   Outputs:
325  *   -------
326  *
327  *   Procedures Called
328  *   -----------------
329  *   DrawToggle()    [Toggle.c]
330  *   ComputeSpace()    [Toggle.c]
331  *   XtCallCallbacks()
332  *************************************<->***********************************/
333 
Toggle(w,event)334 static void Toggle(w,event)
335      Widget w;
336      XEvent *event;
337 {
338   XwToggleWidget cbox = (XwToggleWidget)w;
339 
340   cbox->button.set = (cbox->button.set == TRUE) ? FALSE : TRUE;
341   DrawToggle(w, FALSE);
342   ComputeSpace(w, FALSE);
343   XFlush(XtDisplay(w));
344   if (cbox->button.set == TRUE)
345      XtCallCallbacks (w, XtNselect, NULL);
346   else
347      XtCallCallbacks (w, XtNrelease, NULL);
348 }
349 
350 
351 /*************************************<->*************************************
352  *
353  *  Select (w, event)                  PRIVATE
354  *
355  *   Description:
356  *   -----------
357  *     Mark Toggle as selected, (i.e., draw it as active)
358  *     Generate the correct callbacks.
359  *
360  *     NOTE: this code assumes that instances do not receive selection
361  *           events when insensitive.
362  *
363  *   Inputs:
364  *   ------
365  *     w           =   widget instance that was selected.
366  *     event       =   event record
367  *
368  *   Outputs:
369  *   -------
370  *
371  *   Procedures Called
372  *   -----------------
373  *   DrawToggle()    [Toggle.c]
374  *   ComputeSpace()    [Toggle.c]
375  *   XtCallCallbacks()
376  *************************************<->***********************************/
377 
Select(w,event)378 static void Select(w,event)
379      Widget w;
380      XEvent *event;
381 {
382   XwToggleWidget cbox = (XwToggleWidget)w;
383 
384   cbox->button.set = TRUE;
385   DrawToggle(w, FALSE);
386   ComputeSpace(w,FALSE);
387   XFlush(XtDisplay(w));
388   XtCallCallbacks (w, XtNselect, NULL);
389 }
390 
391 
392 /*************************************<->*************************************
393  *
394  *  Unselect (w, event)                  PRIVATE
395  *
396  *   Description:
397  *   -----------
398  *     When this Toggle is unselected draw it as inactive.
399  *     Generate the correct callbacks.
400  *
401  *     NOTE: this code assumes that instances do not receive selection
402  *           events when insensitive.
403  *
404  *   Inputs:
405  *   ------
406  *     w           =   widget instance that was selected.
407  *     event       =   event record
408  *
409  *   Outputs:
410  *   -------
411  *
412  *   Procedures Called
413  *   -----------------
414  *   DrawToggle()    [Toggle.c]
415  *   ComputeSpace()    [Toggle.c]
416  *   XtCallCallbacks()
417  *************************************<->***********************************/
418 
Unselect(w,event)419 static void Unselect(w,event)
420      Widget w;
421      XEvent *event;
422 {
423   XwToggleWidget cbox = (XwToggleWidget)w;
424 
425   cbox->button.set = FALSE;
426   DrawToggle(w, FALSE);
427   ComputeSpace(w,FALSE);
428   XFlush(XtDisplay(w));
429   XtCallCallbacks (w, XtNrelease, NULL);
430 }
431 
432 
433 
434 
435 /************************************************************************
436  *
437  *  GetSelectGC
438  *	Get the graphics context to be used to fill the interior of
439  *	a square or diamond when selected.
440  *
441  ************************************************************************/
442 
GetSelectGC(tw)443 static void GetSelectGC (tw)
444 XwToggleWidget tw;
445 
446 {
447    XGCValues values;
448 
449    values.foreground = tw -> toggle.select_color;
450    values.background = tw -> core.background_pixel;
451    values.fill_style = FillSolid;
452 
453    tw -> toggle.select_GC =
454       XtGetGC ((Widget)tw, GCForeground | GCBackground | GCFillStyle, &values);
455 
456 }
457 
458 
459 
460 
461 /*************************************<->*************************************
462  *
463  *  Resize
464  *
465  *   Description:
466  *   -----------
467  *     A resize event has been generated. Recompute location of button
468  *     elements.
469  *
470  *   Inputs:
471  *   ------
472  *     w  = widget to be resized.
473  *
474  *************************************<->***********************************/
475 
Resize(w)476 static void Resize(w)
477     Widget w;
478 {
479     register XwButtonWidget aButton = (XwButtonWidget) w;
480     int direction = aButton->button.label_location;
481 
482        switch (direction)
483 	 {
484             case XwRIGHT:
485              aButton->button.label_x =  aButton->button.internal_width +
486                                   aButton->primitive.highlight_thickness +
487 				  aButton->button.label_height +
488 				    aButton->button.label_height/SPACE_FACTOR;
489              break;
490 
491            default:
492             aButton->button.label_x = aButton->button.internal_width +
493                                  aButton->primitive.highlight_thickness;
494           }
495 
496     aButton->button.label_y =
497        (((int)aButton->core.height - (int)aButton->button.label_height) >> 1)
498  	 + aButton->button.font->max_bounds.ascent;
499 }
500 
501 /*************************************<->*************************************
502  *
503  *  Initialize
504  *
505  *   Description:
506  *   -----------
507  *    If the core height and width fields are set to 0, treat that as a flag
508  *    and compute the optimum size for this button.  Then using what ever
509  *    the core fields are set to, compute the text placement fields.
510  *    Make sure that the label location field is properly set for the
511  *    Resize call.
512  *************************************<->***********************************/
Initialize(request,new)513 static void Initialize (request, new)
514  Widget request, new;
515 {
516      XwToggleWidget cbox = (XwToggleWidget) new;
517 
518     if ((cbox->button.label_location != XwLEFT) &&
519           (cbox->button.label_location != XwRIGHT))
520       {
521         cbox->button.label_location = XwLEFT;
522 	XtWarning ("XwToggle Initialize: invalid label location setting.");
523       }
524 
525     if (request->core.width == 0)  cbox->core.width +=
526            cbox->button.label_width +
527 	      2 * cbox->button.internal_width +    /* white space */
528 		   cbox->button.label_height +    /* size of box */
529 		       cbox->button.label_height/SPACE_FACTOR  +    /* space */
530 		    2 * cbox->primitive.highlight_thickness;
531 
532     if (request->core.height == 0) cbox->core.height +=
533            cbox->button.label_height + 2 * cbox->button.internal_height
534 	      + 2 * cbox->primitive.highlight_thickness;
535 
536 /* dana change */
537     if (!cbox->toggle.square) cbox->core.height += 2;
538 
539     GetSelectGC (new);
540     Resize (new);
541 }
542 
543 
544 
545 
546 
547 /************************************************************************
548  *
549  *  Destroy
550  *	Free toggle's graphic context.
551  *
552  ************************************************************************/
553 
Destroy(tw)554 static void Destroy (tw)
555 XwToggleWidget tw;
556 
557 {
558    XtDestroyGC (tw -> toggle.select_GC);
559 }
560 
561 
562 
563 
564 
565 /*************************************<->*************************************
566  *
567  *  DrawToggle(w)
568  *
569  *   Description:
570  *   -----------
571  *     Depending on the state of this widget, draw the Toggle.
572  *
573  *
574  *   Inputs:
575  *   ------
576  *     w = widget to be (re)displayed.
577  *
578  *************************************<->***********************************/
579 
DrawToggle(w,all)580 static void DrawToggle(w, all)
581    XwToggleWidget w;
582    Boolean all;         /* redo all, or just center? */
583 {
584    int x, y, edge;
585 
586    /***************************************************************
587     * Determine whether label should appear to the left or
588     * the right of the box and set label X coordinate accordingly.
589     ****************************************************************/
590 
591    edge = Min((int)w->button.label_height,
592 	      Max(0, (int)w->core.height - 2*(w->primitive.highlight_thickness
593 		   + (int)w->button.internal_height)));
594 
595    if (w->button.label_location == XwRIGHT)
596         x= w->button.internal_width + w->primitive.highlight_thickness;
597    else
598 	x= Max(0, (int)w->core.width - (int)w->button.internal_width
599 	   - w->primitive.highlight_thickness - edge);      /* size of box */
600 
601    y= Max(0, ((int)w->core.height - edge) / 2);
602 
603    if (w->toggle.square)
604    {
605       _XwDrawBox (XtDisplay (w), XtWindow (w),
606                      w -> button.normal_GC, T_BW,
607                      x, y, edge, edge);
608       if (edge > 6) XFillRectangle (XtDisplay ((Widget) w),
609                                     XtWindow ((Widget) w),
610                                     ((w->button.set) ? w -> toggle.select_GC :
611                                                        w -> button.inverse_GC),
612                                     x+3, y+3, edge-6, edge-6);
613    }
614    else
615       DrawDiamondButton ((XwButtonWidget) w, x-1, y-1, edge+2,
616                          w -> button.normal_GC,
617                          ((w->button.set) ?
618                            w -> toggle.select_GC :
619                            w -> button.inverse_GC));
620 }
621 
622 
623 
624 
625 /*************************************<->*************************************
626  *
627  *  ClassInitialize
628  *
629  *   Description:
630  *   -----------
631  *    Set fields in primitive class part of our class record so that
632  *    the traversal code can invoke our button select procedures.
633  *
634  *************************************<->***********************************/
ClassInitialize()635 static void ClassInitialize()
636 {
637    XwtoggleClassRec.primitive_class.select_proc = (XwEventProc) Select;
638    XwtoggleClassRec.primitive_class.release_proc = (XwEventProc) Unselect;
639    XwtoggleClassRec.primitive_class.toggle_proc = (XwEventProc) Toggle;
640 }
641 
642 
643 /*************************************<->*************************************
644  *
645  *  Redisplay (w, event)
646  *
647  *   Description:
648  *   -----------
649  *     Cause the widget, identified by w, to be redisplayed.
650  *
651  *
652  *   Inputs:
653  *   ------
654  *     w = widget to be redisplayed;
655  *     event = event structure identifying need for redisplay on this
656  *             widget.
657  *
658  *   Outputs:
659  *   -------
660  *
661  *   Procedures Called
662  *   -----------------
663  *   XDrawString()
664  *   DrawToggle()     [Toggle.c]
665  *   ComputeSpace()   [Toggle.c]
666  *************************************<->***********************************/
667 
Redisplay(w,event)668 static void Redisplay(w, event)
669     Widget w;
670     XEvent *event;
671 {
672    register XwToggleWidget cbox = (XwToggleWidget) w;
673 
674    if (cbox->button.label_len > 0)
675           XDrawString( XtDisplay(w), XtWindow(w),  cbox->button.normal_GC,
676 	               cbox->button.label_x, cbox->button.label_y,
677     	               cbox->button.label, cbox->button.label_len);
678    DrawToggle(cbox, TRUE);
679    ComputeSpace(w, TRUE);
680 }
681 
682 
683 
684 /*************************************<->*************************************
685  *
686  *  SetValues(current, request, new)
687  *
688  *   Description:
689  *   -----------
690  *     This is the set values procedure for the Toggle class.  It is
691  *     called last (the set values rtnes for its superclasses are called
692  *     first).
693  *
694  *
695  *   Inputs:
696  *   ------
697  *    current = original widget;
698  *    request = copy of current (?);
699  *    new = copy of request which reflects changes made to it by
700  *          set values procedures of its superclasses;
701  *
702  *
703  *************************************<->***********************************/
704 
SetValues(current,request,new)705 static Boolean SetValues(current, request, new)
706     Widget current, request, new;
707 {
708     XwToggleWidget curcbox = (XwToggleWidget) current;
709     XwToggleWidget newcbox = (XwToggleWidget) new;
710     Boolean  flag = FALSE;    /* our return value */
711 
712 
713     /**********************************************************************
714      * Calculate the window size:  The assumption here is that if
715      * the width and height are the same in the new and current instance
716      * record that those fields were not changed with set values.  Therefore
717      * its okay to recompute the necessary width and height.  However, if
718      * the new and current do have different width/heights then leave them
719      * alone because that's what the user wants.
720      *********************************************************************/
721 
722     if ((curcbox->core.width == newcbox->core.width) &&
723         (_XwRecomputeSize(current, new)))
724      {
725 	newcbox->core.width =
726 	    newcbox->button.label_width +2*newcbox->button.internal_width
727 	       + newcbox->button.label_height +
728 		  newcbox->button.label_height/SPACE_FACTOR +
729      		    2 * newcbox->primitive.highlight_thickness;
730 	flag = TRUE;
731      }
732 
733     if ((curcbox->core.height == newcbox->core.height) &&
734         (_XwRecomputeSize(current, new)))
735      {
736 	newcbox->core.height =
737 	    newcbox->button.label_height + 2*newcbox->button.internal_height +
738      		    2 * newcbox->primitive.highlight_thickness;
739 	flag = TRUE;
740      }
741 
742 
743     if (curcbox -> toggle.select_color != newcbox -> toggle.select_color)
744     {
745        XtDestroyGC (newcbox -> toggle.select_GC);
746        GetSelectGC (newcbox);
747        flag = True;
748     }
749 
750 
751     if (curcbox -> toggle.square != newcbox -> toggle.square)
752     {
753        flag = True;
754     }
755 
756 
757     Resize(new);  /* fix label x and label y positioning */
758     return(flag);
759 }
760 
761 
762 
763 
764 
765 /************************************************************************
766  *
767  *  DrawDiamondButton()
768  *	The dimond drawing routine.  Used in place of primitives
769  *	draw routine when toggle's square flag is False.
770  *
771  ************************************************************************/
772 
773 
DrawDiamondButton(bw,x,y,size,borderGC,centerGC)774 static void DrawDiamondButton (bw, x, y, size, borderGC, centerGC)
775 XwButtonWidget bw;
776 int x, y, size;
777 GC borderGC, centerGC;
778 
779 
780 {
781    XSegment seg[8];
782    XPoint   pt[5];
783    int midX, midY;
784 
785    if (size % 2 == 0)
786       size--;
787 
788    midX = x + (size + 1) / 2;
789    midY = y + (size + 1) / 2;
790 
791 
792    /*  The top segments  */
793 
794    seg[0].x1 = x;			/*  1  */
795    seg[0].y1 = midY - 1;
796    seg[0].x2 = midX - 1;		/*  2  */
797    seg[0].y2 = y;
798 
799    seg[1].x1 = x + 1;			/*  3  */
800    seg[1].y1 = midY - 1;
801    seg[1].x2 = midX - 1;		/*  4  */
802    seg[1].y2 = y + 1;
803 
804    seg[2].x1 = midX - 1;		/*  5  */
805    seg[2].y1 = y;
806    seg[2].x2 = x + size - 1;		/*  6  */
807    seg[2].y2 = midY - 1;
808 
809    seg[3].x1 = midX - 1;		/*  7  */
810    seg[3].y1 = y + 1;
811    seg[3].x2 = x + size - 2;		/*  8  */
812    seg[3].y2 = midY - 1;
813 
814 
815    /*  The bottom segments  */
816 
817    seg[4].x1 = x;			/*  9  */
818    seg[4].y1 = midY - 1;
819    seg[4].x2 = midX - 1;		/*  10  */
820    seg[4].y2 = y + size - 1;
821 
822    seg[5].x1 = x + 1;			/*  11  */
823    seg[5].y1 = midY - 1;
824    seg[5].x2 = midX - 1;		/*  12  */
825    seg[5].y2 = y + size - 2;
826 
827    seg[6].x1 = midX - 1;		/*  13  */
828    seg[6].y1 = y + size - 1;
829    seg[6].x2 = x + size - 1;		/*  14  */
830    seg[6].y2 = midY - 1;
831 
832    seg[7].x1 = midX - 1;		/*  15  */
833    seg[7].y1 = y + size - 2;
834    seg[7].x2 = x + size - 2;		/*  16  */
835    seg[7].y2 = midY - 1;
836 
837    XDrawSegments (XtDisplay ((Widget) bw), XtWindow ((Widget) bw),
838                   borderGC, &seg[2], 2);
839 
840    XDrawSegments (XtDisplay ((Widget) bw), XtWindow ((Widget) bw),
841                   borderGC, &seg[4], 4);
842 
843    XDrawSegments (XtDisplay ((Widget) bw), XtWindow ((Widget) bw),
844                   borderGC, &seg[0], 2);
845 
846 
847    pt[0].x = x + 3;
848    pt[0].y = midY - 1;
849    pt[1].x = midX - 1;
850    pt[1].y = y + 3;
851    pt[2].x = x + size - 4;
852    pt[2].y = midY - 1;
853    pt[3].x = midX - 2;
854    pt[3].y = y + size - 4;
855 
856    XFillPolygon (XtDisplay ((Widget) bw), XtWindow ((Widget) bw),
857                  centerGC, pt, 4, Convex, CoordModeOrigin);
858 }
859