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