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