diff options
Diffstat (limited to 'src/Label.c')
-rw-r--r-- | src/Label.c | 871 |
1 files changed, 871 insertions, 0 deletions
diff --git a/src/Label.c b/src/Label.c new file mode 100644 index 0000000..5fd2e32 --- /dev/null +++ b/src/Label.c @@ -0,0 +1,871 @@ +/* $XConsortium: Label.c,v 1.97 94/04/17 20:12:12 kaleb Exp $ */ + +/*********************************************************** + +Copyright (c) 1987, 1988, 1994 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +/* + * Label.c - Label widget + * + */ + +#include "Xaw3dP.h" +#include <X11/IntrinsicP.h> +#include <X11/StringDefs.h> +#include <X11/Xos.h> +#include <X11/Xaw3d/XawInit.h> +#include <X11/Xaw3d/LabelP.h> +#include <X11/Xmu/Converters.h> +#include <X11/Xmu/Drawing.h> +#include <stdio.h> +#include <ctype.h> + +/* needed for abs() */ +#ifndef X_NOT_STDC_ENV +#include <stdlib.h> +#else +int abs(); +#endif + +#define streq(a,b) (strcmp( (a), (b) ) == 0) + +#define MULTI_LINE_LABEL 32767 + +#ifdef CRAY +#define WORD64 +#endif + +/**************************************************************** + * + * Full class record constant + * + ****************************************************************/ + +/* Private Data */ + +#define offset(field) XtOffsetOf(LabelRec, field) +static XtResource resources[] = { + {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel), + offset(label.foreground), XtRString, XtDefaultForeground}, + {XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *), + offset(label.font),XtRString, XtDefaultFont}, +#ifdef XAW_INTERNATIONALIZATION + {XtNfontSet, XtCFontSet, XtRFontSet, sizeof(XFontSet ), + offset(label.fontset),XtRString, XtDefaultFontSet}, +#endif + {XtNlabel, XtCLabel, XtRString, sizeof(String), + offset(label.label), XtRString, NULL}, + {XtNencoding, XtCEncoding, XtRUnsignedChar, sizeof(unsigned char), + offset(label.encoding), XtRImmediate, (XtPointer)XawTextEncoding8bit}, + {XtNjustify, XtCJustify, XtRJustify, sizeof(XtJustify), + offset(label.justify), XtRImmediate, (XtPointer)XtJustifyCenter}, + {XtNinternalWidth, XtCWidth, XtRDimension, sizeof(Dimension), + offset(label.internal_width), XtRImmediate, (XtPointer)4}, + {XtNinternalHeight, XtCHeight, XtRDimension, sizeof(Dimension), + offset(label.internal_height), XtRImmediate, (XtPointer)2}, + {XtNleftBitmap, XtCLeftBitmap, XtRBitmap, sizeof(Pixmap), + offset(label.left_bitmap), XtRImmediate, (XtPointer) None}, + {XtNbitmap, XtCPixmap, XtRBitmap, sizeof(Pixmap), + offset(label.pixmap), XtRImmediate, (XtPointer)None}, + {XtNresize, XtCResize, XtRBoolean, sizeof(Boolean), + offset(label.resize), XtRImmediate, (XtPointer)True}, + {XtNborderWidth, XtCBorderWidth, XtRDimension, sizeof(Dimension), + XtOffsetOf(RectObjRec,rectangle.border_width), XtRImmediate, + (XtPointer)1} +}; +#undef offset + +static void Initialize(); +static void Resize(); +static void Redisplay(); +static Boolean SetValues(); +static void ClassInitialize(); +static void Destroy(); +static XtGeometryResult QueryGeometry(); + +LabelClassRec labelClassRec = { + { +/* core_class fields */ + /* superclass */ (WidgetClass) &threeDClassRec, + /* class_name */ "Label", + /* widget_size */ sizeof(LabelRec), + /* class_initialize */ ClassInitialize, + /* class_part_initialize */ NULL, + /* class_inited */ FALSE, + /* initialize */ Initialize, + /* initialize_hook */ NULL, + /* realize */ XtInheritRealize, + /* actions */ NULL, + /* num_actions */ 0, + /* resources */ resources, + /* num_resources */ XtNumber(resources), + /* xrm_class */ NULLQUARK, + /* compress_motion */ TRUE, + /* compress_exposure */ TRUE, + /* compress_enterleave */ TRUE, + /* visible_interest */ FALSE, + /* destroy */ Destroy, + /* resize */ Resize, + /* expose */ Redisplay, + /* set_values */ SetValues, + /* set_values_hook */ NULL, + /* set_values_almost */ XtInheritSetValuesAlmost, + /* get_values_hook */ NULL, + /* accept_focus */ NULL, + /* version */ XtVersion, + /* callback_private */ NULL, + /* tm_table */ NULL, + /* query_geometry */ QueryGeometry, + /* display_accelerator */ XtInheritDisplayAccelerator, + /* extension */ NULL + }, +/* Simple class fields initialization */ + { + /* change_sensitive */ XtInheritChangeSensitive + }, +/* ThreeD class fields initialization */ + { + /* shadowdraw */ XtInheritXaw3dShadowDraw + }, +/* Label class fields initialization */ + { + /* ignore */ 0 + } +}; + +WidgetClass labelWidgetClass = (WidgetClass)&labelClassRec; + +/**************************************************************** + * + * Private Procedures + * + ****************************************************************/ + +static void ClassInitialize() +{ + XawInitializeWidgetSet(); + XtAddConverter( XtRString, XtRJustify, XmuCvtStringToJustify, + (XtConvertArgList)NULL, 0 ); +} + +#ifndef WORD64 + +#define TXT16 XChar2b + +#else + +#define TXT16 char + +static XChar2b *buf2b; +static int buf2blen = 0; + +_XawLabelWidth16(fs, str, n) + XFontStruct *fs; + char *str; + int n; +{ + int i; + XChar2b *ptr; + + if (n > buf2blen) { + buf2b = (XChar2b *)XtRealloc((char *)buf2b, n * sizeof(XChar2b)); + buf2blen = n; + } + for (ptr = buf2b, i = n; --i >= 0; ptr++) { + ptr->byte1 = *str++; + ptr->byte2 = *str++; + } + return XTextWidth16(fs, buf2b, n); +} + +_XawLabelDraw16(dpy, d, gc, x, y, str, n) + Display *dpy; + Drawable d; + GC gc; + int x, y; + char *str; + int n; +{ + int i; + XChar2b *ptr; + + if (n > buf2blen) { + buf2b = (XChar2b *)XtRealloc((char *)buf2b, n * sizeof(XChar2b)); + buf2blen = n; + } + for (ptr = buf2b, i = n; --i >= 0; ptr++) { + ptr->byte1 = *str++; + ptr->byte2 = *str++; + } + XDrawString16(dpy, d, gc, x, y, buf2b, n); +} + +#define XTextWidth16 _XawLabelWidth16 +#define XDrawString16 _XawLabelDraw16 + +#endif /* WORD64 */ + +/* + * Calculate width and height of displayed text in pixels + */ + +static void SetTextWidthAndHeight(lw) + LabelWidget lw; +{ + XFontStruct *fs = lw->label.font; + + char *nl; + + if (lw->label.pixmap != None) { + Window root; + int x, y; + unsigned int width, height, bw, depth; + + if (XGetGeometry(XtDisplay(lw), lw->label.pixmap, &root, &x, &y, + &width, &height, &bw, &depth)) { + lw->label.label_height = height; + lw->label.label_width = width; + lw->label.depth = depth; + return; + } + } +#ifdef XAW_INTERNATIONALIZATION + if ( lw->simple.international == True ) { + XFontSet fset = lw->label.fontset; + XFontSetExtents *ext = XExtentsOfFontSet(fset); + + lw->label.label_height = ext->max_ink_extent.height; + if (lw->label.label == NULL) { + lw->label.label_len = 0; + lw->label.label_width = 0; + } + else if ((nl = index(lw->label.label, '\n')) != NULL) { + char *label; + lw->label.label_len = MULTI_LINE_LABEL; + lw->label.label_width = 0; + for (label = lw->label.label; nl != NULL; nl = index(label, '\n')) { + int width = XmbTextEscapement(fset, label, (int)(nl - label)); + + if (width > (int)lw->label.label_width) + lw->label.label_width = width; + label = nl + 1; + if (*label) + lw->label.label_height += + ext->max_ink_extent.height; + } + if (*label) { + int width = XmbTextEscapement(fset, label, strlen(label)); + + if (width > (int) lw->label.label_width) + lw->label.label_width = width; + } + } else { + lw->label.label_len = strlen(lw->label.label); + lw->label.label_width = + XmbTextEscapement(fset, lw->label.label, (int) lw->label.label_len); + } + + } else +#endif + { + lw->label.label_height = fs->max_bounds.ascent + fs->max_bounds.descent; + if (lw->label.label == NULL) { + lw->label.label_len = 0; + lw->label.label_width = 0; + } + else if ((nl = index(lw->label.label, '\n')) != NULL) { + char *label; + lw->label.label_len = MULTI_LINE_LABEL; + lw->label.label_width = 0; + for (label = lw->label.label; nl != NULL; nl = index(label, '\n')) { + int width; + + if (lw->label.encoding) + width = XTextWidth16(fs, (TXT16*)label, (int)(nl - label)/2); + else + width = XTextWidth(fs, label, (int)(nl - label)); + if (width > (int)lw->label.label_width) + lw->label.label_width = width; + label = nl + 1; + if (*label) + lw->label.label_height += + fs->max_bounds.ascent + fs->max_bounds.descent; + } + if (*label) { + int width = XTextWidth(fs, label, strlen(label)); + + if (lw->label.encoding) + width = XTextWidth16(fs, (TXT16*)label, (int)strlen(label)/2); + else + width = XTextWidth(fs, label, strlen(label)); + if (width > (int) lw->label.label_width) + lw->label.label_width = width; + } + } else { + lw->label.label_len = strlen(lw->label.label); + if (lw->label.encoding) + lw->label.label_width = + XTextWidth16(fs, (TXT16*)lw->label.label, + (int) lw->label.label_len/2); + else + lw->label.label_width = + XTextWidth(fs, lw->label.label, (int) lw->label.label_len); + } + + } +} + +static void GetnormalGC(lw) + LabelWidget lw; +{ + XGCValues values; + + values.foreground = lw->label.foreground; + values.background = lw->core.background_pixel; + values.font = lw->label.font->fid; + values.graphics_exposures = False; + +#ifdef XAW_INTERNATIONALIZATION + if ( lw->simple.international == True ) + /* Since Xmb/wcDrawString eats the font, I must use XtAllocateGC. */ + lw->label.normal_GC = XtAllocateGC( + (Widget)lw, 0, + (unsigned) GCForeground | GCBackground | GCGraphicsExposures, + &values, GCFont, 0 ); + else +#endif + lw->label.normal_GC = XtGetGC( + (Widget)lw, + (unsigned) GCForeground | GCBackground | GCFont | GCGraphicsExposures, + &values); +} + +static void GetgrayGC(lw) + LabelWidget lw; +{ + XGCValues values; + + values.foreground = lw->label.foreground; + values.background = lw->core.background_pixel; + values.font = lw->label.font->fid; + values.fill_style = FillTiled; + values.tile = XmuCreateStippledPixmap(XtScreen((Widget)lw), + lw->label.foreground, + lw->core.background_pixel, + lw->core.depth); + values.graphics_exposures = False; + + lw->label.stipple = values.tile; +#ifdef XAW_INTERNATIONALIZATION + if ( lw->simple.international == True ) + /* Since Xmb/wcDrawString eats the font, I must use XtAllocateGC. */ + lw->label.gray_GC = XtAllocateGC((Widget)lw, 0, + (unsigned) GCForeground | GCBackground | + GCTile | GCFillStyle | + GCGraphicsExposures, + &values, GCFont, 0); + else +#endif + lw->label.gray_GC = XtGetGC((Widget)lw, + (unsigned) GCForeground | GCBackground | + GCFont | GCTile | GCFillStyle | + GCGraphicsExposures, + &values); +} + +static void compute_bitmap_offsets (lw) + LabelWidget lw; +{ + if (lw->label.lbm_height != 0) + lw->label.lbm_y = (lw->core.height - lw->label.lbm_height) / 2; + else + lw->label.lbm_y = 0; +} + +static void set_bitmap_info (lw) + LabelWidget lw; +{ + Window root; + int x, y; + unsigned int bw; + + if (lw->label.pixmap || !(lw->label.left_bitmap && + XGetGeometry (XtDisplay(lw), lw->label.left_bitmap, &root, &x, &y, + &lw->label.lbm_width, &lw->label.lbm_height, + &bw, &lw->label.depth))) { + lw->label.lbm_width = lw->label.lbm_height = 0; + } + compute_bitmap_offsets (lw); +} + +/* ARGSUSED */ +static void Initialize(request, new, args, num_args) + Widget request, new; + ArgList args; + Cardinal *num_args; +{ + extern WidgetClass commandWidgetClass; + LabelWidget lw = (LabelWidget) new; + + /* disable shadows if we're not a subclass of Command */ + if (!XtIsSubclass(new, commandWidgetClass)) + lw->threeD.shadow_width = 0; + + if (lw->label.label == NULL) + lw->label.label = XtNewString(lw->core.name); + else + lw->label.label = XtNewString(lw->label.label); + + GetnormalGC(lw); + GetgrayGC(lw); + + SetTextWidthAndHeight(lw); /* label.label or label.pixmap */ + + if (lw->core.height == 0) + lw->core.height = lw->label.label_height + + 2 * lw->label.internal_height; + + set_bitmap_info(lw); /* req's core.height, sets label.lbm_* */ + + if (lw->label.lbm_height > lw->label.label_height) + lw->core.height = lw->label.lbm_height + + 2 * lw->label.internal_height; + + if (lw->core.width == 0) + lw->core.width = lw->label.label_width + + 2 * lw->label.internal_width + + LEFT_OFFSET(lw); /* req's label.lbm_width */ + + lw->label.label_x = lw->label.label_y = 0; + (*XtClass(new)->core_class.resize) ((Widget)lw); + + lw->label.stippled = lw->label.left_stippled = None; +} /* Initialize */ + +/* + * Repaint the widget window + */ + +/* ARGSUSED */ +static void Redisplay(gw, event, region) + Widget gw; + XEvent *event; + Region region; +{ + extern WidgetClass commandWidgetClass; + LabelWidget w = (LabelWidget) gw; + LabelWidgetClass lwclass = (LabelWidgetClass) XtClass (gw); + Pixmap pm; + GC gc; + + /* + * Don't draw shadows if Command is going to redraw them. + * The shadow draw method is region aware, but since 99% of + * all labels don't have shadows, we'll check for a shadow + * before we incur the function call overhead. + */ + if (!XtIsSubclass (gw, commandWidgetClass) && w->threeD.shadow_width > 0) + (*lwclass->threeD_class.shadowdraw) (gw, event, region, + w->threeD.relief, True); + + /* + * now we'll see if we need to draw the rest of the label + */ + if (region != NULL) { + int x = w->label.label_x; + unsigned int width = w->label.label_width; + if (w->label.lbm_width) { + if (w->label.label_x > (x = w->label.internal_width)) + width += w->label.label_x - x; + } + if (XRectInRegion(region, x, w->label.label_y, + width, w->label.label_height) == RectangleOut){ + return; + } + } + + gc = XtIsSensitive(gw) ? w->label.normal_GC : w->label.gray_GC; +#ifdef notdef + if (region != NULL) + XSetRegion(XtDisplay(gw), gc, region); +#endif /*notdef*/ + + if (w->label.pixmap == None) { + int len = w->label.label_len; + char *label = w->label.label; + Position y = w->label.label_y + w->label.font->max_bounds.ascent; + Position ksy = w->label.label_y; + + /* display left bitmap */ + if (w->label.left_bitmap && w->label.lbm_width != 0) { + pm = w->label.left_bitmap; +#ifdef XAW_MULTIPLANE_PIXMAPS + if (!XtIsSensitive(gw)) { + if (w->label.left_stippled == None) + w->label.left_stippled = stipplePixmap(gw, + w->label.left_bitmap, w->core.colormap, + w->core.background_pixel, w->label.depth); + if (w->label.left_stippled != None) + pm = w->label.left_stippled; + } +#endif + + if (w->label.depth == 1) + XCopyPlane(XtDisplay(gw), pm, XtWindow(gw), gc, 0, 0, + w->label.lbm_width, w->label.lbm_height, + (int) w->label.internal_width, + (int) w->label.lbm_y, + (unsigned long) 1L); + else + XCopyArea(XtDisplay(gw), pm, XtWindow(gw), gc, 0, 0, + w->label.lbm_width, w->label.lbm_height, + (int) w->label.internal_width, + (int) w->label.lbm_y); + } + +#ifdef XAW_INTERNATIONALIZATION + if ( w->simple.international == True ) { + + XFontSetExtents *ext = XExtentsOfFontSet(w->label.fontset); + + ksy += abs(ext->max_ink_extent.y); + + if (len == MULTI_LINE_LABEL) { + char *nl; + while ((nl = index(label, '\n')) != NULL) { + XmbDrawString(XtDisplay(w), XtWindow(w), w->label.fontset, gc, + w->label.label_x, ksy, label, (int)(nl - label)); + ksy += ext->max_ink_extent.height; + label = nl + 1; + } + len = strlen(label); + } + if (len) + XmbDrawString(XtDisplay(w), XtWindow(w), w->label.fontset, gc, + w->label.label_x, ksy, label, len); + + } else +#endif + { /* international false, so use R5 routine */ + + if (len == MULTI_LINE_LABEL) { + char *nl; + while ((nl = index(label, '\n')) != NULL) { + if (w->label.encoding) + XDrawString16(XtDisplay(gw), XtWindow(gw), gc, + w->label.label_x, y, + (TXT16*)label, (int)(nl - label)/2); + else + XDrawString(XtDisplay(gw), XtWindow(gw), gc, + w->label.label_x, y, label, (int)(nl - label)); + y += w->label.font->max_bounds.ascent + + w->label.font->max_bounds.descent; + label = nl + 1; + } + len = strlen(label); + } + if (len) { + if (w->label.encoding) + XDrawString16(XtDisplay(gw), XtWindow(gw), gc, + w->label.label_x, y, (TXT16*)label, len/2); + else + XDrawString(XtDisplay(gw), XtWindow(gw), gc, + w->label.label_x, y, label, len); + } + + } /* endif international */ + + } else { + pm = w->label.pixmap; +#ifdef XAW_MULTIPLANE_PIXMAPS + if (!XtIsSensitive(gw)) { + if (w->label.stippled == None) + w->label.stippled = stipplePixmap(gw, + w->label.pixmap, w->core.colormap, + w->core.background_pixel, w->label.depth); + if (w->label.stippled != None) + pm = w->label.stippled; + } +#endif + + if (w->label.depth == 1) + XCopyPlane(XtDisplay(gw), pm, XtWindow(gw), gc, 0, 0, + w->label.label_width, w->label.label_height, + w->label.label_x, w->label.label_y, + 1L); + else + XCopyArea(XtDisplay(gw), pm, XtWindow(gw), gc, 0, 0, + w->label.label_width, w->label.label_height, + w->label.label_x, w->label.label_y); + } + +#ifdef notdef + if (region != NULL) + XSetClipMask(XtDisplay(gw), gc, (Pixmap)None); +#endif /* notdef */ +} + +static void _Reposition(lw, width, height, dx, dy) + LabelWidget lw; + Dimension width, height; + Position *dx, *dy; +{ + Position newPos; + Position leftedge = lw->label.internal_width + LEFT_OFFSET(lw); + + switch (lw->label.justify) { + case XtJustifyLeft: + newPos = leftedge; + break; + case XtJustifyRight: + newPos = width - lw->label.label_width - lw->label.internal_width; + break; + case XtJustifyCenter: + default: + newPos = (int)(width - lw->label.label_width) / 2; + break; + } + + if (newPos < (Position)leftedge) + newPos = leftedge; + *dx = newPos - lw->label.label_x; + lw->label.label_x = newPos; + + *dy = (newPos = (int)(height - lw->label.label_height) / 2) + - lw->label.label_y; + lw->label.label_y = newPos; + + lw->label.lbm_y = (height - lw->label.lbm_height) / 2; + + return; +} + +static void Resize(w) + Widget w; +{ + LabelWidget lw = (LabelWidget)w; + Position dx, dy; + + _Reposition(lw, w->core.width, w->core.height, &dx, &dy); + compute_bitmap_offsets (lw); +} + +/* + * Set specified arguments into widget + */ + +#define PIXMAP 0 +#define WIDTH 1 +#define HEIGHT 2 +#define NUM_CHECKS 3 + +static Boolean SetValues(current, request, new, args, num_args) + Widget current, request, new; + ArgList args; + Cardinal *num_args; +{ + LabelWidget curlw = (LabelWidget) current; + LabelWidget reqlw = (LabelWidget) request; + LabelWidget newlw = (LabelWidget) new; + int i; + Boolean was_resized = False, redisplay = False, checks[NUM_CHECKS]; + + for (i = 0; i < NUM_CHECKS; i++) + checks[i] = FALSE; + for (i = 0; i < *num_args; i++) { + if (streq(XtNbitmap, args[i].name)) + checks[PIXMAP] = TRUE; + if (streq(XtNwidth, args[i].name)) + checks[WIDTH] = TRUE; + if (streq(XtNheight, args[i].name)) + checks[HEIGHT] = TRUE; + } + + if (newlw->label.label == NULL) + newlw->label.label = newlw->core.name; + if (curlw->label.label != newlw->label.label) { + if (curlw->label.label != curlw->core.name) + XtFree((char *)curlw->label.label); + if (newlw->label.label != newlw->core.name) + newlw->label.label = XtNewString(newlw->label.label); + was_resized = True; + } + + if (was_resized || checks[PIXMAP] || + curlw->label.font != newlw->label.font || +#ifdef XAW_INTERNATIONALIZATION + (curlw->simple.international && + curlw->label.fontset != newlw->label.fontset) || +#endif + curlw->label.encoding != newlw->label.encoding || + curlw->label.justify != newlw->label.justify) { + SetTextWidthAndHeight(newlw); /* label.label or label.pixmap */ + was_resized = True; + } + + if (curlw->label.left_bitmap != newlw->label.left_bitmap || + curlw->label.internal_width != newlw->label.internal_width || + curlw->label.internal_height != newlw->label.internal_height) + was_resized = True; + + /* recalculate the window size if something has changed. */ + if (newlw->label.resize && was_resized) { + if (curlw->core.height == reqlw->core.height && !checks[HEIGHT]) + newlw->core.height = newlw->label.label_height + + 2 * newlw->label.internal_height; + + set_bitmap_info (newlw); /* req's core.height, sets label.lbm_* */ + + if (newlw->label.lbm_height > newlw->label.label_height) + newlw->core.height = newlw->label.lbm_height + + 2 * newlw->label.internal_height; + + if (curlw->core.width == reqlw->core.width && !checks[WIDTH]) + newlw->core.width = newlw->label.label_width + + 2 * newlw->label.internal_width + + LEFT_OFFSET(newlw); /* req's label.lbm_width */ + } + + /* enforce minimum dimensions */ + if (newlw->label.resize) { + if (checks[HEIGHT]) { + if (newlw->label.label_height > newlw->label.lbm_height) + i = newlw->label.label_height + + 2 * newlw->label.internal_height; + else + i = newlw->label.lbm_height + 2 * newlw->label.internal_height; + if (i > newlw->core.height) + newlw->core.height = i; + } + if (checks[WIDTH]) { + i = newlw->label.label_width + 2 * newlw->label.internal_width + + LEFT_OFFSET(newlw); /* req's label.lbm_width */ + if (i > newlw->core.width) + newlw->core.width = i; + } + } + + if (curlw->core.background_pixel != newlw->core.background_pixel || + curlw->label.foreground != newlw->label.foreground || + curlw->label.font->fid != newlw->label.font->fid) { + /* the fontset is not in the GC - no new GC if fontset changes */ + XtReleaseGC(new, curlw->label.normal_GC); + XtReleaseGC(new, curlw->label.gray_GC); + XmuReleaseStippledPixmap( XtScreen(current), curlw->label.stipple ); + GetnormalGC(newlw); + GetgrayGC(newlw); + redisplay = True; + } + +#ifdef XAW_MULTIPLANE_PIXMAPS + if (curlw->label.pixmap != newlw->label.pixmap) + { + newlw->label.stippled = None; + if (curlw->label.stippled != None) + XFreePixmap(XtDisplay(current), curlw->label.stippled); + } + if (curlw->label.left_bitmap != newlw->label.left_bitmap) + { + newlw->label.left_stippled = None; + if (curlw->label.left_stippled != None) + XFreePixmap(XtDisplay(current), curlw->label.left_stippled); + } +#endif + + if (was_resized) { + Position dx, dy; + + /* Resize() will be called if geometry changes succeed */ + _Reposition(newlw, curlw->core.width, curlw->core.height, &dx, &dy); + } + + return was_resized || redisplay || + XtIsSensitive(current) != XtIsSensitive(new); +} + +static void Destroy(w) + Widget w; +{ + LabelWidget lw = (LabelWidget)w; + + if ( lw->label.label != lw->core.name ) + XtFree( lw->label.label ); + XtReleaseGC( w, lw->label.normal_GC ); + XtReleaseGC( w, lw->label.gray_GC); +#ifdef XAW_MULTIPLANE_PIXMAPS + if (lw->label.stippled != None) + XFreePixmap(XtDisplay(w), lw->label.stippled); + if (lw->label.left_stippled != None) + XFreePixmap(XtDisplay(w), lw->label.left_stippled); +#endif + XmuReleaseStippledPixmap( XtScreen(w), lw->label.stipple ); +} + + +static XtGeometryResult QueryGeometry(w, intended, preferred) + Widget w; + XtWidgetGeometry *intended, *preferred; +{ + LabelWidget lw = (LabelWidget)w; + + preferred->request_mode = CWWidth | CWHeight; + preferred->width = (lw->label.label_width + + 2 * lw->label.internal_width + + LEFT_OFFSET(lw)); + preferred->height = lw->label.label_height + + 2 * lw->label.internal_height; + if ( ((intended->request_mode & (CWWidth | CWHeight)) + == (CWWidth | CWHeight)) && + intended->width == preferred->width && + intended->height == preferred->height) + return XtGeometryYes; + else if (preferred->width == w->core.width && + preferred->height == w->core.height) + return XtGeometryNo; + else + return XtGeometryAlmost; +} |