1 /*
2  * Motif
3  *
4  * Copyright (c) 1987-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 #ifdef REV_INFO
24 #ifndef lint
25 static char rcsid[] = "$TOG: Label.c /main/26 1997/06/18 17:40:00 samborn $"
26 #endif
27 #endif
28 
29 #ifdef HAVE_CONFIG_H
30 #include <config.h>
31 #endif
32 
33 
34 #include <ctype.h>
35 #include <X11/IntrinsicP.h>
36 #include <X11/ShellP.h>
37 #include <X11/Xatom.h>
38 #include <X11/Xlocale.h>
39 #include <X11/keysymdef.h>
40 #include <Xm/AccTextT.h>
41 #include <Xm/AtomMgr.h>
42 #include <Xm/BaseClassP.h>
43 #include <Xm/CascadeBP.h>
44 #include <Xm/DisplayP.h>
45 #include <Xm/DragC.h>
46 #include <Xm/DragIcon.h>
47 #include <Xm/DragIconP.h>
48 #include <Xm/DrawP.h>
49 #include <Xm/MenuT.h>
50 #include <Xm/RowColumnP.h>
51 #include <Xm/TraitP.h>
52 #include <Xm/TransferT.h>
53 #include <Xm/TransltnsP.h>
54 #include <Xm/VaSimpleP.h>
55 #include "GadgetUtiI.h"
56 #include "GMUtilsI.h"
57 #include "LabelGI.h"
58 #include "LabelI.h"
59 #include "MessagesI.h"
60 #include "MenuProcI.h"
61 #include "PrimitiveI.h"
62 #include "RepTypeI.h"
63 #include "ScreenI.h"
64 #include "TransferI.h"
65 #include "TravActI.h"
66 #include "XmI.h"
67 #include "XmosI.h"
68 #include "XmStringI.h"
69 #include <Xm/XpmP.h>
70 #include <string.h>
71 #include <Xm/XmP.h>
72 #ifdef FIX_1381
73 #include <Xm/ColorI.h>
74 #endif
75 #ifdef FIX_1521
76 #ifdef USE_XFT
77 #include "XmRenderTI.h"
78 #include <X11/Xft/Xft.h>
79 #endif
80 #endif
81 
82 #define FIX_1442
83 #define FIX_1484
84 #define FIX_1504
85 
86 #define Pix(w)			((w)->label.pixmap)
87 #define Pix_insen(w)		((w)->label.pixmap_insen)
88 
89 /* Warning Messages */
90 
91 #define CS_STRING_MESSAGE	_XmMMsgLabel_0003
92 #define ACC_MESSAGE		_XmMMsgLabel_0004
93 
94 /********    Static Function Declarations    ********/
95 
96 static void ClassInitialize(void);
97 static void ClassPartInitialize(WidgetClass c);
98 static void InitializePrehook(Widget req, Widget new_w,
99 			      ArgList args, Cardinal *num_args);
100 static void InitializePosthook(Widget req, Widget new_w,
101 			       ArgList args, Cardinal *num_args);
102 static void SetNormalGC(XmLabelWidget lw);
103 static void Resize(Widget wid);
104 static void Initialize(Widget req, Widget new_w,
105 		       ArgList args, Cardinal *num_args);
106 static XtGeometryResult QueryGeometry(Widget wid,
107 				      XtWidgetGeometry *intended,
108 				      XtWidgetGeometry *reply);
109 static void Destroy(Widget w);
110 static void Redisplay(Widget wid, XEvent *event, Region region);
111 static void Enter(Widget wid, XEvent *event,
112 		  String *params, Cardinal *num_params);
113 static void Leave(Widget wid, XEvent *event,
114 		  String *params, Cardinal *num_params);
115 static Boolean SetValues(Widget cw, Widget rw, Widget nw,
116 			 ArgList args, Cardinal *num_args);
117 static void SetOverrideCallback(Widget wid);
118 static void Help(Widget w, XEvent *event, String *params, Cardinal *num_params);
119 static void GetLabelString(Widget wid, int resource, XtArgVal *value);
120 static void GetAccelerator(Widget wid, int resource, XtArgVal *value);
121 static void GetAcceleratorText(Widget wid, int resource, XtArgVal *value);
122 static XmStringCharSet _XmStringCharSetCreate(XmStringCharSet stringcharset);
123 static void GetMnemonicCharSet(Widget wid, int resource, XtArgVal *value);
124 static void SetValuesAlmost(Widget cw, Widget nw,
125 			    XtWidgetGeometry *request, XtWidgetGeometry *reply);
126 static Boolean XmLabelGetDisplayRect(Widget w, XRectangle *displayrect);
127 static Boolean XmLabelGetBaselines(Widget wid,
128 				   Dimension **baselines,
129 				   int *line_count);
130 static void XmLabelMarginsProc(Widget w,
131 			       XmBaselineMargins *margins_rec);
132 static Widget GetPixmapDragIcon(Widget w);
133 static void ProcessDrag(Widget w, XEvent *event,
134                         String *params, Cardinal *num_params);
135 static void SetActivateCallbackState(Widget w, XmActivateState state);
136 static void CheckSetRenderTable(Widget wid, int offset, XrmValue *value);
137 static void FromPaddingPixels(Widget, int, XtArgVal *);
138 static XmImportOperator ToPaddingPixels(Widget, int, XtArgVal*);
139 static XtPointer LabelGetValue(Widget, int);
140 static void LabelSetValue(Widget, XtPointer, int);
141 static int LabelPreferredValue(Widget);
142 static char* GetLabelAccelerator(Widget);
143 static KeySym GetLabelMnemonic(Widget);
144 static XtPointer ConvertToEncoding(Widget, char*, Atom, unsigned long *,
145 				 Boolean *);
146 /********    End Static Function Declarations    ********/
147 
148 
149 void _XmLabelConvert(Widget w, XtPointer ignore, XmConvertCallbackStruct*);
150 
151 /* Transfer trait record */
152 static XmConst XmTransferTraitRec LabelTransfer = {
153   0, 						/* version		  */
154   (XmConvertCallbackProc) _XmLabelConvert,	/* convertProc		  */
155   NULL,						/* destinationProc	  */
156   NULL						/* destinationPreHookProc */
157 };
158 
159 /* Menu Savvy trait record */
160 static XmConst XmMenuSavvyTraitRec MenuSavvyRecord = {
161   0,						     /* version		  */
162   (XmMenuSavvyDisableProc) SetActivateCallbackState, /* disableCallback	  */
163   GetLabelAccelerator,				     /* getAccelerator	  */
164   GetLabelMnemonic,				     /* getMnemonic	  */
165   (XmMenuSavvyGetActivateCBNameProc) NULL,	     /* getActivateCBName */
166 };
167 
168 /* Access Textual trait record */
169 XmAccessTextualTraitRec _XmLabel_AccessTextualRecord = {
170   0,				/* version         */
171   LabelGetValue,		/* getValueMethod  */
172   LabelSetValue,		/* setValuesMethod */
173   LabelPreferredValue,		/* preferredFormat */
174 };
175 
176 
177 /* Default translations and action recs */
178 
179 static XtTranslations default_parsed;
180 
181 #define defaultTranslations	_XmLabel_defaultTranslations
182 
183 static XtTranslations menu_parsed;
184 
185 #define menuTranslations	_XmLabel_menuTranslations
186 
187 
188 static XtActionsRec ActionsList[] = {
189   { "Enter",		Enter		},
190   { "Leave",		Leave		},
191   { "Help",		Help		},
192   { "ProcessDrag",	ProcessDrag	}
193 };
194 
195 
196 /* Here are the translations used by the subclasses for menu traversal */
197 /* The matching actions are defined in RowColumn.c                     */
198 
199 #define menu_traversal_events	_XmLabel_menu_traversal_events
200 
201 static XtResource resources[] =
202 {
203   {
204     XmNshadowThickness, XmCShadowThickness, XmRHorizontalDimension,
205     sizeof(Dimension), XtOffsetOf(XmLabelRec, primitive.shadow_thickness),
206     XmRImmediate, (XtPointer) 0
207   },
208 
209   {
210     XmNalignment, XmCAlignment, XmRAlignment,
211     sizeof(unsigned char), XtOffsetOf(XmLabelRec, label.alignment),
212     XmRImmediate, (XtPointer) XmALIGNMENT_CENTER
213   },
214 
215   {
216     XmNlabelType, XmCLabelType, XmRLabelType,
217     sizeof(unsigned char), XtOffsetOf(XmLabelRec, label.label_type),
218     XmRImmediate, (XtPointer) XmSTRING
219   },
220 
221   {
222     XmNmarginWidth, XmCMarginWidth, XmRHorizontalDimension,
223     sizeof(Dimension), XtOffsetOf(XmLabelRec, label.margin_width),
224     XmRImmediate, (XtPointer) 2
225   },
226 
227   {
228     XmNmarginHeight, XmCMarginHeight, XmRVerticalDimension,
229     sizeof(Dimension), XtOffsetOf(XmLabelRec, label.margin_height),
230     XmRImmediate, (XtPointer) 2
231   },
232 
233   {
234     XmNmarginLeft, XmCMarginLeft, XmRHorizontalDimension,
235     sizeof(Dimension), XtOffsetOf(XmLabelRec, label.margin_left),
236     XmRImmediate, (XtPointer) 0
237   },
238 
239   {
240     XmNmarginRight, XmCMarginRight, XmRHorizontalDimension,
241     sizeof(Dimension), XtOffsetOf(XmLabelRec, label.margin_right),
242     XmRImmediate, (XtPointer) 0
243   },
244 
245   {
246     XmNmarginTop, XmCMarginTop, XmRVerticalDimension,
247     sizeof(Dimension), XtOffsetOf(XmLabelRec, label.margin_top),
248     XmRImmediate, (XtPointer) 0
249   },
250 
251   {
252     XmNmarginBottom, XmCMarginBottom, XmRVerticalDimension,
253     sizeof(Dimension), XtOffsetOf(XmLabelRec, label.margin_bottom),
254     XmRImmediate, (XtPointer) 0
255   },
256 
257   {
258       "pri.vate","Pri.vate",XmRBoolean,
259       sizeof(Boolean), XtOffsetOf(XmLabelRec, label.check_set_render_table),
260       XmRImmediate, (XtPointer) False
261   },
262 
263   {
264     XmNfontList, XmCFontList, XmRFontList,
265     sizeof(XmFontList), XtOffsetOf(XmLabelRec, label.font),
266     XmRCallProc, (XtPointer)CheckSetRenderTable
267   },
268 
269   {
270     XmNrenderTable, XmCRenderTable, XmRRenderTable,
271     sizeof(XmRenderTable), XtOffsetOf(XmLabelRec, label.font),
272     XmRCallProc, (XtPointer)CheckSetRenderTable
273   },
274 
275   {
276     XmNlabelPixmap, XmCLabelPixmap, XmRDynamicPixmap,
277     sizeof(Pixmap), XtOffsetOf(XmLabelRec, label.pixmap),
278     XmRImmediate, (XtPointer) XmUNSPECIFIED_PIXMAP
279   },
280 
281   {
282     XmNlabelInsensitivePixmap, XmCLabelInsensitivePixmap, XmRDynamicPixmap,
283     sizeof(Pixmap), XtOffsetOf(XmLabelRec, label.pixmap_insen),
284     XmRImmediate, (XtPointer) XmUNSPECIFIED_PIXMAP
285   },
286 
287   {
288     XmNlabelString, XmCXmString, XmRXmString,
289     sizeof(XmString), XtOffsetOf(XmLabelRec, label._label),
290     XmRImmediate, (XtPointer) NULL
291   },
292 
293   {
294     XmNmnemonic, XmCMnemonic, XmRKeySym,
295     sizeof(KeySym), XtOffsetOf(XmLabelRec, label.mnemonic),
296     XmRImmediate, (XtPointer) XK_VoidSymbol
297   },
298 
299    {
300      XmNmnemonicCharSet, XmCMnemonicCharSet, XmRString,
301      sizeof(XmStringCharSet), XtOffsetOf(XmLabelRec, label.mnemonicCharset),
302      XmRImmediate, (XtPointer) XmFONTLIST_DEFAULT_TAG
303    },
304 
305   {
306     XmNaccelerator, XmCAccelerator, XmRString,
307     sizeof(char *), XtOffsetOf(XmLabelRec, label.accelerator),
308     XmRImmediate, (XtPointer) NULL
309   },
310 
311   {
312     XmNacceleratorText, XmCAcceleratorText, XmRXmString,
313     sizeof(XmString), XtOffsetOf(XmLabelRec, label._acc_text),
314     XmRImmediate, (XtPointer) NULL
315   },
316 
317  {
318    XmNrecomputeSize, XmCRecomputeSize, XmRBoolean,
319    sizeof(Boolean), XtOffsetOf(XmLabelRec, label.recompute_size),
320    XmRImmediate, (XtPointer) True
321  },
322 
323  {
324    XmNstringDirection, XmCStringDirection, XmRStringDirection,
325    sizeof(unsigned char), XtOffsetOf(XmLabelRec, label.string_direction),
326    XmRImmediate, (XtPointer) XmDEFAULT_DIRECTION
327  },
328 
329  {
330    XmNtraversalOn, XmCTraversalOn, XmRBoolean,
331    sizeof(Boolean), XtOffsetOf(XmPrimitiveRec, primitive.traversal_on),
332    XmRImmediate, (XtPointer) False
333   },
334 
335   {
336     XmNhighlightThickness, XmCHighlightThickness, XmRHorizontalDimension,
337     sizeof(Dimension), XtOffsetOf(XmPrimitiveRec, primitive.highlight_thickness),
338     XmRImmediate, (XtPointer) 0
339   },
340 #ifndef XM_PART_BC
341   {
342     XmNlayoutDirection, XmCLayoutDirection, XmRDirection,
343     sizeof(XmDirection), XtOffsetOf(XmPrimitiveRec, primitive.layout_direction),
344     XmRImmediate, (XtPointer) XmDEFAULT_DIRECTION
345   },
346 #endif
347   {
348     XmNpixmapPlacement, XmCPixmapPlacement, XmRPixmapPlacement,
349     sizeof(XmPixmapPlacement), XtOffsetOf(XmLabelRec, label.pixmap_placement),
350     XmRImmediate, (XtPointer) XmPIXMAP_LEFT
351   },
352   {
353     XmNpixmapTextPadding, XmCSpace, XmRVerticalDimension,
354     sizeof(Dimension), XtOffsetOf(XmLabelRec, label.pixmap_text_padding),
355     XmRImmediate, (XtPointer) 2
356   }
357 };
358 
359 /* Definition for resources that need special processing in get values. */
360 
361 static XmSyntheticResource syn_resources[] =
362 {
363   {
364     XmNmarginWidth, sizeof(Dimension),
365     XtOffsetOf(XmLabelRec, label.margin_width),
366     XmeFromHorizontalPixels, XmeToHorizontalPixels
367   },
368 
369   {
370     XmNmarginHeight, sizeof(Dimension),
371     XtOffsetOf(XmLabelRec, label.margin_height),
372     XmeFromVerticalPixels, XmeToVerticalPixels
373   },
374 
375   {
376     XmNmarginLeft, sizeof(Dimension),
377     XtOffsetOf(XmLabelRec, label.margin_left),
378     XmeFromHorizontalPixels, XmeToHorizontalPixels
379   },
380 
381   {
382     XmNmarginRight, sizeof(Dimension),
383     XtOffsetOf(XmLabelRec, label.margin_right),
384     XmeFromHorizontalPixels, XmeToHorizontalPixels
385   },
386 
387   {
388     XmNmarginTop, sizeof(Dimension),
389     XtOffsetOf(XmLabelRec, label.margin_top),
390     XmeFromVerticalPixels, XmeToVerticalPixels
391   },
392 
393   {
394     XmNmarginBottom, sizeof(Dimension),
395     XtOffsetOf(XmLabelRec, label.margin_bottom),
396     XmeFromVerticalPixels, XmeToVerticalPixels
397   },
398 
399   {
400     XmNlabelString, sizeof(XmString),
401     XtOffsetOf(XmLabelRec, label._label),
402     GetLabelString, NULL
403   },
404 
405   {
406     XmNmnemonicCharSet, sizeof(XmStringCharSet),
407     XtOffsetOf(XmLabelRec, label.mnemonicCharset),
408     GetMnemonicCharSet, NULL
409   },
410 
411   {
412     XmNaccelerator, sizeof(String),
413     XtOffsetOf(XmLabelRec, label.accelerator),
414     GetAccelerator, NULL
415   },
416 
417   {
418     XmNacceleratorText, sizeof(XmString),
419     XtOffsetOf(XmLabelRec, label._acc_text),
420     GetAcceleratorText, NULL
421   },
422 
423   {
424     XmNpixmapTextPadding, sizeof(Dimension),
425     XtOffsetOf(XmLabelRec, label.pixmap_text_padding),
426     FromPaddingPixels, (XmImportProc) ToPaddingPixels
427   }
428 };
429 
430 static XmBaseClassExtRec labelBaseClassExtRec = {
431   NULL,				/* Next extension         */
432   NULLQUARK,			/* record type XmQmotif   */
433   XmBaseClassExtVersion,	/* version                */
434   sizeof(XmBaseClassExtRec),	/* size                   */
435   InitializePrehook,		/* initialize prehook     */
436   XmInheritSetValuesPrehook,	/* set_values prehook     */
437   InitializePosthook,		/* initialize posthook    */
438   XmInheritSetValuesPosthook,	/* set_values posthook    */
439   XmInheritClass,		/* secondary class        */
440   XmInheritSecObjectCreate,	/* creation proc          */
441   XmInheritGetSecResData,	/* getSecResData          */
442   { 0 },			/* fast subclass          */
443   XmInheritGetValuesPrehook,	/* get_values prehook     */
444   XmInheritGetValuesPosthook,	/* get_values posthook    */
445   NULL,				/* classPartInitPrehook   */
446   NULL,				/* classPartInitPosthook  */
447   NULL,				/* ext_resources          */
448   NULL,				/* compiled_ext_resources */
449   0,				/* num_ext_resources      */
450   FALSE,			/* use_sub_resources      */
451   XmInheritWidgetNavigable,	/* widgetNavigable        */
452   XmInheritFocusChange		/* focusChange            */
453 };
454 
455 static XmPrimitiveClassExtRec _XmLabelPrimClassExtRec = {
456   NULL,					/* next_extension      */
457   NULLQUARK,				/* record_type         */
458   XmPrimitiveClassExtVersion,		/* version             */
459   sizeof(XmPrimitiveClassExtRec),	/* record_size         */
460   XmLabelGetBaselines,			/* widget_baseline     */
461   XmLabelGetDisplayRect,		/* widget_display_rect */
462   XmLabelMarginsProc,			/* widget_margins      */
463 };
464 
465 externaldef (xmlabelclassrec) XmLabelClassRec xmLabelClassRec = {
466   {
467     (WidgetClass) &xmPrimitiveClassRec,	/* superclass	       */
468     "XmLabel",				/* class_name	       */
469     sizeof(XmLabelRec),			/* widget_size	       */
470     ClassInitialize,			/* class_initialize    */
471     ClassPartInitialize,		/* chained class init  */
472     FALSE,				/* class_inited	       */
473     Initialize,				/* initialize	       */
474     NULL,				/* initialize hook     */
475     XtInheritRealize,			/* realize	       */
476     ActionsList,			/* actions	       */
477     XtNumber(ActionsList),		/* num_actions	       */
478     resources,				/* resources	       */
479     XtNumber(resources),		/* num_resources       */
480     NULLQUARK,				/* xrm_class	       */
481     TRUE,				/* compress_motion     */
482     XtExposeCompressMaximal,		/* compress_exposure   */
483     TRUE,				/* compress enter/exit */
484     FALSE,				/* visible_interest    */
485     Destroy,				/* destroy	       */
486     Resize,				/* resize	       */
487     Redisplay,				/* expose	       */
488     SetValues,				/* set_values	       */
489     NULL,				/* set values hook     */
490     SetValuesAlmost,			/* set values almost   */
491     NULL,				/* get values hook     */
492     NULL,				/* accept_focus	       */
493     XtVersion,				/* version	       */
494     NULL,				/* callback offsetlst  */
495     NULL,				/* default trans       */
496     QueryGeometry,			/* query geo proc      */
497     NULL,				/* display accelerator */
498     (XtPointer)&labelBaseClassExtRec	/* extension record    */
499   },
500 
501   { /* XmPrimitiveClassPart */
502     XmInheritBorderHighlight,		 /* border_highlight   */
503     XmInheritBorderUnhighlight,		 /* border_unhighlight */
504     XtInheritTranslations,		 /* translations       */
505     NULL,				 /* arm_and_activate   */
506     syn_resources,			 /* syn resources      */
507     XtNumber(syn_resources),		 /* num syn_resources  */
508     (XtPointer)&_XmLabelPrimClassExtRec, /* extension          */
509   },
510 
511   { /* XmLabelClassPart */
512     SetOverrideCallback,	/* override_callback             */
513     NULL,			/* menu procedure interface      */
514     NULL,			/* translations                  */
515     NULL			/* extension record              */
516   }
517 };
518 
519 externaldef(xmlabelwidgetclass) WidgetClass xmLabelWidgetClass =
520 				(WidgetClass) &xmLabelClassRec;
521 
522 /*********************************************************************
523  *
524  * ClassInitialize
525  *       This is the class initialization routine.  It is called only
526  *       the first time a widget of this class is initialized.
527  *
528  ********************************************************************/
529 
530 /*ARGSUSED*/
531 static void
ClassInitialize(void)532 ClassInitialize(void)
533 {
534   /* Parse the various translation tables */
535   menu_parsed	 = XtParseTranslationTable(menuTranslations);
536   default_parsed = XtParseTranslationTable(defaultTranslations);
537 
538   /* Set up base class extension quark */
539   labelBaseClassExtRec.record_type = XmQmotif;
540 
541   xmLabelClassRec.label_class.translations =
542     (String) (XtParseTranslationTable(menu_traversal_events));
543 
544   /* Install menu savvy on just this class */
545   XmeTraitSet((XtPointer) &xmLabelClassRec,
546 	      XmQTmenuSavvy, (XtPointer) &MenuSavvyRecord);
547 }
548 
549 void
_XmLabelCloneMenuSavvy(WidgetClass wc,XmMenuSavvyTrait mst)550 _XmLabelCloneMenuSavvy(WidgetClass wc,
551 		       XmMenuSavvyTrait mst)
552 {
553   /* Modify and reinstall menu savvy trait */
554   if (mst->version == -1)
555     {
556       mst->version = MenuSavvyRecord.version;
557       mst->disableCallback = MenuSavvyRecord.disableCallback;
558       mst->getAccelerator = MenuSavvyRecord.getAccelerator;
559       mst->getMnemonic = MenuSavvyRecord.getMnemonic;
560     }
561 
562   /* Install the new record */
563   XmeTraitSet((XtPointer) wc, XmQTmenuSavvy, (XtPointer) mst);
564 }
565 
_XmCBNameActivate()566 char* _XmCBNameActivate()
567 {
568   return XmNactivateCallback;
569 }
570 
_XmCBNameValueChanged()571 char* _XmCBNameValueChanged()
572 {
573   return XmNvalueChangedCallback;
574 }
575 
576 /************************************************************
577  *
578  * InitializePosthook
579  *	Restore core class translations.
580  *
581  ************************************************************/
582 
583 /*ARGSUSED*/
584 static void
InitializePosthook(Widget req,Widget new_w,ArgList args,Cardinal * num_args)585 InitializePosthook(Widget req,		/* unused */
586 		   Widget new_w,
587 		   ArgList args,	/* unused */
588 		   Cardinal *num_args)	/* unused */
589 {
590   _XmRestoreCoreClassTranslations (new_w);
591 }
592 
593 /*********************************************************************
594  *
595  *  ClassPartInitialize
596  *      Processes the class fields which need to be inherited.
597  *
598  ************************************************************************/
599 static void
ClassPartInitialize(WidgetClass c)600 ClassPartInitialize(WidgetClass c)
601 {
602   register XmLabelWidgetClass wc = (XmLabelWidgetClass) c;
603   XmLabelWidgetClass super = (XmLabelWidgetClass)wc->core_class.superclass;
604 
605   if (wc->label_class.setOverrideCallback == XmInheritSetOverrideCallback)
606     wc->label_class.setOverrideCallback =
607       super->label_class.setOverrideCallback;
608 
609   if (wc->label_class.translations == XtInheritTranslations)
610     wc->label_class.translations = super->label_class.translations;
611 
612   _XmFastSubclassInit (c, XmLABEL_BIT);
613 
614 
615   /* Install traits */
616   XmeTraitSet((XtPointer) c, XmQTtransfer, (XtPointer) &LabelTransfer);
617   XmeTraitSet((XtPointer) c, XmQTaccessTextual,
618 	      (XtPointer) &_XmLabel_AccessTextualRecord);
619 }
620 
621 /************************************************************
622  *
623  * InitializePrehook
624  *	Put the proper translations in core_class tm_table so
625  * that the data is massaged correctly.
626  *
627  ************************************************************/
628 
629 /*ARGSUSED*/
630 static void
InitializePrehook(Widget req,Widget new_w,ArgList args,Cardinal * num_args)631 InitializePrehook(Widget req,		/* unused */
632 		  Widget new_w,
633 		  ArgList args,		/* unused */
634 		  Cardinal *num_args)	/* unused */
635 {
636   unsigned char type;
637   XmMenuSystemTrait menuSTrait;
638 
639   _XmProcessLock();
640   if (new_w->core.widget_class->core_class.tm_table != NULL) {
641     _XmProcessUnlock();
642     return;
643   }
644 
645   _XmSaveCoreClassTranslations (new_w);
646 
647   menuSTrait = (XmMenuSystemTrait)
648     XmeTraitGet((XtPointer) XtClass((Widget) XtParent(new_w)), XmQTmenuSystem);
649 
650   if (menuSTrait != (XmMenuSystemTrait) NULL)
651     type = menuSTrait->type(XtParent(new_w));
652   else
653     type = XmWORK_AREA;
654 
655   if (type == XmWORK_AREA)
656     new_w->core.widget_class->core_class.tm_table = (String) default_parsed;
657   else
658     new_w->core.widget_class->core_class.tm_table = (String) menu_parsed;
659   _XmProcessUnlock();
660 }
661 
662 /************************************************************************
663  *
664  *  SetNormalGC
665  *      Create the normal and insensitive GC's for the gadget.
666  *
667  ************************************************************************/
668 
669 static void
SetNormalGC(XmLabelWidget lw)670 SetNormalGC(XmLabelWidget lw)
671 {
672   XGCValues       values;
673   XtGCMask        valueMask, dynamicMask;
674   XFontStruct     *fs = (XFontStruct *) NULL;
675 
676   valueMask = GCForeground | GCBackground | GCGraphicsExposures;
677   dynamicMask = GCClipMask | GCClipXOrigin | GCClipYOrigin;
678 
679   values.foreground = lw->primitive.foreground;
680   values.background = lw->core.background_pixel;
681   values.graphics_exposures = False;
682 
683   if (XmeRenderTableGetDefaultFont(lw->label.font, &fs))
684     values.font = fs->fid, valueMask |= GCFont;
685 
686   lw->label.normal_GC = XtAllocateGC((Widget) lw, 0, valueMask, &values,
687 				     dynamicMask, 0);
688 
689 #ifdef FIX_1381
690   /*generally gray insensitive foreground (instead stipple)*/
691   values.foreground =  _XmAssignInsensitiveColor((Widget)lw);
692   values.background = lw->core.background_pixel;
693 #else
694   valueMask |= GCFillStyle | GCStipple;
695   values.foreground = lw->core.background_pixel;
696   values.background = lw->primitive.foreground;
697   values.fill_style = FillOpaqueStippled;
698   values.stipple = _XmGetInsensitiveStippleBitmap((Widget) lw);
699 #endif
700 
701   lw->label.insensitive_GC = XtAllocateGC((Widget) lw, 0, valueMask, &values,
702 					  dynamicMask, 0);
703 #ifdef FIX_1381
704   /*light shadow for insensitive text (instead stipple)*/
705   values.foreground = lw->primitive.top_shadow_color;
706   lw->label.shadow_GC = XtAllocateGC((Widget) lw, 0, valueMask, &values,
707 					  dynamicMask, 0);
708 #endif
709 
710 }
711 
712 /************************************************************************
713  *
714  * _XmCalcLabelDimensions()
715  *   Calculates the dimensions of the label text and pixmap, and updates
716  *   the TextRect fields appropriately. Called at Initialize and SetValues.
717  *   Also called by subclasses to recalculate label dimensions.
718  *
719  ************************************************************************/
720 
721 void
_XmCalcLabelDimensions(Widget wid)722 _XmCalcLabelDimensions(Widget wid)
723 {
724   XmLabelWidget newlw = (XmLabelWidget) wid;
725   XmLabelPart  *lp = &(newlw->label);
726   unsigned int  w = 0, h = 0;
727 
728 
729   /* Initialize TextRect width and height to 0, change later if needed */
730   lp->acc_TextRect.width = 0;
731   lp->acc_TextRect.height = 0;
732   lp->StringRect.x = 0;
733   lp->StringRect.y = 0;
734   lp->StringRect.width = 0;
735   lp->StringRect.height = 0;
736   lp->PixmapRect.x = 0;
737   lp->PixmapRect.y = 0;
738   lp->PixmapRect.width = 0;
739   lp->PixmapRect.height = 0;
740 
741   if (Lab_IsPixmap(newlw) || Lab_IsPixmapAndText(newlw))
742     {
743       /* change NULL pixmap to refer to XmUNSPECIFIED_PIXMAP */
744       if (Pix(newlw) == (Pixmap)None)
745         Pix(newlw) = XmUNSPECIFIED_PIXMAP;
746       if (Pix_insen(newlw) == (Pixmap)None)
747         Pix_insen(newlw) = XmUNSPECIFIED_PIXMAP;
748 
749       /* Is a pixmap so find out how big it is. */
750       if (XtIsSensitive(wid))
751 	{
752 	  if (Pix(newlw) != XmUNSPECIFIED_PIXMAP)
753 	    {
754 	      XmeGetPixmapData(XtScreen(newlw), Pix(newlw),
755 			       NULL, NULL, NULL, NULL, NULL, NULL,
756 			       &w, &h);
757 
758 	      lp->PixmapRect.width = (unsigned short) w;
759 	      lp->PixmapRect.height = (unsigned short) h;
760 	    }
761 	}
762       else
763 	{
764 	  Pixmap pix_use = Pix_insen (newlw) ;
765 
766 	  if (pix_use == XmUNSPECIFIED_PIXMAP)
767 	      pix_use = Pix(newlw);
768 
769 	  if (pix_use != XmUNSPECIFIED_PIXMAP)
770 	    {
771 	      XmeGetPixmapData(XtScreen(newlw), pix_use,
772 			       NULL, NULL, NULL, NULL, NULL, NULL,
773 			       &w, &h);
774 
775 	      lp->PixmapRect.width = (unsigned short) w;
776 	      lp->PixmapRect.height = (unsigned short) h;
777 	    }
778 	}
779     }
780 
781   if (Lab_IsText(newlw) || Lab_IsPixmapAndText(newlw))
782     {
783       Dimension w, h;
784 
785       if (!XmStringEmpty (lp->_label))
786 	{
787 	  /* If we have a string then size it. */
788 	  XmStringExtent(lp->font, lp->_label, &w, &h);
789 	  lp->StringRect.width = (unsigned short)w;
790 	  lp->StringRect.height = (unsigned short)h;
791 	}
792     }
793 
794   _XmLabelCalcTextRect(wid);
795 
796  if (lp->_acc_text != NULL)
797    {
798      Dimension w, h;
799 
800      /* If we have a string then size it. */
801      if (!XmStringEmpty (lp->_acc_text))
802        {
803          XmStringExtent(lp->font, lp->_acc_text, &w, &h);
804          lp->acc_TextRect.width = (unsigned short)w;
805          lp->acc_TextRect.height = (unsigned short)h;
806        }
807    }
808 }
809 
810 void
_XmLabelCalcTextRect(Widget wid)811 _XmLabelCalcTextRect(Widget wid)
812 {
813   XmLabelWidget newlw = (XmLabelWidget) wid;
814   XmLabelPart  *lp = &(newlw->label);
815 
816   lp->TextRect.width = 0;
817   lp->TextRect.height = 0;
818 
819   if (Lab_IsPixmap(newlw))
820     {
821       lp->TextRect.width = lp->PixmapRect.width;
822       lp->TextRect.height = lp->PixmapRect.height;
823     }
824   else if (Lab_IsText(newlw))
825     {
826       lp->TextRect.width = lp->StringRect.width;
827       lp->TextRect.height = lp->StringRect.height;
828     }
829   else if (Lab_IsPixmapAndText(newlw))
830     {
831       if (lp->pixmap_placement == XmPIXMAP_TOP ||
832           lp->pixmap_placement == XmPIXMAP_BOTTOM)
833 	{
834           lp->TextRect.height =	lp->PixmapRect.height +
835           	lp->StringRect.height + lp->pixmap_text_padding;
836           lp->TextRect.width = MAX(lp->StringRect.width, lp->PixmapRect.width);
837 	}
838       else if (lp->pixmap_placement == XmPIXMAP_LEFT ||
839 	       lp->pixmap_placement == XmPIXMAP_RIGHT)
840         {
841           lp->TextRect.width = lp->PixmapRect.width +
842           	lp->StringRect.width + lp->pixmap_text_padding;
843           lp->TextRect.height = MAX(lp->StringRect.height, lp->PixmapRect.height);
844         }
845 
846       if (lp->pixmap_placement == XmPIXMAP_TOP)
847         {
848 	  lp->PixmapRect.y = 0;
849 	  lp->StringRect.y = lp->PixmapRect.height + lp->pixmap_text_padding;
850         }
851       else if (lp->pixmap_placement == XmPIXMAP_BOTTOM)
852         {
853           lp->StringRect.y = 0;
854           lp->PixmapRect.y = lp->StringRect.height + lp->pixmap_text_padding;
855         }
856       else if ((lp->pixmap_placement == XmPIXMAP_RIGHT &&
857 	        LayoutIsRtoLP(wid)) ||
858                (lp->pixmap_placement == XmPIXMAP_LEFT &&
859                 !LayoutIsRtoLP(wid)))
860 	{
861           lp->PixmapRect.x = 0;
862           lp->StringRect.x = lp->PixmapRect.width + lp->pixmap_text_padding;
863 	}
864       else if ((lp->pixmap_placement == XmPIXMAP_LEFT &&
865                 LayoutIsRtoLP(wid)) ||
866                (lp->pixmap_placement == XmPIXMAP_RIGHT &&
867                 !LayoutIsRtoLP(wid)))
868 	{
869 	   lp->StringRect.x = 0;
870 	   lp->PixmapRect.x = lp->StringRect.width + lp->pixmap_text_padding;
871 	}
872 
873       if (lp->pixmap_placement == XmPIXMAP_RIGHT ||
874 	    lp->pixmap_placement == XmPIXMAP_LEFT)
875         {
876           lp->PixmapRect.y = (lp->TextRect.height - lp->PixmapRect.height) / 2;
877           lp->StringRect.y = (lp->TextRect.height - lp->StringRect.height) / 2;
878         }
879       else
880         {
881           if (lp->alignment == XmALIGNMENT_CENTER)
882             {
883               lp->PixmapRect.x =
884 	        (lp->TextRect.width - lp->PixmapRect.width) / 2;
885               lp->StringRect.x =
886               	(lp->TextRect.width - lp->StringRect.width) / 2;
887             }
888           else if ((lp->alignment == XmALIGNMENT_END &&
889                      !LayoutIsRtoLP(wid)) ||
890                     (lp->alignment == XmALIGNMENT_BEGINNING &&
891                      LayoutIsRtoLP(wid)))
892             {
893               lp->PixmapRect.x = lp->TextRect.width - lp->PixmapRect.width;
894               lp->StringRect.x = lp->TextRect.width - lp->StringRect.width;
895             }
896         }
897     }
898 }
899 
900 /************************************************************************
901  *
902  *  Resize
903  *      Sets new width, new height, and new label.TextRect
904  *      appropriately. This routine is called by Initialize and
905  *      SetValues.
906  *
907  ************************************************************************/
908 
909 static void
Resize(Widget wid)910 Resize(Widget wid)
911 {
912   XmLabelWidget newlw = (XmLabelWidget) wid;
913   XmLabelPart *lp = &(newlw->label);
914   int leftx, rightx;
915 
916   /* Increase margin width if necessary to accomodate accelerator text. */
917   if (lp->_acc_text != NULL)
918     {
919       if (LayoutIsRtoLP(newlw))
920 	{
921           if (lp->margin_left < (Dimension) (lp->acc_TextRect.width + LABEL_ACC_PAD) )
922 	    {
923 	      int delta =
924 		lp->acc_TextRect.width + LABEL_ACC_PAD - lp->margin_left;
925 	      lp->acc_left_delta += delta;
926 	      lp->margin_left += delta;
927 	    }
928 	}
929       else
930 	{
931 	  if (lp->margin_right < (Dimension) (lp->acc_TextRect.width + LABEL_ACC_PAD) )
932 	    {
933 	      int delta =
934 		lp->acc_TextRect.width + LABEL_ACC_PAD - lp->margin_right;
935 	      lp->acc_right_delta += delta;
936 	      lp->margin_right += delta;
937 	    }
938 	}
939     }
940 
941   /* Has a width been specified?  */
942   if (newlw->core.width == 0)
943     newlw->core.width = (Dimension)
944       lp->TextRect.width +
945 	lp->margin_left + lp->margin_right +
946 	  (2 * (lp->margin_width
947 		+ newlw->primitive.highlight_thickness
948 		+ newlw->primitive.shadow_thickness));
949 
950   leftx = (newlw->primitive.highlight_thickness +
951 	   newlw->primitive.shadow_thickness +
952 	   lp->margin_width + lp->margin_left);
953 
954   rightx = (newlw->core.width -
955 	    (newlw->primitive.highlight_thickness +
956 	     newlw->primitive.shadow_thickness +
957 	     lp->margin_width + lp->margin_right));
958 
959   switch (lp->alignment)
960     {
961     case XmALIGNMENT_BEGINNING:
962       if (LayoutIsRtoLP(newlw))
963 	lp->TextRect.x = rightx - lp->TextRect.width;
964       else
965 	lp->TextRect.x = leftx;
966       break;
967 
968     case XmALIGNMENT_END:
969       if (LayoutIsRtoLP(newlw))
970 	lp->TextRect.x = leftx;
971       else
972 	lp->TextRect.x = rightx - lp->TextRect.width;
973       break;
974 
975     default:
976       /* CR 9737: Be careful about casting here, since rounding during */
977       /*	division on Suns depends on the sign. */
978       lp->TextRect.x = leftx + (rightx - leftx - (int)lp->TextRect.width) / 2;
979       break;
980     }
981 
982   /* Has a height been specified? */
983   if (newlw->core.height == 0)
984     newlw->core.height = (Dimension)
985       MAX(lp->TextRect.height, lp->acc_TextRect.height) +
986 	lp->margin_top +
987 	  lp->margin_bottom
988 	    + (2 * (lp->margin_height
989 		    + newlw->primitive.highlight_thickness
990 		    + newlw->primitive.shadow_thickness));
991 
992   lp->TextRect.y =  (short) (newlw->primitive.highlight_thickness
993 			     + newlw->primitive.shadow_thickness
994 			     + lp->margin_height + lp->margin_top +
995 			     ((int) (newlw->core.height - lp->margin_top
996 			       - lp->margin_bottom
997 			       - (2 * (lp->margin_height
998 				       + newlw->primitive.highlight_thickness
999 				       + newlw->primitive.shadow_thickness))
1000 			       - lp->TextRect.height) / 2));
1001 
1002   if (lp->_acc_text != NULL)
1003     {
1004       Dimension  base_label, base_accText, diff;
1005 
1006       if (LayoutIsRtoLP(newlw))
1007 	lp->acc_TextRect.x = newlw->primitive.highlight_thickness +
1008 	  newlw->primitive.shadow_thickness +
1009 	    newlw->label.margin_width;
1010       else
1011 	lp->acc_TextRect.x = (short) newlw->core.width -
1012 	  newlw->primitive.highlight_thickness -
1013 	    newlw->primitive.shadow_thickness -
1014 	      newlw->label.margin_width -
1015 		newlw->label.margin_right + LABEL_ACC_PAD;
1016 
1017       lp->acc_TextRect.y =
1018 	(short) (newlw->primitive.highlight_thickness
1019 		 + newlw->primitive.shadow_thickness
1020 		 + lp->margin_height + lp->margin_top +
1021 		 ((int) (newlw->core.height - lp->margin_top
1022 		   - lp->margin_bottom
1023 		   - (2 * (lp->margin_height
1024 			   + newlw->primitive.highlight_thickness
1025 			   + newlw->primitive.shadow_thickness))
1026 				       - lp->acc_TextRect.height) / 2));
1027 
1028       /* make sure the label and accelerator text line up */
1029       /* when the fonts are different */
1030 
1031       if (Lab_IsText(newlw) || Lab_IsPixmapAndText(newlw))
1032 	{
1033 	  base_label = XmStringBaseline (lp->font, lp->_label);
1034 	  base_accText = XmStringBaseline (lp->font, lp->_acc_text);
1035 
1036 	  if (base_label > base_accText)
1037 	    {
1038 	      diff = base_label - base_accText;
1039 	      lp->acc_TextRect.y = (short) lp->TextRect.y + diff - 1;
1040 	    }
1041 	  else if (base_label < base_accText)
1042 	    {
1043 	      diff = base_accText - base_label;
1044 	      lp->TextRect.y = (short) lp->acc_TextRect.y + diff - 1;
1045 	    }
1046 	}
1047     }
1048 
1049   if (newlw->core.width == 0)    /* set core width and height to a */
1050     newlw->core.width = 1;       /* default value so that it doesn't */
1051   if (newlw->core.height == 0)   /* generate a Toolkit Error */
1052     newlw->core.height = 1;
1053 }
1054 
1055 /************************************************************
1056  *
1057  * Initialize
1058  *    This is the widget's instance initialize routine.  It is
1059  *    called once for each widget
1060  *
1061  ************************************************************/
1062 /*ARGSUSED*/
1063 static void
Initialize(Widget req,Widget new_w,ArgList args,Cardinal * num_args)1064 Initialize(
1065         Widget req,
1066         Widget new_w,
1067         ArgList args,		/* unused */
1068         Cardinal *num_args)	/* unused */
1069 {
1070   XmLabelWidget lw = (XmLabelWidget) new_w;
1071   XmMenuSystemTrait menuSTrait;
1072   XtTranslations	trans;
1073 
1074   lw->label.baselines = NULL;
1075   lw->label.computing_size = FALSE;
1076 
1077   /* if menuProcs is not set up yet, try again */
1078   if (xmLabelClassRec.label_class.menuProcs == NULL)
1079     xmLabelClassRec.label_class.menuProcs =
1080       (XmMenuProc) _XmGetMenuProcContext();
1081 
1082   /* Check for Invalid enumerated types */
1083 
1084   if (!XmRepTypeValidValue(XmRID_LABEL_TYPE, lw->label.label_type, (Widget) lw))
1085     {
1086       lw->label.label_type = XmSTRING;
1087     }
1088 
1089   if (!XmRepTypeValidValue(XmRID_ALIGNMENT, lw->label.alignment, (Widget) lw))
1090     {
1091       lw->label.alignment = XmALIGNMENT_CENTER;
1092     }
1093 
1094   if (!XmRepTypeValidValue(XmRID_PIXMAP_PLACEMENT, lw->label.pixmap_placement, (Widget) lw))
1095     {
1096       lw->label.pixmap_placement = XmPIXMAP_LEFT;
1097     }
1098 #ifndef NO_XM_1_2_BC
1099   /*
1100    * Some pre-Motif 2.0 XmManager subclasses may be bypassing the
1101    * synthetic resouce GetValues hook and passing us the manager's raw
1102    * string_direction field (which is now a layout_direction).  Fixup
1103    * the common/simple cases.
1104    */
1105   switch (lw->label.string_direction)
1106     {
1107     case XmLEFT_TO_RIGHT:
1108     case XmRIGHT_TO_LEFT:
1109       /* These string directions are erroneous uses of layout directions. */
1110       lw->label.string_direction =
1111 	XmDirectionToStringDirection(lw->label.string_direction);
1112       break;
1113     default:
1114       /* Other unknown layout directions will still get a warning. */
1115       break;
1116     }
1117 #endif
1118 
1119   /* If layout_direction is set, it overrides string_direction.
1120    * If string_direction is set, but not layout_direction, use
1121    *	string_direction value.
1122    * If neither is set, get from parent
1123    */
1124   if (XmPrim_layout_direction(lw) != XmDEFAULT_DIRECTION) {
1125     if (lw->label.string_direction == XmDEFAULT_DIRECTION)
1126       lw->label.string_direction =
1127 	XmDirectionToStringDirection(XmPrim_layout_direction(lw));
1128   } else if (lw->label.string_direction != XmDEFAULT_DIRECTION) {
1129     XmPrim_layout_direction(lw) =
1130       XmStringDirectionToDirection(lw->label.string_direction);
1131   } else {
1132     XmPrim_layout_direction(lw) = _XmGetLayoutDirection(XtParent(new_w));
1133     lw->label.string_direction =
1134       XmDirectionToStringDirection(XmPrim_layout_direction(lw));
1135   }
1136 
1137   if (!XmRepTypeValidValue(XmRID_STRING_DIRECTION,
1138 			   lw->label.string_direction, (Widget) lw))
1139     {
1140       lw->label.string_direction = XmSTRING_DIRECTION_L_TO_R;
1141     }
1142 
1143   /* Make a local copy of the font list */
1144   if (lw->label.font == NULL)
1145     {
1146       /* CR 2990: Let subclasses choose their own default font. */
1147       lw->label.font = XmeGetDefaultRenderTable (new_w, XmLABEL_FONTLIST);
1148     }
1149   lw->label.font = XmFontListCopy(lw->label.font);
1150 
1151   menuSTrait = (XmMenuSystemTrait)
1152     XmeTraitGet((XtPointer) XtClass(XtParent(new_w)), XmQTmenuSystem);
1153 
1154   /* get menu type and which button */
1155   if (menuSTrait != (XmMenuSystemTrait) NULL)
1156     lw->label.menu_type = menuSTrait->type(XtParent(new_w));
1157   else
1158     lw->label.menu_type = XmWORK_AREA;
1159 
1160   /*  Handle the label string :
1161    *   If label is the constant XmUNSPECIFIED, creates a empty XmString.
1162    *    (this is used by DrawnB instead of a default conversion that leads
1163    *     to a leak when someone provides a real label)
1164    *   If no label string is given accept widget's name as default.
1165    *     convert the widgets name to an XmString before storing;
1166    *   else
1167    *     save a copy of the given string.
1168    *     If the given string is not an XmString issue an warning.
1169    */
1170   if (lw->label._label == (XmString) XmUNSPECIFIED)
1171     {
1172       lw->label._label = XmeGetLocalizedString ((char *) NULL, /* reserved */
1173 						(Widget) lw,
1174 						XmNlabelString,
1175 						"");
1176     }
1177   else if (lw->label._label == NULL)
1178     {
1179       lw->label._label = XmeGetLocalizedString ((char *) NULL, /* reserved */
1180 						(Widget) lw,
1181 						XmNlabelString,
1182 						lw->core.name);
1183     }
1184   else if (XmeStringIsValid(lw->label._label))
1185     {
1186       lw->label._label= XmStringCopy(lw->label._label);
1187     }
1188   else
1189     {
1190       XmeWarning((Widget) lw, CS_STRING_MESSAGE);
1191       lw->label._label = XmStringCreateLocalized(lw->core.name);
1192     }
1193 
1194   /*
1195    * Convert the given mnemonicCharset to the internal Xm-form.
1196    */
1197   if  (lw->label.mnemonicCharset != NULL)
1198     lw->label.mnemonicCharset =
1199       _XmStringCharSetCreate (lw->label.mnemonicCharset);
1200   else
1201     lw->label.mnemonicCharset =
1202       _XmStringCharSetCreate (XmFONTLIST_DEFAULT_TAG);
1203 
1204   /* Accelerators are currently only supported in menus */
1205   if ((lw->label._acc_text != NULL) && Lab_IsMenupane(lw))
1206     {
1207       if (XmeStringIsValid((XmString) lw->label._acc_text))
1208         {
1209 	  /*
1210 	   * Copy the input string into local space, if
1211 	   * not a Cascade Button
1212 	   */
1213 	  if (XmIsCascadeButton(lw))
1214 	    lw->label._acc_text = NULL;
1215 	  else
1216 	    lw->label._acc_text =
1217 	      XmStringCopy((XmString) lw->label._acc_text);
1218         }
1219       else
1220         {
1221 	  XmeWarning((Widget) lw, ACC_MESSAGE);
1222 	  lw->label._acc_text = NULL;
1223         }
1224     }
1225   else
1226     lw->label._acc_text = NULL;
1227 
1228 
1229   if ((lw->label.accelerator != NULL) && Lab_IsMenupane(lw))
1230     {
1231       /* Copy the accelerator into local space */
1232       lw->label.accelerator = XtNewString(lw->label.accelerator);
1233     }
1234   else
1235     lw->label.accelerator = NULL;
1236 
1237   lw->label.skipCallback = FALSE;
1238 
1239   lw->label.acc_right_delta = 0;
1240   lw->label.acc_left_delta = 0;
1241 
1242   /*  If zero width and height was requested by the application,  */
1243   /*  reset new_w's width and height to zero to allow Resize()   */
1244   /*  to operate properly.                                        */
1245 
1246   if (req->core.width == 0)
1247     lw->core.width = 0;
1248 
1249   if (req->core.height == 0)
1250     lw->core.height = 0;
1251 
1252   /* CR 6267:  Suppress highlight thickness before sizing also. */
1253   if ((lw->label.menu_type == XmMENU_POPUP) ||
1254       (lw->label.menu_type == XmMENU_PULLDOWN) ||
1255       (lw->label.menu_type == XmMENU_BAR))
1256     lw->primitive.highlight_thickness = 0;
1257 
1258   _XmCalcLabelDimensions(new_w);
1259 
1260   /* CR 7283: We can't use the resize method pointer, because */
1261   /*	subclasses haven't been initialized yet.	      */
1262   Resize((Widget) lw);
1263 
1264   SetNormalGC(lw);
1265 
1266   /* Force the label traversal flag when in a menu. */
1267 
1268   if ((XtClass(lw) == xmLabelWidgetClass) &&
1269       ((lw->label.menu_type == XmMENU_POPUP) ||
1270        (lw->label.menu_type == XmMENU_PULLDOWN) ||
1271        (lw->label.menu_type == XmMENU_OPTION)))
1272     {
1273       lw->primitive.traversal_on = FALSE;
1274       lw->primitive.highlight_on_enter = FALSE;
1275     }
1276 
1277   /* if in menu, override with menu traversal translations */
1278   if ((lw->label.menu_type == XmMENU_POPUP) ||
1279       (lw->label.menu_type == XmMENU_PULLDOWN) ||
1280       (lw->label.menu_type == XmMENU_BAR) ||
1281       (lw->label.menu_type == XmMENU_OPTION))
1282     {
1283 
1284       _XmProcessLock();
1285       trans = (XtTranslations)
1286 	  ((XmLabelClassRec *)XtClass(lw))->label_class.translations;
1287       _XmProcessUnlock();
1288 
1289       XtOverrideTranslations((Widget) lw, trans);
1290     }
1291   else
1292     {
1293 
1294       _XmProcessLock();
1295       trans = (XtTranslations)
1296 	  ((XmPrimitiveClassRec *) XtClass(lw))->primitive_class.translations;
1297       _XmProcessUnlock();
1298 
1299       /* Otherwise override with primitive traversal translations */
1300       XtOverrideTranslations((Widget) lw, trans);
1301     }
1302 }
1303 
1304 /************************************************************************
1305  *
1306  *  QueryGeometry
1307  *
1308  ************************************************************************/
1309 static XtGeometryResult
QueryGeometry(Widget widget,XtWidgetGeometry * intended,XtWidgetGeometry * desired)1310 QueryGeometry(
1311         Widget widget,
1312         XtWidgetGeometry *intended,
1313         XtWidgetGeometry *desired)
1314 {
1315   XmLabelWidget lw = (XmLabelWidget) widget;
1316 
1317   if (lw->label.recompute_size == FALSE)
1318     {
1319       desired->width = XtWidth(widget);
1320       desired->height = XtHeight(widget);
1321     }
1322   else
1323     {
1324       desired->width = (Dimension) lw->label.TextRect.width +
1325 	(2 * (lw->label.margin_width +
1326 	      lw->primitive.highlight_thickness +
1327 	      lw->primitive.shadow_thickness)) +
1328 		lw->label.margin_left +
1329 		  lw->label.margin_right;
1330       if (desired->width == 0)
1331 	desired->width = 1;
1332 
1333       desired->height = (Dimension) MAX(lw->label.TextRect.height,
1334 					lw->label.acc_TextRect.height)
1335 	+ (2 * (lw->label.margin_height +
1336 		lw->primitive.highlight_thickness +
1337 		lw->primitive.shadow_thickness)) +
1338 		  lw->label.margin_top +
1339 		    lw->label.margin_bottom;
1340       if (desired->height == 0)
1341 	desired->height = 1;
1342     }
1343 
1344   return XmeReplyToQueryGeometry(widget, intended, desired);
1345 }
1346 
1347 /************************************************************************
1348  *
1349  *  Destroy
1350  *      Free up the label gadget allocated space.  This includes
1351  *      the label, and GC's.
1352  *
1353  ************************************************************************/
1354 static void
Destroy(Widget w)1355 Destroy(
1356         Widget w)
1357 {
1358   XmLabelWidget lw = (XmLabelWidget) w;
1359 
1360   if (lw->label._label != NULL)
1361     XmStringFree (lw->label._label);
1362 
1363   if (lw->label._acc_text != NULL)
1364     XmStringFree (lw->label._acc_text);
1365 
1366   if (lw->label.accelerator != NULL)
1367     XtFree (lw->label.accelerator);
1368 
1369   if (lw->label.font != NULL)
1370     XmFontListFree (lw->label.font);
1371 
1372   if (lw->label.mnemonicCharset != NULL)
1373     XtFree (lw->label.mnemonicCharset);
1374 
1375   if (lw->label.baselines != NULL)
1376     XtFree ((char*) lw->label.baselines);
1377 
1378   XtReleaseGC ((Widget) lw, lw->label.normal_GC);
1379   XtReleaseGC ((Widget) lw, lw->label.insensitive_GC);
1380 #ifdef FIX_1381
1381   XtReleaseGC ((Widget) lw, lw->label.shadow_GC);
1382 #endif
1383 }
1384 
1385 /************************************************************************
1386  *
1387  *  Redisplay
1388  *
1389 
1390  ***********************************************************************/
1391 static void
Redisplay(Widget wid,XEvent * event,Region region)1392 Redisplay(
1393         Widget wid,
1394         XEvent *event,
1395         Region region)
1396 {
1397   XmLabelWidget lw = (XmLabelWidget) wid;
1398   GC gc;
1399   GC clipgc = NULL;
1400   XRectangle clip_rect;
1401   XmLabelPart *lp;
1402   Dimension availW, availH, marginal_width, marginal_height, max_text_height;
1403   int depth;
1404 
1405   lp = &(lw->label);
1406 
1407   /*
1408    * Set a clipping area if the label will overwrite critical margins.
1409    * A critical margin is defined to be "margin_{left,right,
1410    * top,bottom} margin" because it used for other things
1411    * such as default_button_shadows and accelerators.   Note that
1412    * overwriting the "margin_{width,height}" margins is allowed.
1413    */
1414   availH = lw->core.height;
1415   availW = lw->core.width;
1416 
1417   /* Adjust definitions of temporary variables */
1418   marginal_width = lp->margin_left + lp->margin_right +
1419     (2 * (lw->primitive.highlight_thickness +
1420 	  lw->primitive.shadow_thickness));
1421 
1422   marginal_height = lp->margin_top + lp->margin_bottom +
1423     (2 * (lw->primitive.highlight_thickness +
1424 	  lw->primitive.shadow_thickness));
1425 
1426   max_text_height = MAX(lp->TextRect.height, lp->acc_TextRect.height);
1427 
1428   if (XtIsSensitive(wid))
1429     clipgc = lp->normal_GC;
1430   else
1431     clipgc = lp->insensitive_GC;
1432 
1433   if ((availH < (Dimension)(marginal_height + max_text_height)) ||
1434       (availW < (Dimension)(marginal_width + lp->TextRect.width)))
1435     {
1436       clip_rect.x = lw->primitive.highlight_thickness +
1437 	lw->primitive.shadow_thickness + lp->margin_left;
1438       clip_rect.y = lw->primitive.highlight_thickness +
1439 	lw->primitive.shadow_thickness + lp->margin_top;
1440 
1441       /* Don't allow negative dimensions. */
1442       if (availW > marginal_width)
1443 	clip_rect.width = availW - marginal_width;
1444       else
1445 	clip_rect.width = 0;
1446 
1447       if (availH > marginal_height)
1448 	clip_rect.height = availH - marginal_height;
1449       else
1450 	clip_rect.height = 0;
1451 
1452       XSetClipRectangles(XtDisplay(lw), clipgc, 0,0, &clip_rect, 1, Unsorted);
1453 #ifdef FIX_1521
1454 #ifdef USE_XFT
1455       _XmXftSetClipRectangles(XtDisplay(lw), XtWindow(lw), 0, 0, &clip_rect, 1);
1456 #endif
1457 #endif
1458     } else
1459     {
1460       XSetClipMask (XtDisplay (lw), clipgc, None);
1461 #ifdef FIX_1521
1462 #ifdef USE_XFT
1463       XftDraw* draw = _XmXftDrawCreate(XtDisplay(lw), XtWindow(lw));
1464       XftDrawSetClip(draw, NULL);
1465 #endif
1466 #endif
1467     }
1468 
1469 #ifdef USE_XFT
1470     /* it is needed to clear anti-aliased text before draw it again */
1471     if ((Lab_IsText (lw) || Lab_IsPixmapAndText(lw)) && (lp->_label != NULL)
1472 		&& lp->TextRect.width > 0 && lp->TextRect.height > 0)
1473       {
1474         XClearArea(XtDisplay(lw), XtWindow(lw),
1475 			lp->TextRect.x,
1476 			lp->TextRect.y,
1477  			lp->TextRect.width,
1478 			lp->TextRect.height, False);
1479      }
1480 #endif
1481 
1482   if (Lab_IsPixmap(lw) || Lab_IsPixmapAndText(lw))
1483     {
1484       if (XtIsSensitive(wid))
1485 	{
1486 	  if (Pix (lw) != XmUNSPECIFIED_PIXMAP)
1487 	    {
1488 	      gc = lp->normal_GC;
1489 
1490 	      XmeGetPixmapData(XtScreen(lw), Pix(lw), NULL, &depth,
1491 			       NULL, NULL, NULL, NULL, NULL, NULL);
1492 
1493 	      if (depth == lw->core.depth)
1494 		XCopyArea (XtDisplay(lw), Pix(lw), XtWindow(lw), gc, 0, 0,
1495 			   lp->PixmapRect.width,
1496 			   lp->PixmapRect.height,
1497 			   lp->TextRect.x + lp->PixmapRect.x,
1498 			   lp->TextRect.y + lp->PixmapRect.y);
1499 	      else if (depth == 1)
1500 		XCopyPlane (XtDisplay(lw), Pix(lw), XtWindow(lw),
1501 			    gc, 0, 0,
1502 			    lp->PixmapRect.width,
1503 			    lp->PixmapRect.height,
1504 			    lp->TextRect.x + lp->PixmapRect.x,
1505 			    lp->TextRect.y + lp->PixmapRect.y,
1506 			    1);
1507 	    }
1508 	}
1509       else
1510 	{
1511 	  Pixmap pix_use = Pix_insen (lw) ;
1512 
1513 	  if (pix_use == XmUNSPECIFIED_PIXMAP)
1514 #ifdef FIX_1381
1515 		Pix_insen(lw) = pix_use = _XmConvertToBW(wid, Pix(lw));
1516 #else
1517 		pix_use = Pix(lw);
1518 #endif
1519 	  if (pix_use != XmUNSPECIFIED_PIXMAP)
1520 	    {
1521 	      gc = lp->insensitive_GC;
1522 
1523 	      XmeGetPixmapData(XtScreen(lw), pix_use, NULL, &depth,
1524 			       NULL, NULL, NULL, NULL, NULL, NULL);
1525 
1526 	      if (depth == lw->core.depth)
1527 		XCopyArea (XtDisplay(lw), pix_use, XtWindow(lw),
1528 			   gc, 0, 0,
1529 			   lp->PixmapRect.width,
1530 			   lp->PixmapRect.height,
1531 			   lp->TextRect.x + lp->PixmapRect.x,
1532 			   lp->TextRect.y + lp->PixmapRect.y);
1533 	      else if (depth == 1)
1534 		XCopyPlane (XtDisplay(lw), pix_use, XtWindow(lw),
1535 			    gc, 0, 0,
1536 			    lp->PixmapRect.width,
1537 			    lp->PixmapRect.height,
1538 			    lp->TextRect.x + lp->PixmapRect.x,
1539 			    lp->TextRect.y + lp->PixmapRect.y,
1540 			    1);
1541 
1542 #ifndef FIX_1381
1543 	      /* if no insensitive pixmap but a regular one, we need
1544  		 to do the stipple manually, since copyarea doesn't */
1545  	      if (pix_use == Pix(lw)) {
1546  		  /* need fill stipple, not opaque */
1547  		  XSetFillStyle(XtDisplay(lw), gc, FillStippled);
1548  		  XFillRectangle(XtDisplay(lw), XtWindow(lw), gc,
1549 			lp->TextRect.x + lp->PixmapRect.x,
1550 			lp->TextRect.y + lp->PixmapRect.y,
1551  			lp->PixmapRect.width,
1552 			lp->PixmapRect.height);
1553  		  XSetFillStyle(XtDisplay(lw), gc, FillOpaqueStippled);
1554 
1555  	      }
1556 #endif
1557 #ifdef FIX_1505
1558 	      if (pix_use == Pix(lw)) {
1559 		  XSetFillStyle(XtDisplay(lw), gc, FillStippled);
1560 		  XSetStipple(XtDisplay(lw), gc, _XmGetInsensitiveStippleBitmap((Widget)lw));
1561 		  XFillRectangle(XtDisplay(lw), XtWindow(lw), gc,
1562 			lp->TextRect.x + lp->PixmapRect.x,
1563 			lp->TextRect.y + lp->PixmapRect.y,
1564 			lp->PixmapRect.width,
1565 			lp->PixmapRect.height);
1566 		  XSetFillStyle(XtDisplay(lw), gc, FillSolid);
1567 
1568 	      }
1569 #endif
1570 	    }
1571 	}
1572     }
1573 
1574   if ((Lab_IsText (lw) || Lab_IsPixmapAndText(lw)) && (lp->_label != NULL))
1575     {
1576       if (lp->mnemonic != XK_VoidSymbol)
1577 	{
1578 	  /* CR 5181: Convert the mnemonic keysym to a character string. */
1579 	  char tmp[MB_LEN_MAX * 2];
1580 	  XmString underline;
1581 
1582  	  tmp[_XmOSKeySymToCharacter(lp->mnemonic, NULL, tmp)] = '\0';
1583 	  underline = XmStringCreate(tmp, lp->mnemonicCharset);
1584 
1585 #ifdef FIX_1381
1586 	  if (XtIsSensitive(wid) )
1587 	  {
1588 		  /*Draw normal text*/
1589 		  XmStringDrawUnderline(XtDisplay(lw), XtWindow(lw),
1590 				  lp->font, lp->_label,
1591 				  lp->normal_GC,
1592 				  lp->TextRect.x + lp->StringRect.x,
1593 				  lp->TextRect.y + lp->StringRect.y,
1594 				  lp->StringRect.width,
1595 				  lp->alignment,
1596 				  XmPrim_layout_direction(lw), NULL,
1597 				  underline);
1598 	  }
1599 	  else
1600 	  {
1601 		  /*Draw shadow for insensitive text*/
1602 		  XmStringDrawUnderline(XtDisplay(lw), XtWindow(lw),
1603 				  lp->font, lp->_label,
1604 				  lp->shadow_GC,
1605 				  lp->TextRect.x+1 + lp->StringRect.x,
1606 				  lp->TextRect.y+1 + lp->StringRect.y,
1607 				  lp->StringRect.width,
1608 				  lp->alignment,
1609 				  XmPrim_layout_direction(lw), NULL,
1610 				  underline);
1611 		  /*Draw insensitive text*/
1612 		  XmStringDrawUnderline(XtDisplay(lw), XtWindow(lw),
1613 				  lp->font, lp->_label,
1614 				  lp->insensitive_GC,
1615 				  lp->TextRect.x + lp->StringRect.x,
1616 				  lp->TextRect.y + lp->StringRect.y,
1617 				  lp->StringRect.width,
1618 				  lp->alignment,
1619 				  XmPrim_layout_direction(lw), NULL,
1620 				  underline);
1621 
1622 	  }
1623 #else
1624 	  XmStringDrawUnderline(XtDisplay(lw), XtWindow(lw),
1625 				lp->font, lp->_label,
1626 				(XtIsSensitive(wid) ?
1627 				 lp->normal_GC : lp->insensitive_GC),
1628 				lp->TextRect.x + lp->StringRect.x,
1629 				lp->TextRect.y + lp->StringRect.y,
1630 				lp->StringRect.width,
1631 				lp->alignment,
1632 				XmPrim_layout_direction(lw), NULL,
1633 				underline);
1634 #endif
1635 	  XmStringFree(underline);
1636 	}
1637       else
1638 #ifdef FIX_1381
1639 	{
1640 	  if (XtIsSensitive(wid) )
1641 	  {
1642 	  /*Draw normal text*/
1643 	  XmStringDraw (XtDisplay(lw), XtWindow(lw),
1644 			  lp->font, lp->_label,
1645   			  lp->normal_GC,
1646 			  lp->TextRect.x + lp->StringRect.x,
1647 			  lp->TextRect.y + lp->StringRect.y,
1648 			  lp->StringRect.width,
1649 			  lp->alignment,
1650 			  XmPrim_layout_direction(lw), NULL);
1651 	  }
1652 	else
1653 	  {
1654 	    /*Draw shadow for insensitive text*/
1655 	    XmStringDraw (XtDisplay(lw), XtWindow(lw),
1656 			  lp->font, lp->_label,
1657 			  lp->shadow_GC,
1658 			  lp->TextRect.x+1 + lp->StringRect.x,
1659 			  lp->TextRect.y+1 + lp->StringRect.y,
1660 			  lp->StringRect.width,
1661 			  lp->alignment,
1662 			  XmPrim_layout_direction(lw), NULL);
1663 	    /*Draw insensitive text*/
1664 	    XmStringDraw (XtDisplay(lw), XtWindow(lw),
1665 			  lp->font, lp->_label,
1666 			  lp->insensitive_GC,
1667 			  lp->TextRect.x + lp->StringRect.x,
1668 			  lp->TextRect.y + lp->StringRect.y,
1669 			  lp->StringRect.width,
1670 			  lp->alignment,
1671 			  XmPrim_layout_direction(lw), NULL);
1672 	  }
1673 	}
1674 #else
1675 	XmStringDraw (XtDisplay(lw), XtWindow(lw),
1676 		       lp->font, lp->_label,
1677 		       (XtIsSensitive(wid) ?
1678 			lp->normal_GC : lp->insensitive_GC),
1679 		       lp->TextRect.x + lp->StringRect.x,
1680 		       lp->TextRect.y + lp->StringRect.y,
1681 		       lp->StringRect.width,
1682 		       lp->alignment,
1683 		       XmPrim_layout_direction(lw), NULL);
1684 #endif
1685 
1686 #ifndef FIX_1381
1687 #ifdef USE_XFT
1688       if (!XtIsSensitive(wid))
1689         {
1690           XSetFillStyle(XtDisplay(lw), lp->insensitive_GC, FillStippled);
1691           XFillRectangle(XtDisplay(lw), XtWindow(lw), lp->insensitive_GC,
1692 			lp->TextRect.x + lp->StringRect.x,
1693 			lp->TextRect.y + lp->StringRect.y,
1694  			lp->StringRect.width,
1695 			lp->StringRect.height);
1696           XSetFillStyle(XtDisplay(lw), lp->insensitive_GC, FillOpaqueStippled);
1697         }
1698 #endif
1699 #endif
1700 
1701     }
1702 
1703   if (lp->_acc_text != NULL)
1704     {
1705       /* Since accelerator text  is drawn by moving in from the right,
1706        * it is possible to overwrite label text when there is clipping,
1707        * Therefore draw accelerator text only if there is enough
1708        * room for everything
1709        */
1710 
1711       if (lw->core.width >= (Dimension)
1712 	  (2 * (lw->primitive.highlight_thickness +
1713 		lw->primitive.shadow_thickness +
1714 		lp->margin_width) +
1715 	   lp->margin_left + lp->TextRect.width + lp->margin_right))
1716 	     {
1717 #ifdef FIX_1381
1718 		  if (XtIsSensitive(wid) )
1719 		  {
1720 			  /*Draw normal text*/
1721 			  XmStringDraw (XtDisplay(lw), XtWindow(lw),
1722 					  lp->font, lp->_acc_text,
1723      				   lp->normal_GC,
1724 					  lp->acc_TextRect.x, lp->acc_TextRect.y,
1725 					  lp->acc_TextRect.width, XmALIGNMENT_END,
1726 					  XmPrim_layout_direction(lw), NULL);
1727 		  }
1728 		  else
1729 		  {
1730 			/*Draw shadow for insensitive text*/
1731 			XmStringDraw (XtDisplay(lw), XtWindow(lw),
1732 					  lp->font, lp->_acc_text,
1733 					   lp->shadow_GC,
1734 					  lp->acc_TextRect.x+1, lp->acc_TextRect.y+1,
1735 					  lp->acc_TextRect.width, XmALIGNMENT_END,
1736 					  XmPrim_layout_direction(lw), NULL);
1737 			/*Draw insensitive text*/
1738 			XmStringDraw (XtDisplay(lw), XtWindow(lw),
1739 					  lp->font, lp->_acc_text,
1740 					   lp->insensitive_GC,
1741 					  lp->acc_TextRect.x, lp->acc_TextRect.y,
1742 					  lp->acc_TextRect.width, XmALIGNMENT_END,
1743 					  XmPrim_layout_direction(lw), NULL);
1744 		  }
1745 #else
1746 	XmStringDraw (XtDisplay(lw), XtWindow(lw),
1747 		       lp->font, lp->_acc_text,
1748 		       (XtIsSensitive(wid) ?
1749 			lp->normal_GC : lp->insensitive_GC),
1750 		       lp->acc_TextRect.x, lp->acc_TextRect.y,
1751 		       lp->acc_TextRect.width, XmALIGNMENT_END,
1752 		       XmPrim_layout_direction(lw), NULL);
1753 #endif
1754 	     }
1755     }
1756 
1757   /* Redraw the proper highlight  */
1758   if (! Lab_IsMenupane(lw) && Lab_MenuType(lw) != XmMENU_BAR)
1759     {
1760       XtExposeProc expose;
1761 
1762       _XmProcessLock();
1763       expose = (xmPrimitiveClassRec.core_class.expose);
1764       _XmProcessUnlock();
1765 
1766       /* Envelop our superclass expose method */
1767       (*(expose))((Widget) lw, event, region);
1768     }
1769 }
1770 
1771 /**********************************************************************
1772  *
1773  * Enter
1774  *
1775  *********************************************************************/
1776 
1777 static void
Enter(Widget wid,XEvent * event,String * params,Cardinal * num_params)1778 Enter(Widget wid,
1779       XEvent *event,
1780       String *params,
1781       Cardinal *num_params)
1782 {
1783   XmLabelWidget w = (XmLabelWidget) wid;
1784 
1785   if (w->primitive.highlight_on_enter)
1786     _XmPrimitiveEnter (wid, event, params, num_params);
1787 }
1788 
1789 /**********************************************************************
1790  *
1791  * Leave
1792  *
1793  *********************************************************************/
1794 
1795 static void
Leave(Widget wid,XEvent * event,String * params,Cardinal * num_params)1796 Leave(Widget wid,
1797       XEvent *event,
1798       String *params,
1799       Cardinal *num_params)
1800 {
1801   XmLabelWidget w = (XmLabelWidget) wid;
1802 
1803   if (w->primitive.highlight_on_enter)
1804     _XmPrimitiveLeave ((Widget) w, event, params, num_params);
1805 }
1806 
1807 /************************************************************************
1808  *
1809  * SetValues
1810  *	This routine will take care of any changes that have been made.
1811  *
1812  ************************************************************************/
1813 
1814 /*ARGSUSED*/
1815 static Boolean
SetValues(Widget cw,Widget rw,Widget nw,ArgList args,Cardinal * num_args)1816 SetValues(Widget cw,
1817 	  Widget rw,
1818 	  Widget nw,
1819 	  ArgList args,		/* unused */
1820 	  Cardinal *num_args)	/* unused */
1821 {
1822   XmLabelWidget current = (XmLabelWidget) cw;
1823   XmLabelWidget req = (XmLabelWidget) rw;
1824   XmLabelWidget new_w = (XmLabelWidget) nw;
1825   Boolean flag = FALSE;
1826   Boolean newstring = FALSE;
1827   XmLabelPart        *newlp, *curlp, *reqlp;
1828   Boolean ProcessFlag = FALSE;
1829   Boolean CleanupFontFlag = FALSE;
1830   Boolean Call_Resize = False;
1831   XmMenuSystemTrait menuSTrait;
1832 
1833   /* Get pointers to the label parts  */
1834   newlp = &(new_w->label);
1835   curlp = &(current->label);
1836   reqlp = &(req->label);
1837 
1838 
1839   /* Discard the baseline cache if it is no longer valid. */
1840   if ((newlp->_label != curlp->_label) ||
1841       (newlp->font != curlp->font))
1842     {
1843       if (newlp->baselines)
1844 	{
1845 	  XtFree ((char*) newlp->baselines);
1846 	  newlp->baselines = NULL;
1847 	}
1848     }
1849 
1850   /* If the label has changed, make a copy of the new label */
1851   /* and free the old label.                                */
1852 
1853   if (newlp->_label != curlp->_label)
1854     {
1855       newstring = TRUE;
1856       if (newlp->_label == NULL)
1857 	{
1858           newlp->_label = XmStringCreateLocalized(new_w->core.name);
1859 	}
1860       else
1861 	{
1862 	  if (XmeStringIsValid((XmString) newlp->_label))
1863 	    newlp->_label = XmStringCopy((XmString) newlp->_label);
1864 	  else
1865 	    {
1866 	      XmeWarning((Widget) new_w, CS_STRING_MESSAGE);
1867 
1868 	      newlp->_label = XmStringCreateLocalized(new_w->core.name);
1869 	    }
1870 	}
1871 
1872       XmStringFree(curlp->_label);
1873       curlp->_label= NULL;
1874       reqlp->_label= NULL;
1875     }
1876 
1877 
1878   if (newlp->margin_right != curlp->margin_right)
1879     newlp->acc_right_delta = 0;
1880   if (newlp->margin_left != curlp->margin_left)
1881     newlp->acc_left_delta = 0;
1882 
1883   if ((newlp->_acc_text != curlp->_acc_text) &&
1884       Lab_IsMenupane(new_w))
1885     {
1886       /* BEGIN OSF Fix pir 1098 */
1887       newstring = TRUE;
1888       /* END OSF Fix pir 1098 */
1889       if (newlp->_acc_text != NULL)
1890 	{
1891 	  if (XmeStringIsValid((XmString) newlp->_acc_text))
1892 	    {
1893 	      if ((XmIsCascadeButton (new_w)) && (newlp->_acc_text != NULL))
1894 		newlp->_acc_text = NULL;
1895 	      else
1896 		newlp->_acc_text = XmStringCopy((XmString) newlp->_acc_text);
1897 
1898 	      XmStringFree(curlp->_acc_text);
1899 	      curlp->_acc_text= NULL;
1900 	      reqlp->_acc_text= NULL;
1901 	    }
1902 	  else
1903 	    {
1904 	      XmeWarning((Widget) new_w, ACC_MESSAGE);
1905 	      newlp->_acc_text = NULL;
1906 	      curlp->_acc_text= NULL;
1907 	      reqlp->_acc_text= NULL;
1908 	    }
1909 	}
1910       /* BEGIN OSF Fix pir 1098 */
1911       else if (curlp->_acc_text)
1912 	{
1913 	  /* CR 3481:  Don't blindly force the margin back to 0; */
1914 	  /* 	try to preserve the user specified value. */
1915 	  if (LayoutIsRtoLP(new_w))
1916 	    {
1917 	      newlp->margin_left -= newlp->acc_left_delta;
1918 	      newlp->acc_left_delta = 0;
1919 	    }
1920 	  else
1921 	    {
1922 	      newlp->margin_right -= newlp->acc_right_delta;
1923 	      newlp->acc_right_delta = 0;
1924 	    }
1925 	}
1926       /* END OSF Fix pir 1098 */
1927     }
1928   else
1929     newlp->_acc_text = curlp->_acc_text;
1930 
1931 
1932   if (newlp->font != curlp->font)
1933     {
1934       CleanupFontFlag = True;
1935       if (newlp->font == NULL)
1936 	{
1937 	  /* CR 2990:  Let subclasses determine default fonts. */
1938 	  newlp->font =
1939 	    XmeGetDefaultRenderTable((Widget) new_w, XmLABEL_FONTLIST);
1940 	}
1941       newlp->font = XmFontListCopy (newlp->font);
1942 
1943     }
1944 
1945   if ((new_w->label.menu_type == XmMENU_POPUP) ||
1946       (new_w->label.menu_type == XmMENU_PULLDOWN) ||
1947       (new_w->label.menu_type == XmMENU_BAR))
1948     new_w->primitive.highlight_thickness = 0;
1949 
1950   if (!XmRepTypeValidValue(XmRID_LABEL_TYPE, new_w->label.label_type,
1951 			   (Widget) new_w))
1952     {
1953       new_w->label.label_type = current->label.label_type;
1954     }
1955 #ifdef FIX_1484
1956   if (!XmRepTypeValidValue(XmRID_PIXMAP_PLACEMENT, new_w->label.pixmap_placement,
1957 #else
1958   if (!XmRepTypeValidValue(XmRID_LABEL_TYPE, new_w->label.pixmap_placement,
1959 #endif
1960 			   (Widget) new_w))
1961     {
1962       new_w->label.pixmap_placement = current->label.pixmap_placement;
1963     }
1964 
1965   if (LayoutP(new_w) != LayoutP(current))
1966     {
1967       /* if no new margins specified swap them */
1968       if ((LayoutIsRtoLP(current) != LayoutIsRtoLP(new_w)) &&
1969 	  (Lab_MarginLeft(current)  == Lab_MarginLeft(new_w)) &&
1970 	  (Lab_MarginRight(current) == Lab_MarginRight(new_w)))
1971 	{
1972 	  Lab_MarginLeft(new_w)  = Lab_MarginRight(current);
1973 	  Lab_MarginRight(new_w) = Lab_MarginLeft(current);
1974 	}
1975       flag = TRUE;
1976     }
1977 
1978   /* ValidateInputs(new_w); */
1979 #ifdef FIX_1504
1980   _XmCalcLabelDimensions((Widget) new_w);
1981   Boolean pixmap_size_changed = ((newlp->PixmapRect.width
1982       != curlp->PixmapRect.width) || (newlp->PixmapRect.height
1983       != curlp->PixmapRect.height));
1984 #endif
1985 
1986   if (((Lab_IsText(new_w) || Lab_IsPixmapAndText(new_w)) &&
1987        ((newstring) ||
1988 	(newlp->font != curlp->font))) ||
1989       ((Lab_IsPixmap(new_w) || Lab_IsPixmapAndText(new_w)) &&
1990        ((newlp->pixmap != curlp->pixmap) ||
1991 	(newlp->pixmap_insen  != curlp->pixmap_insen) ||
1992 	/* When you have different sized pixmaps for sensitive and */
1993 	/* insensitive states and sensitivity changes, */
1994 	/* the right size is chosen. (osfP2560) */
1995 #ifdef FIX_1504
1996 	(XtIsSensitive(nw) != XtIsSensitive(cw))) && pixmap_size_changed) ||
1997 #else
1998 	(XtIsSensitive(nw) != XtIsSensitive(cw)))) ||
1999 #endif
2000       (Lab_IsPixmapAndText(new_w) &&
2001 	(newlp->pixmap_placement != curlp->pixmap_placement)) ||
2002       (newlp->label_type != curlp->label_type))
2003     {
2004       /* CR 9179: Redo CR 5419 changes. */
2005 
2006       if (newlp->recompute_size)
2007 	{
2008 	  if (req->core.width == current->core.width)
2009 	    new_w->core.width = 0;
2010 	  if (req->core.height == current->core.height)
2011 	    new_w->core.height = 0;
2012 	}
2013 
2014 #ifndef FIX_1504
2015       _XmCalcLabelDimensions((Widget) new_w);
2016 #endif
2017 
2018       Call_Resize = True;
2019 
2020       flag = True;
2021     }
2022 
2023   if ((newlp->alignment != curlp->alignment) ||
2024       (XmPrim_layout_direction(new_w) !=
2025        XmPrim_layout_direction(current)))
2026     {
2027       if (!XmRepTypeValidValue(XmRID_ALIGNMENT, new_w->label.alignment,
2028 			       (Widget) new_w))
2029 	{
2030 	  new_w->label.alignment = current->label.alignment;
2031 	}
2032 
2033       Call_Resize = True;
2034 
2035       flag = True;
2036     }
2037 
2038   if ((newlp->margin_height != curlp->margin_height) ||
2039       (newlp->margin_width != curlp->margin_width) ||
2040       (newlp->margin_left != curlp->margin_left) ||
2041       (newlp->margin_right != curlp->margin_right) ||
2042       (newlp->margin_top != curlp->margin_top) ||
2043       (newlp->margin_bottom != curlp->margin_bottom) ||
2044       (new_w->primitive.shadow_thickness !=
2045        current->primitive.shadow_thickness) ||
2046       (new_w->primitive.highlight_thickness !=
2047        current->primitive.highlight_thickness) ||
2048       ((new_w->core.width <= 0) || (new_w->core.height <= 0)) ||
2049       (newlp->pixmap_text_padding != curlp->pixmap_text_padding))
2050     {
2051       if (!XmRepTypeValidValue(XmRID_ALIGNMENT, new_w->label.alignment,
2052 			       (Widget) new_w))
2053         {
2054 	  new_w->label.alignment = current->label.alignment;
2055         }
2056 
2057       if (!XmRepTypeValidValue(XmRID_STRING_DIRECTION,
2058 			       new_w->label.string_direction, (Widget) new_w))
2059         {
2060 	  new_w->label.string_direction = current->label.string_direction;
2061         }
2062 
2063       if (newlp->recompute_size)
2064         {
2065           if (req->core.width == current->core.width)
2066             new_w->core.width = 0;
2067           if (req->core.height == current->core.height)
2068             new_w->core.height = 0;
2069         }
2070 
2071       Call_Resize = True;
2072 
2073       flag = True;
2074     }
2075 
2076 
2077   /* Resize is called only if we need to calculate the dimensions or */
2078   /* coordinates  for the string.				     */
2079   if (Call_Resize)
2080     {
2081       XtWidgetProc resize;
2082 
2083       /* CR 5419: Suppress redundant calls to DrawnB's resize callbacks. */
2084       Boolean was_computing = newlp->computing_size;
2085 
2086       newlp->computing_size = TRUE;
2087 
2088       _XmProcessLock();
2089       resize = new_w->core.widget_class->core_class.resize;
2090       _XmProcessUnlock();
2091 
2092       (* (resize)) ((Widget) new_w);
2093       newlp->computing_size = was_computing;
2094     }
2095 
2096 
2097 
2098   /*
2099    * If sensitivity of the label has changed then we must redisplay
2100    *  the label.
2101    */
2102   if (XtIsSensitive(nw) != XtIsSensitive(cw))
2103     {
2104       flag = TRUE;
2105     }
2106 
2107   if ((new_w->primitive.foreground != current->primitive.foreground) ||
2108       (new_w->core.background_pixel != current->core.background_pixel) ||
2109       (newlp->font != curlp->font))
2110     {
2111       XtReleaseGC((Widget) current, current->label.normal_GC);
2112       XtReleaseGC((Widget) current, current->label.insensitive_GC);
2113       SetNormalGC(new_w);
2114       flag = TRUE;
2115     }
2116 
2117   /*  Force the traversal flag when in a menu.  */
2118 
2119   if ((XtClass(new_w) == xmLabelWidgetClass) &&
2120       ((new_w->label.menu_type == XmMENU_POPUP) ||
2121        (new_w->label.menu_type == XmMENU_PULLDOWN) ||
2122        (new_w->label.menu_type == XmMENU_OPTION)))
2123     {
2124       new_w->primitive.traversal_on = FALSE;
2125       new_w->primitive.highlight_on_enter = FALSE;
2126     }
2127 
2128   if (new_w->primitive.traversal_on &&
2129       (new_w->primitive.traversal_on != current->primitive.traversal_on) &&
2130       new_w->core.tm.translations)
2131     {
2132 
2133      XtTranslations trans;
2134 
2135      if ((new_w->label.menu_type == XmMENU_POPUP) ||
2136 	  (new_w->label.menu_type == XmMENU_PULLDOWN) ||
2137 	  (new_w->label.menu_type == XmMENU_BAR) ||
2138 	  (new_w->label.menu_type == XmMENU_OPTION))
2139 	{
2140 
2141 	  _XmProcessLock();
2142 	  trans = (XtTranslations)
2143 	      ((XmLabelClassRec *)XtClass(new_w))->label_class.translations;
2144 	  _XmProcessUnlock();
2145 	  if (trans) XtOverrideTranslations((Widget)new_w, trans);
2146 	}
2147       else
2148 	{
2149 
2150 	  _XmProcessLock();
2151 	  trans = (XtTranslations)
2152 	     ((XmLabelClassRec*) XtClass(new_w))->primitive_class.translations;
2153 	  _XmProcessUnlock();
2154 	  if (trans) XtOverrideTranslations ((Widget)new_w, trans);
2155 	}
2156     }
2157 
2158   if ((new_w->label.menu_type != XmWORK_AREA) &&
2159       (new_w->label.mnemonic != current->label.mnemonic))
2160     {
2161       /* New grabs only required if mnemonic changes */
2162       ProcessFlag = TRUE;
2163       if (new_w->label.label_type == XmSTRING ||
2164           new_w->label.label_type == XmPIXMAP_AND_STRING)
2165 	flag = TRUE;
2166     }
2167 
2168   if (new_w->label.mnemonicCharset != current->label.mnemonicCharset)
2169     {
2170       if (new_w->label.mnemonicCharset)
2171 	new_w->label.mnemonicCharset =
2172 	  _XmStringCharSetCreate(new_w->label.mnemonicCharset);
2173       else
2174 	new_w->label.mnemonicCharset =
2175 	  _XmStringCharSetCreate(XmFONTLIST_DEFAULT_TAG);
2176 
2177       if (current->label.mnemonicCharset != NULL)
2178 	XtFree (current->label.mnemonicCharset);
2179 
2180       if (new_w->label.label_type == XmSTRING ||
2181           new_w->label.label_type == XmPIXMAP_AND_STRING)
2182 	flag = TRUE;
2183     }
2184 
2185   if (Lab_IsMenupane(new_w) &&
2186       (new_w->label.accelerator != current->label.accelerator))
2187     {
2188       if (newlp->accelerator != NULL)
2189 	{
2190 	  /* Copy the accelerator into local space */
2191 	  newlp->accelerator = XtNewString(newlp->accelerator);
2192 	}
2193 
2194       XtFree(curlp->accelerator);
2195       curlp->accelerator = NULL;
2196       reqlp->accelerator = NULL;
2197       ProcessFlag = TRUE;
2198     }
2199   else
2200     newlp->accelerator = curlp->accelerator;
2201 
2202   menuSTrait = (XmMenuSystemTrait)
2203     XmeTraitGet((XtPointer) XtClass(XtParent(current)), XmQTmenuSystem);
2204 
2205   if (ProcessFlag && menuSTrait != NULL)
2206     menuSTrait->updateBindings((Widget)new_w, XmREPLACE);
2207 
2208   if (flag &&
2209       (new_w->label.menu_type == XmMENU_PULLDOWN) && menuSTrait != NULL)
2210     menuSTrait->updateHistory(XtParent(new_w), (Widget) new_w, True);
2211 
2212   if (CleanupFontFlag)
2213     if (curlp->font) XmFontListFree(curlp->font);
2214 
2215   return flag;
2216 }
2217 
2218 /************************************************************************
2219  *
2220  *  SetActivateCallbackState
2221  *
2222  * This function is used as the method of the menuSavvy trait. It is
2223  * used by menu savvy parents to set whether or not the child will
2224  * invoke its own activate callback or whether it will defer to the
2225  * entryCallback of the parent.
2226  *
2227  ************************************************************************/
2228 
2229 static void
SetActivateCallbackState(Widget wid,XmActivateState state)2230 SetActivateCallbackState(Widget          wid,
2231 			 XmActivateState state)
2232 {
2233   XmLabelWidget w = (XmLabelWidget) wid;
2234 
2235   switch (state)
2236     {
2237     case XmDISABLE_ACTIVATE:
2238       w->label.skipCallback = True;
2239       break;
2240 
2241     case XmENABLE_ACTIVATE:
2242       w->label.skipCallback = False;
2243       break;
2244     }
2245 }
2246 
2247 /************************************************************************
2248  *
2249  * SetOverrideCallback
2250  *	Used by subclasses.  If this is set true, then there is a RowColumn
2251  * parent with the entryCallback resource set.  The subclasses do not
2252  * do their activate callbacks, instead the RowColumn callbacks are called
2253  * by RowColumn.
2254  ************************************************************************/
2255 
2256 static void
SetOverrideCallback(Widget wid)2257 SetOverrideCallback(Widget wid)
2258 {
2259   XmLabelWidget w = (XmLabelWidget) wid;
2260 
2261   w->label.skipCallback = True;
2262 }
2263 
2264 /************************************************************************
2265  *
2266  *  Help
2267  *      This routine is called if the user made a help selection
2268  *      on the widget.
2269  *
2270  ************************************************************************/
2271 
2272 static void
Help(Widget w,XEvent * event,String * params,Cardinal * num_params)2273 Help(Widget w,
2274      XEvent *event,
2275      String *params,
2276      Cardinal *num_params)
2277 {
2278   XmLabelWidget lw = (XmLabelWidget) w;
2279   Widget parent = XtParent(lw);
2280   XmMenuSystemTrait menuSTrait;
2281 
2282   menuSTrait = (XmMenuSystemTrait)
2283     XmeTraitGet((XtPointer) XtClass(XtParent(lw)), XmQTmenuSystem);
2284 
2285   if (Lab_IsMenupane(lw) && menuSTrait != NULL)
2286     menuSTrait->popdown((Widget) parent, event);
2287 
2288   _XmPrimitiveHelp((Widget) w, event, params, num_params);
2289 }
2290 
2291 /************************************************************************
2292  *
2293  * GetLabelString
2294  *	This is a get values hook function that returns the external
2295  * form of the label string from the internal form.
2296  *
2297  ***********************************************************************/
2298 
2299 /*ARGSUSED*/
2300 static void
GetLabelString(Widget wid,int resource,XtArgVal * value)2301 GetLabelString(Widget wid,
2302 	       int resource,	/* unused */
2303 	       XtArgVal *value)
2304 {
2305   XmLabelWidget lw = (XmLabelWidget) wid;
2306   XmString string;
2307 
2308   string = XmStringCopy(lw->label._label);
2309 
2310   *value = (XtArgVal) string;
2311 }
2312 
2313 /************************************************************************
2314  *
2315  *  GetAccelerator
2316  *     This is a get values hook function that returns a copy
2317  *     of the accelerator string.
2318  *
2319  ***********************************************************************/
2320 
2321 /*ARGSUSED*/
2322 static void
GetAccelerator(Widget wid,int resource,XtArgVal * value)2323 GetAccelerator(Widget wid,
2324 	       int resource,	/* unused */
2325 	       XtArgVal *value)
2326 {
2327   XmLabelWidget lw = (XmLabelWidget) wid;
2328   String string;
2329 
2330   string = XtNewString(Lab_Accelerator(lw));
2331 
2332   *value = (XtArgVal) string;
2333 }
2334 
2335 /************************************************************************
2336  *
2337  *  GetAcceleratorText
2338  *     This is a get values hook function that returns the external
2339  *     form of the accelerator text from the internal form.
2340  *
2341  ***********************************************************************/
2342 
2343 /*ARGSUSED*/
2344 static void
GetAcceleratorText(Widget wid,int resource,XtArgVal * value)2345 GetAcceleratorText(Widget wid,
2346 		   int resource, /* unused */
2347 		   XtArgVal *value)
2348 {
2349   XmLabelWidget lw = (XmLabelWidget) wid;
2350   XmString string;
2351 
2352   string = XmStringCopy(lw->label._acc_text);
2353 
2354   *value = (XtArgVal) string;
2355 }
2356 
2357 /************************************************************************
2358  *
2359  *  XmCreateLabel()
2360  *  XmVaCreateLabel()
2361  *  XmVaCreateManagedLabel()
2362  *      Externally accessable function for creating a label gadget.
2363  *
2364  ************************************************************************/
2365 
2366 Widget
XmCreateLabel(Widget parent,char * name,Arg * arglist,Cardinal argCount)2367 XmCreateLabel(Widget parent,
2368 	      char *name,
2369 	      Arg *arglist,
2370 	      Cardinal argCount)
2371 {
2372   return XtCreateWidget(name,xmLabelWidgetClass,parent,arglist,argCount);
2373 }
2374 
2375 Widget
XmVaCreateLabel(Widget parent,char * name,...)2376 XmVaCreateLabel(
2377         Widget parent,
2378         char *name,
2379         ...)
2380 {
2381     register Widget w;
2382     va_list var;
2383     int count;
2384 
2385     Va_start(var,name);
2386     count = XmeCountVaListSimple(var);
2387     va_end(var);
2388 
2389 
2390     Va_start(var, name);
2391     w = XmeVLCreateWidget(name,
2392                          xmLabelWidgetClass,
2393                          parent, False,
2394                          var, count);
2395     va_end(var);
2396     return w;
2397 
2398 }
2399 
2400 Widget
XmVaCreateManagedLabel(Widget parent,char * name,...)2401 XmVaCreateManagedLabel(
2402         Widget parent,
2403         char *name,
2404         ...)
2405 {
2406     Widget w = NULL;
2407     va_list var;
2408     int count;
2409 
2410     Va_start(var, name);
2411     count = XmeCountVaListSimple(var);
2412     va_end(var);
2413 
2414     Va_start(var, name);
2415     w = XmeVLCreateWidget(name,
2416                          xmLabelWidgetClass,
2417                          parent, True,
2418                          var, count);
2419     va_end(var);
2420     return w;
2421 
2422 }
2423 
2424 
2425 static XmStringCharSet
_XmStringCharSetCreate(XmStringCharSet stringcharset)2426 _XmStringCharSetCreate(XmStringCharSet stringcharset)
2427 {
2428   return (XmStringCharSet) XtNewString((char*) stringcharset);
2429 }
2430 
2431 /************************************************************************
2432  *
2433  * GetMnemonicCharSet
2434  *	 This is a get values hook function that returns the external
2435  * form of the mnemonicCharSet from the internal form.  Returns a
2436  * string containg the mnemonicCharSet.  Caller must free the string.
2437  ***********************************************************************/
2438 
2439 /*ARGSUSED*/
2440 static void
GetMnemonicCharSet(Widget wid,int resource,XtArgVal * value)2441 GetMnemonicCharSet(Widget wid,
2442 		   int resource, /* unused */
2443 		   XtArgVal *value)
2444 {
2445   XmLabelWidget lw = (XmLabelWidget) wid;
2446   char *cset;
2447   int   size;
2448 
2449   cset = NULL;
2450   if (lw->label.mnemonicCharset)
2451     {
2452       size = strlen (lw->label.mnemonicCharset);
2453       if (size > 0)
2454 	cset = (char *) (_XmStringCharSetCreate(lw->label.mnemonicCharset));
2455     }
2456 
2457   *value = (XtArgVal) cset;
2458 }
2459 
2460 /*ARGSUSED*/
2461 static void
SetValuesAlmost(Widget cw,Widget nw,XtWidgetGeometry * request,XtWidgetGeometry * reply)2462 SetValuesAlmost(Widget cw,	/* unused */
2463 		Widget nw,
2464 		XtWidgetGeometry *request,
2465 		XtWidgetGeometry *reply)
2466 {
2467   XmLabelWidget new_w = (XmLabelWidget) nw;
2468   XtWidgetProc resize;
2469 
2470   _XmProcessLock();
2471   resize = new_w->core.widget_class->core_class.resize;
2472   _XmProcessUnlock();
2473 
2474   (* (resize)) ((Widget) new_w);
2475   *request = *reply;
2476 }
2477 
2478 /************************************************************************
2479  *
2480  * XmLabelGetDisplayRect
2481  *	A Class function which returns True if the widget being passed in
2482  * has a display rectangle associated with it.  It also determines the
2483  * x,y coordinates of the character cell or pixmap relative to the origin,
2484  * and the width and height in pixels of the smallest rectangle that encloses
2485  * the text or pixmap.  This is assigned to the variable being passed in
2486  *
2487  ***********************************************************************/
2488 
2489 static Boolean
XmLabelGetDisplayRect(Widget w,XRectangle * displayrect)2490 XmLabelGetDisplayRect(Widget w,
2491 		      XRectangle *displayrect)
2492 {
2493   XmLabelWidget wid = (XmLabelWidget) w;
2494 
2495   (*displayrect).x = wid->label.TextRect.x;
2496   (*displayrect).y = wid->label.TextRect.y;
2497   (*displayrect).width = wid->label.TextRect.width;
2498   (*displayrect).height = wid->label.TextRect.height;
2499 
2500   return TRUE;
2501 }
2502 
2503 /************************************************************************
2504  *
2505  * XmLabelGetBaselines
2506  *	A Class function which when called returns True, if the widget
2507  * has a baseline and also determines the number of pixels from the y
2508  * origin to the first line of text and assigns it to the variable
2509  * being passed in.
2510  *
2511  ************************************************************************/
2512 
2513 static Boolean
XmLabelGetBaselines(Widget wid,Dimension ** baselines,int * line_count)2514 XmLabelGetBaselines(Widget wid,
2515 		    Dimension **baselines,
2516 		    int *line_count)
2517 {
2518   XmLabelWidget lw = (XmLabelWidget)wid;
2519   Cardinal count;
2520   int delta;
2521 
2522   if (Lab_IsPixmap(wid))
2523     return False;
2524 
2525   /* Compute raw baselines if unavailable. */
2526   if (lw->label.baselines == NULL)
2527     {
2528       _XmStringGetBaselines(lw->label.font, lw->label._label,
2529 			    &(lw->label.baselines), &count);
2530       assert(lw->label.baselines != NULL);
2531 
2532       /* Store the current offset in an extra location. */
2533       lw->label.baselines = (Dimension*)
2534 	XtRealloc((char*) lw->label.baselines, (count+1) * sizeof(Dimension));
2535       lw->label.baselines[count] = 0;
2536     }
2537   else
2538     {
2539       count = XmStringLineCount(lw->label._label);
2540     }
2541 
2542   /* Readjust offsets if necessary. */
2543   delta = Lab_TextRect_y(lw) - lw->label.baselines[count];
2544   if (delta)
2545     {
2546       int tmp;
2547       for (tmp = 0; tmp <= count; tmp++)
2548 	lw->label.baselines[tmp] += delta;
2549     }
2550 
2551   /* Copy the cached data. */
2552   *line_count = count;
2553   *baselines = (Dimension*) XtMalloc(*line_count * sizeof(Dimension));
2554   memcpy((char*) *baselines, (char*) lw->label.baselines,
2555 	 *line_count * sizeof(Dimension));
2556 
2557   return True;
2558 }
2559 /************************************************************************
2560  *
2561  * XmLabelMarginsProc
2562  *
2563  ***********************************************************************/
2564 
2565 /* ARGSUSED */
2566 static void
XmLabelMarginsProc(Widget w,XmBaselineMargins * margins_rec)2567 XmLabelMarginsProc(Widget w,
2568 		   XmBaselineMargins *margins_rec)
2569 {
2570 
2571   if (margins_rec->get_or_set == XmBASELINE_SET) {
2572     Lab_MarginTop(w) = margins_rec->margin_top;
2573     Lab_MarginBottom(w) = margins_rec->margin_bottom;
2574   } else {
2575     margins_rec->margin_top = Lab_MarginTop(w);
2576     margins_rec->margin_bottom = Lab_MarginBottom(w);
2577     margins_rec->shadow = Lab_Shadow(w);
2578     margins_rec->highlight = Lab_Highlight(w);
2579     margins_rec->text_height = Lab_TextRect_height(w);
2580     margins_rec->margin_height = Lab_MarginHeight(w);
2581   }
2582 }
2583 
2584 
2585 static Widget
GetPixmapDragIcon(Widget w)2586 GetPixmapDragIcon(Widget w)
2587 {
2588   XmLabelWidget lw = (XmLabelWidget) w;
2589   Arg args[10];
2590   int n;
2591   Widget drag_icon;
2592   Widget screen_object = XmGetXmScreen(XtScreen(w));
2593   unsigned int width, height;
2594   int depth;
2595 
2596   /* It's a labelPixmap, use directly the pixmap */
2597 
2598   XmeGetPixmapData(XtScreen(lw), Pix(lw), NULL, &depth,
2599 		   NULL, NULL, NULL, NULL, &width, &height);
2600 
2601   n = 0;
2602   XtSetArg(args[n], XmNhotX, 0),				n++;
2603   XtSetArg(args[n], XmNhotY, 0),				n++;
2604   XtSetArg(args[n], XmNwidth, width),				n++;
2605   XtSetArg(args[n], XmNheight, height),				n++;
2606   XtSetArg(args[n], XmNmaxWidth, width),			n++;
2607   XtSetArg(args[n], XmNmaxHeight, height),			n++;
2608   XtSetArg(args[n], XmNdepth, depth),				n++;
2609   XtSetArg(args[n], XmNpixmap, Pix(lw)),			n++;
2610   XtSetArg(args[n], XmNforeground, lw->core.background_pixel),	n++;
2611   XtSetArg(args[n], XmNbackground, lw->primitive.foreground),	n++;
2612   assert(n <= XtNumber(args));
2613   drag_icon = XtCreateWidget("drag_icon", xmDragIconObjectClass,
2614 			     screen_object, args, n);
2615   return drag_icon;
2616 }
2617 
2618 /*ARGSUSED*/
2619 static void
ProcessDrag(Widget w,XEvent * event,String * params,Cardinal * num_params)2620 ProcessDrag(Widget w,
2621 	    XEvent *event,
2622 	    String *params,
2623 	    Cardinal *num_params)
2624 {
2625   XmLabelWidget lw = (XmLabelWidget) w;
2626   Widget drag_icon;
2627   Arg args[10];
2628   int n;
2629   Time _time = _XmGetDefaultTime(w, event);
2630   XmDisplay dpy = (XmDisplay) XmGetXmDisplay(XtDisplay(w));
2631 
2632   if (Lab_IsMenupane(w))
2633     XAllowEvents(XtDisplay(w), SyncPointer, _time);
2634 
2635   /* Disallow drag if this is a cascade button and armed - Hack alert */
2636   if (XmIsCascadeButton(w) && CB_IsArmed(w)) return;
2637 
2638   /* CDE - allow user to not drag labels and label subclasses
2639      also,  disable drag if enable_btn1_transfer is set to
2640      BUTTON2_ADJUST and the trigger was button2 */
2641   if (! dpy -> display.enable_unselectable_drag ||
2642       (dpy -> display.enable_btn1_transfer == XmBUTTON2_ADJUST &&
2643        event && event -> xany.type == ButtonPress &&
2644        event -> xbutton.button == 2)) return;
2645 
2646   /* CR 5141: Don't allow multi-button drags; they just cause confusion. */
2647   if (event && ! (event->xbutton.state &
2648 	 ~((Button1Mask >> 1) << event->xbutton.button) &
2649 	 (Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask)))
2650     {
2651       n = 0;
2652       XtSetArg(args[n], XmNcursorBackground, lw->core.background_pixel), n++;
2653       XtSetArg(args[n], XmNcursorForeground, lw->primitive.foreground),  n++;
2654 
2655       /* If it's a labelPixmap, only specify the pixmap icon */
2656       if (Lab_IsPixmap(lw) && (Pix(lw) != XmUNSPECIFIED_PIXMAP))
2657 	{
2658 	  drag_icon = GetPixmapDragIcon(w);
2659 	  XtSetArg(args[n], XmNsourcePixmapIcon, drag_icon), n++;
2660 	}
2661       else
2662 	{
2663 	  drag_icon = XmeGetTextualDragIcon(w);
2664 	  XtSetArg(args[n], XmNsourceCursorIcon, drag_icon), n++;
2665 	}
2666       XtSetArg(args[n], XmNdragOperations, XmDROP_COPY), n++;
2667       (void) XmeDragSource(w, NULL, event, args, n);
2668     }
2669 }
2670 
2671 /*ARGSUSED*/
2672 void
_XmLabelConvert(Widget w,XtPointer ignore,XmConvertCallbackStruct * cs)2673 _XmLabelConvert(Widget w,
2674 		XtPointer ignore,
2675 		XmConvertCallbackStruct *cs)
2676 {
2677   enum { XmA_MOTIF_COMPOUND_STRING, XmACOMPOUND_TEXT, XmATEXT,
2678 	 XmATARGETS, XmA_MOTIF_DROP, XmABACKGROUND, XmAFOREGROUND,
2679 	 XmAPIXEL, XmA_MOTIF_EXPORT_TARGETS,
2680 	 XmA_MOTIF_CLIPBOARD_TARGETS,
2681 #ifdef UTF8_SUPPORTED
2682 	 XmAUTF8_STRING,
2683 #endif
2684 	 NUM_ATOMS };
2685   static char *atom_names[] = {
2686     XmS_MOTIF_COMPOUND_STRING, XmSCOMPOUND_TEXT, XmSTEXT,
2687     XmSTARGETS, XmS_MOTIF_DROP, XmIBACKGROUND, XmIFOREGROUND,
2688     XmIPIXEL, XmS_MOTIF_EXPORT_TARGETS, XmS_MOTIF_CLIPBOARD_TARGETS,
2689 #ifdef UTF8_SUPPORTED
2690     XmSUTF8_STRING
2691 #endif
2692     };
2693 
2694   Atom atoms[XtNumber(atom_names)];
2695   Atom C_ENCODING;
2696   int target_count = 0;
2697   Atom type = None;
2698   XtPointer value = NULL;
2699   unsigned long size = 0;
2700   int format = 8;
2701   XmString label_string;
2702   Pixmap label_pixmap;
2703   Boolean is_pixmap, is_text;
2704 
2705   if (w == (Widget) NULL)
2706     {
2707       cs->status = XmCONVERT_REFUSE;
2708       return;
2709     }
2710 
2711   C_ENCODING = XmeGetEncodingAtom(w);
2712   assert(XtNumber(atom_names) == NUM_ATOMS);
2713   XInternAtoms(XtDisplayOfObject(w), atom_names, XtNumber(atom_names),
2714 	       False, atoms);
2715 
2716   if (cs->selection != atoms[XmA_MOTIF_DROP])
2717     {
2718       cs->status = XmCONVERT_REFUSE;
2719       return;
2720     }
2721 
2722   if (XtIsWidget(w))
2723     {
2724       label_string = ((XmLabelWidget) w)->label._label;
2725       label_pixmap = ((XmLabelWidget) w)->label.pixmap;
2726       is_pixmap = Lab_IsPixmap(w) || Lab_IsPixmapAndText(w);
2727       is_text = Lab_IsText(w) || Lab_IsPixmapAndText(w);
2728     }
2729   else
2730     {
2731       label_string = ((XmLabelGadget) w)->label._label;
2732       label_pixmap = ((XmLabelGadget) w)->label.pixmap;
2733       is_pixmap = LabG_IsPixmap(w) || LabG_IsPixmapAndText(w);;
2734       is_text = LabG_IsText(w) || LabG_IsPixmapAndText(w);
2735     }
2736 
2737   if (cs->target == atoms[XmATARGETS] ||
2738       cs->target == atoms[XmA_MOTIF_EXPORT_TARGETS] ||
2739       cs->target == atoms[XmA_MOTIF_CLIPBOARD_TARGETS])
2740     {
2741       Atom *targs;
2742 
2743       if (cs->target == atoms[XmATARGETS]) {
2744 	targs = XmeStandardTargets(w, 7, &target_count);
2745       } else {
2746 	target_count = 0;
2747 	targs = (Atom *) XtMalloc(sizeof(Atom) * 7);
2748       }
2749 
2750       value = (XtPointer) targs;
2751 
2752       if (is_pixmap)
2753 	{
2754 	  targs[target_count] = XA_PIXMAP; target_count++;
2755 	}
2756 
2757       if (is_text)
2758 	{
2759 	  XtPointer temp;
2760 	  unsigned long length;
2761 	  char* ctext;
2762 	  Boolean success;
2763 
2764 	  ctext = XmCvtXmStringToCT(label_string);
2765 	  targs[target_count] = atoms[XmA_MOTIF_COMPOUND_STRING]; target_count++;
2766 	  targs[target_count] = atoms[XmACOMPOUND_TEXT]; target_count++;
2767 	  targs[target_count] = atoms[XmATEXT]; target_count++;
2768 #ifdef UTF8_SUPPORTED
2769 	  if (C_ENCODING != XA_STRING && C_ENCODING != atoms[XmAUTF8_STRING]) {
2770 	    temp = ConvertToEncoding(w, ctext, C_ENCODING, &length, &success);
2771 	    if (success) {
2772 	      targs[target_count] = C_ENCODING;
2773 	      target_count++;
2774 	    }
2775 	    XtFree((char*) temp);
2776 	  }
2777 #endif
2778 	  temp = ConvertToEncoding(w, ctext, XA_STRING, &length, &success);
2779 	  if (success) {
2780 	    targs[target_count] = XA_STRING;
2781 	    target_count++;
2782 	  }
2783 	  XtFree((char*) temp);
2784 	  XtFree((char*) ctext);
2785 #ifdef UTF8_SUPPORTED
2786 	  ctext = XmCvtXmStringToUTF8String(label_string);
2787 	  if (ctext) {
2788 	    targs[target_count] = atoms[XmAUTF8_STRING];
2789 	    target_count++;
2790 	  }
2791 	  XtFree((char*) ctext);
2792 #endif
2793 	}
2794       type = XA_ATOM;
2795       size = target_count;
2796       format = 32;
2797     }
2798 
2799   if (cs->target == atoms[XmA_MOTIF_COMPOUND_STRING])
2800     {
2801       type = atoms[XmA_MOTIF_COMPOUND_STRING];
2802       format = 8;
2803       size = XmCvtXmStringToByteStream(label_string,
2804 				       (unsigned char **) &value);
2805     }
2806   else if (cs->target == atoms[XmACOMPOUND_TEXT] ||
2807 	   cs->target == atoms[XmATEXT] ||
2808 	   cs->target == XA_STRING ||
2809 	   cs->target == C_ENCODING)
2810     {
2811       type = atoms[XmACOMPOUND_TEXT];
2812       format = 8;
2813       value = XmCvtXmStringToCT(label_string);
2814       if (value != NULL)
2815 	size = strlen((char*) value);
2816       else
2817 	size = 0;
2818 
2819       if (cs->target == XA_STRING)
2820 	{
2821 	  Boolean success;
2822 
2823 	  value = ConvertToEncoding(w, (char*) value,
2824 				    XA_STRING, &size, &success);
2825 
2826 	  if (value != NULL && success == False)
2827 	    cs->flags |= XmCONVERTING_PARTIAL;
2828 	  type = XA_STRING;
2829 	}
2830       else if ((cs->target == atoms[XmATEXT] ||
2831 		cs->target == C_ENCODING) &&
2832 	       value != NULL)
2833 	{
2834 	  char *cvt;
2835 	  Boolean success;
2836 
2837 	  cvt = (char*) ConvertToEncoding(w, (char*) value,
2838 					  C_ENCODING, &size, &success);
2839 
2840 	  if (cvt != NULL && success == False)
2841 	    cs->flags |= XmCONVERTING_PARTIAL;
2842 
2843 	  if (cvt != NULL && success)
2844 	    {
2845 	      /* 100% ok */
2846 	      XtFree((char*) value);
2847 	      value = cvt;
2848 	      type = C_ENCODING;
2849 	    }
2850 	  else
2851 	    {
2852 	      /* If the request was C_ENCODING,  then return only C_ENCODING,
2853 	       * not atoms[XmACOMPOUND_TEXT] */
2854 	      if (cs->target == C_ENCODING)
2855 		{
2856 		  XtFree((char*) value);
2857 		  value = cvt;
2858 		  type = C_ENCODING;
2859 		}
2860 	      else
2861 		if (cvt != NULL) XtFree(cvt);
2862 	      type = atoms[XmACOMPOUND_TEXT];
2863 	    }
2864 	}
2865 #ifdef UTF8_SUPPORTED
2866     } else if (cs->target == atoms[XmAUTF8_STRING]) {
2867       type = atoms[XmAUTF8_STRING];
2868       format = 8;
2869       value = XmCvtXmStringToUTF8String(label_string);
2870       if (value != NULL)
2871 	size = strlen((char*) value);
2872       else
2873 	size = 0;
2874 #endif
2875     }
2876 
2877   if (cs->target == XA_PIXMAP)
2878     {
2879       /* Get widget's pixmap */
2880       Pixmap *pix;
2881 
2882       pix = (Pixmap *) XtMalloc(sizeof(Pixmap));
2883       *pix = label_pixmap;
2884       /* value, type, size, and format must be set */
2885       value = (XtPointer) pix;
2886       type = XA_DRAWABLE;
2887       size = 1;
2888       format = 32;
2889     }
2890 
2891   if (cs->target == atoms[XmABACKGROUND])
2892     {
2893       /* Get widget's background */
2894       Pixel *background;
2895 
2896       background = (Pixel *) XtMalloc(sizeof(Pixel));
2897       if (XtIsWidget(w))
2898 	*background = ((XmLabelWidget) w)->core.background_pixel;
2899       else
2900 	*background = LabG_Background(w);
2901       /* value, type, size, and format must be set */
2902       value = (XtPointer) background;
2903       type = atoms[XmAPIXEL];
2904       size = 1;
2905       format = 32;
2906     }
2907 
2908   if (cs->target == atoms[XmAFOREGROUND])
2909     {
2910       /* Get widget's foreground */
2911       Pixel *foreground;
2912 
2913       foreground = (Pixel *) XtMalloc(sizeof(Pixel));
2914       if (XtIsWidget(w))
2915 	*foreground = ((XmLabelWidget) w)->primitive.foreground;
2916       else
2917 	*foreground = LabG_Foreground(w);
2918       /* value, type, size, and format must be set */
2919       value = (XtPointer) foreground;
2920       type = atoms[XmAPIXEL];
2921       size = 1;
2922       format = 32;
2923     }
2924 
2925   if (cs->target == XA_COLORMAP)
2926     {
2927       /* Get widget's colormap */
2928       Colormap *colormap;
2929 
2930       colormap = (Colormap *) XtMalloc(sizeof(Colormap));
2931       if (XtIsWidget(w))
2932 	*colormap = w->core.colormap;
2933       else
2934 	*colormap = XtParent(w)->core.colormap;
2935       /* value, type, size, and format must be set */
2936       value = (XtPointer) colormap;
2937       type = XA_COLORMAP;
2938       size = 1;
2939       format = 32;
2940     }
2941 
2942   _XmConvertComplete(w, value, size, format, type, cs);
2943 }
2944 
2945 /**************************************************************************
2946  * ConvertToEncoding
2947  *
2948  * This contains conversion code which is needed more than once in
2949  * _XmLabelConvert.  The first calls are to check for 100% conversion
2950  * in _MOTIF_EXPORT_TARGETS and _MOTIF_CLIPBOARD_TARGETS.
2951  * The second are for the real conversion
2952  **************************************************************************/
2953 static XtPointer
ConvertToEncoding(Widget w,char * str,Atom encoding,unsigned long * length,Boolean * flag)2954 ConvertToEncoding(Widget w, char* str, Atom encoding,
2955 		  unsigned long *length, Boolean *flag)
2956 {
2957   XtPointer rval = NULL;
2958   XTextProperty tmp_prop;
2959   Atom COMPOUND_TEXT = XInternAtom(XtDisplay(w), XmSCOMPOUND_TEXT, False);
2960 #ifdef UTF8_SUPPORTED
2961   Atom UTF8_STRING = XInternAtom(XtDisplay(w), XmSUTF8_STRING, False);
2962 #endif
2963   int ret_status;
2964 
2965   if (encoding == XA_STRING) {
2966     /* convert value to 8859.1 */
2967     ret_status =
2968       XmbTextListToTextProperty(XtDisplay(w), (char**) &str, 1,
2969 				(XICCEncodingStyle)XStringStyle,
2970 				&tmp_prop);
2971 
2972     if (ret_status == Success || ret_status > 0)
2973       {
2974 	rval = (XtPointer) tmp_prop.value;
2975 	*length = tmp_prop.nitems;
2976       }
2977     else
2978       {
2979 	rval = NULL;
2980 	*length = 0;
2981       }
2982 
2983     *flag = (ret_status == Success);
2984 #ifdef UTF8_SUPPORTED
2985   } else if (encoding == UTF8_STRING) {
2986     /* convert value to UTF8 */
2987     ret_status =
2988       Xutf8TextListToTextProperty(XtDisplay(w), (char**) &str, 1,
2989 				(XICCEncodingStyle)XUTF8StringStyle,
2990 				&tmp_prop);
2991 
2992     if (ret_status == Success || ret_status > 0)
2993       {
2994 	rval = (XtPointer) tmp_prop.value;
2995 	*length = tmp_prop.nitems;
2996       }
2997     else
2998       {
2999 	rval = NULL;
3000 	*length = 0;
3001       }
3002 
3003     *flag = (ret_status >= Success);
3004 #endif
3005   } else {
3006     /* Locale encoding */
3007     /* Fix for Bug 1117 - if str is null then a SEGVIOLATION occures
3008      * in strlen.
3009      */
3010 #ifdef FIX_1442
3011     *length = str ? strlen(str) : 0;
3012 #else
3013     *length = str ? strlen(rval) : 0;
3014 #endif
3015 
3016     rval = _XmTextToLocaleText(w, (XtPointer) str,
3017 			       COMPOUND_TEXT, 8,
3018 			       *length,
3019 			       flag);
3020   }
3021 
3022   return(rval);
3023 }
3024 
3025 /**************************************************************************
3026  * FromPaddingPixels
3027  *
3028  * Converts from pixels to current unit type does either horiz or vert
3029  * depending on icon placement.
3030  *  widget - the icon button widget.
3031  *  offset, value - passed to correct function based on orientation.
3032  **************************************************************************/
3033 
3034 static void
FromPaddingPixels(Widget widget,int offset,XtArgVal * value)3035 FromPaddingPixels(Widget widget, int offset, XtArgVal *value)
3036 {
3037     XmLabelWidget iw = (XmLabelWidget) widget;
3038 
3039     switch(iw->label.pixmap_placement) {
3040     case XmPIXMAP_TOP:
3041     case XmPIXMAP_BOTTOM:
3042 	XmeFromVerticalPixels(widget, offset, value);
3043 	break;
3044     default:			/* everything else is horiz. */
3045 	XmeFromHorizontalPixels(widget, offset, value);
3046 	break;
3047     }
3048 }
3049 
3050 /**************************************************************************
3051  * ToPaddingPixels
3052  *
3053  * Converts from pixels to current unit type does either horiz or vert
3054  * depending on icon placement.
3055  *  widget - the icon button widget.
3056  *  offset, value - passed to correct function based on orientation.
3057  * Returns the import order from _XmTo{Horizontal, Vertical}Pixels.
3058  **************************************************************************/
3059 
3060 static XmImportOperator
ToPaddingPixels(Widget widget,int offset,XtArgVal * value)3061 ToPaddingPixels(Widget widget, int offset, XtArgVal *value)
3062 {
3063     XmLabelWidget iw = (XmLabelWidget) widget;
3064 
3065     switch(iw->label.pixmap_placement) {
3066     case XmPIXMAP_TOP:
3067     case XmPIXMAP_BOTTOM:
3068 	return(XmeToVerticalPixels(widget, offset, value));
3069     default:
3070 	return(XmeToHorizontalPixels(widget, offset, value));
3071     }
3072 }
3073 
3074 /*
3075  * XmRCallProc routine for checking label.font before setting it to NULL
3076  * If "check_set_render_table" is True, then function has
3077  * been called twice on same widget, thus resource needs to be set NULL,
3078  * otherwise leave it alone.
3079  */
3080 
3081 /*ARGSUSED*/
3082 static void
CheckSetRenderTable(Widget wid,int offset,XrmValue * value)3083 CheckSetRenderTable(Widget wid,
3084 		    int offset,
3085 		    XrmValue *value)
3086 {
3087   XmLabelWidget lw = (XmLabelWidget)wid;
3088 
3089   /* Check if been here before */
3090   if (lw->label.check_set_render_table)
3091       value->addr = NULL;
3092   else {
3093       lw->label.check_set_render_table = True;
3094       value->addr = (char*)&(lw->label.font);
3095   }
3096 
3097 }
3098 
3099 static XtPointer
LabelGetValue(Widget w,int type)3100 LabelGetValue(Widget w, int type)
3101 {
3102   XmString value;
3103 
3104   XtVaGetValues(w, XmNlabelString, &value, NULL);
3105 
3106   if (type == XmFORMAT_XmSTRING)
3107     {
3108       return (XtPointer) value;
3109     }
3110   else if (type == XmFORMAT_MBYTE ||
3111 	   type == XmFORMAT_WCS)
3112     {
3113       XtPointer temp;
3114       temp = (type == XmFORMAT_MBYTE) ?
3115 	_XmStringUngenerate(value, NULL,
3116 			    XmMULTIBYTE_TEXT, XmMULTIBYTE_TEXT) :
3117 	_XmStringUngenerate(value, NULL,
3118 			    XmWIDECHAR_TEXT, XmWIDECHAR_TEXT);
3119       XmStringFree(value);
3120       return temp;
3121     }
3122   else
3123     return NULL;
3124 }
3125 
3126 static void
LabelSetValue(Widget w,XtPointer value,int type)3127 LabelSetValue(Widget w, XtPointer value, int type)
3128 {
3129   Arg args[1];
3130   Cardinal nargs;
3131   XmString temp;
3132   Boolean freetemp = True;
3133 
3134   if (type == XmFORMAT_XmSTRING)
3135     {
3136       temp = (XmString) value;
3137       freetemp = False;
3138     }
3139   else
3140     {
3141       if (type == XmFORMAT_WCS)
3142 	{
3143 	  int length;
3144 	  char *str;
3145 	  wchar_t *str2;
3146 	  str2 = (wchar_t *) value;
3147 
3148 	  /* Get length of wchar string */
3149 	  length = 0;
3150 	  while (str2[length] != 0)
3151 	    length++;
3152 	  str = (char*) XtMalloc(MB_CUR_MAX * length);
3153 	  wcstombs(str, str2, length * MB_CUR_MAX);
3154 	  XtFree((char*) value);
3155 	  value = str;
3156 	}
3157       temp = XmStringCreateLocalized((char*) value);
3158     }
3159 
3160   nargs = 0;
3161   XtSetArg(args[nargs], XmNlabelString, temp), nargs++;
3162   assert(nargs <= XtNumber(args));
3163   XtSetValues(w, args, nargs);
3164 
3165   if (freetemp)
3166     XmStringFree(temp);
3167 }
3168 
3169 /*ARGSUSED*/
3170 static int
LabelPreferredValue(Widget w)3171 LabelPreferredValue(Widget w)	/* unused */
3172 {
3173   return XmFORMAT_XmSTRING;
3174 }
3175 
3176 static char*
GetLabelAccelerator(Widget w)3177 GetLabelAccelerator(Widget w)
3178 {
3179   if (XtClass(w) == xmLabelWidgetClass)
3180     return NULL;
3181   else
3182     return Lab_Accelerator(w);
3183 }
3184 
3185 static KeySym
GetLabelMnemonic(Widget w)3186 GetLabelMnemonic(Widget w)
3187 {
3188   if (XtClass(w) == xmLabelWidgetClass)
3189     return XK_VoidSymbol;
3190   else
3191     return Lab_Mnemonic(w);
3192 }
3193 
3194