e30463686a3155ae023c0bbbf8ce1e8fa49180c7
[framework/uifw/xorg/lib/libxaw.git] / src / Label.c
1 /***********************************************************
2
3 Copyright 1987, 1988, 1994, 1998  The Open Group
4
5 Permission to use, copy, modify, distribute, and sell this software and its
6 documentation for any purpose is hereby granted without fee, provided that
7 the above copyright notice appear in all copies and that both that
8 copyright notice and this permission notice appear in supporting
9 documentation.
10
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
13
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
17 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21 Except as contained in this notice, the name of The Open Group shall not be
22 used in advertising or otherwise to promote the sale, use or other dealings
23 in this Software without prior written authorization from The Open Group.
24
25
26 Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
27
28                         All Rights Reserved
29
30 Permission to use, copy, modify, and distribute this software and its
31 documentation for any purpose and without fee is hereby granted,
32 provided that the above copyright notice appear in all copies and that
33 both that copyright notice and this permission notice appear in
34 supporting documentation, and that the name of Digital not be
35 used in advertising or publicity pertaining to distribution of the
36 software without specific, written prior permission.
37
38 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
39 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
40 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
41 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
42 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
43 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
44 SOFTWARE.
45
46 ******************************************************************/
47
48 #ifdef HAVE_CONFIG_H
49 #include <config.h>
50 #endif
51 #include <stdio.h>
52 #include <ctype.h>
53 #include <X11/IntrinsicP.h>
54 #include <X11/StringDefs.h>
55 #include <X11/Xos.h>
56 #include <X11/Xmu/Converters.h>
57 #include <X11/Xmu/Drawing.h>
58 #include <X11/Xaw/LabelP.h>
59 #include <X11/Xaw/XawInit.h>
60 #include "Private.h"
61
62 #define streq(a, b)             (strcmp((a), (b)) == 0)
63
64 #define MULTI_LINE_LABEL 32767
65
66 #ifdef CRAY
67 #define WORD64
68 #endif
69
70 /*
71  * Class Methods
72  */
73 static void XawLabelClassInitialize(void);
74 static void XawLabelDestroy(Widget);
75 static void XawLabelInitialize(Widget, Widget, ArgList, Cardinal*);
76 static XtGeometryResult XawLabelQueryGeometry(Widget, XtWidgetGeometry*,
77                                               XtWidgetGeometry*);
78 static void XawLabelRedisplay(Widget, XEvent*, Region);
79 static void XawLabelResize(Widget);
80 static Boolean XawLabelSetValues(Widget, Widget, Widget,
81                                  ArgList, Cardinal*);
82
83 /*
84  * Prototypes
85  */
86 #ifdef WORD64
87 static int _XawLabelWidth16(XFontStruct*, char*, int);
88 static void _XawLabelDraw16(Display*, Drawable, GC, int, int, char*, int);
89 #endif
90 static void compute_bitmap_offsets(LabelWidget);
91 static void GetGrayGC(LabelWidget);
92 static void GetNormalGC(LabelWidget);
93 static void _Reposition(LabelWidget, unsigned int, unsigned int,
94                         Position*, Position*);
95 static void set_bitmap_info(LabelWidget);
96 static void SetTextWidthAndHeight(LabelWidget);
97
98 /*
99  * Initialization
100  */
101 #define offset(field) XtOffsetOf(LabelRec, field)
102 static XtResource resources[] = {
103   {
104     XtNforeground,
105     XtCForeground,
106     XtRPixel,
107     sizeof(Pixel),
108     offset(label.foreground),
109     XtRString,
110     XtDefaultForeground
111   },
112   {
113     XtNfont,
114     XtCFont,
115     XtRFontStruct,
116     sizeof(XFontStruct*),
117     offset(label.font),
118     XtRString,
119     XtDefaultFont
120   },
121   {
122     XtNfontSet,
123     XtCFontSet,
124     XtRFontSet,
125     sizeof(XFontSet),
126     offset(label.fontset),
127     XtRString,
128     XtDefaultFontSet
129   },
130   {
131     XtNlabel,
132     XtCLabel,
133     XtRString,
134     sizeof(String),
135     offset(label.label),
136     XtRString,
137     NULL
138   },
139   {
140     XtNencoding,
141     XtCEncoding,
142     XtRUnsignedChar,
143     sizeof(unsigned char),
144     offset(label.encoding),
145     XtRImmediate,
146     (XtPointer)XawTextEncoding8bit
147   },
148   {
149     XtNjustify,
150     XtCJustify,
151     XtRJustify,
152     sizeof(XtJustify),
153     offset(label.justify),
154     XtRImmediate,
155     (XtPointer)XtJustifyCenter
156   },
157   {
158     XtNinternalWidth,
159     XtCWidth,
160     XtRDimension,
161     sizeof(Dimension),
162     offset(label.internal_width),
163     XtRImmediate,
164     (XtPointer)4
165   },
166   {
167     XtNinternalHeight,
168     XtCHeight,
169     XtRDimension,
170     sizeof(Dimension),
171     offset(label.internal_height),
172     XtRImmediate,
173     (XtPointer)2
174   },
175   {
176     XtNleftBitmap,
177     XtCLeftBitmap,
178     XtRBitmap,
179     sizeof(Pixmap),
180     offset(label.left_bitmap),
181     XtRImmediate,
182     (XtPointer)None
183   },
184   {
185     XtNbitmap,
186     XtCPixmap,
187     XtRBitmap,
188     sizeof(Pixmap),
189     offset(label.pixmap),
190     XtRImmediate,
191     (XtPointer)None
192   },
193   {
194     XtNresize,
195     XtCResize,
196     XtRBoolean,
197     sizeof(Boolean),
198     offset(label.resize),
199     XtRImmediate,
200     (XtPointer)True
201   },
202   {
203     XtNlabelX,
204     XtCPosition,
205     XtRPosition,
206     sizeof(Position),
207     offset(label.label_x),
208     XtRImmediate,
209     (XtPointer)0
210   },
211   {
212     XtNlabelY,
213     XtCPosition,
214     XtRPosition,
215     sizeof(Position),
216     offset(label.label_y),
217     XtRImmediate,
218     (XtPointer)0
219   },
220 };
221 #undef offset
222
223 #define Superclass (&simpleClassRec)
224 LabelClassRec labelClassRec = {
225   /* core */
226   {
227     (WidgetClass)&simpleClassRec,       /* superclass */
228     "Label",                            /* class_name */
229     sizeof(LabelRec),                   /* widget_size */
230     XawLabelClassInitialize,            /* class_initialize */
231     NULL,                               /* class_part_initialize */
232     False,                              /* class_inited */
233     XawLabelInitialize,                 /* initialize */
234     NULL,                               /* initialize_hook */
235     XtInheritRealize,                   /* realize */
236     NULL,                               /* actions */
237     0,                                  /* num_actions */
238     resources,                          /* resources */
239     XtNumber(resources),                /* num_resources */
240     NULLQUARK,                          /* xrm_class */
241     True,                               /* compress_motion */
242     True,                               /* compress_exposure */
243     True,                               /* compress_enterleave */
244     False,                              /* visible_interest */
245     XawLabelDestroy,                    /* destroy */
246     XawLabelResize,                     /* resize */
247     XawLabelRedisplay,                  /* expose */
248     XawLabelSetValues,                  /* set_values */
249     NULL,                               /* set_values_hook */
250     XtInheritSetValuesAlmost,           /* set_values_almost */
251     NULL,                               /* get_values_hook */
252     NULL,                               /* accept_focus */
253     XtVersion,                          /* version */
254     NULL,                               /* callback_private */
255     NULL,                               /* tm_table */
256     XawLabelQueryGeometry,              /* query_geometry */
257     XtInheritDisplayAccelerator,        /* display_accelerator */
258     NULL,                               /* extension */
259   },
260   /* simple */
261   {
262     XtInheritChangeSensitive,           /* change_sensitive */
263   },
264   /* label */
265   {
266     NULL,                               /* extension */
267   }
268 };
269
270 WidgetClass labelWidgetClass = (WidgetClass)&labelClassRec;
271
272 /*
273  * Implementation
274  */
275 static void
276 XawLabelClassInitialize(void)
277 {
278     XawInitializeWidgetSet();
279     XtAddConverter(XtRString, XtRJustify, XmuCvtStringToJustify, NULL, 0);
280     XtSetTypeConverter(XtRJustify, XtRString, XmuCvtJustifyToString,
281                        NULL, 0, XtCacheNone, NULL);
282 }
283
284 #ifndef WORD64
285 #define TXT16 XChar2b
286 #else
287 #define TXT16 char
288
289 static XChar2b *buf2b;
290 static int buf2blen = 0;
291
292 static int
293 _XawLabelWidth16(XFontStruct *fs, char *str, int n)
294 {
295     int i;
296     XChar2b *ptr;
297
298     if (n > buf2blen) {
299         buf2b = (XChar2b *)XtRealloc((char *)buf2b, n * sizeof(XChar2b));
300         buf2blen = n;
301     }
302     for (ptr = buf2b, i = n; --i >= 0; ptr++) {
303         ptr->byte1 = *str++;
304         ptr->byte2 = *str++;
305     }
306
307     return (XTextWidth16(fs, buf2b, n));
308 }
309
310 static void
311 _XawLabelDraw16(Display *dpy, Drawable d, GC gc, int x, int y,
312                 char *str, int n)
313 {
314     int i;
315     XChar2b *ptr;
316
317     if (n > buf2blen) {
318         buf2b = (XChar2b *)XtRealloc((char *)buf2b, n * sizeof(XChar2b));
319         buf2blen = n;
320     }
321     for (ptr = buf2b, i = n; --i >= 0; ptr++) {
322         ptr->byte1 = *str++;
323         ptr->byte2 = *str++;
324     }
325     XDrawString16(dpy, d, gc, x, y, buf2b, n);
326 }
327
328 #define XTextWidth16 _XawLabelWidth16
329 #define XDrawString16 _XawLabelDraw16
330 #endif /* WORD64 */
331
332 /*
333  * Calculate width and height of displayed text in pixels
334  */
335 static void
336 SetTextWidthAndHeight(LabelWidget lw)
337 {
338     XFontStruct *fs = lw->label.font;
339     char *nl;
340
341     if (lw->label.pixmap != None) {
342         Window root;
343         int x, y;
344         unsigned int width, height, bw, depth;
345
346         if (XGetGeometry(XtDisplay(lw), lw->label.pixmap, &root, &x, &y,
347                        &width, &height, &bw, &depth)) {
348             lw->label.label_height = height;
349             lw->label.label_width = width;
350             lw->label.label_len = depth;
351             return;
352         }
353     }
354     if (lw->simple.international == True) {
355         XFontSet        fset = lw->label.fontset;
356         XFontSetExtents *ext = XExtentsOfFontSet(fset);
357
358         lw->label.label_height = ext->max_ink_extent.height;
359         if (lw->label.label == NULL) {
360             lw->label.label_len = 0;
361             lw->label.label_width = 0;
362         }
363         else if ((nl = index(lw->label.label, '\n')) != NULL) {
364             char *label;
365
366             lw->label.label_len = MULTI_LINE_LABEL;
367             lw->label.label_width = 0;
368             for (label = lw->label.label; nl != NULL; nl = index(label, '\n')) {
369                 int width = XmbTextEscapement(fset, label, (int)(nl - label));
370
371                 if (width > (int)lw->label.label_width)
372                     lw->label.label_width = width;
373                 label = nl + 1;
374                 if (*label)
375                     lw->label.label_height += ext->max_ink_extent.height;
376             }
377             if (*label) {
378                 int width = XmbTextEscapement(fset, label, strlen(label));
379
380                 if (width > (int)lw->label.label_width)
381                     lw->label.label_width = width;
382             }
383         }
384         else {
385             lw->label.label_len = strlen(lw->label.label);
386             lw->label.label_width =
387                 XmbTextEscapement(fset, lw->label.label, lw->label.label_len);
388         }
389     }
390     else {
391         lw->label.label_height = fs->max_bounds.ascent + fs->max_bounds.descent;
392         if (lw->label.label == NULL) {
393             lw->label.label_len = 0;
394             lw->label.label_width = 0;
395         }
396         else if ((nl = index(lw->label.label, '\n')) != NULL) {
397             char *label;
398
399             lw->label.label_len = MULTI_LINE_LABEL;
400             lw->label.label_width = 0;
401             for (label = lw->label.label; nl != NULL; nl = index(label, '\n')) {
402                 int width;
403
404                 if (lw->label.encoding)
405                     width = XTextWidth16(fs, (TXT16*)label, (int)(nl - label) / 2);
406                 else
407                     width = XTextWidth(fs, label, (int)(nl - label));
408                 if (width > (int)lw->label.label_width)
409                     lw->label.label_width = width;
410                 label = nl + 1;
411                 if (*label)
412                     lw->label.label_height +=
413                         fs->max_bounds.ascent + fs->max_bounds.descent;
414             }
415             if (*label) {
416                 int width = XTextWidth(fs, label, strlen(label));
417
418                 if (lw->label.encoding)
419                     width = XTextWidth16(fs, (TXT16*)label, strlen(label) / 2);
420                 else
421                     width = XTextWidth(fs, label, strlen(label));
422                 if (width > (int) lw->label.label_width)
423                     lw->label.label_width = width;
424             }
425         }
426         else {
427             lw->label.label_len = strlen(lw->label.label);
428             if (lw->label.encoding)
429                 lw->label.label_width =
430                     XTextWidth16(fs, (TXT16*)lw->label.label,
431                            (int)lw->label.label_len / 2);
432             else
433                 lw->label.label_width =
434               XTextWidth(fs, lw->label.label, (int)lw->label.label_len);
435         }
436     }
437 }
438
439 static void
440 GetNormalGC(LabelWidget lw)
441 {
442     XGCValues   values;
443
444     values.foreground   = lw->label.foreground;
445     values.background   = lw->core.background_pixel;
446     values.font         = lw->label.font->fid;
447     values.graphics_exposures = False;
448
449     if (lw->simple.international == True)
450     /* Since Xmb/wcDrawString eats the font, I must use XtAllocateGC */
451         lw->label.normal_GC = XtAllocateGC((Widget)lw, 0,
452                                            GCForeground | GCBackground |
453                                            GCGraphicsExposures,
454                                            &values, GCFont, 0);
455     else
456         lw->label.normal_GC = XtGetGC((Widget)lw,
457                                       GCForeground | GCBackground | GCFont |
458                                       GCGraphicsExposures, &values);
459 }
460
461 static void
462 GetGrayGC(LabelWidget lw)
463 {
464     XGCValues   values;
465
466     values.foreground = lw->label.foreground;
467     values.background = lw->core.background_pixel;
468     values.font       = lw->label.font->fid;
469     values.fill_style = FillTiled;
470     values.tile       = XmuCreateStippledPixmap(XtScreen((Widget)lw),
471                                                 lw->label.foreground,
472                                                 lw->core.background_pixel,
473                                                 lw->core.depth);
474     values.graphics_exposures = False;
475
476     lw->label.stipple = values.tile;
477     if (lw->simple.international == True)
478         /* Since Xmb/wcDrawString eats the font, I must use XtAllocateGC */
479         lw->label.gray_GC = XtAllocateGC((Widget)lw, 0,
480                                          GCForeground | GCBackground |
481                                          GCTile | GCFillStyle |
482                                          GCGraphicsExposures,
483                                          &values, GCFont, 0);
484         else
485             lw->label.gray_GC = XtGetGC((Widget)lw,
486                                         GCForeground | GCBackground |
487                                         GCFont | GCTile | GCFillStyle |
488                                         GCGraphicsExposures,
489                                         &values);
490 }
491
492 static void
493 compute_bitmap_offsets(LabelWidget lw)
494 {
495     /*
496      * bitmap will be eventually be displayed at
497      * (internal_width, internal_height + lbm_y)
498      */
499     if (lw->label.lbm_height != 0)
500         lw->label.lbm_y = (XtHeight(lw) - (lw->label.internal_height * 2 +
501                            lw->label.lbm_height)) / 2;
502     else
503         lw->label.lbm_y = 0;
504 }
505
506 static void
507 set_bitmap_info(LabelWidget lw)
508 {
509     Window root;
510     int x, y;
511     unsigned int bw, depth;
512
513     if (!(lw->label.left_bitmap
514         && XGetGeometry(XtDisplay(lw), lw->label.left_bitmap, &root, &x, &y,
515                         &lw->label.lbm_width, &lw->label.lbm_height,
516                         &bw, &depth)))
517         lw->label.lbm_width = lw->label.lbm_height = 0;
518
519     compute_bitmap_offsets(lw);
520 }
521
522 /*ARGSUSED*/
523 static void
524 XawLabelInitialize(Widget request, Widget cnew,
525                    ArgList args, Cardinal *num_args)
526 {
527     LabelWidget lw = (LabelWidget)cnew;
528
529     if (!lw->label.font) XtError("Aborting: no font found\n");
530     if (lw->simple.international && !lw->label.fontset)
531         XtError("Aborting: no fontset found\n");
532
533     if (lw->label.label == NULL)
534         lw->label.label = XtNewString(lw->core.name);
535     else
536         lw->label.label = XtNewString(lw->label.label);
537
538     GetNormalGC(lw);
539     GetGrayGC(lw);
540
541     SetTextWidthAndHeight(lw);
542
543     if (XtHeight(lw) == 0)
544         XtHeight(lw) = lw->label.label_height + 2 * lw->label.internal_height;
545
546     set_bitmap_info(lw);                /* need core.height */
547
548     if (XtWidth(lw) == 0)               /* need label.lbm_width */
549         XtWidth(lw) = lw->label.label_width + 2 * lw->label.internal_width +
550                       LEFT_OFFSET(lw);
551
552     lw->label.label_x = lw->label.label_y = 0;
553     (*XtClass(cnew)->core_class.resize)((Widget)lw);
554 }
555
556 /*ARGSUSED*/
557 static void
558 XawLabelRedisplay(Widget gw, XEvent *event, Region region)
559 {
560     LabelWidget w = (LabelWidget)gw;
561     GC gc;
562
563     if (*Superclass->core_class.expose != NULL)
564         (*Superclass->core_class.expose)(gw, event, region);
565
566     gc = XtIsSensitive(gw) ? w->label.normal_GC : w->label.gray_GC;
567 #ifdef notdef
568     if (region != NULL)
569         XSetRegion(XtDisplay(gw), gc, region);
570 #endif /*notdef*/
571
572     if (w->label.pixmap == None) {
573         int len = w->label.label_len;
574         char *label = w->label.label;
575         Position y = w->label.label_y + w->label.font->max_bounds.ascent;
576         Position ksy = w->label.label_y;
577
578         /* display left bitmap */
579         if (w->label.left_bitmap && w->label.lbm_width != 0)
580             XCopyPlane (XtDisplay(gw), w->label.left_bitmap, XtWindow(gw), gc,
581                         0, 0, w->label.lbm_width, w->label.lbm_height,
582                         w->label.internal_width,
583                         w->label.internal_height + w->label.lbm_y, 1L);
584
585         if (w->simple.international == True) {
586             XFontSetExtents *ext = XExtentsOfFontSet(w->label.fontset);
587
588             ksy += XawAbs(ext->max_ink_extent.y);
589
590             if (len == MULTI_LINE_LABEL) {
591                 char *nl;
592
593                 while ((nl = index(label, '\n')) != NULL) {
594                     XmbDrawString(XtDisplay(w), XtWindow(w), w->label.fontset,
595                                   gc, w->label.label_x, ksy, label,
596                                   (int)(nl - label));
597                     ksy += ext->max_ink_extent.height;
598                     label = nl + 1;
599                 }
600                 len = strlen(label);
601             }
602             if (len)
603                 XmbDrawString(XtDisplay(w), XtWindow(w), w->label.fontset, gc,
604                               w->label.label_x, ksy, label, len);
605         }
606         else {
607             if (len == MULTI_LINE_LABEL) {
608                 char *nl;
609
610                 while ((nl = index(label, '\n')) != NULL) {
611                     if (w->label.encoding)
612                         XDrawString16(XtDisplay(gw), XtWindow(gw), gc,
613                                       w->label.label_x, y,
614                                       (TXT16*)label, (int)(nl - label) / 2);
615                     else
616                         XDrawString(XtDisplay(gw), XtWindow(gw), gc,
617                                     w->label.label_x, y, label, (int)(nl - label));
618                     y += w->label.font->max_bounds.ascent +
619                          w->label.font->max_bounds.descent;
620                     label = nl + 1;
621                 }
622                 len = strlen(label);
623             }
624             if (len) {
625                 if (w->label.encoding)
626                     XDrawString16(XtDisplay(gw), XtWindow(gw), gc,
627                                   w->label.label_x, y, (TXT16*)label, len / 2);
628                 else
629                     XDrawString(XtDisplay(gw), XtWindow(gw), gc,
630                                 w->label.label_x, y, label, len);
631             }
632         }
633     }
634     else if (w->label.label_len == 1)
635         XCopyPlane(XtDisplay(gw), w->label.pixmap, XtWindow(gw), gc,
636                    0, 0, w->label.label_width, w->label.label_height,
637                    w->label.label_x, w->label.label_y, 1L);
638     else
639         XCopyArea(XtDisplay(gw), w->label.pixmap, XtWindow(gw), gc,
640                   0, 0, w->label.label_width, w->label.label_height,
641                   w->label.label_x, w->label.label_y);
642
643 #ifdef notdef
644     if (region != NULL)
645         XSetClipMask(XtDisplay(gw), gc, (Pixmap)None);
646 #endif /* notdef */
647 }
648
649 static void
650 _Reposition(LabelWidget lw, unsigned int width, unsigned int height,
651             Position *dx, Position *dy)
652 {
653     Position newPos;
654     Position leftedge = lw->label.internal_width + LEFT_OFFSET(lw);
655
656     switch (lw->label.justify) {
657         case XtJustifyLeft:
658             newPos = leftedge;
659             break;
660         case XtJustifyRight:
661             newPos = width - (lw->label.label_width + lw->label.internal_width);
662             break;
663         case XtJustifyCenter:
664         /*FALLTRHOUGH*/
665         default:
666             newPos = (int)(width - lw->label.label_width) >> 1;
667             break;
668     }
669     if (newPos < (Position)leftedge)
670         newPos = leftedge;
671     *dx = newPos - lw->label.label_x;
672     lw->label.label_x = newPos;
673
674     newPos = (height - lw->label.label_height) >> 1;
675     *dy = newPos - lw->label.label_y;
676     lw->label.label_y = newPos;
677 }
678
679 static void
680 XawLabelResize(Widget w)
681 {
682     LabelWidget lw = (LabelWidget)w;
683     Position dx, dy;
684
685     _Reposition(lw, XtWidth(w), XtHeight(w), &dx, &dy);
686     compute_bitmap_offsets(lw);
687 }
688
689 #define PIXMAP 0
690 #define WIDTH 1
691 #define HEIGHT 2
692 #define NUM_CHECKS 3
693 static Boolean
694 XawLabelSetValues(Widget current, Widget request, Widget cnew,
695                   ArgList args, Cardinal *num_args)
696 {
697     LabelWidget curlw = (LabelWidget)current;
698     LabelWidget reqlw = (LabelWidget)request;
699     LabelWidget newlw = (LabelWidget)cnew;
700     unsigned int i;
701     Boolean was_resized = False, redisplay = False, checks[NUM_CHECKS];
702
703     for (i = 0; i < NUM_CHECKS; i++)
704         checks[i] = False;
705
706     for (i = 0; i < *num_args; i++) {
707         if (streq(XtNbitmap, args[i].name))
708             checks[PIXMAP] = True;
709         else if (streq(XtNwidth, args[i].name))
710             checks[WIDTH] = True;
711         else if (streq(XtNheight, args[i].name))
712             checks[HEIGHT] = True;
713     }
714
715     if (newlw->label.label == NULL)
716         newlw->label.label = newlw->core.name;
717
718     /*
719      * resize on bitmap change
720      */
721     if (curlw->label.left_bitmap != newlw->label.left_bitmap)
722         was_resized = True;
723
724     if (curlw->label.encoding != newlw->label.encoding)
725         was_resized = True;
726
727     if (curlw->simple.international
728         && curlw->label.fontset != newlw->label.fontset)
729         was_resized = True;
730
731     if (curlw->label.label != newlw->label.label) {
732         if (curlw->label.label != curlw->core.name)
733             XtFree((char *)curlw->label.label);
734
735         if (newlw->label.label != newlw->core.name)
736             newlw->label.label = XtNewString(newlw->label.label);
737
738         was_resized = True;
739     }
740
741     if (was_resized || (curlw->label.font != newlw->label.font) ||
742         curlw->label.justify != newlw->label.justify || checks[PIXMAP]) {
743         SetTextWidthAndHeight(newlw);
744         was_resized = True;
745     }
746
747     /* recalculate the window size if something has changed */
748     if (newlw->label.resize && was_resized) {
749         if (XtHeight(curlw) == XtHeight(reqlw) && !checks[HEIGHT])
750             XtHeight(newlw) = newlw->label.label_height +
751                               (newlw->label.internal_height << 1);
752
753         set_bitmap_info(newlw);
754
755         if (XtWidth(curlw) == XtWidth(reqlw) && !checks[WIDTH])
756             XtWidth(newlw) = newlw->label.label_width + LEFT_OFFSET(newlw) +
757                              (newlw->label.internal_width << 1);
758     }
759
760     if (curlw->label.foreground         != newlw->label.foreground
761         || curlw->core.background_pixel != newlw->core.background_pixel
762         || curlw->label.font->fid       != newlw->label.font->fid) {
763         /* The Fontset is not in the GC - don't make a new GC if FS changes! */
764         XtReleaseGC(cnew, curlw->label.normal_GC);
765         XtReleaseGC(cnew, curlw->label.gray_GC);
766         XmuReleaseStippledPixmap(XtScreen(current), curlw->label.stipple);
767         GetNormalGC(newlw);
768         GetGrayGC(newlw);
769         redisplay = True;
770     }
771
772     if (curlw->label.label_x != newlw->label.label_x ||
773         curlw->label.label_y != newlw->label.label_y)
774         redisplay = True;
775
776     if (curlw->label.internal_width != newlw->label.internal_width
777         || curlw->label.internal_height != newlw->label.internal_height
778         || was_resized) {
779         /* Resize() will be called if geometry changes succeed */
780         Position dx, dy;
781
782         _Reposition(newlw, XtWidth(curlw), XtHeight(curlw), &dx, &dy);
783     }
784
785       return (was_resized || redisplay ||
786               XtIsSensitive(current) != XtIsSensitive(cnew));
787 }
788
789 static void
790 XawLabelDestroy(Widget w)
791 {
792     LabelWidget lw = (LabelWidget)w;
793
794     if (lw->label.label != lw->core.name)
795         XtFree(lw->label.label);
796     XtReleaseGC(w, lw->label.normal_GC);
797     XtReleaseGC(w, lw->label.gray_GC);
798     XmuReleaseStippledPixmap(XtScreen(w), lw->label.stipple);
799 }
800
801 static XtGeometryResult
802 XawLabelQueryGeometry(Widget w, XtWidgetGeometry *intended,
803                       XtWidgetGeometry *preferred)
804 {
805     LabelWidget lw = (LabelWidget)w;
806
807     preferred->request_mode = CWWidth | CWHeight;
808     preferred->width = lw->label.label_width +
809                        (lw->label.internal_width << 1) + LEFT_OFFSET(lw);
810     preferred->height = lw->label.label_height +
811                         (lw->label.internal_height << 1);
812
813     if (((intended->request_mode & (CWWidth | CWHeight)) == (CWWidth | CWHeight))
814         && intended->width == preferred->width
815         && intended->height == preferred->height)
816         return (XtGeometryYes);
817       else if (preferred->width == XtWidth(w) && preferred->height == XtHeight(w))
818         return (XtGeometryNo);
819
820     return (XtGeometryAlmost);
821 }