home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / xfe / XfeWidgets / Xfe / Button.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  64.6 KB  |  2,521 lines

  1. /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18. /*-----------------------------------------*/
  19. /*                                                                        */
  20. /* Name:        <Xfe/Button.c>                                            */
  21. /* Description:    XfeButton widget source.                                */
  22. /* Author:        Ramiro Estrugo <ramiro@netscape.com>                    */
  23. /*                                                                        */
  24. /*----------------------------------------------------------------------*/
  25.  
  26.  
  27. #include <Xfe/ButtonP.h>
  28. #include <Xfe/ManagerP.h>
  29.  
  30. /*----------------------------------------------------------------------*/
  31. /*                                                                        */
  32. /* Warnings and messages                                                */
  33. /*                                                                        */
  34. /*----------------------------------------------------------------------*/
  35. #define MESSAGE1 "Widget is not a XfeButton."
  36.  
  37.  
  38. #define MESSAGE2  "XmNpixmap needs to have the same depth as the XfeButton."
  39. #define MESSAGE3  "Cannot obtain geometry info for XmNpixmap."
  40. #define MESSAGE4  "Cannot obtain geometry info for XmNarmedPixmap."
  41. #define MESSAGE5  "Cannot obtain geometry info for XmNraisedPixmap."
  42. #define MESSAGE6  "Cannot obtain geometry info for XmNinsensitivePixmap."
  43. #define MESSAGE7  "Cannot use XmNarmedPixmap since XmNpixmap is bad."
  44. #define MESSAGE8  "Cannot use XmNraisedPixmap since XmNpixmap is bad."
  45. #define MESSAGE9  "Cannot use XmNinsensitivePixmap since XmNpixmap is bad."
  46. #define MESSAGE10 "XmNarmedPixmap dimensions do not match XmNpixmap."
  47. #define MESSAGE11 "XmNraisedPixmap dimensions do not match XmNpixmap."
  48. #define MESSAGE12 "XmNinsensitivePixmap dimensions do not match XmNpixmap."
  49. #define MESSAGE13 "XmNarmedPixmap needs to have same depth as the XfeButton."
  50. #define MESSAGE14 "XmNraisedPixmap needs to have same depth as the XfeButton."
  51. #define MESSAGE15 "XmNinsensitivePixmap needs to have same depth as the XfeButton."
  52. #define MESSAGE16 "XfeButtonPreferredGeometry: The given layout is invalid."
  53. #define MESSAGE17 "XmNarmed can only be set for XmBUTTON_TOGGLE XmNbuttonType."
  54. #define MESSAGE18 "XmNraised can only be set when XmNraiseOnEnter is True."
  55.  
  56. #define RAISE_OFFSET(bp) \
  57. (bp->raise_on_enter ? bp->raise_border_thickness : 0)
  58.  
  59. #define XY_IN_LABEL(_lp,_x,_y) XfePointInRect(&(_lp)->label_rect,(_x),(_y))
  60. #define XY_IN_PIXMAP(_bp,_x,_y) XfePointInRect(&(_bp)->pixmap_rect,(_x),(_y))
  61.  
  62. #define MIN_COMP_WIDTH(_lp,_bp) \
  63. XfeMin((_bp)->pixmap_rect.width,(_lp)->label_rect.width)
  64.  
  65. #define MIN_COMP_HEIGHT(_lp,_bp) \
  66. XfeMin((bp)->pixmap_rect.height,(_lp)->label_rect.height)
  67.  
  68. /*----------------------------------------------------------------------*/
  69. /*                                                                        */
  70. /* Core class methods                                                    */
  71. /*                                                                        */
  72. /*----------------------------------------------------------------------*/
  73. static void        ClassPartInit    (WidgetClass);
  74. static void     Initialize        (Widget,Widget,ArgList,Cardinal *);
  75. static void     Destroy            (Widget);
  76. static Boolean    SetValues        (Widget,Widget,Widget,ArgList,Cardinal *);
  77.  
  78. /*----------------------------------------------------------------------*/
  79. /*                                                                        */
  80. /* XfePrimitive class methods                                            */
  81. /*                                                                        */
  82. /*----------------------------------------------------------------------*/
  83. static void    PreferredGeometry    (Widget,Dimension *,Dimension *);
  84. static void    PrepareComponents    (Widget,int);
  85. static void    LayoutComponents    (Widget);
  86. static void    DrawComponents        (Widget,XEvent *,Region,XRectangle *);
  87. static void    DrawBackground        (Widget,XEvent *,Region,XRectangle *);
  88. static void    DrawShadow            (Widget,XEvent *,Region,XRectangle *);
  89.  
  90. /*----------------------------------------------------------------------*/
  91. /*                                                                        */
  92. /* XfeLabel class methods                                                */
  93. /*                                                                        */
  94. /*----------------------------------------------------------------------*/
  95. static void    LayoutString            (Widget);
  96. static void    DrawString            (Widget,XEvent *,Region,XRectangle *);
  97. static GC    GetLabelGC            (Widget);
  98.  
  99. /*----------------------------------------------------------------------*/
  100. /*                                                                        */
  101. /* XfeButton class methods                                                */
  102. /*                                                                        */
  103. /*----------------------------------------------------------------------*/
  104. static void    LayoutPixmap        (Widget);
  105. static void    DrawPixmap            (Widget,XEvent *,Region,XRectangle *);
  106. static void    DrawRaiseBorder        (Widget,XEvent *,Region,XRectangle *);
  107. static void    ArmTimeout            (XtPointer,XtIntervalId *);
  108.  
  109. /*----------------------------------------------------------------------*/
  110. /*                                                                        */
  111. /* Misc XfeButton functions                                                */
  112. /*                                                                        */
  113. /*----------------------------------------------------------------------*/
  114. static void        PixmapPrepare                (Widget);
  115. static void        PixmapArmedPrepare            (Widget);
  116. static void        PixmapRaisedPrepare            (Widget);
  117. static void        PixmapInsensPrepare            (Widget);
  118.  
  119. static void        StringLayoutLabelOnBottom    (Widget);
  120. static void        StringLayoutLabelOnLeft        (Widget);
  121. static void        StringLayoutLabelOnRight    (Widget);
  122. static void        StringLayoutLabelOnTop        (Widget);
  123. static void        StringLayoutLabelOnly        (Widget);
  124.  
  125. static void        InvokeCallback            (Widget,XtCallbackList,int,XEvent *);
  126.  
  127. static Boolean    AcceptEvent                (Widget,XEvent *);
  128. static Boolean    SpacingContainsXY        (Widget,int,int);
  129.  
  130. static void        TransparentCursorSetState        (Widget,Boolean);
  131.  
  132. /*----------------------------------------------------------------------*/
  133. /*                                                                        */
  134. /* Resource Callprocs                                                    */
  135. /*                                                                        */
  136. /*----------------------------------------------------------------------*/
  137. static void    DefaultArmBackground    (Widget,int,XrmValue *);
  138. static void    DefaultRaiseBackground    (Widget,int,XrmValue *);
  139.  
  140. /*----------------------------------------------------------------------*/
  141. /*                                                                        */
  142. /* XfeButton Resources                                                    */
  143. /*                                                                        */
  144. /*----------------------------------------------------------------------*/
  145. static XtResource resources[] = 
  146. {
  147.     /* Callback resources */         
  148.     { 
  149.         XmNactivateCallback,
  150.         XmCCallback,
  151.         XmRCallback,
  152.         sizeof(XtCallbackList),
  153.         XtOffsetOf(XfeButtonRec , xfe_button . activate_callback),
  154.         XmRImmediate, 
  155.         (XtPointer) NULL
  156.     },
  157.     { 
  158.         XmNarmCallback,
  159.         XmCCallback,
  160.         XmRCallback,
  161.         sizeof(XtCallbackList),
  162.         XtOffsetOf(XfeButtonRec , xfe_button . arm_callback),
  163.         XmRImmediate, 
  164.         (XtPointer) NULL
  165.     },
  166.     { 
  167.         XmNbutton3DownCallback,
  168.         XmCCallback,
  169.         XmRCallback,
  170.         sizeof(XtCallbackList),
  171.         XtOffsetOf(XfeButtonRec , xfe_button . button_3_down_callback),
  172.         XmRImmediate, 
  173.         (XtPointer) NULL
  174.     },
  175.     { 
  176.         XmNbutton3UpCallback,
  177.         XmCCallback,
  178.         XmRCallback,
  179.         sizeof(XtCallbackList),
  180.         XtOffsetOf(XfeButtonRec , xfe_button . button_3_up_callback),
  181.         XmRImmediate, 
  182.         (XtPointer) NULL
  183.     },
  184.     { 
  185.         XmNdisarmCallback,
  186.         XmCCallback,
  187.         XmRCallback,
  188.         sizeof(XtCallbackList),
  189.         XtOffsetOf(XfeButtonRec , xfe_button . disarm_callback),
  190.         XmRImmediate, 
  191.         (XtPointer) NULL
  192.     },
  193.     
  194.     /* Label resources */
  195.     { 
  196.         XmNraiseForeground,
  197.         XmCRaiseForeground,
  198.         XmRPixel,
  199.         sizeof(Pixel),
  200.         XtOffsetOf(XfeButtonRec , xfe_button . raise_foreground),
  201.         XmRCallProc, 
  202.         (XtPointer) _XfeCallProcCopyForeground
  203.     },
  204.  
  205.     /* Pixmap resources */
  206.     { 
  207.         XmNarmedPixmap,
  208.         XmCArmedPixmap,
  209.         XmRPixmap,
  210.         sizeof(Pixmap),
  211.         XtOffsetOf(XfeButtonRec , xfe_button . armed_pixmap),
  212.         XmRImmediate, 
  213.         (XtPointer) XmUNSPECIFIED_PIXMAP
  214.     },
  215.     { 
  216.         XmNinsensitivePixmap,
  217.         XmCInsensitivePixmap,
  218.         XmRPixmap,
  219.         sizeof(Pixmap),
  220.         XtOffsetOf(XfeButtonRec , xfe_button . insensitive_pixmap),
  221.         XmRImmediate, 
  222.         (XtPointer) XmUNSPECIFIED_PIXMAP
  223.     },
  224.     { 
  225.         XmNpixmap,
  226.         XmCPixmap,
  227.         XmRPixmap,
  228.         sizeof(Pixmap),
  229.         XtOffsetOf(XfeButtonRec , xfe_button . pixmap),
  230.         XmRImmediate, 
  231.         (XtPointer) XmUNSPECIFIED_PIXMAP
  232.     },
  233.     { 
  234.         XmNraisedPixmap,
  235.         XmCRaisedPixmap,
  236.         XmRPixmap,
  237.         sizeof(Pixmap),
  238.         XtOffsetOf(XfeButtonRec , xfe_button . raised_pixmap),
  239.         XmRImmediate, 
  240.         (XtPointer) XmUNSPECIFIED_PIXMAP
  241.     },
  242.     { 
  243.         XmNarmedPixmapMask,
  244.         XmCArmedPixmapMask,
  245.         XmRPixmap,
  246.         sizeof(Pixmap),
  247.         XtOffsetOf(XfeButtonRec , xfe_button . armed_pixmap_mask),
  248.         XmRImmediate, 
  249.         (XtPointer) XmUNSPECIFIED_PIXMAP
  250.     },
  251.     { 
  252.         XmNinsensitivePixmapMask,
  253.         XmCInsensitivePixmapMask,
  254.         XmRPixmap,
  255.         sizeof(Pixmap),
  256.         XtOffsetOf(XfeButtonRec , xfe_button . insensitive_pixmap_mask),
  257.         XmRImmediate, 
  258.         (XtPointer) XmUNSPECIFIED_PIXMAP
  259.     },
  260.     { 
  261.         XmNpixmapMask,
  262.         XmCPixmapMask,
  263.         XmRPixmap,
  264.         sizeof(Pixmap),
  265.         XtOffsetOf(XfeButtonRec , xfe_button . pixmap_mask),
  266.         XmRImmediate, 
  267.         (XtPointer) XmUNSPECIFIED_PIXMAP
  268.     },
  269.     { 
  270.         XmNraisedPixmapMask,
  271.         XmCRaisedPixmapMask,
  272.         XmRPixmap,
  273.         sizeof(Pixmap),
  274.         XtOffsetOf(XfeButtonRec , xfe_button . raised_pixmap_mask),
  275.         XmRImmediate, 
  276.         (XtPointer) XmUNSPECIFIED_PIXMAP
  277.     },
  278.  
  279.     /* Raise resources */
  280.     { 
  281.         XmNfillOnEnter,
  282.         XmCFillOnEnter,
  283.         XmRBoolean,
  284.         sizeof(Boolean),
  285.         XtOffsetOf(XfeButtonRec , xfe_button . fill_on_enter),
  286.         XmRImmediate, 
  287.         (XtPointer) False
  288.     },
  289.     { 
  290.         XmNraised,
  291.         XmCRaised,
  292.         XmRBoolean,
  293.         sizeof(Boolean),
  294.         XtOffsetOf(XfeButtonRec , xfe_button . raised),
  295.         XmRImmediate, 
  296.         (XtPointer) False
  297.     },
  298.     { 
  299.         XmNraiseBackground,
  300.         XmCRaiseBackground,
  301.         XmRPixel,
  302.         sizeof(Pixel),
  303.         XtOffsetOf(XfeButtonRec , xfe_button . raise_background),
  304.         XmRCallProc, 
  305.         (XtPointer) DefaultRaiseBackground
  306.     },
  307.     { 
  308.         XmNraiseBorderThickness,
  309.         XmCRaiseBorderThickness,
  310.         XmRHorizontalDimension,
  311.         sizeof(Dimension),
  312.         XtOffsetOf(XfeButtonRec , xfe_button . raise_border_thickness),
  313.         XmRImmediate, 
  314.         (XtPointer) 1
  315.     },
  316.     { 
  317.         XmNraiseOnEnter,
  318.         XmCRaiseOnEnter,
  319.         XmRBoolean,
  320.         sizeof(Boolean),
  321.         XtOffsetOf(XfeButtonRec , xfe_button . raise_on_enter),
  322.         XmRImmediate, 
  323.         (XtPointer) True
  324.     },
  325.  
  326.     /* Arm resources */
  327.     { 
  328.         XmNfillOnArm,
  329.         XmCFillOnArm,
  330.         XmRBoolean,
  331.         sizeof(Boolean),
  332.         XtOffsetOf(XfeButtonRec , xfe_button . fill_on_arm),
  333.         XmRImmediate, 
  334.         (XtPointer) True
  335.     },
  336.     { 
  337.         XmNarmBackground,
  338.         XmCArmBackground,
  339.         XmRPixel,
  340.         sizeof(Pixel),
  341.         XtOffsetOf(XfeButtonRec , xfe_button . arm_background),
  342.         XmRCallProc, 
  343.         (XtPointer) DefaultArmBackground
  344.     },
  345.     { 
  346.         XmNarmOffset,
  347.         XmCArmOffset,
  348.         XmRHorizontalDimension,
  349.         sizeof(Dimension),
  350.         XtOffsetOf(XfeButtonRec , xfe_button . arm_offset),
  351.         XmRImmediate, 
  352.         (XtPointer) XfeDEFAULT_ARM_OFFSET
  353.     },
  354.     { 
  355.         XmNarmed,
  356.         XmCArmed,
  357.         XmRBoolean,
  358.         sizeof(Boolean),
  359.         XtOffsetOf(XfeButtonRec , xfe_button . armed),
  360.         XmRImmediate, 
  361.         (XtPointer) False
  362.     },
  363.     { 
  364.         XmNdeterminate,
  365.         XmCDeterminate,
  366.         XmRBoolean,
  367.         sizeof(Boolean),
  368.         XtOffsetOf(XfeButtonRec , xfe_button . determinate),
  369.         XmRImmediate, 
  370.         (XtPointer) True
  371.     },
  372.  
  373.  
  374.     /* Misc resources */
  375.     { 
  376.         XmNbuttonLayout,
  377.         XmCButtonLayout,
  378.         XmRButtonLayout,
  379.         sizeof(unsigned char),
  380.         XtOffsetOf(XfeButtonRec , xfe_button . button_layout),
  381.         XmRImmediate, 
  382.         (XtPointer) XmBUTTON_LABEL_ON_BOTTOM
  383.     },
  384.     { 
  385.         XmNbuttonTrigger,
  386.         XmCButtonTrigger,
  387.         XmRButtonTrigger,
  388.         sizeof(unsigned char),
  389.         XtOffsetOf(XfeButtonRec , xfe_button . button_trigger),
  390.         XmRImmediate, 
  391.         (XtPointer) XmBUTTON_TRIGGER_ANYWHERE
  392.     },
  393.     { 
  394.         XmNbuttonType,
  395.         XmCButtonType,
  396.         XmRButtonType,
  397.         sizeof(unsigned char),
  398.         XtOffsetOf(XfeButtonRec , xfe_button . button_type),
  399.         XmRImmediate, 
  400.         (XtPointer) XmBUTTON_PUSH
  401.     },
  402.     { 
  403.         XmNemulateMotif,
  404.         XmCEmulateMotif,
  405.         XmRBoolean,
  406.         sizeof(Boolean),
  407.         XtOffsetOf(XfeButtonRec , xfe_button . emulate_motif),
  408.         XmRImmediate, 
  409.         (XtPointer) XfeDEFAULT_EMULATE_MOTIF
  410.     },
  411.     { 
  412.         XmNspacing,
  413.         XmCSpacing,
  414.         XmRHorizontalDimension,
  415.         sizeof(Dimension),
  416.         XtOffsetOf(XfeButtonRec , xfe_button . spacing),
  417.         XmRImmediate, 
  418.         (XtPointer) 4
  419.     },
  420.  
  421.     /* Cursor resources */
  422.     { 
  423.         XmNtransparentCursor,
  424.         XmCCursor,
  425.         XmRCursor,
  426.         sizeof(Cursor),
  427.         XtOffsetOf(XfeButtonRec , xfe_button . transparent_cursor),
  428.         XmRImmediate, 
  429.         (XtPointer) None
  430.     },
  431.     
  432.     
  433.     /* Force margins to 0 */
  434.     { 
  435.         XmNmarginBottom,
  436.         XmCMarginBottom,
  437.         XmRVerticalDimension,
  438.         sizeof(Dimension),
  439.         XtOffsetOf(XfeButtonRec , xfe_primitive . margin_bottom),
  440.         XmRImmediate, 
  441.         (XtPointer) 0
  442.     },
  443.     { 
  444.         XmNmarginLeft,
  445.         XmCMarginLeft,
  446.         XmRHorizontalDimension,
  447.         sizeof(Dimension),
  448.         XtOffsetOf(XfeButtonRec , xfe_primitive . margin_left),
  449.         XmRImmediate, 
  450.         (XtPointer) 0
  451.     },
  452.     { 
  453.         XmNmarginRight,
  454.         XmCMarginRight,
  455.         XmRHorizontalDimension,
  456.         sizeof(Dimension),
  457.         XtOffsetOf(XfeButtonRec , xfe_primitive . margin_right),
  458.         XmRImmediate, 
  459.         (XtPointer) 0
  460.     },
  461.     { 
  462.         XmNmarginTop,
  463.         XmCMarginTop,
  464.         XmRVerticalDimension,
  465.         sizeof(Dimension),
  466.         XtOffsetOf(XfeButtonRec , xfe_primitive . margin_top),
  467.         XmRImmediate, 
  468.         (XtPointer) 0
  469.     },
  470.  
  471.     /* Force buffer type to XmBUFFER_SHARED */
  472.     { 
  473.         XmNbufferType,
  474.         XmCBufferType,
  475.         XmRBufferType,
  476.         sizeof(unsigned char),
  477.         XtOffsetOf(XfeButtonRec , xfe_primitive . buffer_type),
  478.         XmRImmediate, 
  479.         (XtPointer) XmBUFFER_SHARED
  480.     },
  481. };
  482.  
  483. /*----------------------------------------------------------------------*/
  484. /*                                                                        */
  485. /* XfeButton Synthetic Resources                                        */
  486. /*                                                                        */
  487. /*----------------------------------------------------------------------*/
  488. static XmSyntheticResource syn_resources[] =
  489. {
  490.     { 
  491.         XmNarmOffset,
  492.         sizeof(Dimension),
  493.         XtOffsetOf(XfeButtonRec , xfe_button . arm_offset),
  494.         _XmFromHorizontalPixels,
  495.         _XmToHorizontalPixels 
  496.     },
  497.     { 
  498.         XmNraiseBorderThickness,
  499.         sizeof(Dimension),
  500.         XtOffsetOf(XfeButtonRec , xfe_button . raise_border_thickness),
  501.         _XmFromHorizontalPixels,
  502.         _XmToHorizontalPixels 
  503.     },
  504.     { 
  505.         XmNspacing,
  506.         sizeof(Dimension),
  507.         XtOffsetOf(XfeButtonRec , xfe_button . spacing),
  508.         _XmFromHorizontalPixels,
  509.         _XmToHorizontalPixels 
  510.     },
  511. };
  512.  
  513. /*----------------------------------------------------------------------*/
  514. /*                                                                        */
  515. /* XfeButton actions                                                    */
  516. /*                                                                        */
  517. /*----------------------------------------------------------------------*/
  518. static XtActionsRec actions[] = 
  519. {
  520.     { "Enter",                _XfeButtonEnter                },
  521.     { "Leave",                _XfeButtonLeave                },
  522.     { "Motion",                _XfeButtonMotion            },
  523.     { "Activate",            _XfeButtonActivate            },
  524.     { "Arm",                _XfeButtonArm                },
  525.     { "Disarm",                _XfeButtonDisarm            },
  526.     { "ArmAndActivate",        _XfeButtonArmAndActivate    },
  527.     { "Btn3Down",            _XfeButtonBtn3Down            },
  528.     { "Btn3Up",                _XfeButtonBtn3Up            },
  529. };
  530.  
  531. /*----------------------------------------------------------------------*/
  532. /*                                                                        */
  533. /* XfeButton widget class record initialization                            */
  534. /*                                                                        */
  535. /*----------------------------------------------------------------------*/
  536. _XFE_WIDGET_CLASS_RECORD(button,Button) =
  537. {
  538.     {
  539.         /* Core Part */
  540.         (WidgetClass) &xfeLabelClassRec,        /* superclass             */
  541.         "XfeButton",                            /* class_name             */
  542.         sizeof(XfeButtonRec),                    /* widget_size            */
  543.         NULL,                                    /* class_initialize       */
  544.         ClassPartInit,                            /* class_part_initialize*/
  545.         FALSE,                                  /* class_inited           */
  546.         Initialize,                             /* initialize             */
  547.         NULL,                                   /* initialize_hook        */
  548.         XtInheritRealize,                       /* realize                */
  549.         actions,                                /* actions                */
  550.         XtNumber(actions),                        /* num_actions            */
  551.         resources,                              /* resources              */
  552.         XtNumber(resources),                    /* num_resources          */
  553.         NULLQUARK,                              /* xrm_class              */
  554.         TRUE,                                   /* compress_motion        */
  555.         XtExposeCompressMaximal,                /* compress_exposure      */
  556.         TRUE,                                   /* compress_enterleave    */
  557.         FALSE,                                  /* visible_interest       */
  558.         Destroy,                                /* destroy                */
  559.         XtInheritResize,                        /* resize                 */
  560.         XtInheritExpose,                        /* expose                 */
  561.         SetValues,                              /* set_values             */
  562.         NULL,                                   /* set_values_hook        */
  563.         XtInheritSetValuesAlmost,                /* set_values_almost      */
  564.         NULL,                                    /* get_values_hook        */
  565.         NULL,                                   /* accept_focus           */
  566.         XtVersion,                              /* version                */
  567.         NULL,                                   /* callback_private       */
  568.         _XfeButtonDefaultTranslations,            /* tm_table               */
  569.         XtInheritQueryGeometry,                    /* query_geometry         */
  570.         XtInheritDisplayAccelerator,            /* display accel          */
  571.         NULL,                                   /* extension              */
  572.     },
  573.  
  574.     /* XmPrimitive Part */
  575.     {
  576.         XmInheritBorderHighlight,                /* border_highlight        */
  577.         XmInheritBorderUnhighlight,                /* border_unhighlight     */
  578.         XtInheritTranslations,                  /* translations           */
  579.         _XfeButtonArmAndActivate,                /* arm_and_activate       */
  580.         syn_resources,                            /* syn resources          */
  581.         XtNumber(syn_resources),                /* num syn_resources      */
  582.         NULL,                                    /* extension              */
  583.     },
  584.  
  585.     /* XfePrimitive Part */
  586.     {
  587.         XfeInheritBitGravity,                    /* bit_gravity            */
  588.         PreferredGeometry,                        /* preferred_geometry    */
  589.         XfeInheritMinimumGeometry,                /* minimum_geometry        */
  590.         XfeInheritUpdateRect,                    /* update_rect            */
  591.         PrepareComponents,                        /* prepare_components    */
  592.         LayoutComponents,                        /* layout_components    */
  593.         DrawBackground,                            /* draw_background        */
  594.         DrawShadow,                                /* draw_shadow            */
  595.         DrawComponents,                            /* draw_components        */
  596.         NULL,                                    /* extension            */
  597.     },
  598.  
  599.     /* XfeLabel Part */
  600.     {
  601.         LayoutString,                            /* layout_string        */
  602.         DrawString,                                /* draw_string            */
  603.         XfeInheritDrawSelection,                /* draw_selection        */
  604.         GetLabelGC,                                /* get_label_gc            */
  605.         XfeInheritGetSelectionGC,                /* get_selection_gc        */
  606.         NULL,                                    /* extension            */
  607.     },
  608.  
  609.     /* XfeButton Part */
  610.     {
  611.         LayoutPixmap,                            /* layout_pixmap        */
  612.         DrawPixmap,                                /* draw_pixmap            */
  613.         DrawRaiseBorder,                        /* draw_raise_border    */
  614.         ArmTimeout,                                /* arm_timeout            */
  615.         NULL,                                    /* extension            */
  616.     },
  617. };
  618.  
  619. /*----------------------------------------------------------------------*/
  620. /*                                                                        */
  621. /* xfeButtonWidgetClass declaration.                                    */
  622. /*                                                                        */
  623. /*----------------------------------------------------------------------*/
  624. _XFE_WIDGET_CLASS(button,Button);
  625.  
  626. /*----------------------------------------------------------------------*/
  627. /*                                                                        */
  628. /* XfeButton resource call procedures                                    */
  629. /*                                                                        */
  630. /*----------------------------------------------------------------------*/
  631. static void
  632. DefaultArmBackground(Widget w,int offset,XrmValue * value)
  633. {
  634.     XfeButtonPart *        bp = _XfeButtonPart(w);
  635.     static Pixel        arm_background;
  636.  
  637.     if (bp->fill_on_arm)
  638.     {
  639.         arm_background = XfeSelectPixel(w,bp->raise_background);
  640.     }
  641.     else
  642.     {
  643.         arm_background = _XfeBackgroundPixel(w);
  644.     }
  645.    
  646.     value->addr = (XPointer) &arm_background;
  647.     value->size = sizeof(arm_background);
  648. }
  649. /*----------------------------------------------------------------------*/
  650. static void
  651. DefaultRaiseBackground(Widget w,int offset,XrmValue * value)
  652. {
  653.     XfeButtonPart *        bp = _XfeButtonPart(w);
  654.     static Pixel        raise_background;
  655.  
  656.     if (bp->fill_on_enter)
  657.     {
  658.         raise_background = XfeSelectPixel(w,_XfeBackgroundPixel(w));
  659.     }
  660.     else
  661.     {
  662.         raise_background = _XfeBackgroundPixel(w);
  663.     }
  664.    
  665.     value->addr = (XPointer) &raise_background;
  666.     value->size = sizeof(raise_background);
  667. }
  668. /*----------------------------------------------------------------------*/
  669.  
  670. /*----------------------------------------------------------------------*/
  671. /*                                                                        */
  672. /* Core class methods                                                    */
  673. /*                                                                        */
  674. /*----------------------------------------------------------------------*/
  675. static void
  676. ClassPartInit(WidgetClass wc)
  677. {
  678.     XfeButtonWidgetClass cc = (XfeButtonWidgetClass) wc;
  679.     XfeButtonWidgetClass sc = (XfeButtonWidgetClass) wc->core_class.superclass;
  680.  
  681.     /* Resolve inheritance of all XfeButton class methods */
  682.     _XfeResolve(cc,sc,xfe_button_class,layout_pixmap,XfeInheritLayoutPixmap);
  683.     _XfeResolve(cc,sc,xfe_button_class,draw_pixmap,XfeInheritDrawPixmap);
  684.  
  685.     _XfeResolve(cc,sc,xfe_button_class,draw_raise_border,
  686.                 XfeInheritDrawRaiseBorder);
  687.  
  688.     _XfeResolve(cc,sc,xfe_button_class,arm_timeout,XfeInheritArmTimeout);
  689. }
  690. /*----------------------------------------------------------------------*/
  691. static void
  692. Initialize(Widget rw,Widget nw,ArgList args,Cardinal *nargs)
  693. {
  694.     XfeButtonPart * bp = _XfeButtonPart(nw);
  695.     XfeLabelPart *    lp = _XfeLabelPart(nw);
  696.  
  697.     /* Make sure rep types are ok */
  698.     XfeRepTypeCheck(nw,XmRButtonType,&bp->button_type,
  699.                     XmBUTTON_PUSH);
  700.     
  701.     XfeRepTypeCheck(nw,XmRButtonLayout,&bp->button_layout,
  702.                     XmBUTTON_LABEL_ON_BOTTOM);
  703.     
  704.     XfeRepTypeCheck(nw,XmRButtonTrigger,&bp->button_trigger,
  705.                     XmBUTTON_TRIGGER_ANYWHERE);
  706.  
  707.     /* Allocate the label raised GCs */
  708.     bp->label_raised_GC = XfeAllocateStringGc(nw,lp->font_list,
  709.                                               bp->raise_foreground,
  710.                                               None,True);
  711.  
  712.     /* Allocate the armed GCs */
  713.     bp->armed_GC = XfeAllocateColorGc(nw,bp->arm_background,None,True);
  714.     
  715.     /* Allocate the raised GCs */
  716.     bp->raised_GC = XfeAllocateColorGc(nw,bp->raise_background,None,True);
  717.  
  718.     /* Allocate the pixmap GC */
  719.     bp->pixmap_GC = XfeAllocateTransparentGc(nw);
  720.  
  721.     /* Initialize other private members */
  722.     bp->clicking                    = False;
  723.     bp->transparent_cursor_state    = False;
  724.  
  725.     /* Make sure the background gc is allocated if needed */
  726.     if (_XfePixmapGood(bp->insensitive_pixmap))
  727.     {
  728.         _XfePrimitiveAllocateBackgroundGC(nw);
  729.     }
  730.  
  731.     /* Need to track motion if trigger is not anywhere */
  732.     if (bp->button_trigger != XmBUTTON_TRIGGER_ANYWHERE)
  733.     {
  734.         XfeOverrideTranslations(nw,_XfeButtonMotionAddTranslations);
  735.     }
  736.  
  737.     /* Finish of initialization */
  738.     _XfePrimitiveChainInitialize(rw,nw,xfeButtonWidgetClass);
  739. }
  740. /*----------------------------------------------------------------------*/
  741. static void
  742. Destroy(Widget w)
  743. {
  744.     XfeButtonPart * bp = _XfeButtonPart(w);
  745.  
  746.     /* Release GCs */
  747.     XtReleaseGC(w,bp->armed_GC);
  748.     XtReleaseGC(w,bp->label_raised_GC);
  749.     XtReleaseGC(w,bp->pixmap_GC);
  750.     XtReleaseGC(w,bp->raised_GC);
  751.  
  752.     /* Remove all CallBacks */
  753.     /* XtRemoveAllCallbacks(w,XmNactivateCallback); */
  754.     /* XtRemoveAllCallbacks(w,XmNarmCallback); */
  755.     /* XtRemoveAllCallbacks(w,XmNdisarmCallback); */
  756. }
  757. /*----------------------------------------------------------------------*/
  758. static Boolean
  759. SetValues(Widget ow,Widget rw,Widget nw,ArgList args,Cardinal *nargs)
  760. {
  761.     XfeButtonPart *    np = _XfeButtonPart(nw);
  762.     XfeButtonPart *    op = _XfeButtonPart(ow);
  763.     XfeLabelPart *    nlp = _XfeLabelPart(nw);
  764.     Boolean            label_raised_gc_flag = False;
  765.     Boolean            armed_gc_flag = False;
  766.     Boolean            raised_gc_flag = False;
  767.  
  768.     /* button_type */
  769.     if (np->button_type != op->button_type)
  770.     {
  771.         /* Make sure the new button type is ok */
  772.         XfeRepTypeCheck(nw,XmRButtonType,&np->button_type,
  773.                         XmBUTTON_PUSH);
  774.  
  775. #if 0
  776.         /* If the new button_type is not toggle, make sure we are not armed */
  777.         if (np->button_type != XmBUTTON_TOGGLE)
  778.         {
  779.             np->armed = False;
  780.         }
  781. #endif
  782.  
  783.         _XfeConfigFlags(nw) |= XfeConfigExpose;
  784.     }
  785.  
  786.     /* button_layout */
  787.     if (np->button_layout != op->button_layout)
  788.     {
  789.         /* Make sure the new layout type is ok */
  790.         XfeRepTypeCheck(nw,XmRButtonLayout,&np->button_layout,
  791.                         XmBUTTON_LABEL_ON_BOTTOM);
  792.  
  793.         _XfeConfigFlags(nw) |= XfeConfigGLE;
  794.     }
  795.  
  796.     /* button_trigger */
  797.     if (np->button_trigger != op->button_trigger)
  798.     {
  799.         /* Make sure the new trigger type is ok */
  800.         XfeRepTypeCheck(nw,XmRButtonTrigger,&np->button_trigger,
  801.                         XmBUTTON_TRIGGER_ANYWHERE);
  802.  
  803.         /* No motion tracking */
  804.         if (np->button_trigger == XmBUTTON_TRIGGER_ANYWHERE)
  805.         {
  806.             XfeOverrideTranslations(nw,_XfeButtonMotionRemoveTranslations);
  807.         }
  808.         /* Yes motion tracking */
  809.         else
  810.         {
  811.             XfeOverrideTranslations(nw,_XfeButtonMotionAddTranslations);
  812.         }
  813.     }
  814.  
  815.     /* raise_border_thickness */
  816.     if (np->raise_border_thickness != op->raise_border_thickness)
  817.     {
  818.         _XfeConfigFlags(nw) |= XfeConfigGLE;
  819.     }
  820.  
  821.     /* arm_offset */
  822.     if (np->arm_offset != op->arm_offset)
  823.     {
  824.         _XfeConfigFlags(nw) |= XfeConfigGLE;
  825.     }
  826.  
  827.  
  828.     /* background */
  829.     if (_XfeBackgroundPixel(nw) != _XfeBackgroundPixel(ow))
  830.     {
  831.         _XfeConfigFlags(nw) |= XfeConfigExpose;
  832.     }
  833.  
  834.     if (np->determinate != op->determinate)
  835.     {
  836.         _XfeConfigFlags(nw) |= XfeConfigExpose;
  837.     }
  838.  
  839.     /* spacing */
  840.     if (np->spacing != op->spacing)
  841.     {
  842.         _XfeConfigFlags(nw) |= XfeConfigGLE;
  843.     }
  844.  
  845.     /* pixmap */
  846.     if (np->pixmap != op->pixmap)
  847.     {
  848.         _XfeConfigFlags(nw) |= XfeConfigGLE;
  849.  
  850.         _XfePrepareFlags(nw) |= _XFE_PREPARE_BUTTON_PIXMAP;
  851.     }
  852.  
  853.     /* armed_pixmap */
  854.     if (np->armed_pixmap != op->armed_pixmap)
  855.     {
  856.         _XfeConfigFlags(nw) |= XfeConfigExpose;
  857.  
  858.         _XfePrepareFlags(nw) |= _XFE_PREPARE_BUTTON_ARMED_PIXMAP;
  859.     }
  860.  
  861.     /* raised_pixmap */
  862.     if (np->raised_pixmap != op->raised_pixmap)
  863.     {
  864.         _XfeConfigFlags(nw) |= XfeConfigExpose;
  865.  
  866.         _XfePrepareFlags(nw) |= _XFE_PREPARE_BUTTON_RAISED_PIXMAP;
  867.     }
  868.  
  869.     /* insensitive_pixmap */
  870.     if (np->insensitive_pixmap != op->insensitive_pixmap)
  871.     {
  872.         _XfeConfigFlags(nw) |= XfeConfigExpose;
  873.  
  874.         _XfePrepareFlags(nw) |= _XFE_PREPARE_BUTTON_INSENSITIVE_PIXMAP;
  875.  
  876.         /* Make sure the background gc is allocated if needed */
  877.         if (_XfePixmapGood(np->insensitive_pixmap))
  878.         {
  879.             _XfePrimitiveAllocateBackgroundGC(nw);
  880.         }
  881.     }
  882.  
  883.     /* armed */
  884.     if (np->armed != op->armed)
  885.     {
  886.         if (np->button_type == XmBUTTON_TOGGLE)
  887.         {
  888.             _XfeConfigFlags(nw) |= XfeConfigExpose;
  889.         }
  890.         else
  891.         {
  892.             _XfeWarning(nw,MESSAGE17);
  893.             
  894.             np->armed = op->armed;
  895.         }
  896.     }
  897.  
  898.     /* raise_on_enter */
  899.     if (np->raise_on_enter != op->raise_on_enter)
  900.     {
  901.         /* Make sure we are not raised if raise_on_enter changes */
  902.         np->raised = False;
  903.  
  904.         _XfeConfigFlags(nw) |= XfeConfigExpose;
  905.     }
  906.  
  907.     /* raised */
  908.     if (np->raised != op->raised)
  909.     {
  910.         if (!np->raise_on_enter)
  911.         {
  912.             _XfeWarning(nw,MESSAGE18);
  913.             
  914.             np->raised = op->raised;
  915.         }
  916.         else
  917.         {
  918.             _XfeConfigFlags(nw) |= XfeConfigExpose;
  919.         }
  920.     }
  921.  
  922.     /* sensitive */
  923.     if (_XfeSensitive(nw) != _XfeSensitive(ow))
  924.     {
  925.         /* If button is now insensitive make sure old states are cleared */
  926.         if (!_XfeSensitive(nw))
  927.         {
  928.             np->armed = False;
  929.             np->clicking = False;
  930.             np->raised = False;
  931.         }
  932.         else
  933.         {
  934.             /* Button is now sensitive and pointer is inside */
  935.             if (_XfePointerInside(nw) && np->raise_on_enter)
  936.             {
  937.                 /* The button is raised if the pointer is still inside */
  938.                 np->raised = True;
  939.             }
  940.         }
  941.     }
  942.  
  943.     /* pretend_sensitive */
  944.     if (_XfePretendSensitive(nw) != _XfePretendSensitive(ow))
  945.     {
  946.         /* 
  947.          * If button is now pretending to be insensitive, make sure 
  948.          * old states are cleared 
  949.          */
  950.         if (!_XfePretendSensitive(nw))
  951.         {
  952.             np->armed = False;
  953.             np->clicking = False;
  954.             np->raised = False;
  955.         }
  956.         else
  957.         {
  958.             /* Button is now sensitive and pointer is inside */
  959.             if (_XfePointerInside(nw) && np->raise_on_enter)
  960.             {
  961.                 /* The button is raised if the pointer is still inside */
  962.                 np->raised = True;
  963.             }
  964.         }
  965.     }
  966.  
  967.     /* raise_foreground */
  968.     if (np->raise_foreground != op->raise_foreground)
  969.     {
  970.         label_raised_gc_flag = True;   
  971.  
  972.         if (np->raised)
  973.         {
  974.             _XfeConfigFlags(nw) |= XfeConfigExpose;
  975.         }
  976.     }
  977.  
  978.     /* fill_on_arm */
  979.     if (np->fill_on_arm != op->fill_on_arm)
  980.     {
  981.         if (np->armed)
  982.         {
  983.             _XfeConfigFlags(nw) |= XfeConfigExpose;
  984.         }
  985.     }
  986.  
  987.     /* fill_on_enter */
  988.     if (np->fill_on_enter != op->fill_on_enter)
  989.     {
  990.         if (np->raised)
  991.         {
  992.             _XfeConfigFlags(nw) |= XfeConfigExpose;
  993.         }
  994.     }
  995.  
  996.     /* arm_background */
  997.     if (np->arm_background != op->arm_background)
  998.     {
  999.         armed_gc_flag = True;   
  1000.  
  1001.         if (np->armed && np->fill_on_arm)
  1002.         {
  1003.             _XfeConfigFlags(nw) |= XfeConfigExpose;
  1004.         }
  1005.     }
  1006.  
  1007.     /* raise_background */
  1008.     if (np->raise_background != op->raise_background)
  1009.     {
  1010.         raised_gc_flag = True;   
  1011.  
  1012.         if (np->raised && np->fill_on_enter)
  1013.         {
  1014.             _XfeConfigFlags(nw) |= XfeConfigExpose;
  1015.         }
  1016.     }
  1017.  
  1018.  
  1019.     /* Update the label raised GC */
  1020.     if (label_raised_gc_flag)
  1021.     {
  1022.         /* Release the old label GC */
  1023.         XtReleaseGC(nw,np->label_raised_GC);
  1024.     
  1025.         /* Allocate the new label GC */
  1026.         np->label_raised_GC = XfeAllocateStringGc(nw,nlp->font_list,
  1027.                                                   np->raise_foreground,
  1028.                                                   None,True);
  1029.     }
  1030.  
  1031.     /* Update the armed GC */
  1032.     if (armed_gc_flag)
  1033.     {
  1034.         /* Release the old armed GC */
  1035.         XtReleaseGC(nw,np->armed_GC);
  1036.     
  1037.         /* Allocate the new armed GC */
  1038.         np->armed_GC = XfeAllocateColorGc(nw,np->arm_background,None,True);
  1039.     }
  1040.  
  1041.     /* Update the raised GC */
  1042.     if (raised_gc_flag)
  1043.     {
  1044.         /* Release the old raised GC */
  1045.         XtReleaseGC(nw,np->raised_GC);
  1046.         
  1047.         /* Allocate the new raised GC */
  1048.         np->raised_GC = XfeAllocateColorGc(nw,np->raise_background,None,True);
  1049.     }
  1050.  
  1051.     return _XfePrimitiveChainSetValues(ow,rw,nw,xfeButtonWidgetClass);
  1052. }
  1053. /*----------------------------------------------------------------------*/
  1054.  
  1055. /*----------------------------------------------------------------------*/
  1056. /*                                                                        */
  1057. /* XfePrimitive methods                                                    */
  1058. /*                                                                        */
  1059. /*----------------------------------------------------------------------*/
  1060. static void
  1061. PreferredGeometry(Widget w,Dimension *width,Dimension *height)
  1062. {
  1063.     XfeButtonPart * bp = _XfeButtonPart(w);
  1064.     XfeLabelPart *    lp = _XfeLabelPart(w);
  1065.  
  1066.     *width  = _XfeOffsetLeft(w) + _XfeOffsetRight(w);
  1067.     *height = _XfeOffsetTop(w)  + _XfeOffsetBottom(w);
  1068.  
  1069.     /* Include the arm_offset if needed */
  1070.     if (bp->button_type != XmBUTTON_NONE)
  1071.     {
  1072.         *width  += (2 * bp->arm_offset);
  1073.         *height += (2 * bp->arm_offset);
  1074.     }
  1075.  
  1076.     /* Include the raise_border_thickenss if needed */
  1077.     if (bp->raise_on_enter)
  1078.     {
  1079.         *width  += (2 * bp->raise_border_thickness);
  1080.         *height += (2 * bp->raise_border_thickness);
  1081.     }
  1082.     
  1083.     switch(bp->button_layout)
  1084.     {
  1085.     case XmBUTTON_LABEL_ONLY:
  1086.         
  1087.         *width  += lp->label_rect.width;
  1088.         *height += lp->label_rect.height;
  1089.         
  1090.         break;
  1091.         
  1092.     case XmBUTTON_LABEL_ON_BOTTOM:
  1093.     case XmBUTTON_LABEL_ON_TOP:
  1094.         
  1095.         if (bp->pixmap_rect.width && bp->pixmap_rect.height)
  1096.         {
  1097.             *width  += 
  1098.                 XfeMax(bp->pixmap_rect.width,lp->label_rect.width);
  1099.             
  1100.             *height += 
  1101.                 (bp->pixmap_rect.height + lp->label_rect.height + bp->spacing);
  1102.         }
  1103.         else
  1104.         {
  1105.             *width  += lp->label_rect.width;
  1106.             *height += lp->label_rect.height;
  1107.         }
  1108.         
  1109.         break;
  1110.         
  1111.     case XmBUTTON_LABEL_ON_LEFT:
  1112.     case XmBUTTON_LABEL_ON_RIGHT:
  1113.         
  1114.         if (bp->pixmap_rect.width && bp->pixmap_rect.height)
  1115.         {
  1116.             *height += 
  1117.                 XfeMax(bp->pixmap_rect.height,lp->label_rect.height);
  1118.             
  1119.             *width  += 
  1120.                 (bp->pixmap_rect.width + lp->label_rect.width + bp->spacing);
  1121.         }
  1122.         else
  1123.         {
  1124.             *width  += lp->label_rect.width;
  1125.             *height += lp->label_rect.height;
  1126.         }
  1127.         
  1128.         
  1129.         break;
  1130.         
  1131.     case XmBUTTON_PIXMAP_ONLY:
  1132.         
  1133.         *width  += bp->pixmap_rect.width;
  1134.         *height += bp->pixmap_rect.height;
  1135.         
  1136.         break;
  1137.     }
  1138. }
  1139. /*----------------------------------------------------------------------*/
  1140. static void
  1141. PrepareComponents(Widget w,int flags)
  1142. {
  1143.     if (flags & _XFE_PREPARE_BUTTON_PIXMAP)
  1144.     {
  1145.         PixmapPrepare(w);
  1146.     }
  1147.  
  1148.     if (flags & _XFE_PREPARE_BUTTON_ARMED_PIXMAP)
  1149.     {
  1150.         PixmapArmedPrepare(w);
  1151.     }
  1152.  
  1153.     if (flags & _XFE_PREPARE_BUTTON_RAISED_PIXMAP)
  1154.     {
  1155.         PixmapRaisedPrepare(w);
  1156.     }
  1157.  
  1158.     if (flags & _XFE_PREPARE_BUTTON_INSENSITIVE_PIXMAP)
  1159.     {
  1160.         PixmapInsensPrepare(w);
  1161.     }
  1162. }
  1163. /*----------------------------------------------------------------------*/
  1164. static void
  1165. LayoutComponents(Widget w)
  1166. /*----------------------------------------------------------------------*/
  1167. {
  1168.     /* Invoke layout_string method */
  1169.     _XfeLabelLayoutString(w);
  1170.  
  1171.     /* Invoke layout_pixmap method */
  1172.     _XfeButtonLayoutPixmap(w);
  1173. }
  1174. /*----------------------------------------------------------------------*/
  1175. static void
  1176. DrawComponents(Widget w,XEvent *event,Region region,XRectangle * clip_rect)
  1177. {
  1178.     /* Invoke draw_selection method */
  1179.     _XfeLabelDrawSelection(w,event,region,clip_rect);
  1180.  
  1181.     /* Invoke draw_string method */
  1182.     _XfeLabelDrawString(w,event,region,clip_rect);
  1183.  
  1184.     /* Invoke draw_pixmap method */
  1185.     _XfeButtonDrawPixmap(w,event,region,clip_rect);
  1186.  
  1187.     /* Invoke draw_raise_border method */
  1188.     _XfeButtonDrawRaiseBorder(w,event,region,clip_rect);
  1189. }
  1190. /*----------------------------------------------------------------------*/
  1191. static void
  1192. DrawShadow(Widget w,XEvent * event,Region region,XRectangle * clip_rect)
  1193. {
  1194.     XfeButtonPart *    bp = _XfeButtonPart(w);
  1195.     unsigned char    shadow_type = _XfeShadowType(w);
  1196.     Boolean            need_shadow = True;
  1197.  
  1198.     if (!_XfeShadowThickness(w))
  1199.     {
  1200.         return;
  1201.     }
  1202.  
  1203.     if (bp->raise_on_enter)
  1204.     {
  1205.         if (bp->armed)
  1206.         {
  1207.             shadow_type = XmSHADOW_IN;
  1208.         }
  1209.         else if (bp->raised)
  1210.         {
  1211.             shadow_type = XmSHADOW_OUT;
  1212.         }
  1213.         else
  1214.         {
  1215.             need_shadow = False;
  1216.         }
  1217.     }
  1218.     else
  1219.     {
  1220.         /* For both toggle and push the shadow depends on the arming state */
  1221.         if (bp->button_type != XmBUTTON_NONE)
  1222.         {
  1223.             shadow_type = bp->armed ? XmSHADOW_IN : XmSHADOW_OUT;
  1224.         }
  1225.     }
  1226.  
  1227.     /* Draw the shadow only if needed */
  1228.     if (need_shadow)
  1229.     {
  1230.         Dimension raise_offset = RAISE_OFFSET(bp);
  1231.         
  1232.         _XmDrawShadows(XtDisplay(w),
  1233.  
  1234.                        _XfePrimitiveDrawable(w),
  1235.  
  1236.                        _XfeTopShadowGC(w),_XfeBottomShadowGC(w),
  1237.  
  1238.                        _XfeHighlightThickness(w) + raise_offset,
  1239.  
  1240.                        _XfeHighlightThickness(w) + raise_offset,
  1241.  
  1242.                        _XfeWidth(w) - 
  1243.                        2 * _XfeHighlightThickness(w) -
  1244.                        2 * raise_offset,
  1245.  
  1246.                        _XfeHeight(w) - 
  1247.                        2 * _XfeHighlightThickness(w) - 
  1248.                        2 * raise_offset,
  1249.  
  1250.                        _XfeShadowThickness(w),
  1251.  
  1252.                        shadow_type);
  1253.     }
  1254. }
  1255. /*----------------------------------------------------------------------*/
  1256. static void
  1257. DrawBackground(Widget w,XEvent *event,Region region,XRectangle * clip_rect)
  1258. {
  1259.     XfeButtonPart *    bp = _XfeButtonPart(w);
  1260.  
  1261.     /* Fill the background if needed */
  1262.     if (bp->fill_on_arm && bp->armed)
  1263.     {
  1264.         XFillRectangle(XtDisplay(w),
  1265.                        _XfePrimitiveDrawable(w),
  1266.                        bp->armed_GC,
  1267.                        0,0,
  1268.                        _XfeWidth(w),_XfeHeight(w));
  1269.     }
  1270.     else if (bp->fill_on_enter && (bp->raised || _XfePointerInside(w)))
  1271.     {
  1272.         XFillRectangle(XtDisplay(w),
  1273.                        _XfePrimitiveDrawable(w),
  1274.                        bp->raised_GC,
  1275.                        0,0,
  1276.                        _XfeWidth(w),_XfeHeight(w));
  1277.     }
  1278. }
  1279. /*----------------------------------------------------------------------*/
  1280.  
  1281. /*----------------------------------------------------------------------*/
  1282. /*                                                                        */
  1283. /* XfeLabel methods                                                        */
  1284. /*                                                                        */
  1285. /*----------------------------------------------------------------------*/
  1286. static void
  1287. LayoutString(Widget w)
  1288. {
  1289.     XfeButtonPart *    bp = _XfeButtonPart(w);
  1290.  
  1291.     if ((bp->button_layout == XmBUTTON_LABEL_ONLY) ||
  1292.         !bp->pixmap_rect.width || !bp->pixmap_rect.height)
  1293.     {
  1294.         StringLayoutLabelOnly(w);
  1295.     }
  1296.     else
  1297.     {
  1298.         /* Layout the label according to the button's layout */
  1299.         switch(bp->button_layout)
  1300.         {
  1301.         case XmBUTTON_LABEL_ON_BOTTOM:
  1302.  
  1303.             StringLayoutLabelOnBottom(w);
  1304.  
  1305.             break;
  1306.         
  1307.         case XmBUTTON_LABEL_ON_TOP:
  1308.         
  1309.             StringLayoutLabelOnTop(w);
  1310.  
  1311.             break;
  1312.         
  1313.         case XmBUTTON_LABEL_ON_LEFT:
  1314.  
  1315.             StringLayoutLabelOnLeft(w);
  1316.         
  1317.             break;
  1318.         
  1319.         case XmBUTTON_LABEL_ON_RIGHT:
  1320.         
  1321.             StringLayoutLabelOnRight(w);
  1322.         
  1323.             break;
  1324.         }
  1325.     }        
  1326. }
  1327. /*----------------------------------------------------------------------*/
  1328. static void
  1329. DrawString(Widget w,XEvent * event,Region region,XRectangle * clip_rect)
  1330. {
  1331.     XfeButtonPart *            bp = _XfeButtonPart(w);
  1332.     XfeLabelPart *            lp = _XfeLabelPart(w);
  1333.     XfeLabelWidgetClass        lwc = (XfeLabelWidgetClass) xfeLabelWidgetClass;
  1334.  
  1335.     /* Make sure the label needs to be drawn */
  1336.     if (bp->button_layout == XmBUTTON_PIXMAP_ONLY)
  1337.     {
  1338.         return;
  1339.     }
  1340.  
  1341.     /* Set the label's misc offset to the arm offset if needed */
  1342.     lp->misc_offset = bp->armed ? bp->arm_offset : 0;
  1343.  
  1344.  
  1345.     /* Explicit invoke of XfeLabel's draw_string() method */
  1346.     (*lwc->xfe_label_class.draw_string)(w,event,region,clip_rect);
  1347.  
  1348.     /* Restore the label's misc offset */
  1349.     lp->misc_offset = 0;
  1350. }
  1351. /*----------------------------------------------------------------------*/
  1352. static GC
  1353. GetLabelGC(Widget w)
  1354. {
  1355.     XfeButtonPart *    bp = _XfeButtonPart(w);
  1356.     XfeLabelPart *    lp = _XfeLabelPart(w);
  1357.  
  1358.     return bp->raised ? bp->label_raised_GC : lp->label_GC;
  1359. }
  1360. /*----------------------------------------------------------------------*/
  1361.  
  1362. /*----------------------------------------------------------------------*/
  1363. /*                                                                        */
  1364. /* XfeButton class methods                                                */
  1365. /*                                                                        */
  1366. /*----------------------------------------------------------------------*/
  1367. static void
  1368. LayoutPixmap(Widget w)
  1369. {
  1370.     XfeButtonPart *    bp = _XfeButtonPart(w);
  1371.     XfeLabelPart *    lp = _XfeLabelPart(w);
  1372.  
  1373.     if ((bp->button_layout == XmBUTTON_PIXMAP_ONLY) ||
  1374.         !lp->label_rect.width || !lp->label_rect.height)
  1375.     {
  1376.         bp->pixmap_rect.x = (_XfeWidth(w) - bp->pixmap_rect.width) / 2;
  1377.         bp->pixmap_rect.y = (_XfeHeight(w) - bp->pixmap_rect.height) / 2;
  1378.     }
  1379.     else
  1380.     {
  1381.         Dimension raise_offset = RAISE_OFFSET(bp);
  1382.  
  1383.         /* Layout the label according to the button's layout */
  1384.         switch(bp->button_layout)
  1385.         {
  1386.         case XmBUTTON_LABEL_ON_BOTTOM:
  1387.         
  1388.             bp->pixmap_rect.x = (_XfeWidth(w) - bp->pixmap_rect.width) / 2;
  1389.         
  1390.             bp->pixmap_rect.y = _XfeOffsetTop(w) + raise_offset;
  1391.         
  1392.             break;
  1393.         
  1394.         case XmBUTTON_LABEL_ON_TOP:
  1395.         
  1396.             bp->pixmap_rect.x = (_XfeWidth(w) - bp->pixmap_rect.width) / 2;
  1397.         
  1398.             bp->pixmap_rect.y = 
  1399.                 _XfeHeight(w) - 
  1400.                 _XfeOffsetBottom(w) - 
  1401.                 bp->pixmap_rect.height -
  1402.                 raise_offset;
  1403.         
  1404.             break;
  1405.         
  1406.         case XmBUTTON_LABEL_ON_LEFT:
  1407.         
  1408.             bp->pixmap_rect.y = (_XfeHeight(w) - bp->pixmap_rect.height) / 2;
  1409.         
  1410.             bp->pixmap_rect.x = 
  1411.                 _XfeWidth(w) - 
  1412.                 _XfeOffsetRight(w) - 
  1413.                 bp->pixmap_rect.width -
  1414.                 raise_offset;
  1415.             
  1416.             break;
  1417.         
  1418.         case XmBUTTON_LABEL_ON_RIGHT:
  1419.         
  1420.             bp->pixmap_rect.y = (_XfeHeight(w) - bp->pixmap_rect.height) / 2;
  1421.         
  1422.             bp->pixmap_rect.x = _XfeOffsetLeft(w) + raise_offset;
  1423.         
  1424.             break;
  1425.         }
  1426.     }
  1427. }
  1428. /*----------------------------------------------------------------------*/
  1429. static void
  1430. DrawPixmap(Widget w,XEvent * event,Region region,XRectangle * clip_rect)
  1431. {
  1432.     XfeButtonPart *    bp = _XfeButtonPart(w);
  1433.     Pixmap            pixmap = XmUNSPECIFIED_PIXMAP;
  1434.     Pixmap            mask = XmUNSPECIFIED_PIXMAP;
  1435.     Boolean            insensitive = False;
  1436.  
  1437.     /* Make sure the pixmap needs to be drawn */
  1438.     if (bp->button_layout == XmBUTTON_LABEL_ONLY)
  1439.     {
  1440.         return;
  1441.     }
  1442.  
  1443.     /* Determine if the button is insensitive */
  1444.     insensitive = (!_XfeIsSensitive(w) || !bp->determinate);
  1445.  
  1446.     /* Determine which pixmap to use */
  1447.     /* for indeterminate state, use insensitive pixmap */
  1448.     if (insensitive && _XfePixmapGood(bp->insensitive_pixmap))
  1449.     {
  1450.         pixmap = bp->insensitive_pixmap;
  1451.         mask = bp->insensitive_pixmap_mask;
  1452.     }
  1453.     else if (bp->armed && _XfePixmapGood(bp->armed_pixmap))
  1454.     {
  1455.         pixmap = bp->armed_pixmap;
  1456.         mask = bp->armed_pixmap_mask;
  1457.     }
  1458.     else if (bp->raised && _XfePixmapGood(bp->raised_pixmap))
  1459.     {
  1460.         pixmap = bp->raised_pixmap;
  1461.         mask = bp->raised_pixmap_mask;
  1462.     }
  1463.     else
  1464.     {
  1465.         pixmap = bp->pixmap;
  1466.         mask = bp->pixmap_mask;
  1467.     }
  1468.  
  1469.     /* Make sure the pixmap is good before rendering it */
  1470.     if (_XfePixmapGood(pixmap) && 
  1471.         bp->pixmap_rect.width && 
  1472.         bp->pixmap_rect.height)
  1473.     {
  1474.         Dimension    offset = bp->armed ? bp->arm_offset : 0;
  1475.         Position    x = bp->pixmap_rect.x + offset;
  1476.         Position    y = bp->pixmap_rect.y + offset;
  1477.  
  1478.         if (_XfePixmapGood(mask))
  1479.         {
  1480.             XSetClipOrigin(XtDisplay(w),bp->pixmap_GC,x,y);
  1481.             XSetClipMask(XtDisplay(w),bp->pixmap_GC,mask);
  1482.         }
  1483.         else
  1484.         {
  1485.             XSetClipMask(XtDisplay(w),bp->pixmap_GC,None);
  1486.         }
  1487.  
  1488.         XCopyArea(XtDisplay(w),
  1489.                   pixmap,
  1490.                   _XfePrimitiveDrawable(w),
  1491.                   bp->pixmap_GC,
  1492.                   0,0,
  1493.                   bp->pixmap_rect.width,
  1494.                   bp->pixmap_rect.height,
  1495.                   x,
  1496.                   y);
  1497.  
  1498.         /*
  1499.          * If the button is insensitive and the pixmap we just
  1500.          * rendered is not the XmNinsensitivePixmap, then we 
  1501.          * need to also render the insensitive effect.
  1502.          */
  1503.         if (insensitive && (pixmap != bp->insensitive_pixmap))
  1504.         {
  1505.             assert( _XfeBackgroundGC(w) != NULL );
  1506.  
  1507.             XfeStippleRectangle(XtDisplay(w),
  1508.                                 _XfePrimitiveDrawable(w),
  1509.                                  _XfeBackgroundGC(w),
  1510.                                 x,
  1511.                                 y,
  1512.                                 bp->pixmap_rect.width,
  1513.                                 bp->pixmap_rect.height,
  1514.                                 2);
  1515.         }
  1516.     }
  1517. }
  1518. /*----------------------------------------------------------------------*/
  1519. static void
  1520. DrawRaiseBorder(Widget w,XEvent *event,Region region,XRectangle * clip_rect)
  1521. {
  1522.     XfeButtonPart *    bp = _XfeButtonPart(w);
  1523.  
  1524.     /* Make sure the thickness of the raise border ain't */
  1525.     if (bp->raise_border_thickness == 0)
  1526.     {
  1527.         return;
  1528.     }
  1529.     
  1530.     /*
  1531.      * The border is only needed if raise_on_enter is true or we are in
  1532.      * a special clicking state (between Arm() and Disarm())
  1533.      */
  1534.     if (!bp->raise_on_enter && !bp->armed)
  1535.     {
  1536.         return;
  1537.     }
  1538.  
  1539.      if (bp->raised || (bp->raise_on_enter && bp->armed && bp->clicking))
  1540.     {
  1541.         XfeDrawRectangle(XtDisplay(w),
  1542.                          
  1543.                          _XfePrimitiveDrawable(w),
  1544.                              
  1545.                          _XfeHighlightGC(w),
  1546.                              
  1547.                          _XfeHighlightThickness(w),
  1548.                              
  1549.                          _XfeHighlightThickness(w),
  1550.                              
  1551.                          _XfeWidth(w) - 2 * _XfeHighlightThickness(w),
  1552.                              
  1553.                          _XfeHeight(w) - 2 * _XfeHighlightThickness(w),
  1554.                              
  1555.                          bp->raise_border_thickness);
  1556.     }
  1557.     else
  1558.     {
  1559.         XfeDrawRectangle(XtDisplay(w),
  1560.                              
  1561.                          _XfePrimitiveDrawable(w),
  1562.                              
  1563.                          _XfemBackgroundGC(XtParent(w)),
  1564.                              
  1565.                          _XfeHighlightThickness(w),
  1566.                              
  1567.                          _XfeHighlightThickness(w),
  1568.                              
  1569.                          _XfeWidth(w) - 2 * _XfeHighlightThickness(w),
  1570.                              
  1571.                          _XfeHeight(w) - 2 * _XfeHighlightThickness(w),
  1572.                              
  1573.                          bp->raise_border_thickness);
  1574.     }
  1575. }
  1576. /*----------------------------------------------------------------------*/
  1577. static void
  1578. ArmTimeout(XtPointer client_data,XtIntervalId * id)
  1579. {
  1580.     /* Write me */
  1581. }
  1582. /*----------------------------------------------------------------------*/
  1583.  
  1584. /*----------------------------------------------------------------------*/
  1585. /*                                                                        */
  1586. /* Misc XfeButton functions                                                */
  1587. /*                                                                        */
  1588. /*----------------------------------------------------------------------*/
  1589. static void
  1590. PixmapPrepare(Widget w)
  1591. {
  1592.     XfeButtonPart *    bp = _XfeButtonPart(w);
  1593.  
  1594.     _XfePixmapPrepare(w,
  1595.                       &bp->pixmap,
  1596.                       &bp->pixmap_rect.width,
  1597.                       &bp->pixmap_rect.height,
  1598.                       XmNpixmap);
  1599. }
  1600. /*----------------------------------------------------------------------*/
  1601. static void
  1602. PixmapArmedPrepare(Widget w)
  1603. {
  1604.     XfeButtonPart *    bp = _XfeButtonPart(w);
  1605.     XRectangle        rect;
  1606.  
  1607.     _XfePixmapPrepare(w,
  1608.                       &bp->armed_pixmap,
  1609.                       &rect.width,
  1610.                       &rect.height,
  1611.                       XmNarmedPixmap);
  1612.  
  1613.     if (_XfePixmapGood(bp->armed_pixmap))
  1614.     {
  1615.         /* Make sure the normal pixmap is defined */
  1616.         if (_XfePixmapGood(bp->pixmap))
  1617.         {
  1618.             /* Make sure the geometry matches the main pixmap's */
  1619.             if ((rect.width  != bp->pixmap_rect.width) ||
  1620.                 (rect.height != bp->pixmap_rect.height))
  1621.             {
  1622.                 bp->armed_pixmap = XmUNSPECIFIED_PIXMAP;
  1623.                 
  1624.                 _XfeWarning(w,MESSAGE10);
  1625.             }
  1626.         }
  1627.         else
  1628.         {
  1629.             bp->armed_pixmap = XmUNSPECIFIED_PIXMAP;
  1630.  
  1631.             _XfeWarning(w,MESSAGE7);
  1632.         }
  1633.     }
  1634. }
  1635. /*----------------------------------------------------------------------*/
  1636. static void
  1637. PixmapRaisedPrepare(Widget w)
  1638. {
  1639.     XfeButtonPart *    bp = _XfeButtonPart(w);
  1640.     XRectangle        rect;
  1641.  
  1642.     _XfePixmapPrepare(w,
  1643.                       &bp->raised_pixmap,
  1644.                       &rect.width,
  1645.                       &rect.height,
  1646.                       XmNraisedPixmap);
  1647.  
  1648.     if (_XfePixmapGood(bp->raised_pixmap))
  1649.     {
  1650.         /* Make sure the normal pixmap is defined */
  1651.         if (_XfePixmapGood(bp->pixmap))
  1652.         {
  1653.             /* Make sure the geometry matches the main pixmap's */
  1654.             if ((rect.width  != bp->pixmap_rect.width) ||
  1655.                 (rect.height != bp->pixmap_rect.height))
  1656.             {
  1657.                 bp->raised_pixmap = XmUNSPECIFIED_PIXMAP;
  1658.                 
  1659.                 _XfeWarning(w,MESSAGE11);
  1660.             }
  1661.         }
  1662.         else
  1663.         {
  1664.             bp->raised_pixmap = XmUNSPECIFIED_PIXMAP;
  1665.  
  1666.             _XfeWarning(w,MESSAGE8);
  1667.         }
  1668.     }
  1669. }
  1670. /*----------------------------------------------------------------------*/
  1671. static void
  1672. PixmapInsensPrepare(Widget w)
  1673. {
  1674.     XfeButtonPart *    bp = _XfeButtonPart(w);
  1675.     XRectangle        rect;
  1676.  
  1677.     _XfePixmapPrepare(w,
  1678.                       &bp->insensitive_pixmap,
  1679.                       &rect.width,
  1680.                       &rect.height,
  1681.                       XmNinsensitivePixmap);
  1682.  
  1683.     if (_XfePixmapGood(bp->insensitive_pixmap))
  1684.     {
  1685.         /* Make sure the normal pixmap is defined */
  1686.         if (_XfePixmapGood(bp->pixmap))
  1687.         {
  1688.             /* Make sure the geometry matches the main pixmap's */
  1689.             if ((rect.width  != bp->pixmap_rect.width) ||
  1690.                 (rect.height != bp->pixmap_rect.height))
  1691.             {
  1692.                 bp->insensitive_pixmap = XmUNSPECIFIED_PIXMAP;
  1693.                 
  1694.                 _XfeWarning(w,MESSAGE12);
  1695.             }
  1696.         }
  1697.         else
  1698.         {
  1699.             bp->insensitive_pixmap = XmUNSPECIFIED_PIXMAP;
  1700.  
  1701.             _XfeWarning(w,MESSAGE9);
  1702.         }
  1703.     }
  1704. }
  1705. /*----------------------------------------------------------------------*/
  1706. static void
  1707. StringLayoutLabelOnly(Widget w)
  1708. {
  1709.     XfeButtonPart *    bp = _XfeButtonPart(w);
  1710.     XfeLabelPart *    lp = _XfeLabelPart(w);
  1711.  
  1712.     /* Layout horizontally according to alignment */
  1713.     switch(lp->label_alignment)
  1714.     {
  1715.     case XmALIGNMENT_BEGINNING:
  1716.         
  1717.         lp->label_rect.x = _XfeRectX(w) + RAISE_OFFSET(bp);
  1718.         
  1719.         break;
  1720.         
  1721.     case XmALIGNMENT_CENTER:
  1722.         
  1723.         lp->label_rect.x = (_XfeWidth(w) - lp->label_rect.width) / 2;
  1724.         
  1725.         break;
  1726.         
  1727.     case XmALIGNMENT_END:
  1728.         
  1729.         lp->label_rect.x = 
  1730.             XfeWidth(w) - 
  1731.             lp->label_rect.width - 
  1732.             _XfeOffsetRight(w) -
  1733.             RAISE_OFFSET(bp);
  1734.         
  1735.         break;
  1736.     }
  1737.     
  1738.     /* Layout vertically centred */
  1739.     lp->label_rect.y = (_XfeHeight(w) - lp->label_rect.height) / 2;
  1740. }
  1741. /*----------------------------------------------------------------------*/
  1742. static void
  1743. StringLayoutLabelOnBottom(Widget w)
  1744. {
  1745.     XfeButtonPart *    bp = _XfeButtonPart(w);
  1746.     XfeLabelPart *    lp = _XfeLabelPart(w);
  1747.  
  1748.     /* Layout horizontally according to alignment */
  1749.     switch(lp->label_alignment)
  1750.     {
  1751.     case XmALIGNMENT_BEGINNING:
  1752.         
  1753.         lp->label_rect.x = _XfeRectX(w) + RAISE_OFFSET(bp);
  1754.         
  1755.         break;
  1756.         
  1757.     case XmALIGNMENT_CENTER:
  1758.         
  1759.         lp->label_rect.x = (_XfeWidth(w) - lp->label_rect.width) / 2;
  1760.         
  1761.         break;
  1762.         
  1763.     case XmALIGNMENT_END:
  1764.         
  1765.         lp->label_rect.x = 
  1766.             XfeWidth(w) - 
  1767.             lp->label_rect.width - 
  1768.             _XfeOffsetRight(w) -
  1769.             RAISE_OFFSET(bp);
  1770.         
  1771.         break;
  1772.     }
  1773.     
  1774.     /* Layout horizontally on bottom */
  1775.     lp->label_rect.y = 
  1776.         _XfeHeight(w) - 
  1777.         _XfeOffsetBottom(w) - 
  1778.         lp->label_rect.height -
  1779.         RAISE_OFFSET(bp);
  1780. }
  1781. /*----------------------------------------------------------------------*/
  1782. static void
  1783. StringLayoutLabelOnTop(Widget w)
  1784. {
  1785.     XfeButtonPart *    bp = _XfeButtonPart(w);
  1786.     XfeLabelPart *    lp = _XfeLabelPart(w);
  1787.  
  1788.     /* Layout horizontally according to alignment */
  1789.     switch(lp->label_alignment)
  1790.     {
  1791.     case XmALIGNMENT_BEGINNING:
  1792.         
  1793.         lp->label_rect.x = _XfeRectX(w) + RAISE_OFFSET(bp);
  1794.         
  1795.         break;
  1796.         
  1797.     case XmALIGNMENT_CENTER:
  1798.         
  1799.         lp->label_rect.x = (_XfeWidth(w) - lp->label_rect.width) / 2;
  1800.         
  1801.         break;
  1802.         
  1803.     case XmALIGNMENT_END:
  1804.         
  1805.         lp->label_rect.x = 
  1806.             XfeWidth(w) - 
  1807.             lp->label_rect.width - 
  1808.             _XfeOffsetRight(w) -
  1809.             RAISE_OFFSET(bp);
  1810.         
  1811.         break;
  1812.     }
  1813.  
  1814.     /* Layout horizontally on top */
  1815.     lp->label_rect.y = _XfeOffsetTop(w) + RAISE_OFFSET(bp);
  1816. }
  1817. /*----------------------------------------------------------------------*/
  1818. static void
  1819. StringLayoutLabelOnLeft(Widget w)
  1820. {
  1821.     XfeButtonPart *    bp = _XfeButtonPart(w);
  1822.     XfeLabelPart *    lp = _XfeLabelPart(w);
  1823.  
  1824.     lp->label_rect.x = _XfeOffsetLeft(w) + RAISE_OFFSET(bp);
  1825.  
  1826.     lp->label_rect.y = (_XfeHeight(w) - lp->label_rect.height) / 2;
  1827.     
  1828. }
  1829. /*----------------------------------------------------------------------*/
  1830. static void
  1831. StringLayoutLabelOnRight(Widget w)
  1832. {
  1833.     XfeButtonPart *    bp = _XfeButtonPart(w);
  1834.     XfeLabelPart *    lp = _XfeLabelPart(w);
  1835.  
  1836.     lp->label_rect.x = 
  1837.         _XfeWidth(w) - 
  1838.         _XfeOffsetRight(w) - 
  1839.         lp->label_rect.width -
  1840.         RAISE_OFFSET(bp);
  1841.  
  1842.     lp->label_rect.y = (_XfeHeight(w) - lp->label_rect.height) / 2;
  1843. }
  1844. /*----------------------------------------------------------------------*/
  1845. static void
  1846. InvokeCallback(Widget w,XtCallbackList list,int reason,XEvent * event)
  1847. {
  1848.     XfeButtonPart *    bp = _XfeButtonPart(w);
  1849.  
  1850.     /* Invoke the callbacks only if needed */
  1851.     if (list)
  1852.     {
  1853.         XfeButtonCallbackStruct cbs;
  1854.     
  1855.         cbs.event    = event;
  1856.         cbs.reason    = reason;
  1857.         cbs.armed    = bp->armed;
  1858.         cbs.raised    = bp->raised;
  1859.  
  1860.         /* Flush the display */
  1861.         XFlush(XtDisplay(w));
  1862.     
  1863.         /* Invoke the Callback List */
  1864.         XtCallCallbackList(w,list,&cbs);
  1865.     }
  1866. }
  1867. /*----------------------------------------------------------------------*/
  1868. static Boolean
  1869. AcceptEvent(Widget w,XEvent * event)
  1870. {
  1871.     int        x;
  1872.     int        y;
  1873.  
  1874.     /* Obtain the event coords */
  1875.     if (XfeEventGetXY(event,&x,&y))
  1876.     {
  1877.         return XfeButtonAcceptXY(w,x,y);
  1878.     }
  1879.  
  1880.     return False;
  1881. }
  1882. /*----------------------------------------------------------------------*/
  1883. static Boolean
  1884. SpacingContainsXY(Widget w,int x,int y)
  1885. {
  1886.     XfeButtonPart *    bp = _XfeButtonPart(w);
  1887.     XfeLabelPart *    lp = _XfeLabelPart(w);
  1888.  
  1889.     /* Check whether the coords are inside the spacing only if its > 0 */
  1890.     if (bp->spacing > 0)
  1891.     {
  1892.         XRectangle rect;
  1893.         
  1894.         if (bp->button_layout == XmBUTTON_LABEL_ON_BOTTOM)
  1895.         {
  1896.             XfeRectSet(&rect,
  1897.                        (_XfeWidth(w) - MIN_COMP_WIDTH(lp,bp)) / 2,
  1898.                        lp->label_rect.y - bp->spacing,
  1899.                        MIN_COMP_WIDTH(lp,bp),
  1900.                        bp->spacing);
  1901.         }
  1902.         else if (bp->button_layout == XmBUTTON_LABEL_ON_TOP)
  1903.         {
  1904.             XfeRectSet(&rect,
  1905.                        (_XfeWidth(w) - MIN_COMP_WIDTH(lp,bp)) / 2,
  1906.                        bp->pixmap_rect.y - bp->spacing,
  1907.                        MIN_COMP_WIDTH(lp,bp),
  1908.                        bp->spacing);
  1909.         }
  1910.         else if (bp->button_layout == XmBUTTON_LABEL_ON_LEFT)
  1911.         {
  1912.             XfeRectSet(&rect,
  1913.                        bp->pixmap_rect.x - bp->spacing,
  1914.                        (_XfeHeight(w) - MIN_COMP_HEIGHT(lp,bp)) / 2,
  1915.                        bp->spacing,
  1916.                        MIN_COMP_HEIGHT(lp,bp));
  1917.         }
  1918.         else if (bp->button_layout == XmBUTTON_LABEL_ON_RIGHT)
  1919.         {
  1920.             XfeRectSet(&rect,
  1921.                        lp->label_rect.x - bp->spacing,
  1922.                        (_XfeHeight(w) - MIN_COMP_HEIGHT(lp,bp)) / 2,
  1923.                        bp->spacing,
  1924.                        MIN_COMP_HEIGHT(lp,bp));
  1925.         }
  1926.         
  1927.         return XfePointInRect(&rect,x,y);
  1928.     }
  1929.     
  1930.     return False;
  1931. }
  1932. /*----------------------------------------------------------------------*/
  1933. static void
  1934. TransparentCursorSetState(Widget w,Boolean state)
  1935. {
  1936.     XfeButtonPart *    bp = _XfeButtonPart(w);
  1937.  
  1938.     /* Make sure the transparent cursor is good and we are sensitive */
  1939.     if (!_XfeCursorGood(bp->transparent_cursor) || !_XfeIsSensitive(w))
  1940.     {
  1941.         return;
  1942.     }
  1943.  
  1944.     /* Make sure the state has changed */
  1945.     if (state == bp->transparent_cursor_state)
  1946.     {
  1947.         return;
  1948.     }
  1949.  
  1950.     /* Update the state */
  1951.     bp->transparent_cursor_state = state;
  1952.  
  1953.     if(state)
  1954.     {
  1955.         XfeCursorDefine(w,bp->transparent_cursor);
  1956.     }
  1957.     else
  1958.     {
  1959.         XfeCursorUndefine(w);
  1960.     }
  1961. }
  1962. /*----------------------------------------------------------------------*/
  1963.  
  1964. /*----------------------------------------------------------------------*/
  1965. /*                                                                        */
  1966. /* XfeButton Method invocation functions                                */
  1967. /*                                                                        */
  1968. /*----------------------------------------------------------------------*/
  1969. /* extern */ void
  1970. _XfeButtonLayoutPixmap(Widget w)
  1971. {
  1972.     XfeButtonWidgetClass bc = (XfeButtonWidgetClass) XtClass(w);
  1973.  
  1974.     if (bc->xfe_button_class.layout_pixmap)
  1975.     {
  1976.         (*bc->xfe_button_class.layout_pixmap)(w);
  1977.     }
  1978. }
  1979. /*----------------------------------------------------------------------*/
  1980. /* extern */ void
  1981. _XfeButtonDrawPixmap(Widget            w,
  1982.                      XEvent *        event,
  1983.                      Region            region,
  1984.                      XRectangle *    clip_rect)
  1985. {
  1986.     XfeButtonWidgetClass bc = (XfeButtonWidgetClass) XtClass(w);
  1987.  
  1988.     if (bc->xfe_button_class.draw_pixmap)
  1989.     {
  1990.         (*bc->xfe_button_class.draw_pixmap)(w,event,region,clip_rect);
  1991.     }
  1992. }
  1993. /*----------------------------------------------------------------------*/
  1994. /* extern */ void
  1995. _XfeButtonDrawRaiseBorder(Widget        w,
  1996.                           XEvent *        event,
  1997.                           Region        region,
  1998.                           XRectangle *    clip_rect)
  1999. {
  2000.     XfeButtonWidgetClass bc = (XfeButtonWidgetClass) XtClass(w);
  2001.  
  2002.     if (bc->xfe_button_class.draw_raise_border)
  2003.     {
  2004.         (*bc->xfe_button_class.draw_raise_border)(w,event,region,clip_rect);
  2005.     }
  2006. }
  2007. /*----------------------------------------------------------------------*/
  2008. /* extern */ void
  2009. _XfeButtonArmTimeout(Widget w,XtPointer client_data,XtIntervalId * id)
  2010. {
  2011.     XfeButtonWidgetClass bc = (XfeButtonWidgetClass) XtClass(w);
  2012.     
  2013.     if (bc->xfe_button_class.arm_timeout)
  2014.     {
  2015.         (*bc->xfe_button_class.arm_timeout)(client_data,id);
  2016.     }
  2017. }
  2018. /*----------------------------------------------------------------------*/
  2019.  
  2020. /*----------------------------------------------------------------------*/
  2021. /*                                                                        */
  2022. /* XfeButton action procedures                                            */
  2023. /*                                                                        */
  2024. /*----------------------------------------------------------------------*/
  2025. /* extern */  void
  2026. _XfeButtonEnter(Widget w,XEvent * event,char ** params,Cardinal * nparams)
  2027. {
  2028.     XfeButtonPart *    bp = _XfeButtonPart(w);
  2029.     Boolean            redisplay = False;
  2030.  
  2031.     /* Accept the event based on the button_trigger resource.  This needs to
  2032.      * happen before we call _XfePrimitiveEnter() so that enter callbacks 
  2033.      * don't get called.
  2034.      */
  2035.     if (!AcceptEvent(w,event))
  2036.     {
  2037.         /* Turn the transparent cursor on */
  2038.         TransparentCursorSetState(w,True);
  2039.         
  2040.         return;
  2041.     }
  2042.  
  2043.     if (XfeEventGetModifiers(event) & Button1Mask)
  2044.     {
  2045.         if (bp->transparent_cursor_state)
  2046.         {
  2047.             return;
  2048.         }
  2049.     }
  2050.  
  2051.     /* First, invoke the XfePrimitive's enter action */
  2052.     _XfePrimitiveEnter(w,event,params,nparams);
  2053.  
  2054.     /* Make sure we are not pretending to be insensitive */
  2055.     if (!_XfeIsSensitive(w))
  2056.     {
  2057.         return;
  2058.     }
  2059.  
  2060.     /* Adjust armed state if needed */
  2061.     if (bp->clicking && !bp->emulate_motif)
  2062.     {
  2063.         bp->armed = True;
  2064.  
  2065.         redisplay = True;
  2066.     }
  2067.  
  2068.     /* Adjust raised state if needed */
  2069.     if (bp->raise_on_enter)
  2070.     {
  2071.         if (!bp->clicking)
  2072.         {
  2073.             bp->raised = True;
  2074.             
  2075.             redisplay = True;
  2076.         }
  2077.     }
  2078.     else if (bp->fill_on_enter)
  2079.     {
  2080.         redisplay = True;
  2081.     }
  2082.  
  2083.     if (redisplay)
  2084.     {
  2085.         /* Erase the old stuff */
  2086.         _XfePrimitiveClearBackground(w);
  2087.     
  2088.         /* Redraw the buffer */
  2089.         _XfePrimitiveDrawEverything(w,NULL,NULL);
  2090.     
  2091.         /* Draw the buffer onto the window */
  2092.         XfeExpose(w,NULL,NULL);
  2093.     }
  2094. }
  2095. /*----------------------------------------------------------------------*/
  2096. /* extern */ void
  2097. _XfeButtonLeave(Widget w,XEvent * event,char ** params,Cardinal * nparams)
  2098. {
  2099.     XfeButtonPart *    bp = _XfeButtonPart(w);
  2100.     Boolean            redisplay = False;
  2101.  
  2102.     /* Turn the transparent cursor off if needed */
  2103.     if (bp->button_trigger != XmBUTTON_TRIGGER_ANYWHERE)
  2104.     {
  2105.         TransparentCursorSetState(w,False);
  2106.     }
  2107.  
  2108.     /* First, invoke the XfePrimitive's leave action */
  2109.     _XfePrimitiveLeave(w,event,params,nparams);
  2110.  
  2111.     /* Make sure we are not pretending to be insensitive */
  2112.     if (!_XfeIsSensitive(w))
  2113.     {
  2114.         return;
  2115.     }
  2116.  
  2117.     /* Adjust armed state if needed */
  2118.     if (bp->armed && !bp->emulate_motif)
  2119.     {
  2120.         bp->armed = False;
  2121.  
  2122.         redisplay = True;
  2123.     }
  2124.  
  2125.     /* Adjust raised state if needed */
  2126.     if (bp->raise_on_enter)
  2127.     {
  2128.         if (!bp->clicking)
  2129.         {
  2130.             bp->raised = False;
  2131.             
  2132.             redisplay = True;
  2133.         }
  2134.     }
  2135.     else if (bp->fill_on_enter)
  2136.     {
  2137.         redisplay = True;
  2138.     }
  2139.  
  2140.     if (redisplay)
  2141.     {
  2142.         /* Erase the old stuff */
  2143.         _XfePrimitiveClearBackground(w);
  2144.     
  2145.         /* Redraw the buffer */
  2146.         _XfePrimitiveDrawEverything(w,NULL,NULL);
  2147.     
  2148.         /* Draw the buffer onto the window */
  2149.         XfeExpose(w,NULL,NULL);
  2150.     }
  2151. }
  2152. /*----------------------------------------------------------------------*/
  2153. /* extern */  void
  2154. _XfeButtonMotion(Widget w,XEvent * event,char ** params,Cardinal * nparams)
  2155. {
  2156.     XfeButtonPart *    bp = _XfeButtonPart(w);
  2157.  
  2158.     /* Make sure a button is not being pressed */ 
  2159.     if (XfeEventGetModifiers(event) & Button1Mask)
  2160.     {
  2161.         return;
  2162.     }
  2163.  
  2164.     /*
  2165.      * If the event is accepted, pretend we got an enter event.  If not,
  2166.      * pretend we got a leave event.
  2167.      */
  2168.     if (AcceptEvent(w,event))
  2169.     {
  2170.         if (!_XfePointerInside(w))
  2171.         {
  2172.             /* Turn the transparent cursor off */
  2173.             TransparentCursorSetState(w,False);
  2174.  
  2175.             _XfeButtonEnter(w,event,params,nparams);
  2176.         }
  2177.     }
  2178.     else
  2179.     {
  2180.         if (_XfePointerInside(w))
  2181.         {
  2182.             _XfeButtonLeave(w,event,params,nparams);
  2183.  
  2184.             /* Turn the transparent cursor on */
  2185.             TransparentCursorSetState(w,True);
  2186.         }
  2187.  
  2188.     }
  2189. }
  2190. /*----------------------------------------------------------------------*/
  2191. /* extern */ void
  2192. _XfeButtonActivate(Widget w,XEvent * event,char ** params,Cardinal * nparams)
  2193. {
  2194.     XfeButtonPart *    bp = _XfeButtonPart(w);
  2195.  
  2196.     /* Make sure we are not insenitsive (or pretending to be insensitive) */
  2197.     if (!_XfeIsSensitive(w))
  2198.     {
  2199.         return;
  2200.     }
  2201.  
  2202.     /* Make sure we are indeed clicking */
  2203.     if (!bp->clicking)
  2204.     {
  2205.         return;
  2206.     }
  2207.  
  2208.     /* Invoke callbacks only if pointer is still inside button */
  2209.     if (_XfePointerInside(w))
  2210.     {
  2211.         InvokeCallback(w,bp->activate_callback,XmCR_ACTIVATE,event);
  2212.     }
  2213. }
  2214. /*----------------------------------------------------------------------*/
  2215. /* extern */ void
  2216. _XfeButtonArm(Widget w,XEvent * event,char ** params,Cardinal * nparams)
  2217. {
  2218.     XfeButtonPart *    bp = _XfeButtonPart(w);
  2219.     XfeLabelPart *    lp = _XfeLabelPart(w);
  2220.     Boolean            accept_event;
  2221.  
  2222.     /* Make sure we are not pretending to be insensitive */
  2223.     if (!_XfeIsSensitive(w))
  2224.     {
  2225.         return;
  2226.     }
  2227.  
  2228.     _XfePrimitiveFocus(w,event,params,nparams);
  2229.  
  2230.     /* Determine whether this event is acceptable */
  2231.     accept_event = AcceptEvent(w,event);
  2232.  
  2233.     /* Look for a Select() action */
  2234.     if (_XfeLabelAcceptSelectionEvent(w,event,!accept_event))
  2235.     {
  2236.         _XfeLabelSetSelected(w,event,!lp->selected,True);
  2237.  
  2238.         return;
  2239.     }
  2240.  
  2241.     /* Make sure the event is accepted */
  2242.     if (!accept_event)
  2243.     {
  2244.         return;
  2245.     }
  2246.  
  2247.     /* Make sure we are not already clicking */
  2248.     if (bp->clicking)
  2249.     {
  2250.         return;
  2251.     }
  2252.  
  2253.     /* We are now clicking */
  2254.     bp->clicking = True;
  2255.  
  2256.     /* If we are in none mode, do nothing more */
  2257.     if (bp->button_type == XmBUTTON_NONE)
  2258.     {
  2259.         return;
  2260.     }
  2261.  
  2262.     /* Being simultaneously armed and raised is confusing, so its out */
  2263.     if (bp->raise_on_enter)
  2264.     {
  2265.         bp->raised = False;
  2266.     }
  2267.  
  2268.     /* If we are in toggle mode, toggle the armed state */
  2269.     if (bp->button_type == XmBUTTON_TOGGLE)
  2270.     {
  2271.         bp->armed = !bp->armed;
  2272.     }
  2273.     /* Otherwise turn it on */
  2274.     else
  2275.     {
  2276.         bp->armed = True;
  2277.     }
  2278.     
  2279.     /* Erase the old stuff */
  2280.     _XfePrimitiveClearBackground(w);
  2281.     
  2282.     /* Redraw the buffer */
  2283.     _XfePrimitiveDrawEverything(w,NULL,NULL);
  2284.     
  2285.     /* Draw the buffer onto the window */
  2286.     XfeExpose(w,NULL,NULL);
  2287.  
  2288.     /* If we are in toggle mode, invoke the appropiate callback */
  2289.     if (bp->button_type == XmBUTTON_TOGGLE)
  2290.     {
  2291.         if (bp->armed)
  2292.         {
  2293.             InvokeCallback(w,bp->arm_callback,XmCR_ARM,event);
  2294.         }
  2295.         else
  2296.         {
  2297.             InvokeCallback(w,bp->disarm_callback,XmCR_DISARM,event);
  2298.         }
  2299.     }
  2300.     /* Otherwise invoke the arm callback */
  2301.     else
  2302.     {
  2303.         InvokeCallback(w,bp->arm_callback,XmCR_ARM,event);
  2304.     }
  2305. }
  2306. /*----------------------------------------------------------------------*/
  2307. /* extern */ void
  2308. _XfeButtonDisarm(Widget w,XEvent * event,char ** params,Cardinal * nparams)
  2309. {
  2310.     XfeButtonPart *    bp = _XfeButtonPart(w);
  2311.  
  2312.     /* Make sure we are not pretending to be insensitive */
  2313.     if (!_XfeIsSensitive(w))
  2314.     {
  2315.         return;
  2316.     }
  2317.  
  2318.     /* Make sure we are indeed clicking */
  2319.     if (!bp->clicking)
  2320.     {
  2321.         return;
  2322.     }
  2323.  
  2324.     /* If we are in none mode, do nothing more */
  2325.     if (bp->button_type == XmBUTTON_NONE)
  2326.     {
  2327.         return;
  2328.     }
  2329.  
  2330.     /* We are now no longer clicking */
  2331.     bp->clicking = False;
  2332.  
  2333.     /* Raise the button if needed and the pointer is still inside */
  2334.     if (bp->raise_on_enter && _XfePointerInside(w))
  2335.     {
  2336.         bp->raised = True;
  2337.     }
  2338.  
  2339.     if (bp->button_type != XmBUTTON_TOGGLE)
  2340.     {
  2341.         bp->armed = False;
  2342.         
  2343.         /* Erase the old stuff */
  2344.         _XfePrimitiveClearBackground(w);
  2345.         
  2346.         /* Redraw the buffer */
  2347.         _XfePrimitiveDrawEverything(w,NULL,NULL);
  2348.         
  2349.         /* Draw the buffer onto the window */
  2350.         XfeExpose(w,NULL,NULL);
  2351.  
  2352.         InvokeCallback(w,bp->disarm_callback,XmCR_DISARM,event);
  2353.     }
  2354. }
  2355. /*----------------------------------------------------------------------*/
  2356. /* extern */ void
  2357. _XfeButtonArmAndActivate(Widget        w,
  2358.                          XEvent *    event,
  2359.                          char **    params,
  2360.                          Cardinal *    nparams)
  2361. {
  2362.     /* Make sure we are not pretending to be insensitive */
  2363.     if (!_XfeIsSensitive(w))
  2364.     {
  2365.         return;
  2366.     }
  2367.  
  2368.     /* Accept the event based on the button_trigger resource */
  2369.     if (!AcceptEvent(w,event))
  2370.     {
  2371.         return;
  2372.     }
  2373.  
  2374.     _XfeButtonArm(w,event,params,nparams);
  2375.  
  2376.     _XfeButtonActivate(w,event,params,nparams);
  2377.  
  2378.     _XfeButtonDisarm(w,event,params,nparams);
  2379. }
  2380. /*----------------------------------------------------------------------*/
  2381. /* extern */ void
  2382. _XfeButtonBtn3Down(Widget w,XEvent * event,char ** params,Cardinal * nparams)
  2383. {
  2384.     XfeButtonPart *    bp = _XfeButtonPart(w);
  2385.  
  2386.     /* Make sure we are not pretending to be insensitive */
  2387.     if (!_XfeIsSensitive(w))
  2388.     {
  2389.         return;
  2390.     }
  2391.  
  2392.     InvokeCallback(w,bp->button_3_down_callback,XmCR_BUTTON_3_DOWN,event);
  2393. }
  2394. /*----------------------------------------------------------------------*/
  2395. /* extern */ void
  2396. _XfeButtonBtn3Up(Widget w,XEvent * event,char ** params,Cardinal * nparams)
  2397. {
  2398.     XfeButtonPart *    bp = _XfeButtonPart(w);
  2399.  
  2400.     /* Make sure we are not pretending to be insensitive */
  2401.     if (!_XfeIsSensitive(w))
  2402.     {
  2403.         return;
  2404.     }
  2405.  
  2406.     InvokeCallback(w,bp->button_3_up_callback,XmCR_BUTTON_3_UP,event);
  2407. }
  2408. /*----------------------------------------------------------------------*/
  2409.  
  2410. /*----------------------------------------------------------------------*/
  2411. /*                                                                        */
  2412. /* XfeButton Public Methods                                                */
  2413. /*                                                                        */
  2414. /*----------------------------------------------------------------------*/
  2415. Widget
  2416. XfeCreateButton(Widget parent,char *name,Arg *args,Cardinal count)
  2417. {
  2418.     return (XtCreateWidget(name,xfeButtonWidgetClass,parent,args,count));
  2419. }
  2420. /*----------------------------------------------------------------------*/
  2421. /* extern */ void
  2422. XfeButtonPreferredGeometry(Widget            w,
  2423.                            unsigned char    layout,
  2424.                            Dimension *        width_out,
  2425.                            Dimension *        height_out)
  2426. {
  2427.     XfeButtonPart *        bp;
  2428.     Dimension            width;
  2429.     Dimension            height;
  2430.     unsigned char        old_layout;
  2431.  
  2432.     assert( _XfeIsAlive(w) );
  2433.     assert( XfeIsButton(w) );
  2434.  
  2435.     bp = _XfeButtonPart(w);
  2436.  
  2437.     /* Make sure the new layout is valid */
  2438.     if (!XfeRepTypeCheck(w,XmRButtonLayout,&layout,XmBUTTON_LABEL_ON_BOTTOM))
  2439.     {
  2440.         _XfeWarning(w,MESSAGE16);
  2441.  
  2442.         return;
  2443.     }
  2444.  
  2445.     /* Remember the old layout */
  2446.     old_layout = bp->button_layout;
  2447.  
  2448.     bp->button_layout = layout;
  2449.     
  2450.     _XfePrimitivePreferredGeometry(w,&width,&height);
  2451.  
  2452.     bp->button_layout = old_layout;
  2453.  
  2454.     if (width_out)
  2455.     {
  2456.         *width_out = width;
  2457.     }
  2458.  
  2459.     if (height_out)
  2460.     {
  2461.         *height_out = height;
  2462.     }
  2463. }
  2464. /*----------------------------------------------------------------------*/
  2465. /* extern */ Boolean
  2466. XfeButtonAcceptXY(Widget w,int x,int y)
  2467. {
  2468.     XfeButtonPart *    bp = _XfeButtonPart(w);
  2469.     XfeLabelPart *    lp = _XfeLabelPart(w);
  2470.     Boolean            result = True;
  2471.  
  2472.     /* Anywhere */
  2473.     if (bp->button_trigger == XmBUTTON_TRIGGER_ANYWHERE)
  2474.     {
  2475.          result = True;
  2476.     }
  2477.     /* Label */
  2478.     else if (bp->button_trigger == XmBUTTON_TRIGGER_LABEL)
  2479.     {
  2480.         if (bp->button_layout != XmBUTTON_PIXMAP_ONLY)
  2481.         {
  2482.             result = XY_IN_LABEL(lp,x,y);
  2483.         }
  2484.     }
  2485.     /* Pixmap */
  2486.     else if (bp->button_trigger == XmBUTTON_TRIGGER_PIXMAP)
  2487.     {
  2488.         if (bp->button_layout != XmBUTTON_LABEL_ONLY)
  2489.         {
  2490.             result = XY_IN_PIXMAP(bp,x,y);
  2491.         }
  2492.     }
  2493.     /* Neither */
  2494.     else if(bp->button_trigger == XmBUTTON_TRIGGER_NEITHER)
  2495.     {
  2496.         result = (!XY_IN_LABEL(lp,x,y) && !XY_IN_PIXMAP(bp,x,y));
  2497.     }
  2498.     /* Either */
  2499.     else if (bp->button_trigger == XmBUTTON_TRIGGER_EITHER)
  2500.     {
  2501.         if (bp->button_layout == XmBUTTON_LABEL_ONLY)
  2502.         {
  2503.             result = XY_IN_LABEL(lp,x,y);
  2504.         }
  2505.         else if (bp->button_layout == XmBUTTON_PIXMAP_ONLY)
  2506.         {
  2507.             result = XY_IN_PIXMAP(bp,x,y);
  2508.         }
  2509.         else 
  2510.         {
  2511.             result = (XY_IN_LABEL(lp,x,y) || 
  2512.                       XY_IN_PIXMAP(bp,x,y) || 
  2513.                       SpacingContainsXY(w,x,y));
  2514.         }
  2515.     }
  2516.  
  2517.     return result;
  2518. }
  2519. /*----------------------------------------------------------------------*/
  2520.  
  2521.