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