/* * @OPENGROUP_COPYRIGHT@ * COPYRIGHT NOTICE * Copyright (c) 1990, 1991, 1992, 1993 Open Software Foundation, Inc. * Copyright (c) 1996, 1997, 1998, 1999, 2000 The Open Group * ALL RIGHTS RESERVED (MOTIF). See the file named COPYRIGHT.MOTIF for * the full copyright text. * * This software is subject to an open license. It may only be * used on, with or for operating systems which are themselves open * source systems. You must contact The Open Group for a license * allowing distribution and sublicensing of this software on, with, * or for operating systems which are not Open Source programs. * * See http://www.opengroup.org/openmotif/license for full * details of the license agreement. Any use, reproduction, or * distribution of the program constitutes recipient's acceptance of * this agreement. * * EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS * PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY * WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY * OR FITNESS FOR A PARTICULAR PURPOSE * * EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT * NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE * EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. */ /* * HISTORY */ #ifdef REV_INFO #ifndef lint static char rcsid[] = "$TOG: ArrowBG.c /main/20 1999/01/26 15:30:15 mgreess $" #endif #endif /* (c) Copyright 1987, 1988, 1989, 1990, 1991, 1992 HEWLETT-PACKARD COMPANY */ #include #include #include #include #include #include #include #include #include "ColorI.h" #include "PixConvI.h" #include "PrimitiveI.h" #include "RepTypeI.h" #include "ScreenI.h" #include "TravActI.h" #include "TraversalI.h" #include "XmI.h" #define DELAY_DEFAULT 100 #define INVALID_PIXEL ((Pixel) -1) #define INVALID_PIXMAP ((Pixmap) -1) /******** Static Function Declarations ********/ static Pixmap GetHighlightPixmapDefault(XmArrowButtonGadget ag); static Pixmap GetTopShadowPixmapDefault(XmArrowButtonGadget ag); static void ClassPartInitialize(WidgetClass wc); static void Initialize(Widget rw, Widget nw, ArgList args, Cardinal *num_args); static void GetArrowGC(XmArrowButtonGadget ag); static void GetBackgroundGC(XmArrowButtonGadget ag); static void Redisplay(Widget w, XEvent *event, Region region); static void Destroy(Widget w); static Boolean SetValues(Widget cw, Widget rw, Widget nw, ArgList args, Cardinal *num_args); static void HighlightBorder(Widget w); static void InputDispatch(Widget wid, XEvent *event, Mask event_mask); static void Arm(XmArrowButtonGadget aw, XEvent *event); static void Activate(Widget wid, XEvent *event, String *params, Cardinal *num_params); static void ArmAndActivate(Widget w, XEvent *event, String *params, Cardinal *num_params); static void ArmTimeout(XtPointer data, XtIntervalId *id); static void Disarm(XmArrowButtonGadget aw, XEvent *event); static void Enter(XmArrowButtonGadget aw, XEvent *event); static void Leave(XmArrowButtonGadget aw, XEvent *event); static void Help(XmArrowButtonGadget aw, XEvent *event); static void ActivateCommonG(XmArrowButtonGadget ag, XEvent *event, Mask event_mask); static void ChangeCB(Widget w, XtCallbackProc activCB, XtPointer closure, Boolean setunset); static Boolean HandleRedraw(Widget kid, Widget cur_parent, Widget new_parent, Mask visual_flag); static void InitNewColorBehavior(XmArrowButtonGadget ag); static void DealWithColors(XmArrowButtonGadget ag); static void DealWithPixmaps(XmArrowButtonGadget ag); static void InitNewPixmapBehavior(XmArrowButtonGadget ag); static void DrawArrowG(XmArrowButtonGadget ag, GC top_gc, GC bottom_gc, GC center_gc); static void GetColors(Widget widget, XmAccessColorData color_data); /******** End Static Function Declarations ********/ /* Resource list for Arrow */ static XtResource resources[] = { { XmNmultiClick, XmCMultiClick, XmRMultiClick, sizeof(unsigned char), XtOffsetOf(struct _XmArrowButtonGadgetRec, arrowbutton.multiClick), XmRImmediate, (XtPointer) XmMULTICLICK_KEEP }, { XmNarrowDirection, XmCArrowDirection, XmRArrowDirection, sizeof(unsigned char), XtOffsetOf(struct _XmArrowButtonGadgetRec, arrowbutton.direction), XmRImmediate, (XtPointer) XmARROW_UP }, { XmNactivateCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList), XtOffsetOf(struct _XmArrowButtonGadgetRec, arrowbutton.activate_callback), XmRPointer, (XtPointer) NULL }, { XmNarmCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList), XtOffsetOf(struct _XmArrowButtonGadgetRec, arrowbutton.arm_callback), XmRPointer, (XtPointer) NULL }, { XmNdisarmCallback, XmCCallback, XmRCallback, sizeof(XtCallbackList), XtOffsetOf(struct _XmArrowButtonGadgetRec, arrowbutton.disarm_callback), XmRPointer, (XtPointer) NULL }, { XmNbackground, XmCBackground, XmRPixel, sizeof(Pixel), XtOffsetOf(struct _XmArrowButtonGadgetRec, arrowbutton.background), XmRImmediate, (XtPointer) INVALID_PIXEL }, { XmNforeground, XmCForeground, XmRPixel, sizeof(Pixel), XtOffsetOf(struct _XmArrowButtonGadgetRec, arrowbutton.foreground), XmRImmediate, (XtPointer) INVALID_PIXEL }, { XmNtopShadowColor, XmCTopShadowColor, XmRPixel, sizeof(Pixel), XtOffsetOf(struct _XmArrowButtonGadgetRec, arrowbutton.top_shadow_color), XmRImmediate, (XtPointer) INVALID_PIXEL }, { XmNtopShadowPixmap, XmCTopShadowPixmap, XmRNoScalingDynamicPixmap, sizeof(Pixmap), XtOffsetOf(struct _XmArrowButtonGadgetRec, arrowbutton.top_shadow_pixmap), XmRImmediate, (XtPointer) INVALID_PIXMAP }, { XmNbottomShadowColor, XmCBottomShadowColor, XmRPixel, sizeof(Pixel), XtOffsetOf(struct _XmArrowButtonGadgetRec, arrowbutton.bottom_shadow_color), XmRImmediate, (XtPointer) INVALID_PIXEL }, { XmNbottomShadowPixmap, XmCBottomShadowPixmap, XmRNoScalingDynamicPixmap, sizeof(Pixmap), XtOffsetOf(struct _XmArrowButtonGadgetRec, arrowbutton.bottom_shadow_pixmap), XmRImmediate, (XtPointer) XmUNSPECIFIED_PIXMAP }, { XmNhighlightColor, XmCHighlightColor, XmRPixel, sizeof(Pixel), XtOffsetOf(struct _XmArrowButtonGadgetRec, arrowbutton.highlight_color), XmRImmediate, (XtPointer) INVALID_PIXEL }, { XmNhighlightPixmap, XmCHighlightPixmap, XmRNoScalingDynamicPixmap, sizeof(Pixmap), XtOffsetOf(struct _XmArrowButtonGadgetRec, arrowbutton.highlight_pixmap), XmRImmediate, (XtPointer) INVALID_PIXMAP }, { XmNdetailShadowThickness, XmCShadowThickness, XmRHorizontalDimension, sizeof (Dimension), XtOffsetOf(XmArrowButtonGadgetRec, arrowbutton.detail_shadow_thickness), XmRCallProc, (XtPointer) _XmSetThickness } }; static XmSyntheticResource syn_resources[] = { { XmNdetailShadowThickness, sizeof(Dimension), XtOffsetOf(XmArrowButtonGadgetRec, arrowbutton.detail_shadow_thickness), XmeFromHorizontalPixels,XmeToHorizontalPixels } }; /* The Arrow class record definition */ externaldef(xmarrowbuttongadgetclassrec) XmArrowButtonGadgetClassRec xmArrowButtonGadgetClassRec = { { /* object fields */ (WidgetClass) &xmGadgetClassRec, /* superclass */ "XmArrowButtonGadget", /* class_name */ sizeof(XmArrowButtonGadgetRec), /* widget_size */ (XtProc)NULL, /* class_initialize */ ClassPartInitialize, /* class_part_initialize */ FALSE, /* class_inited */ Initialize, /* initialize */ (XtArgsProc)NULL, /* initialize_hook */ NULL, /* realize */ NULL, /* actions */ 0, /* num_actions */ resources, /* resources */ XtNumber(resources), /* num_resources */ NULLQUARK, /* xrm_class */ TRUE, /* compress_motion */ XtExposeCompressMaximal, /* compress_exposure */ TRUE, /* compress_enterleave */ FALSE, /* visible_interest */ Destroy, /* destroy */ (XtWidgetProc)NULL, /* resize */ Redisplay, /* expose */ SetValues, /* set_values */ (XtArgsFunc)NULL, /* set_values_hook */ XtInheritSetValuesAlmost, /* set_values_almost */ (XtArgsProc)NULL, /* get_values_hook */ NULL, /* accept_focus */ XtVersion, /* version */ (XtPointer)NULL, /* callback private */ (String)NULL, /* tm_table */ (XtGeometryHandler)NULL, /* query_geometry */ NULL, /* display_accelerator */ (XtPointer)NULL /* extension */ }, { /* XmGadget fields */ HighlightBorder, /* border highlight */ XmInheritBorderUnhighlight, /* border_unhighlight */ ArmAndActivate, /* arm_and_activate */ InputDispatch, /* input dispatch */ XmInheritVisualChange, /* visual_change */ syn_resources, /* syn_resources */ XtNumber(syn_resources), /* num_syn_resources */ (XmCacheClassPartPtr)NULL, /* class cache part */ (XtPointer)NULL /* extension */ }, { /* XmArrowButtonGadget fields */ (XtPointer)NULL /* extension */ } }; externaldef(xmarrowbuttongadgetclass) WidgetClass xmArrowButtonGadgetClass = (WidgetClass) &xmArrowButtonGadgetClassRec; /* Trait record for arrowBG */ static XmConst XmActivatableTraitRec arrowBGAT = { 0, /* version */ ChangeCB /* changeCB */ }; static XmConst XmCareVisualTraitRec arrowBGCVT = { 0, /* version */ HandleRedraw /* redraw */ }; /* Access Colors Trait record for arrow button gadget */ static XmConst XmAccessColorsTraitRec arrowBGACT = { 0, /* version */ GetColors, /* getColors */ NULL /* setColors */ }; static Pixmap GetHighlightPixmapDefault(XmArrowButtonGadget ag) { XmManagerWidget mw = (XmManagerWidget)XtParent(ag); Pixmap result = XmUNSPECIFIED_PIXMAP; if (ag->arrowbutton.highlight_color == ag->arrowbutton.background) result = XmGetPixmapByDepth(XtScreen(ag), XmS50_foreground, ag->arrowbutton.highlight_color, ag->arrowbutton.foreground, mw->core.depth); return result; } static Pixmap GetTopShadowPixmapDefault(XmArrowButtonGadget ag) { XmManagerWidget mw = (XmManagerWidget)XtParent(ag); Pixmap result = XmUNSPECIFIED_PIXMAP; if (ag->arrowbutton.top_shadow_color == ag->arrowbutton.background) result = XmGetPixmapByDepth(XtScreen(ag), XmS50_foreground, ag->arrowbutton.top_shadow_color, ag->arrowbutton.foreground, mw->core.depth); else if (DefaultDepthOfScreen(XtScreen(ag)) == 1) result = XmGetPixmapByDepth(XtScreen(ag), XmS50_foreground, ag->arrowbutton.top_shadow_color, ag->arrowbutton.background, mw->core.depth); return result; } /************************************************************************ * * ClassPartInitialize * Set up the fast subclassing for the widget * ************************************************************************/ static void ClassPartInitialize( WidgetClass wc) { _XmFastSubclassInit (wc, XmARROW_BUTTON_GADGET_BIT); /* Install the activatable trait for all subclasses */ XmeTraitSet((XtPointer)wc, XmQTactivatable, (XtPointer)&arrowBGAT); /* Install the careParentVisual trait for all subclasses as well. */ XmeTraitSet((XtPointer)wc, XmQTcareParentVisual, (XtPointer)&arrowBGCVT); /* Install the accessColors trait for all subclasses as well. */ XmeTraitSet((XtPointer)wc, XmQTaccessColors, (XtPointer)&arrowBGACT); } /************************************************************************ * * Initialize * The main widget instance initialization routine. * ************************************************************************/ /*ARGSUSED*/ static void Initialize( Widget rw, Widget nw, ArgList args, /* unused */ Cardinal *num_args) /* unused */ { XmArrowButtonGadget request = (XmArrowButtonGadget) rw; XmArrowButtonGadget new_w = (XmArrowButtonGadget) nw; /* * Check the data put into the new widget from .Xdefaults * or through the arg list. */ if (!XmRepTypeValidValue(XmRID_ARROW_DIRECTION, new_w->arrowbutton.direction, (Widget) new_w)) { new_w->arrowbutton.direction = XmARROW_UP; } /* Set up a geometry for the widget if it is currently 0. */ if (request->rectangle.width == 0) new_w->rectangle.width += 15; if (request->rectangle.height == 0) new_w->rectangle.height += 15; /* Set the internal arrow variables */ new_w->arrowbutton.timer = 0; new_w->arrowbutton.selected = False; /* Get the drawing graphics contexts. */ DealWithColors(new_w); DealWithPixmaps(new_w); GetArrowGC (new_w); GetBackgroundGC (new_w); new_w->arrowbutton.highlight_GC = _XmGetPixmapBasedGC (XtParent(nw), new_w->arrowbutton.highlight_color, new_w->arrowbutton.background, new_w->arrowbutton.highlight_pixmap); new_w->arrowbutton.top_shadow_GC = _XmGetPixmapBasedGC (XtParent(nw), new_w->arrowbutton.top_shadow_color, new_w->arrowbutton.background, new_w->arrowbutton.top_shadow_pixmap); new_w->arrowbutton.bottom_shadow_GC = _XmGetPixmapBasedGC (XtParent(nw), new_w->arrowbutton.bottom_shadow_color, new_w->arrowbutton.background, new_w->arrowbutton.bottom_shadow_pixmap); /* Initialize the interesting input types. */ new_w->gadget.event_mask = XmARM_EVENT | XmACTIVATE_EVENT | XmHELP_EVENT | XmFOCUS_IN_EVENT | XmFOCUS_OUT_EVENT | XmENTER_EVENT | XmLEAVE_EVENT | XmMULTI_ARM_EVENT| XmMULTI_ACTIVATE_EVENT; } /************************************************************************ * * GetBackgroundGC * Get the graphics context used for drawing the background. * ************************************************************************/ static void GetBackgroundGC( XmArrowButtonGadget ag) { XGCValues values; XtGCMask valueMask; XmManagerWidget mw = (XmManagerWidget) XtParent(ag); ag->arrowbutton.fill_bg_box = ((mw->core.background_pixel != ag->arrowbutton.background) && (mw->core.background_pixmap == XmUNSPECIFIED_PIXMAP)); if (!ag->arrowbutton.fill_bg_box) return; valueMask = GCForeground | GCBackground; values.foreground = ag->arrowbutton.background; values.background = ag->arrowbutton.foreground; ag->arrowbutton.background_GC = XtGetGC ((Widget) mw, valueMask, &values); } /************************************************************************ * * GetArrowGC * Get the graphics context used for drawing the arrowbutton. * ************************************************************************/ static void GetArrowGC( XmArrowButtonGadget ag) { XGCValues values; XtGCMask valueMask, unusedMask; XmManagerWidget mw = (XmManagerWidget) XtParent(ag); valueMask = GCForeground | GCBackground | GCGraphicsExposures; unusedMask = GCClipXOrigin | GCClipYOrigin | GCFont; values.foreground = ag->arrowbutton.foreground; values.background = ag->arrowbutton.background; values.graphics_exposures = False; ag->arrowbutton.arrow_GC = XtAllocateGC ((Widget) mw, 0, valueMask, &values, GCClipMask, unusedMask); valueMask |= GCFillStyle | GCStipple; values.fill_style = FillOpaqueStippled; values.stipple = _XmGetInsensitiveStippleBitmap((Widget) ag); ag->arrowbutton.insensitive_GC = XtAllocateGC((Widget) mw, 0, valueMask, &values, GCClipMask, unusedMask); } /************************************************************************ * * Redisplay * General redisplay function called on exposure events. * ************************************************************************/ /*ARGSUSED*/ static void Redisplay( Widget w, XEvent *event, Region region) { XmArrowButtonGadget aw = (XmArrowButtonGadget) w; int iwidth, iheight; int background_x_offset, background_y_offset, background_width, background_height; iwidth = (int) aw->rectangle.width - 2 * aw->gadget.highlight_thickness; iheight = (int) aw->rectangle.height - 2 * aw->gadget.highlight_thickness; background_x_offset = (aw->rectangle.x + aw->gadget.highlight_thickness + aw->gadget.shadow_thickness); background_y_offset = (aw->rectangle.y + aw->gadget.highlight_thickness + aw->gadget.shadow_thickness); background_height = iheight - 2 * aw->gadget.shadow_thickness; background_width = iwidth - 2 * aw->gadget.shadow_thickness; if (aw->arrowbutton.fill_bg_box) XFillRectangle(XtDisplay(aw), XtWindow((Widget) aw), aw->arrowbutton.background_GC, background_x_offset, background_y_offset, background_width, background_height); /* Draw the arrow */ if ((iwidth > 0) && (iheight > 0)) { if (aw->gadget.shadow_thickness > 0) XmeDrawShadows (XtDisplay (aw), XtWindow (aw), aw->arrowbutton.top_shadow_GC, aw->arrowbutton.bottom_shadow_GC, aw->rectangle.x + aw->gadget.highlight_thickness, aw->rectangle.y + aw->gadget.highlight_thickness, aw->rectangle.width - 2 * aw->gadget.highlight_thickness, aw->rectangle.height-2 * aw->gadget.highlight_thickness, aw->gadget.shadow_thickness, XmSHADOW_OUT); if (aw->arrowbutton.selected && XtIsSensitive(w)) DrawArrowG(aw, aw->arrowbutton.bottom_shadow_GC, aw->arrowbutton.top_shadow_GC, aw->arrowbutton.arrow_GC); else DrawArrowG(aw, aw->arrowbutton.top_shadow_GC, aw->arrowbutton.bottom_shadow_GC, (XtIsSensitive(w) ? aw->arrowbutton.arrow_GC : aw->arrowbutton.insensitive_GC)); } if (aw->gadget.highlighted) { (*(xmArrowButtonGadgetClassRec.gadget_class.border_highlight)) (w); } } /* * * DealWithColors * * Deal with compatibility. * If any resource is set initialize like a widget otherwise get * everything from the parent. * * */ static void DealWithColors( XmArrowButtonGadget ag) { XmManagerWidget mw = (XmManagerWidget) XtParent(ag); /* * If the gadget color is set to the tag value or it is the * same as the manager color; bc mode is enabled otherwise * initialize like a widget. */ if ((ag->arrowbutton.background == INVALID_PIXEL || ag->arrowbutton.background == mw->core.background_pixel) && (ag->arrowbutton.foreground == INVALID_PIXEL || ag->arrowbutton.foreground == mw->manager.foreground) && (ag->arrowbutton.top_shadow_color == INVALID_PIXEL || ag->arrowbutton.top_shadow_color == mw->manager.top_shadow_color) && (ag->arrowbutton.bottom_shadow_color == INVALID_PIXEL || ag->arrowbutton.bottom_shadow_color == mw->manager.bottom_shadow_color) && (ag->arrowbutton.highlight_color == INVALID_PIXEL || ag->arrowbutton.highlight_color == mw->manager.highlight_color)) { ag->arrowbutton.background = mw->core.background_pixel; ag->arrowbutton.foreground = mw->manager.foreground; ag->arrowbutton.top_shadow_color = mw->manager.top_shadow_color; ag->arrowbutton.bottom_shadow_color = mw->manager.bottom_shadow_color; ag->arrowbutton.highlight_color = mw->manager.highlight_color; } else { InitNewColorBehavior(ag); } } static void InitNewColorBehavior( XmArrowButtonGadget ag) { XrmValue value; value.size = sizeof(Pixel); if (ag->arrowbutton.background == INVALID_PIXEL) { _XmBackgroundColorDefault ((Widget)ag, XtOffsetOf(struct _XmArrowButtonGadgetRec, arrowbutton.background), &value); memcpy((char*) &ag->arrowbutton.background, value.addr, value.size); } if (ag->arrowbutton.foreground == INVALID_PIXEL) { _XmForegroundColorDefault ((Widget)ag, XtOffsetOf(struct _XmArrowButtonGadgetRec, arrowbutton.foreground), &value); memcpy((char*) &ag->arrowbutton.foreground, value.addr, value.size); } if (ag->arrowbutton.top_shadow_color == INVALID_PIXEL) { _XmTopShadowColorDefault ((Widget)ag, XtOffsetOf(struct _XmArrowButtonGadgetRec, arrowbutton.top_shadow_color), &value); memcpy((char*)&ag->arrowbutton.top_shadow_color, value.addr,value.size); } if (ag->arrowbutton.bottom_shadow_color == INVALID_PIXEL) { _XmBottomShadowColorDefault((Widget)ag, XtOffsetOf(struct _XmArrowButtonGadgetRec, arrowbutton.bottom_shadow_color), &value); memcpy((char*)&ag->arrowbutton.bottom_shadow_color, value.addr, value.size); } if (ag->arrowbutton.highlight_color == INVALID_PIXEL) { _XmHighlightColorDefault((Widget)ag, XtOffsetOf(struct _XmArrowButtonGadgetRec, arrowbutton.highlight_color), &value); memcpy((char*) &ag->arrowbutton.highlight_color, value.addr,value.size); } } /* * * DealWithPixmaps * * Deal with compatibility. * If any resource is set initialize like a widget otherwise get * everything from the parent. * */ static void DealWithPixmaps( XmArrowButtonGadget ag) { XmManagerWidget mw = (XmManagerWidget) XtParent(ag); if ((ag->arrowbutton.top_shadow_pixmap == INVALID_PIXMAP || ag->arrowbutton.top_shadow_pixmap == mw->manager.top_shadow_pixmap) && (ag->arrowbutton.highlight_pixmap == INVALID_PIXMAP || ag->arrowbutton.highlight_pixmap == mw->manager.highlight_pixmap)) { ag->arrowbutton.top_shadow_pixmap = mw->manager.top_shadow_pixmap; ag->arrowbutton.highlight_pixmap = mw->manager.highlight_pixmap; } else { InitNewPixmapBehavior(ag); } } /* * InitNewPixmapBehavior * * Initialize colors like a widget. */ static void InitNewPixmapBehavior( XmArrowButtonGadget ag) { if (ag->arrowbutton.top_shadow_pixmap == INVALID_PIXMAP) { ag->arrowbutton.top_shadow_pixmap = GetTopShadowPixmapDefault(ag); } if (ag->arrowbutton.highlight_pixmap == INVALID_PIXMAP) { ag->arrowbutton.highlight_pixmap = GetHighlightPixmapDefault(ag); } } /************************************************************************ * * Destroy * Clean up allocated resources when the widget is destroyed. * ************************************************************************/ static void Destroy( Widget w) { XmArrowButtonGadget aw = (XmArrowButtonGadget) w; XmManagerWidget mw = (XmManagerWidget) XtParent(aw); if (aw->arrowbutton.timer) XtRemoveTimeOut (aw->arrowbutton.timer); XtReleaseGC ((Widget) mw, aw->arrowbutton.arrow_GC); XtReleaseGC ((Widget) mw, aw->arrowbutton.insensitive_GC); if (aw->arrowbutton.fill_bg_box) XtReleaseGC ((Widget) mw, aw->arrowbutton.background_GC); XtReleaseGC ((Widget) mw, aw->arrowbutton.top_shadow_GC); XtReleaseGC ((Widget) mw, aw->arrowbutton.bottom_shadow_GC); XtReleaseGC ((Widget) mw, aw->arrowbutton.highlight_GC); } /************************************************************************ * * SetValues * ************************************************************************/ /*ARGSUSED*/ static Boolean SetValues( Widget cw, Widget rw, /* unused */ Widget nw, ArgList args, /* unused */ Cardinal *num_args) /* unused */ { XmArrowButtonGadget current = (XmArrowButtonGadget) cw; XmArrowButtonGadget new_w = (XmArrowButtonGadget) nw; Boolean returnFlag = FALSE; /* Check the data put into the new widget. */ if (!XmRepTypeValidValue(XmRID_ARROW_DIRECTION, new_w->arrowbutton.direction, (Widget) new_w)) { new_w->arrowbutton.direction = current->arrowbutton.direction; } /* ReInitialize the interesting input types. */ new_w->gadget.event_mask |= XmARM_EVENT | XmACTIVATE_EVENT | XmHELP_EVENT | XmFOCUS_IN_EVENT | XmFOCUS_OUT_EVENT | XmENTER_EVENT | XmLEAVE_EVENT | XmMULTI_ARM_EVENT | XmMULTI_ACTIVATE_EVENT; if (new_w->arrowbutton.direction != current->arrowbutton.direction || XtIsSensitive(nw) != XtIsSensitive(cw) || new_w->gadget.highlight_thickness != current->gadget.highlight_thickness || new_w->gadget.shadow_thickness != current->gadget.shadow_thickness) { returnFlag = TRUE; } if (new_w->arrowbutton.foreground != current->arrowbutton.foreground || new_w->arrowbutton.background != current->arrowbutton.background) { XtReleaseGC (XtParent(current), new_w->arrowbutton.arrow_GC); XtReleaseGC (XtParent(current), new_w->arrowbutton.insensitive_GC); if (new_w->arrowbutton.fill_bg_box) XtReleaseGC (XtParent(current), new_w->arrowbutton.background_GC); GetArrowGC (new_w); GetBackgroundGC (new_w); return (True); } if (current->arrowbutton.top_shadow_color != new_w->arrowbutton.top_shadow_color || current->arrowbutton.top_shadow_pixmap != new_w->arrowbutton.top_shadow_pixmap) { XtReleaseGC ((Widget) new_w, new_w->arrowbutton.top_shadow_GC); new_w->arrowbutton.top_shadow_GC = _XmGetPixmapBasedGC (XtParent(nw), new_w->arrowbutton.top_shadow_color, new_w->arrowbutton.background, new_w->arrowbutton.top_shadow_pixmap); returnFlag = True; } if (current->arrowbutton.bottom_shadow_color != new_w->arrowbutton.bottom_shadow_color || current->arrowbutton.bottom_shadow_pixmap != new_w->arrowbutton.bottom_shadow_pixmap) { XtReleaseGC ((Widget) new_w, new_w->arrowbutton.bottom_shadow_GC); new_w->arrowbutton.bottom_shadow_GC = _XmGetPixmapBasedGC (XtParent(nw), new_w->arrowbutton.bottom_shadow_color, new_w->arrowbutton.background, new_w->arrowbutton.bottom_shadow_pixmap); returnFlag = True; } if (current->arrowbutton.highlight_color != new_w->arrowbutton.highlight_color || current->arrowbutton.highlight_pixmap != new_w->arrowbutton.highlight_pixmap) { XtReleaseGC ((Widget) new_w, new_w->arrowbutton.highlight_GC); new_w->arrowbutton.highlight_GC = _XmGetPixmapBasedGC (XtParent(nw), new_w->arrowbutton.highlight_color, new_w->arrowbutton.background, new_w->arrowbutton.highlight_pixmap); returnFlag = True; } return (returnFlag); } static void HighlightBorder( Widget w) { XmArrowButtonGadget ag = (XmArrowButtonGadget) w; if (ag->rectangle.width == 0 || ag->rectangle.height == 0 || ag->gadget.highlight_thickness == 0) { return; } ag->gadget.highlighted = True; ag->gadget.highlight_drawn = True; /* CR 7330: Use XmeDrawHighlight, not _XmDrawHighlight. */ XmeDrawHighlight(XtDisplay((Widget) ag), XtWindow((Widget) ag), ag->arrowbutton.highlight_GC, ag->rectangle.x, ag->rectangle.y, ag->rectangle.width, ag->rectangle.height, ag->gadget.highlight_thickness); } static Boolean HandleRedraw ( Widget kid, Widget cur_parent, Widget new_parent, Mask visual_flag) { XmArrowButtonGadget ag = (XmArrowButtonGadget) kid; XmManagerWidget mw = (XmManagerWidget) new_parent; XmManagerWidget curmw = (XmManagerWidget) cur_parent; Boolean redraw, do_bg, do_arrow, do_highlight, do_top, do_bot; redraw = do_bg = do_arrow = do_highlight = do_top = do_bot = False; if ((visual_flag & VisualBackgroundPixel) && (ag->arrowbutton.background == curmw->core.background_pixel)) { redraw = do_bg = do_arrow = do_highlight = do_top = do_bot = True; ag->arrowbutton.background = mw->core.background_pixel; } if ((visual_flag & VisualForeground) && (ag->arrowbutton.foreground == curmw->manager.foreground)) { redraw = do_arrow = True; ag->arrowbutton.foreground = mw->manager.foreground; } if (visual_flag & VisualBackgroundPixmap) { redraw = do_bg = True; } if (visual_flag & (VisualTopShadowColor | VisualTopShadowPixmap)) { redraw = do_top = True; if (ag->arrowbutton.top_shadow_color == curmw->manager.top_shadow_color) ag->arrowbutton.top_shadow_color = mw->manager.top_shadow_color; if ((ag->arrowbutton.top_shadow_pixmap == curmw->manager.top_shadow_pixmap) && (ag->arrowbutton.top_shadow_pixmap != XmUNSPECIFIED_PIXMAP || ag->arrowbutton.top_shadow_color == curmw->manager.top_shadow_color)) ag->arrowbutton.top_shadow_pixmap = mw->manager.top_shadow_pixmap; } if (visual_flag & (VisualBottomShadowColor | VisualBottomShadowPixmap)) { redraw = do_bot = True; if (ag->arrowbutton.bottom_shadow_color == curmw->manager.bottom_shadow_color) ag->arrowbutton.bottom_shadow_color = mw->manager.bottom_shadow_color; if ((ag->arrowbutton.bottom_shadow_pixmap == curmw->manager.bottom_shadow_pixmap) && (ag->arrowbutton.bottom_shadow_pixmap != XmUNSPECIFIED_PIXMAP || ag->arrowbutton.bottom_shadow_color == curmw->manager.bottom_shadow_color)) ag->arrowbutton.bottom_shadow_pixmap = mw->manager.bottom_shadow_pixmap; } if (visual_flag & (VisualHighlightColor | VisualHighlightPixmap)) { redraw = do_highlight = True; if (ag->arrowbutton.highlight_color == curmw->manager.highlight_color) ag->arrowbutton.highlight_color = mw->manager.highlight_color; if (ag->arrowbutton.highlight_pixmap == curmw->manager.highlight_pixmap && (ag->arrowbutton.highlight_pixmap != XmUNSPECIFIED_PIXMAP || ag->arrowbutton.highlight_color != curmw->manager.highlight_color)) ag->arrowbutton.highlight_pixmap = mw->manager.highlight_pixmap; ag->arrowbutton.highlight_GC = _XmGetPixmapBasedGC (XtParent(ag), ag->arrowbutton.highlight_color, ag->arrowbutton.background, ag->arrowbutton.highlight_pixmap); } if (do_bg) { if (ag->arrowbutton.fill_bg_box) XtReleaseGC ((Widget)mw, ag->arrowbutton.background_GC); GetBackgroundGC (ag); } if (do_arrow) { XtReleaseGC ((Widget)mw, ag->arrowbutton.arrow_GC); XtReleaseGC ((Widget)mw, ag->arrowbutton.insensitive_GC); GetArrowGC (ag); } if (do_highlight) { XtReleaseGC ((Widget)mw, ag->arrowbutton.highlight_GC); ag->arrowbutton.highlight_GC = _XmGetPixmapBasedGC (XtParent(ag), ag->arrowbutton.highlight_color, ag->arrowbutton.background, ag->arrowbutton.highlight_pixmap); } if (do_top) { XtReleaseGC ((Widget)mw, ag->arrowbutton.top_shadow_GC); ag->arrowbutton.top_shadow_GC = _XmGetPixmapBasedGC (XtParent(ag), ag->arrowbutton.top_shadow_color, ag->arrowbutton.background, ag->arrowbutton.top_shadow_pixmap); } if (do_bot) { XtReleaseGC ((Widget)mw, ag->arrowbutton.bottom_shadow_GC); ag->arrowbutton.bottom_shadow_GC = _XmGetPixmapBasedGC (XtParent(ag), ag->arrowbutton.bottom_shadow_color, ag->arrowbutton.background, ag->arrowbutton.bottom_shadow_pixmap); } return redraw; } /************************************************************************ * * InputDispatch * This function catches input sent by a manager and dispatches it * to the individual routines. * ************************************************************************/ static void InputDispatch( Widget wid, XEvent *event, Mask event_mask) { XmArrowButtonGadget ag = (XmArrowButtonGadget) wid; if ((event_mask & XmARM_EVENT) || ((ag->arrowbutton.multiClick == XmMULTICLICK_KEEP) && (event_mask & XmMULTI_ARM_EVENT))) Arm (ag, event); else if (event_mask & XmACTIVATE_EVENT) { ag->arrowbutton.click_count = 1; ActivateCommonG (ag, event, event_mask); } else if (event_mask & XmMULTI_ACTIVATE_EVENT) { /* if XmNMultiClick resource is set to DISCARD - do nothing * else call ActivateCommon() and increment clickCount; */ if (ag->arrowbutton.multiClick == XmMULTICLICK_KEEP) { ag->arrowbutton.click_count++; ActivateCommonG (ag, event, event_mask); } } else if (event_mask & XmHELP_EVENT) Help (ag, event); else if (event_mask & XmENTER_EVENT) Enter (ag, event); else if (event_mask & XmLEAVE_EVENT) Leave (ag, event); else if (event_mask & XmFOCUS_IN_EVENT) _XmFocusInGadget ((Widget) ag, event, NULL, NULL); else if (event_mask & XmFOCUS_OUT_EVENT) _XmFocusOutGadget ((Widget)ag, event, NULL, NULL); } /************************************************************************ * * Arm * This function processes button 1 down occuring on the arrowbutton. * ************************************************************************/ static void Arm( XmArrowButtonGadget aw, XEvent *event) { XmArrowButtonCallbackStruct call_value; aw->arrowbutton.selected = True; DrawArrowG(aw, aw->arrowbutton.bottom_shadow_GC, aw->arrowbutton.top_shadow_GC, NULL); if (aw->arrowbutton.arm_callback) { XFlush(XtDisplay(aw)); call_value.reason = XmCR_ARM; call_value.event = event; XtCallCallbackList ((Widget) aw, aw->arrowbutton.arm_callback, &call_value); } } /************************************************************************ * * Activate * This function processes button 1 up occuring on the arrowbutton. * If the button 1 up occurred inside the button the activate * callbacks are called. * ************************************************************************/ /*ARGSUSED*/ static void Activate( Widget wid, XEvent *event, String *params, /* unused */ Cardinal *num_params) /* unused */ { XmArrowButtonGadget aw = (XmArrowButtonGadget) wid; XButtonPressedEvent *buttonEvent = (XButtonPressedEvent *) event; XmPushButtonCallbackStruct call_value; aw->arrowbutton.selected = False; DrawArrowG(aw, aw->arrowbutton.top_shadow_GC, aw->arrowbutton.bottom_shadow_GC, NULL); /* CR 9181: Consider clipping when testing visibility. */ if ((buttonEvent->type == ButtonPress || buttonEvent->type == ButtonRelease) && _XmGetPointVisibility(wid, buttonEvent->x_root, buttonEvent->y_root) && (aw->arrowbutton.activate_callback)) { XFlush(XtDisplay(aw)); call_value.reason = XmCR_ACTIVATE; call_value.event = (XEvent *) buttonEvent; call_value.click_count = aw->arrowbutton.click_count; XtCallCallbackList ((Widget) aw, aw->arrowbutton.activate_callback, &call_value); } } /************************************************************************ * * ArmAndActivate * ************************************************************************/ /*ARGSUSED*/ static void ArmAndActivate( Widget w, XEvent *event, String *params, /* unused */ Cardinal *num_params) /* unused */ { XmArrowButtonGadget ab = (XmArrowButtonGadget) w; XmPushButtonCallbackStruct call_value; XtExposeProc expose; ab->arrowbutton.selected = TRUE; ab->arrowbutton.click_count = 1; _XmProcessLock(); expose = ab->object.widget_class->core_class.expose; _XmProcessUnlock(); (*(expose)) ((Widget) ab, event, FALSE); XFlush (XtDisplay (ab)); if (ab->arrowbutton.arm_callback) { call_value.reason = XmCR_ARM; call_value.event = event; call_value.click_count = ab->arrowbutton.click_count; XtCallCallbackList ((Widget) ab, ab->arrowbutton.arm_callback, &call_value); } call_value.reason = XmCR_ACTIVATE; call_value.event = event; call_value.click_count = 1; /* always 1 in kselect */ if (ab->arrowbutton.activate_callback) { XFlush (XtDisplay (ab)); XtCallCallbackList ((Widget) ab, ab->arrowbutton.activate_callback, &call_value); } ab->arrowbutton.selected = FALSE; if (ab->arrowbutton.disarm_callback) { XFlush (XtDisplay (ab)); call_value.reason = XmCR_DISARM; XtCallCallbackList ((Widget) ab, ab->arrowbutton.disarm_callback, &call_value); } /* If the button is still around, show it released, after a short delay */ if (ab->object.being_destroyed == False) { ab->arrowbutton.timer = XtAppAddTimeOut(XtWidgetToApplicationContext((Widget) ab), (unsigned long) DELAY_DEFAULT, ArmTimeout, (XtPointer)ab); } } /*ARGSUSED*/ static void ArmTimeout( XtPointer data, XtIntervalId *id) { XmArrowButtonGadget ab = (XmArrowButtonGadget) data; ab->arrowbutton.timer = 0; if (XtIsRealized((Widget)ab) && XtIsManaged((Widget)ab)) { Redisplay ((Widget) ab, NULL, FALSE); XFlush (XtDisplay (ab)); } } /************************************************************************ * * Disarm * This function processes button 1 up occuring on the arrowbutton. * ************************************************************************/ static void Disarm( XmArrowButtonGadget aw, XEvent *event) { XmArrowButtonCallbackStruct call_value; call_value.reason = XmCR_DISARM; call_value.event = event; XtCallCallbackList ((Widget) aw, aw->arrowbutton.disarm_callback, &call_value); } /************************************************************************ * * Enter * ************************************************************************/ static void Enter( XmArrowButtonGadget aw, XEvent *event) { _XmEnterGadget ((Widget) aw, event, NULL, NULL); if (aw->arrowbutton.selected && XtIsSensitive((Widget) aw)) DrawArrowG(aw, aw->arrowbutton.bottom_shadow_GC, aw->arrowbutton.top_shadow_GC, NULL); } /************************************************************************ * * Leave * ************************************************************************/ static void Leave( XmArrowButtonGadget aw, XEvent *event) { _XmLeaveGadget ((Widget) aw, event, NULL, NULL); if (aw->arrowbutton.selected && XtIsSensitive((Widget) aw)) DrawArrowG(aw, aw->arrowbutton.top_shadow_GC, aw->arrowbutton.bottom_shadow_GC, NULL); } /************************************************************************ * * Help * This function processes Function Key 1 press occuring on * the arrowbutton. * ************************************************************************/ static void Help( XmArrowButtonGadget aw, XEvent *event) { _XmSocorro((Widget) aw, event, NULL, NULL); } /************************************************************************ * * ChangeCB * add or remove the activate callback list. * ************************************************************************/ static void ChangeCB( Widget w, XtCallbackProc activCB, XtPointer closure, Boolean setunset) { if (setunset) XtAddCallback (w, XmNactivateCallback, activCB, closure); else XtRemoveCallback (w, XmNactivateCallback, activCB, closure); } static void GetColors(Widget w, XmAccessColorData color_data) { color_data->valueMask = AccessForeground | AccessBackgroundPixel | AccessHighlightColor | AccessTopShadowColor | AccessBottomShadowColor; color_data->background = ArrowBG_Background(w); color_data->foreground = ArrowBG_Foreground(w); color_data->highlight_color = ArrowBG_HighlightColor(w); color_data->top_shadow_color = ArrowBG_TopShadowColor(w); color_data->bottom_shadow_color = ArrowBG_BottomShadowColor(w); } /************************************************************************ * * XmCreateArrowButtonGadget * Create an instance of an arrowbutton and return the widget id. * ************************************************************************/ Widget XmCreateArrowButtonGadget( Widget parent, char *name, ArgList arglist, Cardinal argcount) { return XtCreateWidget(name, xmArrowButtonGadgetClass, parent, arglist, argcount); } /* ARGSUSED */ static void ActivateCommonG( XmArrowButtonGadget ag, XEvent *event, Mask event_mask) { if (event->type == ButtonRelease) { Activate((Widget) ag, event, NULL, NULL); Disarm (ag, event); } else /* assume KeyPress or KeyRelease */ (* (((XmArrowButtonGadgetClassRec *)(ag->object.widget_class))-> gadget_class.arm_and_activate)) ((Widget) ag, event, NULL, NULL); } /* Wrapper around XmeDrawArrow to calculate sizes. */ static void DrawArrowG(XmArrowButtonGadget ag, GC top_gc, GC bottom_gc, GC center_gc) { Position x, y; Dimension width, height; Dimension margin = ag->gadget.highlight_thickness + ag->gadget.shadow_thickness; /* Don't let large margins cause confusion. */ if (margin <= (ag->rectangle.width / 2)) { x = ag->rectangle.x + margin; width = ag->rectangle.width - (margin * 2); } else { x = ag->rectangle.x + ag->rectangle.width / 2; width = 0; } if (margin <= (ag->rectangle.height / 2)) { y = ag->rectangle.y + margin; height = ag->rectangle.height - (margin * 2); } else { y = ag->rectangle.y + ag->rectangle.height / 2; height = 0; } /* The way we currently handle 1 shadowThickness in XmeDrawArrow is by drawing the center a little bit bigger, so the center_gc has to be present. Kinda hacky... */ if (!center_gc && ag->arrowbutton.detail_shadow_thickness == 1) center_gc = ag->arrowbutton.arrow_GC ; if (center_gc) XSetClipMask(XtDisplay((Widget) ag), center_gc, None); XmeDrawArrow (XtDisplay ((Widget) ag), XtWindow ((Widget) ag), top_gc, bottom_gc, center_gc, x, y, width, height, ag->arrowbutton.detail_shadow_thickness, ag->arrowbutton.direction); }