Fix dttypes for BSD systems
[oweals/cde.git] / cde / programs / dtwm / Button.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: Button.c /main/7 1995/11/14 10:03:27 rswiston $ */
24 #ifdef REV_INFO
25 #ifndef lint
26 static char SCCSID[] = "OSF/Motif: @(#)Button.c 1.19 95/05/01";
27 #endif /* lint */
28 #endif /* REV_INFO */
29 /******************************************************************************
30 *******************************************************************************
31 *
32 *  (c) Copyright 1992 HEWLETT-PACKARD COMPANY
33 *  ALL RIGHTS RESERVED
34 *  
35 *******************************************************************************
36 ******************************************************************************/
37 #include <stdio.h>
38 #include <X11/cursorfont.h>
39 #include "ButtonP.h"
40 #include <Xm/ManagerP.h>
41 #include <Xm/DrawP.h>
42 #include <Dt/Control.h>
43 #include <Dt/MacrosP.h>
44 #include <Dt/DtStrDefs.h>
45
46 #define DELAY_DEFAULT 100       
47
48 static void Initialize( 
49                         Widget request_w,
50                         Widget new_w) ;
51 static void GetGCs( 
52                         Widget w) ;
53 static void UpdateGCs( 
54                         Widget w) ;
55 static void Redisplay( 
56                         Widget w,
57                         XEvent *event,
58                         Region region) ;
59 static Boolean SetValues( 
60                         Widget current_w,
61                         Widget request_w,
62                         Widget new_w) ;
63 static void Arm( 
64                         Widget w,
65                         XEvent *event,
66                         String *params,
67                         Cardinal *num_params) ;
68 static void Disarm( 
69                         Widget w,
70                         XEvent *event,
71                         String *params,
72                         Cardinal *num_params) ;
73 static void Activate( 
74                         Widget w,
75                         XEvent *event,
76                         String *params,
77                         Cardinal *num_params) ;
78 static void ArmAndActivate( 
79                         Widget w,
80                         XEvent *event,
81                         String *params,
82                         Cardinal *num_params) ;
83 static void InputDispatch(
84                         Widget w,
85                         XButtonEvent *event,
86                         Mask event_mask) ;
87 static Boolean VisualChange(
88                         Widget w,
89                         Widget current_w,
90                         Widget new_w) ;
91 static void ArmTimeout( 
92                         Widget w,
93                         XtIntervalId *id) ;
94 static void Enter( 
95                         Widget wid,
96                         XEvent *event,
97                         String *params,
98                         Cardinal *num_params) ;
99 static void Leave( 
100                         Widget wid,
101                         XEvent *event,
102                         String *params,
103                         Cardinal *num_params) ;
104 static void CallCallback( 
105                         DtButtonGadget g,
106                         XtCallbackList cb,
107                         int reason,
108                         XEvent *event) ;
109 static void DefaultSelectColor(
110                         Widget widget,
111                         int offset,
112                         XrmValue *value) ;
113
114 /*  Resource list for button  */
115
116 #define R_Offset(field) \
117         XtOffset (DtButtonGadget, button.field)
118 static XtResource resources[] = 
119 {
120         {
121                 XmNcursorFont,
122                 XmCCursorFont, XmRInt, sizeof (int),
123                 R_Offset (cursor_font),
124                 XmRImmediate, (XtPointer) 1
125         },
126         {
127                 XmNarmColor,
128                 XmCArmColor, XmRPixel, sizeof (Pixel),
129                 R_Offset (arm_color),
130                 XmRCallProc, (XtPointer) DefaultSelectColor
131         },
132         {
133                 XmNsubpanel,
134                 XmCSubpanel, XmRWidget, sizeof (Widget),
135                 R_Offset (subpanel),
136                 XmRImmediate, (XtPointer) NULL
137         },
138         {
139                 XmNpushFunction,
140                 XmCPushFunction, XmRFunction, sizeof (XtPointer),
141                 R_Offset (push_function),
142                 XmRImmediate, (XtPointer) NULL
143         },
144         {
145                 XmNpushArgument,
146                 XmCPushArgument, XmRPointer, sizeof (XtPointer),
147                 R_Offset (push_argument),
148                 XmRImmediate, (XtPointer) NULL
149         },
150         {
151                 XmNimageName,
152                 XmCString, XmRString, sizeof (String),
153                 R_Offset (image_name),
154                 XmRImmediate, (XtPointer) ""
155         },
156
157         {
158                 XmNcallback,
159                 XmCCallback, XmRCallback, sizeof(XtCallbackList),
160                 R_Offset (callback),
161                 XmRImmediate, (caddr_t) NULL
162         },
163
164         {
165                 XmNmultiClick,
166                 XmCMultiClick, XmRMultiClick, sizeof (unsigned char),
167                 R_Offset (multiClick),
168                 XmRImmediate, (XtPointer) XmMULTICLICK_KEEP
169         }
170 };
171
172
173 /*  The button class record definition  */
174
175 externaldef (dtbuttongadgetclassrec)
176         DtButtonGadgetClassRec dtButtonGadgetClassRec=
177 {
178    {
179       (WidgetClass) &xmGadgetClassRec,  /* superclass            */     
180       "DtButton",                       /* class_name            */     
181       sizeof(DtButtonGadgetRec),        /* widget_size           */     
182       NULL,                             /* class_initialize      */    
183       NULL,                             /* class_part_initialize */
184       FALSE,                            /* class_inited          */     
185       (XtInitProc) Initialize,          /* initialize            */     
186       NULL,                             /* initialize_hook       */
187       NULL,                             /* realize               */     
188       NULL,                             /* actions               */     
189       0,                                /* num_actions           */     
190       resources,                        /* resources             */     
191       XtNumber(resources),              /* num_resources         */     
192       NULLQUARK,                        /* xrm_class             */     
193       TRUE,                             /* compress_motion       */     
194       XtExposeCompressMaximal,          /* compress_exposure     */     
195       TRUE,                             /* compress_enterleave   */
196       FALSE,                            /* visible_interest      */     
197       NULL,                             /* destroy               */     
198       NULL,                             /* resize                */
199       (XtExposeProc) Redisplay,         /* expose                */     
200       (XtSetValuesFunc) SetValues,      /* set_values            */     
201       NULL,                             /* set_values_hook       */
202       XtInheritSetValuesAlmost,         /* set_values_almost     */
203       NULL,                             /* get_values_hook       */
204       NULL,                             /* accept_focus          */     
205       XtVersion,                        /* version               */
206       NULL,                             /* callback private      */
207       NULL,                             /* tm_table              */
208       NULL,                             /* query_geometry        */
209       NULL,                             /* display_accelerator   */
210       NULL,                             /* extension             */
211    },
212
213    /*      XmGadget Part     */
214    {
215       (XtWidgetProc) _XtInherit,           /* Gadget border_highlight   */
216       (XtWidgetProc) _XtInherit,           /* Gadget border_unhighlight */
217       ArmAndActivate,                      /* arm_and_activate          */
218       (XmWidgetDispatchProc)InputDispatch, /* input_dispatch            */
219       VisualChange,                        /* visual_change             */
220       NULL,                                /* get resources             */
221       0,                                   /* num get_resources         */
222       NULL,                                /* class_cache_part          */
223       NULL,                                /* extension                 */
224    }
225
226 };
227
228 externaldef(dtbuttonwidgetclass) WidgetClass dtButtonGadgetClass =
229                           (WidgetClass) &dtButtonGadgetClassRec;
230
231
232 /************************************************************************
233  *
234  *  Initialize
235  *     The main widget instance initialization routine.
236  *
237  ************************************************************************/
238
239 static void 
240 Initialize(
241         Widget request_w,
242         Widget new_w )
243 {
244    DtButtonGadget request = (DtButtonGadget) request_w ;
245    DtButtonGadget new_g = (DtButtonGadget) new_w ;
246    XmManagerWidget mw = (XmManagerWidget) XtParent(new_w) ;
247
248    new_g->button.timer = 0;
249    new_g->button.click_count = 0;
250    new_g->button.armTimeStamp = 0;
251    new_g->button.activateTimeStamp = 0;
252
253    B_Armed (new_g) = False;
254
255 /* Set the input mask for events handled by Manager.
256 */
257    G_EventMask (new_g) = (XmARM_EVENT | XmACTIVATE_EVENT |
258                         XmMULTI_ARM_EVENT | XmMULTI_ACTIVATE_EVENT |
259                         XmHELP_EVENT | XmFOCUS_IN_EVENT |
260                         XmFOCUS_OUT_EVENT | XmENTER_EVENT | XmLEAVE_EVENT);
261
262 /*      Get pixmap and mask, get pixmap geometry, get gcs.
263  */
264    if (B_ImageName (new_g) != NULL)
265    {
266        String str = B_ImageName (new_g);
267        B_ImageName (new_g) = XtMalloc (strlen (str) + 1);
268        strcpy (B_ImageName (new_g), str);
269
270        B_Pixmap (new_g) =
271                    XmGetPixmap (XtScreen (new_g), B_ImageName (new_g),
272                                    M_BottomShadowColor (mw),
273                                    M_TopShadowColor (mw));
274        B_Mask (new_g) =
275                    _DtGetMask (XtScreen (new_g), B_ImageName (new_g));
276
277        if (B_Pixmap (new_g) != XmUNSPECIFIED_PIXMAP)
278        {
279            Window               root;
280            int          int_x = 0, int_y = 0;
281            unsigned int int_w = 0, int_h = 0,
282                            int_bw, depth;
283
284            XGetGeometry (XtDisplay (new_g), B_Pixmap (new_g),
285                            &root, &int_x, &int_y, &int_w, &int_h,
286                            &int_bw, &depth);
287
288            B_PixmapWidth (new_g) = (Dimension) int_w;
289            B_PixmapHeight (new_g) = (Dimension) int_h;
290        }
291        else
292        {
293            B_PixmapWidth (new_g) = 0;
294            B_PixmapHeight (new_g) = 0;
295        }
296    }
297    else
298    {
299        B_Pixmap (new_g) = XmUNSPECIFIED_PIXMAP;
300        B_Mask (new_g) = XmUNSPECIFIED_PIXMAP;
301        B_PixmapWidth (new_g) = 0;
302        B_PixmapHeight (new_g) = 0;
303    }
304
305    GetGCs (new_w);
306
307 /*      Set widget geometry.
308  */
309    new_g -> gadget.shadow_thickness = 1;
310    new_g -> gadget.highlight_thickness = 1;
311    if (G_Width(request) == 0)
312        {
313        if (B_PixmapWidth (new_g) > 0)
314            G_Width(new_g) = B_PixmapWidth (new_g) + 4;
315        else
316            G_Width(new_g) = 10;
317        }
318    if (G_Height(request) == 0)
319        {
320        if (B_PixmapHeight (new_g) > 0)
321            G_Height(new_g) = B_PixmapHeight (new_g) + 4;
322        else
323            G_Height(new_g) = 10;
324        }
325 }
326
327
328
329
330 /************************************************************************
331  *
332  *  GetGCs
333  *     Get the graphics context used for drawing the button.
334  *
335  ************************************************************************/
336
337 static void 
338 GetGCs(
339         Widget w )
340 {
341 DtButtonGadget bg = (DtButtonGadget) w ;
342 XmManagerWidget mw = (XmManagerWidget) XtParent(w) ;
343 XGCValues values;
344 XtGCMask  valueMask;
345
346 valueMask = GCForeground | GCBackground;
347
348 values.foreground = M_Foreground(mw);
349 values.background = M_Background(mw);
350 bg -> button.gc_normal = XtGetGC ((Widget) mw, valueMask, &values);
351
352 values.foreground = B_ArmColor (bg);
353 bg -> button.gc_armed_bg = XtGetGC ((Widget) mw, valueMask, &values);
354
355 values.foreground = M_Background(mw);
356 values.background = M_Foreground(mw);
357 bg -> button.gc_background = XtGetGC ((Widget) mw, valueMask, &values);
358
359 /*      Get Clip GC
360  */
361 if (B_Mask(bg) != XmUNSPECIFIED_PIXMAP) 
362     {
363     valueMask = GCForeground | GCBackground | GCClipMask;
364     values.clip_mask = B_Mask(bg);
365     values.foreground = M_Foreground (mw);
366     values.background = M_Background (mw);
367     bg->button.gc_clip = XtGetGC ((Widget) mw, valueMask, &values);
368     }
369 else
370     bg->button.gc_clip = NULL;
371 }
372
373
374 static void 
375 UpdateGCs(
376         Widget w )
377 {
378    DtButtonGadget bg = (DtButtonGadget) w ;
379    XmManagerWidget mw = (XmManagerWidget) XtParent(w) ;
380    XGCValues values;
381
382    XtReleaseGC ((Widget) mw, bg->button.gc_normal);
383    XtReleaseGC ((Widget) mw, bg->button.gc_background);
384    XtReleaseGC ((Widget) mw, bg->button.gc_armed_bg);
385
386    if (bg->button.gc_clip != NULL) 
387       XtReleaseGC ((Widget) mw, bg->button.gc_clip);
388
389    GetGCs (w);
390 }
391
392
393 /************************************************************************
394  *
395  *  Redisplay
396  *     General redisplay function called on exposure events.
397  *
398  ************************************************************************/
399 /* ARGSUSED */
400 static void 
401 Redisplay(
402         Widget w,
403         XEvent *event,
404         Region region )
405 {
406 DtButtonGadget bg = (DtButtonGadget) w;
407 XmManagerWidget mw = (XmManagerWidget) XtParent(w);
408 Dimension       s_t = bg -> gadget.shadow_thickness;
409 Dimension       h_t = bg -> gadget.highlight_thickness;
410 Position        x;
411 Pixmap  pix;
412 GC      gc;
413
414 gc = (B_Armed (bg)) ? bg -> button.gc_armed_bg : bg -> button.gc_background;
415 XFillRectangle (XtDisplay (bg), XtWindow (bg),
416                 gc, G_X(bg) +s_t + h_t, G_Y(bg) + s_t + h_t,
417                 G_Width(bg) - 2 * (s_t + h_t),
418                 G_Height(bg) - 2 * (s_t + h_t));
419
420 if (s_t > 0)
421     {
422     GC  gc1, gc2;
423     if (B_Armed (bg))
424         {
425         gc1 = XmParentBottomShadowGC(w);
426         gc2 = XmParentTopShadowGC(w);
427         }
428     else
429         {
430         gc1 = bg -> button.gc_background;
431         gc2 = bg -> button.gc_background;
432         }
433     XmeDrawShadows (XtDisplay(bg), XtWindow (bg), gc1, gc2, 
434                           G_X(bg) + h_t, G_Y(bg) + h_t,
435                           G_Width(bg) - 2 * h_t, G_Height(bg) - 2 * h_t,
436                           s_t,XmSHADOW_OUT);
437     }
438
439 x = G_X(bg) + ((Position)(G_Width(bg) - B_PixmapWidth (bg))/2);
440 if (x % 2 == 1)
441     x++;
442
443 if (B_Mask (bg) != XmUNSPECIFIED_PIXMAP)
444     {
445     gc = bg->button.gc_clip;
446     XSetClipMask (XtDisplay(bg), gc, B_Mask (bg));
447     XSetClipOrigin (XtDisplay(bg), gc,
448                 x, G_Y(bg) + (Position)(G_Height(bg) - B_PixmapHeight (bg))/2);
449     }
450 else
451     gc = bg->button.gc_normal;
452
453 pix = B_Pixmap (bg);
454 if ((gc != NULL) && (pix != XmUNSPECIFIED_PIXMAP))
455     {   
456     XCopyArea (XtDisplay ((Widget) bg), pix, XtWindow ((Widget) bg), gc, 0, 0,
457                 B_PixmapWidth (bg), B_PixmapHeight (bg),
458                 x, G_Y(bg) + (Position)(G_Height(bg) - B_PixmapHeight (bg))/2);
459     }
460
461 if (bg -> gadget.highlighted)
462    (*(xmGadgetClassRec.gadget_class.border_highlight))((Widget) bg);
463
464 }
465
466
467 /************************************************************************
468  *
469  *  Destroy
470  *      Clean up allocated resources when the widget is destroyed.
471  *
472  ************************************************************************/
473 #if 0
474 static void 
475 Destroy(
476         Widget w )
477 {
478 DtButtonGadget bg = (DtButtonGadget) w ;
479
480 if (bg->button.timer)
481     XtRemoveTimeOut (bg->button.timer);
482
483 XtReleaseGC (w, bg -> button.gc_normal);
484 XtReleaseGC (w, bg -> button.gc_background);
485 XtReleaseGC (w, bg -> button.gc_armed_bg);
486 if (bg -> button.gc_clip != NULL) 
487     XtReleaseGC (w, bg -> button.gc_clip);
488
489 XtRemoveAllCallbacks (w, "callback");
490 }
491 #endif /* 0 */
492
493
494
495 /************************************************************************
496  *
497  *  SetValues
498  *      Note:  The only implementation within this function is to
499  *      support the resetting of the image, cursor, and functions
500  *      as needed by the front panel.
501  *
502  ************************************************************************/
503
504 /* ARGSUSED */
505 static Boolean 
506 SetValues(
507         Widget current_w,
508         Widget request_w,
509         Widget new_w )
510
511 {
512    DtButtonGadget  current = (DtButtonGadget) current_w;
513    DtButtonGadget  request = (DtButtonGadget) request_w;
514    DtButtonGadget  new_g = (DtButtonGadget) new_w;
515    XmManagerWidget mw = (XmManagerWidget) XtParent(new_w);
516    Boolean          returnFlag = FALSE;
517    Cursor           cursor;
518
519    G_EventMask (new_g) = (XmARM_EVENT | XmACTIVATE_EVENT |
520                         XmMULTI_ARM_EVENT | XmMULTI_ACTIVATE_EVENT |
521                         XmHELP_EVENT | XmFOCUS_IN_EVENT |
522                         XmFOCUS_OUT_EVENT | XmENTER_EVENT | XmLEAVE_EVENT);
523
524    /*  Change the image  */
525
526    if (strcmp (B_ImageName (current), B_ImageName (new_g)) != 0)
527    {
528       String str = B_ImageName (new_g);
529
530       XtFree (B_ImageName (current));
531       B_ImageName (new_g) = XtMalloc (strlen (str) + 1);
532       strcpy (B_ImageName (new_g), str);
533
534       B_Pixmap (new_g) =
535          XmGetPixmap (XtScreen (new_g), B_ImageName (new_g),
536                       M_BottomShadowColor (mw),
537                       M_TopShadowColor (mw));
538       B_Mask (new_g) =
539          _DtGetMask (XtScreen (new_g), B_ImageName (new_g));
540
541       if (B_Pixmap (new_g) != XmUNSPECIFIED_PIXMAP)
542       {
543          Window       root;
544          int          int_x = 0, int_y = 0;
545          unsigned int int_w = 0, int_h = 0,
546                       int_bw, depth;
547
548          XGetGeometry (XtDisplay (new_g), B_Pixmap (new_g),
549                        &root, &int_x, &int_y, &int_w, &int_h, &int_bw, &depth);
550
551          B_PixmapWidth (new_g) = (Dimension) int_w;
552          B_PixmapHeight (new_g) = (Dimension) int_h;
553       }
554       else
555       {
556          B_PixmapWidth (new_g) = 0;
557          B_PixmapHeight (new_g) = 0;
558       }
559
560       UpdateGCs(new_w);
561
562       returnFlag = TRUE;
563    }
564    else
565    {
566       if (B_ImageName (new_g) != B_ImageName (current))
567       {
568          String str = B_ImageName (new_g);
569
570          XtFree (B_ImageName (current));
571          B_ImageName (new_g) = XtMalloc (strlen (str) + 1);
572          strcpy (B_ImageName (new_g), str);
573       }
574    }
575
576    return (returnFlag);
577 }
578
579
580
581
582 /************************************************************************
583  *
584  *  arm
585  *     This function processes button 1 down occuring on the button.
586  *
587  ************************************************************************/
588
589 static void 
590 Arm(
591         Widget w,
592         XEvent *event,
593         String *params,
594         Cardinal *num_params )
595 {
596    DtButtonGadget bg = (DtButtonGadget) w ;
597
598    (void) XmProcessTraversal((Widget) bg, XmTRAVERSE_CURRENT);
599
600    B_Armed (bg) = True;
601
602    if ((event->xbutton.time - bg->button.armTimeStamp) >
603        XtGetMultiClickTime(XtDisplay(bg)))
604    {
605       bg -> button.armTimeStamp = event->xbutton.time;
606       B_Expose ( w, event, NULL);
607    }
608 }
609
610
611 /************************************************************************
612  *
613  *  disarm
614  *     This function processes button 1 up occuring on the button.
615  *
616  ************************************************************************/
617
618 static void 
619 Disarm(
620         Widget w,
621         XEvent *event,
622         String *params,
623         Cardinal *num_params )
624 {
625    DtButtonGadget bg = (DtButtonGadget) w ;
626
627    B_Armed (bg) = False;
628
629    B_Expose (w, event, NULL);
630 }
631
632
633 /************************************************************************
634  *
635  *  activate
636  *     This function processes button 1 up occuring on the button.
637  *     If the button 1 up occurred inside the button the activate
638  *     callbacks are called.
639  *
640  ************************************************************************/
641
642 static void 
643 Activate(
644         Widget w,
645         XEvent *event,
646         String *params,
647         Cardinal *num_params )
648 {
649    DtButtonGadget bg = (DtButtonGadget) w ;
650    DtButtonCallbackStruct call_value;
651    Dimension bw = G_BorderWidth(bg);
652
653    if (!B_Armed (bg))
654       return;
655
656    if ((event->xbutton.time - bg->button.activateTimeStamp) >
657        XtGetMultiClickTime(XtDisplay(bg)))
658    {
659       bg -> button.activateTimeStamp = event->xbutton.time;
660       bg->button.click_count = 1;
661    }
662    else
663       bg->button.click_count++;
664
665    B_Armed (bg) = False;
666
667    if (bg->button.callback)
668    {
669       call_value.reason = XmCR_ACTIVATE;
670       call_value.event = event;
671       call_value.click_count = bg->button.click_count;
672
673       if ((bg->button.multiClick == XmMULTICLICK_DISCARD) &&
674           (call_value.click_count > 1)) { 
675           return;
676       }
677
678       XFlush(XtDisplay(bg));
679
680       CallCallback (bg, B_Callback (bg), XmCR_ACTIVATE, event);
681    }
682 }
683
684
685 /************************************************************************
686  *
687  *     ArmAndActivate
688  *
689  ************************************************************************/
690
691 static void 
692 ArmAndActivate(
693         Widget w,
694         XEvent *event,
695         String *params,
696         Cardinal *num_params )
697 {
698    DtButtonCallbackStruct call_value;
699    DtButtonGadget bg = (DtButtonGadget) w ;
700
701    B_Armed (bg) = True;
702    Redisplay ( w, event, FALSE); 
703
704    XFlush (XtDisplay (bg));
705
706    call_value.reason = XmCR_ACTIVATE;
707    call_value.event = event;
708    call_value.click_count = 1;  /* always 1 in kselect */
709
710    if (bg->button.callback)
711    {
712       XFlush (XtDisplay (bg));
713       CallCallback (bg, B_Callback (bg), XmCR_ACTIVATE, event);
714    }
715    B_Armed (bg) = False;
716
717    /* If the button is still around, show it released, after a short delay */
718
719    if (bg->object.being_destroyed == False)
720    {
721       bg->button.timer = XtAppAddTimeOut(
722                         XtWidgetToApplicationContext((Widget)bg),
723                         (unsigned long) DELAY_DEFAULT,
724                         (XtTimerCallbackProc)ArmTimeout,
725                         (caddr_t)bg);
726    }
727 }
728
729 /* ARGSUSED */
730 static void 
731 ArmTimeout(
732         Widget w,
733         XtIntervalId *id )
734 {
735     DtButtonGadget bg = (DtButtonGadget) w ;
736
737     bg -> button.timer = 0;
738     if (XtIsRealized ((Widget)bg) && XtIsManaged ((Widget)bg)) {
739        Redisplay ( w, NULL, FALSE); 
740        XFlush (XtDisplay (bg));
741     }
742     return;
743 }
744
745
746 /*-------------------------------------------------------------
747 **      InputDispatch
748 **              Process event dispatched from parent or event handler.
749 */
750 static void
751 InputDispatch(
752         Widget w,
753         XButtonEvent *event,
754         Mask event_mask )
755 {
756         DtButtonGadget bg = (DtButtonGadget) w ;
757
758         if (event_mask & XmARM_EVENT ||
759             event_mask & XmMULTI_ARM_EVENT)
760         {
761            if (event->button == Button1)
762              Arm (w, (XEvent*) event, (String *)NULL, (Cardinal)0);
763         }
764         else if (event_mask & XmACTIVATE_EVENT ||
765                  event_mask & XmMULTI_ACTIVATE_EVENT)
766         {
767                 if (event->button == Button1)
768                 {
769                    if (event->x >= G_X (bg) &&
770                          event->x <= (Position)(G_X (bg) + G_Width (bg)) &&
771                          event->y >= G_Y (bg) &&
772                          event->y <= (Position)(G_Y (bg) + G_Height (bg)))
773                    {
774                         Activate (w, (XEvent*) event,
775                                   (String *)NULL, (Cardinal)0);
776                         Disarm (w, (XEvent*) event,
777                                   (String *)NULL, (Cardinal)0);
778                    }
779                    else
780                         Disarm (w, (XEvent*) event,
781                                   (String *)NULL, (Cardinal)0);
782                 }
783         }
784         else if (event_mask & XmHELP_EVENT)
785                 _XmSocorro (w, (XEvent *)event,
786                                      (String *)NULL,(Cardinal)0);
787         else if (event_mask & XmENTER_EVENT)
788                 Enter (w, (XEvent *)event, (String *)NULL,(Cardinal)0);
789         else if (event_mask & XmLEAVE_EVENT)
790                 Leave (w, (XEvent *)event, (String *)NULL,(Cardinal)0);
791         else if (event_mask & XmFOCUS_IN_EVENT)
792                 _XmFocusInGadget (w, (XEvent *)event,
793                                     (String *)NULL,(Cardinal)0);
794         else if (event_mask & XmFOCUS_OUT_EVENT)
795                 _XmFocusOutGadget (w, (XEvent *)event,
796                                     (String *)NULL,(Cardinal)0);
797 }
798
799
800 /*-------------------------------------------------------------
801 **      VisualChange
802 **              Update GCs when parent visuals change.
803 */
804 static Boolean
805 VisualChange(
806         Widget w,
807         Widget current_w,
808         Widget new_w )
809 {
810     XmManagerWidget  current = (XmManagerWidget) current_w;
811     XmManagerWidget  new_m = (XmManagerWidget) new_w;
812     DtButtonGadget   bg = (DtButtonGadget) w ;
813     Boolean          update = False;
814
815     /* If the parent foreground or background has changed,
816      * then update gcs and pixmap.
817      */
818     if (M_Foreground (current) != M_Foreground (new_m) ||
819         M_Background (current) != M_Background (new_m))
820     {
821        UpdateGCs(w);
822        update = True;
823     }
824
825     if (update)
826     {
827        if (B_ImageName (bg) != NULL)
828        {
829              if (B_Mask(bg) != XmUNSPECIFIED_PIXMAP)
830                 XmDestroyPixmap (XtScreen(bg), B_Mask(bg));
831
832              if (B_Pixmap(bg) != XmUNSPECIFIED_PIXMAP)
833                 XmDestroyPixmap (XtScreen(w), B_Pixmap (bg));
834
835              B_Pixmap (bg) = XmGetPixmap (XtScreen (bg), B_ImageName (bg),
836                                          M_TopShadowColor (new_m),
837                                          M_BottomShadowColor (new_m));
838
839              if (B_Pixmap (bg) != XmUNSPECIFIED_PIXMAP)
840                B_Mask(bg) = (Pixmap)_DtGetMask(XtScreen(bg), B_ImageName(bg));
841
842              return (True);
843        }
844        else
845          return (False);
846     }
847 }
848
849 /************************************************************************
850  *
851  *  Enter
852  *
853  ************************************************************************/
854
855 static void 
856 Enter(
857         Widget wid,
858         XEvent *event,
859         String *params,
860         Cardinal *num_params )
861 {
862    DtButtonGadget bg = (DtButtonGadget) wid ;
863
864    _XmEnterGadget (wid, (XEvent *)event, (String *)NULL,(Cardinal *)0);
865
866    if (B_Armed (bg))
867       B_Expose (wid, event, NULL);
868 }
869
870
871
872
873 /************************************************************************
874  *
875  *  Leave
876  *
877  ************************************************************************/
878
879 static void 
880 Leave(
881         Widget wid,
882         XEvent *event,
883         String *params,
884         Cardinal *num_params )
885 {
886    DtButtonGadget bg = (DtButtonGadget) wid ;
887
888    _XmLeaveGadget (wid, (XEvent *)event, (String *)NULL,  (Cardinal *)0);
889
890    if (B_Armed (bg))
891    {
892       B_Armed (bg) = False;
893       B_Expose (wid, event, NULL);
894       B_Armed (bg) = True;
895    }
896 }
897
898
899 /*-------------------------------------------------------------
900 **      CallCallback
901 **              Call callback, if any, with reason and event.
902 */
903 static void 
904 CallCallback(
905         DtButtonGadget w,
906         XtCallbackList cb,
907         int reason,
908         XEvent *event )
909 {
910     DtControlCallbackStruct     cb_data;
911
912     if (cb != NULL)
913     {
914        cb_data.reason = reason;
915        cb_data.event = event;
916        cb_data.control_type = XmCONTROL_BUTTON;
917        cb_data.set = False;
918        cb_data.subpanel = B_Subpanel (w);
919        cb_data.push_function = B_PushFunction (w);
920        cb_data.push_argument = B_PushArgument (w);
921        cb_data.file_size = 0;
922        XtCallCallbackList ((Widget) w, cb, &cb_data);
923     }
924 }
925
926
927 /*-------------------------------------------------------------
928 **      DefaultSelectColor
929 **              Resource proc. to determine the default select color.
930 **              (Formerly _XmSelectColorDefault).
931 */
932 static void 
933 DefaultSelectColor(
934         Widget widget,
935         int offset,
936         XrmValue *value )
937 {
938    XmeGetDefaultPixel (widget, XmSELECT, offset, value);
939 }
940
941
942 /************************************************************************
943  *
944  *  DtCreateButtonGadget
945  *      Create an instance of an button and return the widget id.
946  *
947  ************************************************************************/
948
949 Widget 
950 DtCreateButtonGadget(
951         Widget parent,
952         char *name,
953         ArgList arglist,
954         Cardinal argcount )
955 {
956    return (XtCreateWidget (name, dtButtonGadgetClass, 
957                            parent, arglist, argcount));
958 }
959