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