summaryrefslogtreecommitdiff
path: root/ULabel.c
diff options
context:
space:
mode:
authorKaleb Keithley <kaleb@freedesktop.org>2003-11-14 16:49:22 +0000
committerKaleb Keithley <kaleb@freedesktop.org>2003-11-14 16:49:22 +0000
commitec7cff5eb04007f30e0fa732bca8a55882f5482f (patch)
tree5192e7a29d7555162fffc2a4428894a8d5ac206f /ULabel.c
Initial revisionXORG-STABLE
Diffstat (limited to 'ULabel.c')
-rw-r--r--ULabel.c864
1 files changed, 864 insertions, 0 deletions
diff --git a/ULabel.c b/ULabel.c
new file mode 100644
index 0000000..c449ea3
--- /dev/null
+++ b/ULabel.c
@@ -0,0 +1,864 @@
+/* $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.
+
+******************************************************************/
+/* $XFree86: xc/programs/xfontsel/ULabel.c,v 1.3 2001/10/28 03:34:32 tsi Exp $ */
+
+/*
+ * ULabel.c - UCSLabel widget
+ *
+ */
+
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+#include <X11/Xos.h>
+#include <X11/Xaw/XawInit.h>
+#include "ULabelP.h"
+#include <X11/Xmu/Converters.h>
+#include <X11/Xmu/Drawing.h>
+#include <stdio.h>
+#include <ctype.h>
+/* needed for abs() */
+#include <stdlib.h>
+
+#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(UCSLabelRec, field)
+static XtResource resources[] = {
+ {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
+ offset(label.foreground), XtRString, XtDefaultForeground},
+ {XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *),
+ offset(label.font),XtRString, XtDefaultFont},
+ {XtNfontSet, XtCFontSet, XtRFontSet, sizeof(XFontSet ),
+ offset(label.fontset),XtRString, XtDefaultFontSet},
+ {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},
+};
+#undef offset
+
+static void Initialize();
+static void Resize();
+static void Redisplay();
+static Boolean SetValues();
+static void ClassInitialize();
+static void Destroy();
+static XtGeometryResult QueryGeometry();
+
+UCSLabelClassRec ucsLabelClassRec = {
+ {
+/* core_class fields */
+ /* superclass */ (WidgetClass) &simpleClassRec,
+ /* class_name */ "UCSLabel",
+ /* widget_size */ sizeof(UCSLabelRec),
+ /* 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
+ },
+/* UCSLabel class fields initialization */
+ {
+ /* ignore */ 0
+ }
+};
+WidgetClass ucsLabelWidgetClass = (WidgetClass)&ucsLabelClassRec;
+/****************************************************************
+ *
+ * Private Procedures
+ *
+ ****************************************************************/
+
+static void ClassInitialize()
+{
+ XawInitializeWidgetSet();
+ XtAddConverter( XtRString, XtRJustify, XmuCvtStringToJustify,
+ (XtConvertArgList)NULL, 0 );
+}
+
+static XChar2b *buf2b;
+static int buf2blen = 0;
+
+#ifndef WORD64
+
+#define TXT16 XChar2b
+
+#else
+
+#define TXT16 char
+
+static int _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);
+}
+
+static void _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 */
+
+static void _XawLabelDrawUCS(dpy, d, gc, x, y, str, n)
+ Display *dpy;
+ Drawable d;
+ GC gc;
+ int x, y;
+ char *str;
+ int n;
+{
+ char *ep;
+ unsigned short codepoint;
+ XChar2b *ptr;
+
+ /*
+ * Convert to UCS2 string on the fly.
+ */
+
+ if (n > buf2blen) {
+ buf2b = (XChar2b *)XtRealloc((char *)buf2b, n * sizeof(XChar2b));
+ buf2blen = n;
+ }
+ ep = str + n;
+ for (ptr = buf2b; str < ep; ptr++) {
+ if((str[0]&0x80)==0) {
+ codepoint=str[0];
+ str++;
+ } else if((str[0]&0x20)==0) {
+ codepoint=(str[0]&0x1F)<<6 | (str[1]&0x3F);
+ str+=2;
+ } else if((str[0]&0x10)==0) {
+ codepoint=(str[0]&0x0F)<<12 | (str[1]&0x3F)<<6 | (str[2]&0x3F);
+ str+=3;
+ } else { /* wrong UTF-8 */
+ codepoint=(unsigned)'?';
+ str++;
+ }
+ ptr->byte1 = (codepoint >> 8) & 0xff;;
+ ptr->byte2 = codepoint & 0xff;
+ }
+ XDrawString16(dpy, d, gc, x, y, buf2b, ptr - buf2b);
+}
+
+static int _XawLabelWidthUCS(fs, str, n)
+ XFontStruct *fs;
+ char *str;
+ int n;
+{
+ char *ep;
+ unsigned short codepoint;
+ XChar2b *ptr;
+
+ /*
+ * Convert to UCS2 string on the fly.
+ */
+
+ if (n > buf2blen) {
+ buf2b = (XChar2b *)XtRealloc((char *)buf2b, n * sizeof(XChar2b));
+ buf2blen = n;
+ }
+ ep = str + n;
+ for (ptr = buf2b; str < ep; ptr++) {
+ if((str[0]&0x80)==0) {
+ codepoint=str[0];
+ str++;
+ } else if((str[0]&0x20)==0) {
+ codepoint=(str[0]&0x1F)<<6 | (str[1]&0x3F);
+ str+=2;
+ } else if((str[0]&0x10)==0) {
+ codepoint=(str[0]&0x0F)<<12 | (str[1]&0x3F)<<6 | (str[2]&0x3F);
+ str+=3;
+ } else { /* wrong UTF-8 */
+ codepoint=(unsigned)'?';
+ str++;
+ }
+ ptr->byte1 = (codepoint >> 8) & 0xff;;
+ ptr->byte2 = codepoint & 0xff;
+ }
+ return XTextWidth16(fs, buf2b, ptr - buf2b);
+}
+
+#define XTextWidthUCS _XawLabelWidthUCS
+#define XDrawStringUCS _XawLabelDrawUCS
+
+/*
+ * Calculate width and height of displayed text in pixels
+ */
+
+static void SetTextWidthAndHeight(lw)
+ UCSLabelWidget 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.label_len = depth;
+ return;
+ }
+ }
+ 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 {
+
+ 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 == XawTextEncodingChar2b)
+ width = XTextWidth16(fs, (TXT16*)label, (int)(nl - label)/2);
+ else if (lw->label.encoding == XawTextEncodingUCS)
+ width = XTextWidthUCS(fs, label, nl - label);
+ 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;
+
+ if (lw->label.encoding == XawTextEncodingChar2b)
+ width = XTextWidth16(fs, (TXT16*)label, (int)strlen(label)/2);
+ else if (lw->label.encoding == XawTextEncodingUCS)
+ width = XTextWidthUCS(fs, label, strlen(label));
+ 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 == XawTextEncodingChar2b)
+ lw->label.label_width =
+ XTextWidth16(fs, (TXT16*)lw->label.label,
+ (int) lw->label.label_len/2);
+ else if (lw->label.encoding == XawTextEncodingUCS)
+ lw->label.label_width = XTextWidthUCS(fs, lw->label.label,
+ lw->label.label_len);
+ else
+ lw->label.label_width =
+ XTextWidth(fs, lw->label.label, (int) lw->label.label_len);
+ }
+
+ }
+}
+
+static void GetnormalGC(lw)
+ UCSLabelWidget lw;
+{
+ XGCValues values;
+
+ values.foreground = lw->label.foreground;
+ values.background = lw->core.background_pixel;
+ values.font = lw->label.font->fid;
+ values.graphics_exposures = False;
+
+ 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
+ lw->label.normal_GC = XtGetGC(
+ (Widget)lw,
+ (unsigned) GCForeground | GCBackground | GCFont | GCGraphicsExposures,
+ &values);
+}
+
+static void GetgrayGC(lw)
+ UCSLabelWidget 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;
+ 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
+ lw->label.gray_GC = XtGetGC((Widget)lw,
+ (unsigned) GCForeground | GCBackground |
+ GCFont | GCTile | GCFillStyle |
+ GCGraphicsExposures,
+ &values);
+}
+
+static void compute_bitmap_offsets (lw)
+ UCSLabelWidget lw;
+{
+ /*
+ * bitmap will be eventually be displayed at
+ * (internal_width, internal_height + lbm_y)
+ */
+ if (lw->label.lbm_height != 0) {
+ lw->label.lbm_y = (lw->core.height -
+ (lw->label.internal_height * 2 +
+ lw->label.lbm_height)) / 2;
+ } else {
+ lw->label.lbm_y = 0;
+ }
+}
+
+
+static void set_bitmap_info (lw)
+ UCSLabelWidget lw;
+{
+ Window root;
+ int x, y;
+ unsigned int bw, depth;
+
+ if (!(lw->label.left_bitmap &&
+ XGetGeometry (XtDisplay(lw), lw->label.left_bitmap, &root, &x, &y,
+ &lw->label.lbm_width, &lw->label.lbm_height,
+ &bw, &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;
+{
+ UCSLabelWidget lw = (UCSLabelWidget) new;
+
+ 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);
+
+ if (lw->core.height == 0)
+ lw->core.height = lw->label.label_height +
+ 2 * lw->label.internal_height;
+
+ set_bitmap_info (lw); /* need core.height */
+
+ if (lw->core.width == 0) /* need label.lbm_width */
+ lw->core.width = (lw->label.label_width +
+ 2 * lw->label.internal_width +
+ LEFT_OFFSET(lw));
+
+ lw->label.label_x = lw->label.label_y = 0;
+ (*XtClass(new)->core_class.resize) ((Widget)lw);
+
+} /* Initialize */
+
+/*
+ * Repaint the widget window
+ */
+
+/* ARGSUSED */
+static void Redisplay(gw, event, region)
+ Widget gw;
+ XEvent *event;
+ Region region;
+{
+ UCSLabelWidget w = (UCSLabelWidget) gw;
+ GC gc;
+
+ /*
+ * 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) {
+ XCopyPlane (XtDisplay(gw), w->label.left_bitmap, XtWindow(gw), gc,
+ 0, 0, w->label.lbm_width, w->label.lbm_height,
+ (int) w->label.internal_width,
+ (int) w->label.internal_height + w->label.lbm_y,
+ (unsigned long) 1L);
+ }
+
+ 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 { /*international false, so use R5 routine */
+
+ if (len == MULTI_LINE_LABEL) {
+ char *nl;
+ while ((nl = index(label, '\n')) != NULL) {
+ if (w->label.encoding == XawTextEncodingChar2b)
+ XDrawString16(XtDisplay(gw), XtWindow(gw), gc,
+ w->label.label_x, y,
+ (TXT16*)label, (int)(nl - label)/2);
+ else if (w->label.encoding == XawTextEncodingUCS)
+ XDrawStringUCS(XtDisplay(gw), XtWindow(gw), gc,
+ w->label.label_x, y, label, (int)(nl - label));
+ 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 == XawTextEncodingChar2b)
+ XDrawString16(XtDisplay(gw), XtWindow(gw), gc,
+ w->label.label_x, y, (TXT16*)label, len/2);
+ else if (w->label.encoding == XawTextEncodingUCS)
+ XDrawStringUCS(XtDisplay(gw), XtWindow(gw), gc,
+ w->label.label_x, y, label, len);
+ else
+ XDrawString(XtDisplay(gw), XtWindow(gw), gc,
+ w->label.label_x, y, label, len);
+ }
+
+ } /*endif international*/
+
+ } else if (w->label.label_len == 1) { /* depth */
+ XCopyPlane(XtDisplay(gw), w->label.pixmap, 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), w->label.pixmap, 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)
+ UCSLabelWidget 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;
+ return;
+}
+
+static void Resize(w)
+ Widget w;
+{
+ UCSLabelWidget lw = (UCSLabelWidget)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;
+{
+ UCSLabelWidget curlw = (UCSLabelWidget) current;
+ UCSLabelWidget reqlw = (UCSLabelWidget) request;
+ UCSLabelWidget newlw = (UCSLabelWidget) 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;
+ }
+
+ /*
+ * resize on bitmap change
+ */
+ if (curlw->label.left_bitmap != newlw->label.left_bitmap) {
+ was_resized = True;
+ }
+
+ if (curlw->label.encoding != newlw->label.encoding)
+ was_resized = True;
+
+ if ( (curlw->label.fontset != newlw->label.fontset) &&
+ curlw->simple.international ){
+ was_resized = True;
+ }
+ 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 || (curlw->label.font != newlw->label.font) ||
+ (curlw->label.justify != newlw->label.justify) || checks[PIXMAP]) {
+
+ SetTextWidthAndHeight(newlw);
+ 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);
+
+ if ((curlw->core.width == reqlw->core.width) && !checks[WIDTH])
+ newlw->core.width = (newlw->label.label_width +
+ LEFT_OFFSET(newlw) +
+ 2 * newlw->label.internal_width);
+ }
+
+ if (curlw->label.foreground != newlw->label.foreground
+ || curlw->core.background_pixel != newlw->core.background_pixel
+ || curlw->label.font->fid != newlw->label.font->fid ) {
+
+ /* The Fontset is not in the GC - don't make a new GC if FS 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;
+ }
+
+ if ((curlw->label.internal_width != newlw->label.internal_width)
+ || (curlw->label.internal_height != newlw->label.internal_height)
+ || was_resized) {
+ /* Resize() will be called if geometry changes succeed */
+ Position dx, dy;
+ _Reposition(newlw, curlw->core.width, curlw->core.height, &dx, &dy);
+ }
+
+ return was_resized || redisplay ||
+ XtIsSensitive(current) != XtIsSensitive(new);
+}
+
+static void Destroy(w)
+ Widget w;
+{
+ UCSLabelWidget lw = (UCSLabelWidget)w;
+
+ if ( lw->label.label != lw->core.name )
+ XtFree( lw->label.label );
+ XtReleaseGC( w, lw->label.normal_GC );
+ XtReleaseGC( w, lw->label.gray_GC);
+ XmuReleaseStippledPixmap( XtScreen(w), lw->label.stipple );
+}
+
+
+static XtGeometryResult QueryGeometry(w, intended, preferred)
+ Widget w;
+ XtWidgetGeometry *intended, *preferred;
+{
+ UCSLabelWidget lw = (UCSLabelWidget)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;
+}