1 /*
2 * Motif
3 *
4 * Copyright (c) 1987-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 #ifdef REV_INFO
24 #ifndef lint
25 static char rcsid[] = "$TOG: DrawnB.c /main/20 1999/04/29 13:05:14 samborn $"
26 #endif
27 #endif
28 /*
29 * Include files & Static Routine Definitions
30 */
31
32 #ifdef HAVE_CONFIG_H
33 #include <config.h>
34 #endif
35
36
37 #include <stdio.h>
38 #include <X11/X.h>
39 #include <Xm/ActivatableT.h>
40 #include <Xm/DisplayP.h>
41 #include <Xm/DrawP.h>
42 #include <Xm/DrawnBP.h>
43 #include <Xm/LabelP.h>
44 #include <Xm/ManagerP.h>
45 #include <Xm/MenuT.h>
46 #include <Xm/RowColumnP.h>
47 #include <Xm/VaSimpleP.h>
48 #include <Xm/TraitP.h>
49 #include <Xm/TransltnsP.h>
50 #include "XmI.h"
51 #include "RepTypeI.h"
52 #include "LabelI.h"
53 #include "MenuUtilI.h"
54 #include "MenuProcI.h"
55 #include "MenuStateI.h"
56 #include "PrimitiveI.h"
57 #include "TravActI.h"
58 #include "TraversalI.h"
59 #include "UniqueEvnI.h"
60
61
62 #define DELAY_DEFAULT 100
63
64 /******** Static Function Declarations ********/
65
66 static void Arm(
67 Widget wid,
68 XEvent *event,
69 String *params,
70 Cardinal *num_params) ;
71 static void MultiArm(
72 Widget wid,
73 XEvent *event,
74 String *params,
75 Cardinal *num_params) ;
76 static void Activate(
77 Widget wid,
78 XEvent *buttonEvent,
79 String *params,
80 Cardinal *num_params) ;
81 static void MultiActivate(
82 Widget wid,
83 XEvent *buttonEvent,
84 String *params,
85 Cardinal *num_params) ;
86 static void ActivateCommon(
87 Widget wid,
88 XEvent *event,
89 String *params,
90 Cardinal *num_params) ;
91 static void ArmAndActivate(
92 Widget wid,
93 XEvent *event,
94 String *params,
95 Cardinal *num_params) ;
96 static void ArmTimeout (
97 XtPointer closure,
98 XtIntervalId *id ) ;
99 static void Disarm(
100 Widget wid,
101 XEvent *event,
102 String *params,
103 Cardinal *num_params) ;
104 static void BtnDown(
105 Widget wid,
106 XEvent *event,
107 String *params,
108 Cardinal *num_params) ;
109 static void BtnUp(
110 Widget wid,
111 XEvent *event,
112 String *params,
113 Cardinal *num_params) ;
114 static void Enter(
115 Widget wid,
116 XEvent *event,
117 String *params,
118 Cardinal *num_params) ;
119 static void Leave(
120 Widget wid,
121 XEvent *event,
122 String *params,
123 Cardinal *num_params) ;
124 static void BorderHighlight(
125 Widget wid) ;
126 static void BorderUnhighlight(
127 Widget wid) ;
128 static void ClassInitialize( void ) ;
129 static void ClassPartInitialize(
130 WidgetClass wc) ;
131 static void InitializePrehook(
132 Widget rw,
133 Widget nw,
134 ArgList args,
135 Cardinal *num_args) ;
136 static void InitializePosthook(
137 Widget rw,
138 Widget nw,
139 ArgList args,
140 Cardinal *num_args) ;
141 static void Initialize(
142 Widget rw,
143 Widget nw,
144 ArgList args,
145 Cardinal *num_args) ;
146 static void Resize(
147 Widget wid) ;
148 static void Redisplay(
149 Widget wid,
150 XEvent *event,
151 Region region) ;
152 static void DrawPushButton(
153 XmDrawnButtonWidget db,
154 #if NeedWidePrototypes
155 int armed) ;
156 #else
157 Boolean armed) ;
158 #endif /* NeedWidePrototypes */
159 static Boolean SetValuesPrehook(
160 Widget cw,
161 Widget rw,
162 Widget nw,
163 ArgList args,
164 Cardinal *num_args) ;
165 static Boolean SetValues(
166 Widget cw,
167 Widget rw,
168 Widget nw,
169 ArgList args,
170 Cardinal *num_args) ;
171 static void Realize(
172 Widget w,
173 XtValueMask *p_valueMask,
174 XSetWindowAttributes *attributes) ;
175 static void Destroy(
176 Widget wid) ;
177
178 static void ChangeCB(Widget w,
179 XtCallbackProc activCB,
180 XtPointer closure,
181 Boolean setunset) ;
182
183 static void DB_FixTearoff(XmDrawnButtonWidget db);
184
185 /******** End Static Function Declarations ********/
186
187 /*************************************<->*************************************
188 *
189 *
190 * Description: translation tables for class: DrawnButton
191 * -----------
192 *
193 * Matches events with string descriptors for internal routines.
194 *
195 *************************************<->***********************************/
196
197 static XtTranslations default_parsed;
198
199 #define defaultTranslations _XmDrawnB_defaultTranslations
200
201 static XtTranslations menu_parsed;
202
203 #define menuTranslations _XmDrawnB_menuTranslations
204
205
206 /*************************************<->*************************************
207 *
208 *
209 * Description: action list for class: DrawnButton
210 * -----------
211 *
212 * Matches string descriptors with internal routines.
213 * Note that Primitive will register additional event handlers
214 * for traversal.
215 *
216 *************************************<->***********************************/
217
218 static XtActionsRec actionsList[] =
219 {
220 {"Arm", Arm },
221 {"Activate", Activate },
222 {"MultiActivate", MultiActivate },
223 {"MultiArm", MultiArm },
224 {"ArmAndActivate", ArmAndActivate },
225 {"Disarm", Disarm },
226 {"BtnDown", BtnDown },
227 {"BtnUp", BtnUp },
228 {"Enter", Enter },
229 {"Leave", Leave },
230 {"ButtonTakeFocus", _XmButtonTakeFocus },
231 {"MenuButtonTakeFocus", _XmMenuButtonTakeFocus },
232 {"MenuButtonTakeFocusUp", _XmMenuButtonTakeFocusUp }
233 };
234
235
236 /* The resource list for Drawn Button */
237
238 static XtResource resources[] =
239 {
240 {
241 XmNmultiClick, XmCMultiClick, XmRMultiClick, sizeof (unsigned char),
242 XtOffsetOf( struct _XmDrawnButtonRec, drawnbutton.multiClick),
243 XmRImmediate, (XtPointer) XmMULTICLICK_KEEP
244 },
245
246 {
247 XmNpushButtonEnabled, XmCPushButtonEnabled, XmRBoolean, sizeof (Boolean),
248 XtOffsetOf( struct _XmDrawnButtonRec, drawnbutton.pushbutton_enabled),
249 XmRImmediate, (XtPointer) False
250 },
251
252 {
253 XmNshadowType, XmCShadowType, XmRShadowType, sizeof(unsigned char),
254 XtOffsetOf( struct _XmDrawnButtonRec, drawnbutton.shadow_type),
255 XmRImmediate, (XtPointer) XmSHADOW_ETCHED_IN
256 },
257
258 {
259 XmNactivateCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList),
260 XtOffsetOf( struct _XmDrawnButtonRec, drawnbutton.activate_callback),
261 XmRPointer, (XtPointer) NULL
262 },
263
264 {
265 XmNarmCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList),
266 XtOffsetOf( struct _XmDrawnButtonRec, drawnbutton.arm_callback),
267 XmRPointer, (XtPointer) NULL
268 },
269
270 {
271 XmNdisarmCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList),
272 XtOffsetOf( struct _XmDrawnButtonRec, drawnbutton.disarm_callback),
273 XmRPointer, (XtPointer) NULL
274 },
275
276 {
277 XmNexposeCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList),
278 XtOffsetOf( struct _XmDrawnButtonRec, drawnbutton.expose_callback),
279 XmRPointer, (XtPointer) NULL
280 },
281
282 {
283 XmNresizeCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList),
284 XtOffsetOf( struct _XmDrawnButtonRec, drawnbutton.resize_callback),
285 XmRPointer, (XtPointer) NULL
286 },
287
288 {
289 XmNshadowThickness, XmCShadowThickness, XmRHorizontalDimension,
290 sizeof(Dimension),
291 XtOffsetOf( struct _XmDrawnButtonRec, primitive.shadow_thickness),
292 XmRCallProc, (XtPointer) _XmSetThickness
293 },
294
295 {
296 XmNlabelString, XmCXmString, XmRXmString, sizeof(XmString),
297 XtOffsetOf( struct _XmDrawnButtonRec, label._label),
298 XmRImmediate, (XtPointer) XmUNSPECIFIED
299 },
300 {
301 XmNtraversalOn,
302 XmCTraversalOn,
303 XmRBoolean,
304 sizeof(Boolean),
305 XtOffsetOf( struct _XmPrimitiveRec, primitive.traversal_on),
306 XmRImmediate,
307 (XtPointer) True
308 },
309
310 {
311 XmNhighlightThickness,
312 XmCHighlightThickness,
313 XmRHorizontalDimension,
314 sizeof (Dimension),
315 XtOffsetOf( struct _XmPrimitiveRec, primitive.highlight_thickness),
316 XmRCallProc,
317 (XtPointer) _XmSetThickness
318 }
319 };
320
321 static XmBaseClassExtRec drawnBBaseClassExtRec = {
322 NULL, /* Next extension */
323 NULLQUARK, /* record type XmQmotif */
324 XmBaseClassExtVersion, /* version */
325 sizeof(XmBaseClassExtRec), /* size */
326 InitializePrehook, /* initialize prehook */
327 SetValuesPrehook, /* set_values prehook */
328 InitializePosthook, /* initialize posthook */
329 XmInheritSetValuesPosthook, /* set_values posthook */
330 XmInheritClass, /* secondary class */
331 XmInheritSecObjectCreate, /* creation proc */
332 XmInheritGetSecResData, /* getSecResData */
333 {0}, /* fast subclass */
334 XmInheritGetValuesPrehook, /* get_values prehook */
335 XmInheritGetValuesPosthook, /* get_values posthook */
336 XmInheritClassPartInitPrehook, /* classPartInitPrehook */
337 XmInheritClassPartInitPosthook, /* classPartInitPosthook*/
338 NULL, /* ext_resources */
339 NULL, /* compiled_ext_resources*/
340 0, /* num_ext_resources */
341 FALSE, /* use_sub_resources */
342 XmInheritWidgetNavigable, /* widgetNavigable */
343 XmInheritFocusChange, /* focusChange */
344 };
345
346
347
348 /*************************************<->*************************************
349 *
350 *
351 * Description: global class record for instances of class: DrawnButton
352 * -----------
353 *
354 * Defines default field settings for this class record.
355 *
356 *************************************<->***********************************/
357
358 externaldef(xmdrawnbuttonclassrec) XmDrawnButtonClassRec xmDrawnButtonClassRec ={
359 {
360 /* core_class record */
361 /* superclass */ (WidgetClass) &xmLabelClassRec,
362 /* class_name */ "XmDrawnButton",
363 /* widget_size */ sizeof(XmDrawnButtonRec),
364 /* class_initialize */ ClassInitialize,
365 /* class_part_init */ ClassPartInitialize,
366 /* class_inited */ FALSE,
367 /* initialize */ Initialize,
368 /* initialize_hook */ NULL,
369 /* realize */ Realize,
370 /* actions */ actionsList,
371 /* num_actions */ XtNumber(actionsList),
372 /* resources */ resources,
373 /* num_resources */ XtNumber(resources),
374 /* xrm_class */ NULLQUARK,
375 /* compress_motion */ TRUE,
376 /* compress_exposure */ XtExposeNoCompress,
377 /* compress_enterlv */ TRUE,
378 /* visible_interest */ FALSE,
379 /* destroy */ Destroy,
380 /* resize */ Resize,
381 /* expose */ Redisplay,
382 /* set_values */ SetValues,
383 /* set_values_hook */ NULL,
384 /* set_values_almost */ XtInheritSetValuesAlmost,
385 /* get_values_hook */ NULL,
386 /* accept_focus */ NULL,
387 /* version */ XtVersion,
388 /* callback_private */ NULL,
389 /* tm_table */ defaultTranslations,
390 /* query_geometry */ NULL,
391 /* display_accelerator */ NULL,
392 /* extension */ (XtPointer) &drawnBBaseClassExtRec,
393 },
394
395 { /* primitive_class record */
396
397 /* Primitive border_highlight */ BorderHighlight,
398 /* Primitive border_unhighlight */ BorderUnhighlight,
399 /* translations */ XtInheritTranslations,
400 /* arm_and_activate */ ArmAndActivate,
401 /* get resources */ NULL,
402 /* num get_resources */ 0,
403 /* extension */ NULL,
404 },
405
406 { /* label_class record */
407
408 /* setOverrideCallback*/ XmInheritWidgetProc,
409 /* Menu procedures */ XmInheritMenuProc,
410 /* menu trav xlations */ XtInheritTranslations,
411 /* extension */ NULL,
412 },
413
414 { /* drawnbutton_class record */
415
416 /* extension */ NULL,
417 }
418
419 };
420 externaldef(xmdrawnbuttonwidgetclass) WidgetClass xmDrawnButtonWidgetClass =
421 (WidgetClass)&xmDrawnButtonClassRec;
422
423 /* Trait record for drawnButton */
424
425 static XmConst XmActivatableTraitRec drawnButtonAT = {
426 0, /* version */
427 ChangeCB,
428 };
429
430 /* Menu Savvy trait record */
431 static XmMenuSavvyTraitRec MenuSavvyRecord = {
432 /* version: */
433 -1,
434 NULL,
435 NULL,
436 NULL,
437 _XmCBNameActivate,
438 };
439
440
441 /************************************************************************
442 *
443 * Arm
444 *
445 * This function processes button 1 down occuring on the drawnbutton.
446 * Mark the drawnbutton as armed if XmNpushButtonEnabled is TRUE.
447 * The callbacks for XmNarmCallback are called.
448 *
449 ************************************************************************/
450 /*ARGSUSED*/
451 static void
Arm(Widget wid,XEvent * event,String * params,Cardinal * num_params)452 Arm(
453 Widget wid,
454 XEvent *event,
455 String *params, /* unused */
456 Cardinal *num_params ) /* unused */
457 {
458 XmDrawnButtonWidget db = (XmDrawnButtonWidget) wid ;
459 XButtonEvent *buttonEvent = (XButtonEvent *) event;
460 XmDrawnButtonCallbackStruct call_value;
461
462 (void) XmProcessTraversal((Widget) db, XmTRAVERSE_CURRENT);
463
464 db -> drawnbutton.armed = TRUE;
465 if (event && (event->type == ButtonPress))
466 db -> drawnbutton.armTimeStamp = buttonEvent->time;
467
468 if (db->drawnbutton.pushbutton_enabled)
469 DrawPushButton(db, db->drawnbutton.armed);
470
471 if (db->drawnbutton.arm_callback) {
472 XFlush(XtDisplay (db));
473
474 call_value.reason = XmCR_ARM;
475 call_value.event = event;
476 call_value.window = XtWindow (db);
477 XtCallCallbackList ((Widget) db, db->drawnbutton.arm_callback,
478 &call_value);
479 }
480 }
481
482
483 /*ARGSUSED*/
484 static void
MultiArm(Widget wid,XEvent * event,String * params,Cardinal * num_params)485 MultiArm(
486 Widget wid,
487 XEvent *event,
488 String *params, /* unused */
489 Cardinal *num_params ) /* unused */
490 {
491 if (((XmDrawnButtonWidget) wid)->drawnbutton.multiClick == XmMULTICLICK_KEEP)
492 Arm (wid, event, NULL, NULL);
493 }
494
495 /************************************************************************
496 *
497 * Activate
498 *
499 * Mark the drawnbutton as unarmed (i.e. inactive).
500 * The foreground and background colors will revert to the
501 * unarmed state if XmNinvertOnArm is set to TRUE.
502 * If the button release occurs inside of the DrawnButton, the
503 * callbacks for XmNactivateCallback are called.
504 *
505 ************************************************************************/
506 static void
Activate(Widget wid,XEvent * buttonEvent,String * params,Cardinal * num_params)507 Activate(
508 Widget wid,
509 XEvent *buttonEvent,
510 String *params,
511 Cardinal *num_params )
512 {
513 XmDrawnButtonWidget db = (XmDrawnButtonWidget) wid ;
514 if (db -> drawnbutton.armed == FALSE)
515 return;
516
517 db->drawnbutton.click_count = 1;
518 ActivateCommon ((Widget) db, buttonEvent, params, num_params);
519
520 }
521
522 static void
MultiActivate(Widget wid,XEvent * buttonEvent,String * params,Cardinal * num_params)523 MultiActivate(
524 Widget wid,
525 XEvent *buttonEvent,
526 String *params,
527 Cardinal *num_params )
528 {
529 XmDrawnButtonWidget db = (XmDrawnButtonWidget) wid ;
530 /* When a multi click sequence occurs and the user Button Presses and
531 * holds for a length of time, the final release should look like a
532 * new/separate activate.
533 */
534 if (db->drawnbutton.multiClick == XmMULTICLICK_KEEP)
535 { if ((buttonEvent->xbutton.time - db->drawnbutton.armTimeStamp) >
536 XtGetMultiClickTime(XtDisplay(db)))
537 db->drawnbutton.click_count = 1;
538 else
539 db->drawnbutton.click_count++;
540 ActivateCommon ((Widget) db, buttonEvent, params, num_params) ;
541 Disarm ((Widget) db, buttonEvent, params, num_params) ;
542 }
543 }
544
545 /*ARGSUSED*/
546 static void
ActivateCommon(Widget wid,XEvent * event,String * params,Cardinal * num_params)547 ActivateCommon(
548 Widget wid,
549 XEvent *event,
550 String *params, /* unused */
551 Cardinal *num_params ) /* unused */
552 {
553 XmDrawnButtonWidget db = (XmDrawnButtonWidget) wid ;
554 XmDrawnButtonCallbackStruct call_value;
555 XmMenuSystemTrait menuSTrait;
556
557 menuSTrait = (XmMenuSystemTrait)
558 XmeTraitGet((XtPointer) XtClass(XtParent(wid)), XmQTmenuSystem);
559
560 if (event && (event->xbutton.type != ButtonRelease))
561 return;
562
563 db -> drawnbutton.armed = FALSE;
564 if (db->drawnbutton.pushbutton_enabled)
565 DrawPushButton(db, db->drawnbutton.armed);
566
567
568 /* CR 9181: Consider clipping when testing visibility. */
569 if ((db->drawnbutton.activate_callback) &&
570 ((event->xany.type == ButtonPress) ||
571 (event->xany.type == ButtonRelease)) &&
572 _XmGetPointVisibility(wid, event->xbutton.x_root, event->xbutton.y_root))
573 {
574 XFlush(XtDisplay (db));
575
576 call_value.reason = XmCR_ACTIVATE;
577 call_value.event = event;
578 call_value.window = XtWindow (db);
579 call_value.click_count = db->drawnbutton.click_count;
580
581 if ((db->drawnbutton.multiClick == XmMULTICLICK_DISCARD) &&
582 (call_value.click_count > 1))
583 {
584 return;
585 }
586
587 if (menuSTrait != NULL)
588 {
589 menuSTrait->entryCallback(XtParent(db), (Widget) db,
590 &call_value);
591 }
592
593 if ((! db->label.skipCallback) &&
594 (db->drawnbutton.activate_callback))
595 {
596 XtCallCallbackList ((Widget) db, db->drawnbutton.activate_callback,
597 &call_value);
598 }
599 }
600 }
601
602
603
604 static void
DB_FixTearoff(XmDrawnButtonWidget db)605 DB_FixTearoff( XmDrawnButtonWidget db)
606 {
607 if (XmMENU_PULLDOWN == db->label.menu_type)
608 {
609 Widget mwid = XmGetPostedFromWidget(XtParent(db));
610 if (mwid && XmIsRowColumn(mwid)
611 && (XmMENU_OPTION == RC_Type(mwid))
612 && _XmIsActiveTearOff(XtParent(db)))
613 XmProcessTraversal((Widget) db, XmTRAVERSE_CURRENT);
614 }
615 }
616 /************************************************************************
617 *
618 * ArmAndActivate
619 *
620 ************************************************************************/
621 /*ARGSUSED*/
622 static void
ArmAndActivate(Widget wid,XEvent * event,String * params,Cardinal * num_params)623 ArmAndActivate(
624 Widget wid,
625 XEvent *event,
626 String *params, /* unused */
627 Cardinal *num_params ) /* unused */
628 {
629 XmDrawnButtonWidget db = (XmDrawnButtonWidget) wid ;
630 XmDrawnButtonCallbackStruct call_value;
631 XmMenuSystemTrait menuSTrait;
632
633 menuSTrait = (XmMenuSystemTrait)
634 XmeTraitGet((XtPointer) XtClass(XtParent(wid)), XmQTmenuSystem);
635
636 db -> drawnbutton.armed = TRUE;
637 if (db->drawnbutton.pushbutton_enabled)
638 DrawPushButton(db, db->drawnbutton.armed);
639
640 XFlush(XtDisplay (db));
641
642 if (db->drawnbutton.arm_callback)
643 {
644 call_value.reason = XmCR_ARM;
645 call_value.event = event;
646 call_value.window = XtWindow (db);
647 XtCallCallbackList ((Widget) db, db->drawnbutton.arm_callback, &call_value);
648 }
649
650 call_value.reason = XmCR_ACTIVATE;
651 call_value.event = event;
652 call_value.window = XtWindow (db);
653 call_value.click_count = 1; /* always 1 in kselect */
654
655 if (menuSTrait != NULL)
656 {
657 menuSTrait->entryCallback(XtParent(db), (Widget) db,
658 &call_value);
659 }
660
661 if ((! db->label.skipCallback) &&
662 (db->drawnbutton.activate_callback))
663 {
664 XtCallCallbackList ((Widget) db, db->drawnbutton.activate_callback,
665 &call_value);
666 }
667
668 db->drawnbutton.armed = FALSE;
669
670 if (db->drawnbutton.disarm_callback)
671 {
672 call_value.reason = XmCR_DISARM;
673 XtCallCallbackList ((Widget) db, db->drawnbutton.disarm_callback,
674 &call_value);
675 }
676
677 /* If the button is still around, show it released, after a short delay */
678 if (!db->core.being_destroyed && db->drawnbutton.pushbutton_enabled)
679 {
680 db->drawnbutton.timer = XtAppAddTimeOut(
681 XtWidgetToApplicationContext((Widget)db),
682 (unsigned long) DELAY_DEFAULT,
683 ArmTimeout,
684 (XtPointer)db);
685 }
686 }
687
688 /*ARGSUSED*/
689 static void
ArmTimeout(XtPointer closure,XtIntervalId * id)690 ArmTimeout (
691 XtPointer closure,
692 XtIntervalId *id )
693 {
694 XmDrawnButtonWidget db = (XmDrawnButtonWidget) closure ;
695
696 db -> drawnbutton.timer = 0;
697
698 if (db->drawnbutton.pushbutton_enabled &&
699 XtIsRealized((Widget)db) && XtIsManaged((Widget)db))
700 {
701 DrawPushButton(db, db->drawnbutton.armed);
702 XFlush (XtDisplay (db));
703 }
704 }
705
706
707
708 /************************************************************************
709 *
710 * Disarm
711 *
712 * Mark the drawnbutton as unarmed (i.e. active).
713 * The foreground and background colors will revert to the
714 * unarmed state if XmNinvertOnSelect is set to TRUE and the
715 * drawnbutton is not in a menu.
716 * The callbacks for XmNdisarmCallback are called..
717 *
718 ************************************************************************/
719 /*ARGSUSED*/
720 static void
Disarm(Widget wid,XEvent * event,String * params,Cardinal * num_params)721 Disarm(
722 Widget wid,
723 XEvent *event,
724 String *params, /* unused */
725 Cardinal *num_params ) /* unused */
726 {
727 XmDrawnButtonWidget db = (XmDrawnButtonWidget) wid ;
728 XmDrawnButtonCallbackStruct call_value;
729
730 db -> drawnbutton.armed = FALSE;
731
732 if (db->drawnbutton.disarm_callback)
733 {
734 XFlush(XtDisplay (db));
735
736 call_value.reason = XmCR_DISARM;
737 call_value.event = event;
738 call_value.window = XtWindow (db);
739 XtCallCallbackList ((Widget) db, db->drawnbutton.disarm_callback, &call_value);
740 }
741 }
742
743
744
745 /************************************************************************
746 *
747 * BtnDown
748 *
749 * This function processes a button down occuring on the drawnbutton
750 * when it is in a popup, pulldown, or option menu.
751 * Popdown the posted menu.
752 * Turn parent's traversal off.
753 * Mark the drawnbutton as armed (i.e. active).
754 * The callbacks for XmNarmCallback are called.
755 *
756 ************************************************************************/
757
758 /*ARGSUSED*/
759 static void
BtnDown(Widget wid,XEvent * event,String * params,Cardinal * num_params)760 BtnDown(
761 Widget wid,
762 XEvent *event,
763 String *params, /* unused */
764 Cardinal *num_params ) /* unused */
765 {
766 XmDrawnButtonWidget db = (XmDrawnButtonWidget) wid ;
767 XmDrawnButtonCallbackStruct call_value;
768 Boolean validButton = False;
769 Boolean already_armed;
770 ShellWidget popup;
771 XmMenuSystemTrait menuSTrait;
772
773 /* Support menu replay, free server input queue until next button event */
774 XAllowEvents(XtDisplay(db), SyncPointer, CurrentTime);
775
776 /* If no menu system trait then parent isn't a menu as it should be. */
777 menuSTrait = (XmMenuSystemTrait)
778 XmeTraitGet((XtPointer) XtClass(XtParent(db)), XmQTmenuSystem);
779 if (menuSTrait == NULL)
780 return;
781
782 if (event && (event->type == ButtonPress))
783 validButton = menuSTrait->verifyButton(XtParent(db), event);
784
785 if (!validButton)
786 return;
787
788 _XmSetInDragMode((Widget)db, True);
789
790 /* Popdown other popus that may be up */
791 if (!(popup = (ShellWidget)_XmGetRC_PopupPosted(XtParent(db))))
792 {
793 if (!XmIsMenuShell(XtParent(XtParent(db))))
794 {
795 /* In case tear off not armed and no grabs in place, do it now.
796 * Ok if already armed and grabbed - nothing done.
797 */
798 menuSTrait->tearOffArm(XtParent(db));
799 }
800 }
801
802 if (popup)
803 {
804 if (popup->shell.popped_up)
805 menuSTrait->popdownEveryone((Widget) popup, event);
806 }
807
808 /* Set focus to this drawnbutton. This must follow the possible
809 * unhighlighting of the CascadeButton else it'll screw up active_child.
810 */
811 (void)XmProcessTraversal ((Widget) db, XmTRAVERSE_CURRENT);
812 /* get the location cursor - get consistent with Gadgets */
813
814 already_armed = db->drawnbutton.armed;
815 db->drawnbutton.armed = TRUE;
816
817 if (db->drawnbutton.arm_callback && !already_armed)
818 {
819 XFlush (XtDisplay (db));
820
821 call_value.reason = XmCR_ARM;
822 call_value.event = event;
823 XtCallCallbackList((Widget) db, db->drawnbutton.arm_callback, &call_value);
824 }
825 _XmRecordEvent (event);
826 }
827
828 /************************************************************************
829 *
830 * BtnUp
831 *
832 * This function processes a button up occuring on the drawnbutton
833 * when it is in a popup, pulldown, or option menu.
834 * Mark the drawnbutton as unarmed (i.e. inactive).
835 * The callbacks for XmNactivateCallback are called.
836 * The callbacks for XmNdisarmCallback are called.
837 *
838 ************************************************************************/
839
840 /*ARGSUSED*/
841 static void
BtnUp(Widget wid,XEvent * event,String * params,Cardinal * num_params)842 BtnUp(
843 Widget wid,
844 XEvent *event,
845 String *params, /* unused */
846 Cardinal *num_params ) /* unused */
847 {
848 XmDrawnButtonWidget db = (XmDrawnButtonWidget) wid ;
849 Widget parent = XtParent(db);
850 XmDrawnButtonCallbackStruct call_value;
851 Boolean flushDone = False;
852 Boolean validButton = False;
853 Boolean popped_up;
854 Boolean is_menupane = Lab_IsMenupane(db);
855 Widget shell = XtParent(XtParent(db));
856 XmMenuSystemTrait menuSTrait;
857
858 /* If no menu system trait then parent isn't a menu as it should be. */
859 menuSTrait = (XmMenuSystemTrait)
860 XmeTraitGet((XtPointer) XtClass(XtParent(db)), XmQTmenuSystem);
861 if (menuSTrait == NULL)
862 return;
863
864 if (event && (event->type == ButtonRelease))
865 validButton = menuSTrait->verifyButton(parent, event);
866
867 if (!validButton || (db->drawnbutton.armed == FALSE))
868 return;
869
870 db->drawnbutton.armed = FALSE;
871
872 if (is_menupane && !XmIsMenuShell(shell))
873 popped_up = menuSTrait->popdown((Widget) db, event);
874 else
875 popped_up = menuSTrait->buttonPopdown((Widget) db, event);
876
877 _XmRecordEvent(event);
878
879 /* XmMENU_POPDOWN left the menu posted on button click - don't activate! */
880 if (popped_up)
881 return;
882
883 call_value.reason = XmCR_ACTIVATE;
884 call_value.event = event;
885 call_value.click_count = 1;
886
887 /* if the parent is menu system able, notify it about the select */
888 if (menuSTrait != NULL)
889 {
890 menuSTrait->entryCallback(parent, (Widget) db, &call_value);
891 flushDone = True;
892 }
893
894 if ((! db->label.skipCallback) &&
895 (db->drawnbutton.activate_callback))
896 {
897 XFlush (XtDisplay (db));
898 flushDone = True;
899 XtCallCallbackList ((Widget) db, db->drawnbutton.activate_callback,
900 &call_value);
901 }
902 if (db->drawnbutton.disarm_callback)
903 {
904 if (!flushDone)
905 XFlush (XtDisplay (db));
906 call_value.reason = XmCR_DISARM;
907 call_value.event = event;
908 XtCallCallbackList ((Widget) db, db->drawnbutton.disarm_callback,
909 &call_value);
910 }
911
912 /* If the original shell does not indicate an active menu, but rather a
913 * tear off pane, leave the button in an armed state. Also, briefly
914 * display the button as depressed to give the user some feedback of
915 * the selection.
916 */
917
918 if (is_menupane) /* necessary check? */
919 {
920 if (!XmIsMenuShell(shell))
921 {
922 if (XtIsSensitive((Widget)db))
923 {
924 XmDisplay dpy = (XmDisplay) XmGetXmDisplay(XtDisplay(db));
925 Boolean etched_in = dpy->display.enable_etched_in_menu;
926
927 if ((db->core.width > 2 * db->primitive.highlight_thickness) &&
928 (db->core.height > 2 * db->primitive.highlight_thickness))
929 XmeDrawShadows
930 (XtDisplay (db), XtWindow (db),
931 db->primitive.bottom_shadow_GC,
932 db->primitive.top_shadow_GC,
933 db->primitive.highlight_thickness,
934 db->primitive.highlight_thickness,
935 db->core.width - 2 * db->primitive.highlight_thickness,
936 db->core.height - 2 * db->primitive.highlight_thickness,
937 db->primitive.shadow_thickness,
938 etched_in ? XmSHADOW_IN : XmSHADOW_OUT);
939
940 XFlush (XtDisplay (db));
941 flushDone = True;
942
943 if (db->core.being_destroyed == False)
944 {
945 if (!db->drawnbutton.timer)
946 db->drawnbutton.timer =
947 XtAppAddTimeOut(XtWidgetToApplicationContext((Widget)db),
948 (unsigned long) DELAY_DEFAULT,
949 ArmTimeout,
950 (XtPointer)(db));
951 }
952
953 db->drawnbutton.armed = TRUE;
954 if (db->drawnbutton.arm_callback)
955 {
956 if (!flushDone)
957 XFlush (XtDisplay (db));
958 call_value.reason = XmCR_ARM;
959 call_value.event = event;
960 XtCallCallbackList ((Widget) db, db->drawnbutton.arm_callback,
961 &call_value);
962 }
963 }
964 }
965 else
966 menuSTrait->reparentToTearOffShell(XtParent(db), event);
967 }
968
969 _XmSetInDragMode((Widget)db, False);
970
971 /* For the benefit of tear off menus, we must set the focus item
972 * to this button. In normal menus, this would not be a problem
973 * because the focus is cleared when the menu is unposted.
974 */
975 if (!XmIsMenuShell(shell))
976 XmProcessTraversal((Widget) db, XmTRAVERSE_CURRENT);
977 DB_FixTearoff(db);
978 }
979
980 /************************************************************************
981 *
982 * Enter
983 *
984 ************************************************************************/
985 static void
Enter(Widget wid,XEvent * event,String * params,Cardinal * num_params)986 Enter(
987 Widget wid,
988 XEvent *event,
989 String *params,
990 Cardinal *num_params )
991 {
992 XmDrawnButtonWidget db = (XmDrawnButtonWidget) wid ;
993 XmDrawnButtonCallbackStruct call_value;
994
995 if (Lab_IsMenupane(db)) {
996 if ((((ShellWidget) XtParent(XtParent(db)))->shell.popped_up) &&
997 _XmGetInDragMode((Widget)db))
998 {
999 XmDisplay dpy = (XmDisplay) XmGetXmDisplay(XtDisplay(wid));
1000
1001 if (db->drawnbutton.armed)
1002 return;
1003
1004 /* So KHelp event is delivered correctly */
1005 _XmSetFocusFlag (XtParent(XtParent(db)), XmFOCUS_IGNORE, TRUE);
1006 XtSetKeyboardFocus(XtParent(XtParent(db)), (Widget)db);
1007 _XmSetFocusFlag (XtParent(XtParent(db)), XmFOCUS_IGNORE, FALSE);
1008
1009 db -> drawnbutton.armed = TRUE;
1010
1011 ((XmManagerWidget) XtParent(wid))->manager.active_child = wid;
1012
1013 if (db->drawnbutton.pushbutton_enabled)
1014 DrawPushButton(db, db->drawnbutton.armed);
1015
1016 if (db->drawnbutton.arm_callback)
1017 {
1018 XFlush (XtDisplay (db));
1019
1020 call_value.reason = XmCR_ARM;
1021 call_value.event = event;
1022 XtCallCallbackList ((Widget) db,
1023 db->drawnbutton.arm_callback, &call_value);
1024 }
1025 }
1026 }
1027 else {
1028 _XmPrimitiveEnter (wid, event, params, num_params);
1029
1030 if (db -> drawnbutton.pushbutton_enabled &&
1031 db -> drawnbutton.armed == TRUE)
1032 DrawPushButton(db, TRUE);
1033 }
1034 }
1035
1036
1037 /************************************************************************
1038 *
1039 * Leave
1040 *
1041 ************************************************************************/
1042 static void
Leave(Widget wid,XEvent * event,String * params,Cardinal * num_params)1043 Leave(
1044 Widget wid,
1045 XEvent *event,
1046 String *params,
1047 Cardinal *num_params )
1048 {
1049 XmDrawnButtonWidget db = (XmDrawnButtonWidget) wid ;
1050 XmDrawnButtonCallbackStruct call_value;
1051
1052 if (Lab_IsMenupane(db)) {
1053 if (_XmGetInDragMode((Widget)db) && db->drawnbutton.armed &&
1054 (/* !ActiveTearOff || */ event->xcrossing.mode == NotifyNormal))
1055 {
1056 XmDisplay dpy = (XmDisplay) XmGetXmDisplay(XtDisplay(wid));
1057
1058 db->drawnbutton.armed = FALSE;
1059
1060 ((XmManagerWidget) XtParent(wid))->manager.active_child = NULL;
1061
1062 if (db->drawnbutton.pushbutton_enabled) {
1063 XmeClearBorder
1064 (XtDisplay (db), XtWindow (db),
1065 db->primitive.highlight_thickness,
1066 db->primitive.highlight_thickness,
1067 db->core.width - 2 * db->primitive.highlight_thickness,
1068 db->core.height - 2 * db->primitive.highlight_thickness,
1069 db->primitive.shadow_thickness);
1070 }
1071
1072 if (db->drawnbutton.disarm_callback)
1073 {
1074 XFlush (XtDisplay (db));
1075
1076 call_value.reason = XmCR_DISARM;
1077 call_value.event = event;
1078 XtCallCallbackList ((Widget) db,
1079 db->drawnbutton.disarm_callback, &call_value);
1080 }
1081 }
1082 }
1083 else {
1084 _XmPrimitiveLeave (wid, event, params, num_params);
1085
1086 if (db -> drawnbutton.pushbutton_enabled &&
1087 db -> drawnbutton.armed == TRUE)
1088 DrawPushButton(db, FALSE);
1089 }
1090 }
1091
1092 /*************************************<->*************************************
1093 *
1094 * BorderHighlight
1095 *
1096 *************************************<->***********************************/
1097
1098 static void
BorderHighlight(Widget wid)1099 BorderHighlight(
1100 Widget wid )
1101 {
1102 XmDrawnButtonWidget db = (XmDrawnButtonWidget) wid ;
1103 XmDrawnButtonCallbackStruct call_value;
1104 XEvent * event = NULL;
1105
1106 if (Lab_IsMenupane(db)) {
1107 XmDisplay dpy = (XmDisplay) XmGetXmDisplay(XtDisplay(wid));
1108 Boolean already_armed = db->drawnbutton.armed;
1109
1110 db->drawnbutton.armed = TRUE;
1111
1112 if (db->drawnbutton.pushbutton_enabled)
1113 DrawPushButton(db, db->drawnbutton.armed);
1114
1115 if (!already_armed && db->drawnbutton.arm_callback)
1116 {
1117 XFlush (XtDisplay (db));
1118
1119 call_value.reason = XmCR_ARM;
1120 call_value.event = event;
1121 XtCallCallbackList ((Widget) db, db->drawnbutton.arm_callback,
1122 &call_value);
1123 }
1124 }
1125 else {
1126 XtWidgetProc border_highlight;
1127
1128 _XmProcessLock();
1129 border_highlight = xmLabelClassRec.primitive_class.border_highlight;
1130 _XmProcessUnlock();
1131 (*border_highlight)(wid);
1132 }
1133
1134 }
1135
1136 /*************************************<->*************************************
1137 *
1138 * BorderUnhighlight
1139 *
1140 *************************************<->***********************************/
1141
1142 static void
BorderUnhighlight(Widget wid)1143 BorderUnhighlight(
1144 Widget wid )
1145 {
1146 XmDrawnButtonWidget db = (XmDrawnButtonWidget) wid ;
1147 XmDrawnButtonCallbackStruct call_value;
1148 XEvent * event = NULL;
1149
1150 if (Lab_IsMenupane(db))
1151 {
1152 XmDisplay dpy = (XmDisplay) XmGetXmDisplay(XtDisplay(wid));
1153 Boolean already_armed = db->drawnbutton.armed;
1154
1155 db->drawnbutton.armed = FALSE;
1156
1157 if (db->drawnbutton.pushbutton_enabled) {
1158 XmeClearBorder
1159 (XtDisplay (db), XtWindow (db),
1160 db->primitive.highlight_thickness,
1161 db->primitive.highlight_thickness,
1162 db->core.width - 2 * db->primitive.highlight_thickness,
1163 db->core.height - 2 * db->primitive.highlight_thickness,
1164 db->primitive.shadow_thickness);
1165 }
1166
1167 if (already_armed && db->drawnbutton.disarm_callback)
1168 {
1169 XFlush (XtDisplay (db));
1170
1171 call_value.reason = XmCR_DISARM;
1172 call_value.event = event;
1173 XtCallCallbackList ((Widget) db, db->drawnbutton.disarm_callback,
1174 &call_value);
1175 }
1176 }
1177 else {
1178 XtWidgetProc border_unhighlight;
1179
1180 _XmProcessLock();
1181 border_unhighlight = xmLabelClassRec.primitive_class.border_unhighlight;
1182 _XmProcessUnlock();
1183 (*border_unhighlight)(wid);
1184 }
1185 }
1186
1187
1188
1189 /************************************************************************
1190 *
1191 * ClassInitialize
1192 * Set up the base class extension record.
1193 *
1194 ************************************************************************/
1195 static void
ClassInitialize(void)1196 ClassInitialize( void )
1197 {
1198 /* parse the various translation tables */
1199 menu_parsed = XtParseTranslationTable(menuTranslations);
1200 default_parsed = XtParseTranslationTable(defaultTranslations);
1201
1202 /* set up base class extension quark */
1203 drawnBBaseClassExtRec.record_type = XmQmotif;
1204 }
1205
1206 /************************************************************************
1207 *
1208 * ClassPartInitialize
1209 * Set up the fast subclassing for the widget
1210 *
1211 ************************************************************************/
1212 static void
ClassPartInitialize(WidgetClass wc)1213 ClassPartInitialize(
1214 WidgetClass wc )
1215 {
1216 _XmFastSubclassInit (wc, XmDRAWN_BUTTON_BIT);
1217
1218 /* Install the menu savvy trait record, copying fields from XmLabel */
1219 _XmLabelCloneMenuSavvy (wc, &MenuSavvyRecord);
1220
1221 /* Install the activatable trait for all subclasses */
1222 XmeTraitSet((XtPointer)wc, XmQTactivatable, (XtPointer) &drawnButtonAT);
1223 }
1224
1225 /************************************************************
1226 *
1227 * InitializePrehook
1228 *
1229 * Put the proper translations in core_class tm_table so that
1230 * the data is massaged correctly
1231 *
1232 ************************************************************/
1233
1234 /*ARGSUSED*/
1235 static void
InitializePrehook(Widget rw,Widget nw,ArgList args,Cardinal * num_args)1236 InitializePrehook(
1237 Widget rw, /* unused */
1238 Widget nw,
1239 ArgList args, /* unused */
1240 Cardinal *num_args ) /* unused */
1241 {
1242 XmDrawnButtonWidget bw = (XmDrawnButtonWidget) nw ;
1243 unsigned char type;
1244 XmMenuSystemTrait menuSTrait;
1245
1246 menuSTrait = (XmMenuSystemTrait)
1247 XmeTraitGet((XtPointer) XtClass(XtParent(nw)), XmQTmenuSystem);
1248
1249 _XmSaveCoreClassTranslations (nw);
1250
1251 if (menuSTrait != NULL)
1252 type = menuSTrait->type(XtParent(nw));
1253 else
1254 type = XmWORK_AREA;
1255
1256 _XmProcessLock();
1257 if (type == XmMENU_PULLDOWN ||
1258 type == XmMENU_POPUP)
1259 nw->core.widget_class->core_class.tm_table = (String) menu_parsed;
1260 else
1261 nw->core.widget_class->core_class.tm_table = (String) default_parsed;
1262
1263 /* CR 2990: Use XmNbuttonFontList as the default font. */
1264 if (bw->label.font == NULL)
1265 bw->label.font = XmeGetDefaultRenderTable (nw, XmBUTTON_FONTLIST);
1266 _XmProcessUnlock();
1267 }
1268
1269 /************************************************************
1270 *
1271 * InitializePosthook
1272 *
1273 * restore core class translations
1274 *
1275 ************************************************************/
1276
1277 /*ARGSUSED*/
1278 static void
InitializePosthook(Widget rw,Widget nw,ArgList args,Cardinal * num_args)1279 InitializePosthook(
1280 Widget rw, /* unused */
1281 Widget nw,
1282 ArgList args, /* unused */
1283 Cardinal *num_args ) /* unused */
1284 {
1285 _XmRestoreCoreClassTranslations (nw);
1286 }
1287
1288 /*************************************<->*************************************
1289 *
1290 * Initialize
1291 *
1292 *************************************<->***********************************/
1293 /*ARGSUSED*/
1294 static void
Initialize(Widget rw,Widget nw,ArgList args,Cardinal * num_args)1295 Initialize(
1296 Widget rw,
1297 Widget nw,
1298 ArgList args,
1299 Cardinal *num_args )
1300 {
1301 XmDrawnButtonWidget new_w = (XmDrawnButtonWidget) nw ;
1302 XmDrawnButtonWidget req_w = (XmDrawnButtonWidget) rw ;
1303
1304 /* CR 2990: Use XmNbuttonFontList as the default font. */
1305 if (req_w->label.font == NULL)
1306 {
1307 XmFontListFree (new_w->label.font);
1308 new_w->label.font =
1309 XmFontListCopy (XmeGetDefaultRenderTable (nw, XmBUTTON_FONTLIST));
1310 }
1311
1312 new_w->drawnbutton.armed = FALSE;
1313 new_w->drawnbutton.timer = 0;
1314
1315 /* if menuProcs is not set up yet, try again */
1316 if (xmLabelClassRec.label_class.menuProcs == (XmMenuProc)NULL)
1317 xmLabelClassRec.label_class.menuProcs =
1318 (XmMenuProc) _XmGetMenuProcContext();
1319
1320 if( !XmRepTypeValidValue( XmRID_SHADOW_TYPE,
1321 new_w->drawnbutton.shadow_type, (Widget) new_w) )
1322 {
1323 new_w -> drawnbutton.shadow_type = XmSHADOW_ETCHED_IN;
1324 }
1325
1326 }
1327
1328 /*************************************<->*************************************
1329 *
1330 * Resize (db)
1331 *
1332 *************************************<->***********************************/
1333 static void
Resize(Widget wid)1334 Resize(
1335 Widget wid )
1336 {
1337 XmDrawnButtonWidget db = (XmDrawnButtonWidget) wid ;
1338 XmDrawnButtonCallbackStruct call_value;
1339 XtWidgetProc resize;
1340
1341 _XmProcessLock();
1342 resize = xmLabelClassRec.core_class.resize;
1343 _XmProcessUnlock();
1344
1345 (* resize) ((Widget) db);
1346
1347 /* CR 5419: Suppress redundant calls to the resize callbacks. */
1348 if (db->drawnbutton.resize_callback &&
1349 !Lab_ComputingSize(db))
1350 {
1351 XFlush(XtDisplay (db));
1352 call_value.reason = XmCR_RESIZE;
1353 call_value.event = NULL;
1354 call_value.window = XtWindow (db);
1355 XtCallCallbackList ((Widget) db, db->drawnbutton.resize_callback, &call_value);
1356 }
1357 }
1358
1359
1360 /*************************************<->*************************************
1361 *
1362 * Redisplay (db, event, region)
1363 *
1364 *************************************<->***********************************/
1365 /*ARGSUSED*/
1366 static void
Redisplay(Widget wid,XEvent * event,Region region)1367 Redisplay(
1368 Widget wid,
1369 XEvent *event,
1370 Region region )
1371 {
1372 XmDrawnButtonWidget db = (XmDrawnButtonWidget) wid ;
1373 XmDrawnButtonCallbackStruct call_value;
1374
1375 if (XtIsRealized((Widget)db))
1376 {
1377 if (event) {
1378 XtExposeProc expose;
1379
1380 _XmProcessLock();
1381 expose = xmLabelClassRec.core_class.expose;
1382 _XmProcessUnlock();
1383
1384 (* expose) ((Widget) db, event, region);
1385 }
1386
1387 if (db->drawnbutton.pushbutton_enabled)
1388 DrawPushButton(db, db->drawnbutton.armed);
1389
1390 else
1391 XmeDrawShadows(XtDisplay((Widget) db),
1392 XtWindow((Widget) db),
1393 db -> primitive.top_shadow_GC,
1394 db -> primitive.bottom_shadow_GC,
1395 db -> primitive.highlight_thickness,
1396 db -> primitive.highlight_thickness,
1397 db -> core.width - 2 *
1398 db -> primitive.highlight_thickness,
1399 db -> core.height - 2 *
1400 db -> primitive.highlight_thickness,
1401 db -> primitive.shadow_thickness,
1402 db->drawnbutton.shadow_type);
1403
1404 if (db->drawnbutton.expose_callback)
1405 {
1406 XFlush(XtDisplay (db));
1407
1408 call_value.reason = XmCR_EXPOSE;
1409 call_value.event = event;
1410 call_value.window = XtWindow (db);
1411 XtCallCallbackList ((Widget) db, db->drawnbutton.expose_callback, &call_value);
1412 }
1413
1414 }
1415 }
1416
1417
1418 static void
DrawPushButton(XmDrawnButtonWidget db,int armed)1419 DrawPushButton(
1420 XmDrawnButtonWidget db,
1421 #if NeedWidePrototypes
1422 int armed )
1423 #else
1424 Boolean armed )
1425 #endif /* NeedWidePrototypes */
1426 {
1427 XmDisplay dpy = (XmDisplay) XmGetXmDisplay(XtDisplay((Widget) db));
1428 Boolean etched_in = dpy -> display.enable_etched_in_menu;
1429 Boolean in_menu = Lab_IsMenupane((Widget) db);
1430 Boolean do_draw;
1431 unsigned int type;
1432
1433 do_draw = (! in_menu) || (in_menu && armed);
1434
1435 if (in_menu)
1436 type = etched_in ? XmSHADOW_IN : XmSHADOW_OUT;
1437 else
1438 type = armed ? XmSHADOW_IN : XmSHADOW_OUT;
1439
1440 if (do_draw)
1441 XmeDrawShadows (XtDisplay (db), XtWindow (db),
1442 db -> primitive.top_shadow_GC,
1443 db -> primitive.bottom_shadow_GC,
1444 db -> primitive.highlight_thickness,
1445 db -> primitive.highlight_thickness,
1446 db -> core.width - 2 *
1447 db->primitive.highlight_thickness,
1448 db -> core.height - 2 *
1449 db->primitive.highlight_thickness,
1450 db -> primitive.shadow_thickness,
1451 type);
1452 }
1453
1454
1455 /************************************************************************
1456 *
1457 * SetValuesPrehook
1458 *
1459 ************************************************************************/
1460
1461 /*ARGSUSED*/
1462 static Boolean
SetValuesPrehook(Widget cw,Widget rw,Widget nw,ArgList args,Cardinal * num_args)1463 SetValuesPrehook(
1464 Widget cw, /* unused */
1465 Widget rw, /* unused */
1466 Widget nw,
1467 ArgList args, /* unused */
1468 Cardinal *num_args ) /* unused */
1469 {
1470 XmDrawnButtonWidget bw = (XmDrawnButtonWidget) nw ;
1471
1472 /* CR 2990: Use XmNbuttonFontList as the default font. */
1473 if (bw->label.font == NULL)
1474 bw->label.font = XmeGetDefaultRenderTable (nw, XmBUTTON_FONTLIST);
1475
1476 return False;
1477 }
1478
1479 /*************************************<->*************************************
1480 *
1481 * SetValues(current, request, new_w)
1482 *
1483 * Description:
1484 * -----------
1485 * This is the set values procedure for the drawnbutton class. It is
1486 * called last (the set values rtnes for its superclasses are called
1487 * first).
1488 *
1489 *
1490 * Inputs:
1491 * ------
1492 * current = original widget;
1493 * request = original copy of request;
1494 * new_w = copy of request which reflects changes made to it by
1495 * set values procedures of its superclasses;
1496 * last = TRUE if this is the last set values procedure to be called.
1497 *
1498 * Outputs:
1499 * -------
1500 *
1501 * Procedures Called
1502 * -----------------
1503 *
1504 *************************************<->***********************************/
1505 /*ARGSUSED*/
1506 static Boolean
SetValues(Widget cw,Widget rw,Widget nw,ArgList args,Cardinal * num_args)1507 SetValues(
1508 Widget cw,
1509 Widget rw,
1510 Widget nw,
1511 ArgList args,
1512 Cardinal *num_args )
1513 {
1514 XmDrawnButtonWidget current = (XmDrawnButtonWidget) cw ;
1515 XmDrawnButtonWidget new_w = (XmDrawnButtonWidget) nw ;
1516 Boolean flag = FALSE; /* our return value */
1517
1518 /* Check the data put into the new widget. */
1519
1520 if( !XmRepTypeValidValue( XmRID_SHADOW_TYPE,
1521 new_w->drawnbutton.shadow_type, (Widget) new_w) )
1522 {
1523 new_w->drawnbutton.shadow_type = current->drawnbutton.shadow_type ;
1524 }
1525
1526 if (new_w -> drawnbutton.shadow_type != current-> drawnbutton.shadow_type ||
1527 new_w -> primitive.foreground != current -> primitive.foreground ||
1528 new_w -> core.background_pixel != current -> core.background_pixel ||
1529 new_w -> primitive.highlight_thickness !=
1530 current -> primitive.highlight_thickness ||
1531 new_w -> primitive.shadow_thickness !=
1532 current -> primitive.shadow_thickness)
1533 {
1534 flag = TRUE;
1535 }
1536
1537 return(flag);
1538 }
1539
1540
1541
1542
1543 /*************************************************************************
1544 *
1545 * Realize
1546 * This function sets the bit gravity to forget.
1547 *
1548 *************************************************************************/
1549 static void
Realize(Widget w,XtValueMask * p_valueMask,XSetWindowAttributes * attributes)1550 Realize(
1551 Widget w,
1552 XtValueMask *p_valueMask,
1553 XSetWindowAttributes *attributes )
1554 {
1555 Mask valueMask = *p_valueMask;
1556
1557 valueMask |= CWBitGravity | CWDontPropagate;
1558 attributes->bit_gravity = ForgetGravity;
1559 attributes->do_not_propagate_mask =
1560 ButtonPressMask | ButtonReleaseMask |
1561 KeyPressMask | KeyReleaseMask | PointerMotionMask;
1562
1563 XtCreateWindow (w, InputOutput, CopyFromParent, valueMask, attributes);
1564 }
1565
1566
1567
1568 /************************************************************************
1569 *
1570 * Destroy
1571 * Clean up allocated resources when the widget is destroyed.
1572 *
1573 ************************************************************************/
1574 static void
Destroy(Widget wid)1575 Destroy(
1576 Widget wid )
1577 {
1578 XmDrawnButtonWidget db = (XmDrawnButtonWidget) wid ;
1579 if (db->drawnbutton.timer)
1580 XtRemoveTimeOut (db->drawnbutton.timer);
1581 }
1582
1583 /************************************************************************
1584 *
1585 * ChangeCB
1586 * add or remove the activate callback list.
1587 *
1588 ************************************************************************/
1589 static void
ChangeCB(Widget w,XtCallbackProc activCB,XtPointer closure,Boolean setunset)1590 ChangeCB(
1591 Widget w,
1592 XtCallbackProc activCB,
1593 XtPointer closure,
1594 Boolean setunset)
1595 {
1596 if (setunset) {
1597 XtAddCallback (w, XmNactivateCallback, activCB, closure);
1598 } else {
1599 XtRemoveCallback (w, XmNactivateCallback, activCB, closure);
1600 }
1601 }
1602
1603
1604 /************************************************************************
1605 *
1606 * Application Accessible External Functions
1607 *
1608 ************************************************************************/
1609
1610
1611 /************************************************************************
1612 *
1613 * XmCreateDrawnButton
1614 * Create an instance of a drawnbutton and return the widget id.
1615 *
1616 ************************************************************************/
1617 Widget
XmCreateDrawnButton(Widget parent,char * name,ArgList arglist,Cardinal argcount)1618 XmCreateDrawnButton(
1619 Widget parent,
1620 char *name,
1621 ArgList arglist,
1622 Cardinal argcount )
1623 {
1624 return (XtCreateWidget (name, xmDrawnButtonWidgetClass,
1625 parent, arglist, argcount));
1626 }
1627
1628 Widget
XmVaCreateDrawnButton(Widget parent,char * name,...)1629 XmVaCreateDrawnButton(
1630 Widget parent,
1631 char *name,
1632 ...)
1633 {
1634 register Widget w;
1635 va_list var;
1636 int count;
1637
1638 Va_start(var,name);
1639 count = XmeCountVaListSimple(var);
1640 va_end(var);
1641
1642
1643 Va_start(var, name);
1644 w = XmeVLCreateWidget(name,
1645 xmDrawnButtonWidgetClass,
1646 parent, False,
1647 var, count);
1648 va_end(var);
1649 return w;
1650 }
1651
1652 Widget
XmVaCreateManagedDrawnButton(Widget parent,char * name,...)1653 XmVaCreateManagedDrawnButton(
1654 Widget parent,
1655 char *name,
1656 ...)
1657 {
1658 Widget w = NULL;
1659 va_list var;
1660 int count;
1661
1662 Va_start(var, name);
1663 count = XmeCountVaListSimple(var);
1664 va_end(var);
1665
1666 Va_start(var, name);
1667 w = XmeVLCreateWidget(name,
1668 xmDrawnButtonWidgetClass,
1669 parent, True,
1670 var, count);
1671 va_end(var);
1672 return w;
1673 }
1674