/* * @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: LabelG.c /main/24 1999/01/26 15:31:18 mgreess $" #endif #endif /* (c) Copyright 1989, DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. */ /* (c) Copyright 1987, 1988, 1989, 1990, 1991, 1992 HEWLETT-PACKARD COMPANY */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "BaseClassI.h" #include "CacheI.h" #include "ColorI.h" #include "ExtObjectI.h" #include "GadgetUtiI.h" #include "LabelGI.h" #include "MessagesI.h" #include "MenuProcI.h" #include "PixConvI.h" #include "RepTypeI.h" #include "ScreenI.h" #include "SyntheticI.h" #include "TravActI.h" #include "XmI.h" #include "XmosI.h" #include "XmStringI.h" #define Pix(w) LabG_Pixmap(w) #define Pix_insen(w) LabG_PixmapInsensitive(w) /* Warning Messages */ #define CS_STRING_MESSAGE _XmMMsgLabel_0003 #define ACC_MESSAGE _XmMMsgLabel_0004 /******** Static Function Declarations ********/ static Pixmap GetTopShadowPixmapDefault(Widget); static Pixmap GetLabelHighlightPixmapDefault(Widget); static void ClassInitialize(void); static void ClassPartInitialize(WidgetClass cl); static void SecondaryObjectCreate(Widget req, Widget new_w, ArgList args, Cardinal *num_args); static void InitializePosthook(Widget req, Widget new_w, ArgList args, Cardinal *num_args); static Boolean SetValuesPrehook(Widget oldParent, Widget refParent, Widget newParent, ArgList args, Cardinal *num_args); static void GetValuesPrehook(Widget newParent, ArgList args, Cardinal *num_args); static void GetValuesPosthook(Widget new_w, ArgList args, Cardinal *num_args); static Boolean SetValuesPosthook(Widget current, Widget req, Widget new_w, ArgList args, Cardinal *num_args); static void BorderHighlight(Widget w); static void SetNormalGC(XmLabelGadget lw); static void Resize(Widget wid); static void Initialize(Widget req, Widget new_w, ArgList args, Cardinal *num_args); static XtGeometryResult QueryGeometry(Widget wid, XtWidgetGeometry *intended, XtWidgetGeometry *reply); static void Destroy(Widget w); static void Redisplay(Widget wid, XEvent *event, Region region); static Boolean SetValues(Widget cw, Widget rw, Widget nw, ArgList args, Cardinal *num_args); static void InputDispatch(Widget wid, XEvent *event, Mask event_mask); static void Help(Widget w, XEvent *event); static void GetLabelString(Widget wid, int offset, XtArgVal *value); static void GetAccelerator(Widget wid, int offset, XtArgVal *value); static void GetAcceleratorText(Widget wid, int offset, XtArgVal *value); static XmStringCharSet _XmStringCharsetCreate(XmStringCharSet stringcharset); static void GetMnemonicCharset(Widget wid, int resource, XtArgVal *value); static void QualifyLabelLocalCache(XmLabelGadget w); static void SetOverrideCallback(Widget w); static Cardinal GetLabelBGClassSecResData(WidgetClass w_class, XmSecondaryResourceData **data_rtn); static XtPointer GetLabelClassResBase(Widget widget, XtPointer client_data); static void SetValuesAlmost(Widget cw, Widget nw, XtWidgetGeometry *request, XtWidgetGeometry *reply); static Boolean XmLabelGadgetGetBaselines(Widget wid, Dimension **baselines, int *line_count); static Boolean XmLabelGadgetGetDisplayRect(Widget w, XRectangle *displayrect); static void XmLabelGadgetMarginsProc(Widget w, XmBaselineMargins *margins_rec); static Widget GetPixmapDragIcon(Widget w); static void SetGadgetActivateCallbackState(Widget w, XmActivateState state); static void CheckSetRenderTable(Widget wid, int offset, XrmValue *value); static Boolean HandleRedraw(Widget kid, Widget cur_parent, Widget new_parent, Mask visual_flag); static void InitNewColorBehavior(XmLabelGadget lw); static void DealWithColors(XmLabelGadget lw); static void DealWithPixmaps(XmLabelGadget lw); static void InitNewPixmapBehavior(XmLabelGadget lw); static char* GetLabelGadgetAccelerator(Widget); static KeySym GetLabelGadgetMnemonic(Widget); static void GetColors(Widget widget, XmAccessColorData color_data); /******** End Static Function Declarations ********/ void _XmLabelConvert(Widget w, XtPointer ignore, XmConvertCallbackStruct*); /* Transfer trait record */ static XmConst XmTransferTraitRec LabelGTransfer = { 0, /* version */ (XmConvertCallbackProc) _XmLabelConvert, /* convertProc */ NULL, /* destinationProc */ NULL /* destinationPreHookProc */ }; /* Menu Savvy trait record */ static XmConst XmMenuSavvyTraitRec MenuSavvyGadgetRecord = { 0, /* version */ SetGadgetActivateCallbackState, /* disableCallback */ GetLabelGadgetAccelerator, /* getAccelerator */ GetLabelGadgetMnemonic, /* getMnemonic */ NULL /* getActivateCBName */ }; /* Used to be: extern XmConst XmAccessTextualTraitRec _XmLabel_AccessTextualRecord; but that was giving a linkage undefined with g++. It looks like a G++ bug. */ extern XmAccessTextualTraitRec _XmLabel_AccessTextualRecord; static XmConst XmCareVisualTraitRec LabelGCVT = { 0, /* version */ HandleRedraw /* redraw */ }; /* Access Colors Trait record for label gadget */ static XmConst XmAccessColorsTraitRec labACT = { 0, /* version */ GetColors, /* getColors */ NULL /* setColors */ }; /* * Uncached resources for Label Gadget */ static XtResource resources[] = { /* The following hackery is a way in Xt to see if a widget has been * initialized. We need to know whether or not the gadget cache is * valid. We use "." in the name so that an end user cannot access * it from a resource file. With that in place, we just need to * check label.cache != NULL to see if the gadget has been * initialized and that we can access the colors for instance. */ { XmNdotCache, XmCDotCache, XmRPointer, sizeof(XtPointer), XtOffsetOf(XmLabelGadgetRec, label.cache), XtRImmediate, (XtPointer) NULL }, { XmNshadowThickness, XmCShadowThickness, XmRHorizontalDimension, sizeof(Dimension), XtOffsetOf(XmLabelGadgetRec, gadget.shadow_thickness), XmRImmediate, (XtPointer) 0 }, { XmNlabelPixmap, XmCLabelPixmap, XmRDynamicPixmap, sizeof(Pixmap), XtOffsetOf(XmLabelGadgetRec, label.pixmap), XmRImmediate, (XtPointer) XmUNSPECIFIED_PIXMAP }, { XmNlabelInsensitivePixmap, XmCLabelInsensitivePixmap, XmRDynamicPixmap, sizeof(Pixmap), XtOffsetOf(XmLabelGadgetRec, label.pixmap_insen), XmRImmediate, (XtPointer) XmUNSPECIFIED_PIXMAP }, { XmNlabelString, XmCXmString, XmRXmString, sizeof(XmString), XtOffsetOf(XmLabelGadgetRec, label._label), XmRImmediate, (XtPointer) NULL }, { "pri.vate","Pri.vate", XmRBoolean, sizeof(Boolean), XtOffsetOf(XmLabelGadgetRec, label.check_set_render_table), XmRImmediate, (XtPointer) False }, { XmNfontList, XmCFontList, XmRFontList, sizeof(XmFontList), XtOffsetOf(XmLabelGadgetRec, label.font), XmRCallProc, (XtPointer)CheckSetRenderTable }, { XmNrenderTable, XmCRenderTable, XmRRenderTable, sizeof(XmRenderTable), XtOffsetOf(XmLabelGadgetRec, label.font), XmRCallProc, (XtPointer)CheckSetRenderTable }, { XmNmnemonic, XmCMnemonic, XmRKeySym, sizeof(KeySym), XtOffsetOf(XmLabelGadgetRec, label.mnemonic), XmRImmediate, (XtPointer) XK_VoidSymbol }, { XmNmnemonicCharSet, XmCMnemonicCharSet, XmRString, sizeof(XmStringCharSet), XtOffsetOf(XmLabelGadgetRec,label.mnemonicCharset), XmRImmediate, (XtPointer) XmFONTLIST_DEFAULT_TAG }, { XmNaccelerator, XmCAccelerator, XmRString, sizeof(char *), XtOffsetOf(XmLabelGadgetRec, label.accelerator), XmRImmediate, (XtPointer) NULL }, { XmNacceleratorText, XmCAcceleratorText, XmRXmString, sizeof(XmString), XtOffsetOf(XmLabelGadgetRec, label._acc_text), XmRImmediate, (XtPointer) NULL }, { XmNtraversalOn, XmCTraversalOn, XmRBoolean, sizeof(Boolean), XtOffsetOf(XmGadgetRec, gadget.traversal_on), XmRImmediate, (XtPointer) False }, { XmNhighlightThickness, XmCHighlightThickness, XmRHorizontalDimension, sizeof(Dimension), XtOffsetOf(XmGadgetRec, gadget.highlight_thickness), XmRImmediate, (XtPointer) 0 } }; /* These 2 slots are needed for the delayed conversion. */ static XtResource label_pixmap_resource[] = { { XmNlabelPixmap, XmCLabelPixmap, XmRDynamicPixmap, sizeof(Pixmap), XtOffsetOf(XmLabelGadgetRec, label.pixmap), XmRImmediate, (XtPointer) XmUNSPECIFIED_PIXMAP } }; static XtResource label_pixmap_insen_resource[] = { { XmNlabelInsensitivePixmap, XmCLabelInsensitivePixmap, XmRDynamicPixmap, sizeof(Pixmap), XtOffsetOf(XmLabelGadgetRec, label.pixmap_insen), XmRImmediate, (XtPointer) XmUNSPECIFIED_PIXMAP } }; /* * Cached resources for Label Gadget */ static XtResource cache_resources[] = { { XmNlabelType, XmCLabelType, XmRLabelType, sizeof(unsigned char), XtOffsetOf(XmLabelGCacheObjRec, label_cache.label_type), XmRImmediate, (XtPointer) XmSTRING }, { XmNalignment, XmCAlignment, XmRAlignment, sizeof(unsigned char), XtOffsetOf(XmLabelGCacheObjRec, label_cache.alignment), XmRImmediate, (XtPointer) XmALIGNMENT_CENTER }, { XmNmarginWidth, XmCMarginWidth, XmRHorizontalDimension, sizeof(Dimension), XtOffsetOf(XmLabelGCacheObjRec, label_cache.margin_width), XmRImmediate, (XtPointer) 2 }, { XmNmarginHeight, XmCMarginHeight, XmRVerticalDimension, sizeof(Dimension), XtOffsetOf(XmLabelGCacheObjRec, label_cache.margin_height), XmRImmediate, (XtPointer) 2 }, { XmNmarginLeft, XmCMarginLeft, XmRHorizontalDimension, sizeof(Dimension), XtOffsetOf(XmLabelGCacheObjRec, label_cache.margin_left), XmRImmediate, (XtPointer) 0 }, { XmNmarginRight, XmCMarginRight, XmRHorizontalDimension, sizeof(Dimension), XtOffsetOf(XmLabelGCacheObjRec, label_cache.margin_right), XmRImmediate, (XtPointer) 0 }, { XmNmarginTop, XmCMarginTop, XmRVerticalDimension, sizeof(Dimension), XtOffsetOf(XmLabelGCacheObjRec, label_cache.margin_top), XmRImmediate, (XtPointer) 0 }, { XmNmarginBottom, XmCMarginBottom, XmRVerticalDimension, sizeof(Dimension), XtOffsetOf(XmLabelGCacheObjRec, label_cache.margin_bottom), XmRImmediate, (XtPointer) 0 }, { XmNrecomputeSize, XmCRecomputeSize, XmRBoolean, sizeof(Boolean), XtOffsetOf(XmLabelGCacheObjRec, label_cache.recompute_size), XmRImmediate, (XtPointer) True }, { XmNstringDirection, XmCStringDirection, XmRStringDirection, sizeof(unsigned char), XtOffsetOf(XmLabelGCacheObjRec, label_cache.string_direction), XmRImmediate, (XtPointer) XmDEFAULT_DIRECTION }, { XmNlayoutDirection, XmCLayoutDirection, XmRDirection, sizeof(XmDirection), XtOffsetOf(XmGadgetRec, gadget.layout_direction), XmRImmediate, (XtPointer) XmDEFAULT_DIRECTION }, { XmNbackground, XmCBackground, XmRPixel, sizeof(Pixel), XtOffsetOf(XmLabelGCacheObjRec, label_cache.background), XmRImmediate, (XtPointer) INVALID_PIXEL }, { XmNforeground, XmCForeground, XmRPixel, sizeof(Pixel), XtOffsetOf(XmLabelGCacheObjRec, label_cache.foreground), XmRImmediate, (XtPointer) INVALID_PIXEL }, { XmNtopShadowColor, XmCTopShadowColor, XmRPixel, sizeof(Pixel), XtOffsetOf(XmLabelGCacheObjRec, label_cache.top_shadow_color), XmRImmediate, (XtPointer) INVALID_PIXEL }, { XmNtopShadowPixmap, XmCTopShadowPixmap, XmRNoScalingDynamicPixmap, sizeof(Pixmap), XtOffsetOf(XmLabelGCacheObjRec, label_cache.top_shadow_pixmap), XmRImmediate, (XtPointer) INVALID_PIXMAP }, { XmNbottomShadowColor, XmCBottomShadowColor, XmRPixel, sizeof(Pixel), XtOffsetOf(XmLabelGCacheObjRec, label_cache.bottom_shadow_color), XmRImmediate, (XtPointer) INVALID_PIXEL }, { XmNbottomShadowPixmap, XmCBottomShadowPixmap, XmRNoScalingDynamicPixmap, sizeof(Pixmap), XtOffsetOf(XmLabelGCacheObjRec, label_cache.bottom_shadow_pixmap), XmRImmediate, (XtPointer) XmUNSPECIFIED_PIXMAP }, { XmNhighlightColor, XmCHighlightColor, XmRPixel, sizeof(Pixel), XtOffsetOf(XmLabelGCacheObjRec, label_cache.highlight_color), XmRImmediate, (XtPointer) INVALID_PIXEL }, { XmNhighlightPixmap, XmCHighlightPixmap, XmRNoScalingDynamicPixmap, sizeof(Pixmap), XtOffsetOf(XmLabelGCacheObjRec, label_cache.highlight_pixmap), XmRImmediate, (XtPointer) INVALID_PIXMAP } }; /* Definition for resources that need special processing in get values */ static XmSyntheticResource syn_resources[] = { { XmNlabelString, sizeof(XmString), XtOffsetOf(XmLabelGadgetRec, label._label), GetLabelString, NULL }, { XmNaccelerator, sizeof(String), XtOffsetOf(XmLabelGadgetRec, label.accelerator), GetAccelerator, NULL }, { XmNacceleratorText, sizeof(XmString), XtOffsetOf(XmLabelGadgetRec, label._acc_text), GetAcceleratorText, NULL }, { XmNmnemonicCharSet, sizeof(XmStringCharSet), XtOffsetOf(XmLabelGadgetRec,label.mnemonicCharset), GetMnemonicCharset, NULL } }; static XmSyntheticResource cache_syn_resources[] = { { XmNmarginWidth, sizeof(Dimension), XtOffsetOf(XmLabelGCacheObjRec, label_cache.margin_width), XmeFromHorizontalPixels, XmeToHorizontalPixels }, { XmNmarginHeight, sizeof(Dimension), XtOffsetOf(XmLabelGCacheObjRec, label_cache.margin_height), XmeFromVerticalPixels, XmeToVerticalPixels }, { XmNmarginLeft, sizeof(Dimension), XtOffsetOf(XmLabelGCacheObjRec, label_cache.margin_left), XmeFromHorizontalPixels, XmeToHorizontalPixels }, { XmNmarginRight, sizeof(Dimension), XtOffsetOf(XmLabelGCacheObjRec, label_cache.margin_right), XmeFromHorizontalPixels, XmeToHorizontalPixels }, { XmNmarginTop, sizeof(Dimension), XtOffsetOf(XmLabelGCacheObjRec, label_cache.margin_top), XmeFromVerticalPixels, XmeToVerticalPixels }, { XmNmarginBottom, sizeof(Dimension), XtOffsetOf(XmLabelGCacheObjRec, label_cache.margin_bottom), XmeFromVerticalPixels, XmeToVerticalPixels } }; static XmCacheClassPart LabelClassCachePart = { { NULL, 0, 0 }, /* head of class cache list */ _XmCacheCopy, /* Copy routine */ _XmCacheDelete, /* Delete routine */ _XmLabelCacheCompare /* Comparison routine */ }; static XmBaseClassExtRec labelBaseClassExtRec = { NULL, /* Next extension */ NULLQUARK, /* record type XmQmotif */ XmBaseClassExtVersion, /* version */ sizeof(XmBaseClassExtRec), /* size */ XmInheritInitializePrehook, /* initialize prehook */ SetValuesPrehook, /* set_values prehook */ InitializePosthook, /* initialize posthook */ SetValuesPosthook, /* set_values posthook */ (WidgetClass)&xmLabelGCacheObjClassRec, /* secondary class */ SecondaryObjectCreate, /* creation proc */ GetLabelBGClassSecResData, /* getSecResData */ {0}, /* fast subclass */ GetValuesPrehook, /* get_values prehook */ GetValuesPosthook, /* get_values posthook */ NULL, /* classPartInitPrehook */ NULL, /* classPartInitPosthook */ NULL, /* ext_resources */ NULL, /* compiled_ext_resources */ 0, /* num_ext_resources */ FALSE, /* use_sub_resources */ XmInheritWidgetNavigable, /* widgetNavigable */ XmInheritFocusChange /* focusChange */ }; externaldef (xmlabelgcacheobjclassrec) XmLabelGCacheObjClassRec xmLabelGCacheObjClassRec = { { (WidgetClass) &xmExtClassRec, /* superclass */ "XmLabelGadget", /* class_name */ sizeof(XmLabelGCacheObjRec), /* widget_size */ NULL, /* class_initialize */ NULL, /* chained class init */ False, /* class_inited */ NULL, /* initialize */ NULL, /* initialize hook */ NULL, /* realize */ NULL, /* actions */ 0, /* num_actions */ cache_resources, /* resources */ XtNumber(cache_resources), /* num_resources */ NULLQUARK, /* xrm_class */ False, /* compress_motion */ False, /* compress_exposure */ False, /* compress enter/exit */ False, /* visible_interest */ NULL, /* destroy */ NULL, /* resize */ NULL, /* expose */ NULL, /* set_values */ NULL, /* set values hook */ NULL, /* set values almost */ NULL, /* get values hook */ NULL, /* accept_focus */ XtVersion, /* version */ NULL, /* callback offsetlst */ NULL, /* default trans */ NULL, /* query geo proc */ NULL, /* display accelerator */ NULL /* extension record */ }, { cache_syn_resources, /* synthetic resources */ XtNumber(cache_syn_resources), /* num_syn_resources */ NULL /* extension */ } }; /* This is the class record that gets set at compile/link time */ /* this is what is passed to the widget create routine as the */ /* the class. All fields must be inited at compile time. */ static XmGadgetClassExtRec _XmLabelGadClassExtRec = { NULL, /* next_extension */ NULLQUARK, /* record_type */ XmGadgetClassExtVersion, /* version */ sizeof(XmGadgetClassExtRec), /* record_size */ XmLabelGadgetGetBaselines, /* widget_baseline */ XmLabelGadgetGetDisplayRect, /* widget_display_rect */ XmLabelGadgetMarginsProc, /* widget_margins */ }; externaldef (xmlabelgadgetclassrec) XmLabelGadgetClassRec xmLabelGadgetClassRec = { { (WidgetClass) &xmGadgetClassRec, /* superclass */ "XmLabelGadget", /* class_name */ sizeof(XmLabelGadgetRec), /* widget_size */ ClassInitialize, /* class_initialize */ ClassPartInitialize, /* chained class init */ False, /* class_inited */ Initialize, /* initialize */ 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 enter/exit */ False, /* visible_interest */ Destroy, /* destroy */ Resize, /* resize */ Redisplay, /* expose */ SetValues, /* set_values */ NULL, /* set values hook */ SetValuesAlmost, /* set values almost */ NULL, /* get values hook */ NULL, /* accept_focus */ XtVersion, /* version */ NULL, /* callback offsetlst */ NULL, /* default trans */ QueryGeometry, /* query geo proc */ NULL, /* display accelerator */ (XtPointer)&labelBaseClassExtRec /* extension record */ }, { /* XmGadgetClassPart */ BorderHighlight, /* border_highlight */ XmInheritBorderUnhighlight, /* border_unhighlight */ NULL, /* arm_and_activate */ InputDispatch, /* input dispatch */ XmInheritVisualChange, /* visual_change */ syn_resources, /* syn resources */ XtNumber(syn_resources), /* num syn_resources */ &LabelClassCachePart, /* class cache part */ (XtPointer)&_XmLabelGadClassExtRec /* extension */ }, { /* XmLabelGadgetClassPart */ SetOverrideCallback, /* override_callback */ NULL, /* menu procedure interface */ NULL /* extension record */ } }; externaldef(xmlabelgadgetclass) WidgetClass xmLabelGadgetClass = (WidgetClass) &xmLabelGadgetClassRec; /*ARGSUSED*/ static Pixmap GetTopShadowPixmapDefault(Widget widget) { XmLabelGadget lg = (XmLabelGadget) widget; XmManagerWidget mw = (XmManagerWidget)XtParent(lg); Pixmap result = XmUNSPECIFIED_PIXMAP; if (LabG_TopShadowColor(lg) == LabG_Background(lg)) result = XmGetPixmapByDepth (XtScreen (lg), XmS50_foreground, LabG_TopShadowColor(lg), LabG_Foreground(lg), mw->core.depth); else if (DefaultDepthOfScreen (XtScreen (widget)) == 1) result = XmGetPixmapByDepth (XtScreen (lg), XmS50_foreground, LabG_TopShadowColor(lg), LabG_Background(lg), mw->core.depth); return result; } /*ARGSUSED*/ static Pixmap GetLabelHighlightPixmapDefault(Widget widget) { XmLabelGadget lg = (XmLabelGadget) widget; XmManagerWidget mw = (XmManagerWidget)XtParent(lg); Pixmap result = XmUNSPECIFIED_PIXMAP; if (LabG_HighlightColor(lg) == LabG_Background(lg)) result = XmGetPixmapByDepth (XtScreen (lg), XmS50_foreground, LabG_HighlightColor(lg), LabG_Foreground(lg), mw->core.depth); return result; } /******************************************************************* * * _XmLabelCacheCompare * *******************************************************************/ int _XmLabelCacheCompare( XtPointer A, XtPointer B) { XmLabelGCacheObjPart *label_inst = (XmLabelGCacheObjPart *) A; XmLabelGCacheObjPart *label_cache_inst = (XmLabelGCacheObjPart *) B; if ((label_inst->label_type == label_cache_inst->label_type) && (label_inst->alignment == label_cache_inst->alignment) && (label_inst->string_direction == label_cache_inst->string_direction) && (label_inst->margin_height == label_cache_inst->margin_height) && (label_inst->margin_width == label_cache_inst->margin_width) && (label_inst->margin_left == label_cache_inst->margin_left) && (label_inst->margin_right == label_cache_inst->margin_right) && (label_inst->margin_top == label_cache_inst->margin_top) && (label_inst->margin_bottom == label_cache_inst->margin_bottom) && (label_inst->recompute_size == label_cache_inst->recompute_size) && (label_inst->skipCallback == label_cache_inst->skipCallback) && (label_inst->menu_type == label_cache_inst->menu_type) && (label_inst->background_GC == label_cache_inst->background_GC) && (label_inst->top_shadow_GC == label_cache_inst->top_shadow_GC) && (label_inst->bottom_shadow_GC == label_cache_inst->bottom_shadow_GC) && (label_inst->highlight_GC == label_cache_inst->highlight_GC) && (label_inst->foreground == label_cache_inst->foreground) && (label_inst->background == label_cache_inst->background) && (label_inst->top_shadow_color == label_cache_inst->top_shadow_color) && (label_inst->top_shadow_pixmap == label_cache_inst->top_shadow_pixmap) && (label_inst->bottom_shadow_color == label_cache_inst->bottom_shadow_color) && (label_inst->bottom_shadow_pixmap == label_cache_inst->bottom_shadow_pixmap) && (label_inst->highlight_color == label_cache_inst->highlight_color) && (label_inst->highlight_pixmap == label_cache_inst->highlight_pixmap)) return 1; else return 0; } /*********************************************************** * * ClassInitialize * ************************************************************/ static void ClassInitialize(void) { labelBaseClassExtRec.record_type = XmQmotif; /* Install menu savvy on just this class */ XmeTraitSet((XtPointer) &xmLabelGadgetClassRec, XmQTmenuSavvy, (XtPointer) &MenuSavvyGadgetRecord); } void _XmLabelGCloneMenuSavvy(WidgetClass wc, XmMenuSavvyTrait mst) { /* Modify and reinstall menu savvy trait */ if (mst->version == -1) { mst->version = MenuSavvyGadgetRecord.version; mst->disableCallback = MenuSavvyGadgetRecord.disableCallback; mst->getAccelerator = MenuSavvyGadgetRecord.getAccelerator; mst->getMnemonic = MenuSavvyGadgetRecord.getMnemonic; } /* Install the new record */ XmeTraitSet((XtPointer) wc, XmQTmenuSavvy, (XtPointer) mst); } /************************************************************************ * * ClassPartInitialize * Processes the class fields which need to be inherited. * ************************************************************************/ static void ClassPartInitialize(WidgetClass cl) { register XmLabelGadgetClass wc = (XmLabelGadgetClass) cl; XmLabelGadgetClass super = (XmLabelGadgetClass)wc->rect_class.superclass; XmGadgetClassExt *wcePtr, *scePtr; if (wc->label_class.setOverrideCallback == XmInheritSetOverrideCallback) wc->label_class.setOverrideCallback = super->label_class.setOverrideCallback; if (wc->rect_class.resize == XmInheritResize) wc->rect_class.resize = super->rect_class.resize; wcePtr = _XmGetGadgetClassExtPtr(wc, NULLQUARK); scePtr = _XmGetGadgetClassExtPtr(super, NULLQUARK); if ((*wcePtr)->widget_baseline == XmInheritBaselineProc) (*wcePtr)->widget_baseline = (*scePtr)->widget_baseline; if ((*wcePtr)->widget_display_rect == XmInheritDisplayRectProc) (*wcePtr)->widget_display_rect = (*scePtr)->widget_display_rect; _XmFastSubclassInit (((WidgetClass)wc), XmLABEL_GADGET_BIT); /* Install transfer trait */ XmeTraitSet((XtPointer)cl, XmQTtransfer, (XtPointer) &LabelGTransfer); XmeTraitSet((XtPointer) cl, XmQTaccessTextual, (XtPointer) &_XmLabel_AccessTextualRecord); /* Install the careParentVisual trait for all subclasses as well. */ XmeTraitSet((XtPointer)cl, XmQTcareParentVisual, (XtPointer)&LabelGCVT); /* Install the accessColors trait for all subclasses as well. */ XmeTraitSet((XtPointer)cl, XmQTaccessColors, (XtPointer)&labACT); } /************************************************************************ * * SecondaryObjectCreate * ************************************************************************/ /*ARGSUSED*/ static void SecondaryObjectCreate(Widget req, Widget new_w, ArgList args, Cardinal *num_args) { XmBaseClassExt *cePtr; XmWidgetExtData extData; WidgetClass wc; Cardinal size; XtPointer newSec, reqSec; _XmProcessLock(); cePtr = _XmGetBaseClassExtPtr(XtClass(new_w), XmQmotif); wc = (*cePtr)->secondaryObjectClass; size = wc->core_class.widget_size; newSec = _XmExtObjAlloc(size); reqSec = _XmExtObjAlloc(size); _XmProcessUnlock(); /* * Update pointers in instance records now so references to resources * in the cache record will be valid for use in CallProcs. * CallProcs are invoked by XtGetSubresources(). */ LabG_Cache(new_w) = &(((XmLabelGCacheObject)newSec)->label_cache); LabG_Cache(req) = &(((XmLabelGCacheObject)reqSec)->label_cache); /* * Fetch the resources in superclass to subclass order */ XtGetSubresources(new_w, newSec, NULL, NULL, wc->core_class.resources, wc->core_class.num_resources, args, *num_args); extData = (XmWidgetExtData) XtCalloc(1, sizeof(XmWidgetExtDataRec)); extData->widget = (Widget)newSec; extData->reqWidget = (Widget)reqSec; ((XmLabelGCacheObject)newSec)->ext.extensionType = XmCACHE_EXTENSION; ((XmLabelGCacheObject)newSec)->ext.logicalParent = new_w; _XmPushWidgetExtData((Widget) new_w, extData, ((XmLabelGCacheObject)newSec)->ext.extensionType); memcpy(reqSec, newSec, size); } /************************************************************************ * * InitializePosthook * ************************************************************************/ /*ARGSUSED*/ static void InitializePosthook(Widget req, Widget new_w, ArgList args, Cardinal *num_args) { XmWidgetExtData ext; XmLabelGadget lw = (XmLabelGadget)new_w; /* * - register parts in cache. * - update cache pointers * - and free req */ _XmProcessLock(); LabG_Cache(lw) = (XmLabelGCacheObjPart *) _XmCachePart(LabG_ClassCachePart(lw), (XtPointer) LabG_Cache(lw), sizeof(XmLabelGCacheObjPart)); /* * Might want to break up into per-class work that gets explicitly * chained. For right now, each class has to replicate all * superclass logic in hook routine. */ /* * free the req subobject used for comparisons */ _XmPopWidgetExtData((Widget) lw, &ext, XmCACHE_EXTENSION); _XmExtObjFree((XtPointer)ext->widget); _XmExtObjFree((XtPointer)ext->reqWidget); _XmProcessUnlock(); XtFree((char *) ext); } /************************************************************************ * * SetValuesPrehook * ************************************************************************/ /*ARGSUSED*/ static Boolean SetValuesPrehook(Widget oldParent, Widget refParent, Widget newParent, ArgList args, Cardinal *num_args) { XmWidgetExtData extData; XmBaseClassExt *cePtr; WidgetClass ec; XmLabelGCacheObject newSec, reqSec; Cardinal size; _XmProcessLock(); cePtr = _XmGetBaseClassExtPtr(XtClass(newParent), XmQmotif); ec = (*cePtr)->secondaryObjectClass; size = ec->core_class.widget_size; newSec = (XmLabelGCacheObject)_XmExtObjAlloc(size); reqSec = (XmLabelGCacheObject)_XmExtObjAlloc(size); _XmProcessUnlock(); newSec->object.self = (Widget)newSec; newSec->object.widget_class = ec; newSec->object.parent = XtParent(newParent); newSec->object.xrm_name = newParent->core.xrm_name; newSec->object.being_destroyed = False; newSec->object.destroy_callbacks = NULL; newSec->object.constraints = NULL; newSec->ext.logicalParent = newParent; newSec->ext.extensionType = XmCACHE_EXTENSION; memcpy(&(newSec->label_cache), LabG_Cache(newParent), sizeof(XmLabelGCacheObjPart)); extData = (XmWidgetExtData) XtCalloc(1, sizeof(XmWidgetExtDataRec)); extData->widget = (Widget)newSec; extData->reqWidget = (Widget)reqSec; _XmPushWidgetExtData(newParent, extData, XmCACHE_EXTENSION); XtSetSubvalues((XtPointer)newSec, ec->core_class.resources, ec->core_class.num_resources, args, *num_args); _XmExtImportArgs((Widget)newSec, args, num_args); memcpy((XtPointer)reqSec, (XtPointer)newSec, size); LabG_Cache(newParent) = &((newSec)->label_cache); LabG_Cache(refParent) = &((reqSec)->label_cache); return FALSE; } /************************************************************************ * * GetValuesPrehook * ************************************************************************/ /*ARGSUSED*/ static void GetValuesPrehook(Widget newParent, ArgList args, Cardinal *num_args) { XmWidgetExtData extData; XmBaseClassExt *cePtr; WidgetClass ec; XmLabelGCacheObject newSec; Cardinal size; _XmProcessLock(); cePtr = _XmGetBaseClassExtPtr(XtClass(newParent), XmQmotif); ec = (*cePtr)->secondaryObjectClass; size = ec->core_class.widget_size; newSec = (XmLabelGCacheObject)_XmExtObjAlloc(size); _XmProcessUnlock(); newSec->object.self = (Widget)newSec; newSec->object.widget_class = ec; newSec->object.parent = XtParent(newParent); newSec->object.xrm_name = newParent->core.xrm_name; newSec->object.being_destroyed = False; newSec->object.destroy_callbacks = NULL; newSec->object.constraints = NULL; newSec->ext.logicalParent = newParent; newSec->ext.extensionType = XmCACHE_EXTENSION; memcpy(&(newSec->label_cache), LabG_Cache(newParent), sizeof(XmLabelGCacheObjPart)); extData = (XmWidgetExtData) XtCalloc(1, sizeof(XmWidgetExtDataRec)); extData->widget = (Widget)newSec; _XmPushWidgetExtData(newParent, extData, XmCACHE_EXTENSION); XtGetSubvalues((XtPointer)newSec, ec->core_class.resources, ec->core_class.num_resources, args, *num_args); _XmExtGetValuesHook((Widget)newSec, args, num_args); } /************************************************************************ * * GetValuesPosthook * ************************************************************************/ /*ARGSUSED*/ static void GetValuesPosthook(Widget new_w, ArgList args, Cardinal *num_args) { XmWidgetExtData ext; _XmPopWidgetExtData(new_w, &ext, XmCACHE_EXTENSION); _XmProcessLock(); _XmExtObjFree((XtPointer)ext->widget); _XmProcessUnlock(); XtFree((char *) ext); } /************************************************************************ * * SetValuesPosthook * ************************************************************************/ /*ARGSUSED*/ static Boolean SetValuesPosthook(Widget current, Widget req, Widget new_w, ArgList args, Cardinal *num_args) { XmWidgetExtData ext; /* * - register parts in cache. * - update cache pointers * - and free req */ /* assign if changed! */ _XmProcessLock(); if (!_XmLabelCacheCompare((XtPointer)LabG_Cache(new_w), (XtPointer)LabG_Cache(current))) { /* delete the old one */ _XmCacheDelete((XtPointer) LabG_Cache(current)); LabG_Cache(new_w) = (XmLabelGCacheObjPart *) _XmCachePart(LabG_ClassCachePart(new_w), (XtPointer) LabG_Cache(new_w), sizeof(XmLabelGCacheObjPart)); } else LabG_Cache(new_w) = LabG_Cache(current); _XmPopWidgetExtData(new_w, &ext, XmCACHE_EXTENSION); _XmExtObjFree((XtPointer)ext->widget); _XmExtObjFree((XtPointer)ext->reqWidget); XtFree((char *) ext); _XmProcessUnlock(); return FALSE; } static void BorderHighlight(Widget w) { XmLabelGadget lg = (XmLabelGadget) w; if (lg->rectangle.width == 0 || lg->rectangle.height == 0 || lg->gadget.highlight_thickness == 0) { return; } lg->gadget.highlighted = True; lg->gadget.highlight_drawn = True; /* CR 7330: Use XmeDrawHighlight, not _XmDrawHighlight. */ XmeDrawHighlight(XtDisplay((Widget) lg), XtWindow((Widget) lg), LabG_HighlightGC(lg), lg->rectangle.x, lg->rectangle.y, lg->rectangle.width, lg->rectangle.height, lg->gadget.highlight_thickness); } /************************************************************************ * * SetNormalGC * Create the normal and insensitive GC's for the gadget. * ************************************************************************/ static void SetNormalGC(XmLabelGadget lw) { XGCValues values; XtGCMask valueMask, dynamicMask; XmManagerWidget mw; XFontStruct *fs = (XFontStruct *) NULL; mw = (XmManagerWidget) XtParent(lw); valueMask = GCForeground | GCBackground | GCGraphicsExposures; dynamicMask = GCClipXOrigin | GCClipYOrigin | GCClipMask; values.foreground = LabG_Foreground(lw); values.background = LabG_Background(lw); values.graphics_exposures = FALSE; if (XmeRenderTableGetDefaultFont(LabG_Font(lw), &fs)) { valueMask |= GCFont; values.font = fs->fid; } LabG_NormalGC(lw) = XtAllocateGC((Widget) mw, 0, valueMask, &values, dynamicMask, 0); valueMask |= GCFillStyle | GCStipple; values.fill_style = FillOpaqueStippled; values.stipple = _XmGetInsensitiveStippleBitmap((Widget) lw); LabG_InsensitiveGC(lw) = XtAllocateGC((Widget) mw, 0, valueMask, &values, dynamicMask, 0); } /************************************************************************ * * _XmLabelSetBackgroundGC * Get the graphics context used for drawing the shadows. * ************************************************************************/ void _XmLabelSetBackgroundGC(XmLabelGadget lw) { XGCValues values; XtGCMask valueMask; XmManagerWidget mw; XFontStruct *fs = (XFontStruct *) NULL; mw = (XmManagerWidget) XtParent(lw); if (lw->label.fill_bg_box != _XmALWAYS_FILL_BG_BOX) { if ((mw->core.background_pixel != LabG_Background(lw)) && (mw->core.background_pixmap == XmUNSPECIFIED_PIXMAP)) lw->label.fill_bg_box = _XmFILL_BG_BOX; else lw->label.fill_bg_box = _XmPLAIN_BG_BOX; } valueMask = GCForeground | GCBackground | GCGraphicsExposures | GCClipMask; values.foreground = LabG_Background(lw); values.background = LabG_Foreground(lw); values.graphics_exposures = FALSE; values.clip_mask = None; /* CR 8980: Use parent's background_pixmap if possible. */ if (mw->core.background_pixmap != XmUNSPECIFIED_PIXMAP) { int depth; XmeGetPixmapData(XtScreen((Widget)lw), mw->core.background_pixmap, NULL, &depth, NULL, NULL, NULL, NULL, NULL, NULL); if (depth == 1) { valueMask |= GCFillStyle | GCStipple ; values.fill_style = FillOpaqueStippled; values.stipple = mw->core.background_pixmap; } else { valueMask |= GCFillStyle | GCTile ; values.fill_style = FillTiled; values.tile = mw->core.background_pixmap; } } if (XmeRenderTableGetDefaultFont(LabG_Font(lw), &fs)) { valueMask |= GCFont; values.font = fs->fid; } LabG_BackgroundGC(lw) = XtGetGC ((Widget) mw, valueMask, &values); } /************************************************************************ * * _XmCalcLabelGDimensions() * Calculates the dimensionsof the label text and pixmap, and updates * the TextRect fields appropriately. Called at Initialize and SetValues. * This is also called by the subclasses to recalculate label dimensions. * *************************************************************************/ void _XmCalcLabelGDimensions(Widget wid) { XmLabelGadget newlw = (XmLabelGadget) wid; unsigned int w = 0 , h = 0; /* initialize TextRect width and height to 0, reset if needed */ LabG_TextRect(newlw).width = 0; LabG_TextRect(newlw).height = 0; LabG_AccTextRect(newlw).width = 0; LabG_AccTextRect(newlw).height = 0; if (LabG_IsPixmap (newlw)) { if (XtIsSensitive(wid)) { if (Pix (newlw) != XmUNSPECIFIED_PIXMAP) { XmeGetPixmapData(XtScreen(newlw), Pix(newlw), NULL, NULL, NULL, NULL, NULL, NULL, &w, &h); LabG_TextRect(newlw).width = (unsigned short) w; LabG_TextRect(newlw).height = (unsigned short) h; } } else { Pixmap pix_use = Pix_insen (newlw) ; if (pix_use == XmUNSPECIFIED_PIXMAP) pix_use = Pix(newlw); if (pix_use != XmUNSPECIFIED_PIXMAP) { XmeGetPixmapData(XtScreen(newlw), pix_use, NULL, NULL, NULL, NULL, NULL, NULL, &w, &h); LabG_TextRect(newlw).width = (unsigned short) w; LabG_TextRect(newlw).height = (unsigned short) h; } } if (LabG__acceleratorText(newlw) != NULL) { /* If we have a string then size it. */ Dimension w,h; if (!XmStringEmpty (LabG__acceleratorText(newlw))) { XmStringExtent(LabG_Font(newlw), LabG__acceleratorText(newlw), &w, &h); LabG_AccTextRect(newlw).width = (unsigned short)w; LabG_AccTextRect(newlw).height = (unsigned short)h; } } } else if (LabG_IsText (newlw)) { Dimension w, h; /* If we have a string then size it. */ if (!XmStringEmpty (LabG__label(newlw))) { XmStringExtent (LabG_Font(newlw), LabG__label(newlw), &w, &h); LabG_TextRect(newlw).width = (unsigned short)w; LabG_TextRect(newlw).height = (unsigned short)h; } if (LabG__acceleratorText(newlw) != NULL) { /* If we have a string then size it. */ if (!XmStringEmpty (LabG__acceleratorText(newlw))) { XmStringExtent(LabG_Font(newlw), LabG__acceleratorText(newlw), &w, &h); LabG_AccTextRect(newlw).width = w; LabG_AccTextRect(newlw).height = h; } } } } /************************************************************************ * * Resize * Sets new width, new height, and new label.TextRect * appropriately. It is called by Initialize and SetValues. * ************************************************************************/ static void Resize(Widget wid) { XmLabelGadget newlw = (XmLabelGadget) wid; int leftx, rightx; /* increase margin width if necessary to accomodate accelerator text */ if (LabG__acceleratorText(newlw) != NULL) if (LayoutIsRtoLG(newlw)) { if (LabG_MarginLeft(newlw) < LabG_AccTextRect(newlw).width + LABELG_ACC_PAD) { int delta = LabG_AccTextRect(newlw).width + LABELG_ACC_PAD - LabG_MarginLeft(newlw); newlw->label.acc_left_delta += delta; LabG_MarginLeft(newlw) += delta; } } else { if (LabG_MarginRight(newlw) < LabG_AccTextRect(newlw).width + LABELG_ACC_PAD) { int delta = LabG_AccTextRect(newlw).width + LABELG_ACC_PAD - LabG_MarginRight(newlw); newlw->label.acc_right_delta += delta; LabG_MarginRight(newlw) += delta; } } /* Has a width been specified? */ if (newlw->rectangle.width == 0) newlw->rectangle.width = LabG_TextRect(newlw).width + LabG_MarginLeft(newlw) + LabG_MarginRight(newlw) + (2 * (LabG_MarginWidth(newlw) + newlw->gadget.highlight_thickness + newlw->gadget.shadow_thickness)); leftx = newlw->gadget.highlight_thickness + newlw->gadget.shadow_thickness + LabG_MarginWidth(newlw) + LabG_MarginLeft(newlw); rightx = newlw->rectangle.width - newlw->gadget.highlight_thickness - newlw->gadget.shadow_thickness - LabG_MarginWidth(newlw) - LabG_MarginRight(newlw); switch (LabG_Alignment(newlw)) { case XmALIGNMENT_BEGINNING: if (LayoutIsRtoLG(newlw)) LabG_TextRect(newlw).x = rightx - LabG_TextRect(newlw).width; else LabG_TextRect(newlw).x = leftx; break; case XmALIGNMENT_END: if (LayoutIsRtoLG(newlw)) LabG_TextRect(newlw).x = leftx; else LabG_TextRect(newlw).x = rightx - LabG_TextRect(newlw).width; break; default: /* XmALIGNMENT_CENTER */ LabG_TextRect(newlw).x = leftx + (rightx - leftx - (int)LabG_TextRect(newlw).width) / 2; break; } /* Has a height been specified? */ if (newlw->rectangle.height == 0) newlw->rectangle.height = MAX(LabG_TextRect(newlw).height, LabG_AccTextRect(newlw).height) + LabG_MarginTop(newlw) + LabG_MarginBottom(newlw) + (2 * (LabG_MarginHeight(newlw) + newlw->gadget.highlight_thickness + newlw->gadget.shadow_thickness)); LabG_TextRect(newlw).y = (short) (newlw->gadget.highlight_thickness + newlw->gadget.shadow_thickness + LabG_MarginHeight(newlw) + LabG_MarginTop(newlw) + ((int) (newlw->rectangle.height - LabG_MarginTop(newlw) - LabG_MarginBottom(newlw) - (2 * (LabG_MarginHeight(newlw) + newlw->gadget.highlight_thickness + newlw->gadget.shadow_thickness)) - LabG_TextRect(newlw).height) / 2)); if (LabG__acceleratorText(newlw) != NULL) { Dimension base_label, base_accText, diff; if (LayoutIsRtoLG(newlw)) LabG_AccTextRect(newlw).x = newlw->rectangle .x + (newlw->gadget.highlight_thickness + newlw->gadget.shadow_thickness + LabG_MarginWidth(newlw)); else LabG_AccTextRect(newlw).x = (newlw->rectangle.width - newlw->gadget.highlight_thickness - newlw->gadget.shadow_thickness - LabG_MarginWidth(newlw) - LabG_MarginRight(newlw) + LABELG_ACC_PAD); LabG_AccTextRect(newlw).y = newlw->gadget.highlight_thickness + newlw->gadget.shadow_thickness + LabG_MarginHeight(newlw) + LabG_MarginTop(newlw) + ((int) (newlw->rectangle.height - LabG_MarginTop(newlw) - LabG_MarginBottom(newlw) - (2 * (LabG_MarginHeight(newlw) + newlw->gadget.highlight_thickness + newlw->gadget.shadow_thickness)) - LabG_AccTextRect(newlw).height) / 2); /* make sure the label and accelerator text line up */ /* when the fonts are different */ if (LabG_IsText (newlw)) { base_label = XmStringBaseline (LabG_Font(newlw), LabG__label(newlw)); base_accText = XmStringBaseline (LabG_Font(newlw), LabG__acceleratorText(newlw)); if (base_label > base_accText) { diff = base_label - base_accText; LabG_AccTextRect(newlw).y = LabG_TextRect(newlw).y + diff - 1; } else if (base_label < base_accText) { diff = base_accText - base_label; LabG_TextRect(newlw).y = LabG_AccTextRect(newlw).y + diff - 1; } } } /* Set core dimensions so we don't get a Toolkit error. */ if (newlw->rectangle.width == 0) newlw->rectangle.width = 1; if (newlw->rectangle.height == 0) newlw->rectangle.height = 1; } /************************************************************************ * * Initialize * This is the widget's instance initialize routine. It is * called once for each widget. * Changes: Treat label, pixmap, labeltype, mnemoniccharset as independently * setable resource. ************************************************************************/ /*ARGSUSED*/ static void Initialize(Widget req, Widget new_w, ArgList args, Cardinal *num_args) { XmMenuSystemTrait menuSTrait; XmLabelGadget lw = (XmLabelGadget) new_w; XmLabelGadget rw = (XmLabelGadget) req; lw->label.baselines = NULL; /* Before doing anything with the pixmap, check if we have to * re-ask for a conversion */ if (Pix (new_w) == XmDELAYED_PIXMAP) { /* This test means that a conversion was asked for * but failed because the colors were not accessible * prior to Initialize, because the cache wasn't there yet. * We have to try again from here. */ XtGetSubresources(new_w, new_w, NULL, NULL, label_pixmap_resource, 1, args, *num_args); } if (Pix_insen (new_w) == XmDELAYED_PIXMAP) { XtGetSubresources(new_w, new_w, NULL, NULL, label_pixmap_insen_resource, 1, args, *num_args); } /* If menuProcs is not set up yet, try again */ _XmProcessLock(); if (xmLabelGadgetClassRec.label_class.menuProcs == NULL) xmLabelGadgetClassRec.label_class.menuProcs = (XmMenuProc) _XmGetMenuProcContext(); _XmProcessUnlock(); LabG_SkipCallback(new_w) = FALSE; /* Check for Invalid enumerated types */ if (!XmRepTypeValidValue(XmRID_LABEL_TYPE, LabG_LabelType(new_w), new_w)) LabG_LabelType(new_w) = XmSTRING; if (!XmRepTypeValidValue(XmRID_ALIGNMENT, LabG_Alignment(new_w), new_w)) LabG_Alignment(new_w) = XmALIGNMENT_CENTER; #ifndef NO_XM_1_2_BC /* * Some pre-Motif 2.0 XmManager subclasses may be bypassing the * synthetic resouce GetValues hook and passing us the manager's raw * string_direction field (which is now a layout_direction). Fixup * the common/simple cases. */ switch (LabG_StringDirection(lw)) { case XmLEFT_TO_RIGHT: case XmRIGHT_TO_LEFT: /* These string directions are erroneous uses of layout directions. */ LabG_StringDirection(lw) = XmDirectionToStringDirection(LabG_StringDirection(lw)); break; default: /* Other unknown layout directions will still get a warning. */ break; } #endif /* If layout_direction is set, it overrides string_direction. * If string_direction is set, but not layout_direction, use * string_direction value. * If neither is set, get from parent. */ if (lw->gadget.layout_direction != XmDEFAULT_DIRECTION) { if (LabG_StringDirection(lw) == XmDEFAULT_DIRECTION) LabG_StringDirection(lw) = XmDirectionToStringDirection(lw->gadget.layout_direction); } else if (LabG_StringDirection(lw) != XmDEFAULT_DIRECTION) { lw->gadget.layout_direction = XmStringDirectionToDirection(LabG_StringDirection(lw)); } else { lw->gadget.layout_direction = _XmGetLayoutDirection(XtParent(new_w)); LabG_StringDirection(lw) = XmDirectionToStringDirection(lw->gadget.layout_direction); } if (!XmRepTypeValidValue(XmRID_STRING_DIRECTION, LabG_StringDirection(new_w), new_w)) LabG_StringDirection(new_w) = XmSTRING_DIRECTION_L_TO_R; /* Make a local copy of the font list */ if (LabG_Font(new_w) == NULL) { /* CR 2990: Let subclasses choose their own default font. */ LabG_Font(new_w) = XmeGetDefaultRenderTable (new_w, XmLABEL_FONTLIST); } LabG_Font(new_w) = XmFontListCopy(LabG_Font(new_w)); menuSTrait = (XmMenuSystemTrait) XmeTraitGet((XtPointer) XtClass((Widget) XtParent(new_w)), XmQTmenuSystem); if (menuSTrait != (XmMenuSystemTrait) NULL) LabG_MenuType(new_w) = menuSTrait->type(XtParent(new_w)); else LabG_MenuType(new_w) = XmWORK_AREA; /* Handle the label string : * If no label string is given accept widget's name as default. * convert the widgets name to an XmString before storing; * else * save a copy of the given string. * If the given string is not an XmString issue an warning. */ if (LabG__label(new_w) == NULL) { LabG__label(new_w) = XmeGetLocalizedString ((char *) NULL, /* reserved */ (Widget) lw, XmNlabelString, XrmQuarkToString(lw->object.xrm_name)); } else if (XmeStringIsValid((XmString) LabG__label(new_w))) { LabG__label(new_w) = XmStringCopy((XmString) LabG__label(new_w)); } else { XmeWarning((Widget) lw, CS_STRING_MESSAGE); LabG__label(new_w) = XmStringCreateLocalized(XrmQuarkToString(lw->object.xrm_name)); } /* * Convert the given mnemonicCharset to the internal Xm-form. */ if (LabG_MnemonicCharset(new_w) != NULL) { LabG_MnemonicCharset (new_w) = _XmStringCharsetCreate (LabG_MnemonicCharset (new_w)); } else LabG_MnemonicCharset (new_w) = _XmStringCharsetCreate (XmFONTLIST_DEFAULT_TAG); /* Accelerators are currently only supported in menus */ if ((LabG__acceleratorText(new_w) != NULL) && LabG_IsMenupane(new_w)) { if (XmeStringIsValid((XmString) LabG__acceleratorText(new_w))) { /* Copy the input string into local space if not a Cascade Button. */ if (XmIsCascadeButtonGadget(new_w)) LabG__acceleratorText(new_w) = NULL; else LabG__acceleratorText(new_w)= XmStringCopy((XmString) LabG__acceleratorText(new_w)); } else { XmeWarning((Widget) lw, ACC_MESSAGE); LabG__acceleratorText(new_w) = NULL; } } else LabG__acceleratorText(new_w) = NULL; if ((LabG_Accelerator(new_w) != NULL) && LabG_IsMenupane(new_w)) { /* Copy the accelerator into local space */ LabG_Accelerator(lw) = XtNewString(LabG_Accelerator(new_w)); } else LabG_Accelerator(lw) = NULL; LabG_SkipCallback(lw) = FALSE; lw->label.acc_left_delta = 0; lw->label.acc_right_delta = 0; /* If zero width and height was requested by the application, */ /* reset new's width and height to zero to allow Resize() */ /* to operate properly. */ if (rw->rectangle.width == 0) lw->rectangle.width = 0; if (rw->rectangle.height == 0) lw->rectangle.height = 0; /* CR 6267: Suppress highlight thickness before sizing also. */ if ((LabG_MenuType(new_w) == XmMENU_POPUP) || (LabG_MenuType(new_w) == XmMENU_PULLDOWN) || (LabG_MenuType(new_w) == XmMENU_BAR)) lw->gadget.highlight_thickness = 0; _XmCalcLabelGDimensions(new_w); /* CR 7283: Can't use the resize method pointer here because */ /* subclasses haven't been initialized. */ Resize((Widget) lw); DealWithColors(lw); DealWithPixmaps(lw); /* Initialize only; set properly in _XmLabelSetBackgroundGC(). */ lw->label.fill_bg_box = _XmPLAIN_BG_BOX; SetNormalGC(lw); _XmLabelSetBackgroundGC (lw); LabG_HighlightGC(lw) = _XmGetPixmapBasedGC (XtParent(new_w), LabG_HighlightColor(lw), LabG_Background(lw), LabG_HighlightPixmap(lw)); LabG_TopShadowGC(lw) = _XmGetPixmapBasedGC (XtParent(new_w), LabG_TopShadowColor(lw), LabG_Background(lw), LabG_TopShadowPixmap(lw)); LabG_BottomShadowGC(lw) = _XmGetPixmapBasedGC (XtParent(new_w), LabG_BottomShadowColor(lw), LabG_Background(lw), LabG_BottomShadowPixmap(lw)); /* Force the label traversal flag when in a menu */ if ((XtClass(lw) == xmLabelGadgetClass) && ((LabG_MenuType(new_w) == XmMENU_POPUP) || (LabG_MenuType(new_w) == XmMENU_PULLDOWN) || (LabG_MenuType(new_w) == XmMENU_OPTION))) { lw->gadget.traversal_on = False; lw->gadget.highlight_on_enter = False; } /* Initialize the interesting input types. */ lw->gadget.event_mask = XmHELP_EVENT | XmFOCUS_IN_EVENT | XmFOCUS_OUT_EVENT | XmENTER_EVENT | XmLEAVE_EVENT | XmBDRAG_EVENT; } /* * DealWithColors * Deal with compatibility. */ static void DealWithColors(XmLabelGadget lw) { XmManagerWidget mw = (XmManagerWidget) XtParent(lw); /* * 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 ((LabG_Background(lw) == INVALID_PIXEL || LabG_Background(lw) == mw->core.background_pixel) && (LabG_Foreground(lw) == INVALID_PIXEL || LabG_Foreground(lw) == mw->manager.foreground) && (LabG_TopShadowColor(lw) == INVALID_PIXEL || LabG_TopShadowColor(lw) == mw->manager.top_shadow_color) && (LabG_BottomShadowColor(lw) == INVALID_PIXEL || LabG_BottomShadowColor(lw) == mw->manager.bottom_shadow_color) && (LabG_HighlightColor(lw) == INVALID_PIXEL || LabG_HighlightColor(lw) == mw->manager.highlight_color)) { LabG_Background(lw) = mw->core.background_pixel; LabG_Foreground(lw) = mw->manager.foreground; LabG_TopShadowColor(lw) = mw->manager.top_shadow_color; LabG_BottomShadowColor(lw) = mw->manager.bottom_shadow_color; LabG_HighlightColor(lw) = mw->manager.highlight_color; } else { InitNewColorBehavior(lw); } } /* * InitNewColorBehavior * Initialize colors like a widget. These are CallProcs so * they should be called with a correct offset. However offset * isn't used by these functions. Even so I supply offset. * You make the call. */ static void InitNewColorBehavior(XmLabelGadget lw) { XrmValue value; value.size = sizeof(Pixel); if (LabG_Background(lw) == INVALID_PIXEL) { _XmBackgroundColorDefault ((Widget) lw, XtOffsetOf(struct _XmLabelGCacheObjRec, label_cache.background), &value); memcpy((char*) &LabG_Background(lw), value.addr, value.size); } if (LabG_Foreground(lw) == INVALID_PIXEL) { _XmForegroundColorDefault ((Widget) lw, XtOffsetOf(struct _XmLabelGCacheObjRec, label_cache.foreground), &value); memcpy((char*) &LabG_Foreground(lw), value.addr, value.size); } if (LabG_TopShadowColor(lw) == INVALID_PIXEL) { _XmTopShadowColorDefault ((Widget) lw, XtOffsetOf(struct _XmLabelGCacheObjRec, label_cache.top_shadow_color), &value); memcpy((char*) &LabG_TopShadowColor(lw), value.addr, value.size); } if (LabG_BottomShadowColor(lw) == INVALID_PIXEL) { _XmBottomShadowColorDefault ((Widget) lw, XtOffsetOf(struct _XmLabelGCacheObjRec, label_cache.bottom_shadow_color), &value); memcpy((char*) &LabG_BottomShadowColor(lw), value.addr, value.size); } if (LabG_HighlightColor(lw) == INVALID_PIXEL) { _XmHighlightColorDefault ((Widget) lw, XtOffsetOf(struct _XmLabelGCacheObjRec, label_cache.highlight_color), &value); memcpy((char*) &LabG_HighlightColor(lw), 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(XmLabelGadget lw) { XmManagerWidget mw = (XmManagerWidget) XtParent(lw); if ((LabG_TopShadowPixmap(lw) == INVALID_PIXMAP || LabG_TopShadowPixmap(lw) == mw->manager.top_shadow_pixmap) && (LabG_HighlightPixmap(lw) == INVALID_PIXMAP || LabG_HighlightPixmap(lw) == mw->manager.highlight_pixmap)) { LabG_TopShadowPixmap(lw) = mw->manager.top_shadow_pixmap; LabG_HighlightPixmap(lw) = mw->manager.highlight_pixmap; } else { InitNewPixmapBehavior(lw); } } /* * InitNewPixmapBehavior * Initialize colors like a widget. */ static void InitNewPixmapBehavior(XmLabelGadget lw) { if (LabG_TopShadowPixmap(lw) == INVALID_PIXMAP) LabG_TopShadowColor(lw) = GetTopShadowPixmapDefault((Widget)lw); if (LabG_HighlightPixmap(lw) == INVALID_PIXMAP) LabG_HighlightPixmap(lw) = GetLabelHighlightPixmapDefault((Widget)lw); } /************************************************************************ * * QueryGeometry * ************************************************************************/ static XtGeometryResult QueryGeometry(Widget wid, XtWidgetGeometry *intended, XtWidgetGeometry *reply) { XmLabelGadget lg = (XmLabelGadget) wid; reply->request_mode = 0; /* Don't really know what to do with queries about x,y,border,stacking. * Since we are interpreting unset bits as a request for information * (asking about neither height or width does the old 0-0 request) * a caller asking about x,y should not get back width and height, * especially since it is an expensive operation. So x, y, border, stack * all return No, this indicates we'd prefer to remain as is. Parent * is free to change it anyway... */ if (GMode(intended) & ~(CWWidth | CWHeight)) return XtGeometryNo; if (LabG_RecomputeSize(lg) == FALSE) return XtGeometryNo; /* pre-load the reply with input values */ reply->request_mode = (CWWidth | CWHeight); reply->width = LabG_TextRect(lg).width + (2 * (LabG_MarginWidth(lg) + lg->gadget.highlight_thickness + lg->gadget.shadow_thickness)) + LabG_MarginLeft(lg) + LabG_MarginRight(lg); if (reply->width == 0) reply->width = 1; reply->height = MAX(LabG_TextRect(lg).height, LabG_AccTextRect(lg).height) + (2 * (LabG_MarginHeight(lg) + lg->gadget.highlight_thickness + lg->gadget.shadow_thickness)) + LabG_MarginTop(lg) + LabG_MarginBottom(lg); if (reply->height == 0) reply->height = 1; if ((IsWidth(intended) && (reply->width != intended->width)) || (IsHeight(intended) && (reply->height != intended->height)) || (GMode(intended) != GMode(reply))) { return XtGeometryAlmost; } else { reply->request_mode = 0; return XtGeometryYes; } } /************************************************************************ * * Destroy * Free up the label gadget allocated space. This includes * the label, and GC's. * ************************************************************************/ static void Destroy(Widget w) { if (LabG__label(w) != NULL) XmStringFree (LabG__label(w)); if (LabG__acceleratorText(w) != NULL) XmStringFree (LabG__acceleratorText(w)); XtFree (LabG_Accelerator(w)); if (LabG_Font(w) != NULL) XmFontListFree (LabG_Font(w)); XtFree (LabG_MnemonicCharset (w)); XtFree ((char*) ((XmLabelGadget)w)->label.baselines); XtReleaseGC (XtParent(w), LabG_NormalGC(w)); XtReleaseGC (XtParent(w), LabG_InsensitiveGC(w)); XtReleaseGC (XtParent(w), LabG_BackgroundGC(w)); XtReleaseGC (XtParent(w), LabG_HighlightGC(w)); XtReleaseGC (XtParent(w), LabG_TopShadowGC(w)); XtReleaseGC (XtParent(w), LabG_BottomShadowGC(w)); /* CR 6571: Free cache *after* making all references. */ _XmProcessLock(); _XmCacheDelete((XtPointer) LabG_Cache(w)); _XmProcessUnlock(); } /*ARGSUSED*/ static void LabelDrawBackground(Widget wid, XEvent *event, /* unused */ Region region, /* unused */ LRectangle *background_box) { XmLabelGadget lw = (XmLabelGadget) wid; switch (lw->label.fill_bg_box) { case _XmPLAIN_BG_BOX: return; case _XmFILL_BG_BOX: case _XmALWAYS_FILL_BG_BOX: default: break; } /* * Background_box is a parameter because subclasses like * PushBG and ToggleBG need to be able to adjust this rectangle. */ if (background_box->width < 0) background_box->width = 0; if (background_box->height < 0) background_box->height = 0; XFillRectangle(XtDisplay(lw), XtWindow((Widget) lw), LabG_BackgroundGC(lw), background_box->x, background_box->y, background_box->width, background_box->height); } /************************************************************************ * * Redisplay * ************************************************************************/ static void Redisplay(Widget wid, XEvent *event, Region region) { XmLabelGadget lw = (XmLabelGadget) wid; LRectangle background_box; background_box.x = lw->rectangle.x + LabG_Highlight(lw); background_box.y = lw->rectangle.y + LabG_Highlight(lw); background_box.width = lw->rectangle.width - (2 * LabG_Highlight(lw)); background_box.height = lw->rectangle.height - (2 * LabG_Highlight(lw)); _XmRedisplayLabG(wid, event, region, &background_box); } void _XmRedisplayLabG(Widget wid, XEvent *event, Region region, LRectangle *background_box) { XmLabelGadget lw = (XmLabelGadget) wid; GC gc; GC clipgc = NULL; XRectangle clip_rect; Dimension availW, availH, marginal_width, marginal_height, max_text_height; if (!XtIsRealized(wid)) return ; if (LabG_IsMenupane(lw)) { ShellWidget mshell = (ShellWidget) XtParent(XtParent(lw)); if (! mshell->shell.popped_up) return; } availH = lw->rectangle.height; availW = lw->rectangle.width; /* * Don't count MarginWidth to be consistent with Label Widget. * * Adjust definitions of temporary variables */ marginal_width = LabG_MarginLeft(lw) + LabG_MarginRight(lw) + (2 * (lw->gadget.highlight_thickness + lw->gadget.shadow_thickness)); marginal_height = LabG_MarginTop(lw) + LabG_MarginBottom(lw) + (2 * (lw->gadget.highlight_thickness + lw->gadget.shadow_thickness)); max_text_height = MAX(LabG_TextRect(lw).height, LabG_AccTextRect(lw).height); if (XtIsSensitive(wid)) clipgc = LabG_NormalGC(lw); else clipgc = LabG_InsensitiveGC(lw); /* Clip should include critical margins (see Label.c) */ if (availH < (marginal_height + max_text_height) || availW < (marginal_width + LabG_TextRect(lw).width)) { clip_rect.x = lw->rectangle.x + lw->gadget.highlight_thickness + lw->gadget.shadow_thickness + LabG_MarginLeft(lw); clip_rect.y = lw->rectangle.y + lw->gadget.highlight_thickness + lw->gadget.shadow_thickness + LabG_MarginTop(lw); /* Don't allow negative dimensions */ if (availW > marginal_width) clip_rect.width = availW - marginal_width; else clip_rect.width = 0; if (availH > marginal_height) clip_rect.height = availH - marginal_height; else clip_rect.height = 0; XSetClipRectangles(XtDisplay(lw), clipgc, 0,0, &clip_rect, 1, Unsorted); } else XSetClipMask (XtDisplay (lw), clipgc, None); /* Draw the pixmap or text */ if (LabG_IsPixmap(lw)) { int depth; LabelDrawBackground((Widget)lw, event, region, background_box); if (XtIsSensitive(wid)) { if (Pix (lw) != XmUNSPECIFIED_PIXMAP) { gc = LabG_NormalGC(lw); XmeGetPixmapData(XtScreen(lw), Pix(lw), NULL, &depth, NULL, NULL, NULL, NULL, NULL, NULL); if (depth == XtParent(lw)->core.depth) XCopyArea (XtDisplay(lw), Pix(lw), XtWindow(lw), gc, 0, 0, LabG_TextRect(lw).width, LabG_TextRect(lw).height, lw->rectangle.x + LabG_TextRect(lw).x, lw->rectangle.y + LabG_TextRect(lw).y); else if (depth == 1) XCopyPlane (XtDisplay(lw), Pix(lw), XtWindow(lw), gc, 0, 0, LabG_TextRect(lw).width, LabG_TextRect(lw).height, lw->rectangle.x + LabG_TextRect(lw).x, lw->rectangle.y + LabG_TextRect(lw).y, 1); } } else { Pixmap pix_use = Pix_insen (lw) ; if (pix_use == XmUNSPECIFIED_PIXMAP) pix_use = Pix(lw); if (pix_use != XmUNSPECIFIED_PIXMAP) { gc = LabG_InsensitiveGC(lw); XmeGetPixmapData(XtScreen(lw), pix_use, NULL, &depth, NULL, NULL, NULL, NULL, NULL, NULL); if (depth == XtParent(lw)->core.depth) XCopyArea (XtDisplay(lw), pix_use, XtWindow(lw), gc, 0, 0, LabG_TextRect(lw).width, LabG_TextRect(lw).height, lw->rectangle.x + LabG_TextRect(lw).x, lw->rectangle.y + LabG_TextRect(lw).y); else if (depth == 1) XCopyPlane (XtDisplay(lw), pix_use, XtWindow(lw), gc, 0, 0, LabG_TextRect(lw).width, LabG_TextRect(lw).height, lw->rectangle.x + LabG_TextRect(lw).x, lw->rectangle.y + LabG_TextRect(lw).y, 1); /* if no insensitive pixmap but a regular one, we need to do the stipple manually, since copyarea doesn't */ if (pix_use == Pix(lw)) { /* need fill stipple, not opaque */ XSetFillStyle(XtDisplay(lw), gc, FillStippled); XFillRectangle(XtDisplay(lw), XtWindow(lw), gc, lw->rectangle.x + LabG_TextRect(lw).x, lw->rectangle.y + LabG_TextRect(lw).y, LabG_TextRect(lw).width, LabG_TextRect(lw).height); XSetFillStyle(XtDisplay(lw), gc, FillOpaqueStippled); } } } } else if ((LabG_IsText (lw)) && (LabG__label(lw) != NULL)) { LabelDrawBackground((Widget)lw, event, region, background_box); if (LabG_Mnemonic(lw) != XK_VoidSymbol) { /* CR 5181: Convert the mnemonic keysym to a character string. */ char tmp[MB_LEN_MAX * 2]; XmString underline; tmp[_XmOSKeySymToCharacter(LabG_Mnemonic(lw), NULL, tmp)] = '\0'; underline = XmStringCreate(tmp, LabG_MnemonicCharset(lw)); XmStringDrawUnderline(XtDisplay(lw), XtWindow(lw), LabG_Font(lw), LabG__label(lw), (XtIsSensitive(wid) ? LabG_NormalGC(lw) : LabG_InsensitiveGC(lw)), lw->rectangle.x + LabG_TextRect(lw).x, lw->rectangle.y + LabG_TextRect(lw).y, LabG_TextRect(lw).width, LabG_Alignment(lw), LayoutG(lw), NULL, underline); XmStringFree(underline); } else XmStringDraw (XtDisplay(lw), XtWindow(lw), LabG_Font(lw), LabG__label(lw), (XtIsSensitive(wid) ? LabG_NormalGC(lw) : LabG_InsensitiveGC(lw)), lw->rectangle.x + LabG_TextRect(lw).x, lw->rectangle.y + LabG_TextRect(lw).y, LabG_TextRect(lw).width, LabG_Alignment(lw), LayoutG(lw), NULL); } if (LabG__acceleratorText(lw) != NULL) { /* Since accelerator text is drawn by moving in from the right, * it is possible to overwrite label text when there is clipping, * Therefore draw accelerator text only if there is enough * room for everything */ if ((lw->rectangle.width) >= (2 * (lw->gadget.highlight_thickness + lw->gadget.shadow_thickness + LabG_MarginWidth(lw)) + LabG_MarginLeft(lw) + LabG_TextRect(lw).width + LabG_MarginRight(lw))) { XmStringDraw (XtDisplay(lw), XtWindow(lw), LabG_Font(lw), LabG__acceleratorText(lw), (XtIsSensitive(wid) ? LabG_NormalGC(lw) : LabG_InsensitiveGC(lw)), lw->rectangle.x + LabG_AccTextRect(lw).x, lw->rectangle.y + LabG_AccTextRect(lw).y, LabG_AccTextRect(lw).width, XmALIGNMENT_END, LayoutG(lw), NULL); } } /* Redraw the proper highlight */ if (! LabG_IsMenupane(lw) && LabG_MenuType(lw) != XmMENU_BAR) { if (lw->gadget.highlighted) { (*((XmGadgetClass) XtClass(lw))->gadget_class.border_highlight) ((Widget) lw); } } } /************************************************************************ * * SetValues * This routine will take care of any changes that have been made * ************************************************************************/ /*ARGSUSED*/ static Boolean SetValues(Widget cw, Widget rw, Widget nw, ArgList args, /* unused */ Cardinal *num_args) /* unused */ { XmLabelGadget current = (XmLabelGadget) cw; XmLabelGadget req = (XmLabelGadget) rw; XmLabelGadget new_w = (XmLabelGadget) nw; Boolean flag = False; Boolean newstring = False; Boolean ProcessFlag = FALSE; Boolean CleanupFontFlag = FALSE; Boolean Call_Resize = False; XmMenuSystemTrait menuSTrait; /* Invalidate the basline cache if necessary. */ if ((LabG__label(new_w) != LabG__label(current)) || (LabG_Font(new_w) != LabG_Font(current))) { if (new_w->label.baselines) { XtFree ((char*) new_w->label.baselines); new_w->label.baselines = NULL; } } /* If the label has changed, make a copy of the new label, */ /* and free the old label. */ if (LabG__label(new_w)!= LabG__label(current)) { newstring = True; if (LabG__label(new_w) == NULL) { LabG__label(new_w) = XmStringCreateLocalized(XrmQuarkToString (current->object.xrm_name)); } else { if (XmeStringIsValid((XmString) LabG__label(new_w))) { LabG__label(new_w) = XmStringCopy((XmString) LabG__label(new_w)); } else { XmeWarning((Widget) new_w, CS_STRING_MESSAGE); LabG__label(new_w) = XmStringCreateLocalized(XrmQuarkToString(new_w->object.xrm_name)); } } XmStringFree(LabG__label(current)); LabG__label(current)= NULL; LabG__label(req)= NULL; } if (LabG_MarginRight(new_w) != LabG_MarginRight(current)) new_w->label.acc_right_delta = 0; if (LabG_MarginLeft(new_w) != LabG_MarginLeft(current)) new_w->label.acc_left_delta = 0; if ((LabG__acceleratorText(new_w) != LabG__acceleratorText(current)) && LabG_IsMenupane(new_w)) { /* BEGIN OSF Fix pir 1098 */ newstring = TRUE; /* END OSF Fix pir 1098 */ if (LabG__acceleratorText(new_w) != NULL) { if (XmeStringIsValid((XmString) LabG__acceleratorText(new_w))) { if ((XmIsCascadeButtonGadget(new_w)) && (LabG__acceleratorText(new_w) != NULL)) LabG__acceleratorText(new_w) = NULL; else LabG__acceleratorText(new_w) = XmStringCopy(LabG__acceleratorText(new_w)); XmStringFree(LabG__acceleratorText(current)); LabG__acceleratorText(current)= NULL; LabG__acceleratorText(req)= NULL; } else { XmeWarning((Widget) new_w, ACC_MESSAGE); LabG__acceleratorText(new_w) = NULL; XmStringFree(LabG__acceleratorText(current)); LabG__acceleratorText(current)= NULL; LabG__acceleratorText(req)= NULL; } } /* BEGIN OSF Fix pir 1098 */ else if (LabG__acceleratorText(current)) { /* CR 3481: Don't blindly force the margin back to 0; */ /* try to preserve the user specified value. */ if (LayoutIsRtoLG(new_w)) { LabG_MarginLeft(new_w) -= new_w->label.acc_left_delta; new_w->label.acc_left_delta = 0; } else { LabG_MarginRight(new_w) -= new_w->label.acc_right_delta; new_w->label.acc_right_delta = 0; } } /* END OSF Fix pir 1098 */ } else LabG__acceleratorText(new_w) = LabG__acceleratorText(current); if (LabG_Font(new_w) != LabG_Font(current)) { CleanupFontFlag = True; if (LabG_Font(new_w) == NULL) { /* CR 2990: let subclasses pick their own default fonts. */ LabG_Font(new_w) = XmeGetDefaultRenderTable((Widget) new_w, XmLABEL_FONTLIST); } LabG_Font(new_w) = XmFontListCopy (LabG_Font(new_w)); } /* Reinitialize the interesting input types. */ new_w->gadget.event_mask = XmHELP_EVENT; new_w->gadget.event_mask |= XmFOCUS_IN_EVENT | XmFOCUS_OUT_EVENT | XmENTER_EVENT | XmLEAVE_EVENT | XmBDRAG_EVENT; if ((LabG_MenuType(new_w) == XmMENU_POPUP) || (LabG_MenuType(new_w) == XmMENU_PULLDOWN) || (LabG_MenuType(new_w) == XmMENU_BAR)) new_w->gadget.highlight_thickness = 0; if (!XmRepTypeValidValue(XmRID_LABEL_TYPE, LabG_LabelType(new_w), (Widget) new_w)) { LabG_LabelType(new_w) = LabG_LabelType(current); } if (LayoutG(new_w) != LayoutG(current)) { /* If no new margins specified swap them */ if ((LayoutIsRtoLG(current) != LayoutIsRtoLG(new_w)) && (LabG_MarginLeft(current) == LabG_MarginLeft(new_w)) && (LabG_MarginRight(current) == LabG_MarginRight(new_w))) { LabG_MarginLeft(new_w) = LabG_MarginRight(current); LabG_MarginRight(new_w) = LabG_MarginLeft(current); } flag = TRUE; } /* ValidateInputs(new_w); */ if ((LabG_IsText(new_w) && (newstring || (LabG_Font(new_w) != LabG_Font(current)))) || (LabG_IsPixmap(new_w) && ((LabG_Pixmap(new_w) != LabG_Pixmap(current)) || (LabG_PixmapInsensitive(new_w) != LabG_PixmapInsensitive(current)) || /* When you have different sized pixmaps for sensitive and */ /* insensitive states and sensitivity changes, */ /* the right size is chosen. (osfP2560) */ (XtIsSensitive(nw) != XtIsSensitive(cw)))) || (LabG_LabelType(new_w) != LabG_LabelType(current))) { /* CR 9179: back out CR 5419 changes. */ _XmCalcLabelGDimensions((Widget) new_w); if (LabG_RecomputeSize(new_w)) { if (req->rectangle.width == current->rectangle.width) new_w->rectangle.width = 0; if (req->rectangle.height == current->rectangle.height) new_w->rectangle.height = 0; } Call_Resize = True; flag = True; } if ((LabG_Alignment(new_w)!= LabG_Alignment(current)) || (LayoutG(new_w) != LayoutG(current))) { if (!XmRepTypeValidValue(XmRID_ALIGNMENT, LabG_Alignment(new_w), (Widget) new_w)) { LabG_Alignment(new_w) = LabG_Alignment(current); } Call_Resize = True; flag = True; } if ((LabG_MarginHeight(new_w) != LabG_MarginHeight(current)) || (LabG_MarginWidth(new_w) != LabG_MarginWidth(current)) || (LabG_MarginRight(new_w) != LabG_MarginRight(current)) || (LabG_MarginLeft(new_w)!= LabG_MarginLeft(current)) || (LabG_MarginTop(new_w)!= LabG_MarginTop(current)) || (LabG_MarginBottom(new_w)!= LabG_MarginBottom(current)) || (new_w->gadget.shadow_thickness != current->gadget.shadow_thickness) || (new_w->gadget.highlight_thickness != current->gadget.highlight_thickness) || ((new_w->rectangle.width <= 0) || (new_w->rectangle.height <= 0))) { if (LabG_RecomputeSize(new_w)) { if (req->rectangle.width == current->rectangle.width) new_w->rectangle.width = 0; if (req->rectangle.height == current->rectangle.height) new_w->rectangle.height = 0; } Call_Resize = True; flag = True; } /* Resize is called only if we need to calculate the dimensions or */ /* coordinates for the string. */ if (Call_Resize) { XtWidgetProc resize; _XmProcessLock(); resize = (((XmLabelGadgetClassRec *)(new_w->object.widget_class))-> rect_class.resize); _XmProcessUnlock(); (* (resize)) ((Widget) new_w); } /* If the sensitivity has changed then we must redisplay. */ if (XtIsSensitive(nw) != XtIsSensitive(cw)) { flag = True; } /* Force the traversal flag when in a menu. */ if ((XtClass(new_w) == xmLabelGadgetClass) && ((LabG_MenuType(new_w) == XmMENU_POPUP) || (LabG_MenuType(new_w) == XmMENU_PULLDOWN) || (LabG_MenuType(new_w) == XmMENU_OPTION))) { new_w->gadget.traversal_on = False; new_w->gadget.highlight_on_enter = False; } if (LabG_Font(new_w) != LabG_Font(current) || LabG_Foreground(new_w) != LabG_Foreground(current) || LabG_Background(new_w) != LabG_Background(current)) { /* Recreate the GC's if the font has been changed */ XtReleaseGC (XtParent (current), LabG_NormalGC(current)); XtReleaseGC (XtParent (current), LabG_InsensitiveGC(current)); SetNormalGC(new_w); flag = True; } /* * The test for foreground is done here to allow for subclasses * to use this gc in a graphix op that may reference the background * field of the GC (i.e. in this gc background is set to LabG_Foreground. */ if (LabG_Background(new_w) != LabG_Background(current) || LabG_Foreground(new_w) != LabG_Foreground(current)) { XtReleaseGC (XtParent (current), LabG_BackgroundGC(current)); _XmLabelSetBackgroundGC(new_w); flag = True; } if (LabG_TopShadowColor(new_w) != LabG_TopShadowColor(current) || LabG_TopShadowPixmap(new_w) != LabG_TopShadowPixmap(current)) { XtReleaseGC (XtParent (current), LabG_TopShadowGC(current)); LabG_TopShadowGC(new_w) = _XmGetPixmapBasedGC (XtParent(nw), LabG_TopShadowColor(new_w), LabG_Background(new_w), LabG_TopShadowPixmap(new_w)); flag = True; } if (LabG_BottomShadowColor(new_w) != LabG_BottomShadowColor(current) || LabG_BottomShadowPixmap(new_w) != LabG_BottomShadowPixmap(current)) { XtReleaseGC (XtParent (current), LabG_BottomShadowGC(current)); LabG_BottomShadowGC(new_w) = _XmGetPixmapBasedGC (XtParent(nw), LabG_BottomShadowColor(new_w), LabG_Background(new_w), LabG_BottomShadowPixmap(new_w)); flag = True; } if (LabG_HighlightColor(new_w) != LabG_HighlightColor(current) || LabG_HighlightPixmap(new_w) != LabG_HighlightPixmap(current)) { XtReleaseGC (XtParent (current), LabG_HighlightGC(current)); LabG_HighlightGC(new_w) = _XmGetPixmapBasedGC (XtParent(nw), LabG_HighlightColor(new_w), LabG_Background(new_w), LabG_HighlightPixmap(new_w)); flag = True; } if ((LabG_MenuType(new_w) != XmWORK_AREA) && (LabG_Mnemonic(new_w) != LabG_Mnemonic(current))) { /* New grabs only required if mnemonic changes */ ProcessFlag = TRUE; if (LabG_LabelType(new_w) == XmSTRING) flag = TRUE; } if (LabG_MnemonicCharset(new_w) != LabG_MnemonicCharset(current)) { if (LabG_MnemonicCharset(new_w)) LabG_MnemonicCharset(new_w) = _XmStringCharsetCreate(LabG_MnemonicCharset (new_w)); else LabG_MnemonicCharset(new_w) = _XmStringCharsetCreate(XmFONTLIST_DEFAULT_TAG); if (LabG_MnemonicCharset (current) != NULL) XtFree(LabG_MnemonicCharset(current)); if (LabG_LabelType(new_w) == XmSTRING) flag = TRUE; } if (LabG_IsMenupane(new_w) && (LabG_Accelerator(new_w) != LabG_Accelerator(current))) { if (LabG_Accelerator(new_w) != NULL) { /* Copy the accelerator into local space */ LabG_Accelerator(new_w) = XtNewString(LabG_Accelerator(new_w)); } if (LabG_Accelerator(current) != NULL) XtFree(LabG_Accelerator(current)); LabG_Accelerator(current) = NULL; LabG_Accelerator(req) = NULL; ProcessFlag = TRUE; } else LabG_Accelerator(new_w) = LabG_Accelerator(current); menuSTrait = (XmMenuSystemTrait) XmeTraitGet((XtPointer) XtClass(XtParent(new_w)), XmQTmenuSystem); if (ProcessFlag && menuSTrait != NULL) menuSTrait->updateBindings((Widget)new_w, XmREPLACE); if (flag && (LabG_MenuType(new_w) == XmMENU_PULLDOWN) && menuSTrait != NULL) menuSTrait->updateHistory(XtParent(new_w), (Widget) new_w, True); if (CleanupFontFlag) if (LabG_Font(current)) XmFontListFree(LabG_Font(current)); return flag; } /* * So complications. HandleRedraw is a wrapper that calls _XmLabelGCVTRedraw * which does the work for the trait stuff. * * _XmLabelGCVTRedraw returns a boolean which determines if the child, not the * parent should be redrawn. * * This is done to serve as a form of inheritance. ToggleBG needs all the * LabelG stuff changed plus some of its own state. Therefore ToggleBG * will call _XmLabelGCVTRedraw. */ static Boolean HandleRedraw (Widget kid, Widget cur_parent, Widget new_parent, Mask visual_flag) { Boolean redraw = False; XtExposeProc expose; /* Don't change with parent. New Gadget behavior has been enabled. */ redraw = _XmLabelGCVTRedraw (kid, cur_parent, new_parent, visual_flag); _XmProcessLock(); expose = ((XmLabelGadgetClassRec *)(XtClass(kid)))->rect_class.expose; _XmProcessUnlock(); if (redraw) if (! XtIsRealized(kid)) return redraw; else (* (expose)) ((Widget)kid, NULL, (Region) NULL); return False; } Boolean _XmLabelGCVTRedraw(Widget kid, Widget cur_parent, Widget new_parent, Mask visual_flag) { XmLabelGadget lw = (XmLabelGadget) kid; XmManagerWidget mw = (XmManagerWidget) new_parent; XmManagerWidget curmw = (XmManagerWidget) cur_parent; Boolean redraw = False, do_normal = False, do_background = False; XmLabelGCacheObjPart oldCopy; /* * Since we are here the instance record is going to be changed. * So break this out out the cache, make the changes and reinsert * below. */ _XmProcessLock(); _XmCacheCopy((XtPointer) LabG_Cache(lw), (XtPointer) &oldCopy, sizeof(XmLabelGCacheObjPart)); _XmCacheDelete ((XtPointer) LabG_Cache(lw)); _XmProcessUnlock(); LabG_Cache(lw) = &oldCopy; if ((visual_flag & VisualBackgroundPixel) && (LabG_Background(lw) == curmw->core.background_pixel)) { redraw = do_background = do_normal = True; LabG_Background(lw) = mw->core.background_pixel; } if (visual_flag & VisualBackgroundPixmap) { redraw = do_background = True; } if ((visual_flag & VisualForeground) && (LabG_Foreground(lw) == curmw->manager.foreground)) { redraw = do_normal = True; LabG_Foreground(lw) = mw->manager.foreground; } if (do_background) { XtReleaseGC (XtParent(lw), LabG_BackgroundGC(lw)); _XmLabelSetBackgroundGC((XmLabelGadget)lw); } if (do_normal) { XtReleaseGC (XtParent(lw), LabG_NormalGC(lw)); XtReleaseGC (XtParent(lw), LabG_InsensitiveGC(lw)); SetNormalGC((XmLabelGadget)lw); } if (visual_flag & (VisualTopShadowColor | VisualTopShadowPixmap)) { XtReleaseGC (XtParent(lw), LabG_TopShadowGC(lw)); if(LabG_TopShadowColor(lw) == curmw->manager.top_shadow_color) LabG_TopShadowColor(lw) = mw->manager.top_shadow_color; if(LabG_TopShadowPixmap(lw) == curmw->manager.top_shadow_pixmap && (LabG_TopShadowPixmap(lw) != XmUNSPECIFIED_PIXMAP || LabG_TopShadowColor(lw) == curmw->manager.top_shadow_color)) LabG_TopShadowPixmap(lw) = mw->manager.top_shadow_pixmap; LabG_TopShadowGC(lw) = _XmGetPixmapBasedGC (XtParent(lw), LabG_TopShadowColor(lw), LabG_Background(lw), LabG_TopShadowPixmap(lw)); redraw = True; } if (visual_flag & (VisualBottomShadowColor | VisualBottomShadowPixmap)) { XtReleaseGC (XtParent(lw), LabG_BottomShadowGC(lw)); if(LabG_BottomShadowColor(lw) == curmw->manager.bottom_shadow_color) LabG_BottomShadowColor(lw) = mw->manager.bottom_shadow_color; if(LabG_BottomShadowPixmap(lw) == curmw->manager.bottom_shadow_pixmap && (LabG_BottomShadowPixmap(lw) != XmUNSPECIFIED_PIXMAP || LabG_BottomShadowColor(lw) == curmw->manager.bottom_shadow_color)) LabG_BottomShadowPixmap(lw) = mw->manager.bottom_shadow_pixmap; LabG_BottomShadowGC(lw) = _XmGetPixmapBasedGC (XtParent(lw), LabG_BottomShadowColor(lw), LabG_Background(lw), LabG_BottomShadowPixmap(lw)); redraw = True; } if (visual_flag & (VisualHighlightColor | VisualHighlightPixmap)) { XtReleaseGC (XtParent(lw), LabG_HighlightGC(lw)); if(LabG_HighlightColor(lw) == curmw->manager.highlight_color) LabG_HighlightColor(lw) = mw->manager.highlight_color; if(LabG_HighlightPixmap(lw) == curmw->manager.highlight_pixmap && (LabG_HighlightPixmap(lw) != XmUNSPECIFIED_PIXMAP || LabG_HighlightColor(lw) == curmw->manager.highlight_color)) LabG_HighlightPixmap(lw) = mw->manager.highlight_pixmap; LabG_HighlightGC(lw) = _XmGetPixmapBasedGC (XtParent(lw), LabG_HighlightColor(lw), LabG_Background(lw), LabG_HighlightPixmap(lw)); redraw = True; } _XmProcessLock(); LabG_Cache(lw) = (XmLabelGCacheObjPart *) _XmCachePart(LabG_ClassCachePart(lw), (XtPointer) LabG_Cache(lw), sizeof(XmLabelGCacheObjPart)); _XmProcessUnlock(); 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) { XmLabelGadget lg = (XmLabelGadget) wid; if (event_mask & XmHELP_EVENT) Help ((Widget) lg, event); else if (event_mask & XmENTER_EVENT) _XmEnterGadget ((Widget) lg, event, NULL, NULL); else if (event_mask & XmLEAVE_EVENT) _XmLeaveGadget ((Widget) lg, event, NULL, NULL); else if (event_mask & XmFOCUS_IN_EVENT) _XmFocusInGadget ((Widget) lg, event, NULL, NULL); else if (event_mask & XmFOCUS_OUT_EVENT) _XmFocusOutGadget ((Widget) lg, event, NULL, NULL); else if (event_mask & XmBDRAG_EVENT) _XmProcessDrag ((Widget) lg, event, NULL, NULL); } /************************************************************************ * * Help * This routine is called if the user made a help selection * on the widget. * ************************************************************************/ static void Help(Widget w, XEvent *event) { XmLabelGadget lg = (XmLabelGadget) w; XmMenuSystemTrait menuSTrait; menuSTrait = (XmMenuSystemTrait) XmeTraitGet((XtPointer) XtClass(XtParent(lg)), XmQTmenuSystem); if (LabG_IsMenupane(lg) && (menuSTrait != NULL)) menuSTrait->popdown(XtParent(lg), event); _XmSocorro(w, event, NULL, NULL); } /************************************************************************ * * GetLabelString * This is a get values hook function that returns the external * form of the label string from the internal form. * ***********************************************************************/ /*ARGSUSED*/ static void GetLabelString(Widget wid, int offset, XtArgVal *value) { XmLabelGadget lw = (XmLabelGadget) wid; XmString string; string = XmStringCopy(LabG__label(lw)); *value = (XtArgVal) string; } /************************************************************************ * * GetAccelerator * This is a get values hook function that returns a copy * of the accelerator string. * ***********************************************************************/ /*ARGSUSED*/ static void GetAccelerator(Widget wid, int offset, XtArgVal *value) { XmLabelGadget lw = (XmLabelGadget) wid; String string; string = XtNewString(LabG_Accelerator(lw)); *value = (XtArgVal) string; } /************************************************************************ * * GetAcceleratorText * This is a get values hook function that returns the external * form of the accelerator text from the internal form. * ***********************************************************************/ /*ARGSUSED*/ static void GetAcceleratorText(Widget wid, int offset, XtArgVal *value) { XmLabelGadget lw = (XmLabelGadget) wid; XmString string; string = XmStringCopy(LabG__acceleratorText(lw)); *value = (XtArgVal) string; } /************************************************************************ * * _XmStringCharsetCreate * ************************************************************************/ static XmStringCharSet _XmStringCharsetCreate(XmStringCharSet stringcharset) { return (XmStringCharSet) XtNewString((char*) stringcharset); } /************************************************************************ * * GetMnemonicCharset * This is a get values hook function that returns the external * form of the mnemonicCharset from the internal form. * : Returns a string containg the mnemonicCharset. * Caller must free the string . * ***********************************************************************/ /*ARGSUSED*/ static void GetMnemonicCharset(Widget wid, int resource, /* unused */ XtArgVal *value) { XmLabelGadget lw = (XmLabelGadget) wid; char *cset; int size; cset = NULL; if (LabG_MnemonicCharset (lw)) { size = strlen (LabG_MnemonicCharset (lw)); if (size > 0) cset = (char *) (_XmStringCharsetCreate(LabG_MnemonicCharset (lw))); } *value = (XtArgVal) cset; } /************************************************************************ * * Caching Assignment help * These routines are for manager widgets that go into Label's * fields and set them, instead of doing a SetValues. * ************************************************************************/ static XmLabelGCacheObjPart local_cache; static Boolean local_cache_inited = FALSE; /* * QualifyLabelLocalCache * Checks to see if local cache is set up */ static void QualifyLabelLocalCache(XmLabelGadget w) { if (!local_cache_inited) { local_cache_inited = TRUE; ClassCacheCopy(LabG_ClassCachePart(w)) (LabG_Cache(w), &local_cache, sizeof(local_cache)); } } /************************************************************************ * * _XmReCacheLabG() * Check to see if ReCaching is necessary as a result of fields having * been set by a mananger widget. This routine is called by the * manager widget in their SetValues after a change is made to any * of Label's cached fields. * ************************************************************************/ void _XmReCacheLabG(Widget wid) { XmLabelGadget lw = (XmLabelGadget) wid; _XmProcessLock(); if (local_cache_inited && (!_XmLabelCacheCompare((XtPointer)&local_cache, (XtPointer)LabG_Cache(lw)))) { /* Delete the old one. */ _XmCacheDelete((XtPointer) LabG_Cache(lw)); LabG_Cache(lw) = (XmLabelGCacheObjPart *) _XmCachePart(LabG_ClassCachePart(lw), (XtPointer) &local_cache, sizeof(local_cache)); } local_cache_inited = FALSE; _XmProcessUnlock(); } void _XmAssignLabG_MarginHeight(XmLabelGadget lw, #if NeedWidePrototypes int value) #else Dimension value) #endif /* NeedWidePrototypes */ { _XmProcessLock(); QualifyLabelLocalCache(lw); local_cache.margin_height = value; _XmProcessUnlock(); } void _XmAssignLabG_MarginWidth(XmLabelGadget lw, #if NeedWidePrototypes int value) #else Dimension value) #endif /* NeedWidePrototypes */ { _XmProcessLock(); QualifyLabelLocalCache(lw); local_cache.margin_width = value; _XmProcessUnlock(); } void _XmAssignLabG_MarginLeft(XmLabelGadget lw, #if NeedWidePrototypes int value) #else Dimension value) #endif /* NeedWidePrototypes */ { _XmProcessLock(); QualifyLabelLocalCache(lw); local_cache.margin_left = value; _XmProcessUnlock(); } void _XmAssignLabG_MarginRight(XmLabelGadget lw, #if NeedWidePrototypes int value) #else Dimension value) #endif /* NeedWidePrototypes */ { _XmProcessLock(); QualifyLabelLocalCache(lw); local_cache.margin_right = value; _XmProcessUnlock(); } void _XmAssignLabG_MarginTop(XmLabelGadget lw, #if NeedWidePrototypes int value) #else Dimension value) #endif /* NeedWidePrototypes */ { _XmProcessLock(); QualifyLabelLocalCache(lw); local_cache.margin_top = value; _XmProcessUnlock(); } void _XmAssignLabG_MarginBottom(XmLabelGadget lw, #if NeedWidePrototypes int value) #else Dimension value) #endif /* NeedWidePrototypes */ { _XmProcessLock(); QualifyLabelLocalCache(lw); local_cache.margin_bottom = value; _XmProcessUnlock(); } /************************************************************************ * * SetGadgetActivateCallbackState * * This function is used as the method of the menuSavvy trait. It is * used by menu savvy parents to set whether or not the child will * invoke its own activate callback or whether it will defer to the * entryCallback of the parent. * ************************************************************************/ static void SetGadgetActivateCallbackState(Widget wid, XmActivateState state) { XmLabelGCacheObjPart localCache; _XmQualifyLabelLocalCache(&localCache, (XmLabelGadget)wid); switch (state) { case XmDISABLE_ACTIVATE: localCache.skipCallback = True; break; case XmENABLE_ACTIVATE: localCache.skipCallback = False; break; } _XmReCacheLabG_r(&localCache, (XmLabelGadget)wid); } /************************************************************************ * * SetOverrideCallback * * Used by subclasses. If this is set true, then there is a RowColumn * parent with the entryCallback resource set. The subclasses do not * do their activate callbacks, instead the RowColumn callbacks are called * by RowColumn. ************************************************************************/ /*ARGSUSED*/ static void SetOverrideCallback( Widget w) { XmLabelGCacheObjPart localCache; _XmQualifyLabelLocalCache(&localCache, (XmLabelGadget)w); localCache.skipCallback= True; _XmReCacheLabG_r(&localCache, (XmLabelGadget)w); } /************************************************************************ * * XmCreateLabelGadget * Externally accessable function for creating a label gadget. * ************************************************************************/ Widget XmCreateLabelGadget(Widget parent, char *name, Arg *arglist, Cardinal argCount) { return XtCreateWidget(name, xmLabelGadgetClass, parent, arglist, argCount); } /* * GetLabelBGClassSecResData () * Class function to be called to copy secondary resource for external * use. i.e. copy the cached resources and send it back. */ /*ARGSUSED*/ static Cardinal GetLabelBGClassSecResData(WidgetClass w_class, XmSecondaryResourceData **data_rtn) { int arrayCount; XmBaseClassExt bcePtr; String resource_class, resource_name; XtPointer client_data; _XmProcessLock(); bcePtr = &(labelBaseClassExtRec); client_data = NULL; resource_class = NULL; resource_name = NULL; arrayCount = _XmSecondaryResourceData(bcePtr, data_rtn, client_data, resource_name, resource_class, GetLabelClassResBase); _XmProcessUnlock(); return arrayCount; } /* * GetLabelClassResBase () * retrun the address of the base of resources. * - Not yet implemented. */ /*ARGSUSED*/ static XtPointer GetLabelClassResBase(Widget widget, XtPointer client_data) /* unused */ { XtPointer widgetSecdataPtr; int labg_cache_size = sizeof(XmLabelGCacheObjPart); char *cp; widgetSecdataPtr = (XtPointer) (XtMalloc (labg_cache_size +1)); _XmProcessLock(); if (widgetSecdataPtr) { cp = (char *) widgetSecdataPtr; memcpy(cp, LabG_Cache(widget), labg_cache_size); } _XmProcessUnlock(); return widgetSecdataPtr; } /*ARGSUSED*/ static void SetValuesAlmost(Widget cw, /* unused */ Widget nw, XtWidgetGeometry *request, XtWidgetGeometry *reply) { XmLabelGadget new_w = (XmLabelGadget) nw; XtWidgetProc resize; _XmProcessLock(); resize = ((XmLabelGadgetClassRec *)(new_w->object.widget_class))-> rect_class.resize; _XmProcessUnlock(); (* (resize)) ((Widget) new_w); *request = *reply; } static void GetColors(Widget w, XmAccessColorData color_data) { if (LabG_Cache(w)) { color_data->valueMask = AccessForeground | AccessBackgroundPixel | AccessHighlightColor | AccessTopShadowColor | AccessBottomShadowColor; color_data->background = LabG_Background(w); color_data->foreground = LabG_Foreground(w); color_data->highlight_color = LabG_HighlightColor(w); color_data->top_shadow_color = LabG_TopShadowColor(w); color_data->bottom_shadow_color = LabG_BottomShadowColor(w); } else { color_data->valueMask = AccessColorInvalid; } } /************************************************************************ * * XmLabelGadgetGetBaselines * * A Class function which when called returns True, if the widget has * a baseline and also determines the number of pixels from the y * origin to the first line of text and assigns it to the variable * being passed in. * ************************************************************************/ static Boolean XmLabelGadgetGetBaselines(Widget wid, Dimension **baselines, int *line_count) { XmLabelGadget lw = (XmLabelGadget)wid; Cardinal count; int delta; if (LabG_IsPixmap(wid)) return False; /* Compute raw baselines if unavailable. */ if (lw->label.baselines == NULL) { _XmStringGetBaselines(LabG_Font(lw), LabG__label(lw), &(lw->label.baselines), &count); assert(lw->label.baselines != NULL); /* Store the current offset in an extra location. */ lw->label.baselines = (Dimension*) XtRealloc((char*) lw->label.baselines, (count+1) * sizeof(Dimension)); lw->label.baselines[count] = 0; } else { count = XmStringLineCount(LabG__label(lw)); } /* Readjust offsets if necessary. */ delta = LabG_TextRect_y(lw) - lw->label.baselines[count]; if (delta) { int tmp; for (tmp = 0; tmp <= count; tmp++) lw->label.baselines[tmp] += delta; } /* Copy the cached data. */ *line_count = count; *baselines = (Dimension*) XtMalloc(*line_count * sizeof(Dimension)); memcpy((char*) *baselines, (char*) lw->label.baselines, *line_count * sizeof(Dimension)); return True; } /************************************************************************ * * XmLabelGadgetGetDisplayRect * * A Class function which returns true if the widget being passed in * has a display rectangle associated with it. It also determines the * x,y coordinates of the character cell or pixmap relative to the origin * and the width and height in pixels of the smallest rectangle that encloses * the text or pixmap. This is assigned to the variable being passed in * ***********************************************************************/ static Boolean XmLabelGadgetGetDisplayRect(Widget w, XRectangle *displayrect) { XmLabelGadget wid = (XmLabelGadget) w; displayrect->x = wid->label.TextRect.x; displayrect->y = wid->label.TextRect.y; displayrect->width = wid->label.TextRect.width; displayrect->height = wid->label.TextRect.height; return TRUE; } /************************************************************************ * * XmLabelGadgetMarginsProc * ***********************************************************************/ /* ARGSUSED */ static void XmLabelGadgetMarginsProc(Widget w, XmBaselineMargins *margins_rec) { XmLabelGCacheObjPart localCache; if (margins_rec->get_or_set == XmBASELINE_SET) { _XmQualifyLabelLocalCache(&localCache, (XmLabelGadget)w); _XmAssignLabG_MarginTop_r((&localCache), margins_rec->margin_top); _XmAssignLabG_MarginBottom_r((&localCache), margins_rec->margin_bottom); _XmReCacheLabG_r(&localCache, (XmLabelGadget)w); } else { margins_rec->margin_top = LabG_MarginTop(w); margins_rec->margin_bottom = LabG_MarginBottom(w); margins_rec->shadow = LabG_Shadow(w); margins_rec->highlight = LabG_Highlight(w); margins_rec->text_height = LabG_TextRect_height(w); margins_rec->margin_height = LabG_MarginHeight(w); } } static Widget GetPixmapDragIcon(Widget w) { XmLabelGadget lw = (XmLabelGadget) w; Arg args[10]; int n = 0; Widget drag_icon; Widget screen_object = XmGetXmScreen(XtScreen(w)); unsigned int wid, hei; int d; /* it's a labelPixmap, use directly the pixmap */ XmeGetPixmapData(XtScreen(lw), Pix(lw), NULL, &d, NULL, NULL, NULL, NULL, &wid, &hei); n = 0; XtSetArg(args[n], XmNhotX, 0), n++; XtSetArg(args[n], XmNhotY, 0), n++; XtSetArg(args[n], XmNwidth, wid), n++; XtSetArg(args[n], XmNheight, hei), n++; XtSetArg(args[n], XmNmaxWidth, wid), n++; XtSetArg(args[n], XmNmaxHeight, hei), n++; XtSetArg(args[n], XmNdepth, d), n++; XtSetArg(args[n], XmNpixmap, Pix(lw)), n++; XtSetArg(args[n], XmNforeground, LabG_Background(lw)), n++; XtSetArg(args[n], XmNbackground, LabG_Foreground(lw)), n++; assert(n <= XtNumber(args)); drag_icon = XtCreateWidget("drag_icon", xmDragIconObjectClass, screen_object, args, n); return drag_icon; } /*ARGSUSED*/ void _XmProcessDrag(Widget w, XEvent *event, String *params, Cardinal *num_params) { XmLabelGadget lw = (XmLabelGadget) w; Widget drag_icon; Arg args[10]; int n; XmManagerWidget mw; Time _time = _XmGetDefaultTime(w, event); XmDisplay dpy = (XmDisplay) XmGetXmDisplay(XtDisplay(w)); mw = (XmManagerWidget) XtParent(lw); if (LabG_IsMenupane(w)) XAllowEvents(XtDisplay(mw), SyncPointer, _time); /* Disallow drag if this is a cascade button and armed - Hack alert */ if (XmIsCascadeButtonGadget(w) && CBG_IsArmed(w)) return; /* CDE - allow user to not drag labels and label subclasses also, disable drag if enable_btn1_transfer is set to BUTTON2_ADJUST and the trigger was button2 */ if (! dpy -> display.enable_unselectable_drag || (dpy -> display.enable_btn1_transfer == XmBUTTON2_ADJUST && event && event -> xany.type == ButtonPress && event -> xbutton.button == 2)) return; n = 0; XtSetArg(args[n], XmNcursorBackground, LabG_Background(lw)), n++; XtSetArg(args[n], XmNcursorForeground, LabG_Foreground(lw)), n++; /* If it's a labelPixmap, only specify the pixmap icon */ if (LabG_IsPixmap(lw) && (Pix(lw) != XmUNSPECIFIED_PIXMAP)) { drag_icon = GetPixmapDragIcon(w); XtSetArg(args[n], XmNsourcePixmapIcon, drag_icon), n++; } else { drag_icon = XmeGetTextualDragIcon(w); XtSetArg(args[n], XmNsourceCursorIcon, drag_icon), n++; } XtSetArg(args[n], XmNdragOperations, XmDROP_COPY), n++; (void) XmeDragSource(w, NULL, event, args, n); } /* * XmRCallProc routine for checking label.font before setting it to NULL * If "check_set_render_table" is True, then function has * been called twice on same widget, thus resource needs to be set NULL, * otherwise leave it alone. */ /*ARGSUSED*/ static void CheckSetRenderTable(Widget wid, int offset, XrmValue *value) { XmLabelGadget lw = (XmLabelGadget)wid; /* Check if been here before */ if (lw->label.check_set_render_table) value->addr = NULL; else { lw->label.check_set_render_table = True; value->addr = (char*)&(lw->label.font); } } static char* GetLabelGadgetAccelerator(Widget w) { if (XtClass(w) == xmLabelGadgetClass) return NULL; else return LabG_Accelerator(w); } static KeySym GetLabelGadgetMnemonic(Widget w) { if (XtClass(w) == xmLabelGadgetClass) return XK_VoidSymbol; else return LabG_Mnemonic(w); } void _XmQualifyLabelLocalCache( XmLabelGCacheObjPart *local_cache, XmLabelGadget w) { _XmProcessLock(); ClassCacheCopy(LabG_ClassCachePart(w)) (LabG_Cache(w), local_cache, sizeof(XmLabelGCacheObjPart) ); _XmProcessUnlock(); } void _XmReCacheLabG_r(XmLabelGCacheObjPart *local_cache, XmLabelGadget w) { _XmProcessLock(); if (!_XmLabelCacheCompare(local_cache, (XtPointer)LabG_Cache(w))) { _XmCacheDelete((XtPointer)LabG_Cache(w)); LabG_Cache(w) = (XmLabelGCacheObjPart *)_XmCachePart( LabG_ClassCachePart(w), local_cache, sizeof(XmLabelGCacheObjPart)); } _XmProcessUnlock(); }