ULabel.c revision 376c9fa8
19027f4a0Smrg/*********************************************************** 29027f4a0Smrg 39027f4a0SmrgCopyright (c) 1987, 1988, 1994 X Consortium 49027f4a0Smrg 59027f4a0SmrgPermission is hereby granted, free of charge, to any person obtaining a copy 69027f4a0Smrgof this software and associated documentation files (the "Software"), to deal 79027f4a0Smrgin the Software without restriction, including without limitation the rights 89027f4a0Smrgto use, copy, modify, merge, publish, distribute, sublicense, and/or sell 99027f4a0Smrgcopies of the Software, and to permit persons to whom the Software is 109027f4a0Smrgfurnished to do so, subject to the following conditions: 119027f4a0Smrg 129027f4a0SmrgThe above copyright notice and this permission notice shall be included in 139027f4a0Smrgall copies or substantial portions of the Software. 149027f4a0Smrg 159027f4a0SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 169027f4a0SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 179027f4a0SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 189027f4a0SmrgX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 199027f4a0SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 209027f4a0SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 219027f4a0Smrg 229027f4a0SmrgExcept as contained in this notice, the name of the X Consortium shall not be 239027f4a0Smrgused in advertising or otherwise to promote the sale, use or other dealings 249027f4a0Smrgin this Software without prior written authorization from the X Consortium. 259027f4a0Smrg 269027f4a0Smrg 279027f4a0SmrgCopyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. 289027f4a0Smrg 299027f4a0Smrg All Rights Reserved 309027f4a0Smrg 31fe2ac8d7SmrgPermission to use, copy, modify, and distribute this software and its 32fe2ac8d7Smrgdocumentation for any purpose and without fee is hereby granted, 339027f4a0Smrgprovided that the above copyright notice appear in all copies and that 34fe2ac8d7Smrgboth that copyright notice and this permission notice appear in 359027f4a0Smrgsupporting documentation, and that the name of Digital not be 369027f4a0Smrgused in advertising or publicity pertaining to distribution of the 37fe2ac8d7Smrgsoftware without specific, written prior permission. 389027f4a0Smrg 399027f4a0SmrgDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 409027f4a0SmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 419027f4a0SmrgDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 429027f4a0SmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 439027f4a0SmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 449027f4a0SmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 459027f4a0SmrgSOFTWARE. 469027f4a0Smrg 479027f4a0Smrg******************************************************************/ 489027f4a0Smrg 499027f4a0Smrg/* 509027f4a0Smrg * ULabel.c - UCSLabel widget 519027f4a0Smrg * 529027f4a0Smrg */ 539027f4a0Smrg 549027f4a0Smrg#include <X11/IntrinsicP.h> 559027f4a0Smrg#include <X11/StringDefs.h> 569027f4a0Smrg#include <X11/Xos.h> 579027f4a0Smrg#include <X11/Xaw/XawInit.h> 589027f4a0Smrg#include "ULabelP.h" 599027f4a0Smrg#include <X11/Xmu/Converters.h> 609027f4a0Smrg#include <X11/Xmu/Drawing.h> 619027f4a0Smrg#include <stdio.h> 629027f4a0Smrg#include <ctype.h> 639027f4a0Smrg/* needed for abs() */ 649027f4a0Smrg#include <stdlib.h> 659027f4a0Smrg 669027f4a0Smrg#define streq(a,b) (strcmp( (a), (b) ) == 0) 679027f4a0Smrg 689027f4a0Smrg#define MULTI_LINE_LABEL 32767 699027f4a0Smrg 709027f4a0Smrg 719027f4a0Smrg/**************************************************************** 729027f4a0Smrg * 739027f4a0Smrg * Full class record constant 749027f4a0Smrg * 759027f4a0Smrg ****************************************************************/ 769027f4a0Smrg 779027f4a0Smrg/* Private Data */ 789027f4a0Smrg 799027f4a0Smrg#define offset(field) XtOffsetOf(UCSLabelRec, field) 809027f4a0Smrgstatic XtResource resources[] = { 819027f4a0Smrg {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel), 829027f4a0Smrg offset(label.foreground), XtRString, XtDefaultForeground}, 839027f4a0Smrg {XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *), 849027f4a0Smrg offset(label.font),XtRString, XtDefaultFont}, 859027f4a0Smrg {XtNfontSet, XtCFontSet, XtRFontSet, sizeof(XFontSet ), 869027f4a0Smrg offset(label.fontset),XtRString, XtDefaultFontSet}, 879027f4a0Smrg {XtNlabel, XtCLabel, XtRString, sizeof(String), 889027f4a0Smrg offset(label.label), XtRString, NULL}, 899027f4a0Smrg {XtNencoding, XtCEncoding, XtRUnsignedChar, sizeof(unsigned char), 909027f4a0Smrg offset(label.encoding), XtRImmediate, (XtPointer)XawTextEncoding8bit}, 919027f4a0Smrg {XtNjustify, XtCJustify, XtRJustify, sizeof(XtJustify), 929027f4a0Smrg offset(label.justify), XtRImmediate, (XtPointer)XtJustifyCenter}, 939027f4a0Smrg {XtNinternalWidth, XtCWidth, XtRDimension, sizeof(Dimension), 949027f4a0Smrg offset(label.internal_width), XtRImmediate, (XtPointer)4}, 959027f4a0Smrg {XtNinternalHeight, XtCHeight, XtRDimension, sizeof(Dimension), 969027f4a0Smrg offset(label.internal_height), XtRImmediate, (XtPointer)2}, 979027f4a0Smrg {XtNleftBitmap, XtCLeftBitmap, XtRBitmap, sizeof(Pixmap), 989027f4a0Smrg offset(label.left_bitmap), XtRImmediate, (XtPointer) None}, 999027f4a0Smrg {XtNbitmap, XtCPixmap, XtRBitmap, sizeof(Pixmap), 1009027f4a0Smrg offset(label.pixmap), XtRImmediate, (XtPointer)None}, 1019027f4a0Smrg {XtNresize, XtCResize, XtRBoolean, sizeof(Boolean), 1029027f4a0Smrg offset(label.resize), XtRImmediate, (XtPointer)True}, 1039027f4a0Smrg}; 1049027f4a0Smrg#undef offset 1059027f4a0Smrg 1063a72f200Smrgstatic void Initialize(Widget request, Widget new, 1073a72f200Smrg ArgList args, Cardinal *num_args); 1083a72f200Smrgstatic void Resize(Widget w); 1093a72f200Smrgstatic void Redisplay(Widget gw, XEvent *event, Region region); 1103a72f200Smrgstatic Boolean SetValues(Widget current, Widget request, Widget new, 1113a72f200Smrg ArgList args, Cardinal *num_args); 1123a72f200Smrgstatic void ClassInitialize(void); 1133a72f200Smrgstatic void Destroy(Widget w); 1143a72f200Smrgstatic XtGeometryResult QueryGeometry(Widget w, XtWidgetGeometry *intended, 1153a72f200Smrg XtWidgetGeometry *preferred); 1169027f4a0Smrg 1179027f4a0SmrgUCSLabelClassRec ucsLabelClassRec = { 1189027f4a0Smrg { 119fe2ac8d7Smrg/* core_class fields */ 1209027f4a0Smrg /* superclass */ (WidgetClass) &simpleClassRec, 1219027f4a0Smrg /* class_name */ "UCSLabel", 1229027f4a0Smrg /* widget_size */ sizeof(UCSLabelRec), 1239027f4a0Smrg /* class_initialize */ ClassInitialize, 1249027f4a0Smrg /* class_part_initialize */ NULL, 1259027f4a0Smrg /* class_inited */ FALSE, 1269027f4a0Smrg /* initialize */ Initialize, 1279027f4a0Smrg /* initialize_hook */ NULL, 1289027f4a0Smrg /* realize */ XtInheritRealize, 1299027f4a0Smrg /* actions */ NULL, 1309027f4a0Smrg /* num_actions */ 0, 1319027f4a0Smrg /* resources */ resources, 1329027f4a0Smrg /* num_resources */ XtNumber(resources), 1339027f4a0Smrg /* xrm_class */ NULLQUARK, 1349027f4a0Smrg /* compress_motion */ TRUE, 1359027f4a0Smrg /* compress_exposure */ TRUE, 1369027f4a0Smrg /* compress_enterleave */ TRUE, 1379027f4a0Smrg /* visible_interest */ FALSE, 1389027f4a0Smrg /* destroy */ Destroy, 1399027f4a0Smrg /* resize */ Resize, 1409027f4a0Smrg /* expose */ Redisplay, 1419027f4a0Smrg /* set_values */ SetValues, 1429027f4a0Smrg /* set_values_hook */ NULL, 1439027f4a0Smrg /* set_values_almost */ XtInheritSetValuesAlmost, 1449027f4a0Smrg /* get_values_hook */ NULL, 1459027f4a0Smrg /* accept_focus */ NULL, 1469027f4a0Smrg /* version */ XtVersion, 1479027f4a0Smrg /* callback_private */ NULL, 1489027f4a0Smrg /* tm_table */ NULL, 1499027f4a0Smrg /* query_geometry */ QueryGeometry, 1509027f4a0Smrg /* display_accelerator */ XtInheritDisplayAccelerator, 1519027f4a0Smrg /* extension */ NULL 1529027f4a0Smrg }, 1539027f4a0Smrg/* Simple class fields initialization */ 1549027f4a0Smrg { 1559027f4a0Smrg /* change_sensitive */ XtInheritChangeSensitive 1569027f4a0Smrg }, 1579027f4a0Smrg/* UCSLabel class fields initialization */ 1589027f4a0Smrg { 1599027f4a0Smrg /* ignore */ 0 1609027f4a0Smrg } 1619027f4a0Smrg}; 1629027f4a0SmrgWidgetClass ucsLabelWidgetClass = (WidgetClass)&ucsLabelClassRec; 1639027f4a0Smrg/**************************************************************** 1649027f4a0Smrg * 1659027f4a0Smrg * Private Procedures 1669027f4a0Smrg * 1679027f4a0Smrg ****************************************************************/ 1689027f4a0Smrg 1693a72f200Smrgstatic void ClassInitialize(void) 1709027f4a0Smrg{ 1719027f4a0Smrg XawInitializeWidgetSet(); 172fe2ac8d7Smrg XtAddConverter( XtRString, XtRJustify, XmuCvtStringToJustify, 1739027f4a0Smrg (XtConvertArgList)NULL, 0 ); 1749027f4a0Smrg} 1759027f4a0Smrg 1769027f4a0Smrgstatic XChar2b *buf2b; 1779027f4a0Smrgstatic int buf2blen = 0; 1789027f4a0Smrg 1793a72f200Smrgstatic void _XawLabelDrawUCS(Display *dpy, Drawable d, GC gc, 1803a72f200Smrg int x, int y, char *str, int n) 1819027f4a0Smrg{ 1829027f4a0Smrg char *ep; 1839027f4a0Smrg unsigned short codepoint; 1849027f4a0Smrg XChar2b *ptr; 1859027f4a0Smrg 1869027f4a0Smrg /* 1879027f4a0Smrg * Convert to UCS2 string on the fly. 1889027f4a0Smrg */ 1899027f4a0Smrg 1909027f4a0Smrg if (n > buf2blen) { 1919027f4a0Smrg buf2b = (XChar2b *)XtRealloc((char *)buf2b, n * sizeof(XChar2b)); 1929027f4a0Smrg buf2blen = n; 1939027f4a0Smrg } 1949027f4a0Smrg ep = str + n; 1959027f4a0Smrg for (ptr = buf2b; str < ep; ptr++) { 1969027f4a0Smrg if((str[0]&0x80)==0) { 1979027f4a0Smrg codepoint=str[0]; 1989027f4a0Smrg str++; 1999027f4a0Smrg } else if((str[0]&0x20)==0) { 2009027f4a0Smrg codepoint=(str[0]&0x1F)<<6 | (str[1]&0x3F); 2019027f4a0Smrg str+=2; 2029027f4a0Smrg } else if((str[0]&0x10)==0) { 2039027f4a0Smrg codepoint=(str[0]&0x0F)<<12 | (str[1]&0x3F)<<6 | (str[2]&0x3F); 2049027f4a0Smrg str+=3; 2059027f4a0Smrg } else { /* wrong UTF-8 */ 2069027f4a0Smrg codepoint=(unsigned)'?'; 2079027f4a0Smrg str++; 2089027f4a0Smrg } 209376c9fa8Smrg ptr->byte1 = (codepoint >> 8) & 0xff; 2109027f4a0Smrg ptr->byte2 = codepoint & 0xff; 2119027f4a0Smrg } 2129027f4a0Smrg XDrawString16(dpy, d, gc, x, y, buf2b, ptr - buf2b); 2139027f4a0Smrg} 2149027f4a0Smrg 2159027f4a0Smrgstatic int _XawLabelWidthUCS( 2169027f4a0Smrg XFontStruct *fs, 2179027f4a0Smrg char *str, 2189027f4a0Smrg int n 2199027f4a0Smrg) 2209027f4a0Smrg{ 2219027f4a0Smrg char *ep; 2229027f4a0Smrg unsigned short codepoint; 2239027f4a0Smrg XChar2b *ptr; 2249027f4a0Smrg 2259027f4a0Smrg /* 2269027f4a0Smrg * Convert to UCS2 string on the fly. 2279027f4a0Smrg */ 2289027f4a0Smrg 2299027f4a0Smrg if (n > buf2blen) { 2309027f4a0Smrg buf2b = (XChar2b *)XtRealloc((char *)buf2b, n * sizeof(XChar2b)); 2319027f4a0Smrg buf2blen = n; 2329027f4a0Smrg } 2339027f4a0Smrg ep = str + n; 2349027f4a0Smrg for (ptr = buf2b; str < ep; ptr++) { 2359027f4a0Smrg if((str[0]&0x80)==0) { 2369027f4a0Smrg codepoint=str[0]; 2379027f4a0Smrg str++; 2389027f4a0Smrg } else if((str[0]&0x20)==0) { 2399027f4a0Smrg codepoint=(str[0]&0x1F)<<6 | (str[1]&0x3F); 2409027f4a0Smrg str+=2; 2419027f4a0Smrg } else if((str[0]&0x10)==0) { 2429027f4a0Smrg codepoint=(str[0]&0x0F)<<12 | (str[1]&0x3F)<<6 | (str[2]&0x3F); 2439027f4a0Smrg str+=3; 2449027f4a0Smrg } else { /* wrong UTF-8 */ 2459027f4a0Smrg codepoint=(unsigned)'?'; 2469027f4a0Smrg str++; 2479027f4a0Smrg } 248376c9fa8Smrg ptr->byte1 = (codepoint >> 8) & 0xff; 2499027f4a0Smrg ptr->byte2 = codepoint & 0xff; 2509027f4a0Smrg } 2519027f4a0Smrg return XTextWidth16(fs, buf2b, ptr - buf2b); 2529027f4a0Smrg} 2539027f4a0Smrg 2549027f4a0Smrg#define XTextWidthUCS _XawLabelWidthUCS 2559027f4a0Smrg#define XDrawStringUCS _XawLabelDrawUCS 2569027f4a0Smrg 2579027f4a0Smrg/* 2589027f4a0Smrg * Calculate width and height of displayed text in pixels 2599027f4a0Smrg */ 2609027f4a0Smrg 2613a72f200Smrgstatic void SetTextWidthAndHeight(UCSLabelWidget lw) 2629027f4a0Smrg{ 2639027f4a0Smrg XFontStruct *fs = lw->label.font; 2649027f4a0Smrg 2659027f4a0Smrg char *nl; 2669027f4a0Smrg 2679027f4a0Smrg if (lw->label.pixmap != None) { 2689027f4a0Smrg Window root; 2699027f4a0Smrg int x, y; 2709027f4a0Smrg unsigned int width, height, bw, depth; 2719027f4a0Smrg if (XGetGeometry(XtDisplay(lw), lw->label.pixmap, &root, &x, &y, 2729027f4a0Smrg &width, &height, &bw, &depth)) { 2739027f4a0Smrg lw->label.label_height = height; 2749027f4a0Smrg lw->label.label_width = width; 2759027f4a0Smrg lw->label.label_len = depth; 2769027f4a0Smrg return; 2779027f4a0Smrg } 2789027f4a0Smrg } 2799027f4a0Smrg if ( lw->simple.international == True ) { 2809027f4a0Smrg 2819027f4a0Smrg XFontSet fset = lw->label.fontset; 2829027f4a0Smrg XFontSetExtents *ext = XExtentsOfFontSet(fset); 2839027f4a0Smrg 2849027f4a0Smrg lw->label.label_height = ext->max_ink_extent.height; 2859027f4a0Smrg if (lw->label.label == NULL) { 2869027f4a0Smrg lw->label.label_len = 0; 2879027f4a0Smrg lw->label.label_width = 0; 2889027f4a0Smrg } 2899027f4a0Smrg else if ((nl = index(lw->label.label, '\n')) != NULL) { 2909027f4a0Smrg char *label; 2919027f4a0Smrg lw->label.label_len = MULTI_LINE_LABEL; 2929027f4a0Smrg lw->label.label_width = 0; 2939027f4a0Smrg for (label = lw->label.label; nl != NULL; nl = index(label, '\n')) { 2949027f4a0Smrg int width = XmbTextEscapement(fset, label, (int)(nl - label)); 2959027f4a0Smrg 2969027f4a0Smrg if (width > (int)lw->label.label_width) 2979027f4a0Smrg lw->label.label_width = width; 2989027f4a0Smrg label = nl + 1; 2999027f4a0Smrg if (*label) 3009027f4a0Smrg lw->label.label_height += 3019027f4a0Smrg ext->max_ink_extent.height; 3029027f4a0Smrg } 3039027f4a0Smrg if (*label) { 3049027f4a0Smrg int width = XmbTextEscapement(fset, label, strlen(label)); 3059027f4a0Smrg 3069027f4a0Smrg if (width > (int) lw->label.label_width) 3079027f4a0Smrg lw->label.label_width = width; 3089027f4a0Smrg } 3099027f4a0Smrg } else { 3109027f4a0Smrg lw->label.label_len = strlen(lw->label.label); 3119027f4a0Smrg lw->label.label_width = 3129027f4a0Smrg XmbTextEscapement(fset, lw->label.label, (int) lw->label.label_len); 3139027f4a0Smrg } 3149027f4a0Smrg 3159027f4a0Smrg } else { 3169027f4a0Smrg 3179027f4a0Smrg lw->label.label_height = fs->max_bounds.ascent + fs->max_bounds.descent; 3189027f4a0Smrg if (lw->label.label == NULL) { 3199027f4a0Smrg lw->label.label_len = 0; 3209027f4a0Smrg lw->label.label_width = 0; 3219027f4a0Smrg } 3229027f4a0Smrg else if ((nl = index(lw->label.label, '\n')) != NULL) { 3239027f4a0Smrg char *label; 3249027f4a0Smrg lw->label.label_len = MULTI_LINE_LABEL; 3259027f4a0Smrg lw->label.label_width = 0; 3269027f4a0Smrg for (label = lw->label.label; nl != NULL; nl = index(label, '\n')) { 3279027f4a0Smrg int width; 3289027f4a0Smrg 3299027f4a0Smrg if (lw->label.encoding == XawTextEncodingChar2b) 330376c9fa8Smrg width = XTextWidth16(fs, (XChar2b *)label, (int)(nl - label)/2); 3319027f4a0Smrg else if (lw->label.encoding == XawTextEncodingUCS) 3329027f4a0Smrg width = XTextWidthUCS(fs, label, nl - label); 3339027f4a0Smrg else 3349027f4a0Smrg width = XTextWidth(fs, label, (int)(nl - label)); 3359027f4a0Smrg if (width > (int)lw->label.label_width) 3369027f4a0Smrg lw->label.label_width = width; 3379027f4a0Smrg label = nl + 1; 3389027f4a0Smrg if (*label) 3399027f4a0Smrg lw->label.label_height += 3409027f4a0Smrg fs->max_bounds.ascent + fs->max_bounds.descent; 3419027f4a0Smrg } 3429027f4a0Smrg if (*label) { 3439027f4a0Smrg int width; 3449027f4a0Smrg 3459027f4a0Smrg if (lw->label.encoding == XawTextEncodingChar2b) 346376c9fa8Smrg width = XTextWidth16(fs, (XChar2b *)label, (int)strlen(label)/2); 3479027f4a0Smrg else if (lw->label.encoding == XawTextEncodingUCS) 3489027f4a0Smrg width = XTextWidthUCS(fs, label, strlen(label)); 3499027f4a0Smrg else 3509027f4a0Smrg width = XTextWidth(fs, label, strlen(label)); 3519027f4a0Smrg if (width > (int) lw->label.label_width) 3529027f4a0Smrg lw->label.label_width = width; 3539027f4a0Smrg } 3549027f4a0Smrg } else { 3559027f4a0Smrg lw->label.label_len = strlen(lw->label.label); 3569027f4a0Smrg if (lw->label.encoding == XawTextEncodingChar2b) 3579027f4a0Smrg lw->label.label_width = 358376c9fa8Smrg XTextWidth16(fs, (XChar2b *)lw->label.label, 3599027f4a0Smrg (int) lw->label.label_len/2); 3609027f4a0Smrg else if (lw->label.encoding == XawTextEncodingUCS) 3619027f4a0Smrg lw->label.label_width = XTextWidthUCS(fs, lw->label.label, 3629027f4a0Smrg lw->label.label_len); 3639027f4a0Smrg else 3649027f4a0Smrg lw->label.label_width = 3659027f4a0Smrg XTextWidth(fs, lw->label.label, (int) lw->label.label_len); 3669027f4a0Smrg } 3679027f4a0Smrg 3689027f4a0Smrg } 3699027f4a0Smrg} 3709027f4a0Smrg 3713a72f200Smrgstatic void GetnormalGC(UCSLabelWidget lw) 3729027f4a0Smrg{ 3739027f4a0Smrg XGCValues values; 3749027f4a0Smrg 3759027f4a0Smrg values.foreground = lw->label.foreground; 3769027f4a0Smrg values.background = lw->core.background_pixel; 3779027f4a0Smrg values.font = lw->label.font->fid; 3789027f4a0Smrg values.graphics_exposures = False; 3799027f4a0Smrg 3809027f4a0Smrg if ( lw->simple.international == True ) 3819027f4a0Smrg /* Since Xmb/wcDrawString eats the font, I must use XtAllocateGC. */ 3829027f4a0Smrg lw->label.normal_GC = XtAllocateGC( 3839027f4a0Smrg (Widget)lw, 0, 3849027f4a0Smrg (unsigned) GCForeground | GCBackground | GCGraphicsExposures, 3859027f4a0Smrg &values, GCFont, 0 ); 3869027f4a0Smrg else 3879027f4a0Smrg lw->label.normal_GC = XtGetGC( 3889027f4a0Smrg (Widget)lw, 3899027f4a0Smrg (unsigned) GCForeground | GCBackground | GCFont | GCGraphicsExposures, 3909027f4a0Smrg &values); 3919027f4a0Smrg} 3929027f4a0Smrg 3933a72f200Smrgstatic void GetgrayGC(UCSLabelWidget lw) 3949027f4a0Smrg{ 3959027f4a0Smrg XGCValues values; 3969027f4a0Smrg 3979027f4a0Smrg values.foreground = lw->label.foreground; 3989027f4a0Smrg values.background = lw->core.background_pixel; 3999027f4a0Smrg values.font = lw->label.font->fid; 4009027f4a0Smrg values.fill_style = FillTiled; 4019027f4a0Smrg values.tile = XmuCreateStippledPixmap(XtScreen((Widget)lw), 402fe2ac8d7Smrg lw->label.foreground, 4039027f4a0Smrg lw->core.background_pixel, 4049027f4a0Smrg lw->core.depth); 4059027f4a0Smrg values.graphics_exposures = False; 4069027f4a0Smrg 4079027f4a0Smrg lw->label.stipple = values.tile; 4089027f4a0Smrg if ( lw->simple.international == True ) 4099027f4a0Smrg /* Since Xmb/wcDrawString eats the font, I must use XtAllocateGC. */ 4109027f4a0Smrg lw->label.gray_GC = XtAllocateGC((Widget)lw, 0, 4119027f4a0Smrg (unsigned) GCForeground | GCBackground | 4129027f4a0Smrg GCTile | GCFillStyle | 4139027f4a0Smrg GCGraphicsExposures, 4149027f4a0Smrg &values, GCFont, 0); 4159027f4a0Smrg else 416fe2ac8d7Smrg lw->label.gray_GC = XtGetGC((Widget)lw, 4179027f4a0Smrg (unsigned) GCForeground | GCBackground | 4189027f4a0Smrg GCFont | GCTile | GCFillStyle | 4199027f4a0Smrg GCGraphicsExposures, 4209027f4a0Smrg &values); 4219027f4a0Smrg} 4229027f4a0Smrg 4233a72f200Smrgstatic void compute_bitmap_offsets(UCSLabelWidget lw) 4249027f4a0Smrg{ 4259027f4a0Smrg /* 426fe2ac8d7Smrg * bitmap will be eventually be displayed at 4279027f4a0Smrg * (internal_width, internal_height + lbm_y) 4289027f4a0Smrg */ 4299027f4a0Smrg if (lw->label.lbm_height != 0) { 4309027f4a0Smrg lw->label.lbm_y = (lw->core.height - 431fe2ac8d7Smrg (lw->label.internal_height * 2 + 4329027f4a0Smrg lw->label.lbm_height)) / 2; 4339027f4a0Smrg } else { 4349027f4a0Smrg lw->label.lbm_y = 0; 4359027f4a0Smrg } 4369027f4a0Smrg} 4379027f4a0Smrg 4389027f4a0Smrg 4393a72f200Smrgstatic void set_bitmap_info(UCSLabelWidget lw) 4409027f4a0Smrg{ 4419027f4a0Smrg Window root; 4429027f4a0Smrg int x, y; 4439027f4a0Smrg unsigned int bw, depth; 4449027f4a0Smrg 4459027f4a0Smrg if (!(lw->label.left_bitmap && 4469027f4a0Smrg XGetGeometry (XtDisplay(lw), lw->label.left_bitmap, &root, &x, &y, 4479027f4a0Smrg &lw->label.lbm_width, &lw->label.lbm_height, 4489027f4a0Smrg &bw, &depth))) { 4499027f4a0Smrg lw->label.lbm_width = lw->label.lbm_height = 0; 4509027f4a0Smrg } 4519027f4a0Smrg compute_bitmap_offsets (lw); 4529027f4a0Smrg} 4539027f4a0Smrg 4549027f4a0Smrg 4559027f4a0Smrg 4569027f4a0Smrg/* ARGSUSED */ 4573a72f200Smrgstatic void 4583a72f200SmrgInitialize(Widget request, Widget new, ArgList args, Cardinal *num_args) 4599027f4a0Smrg{ 4609027f4a0Smrg UCSLabelWidget lw = (UCSLabelWidget) new; 4619027f4a0Smrg 462fe2ac8d7Smrg if (lw->label.label == NULL) 4639027f4a0Smrg lw->label.label = XtNewString(lw->core.name); 4649027f4a0Smrg else { 4659027f4a0Smrg lw->label.label = XtNewString(lw->label.label); 4669027f4a0Smrg } 4679027f4a0Smrg 4689027f4a0Smrg GetnormalGC(lw); 4699027f4a0Smrg GetgrayGC(lw); 4709027f4a0Smrg 4719027f4a0Smrg SetTextWidthAndHeight(lw); 4729027f4a0Smrg 4739027f4a0Smrg if (lw->core.height == 0) 4749027f4a0Smrg lw->core.height = lw->label.label_height + 4759027f4a0Smrg 2 * lw->label.internal_height; 4769027f4a0Smrg 4779027f4a0Smrg set_bitmap_info (lw); /* need core.height */ 4789027f4a0Smrg 4799027f4a0Smrg if (lw->core.width == 0) /* need label.lbm_width */ 4809027f4a0Smrg lw->core.width = (lw->label.label_width + 4819027f4a0Smrg 2 * lw->label.internal_width + 4829027f4a0Smrg LEFT_OFFSET(lw)); 4839027f4a0Smrg 4849027f4a0Smrg lw->label.label_x = lw->label.label_y = 0; 4859027f4a0Smrg (*XtClass(new)->core_class.resize) ((Widget)lw); 4869027f4a0Smrg 4879027f4a0Smrg} /* Initialize */ 4889027f4a0Smrg 4899027f4a0Smrg/* 4909027f4a0Smrg * Repaint the widget window 4919027f4a0Smrg */ 4929027f4a0Smrg 4939027f4a0Smrg/* ARGSUSED */ 4943a72f200Smrgstatic void Redisplay(Widget gw, XEvent *event, Region region) 4959027f4a0Smrg{ 4969027f4a0Smrg UCSLabelWidget w = (UCSLabelWidget) gw; 4979027f4a0Smrg GC gc; 4989027f4a0Smrg 4999027f4a0Smrg /* 5009027f4a0Smrg * now we'll see if we need to draw the rest of the label 5019027f4a0Smrg */ 5029027f4a0Smrg if (region != NULL) { 5039027f4a0Smrg int x = w->label.label_x; 5049027f4a0Smrg unsigned int width = w->label.label_width; 5059027f4a0Smrg if (w->label.lbm_width) { 5069027f4a0Smrg if (w->label.label_x > (x = w->label.internal_width)) 5079027f4a0Smrg width += w->label.label_x - x; 5089027f4a0Smrg } 5099027f4a0Smrg if (XRectInRegion(region, x, w->label.label_y, 5109027f4a0Smrg width, w->label.label_height) == RectangleOut){ 5119027f4a0Smrg return; 5129027f4a0Smrg } 5139027f4a0Smrg } 5149027f4a0Smrg 5159027f4a0Smrg gc = XtIsSensitive(gw) ? w->label.normal_GC : w->label.gray_GC; 5169027f4a0Smrg#ifdef notdef 5179027f4a0Smrg if (region != NULL) 5189027f4a0Smrg XSetRegion(XtDisplay(gw), gc, region); 5199027f4a0Smrg#endif /*notdef*/ 5209027f4a0Smrg 5219027f4a0Smrg if (w->label.pixmap == None) { 5229027f4a0Smrg int len = w->label.label_len; 5239027f4a0Smrg char *label = w->label.label; 5249027f4a0Smrg Position y = w->label.label_y + w->label.font->max_bounds.ascent; 5259027f4a0Smrg Position ksy = w->label.label_y; 5269027f4a0Smrg 5279027f4a0Smrg /* display left bitmap */ 5289027f4a0Smrg if (w->label.left_bitmap && w->label.lbm_width != 0) { 5299027f4a0Smrg XCopyPlane (XtDisplay(gw), w->label.left_bitmap, XtWindow(gw), gc, 5309027f4a0Smrg 0, 0, w->label.lbm_width, w->label.lbm_height, 5319027f4a0Smrg (int) w->label.internal_width, 532fe2ac8d7Smrg (int) w->label.internal_height + w->label.lbm_y, 5339027f4a0Smrg (unsigned long) 1L); 5349027f4a0Smrg } 5359027f4a0Smrg 5369027f4a0Smrg if ( w->simple.international == True ) { 5379027f4a0Smrg 5389027f4a0Smrg XFontSetExtents *ext = XExtentsOfFontSet(w->label.fontset); 5399027f4a0Smrg 5409027f4a0Smrg ksy += abs(ext->max_ink_extent.y); 5419027f4a0Smrg 5429027f4a0Smrg if (len == MULTI_LINE_LABEL) { 5439027f4a0Smrg char *nl; 5449027f4a0Smrg while ((nl = index(label, '\n')) != NULL) { 5459027f4a0Smrg XmbDrawString(XtDisplay(w), XtWindow(w), w->label.fontset, gc, 5469027f4a0Smrg w->label.label_x, ksy, label, (int)(nl - label)); 5479027f4a0Smrg ksy += ext->max_ink_extent.height; 5489027f4a0Smrg label = nl + 1; 5499027f4a0Smrg } 5509027f4a0Smrg len = strlen(label); 5519027f4a0Smrg } 5529027f4a0Smrg if (len) 5539027f4a0Smrg XmbDrawString(XtDisplay(w), XtWindow(w), w->label.fontset, gc, 5549027f4a0Smrg w->label.label_x, ksy, label, len); 5559027f4a0Smrg 5569027f4a0Smrg } else { /*international false, so use R5 routine */ 5579027f4a0Smrg 5589027f4a0Smrg if (len == MULTI_LINE_LABEL) { 5599027f4a0Smrg char *nl; 5609027f4a0Smrg while ((nl = index(label, '\n')) != NULL) { 5619027f4a0Smrg if (w->label.encoding == XawTextEncodingChar2b) 5629027f4a0Smrg XDrawString16(XtDisplay(gw), XtWindow(gw), gc, 5639027f4a0Smrg w->label.label_x, y, 564376c9fa8Smrg (XChar2b *)label, (int)(nl - label)/2); 5659027f4a0Smrg else if (w->label.encoding == XawTextEncodingUCS) 5669027f4a0Smrg XDrawStringUCS(XtDisplay(gw), XtWindow(gw), gc, 5679027f4a0Smrg w->label.label_x, y, label, (int)(nl - label)); 5689027f4a0Smrg else 5699027f4a0Smrg XDrawString(XtDisplay(gw), XtWindow(gw), gc, 5709027f4a0Smrg w->label.label_x, y, label, (int)(nl - label)); 571fe2ac8d7Smrg y += w->label.font->max_bounds.ascent + 5729027f4a0Smrg w->label.font->max_bounds.descent; 5739027f4a0Smrg label = nl + 1; 5749027f4a0Smrg } 5759027f4a0Smrg len = strlen(label); 5769027f4a0Smrg } 5779027f4a0Smrg if (len) { 5789027f4a0Smrg if (w->label.encoding == XawTextEncodingChar2b) 5799027f4a0Smrg XDrawString16(XtDisplay(gw), XtWindow(gw), gc, 580376c9fa8Smrg w->label.label_x, y, (XChar2b *)label, len/2); 5819027f4a0Smrg else if (w->label.encoding == XawTextEncodingUCS) 5829027f4a0Smrg XDrawStringUCS(XtDisplay(gw), XtWindow(gw), gc, 5839027f4a0Smrg w->label.label_x, y, label, len); 5849027f4a0Smrg else 5859027f4a0Smrg XDrawString(XtDisplay(gw), XtWindow(gw), gc, 5869027f4a0Smrg w->label.label_x, y, label, len); 5879027f4a0Smrg } 5889027f4a0Smrg 5899027f4a0Smrg } /*endif international*/ 5909027f4a0Smrg 5919027f4a0Smrg } else if (w->label.label_len == 1) { /* depth */ 5929027f4a0Smrg XCopyPlane(XtDisplay(gw), w->label.pixmap, XtWindow(gw), gc, 5939027f4a0Smrg 0, 0, w->label.label_width, w->label.label_height, 5949027f4a0Smrg w->label.label_x, w->label.label_y, 1L); 5959027f4a0Smrg } else { 5969027f4a0Smrg XCopyArea(XtDisplay(gw), w->label.pixmap, XtWindow(gw), gc, 5979027f4a0Smrg 0, 0, w->label.label_width, w->label.label_height, 5989027f4a0Smrg w->label.label_x, w->label.label_y); 5999027f4a0Smrg } 6009027f4a0Smrg 6019027f4a0Smrg#ifdef notdef 6029027f4a0Smrg if (region != NULL) 6039027f4a0Smrg XSetClipMask(XtDisplay(gw), gc, (Pixmap)None); 6049027f4a0Smrg#endif /* notdef */ 6059027f4a0Smrg} 6069027f4a0Smrg 6073a72f200Smrgstatic void _Reposition(UCSLabelWidget lw, Dimension width, Dimension height, 6083a72f200Smrg Position *dx, Position *dy) 6099027f4a0Smrg{ 6109027f4a0Smrg Position newPos; 6119027f4a0Smrg Position leftedge = lw->label.internal_width + LEFT_OFFSET(lw); 6129027f4a0Smrg 6139027f4a0Smrg switch (lw->label.justify) { 6149027f4a0Smrg 6159027f4a0Smrg case XtJustifyLeft : 6169027f4a0Smrg newPos = leftedge; 6179027f4a0Smrg break; 6189027f4a0Smrg 6199027f4a0Smrg case XtJustifyRight : 6209027f4a0Smrg newPos = width - 6219027f4a0Smrg (lw->label.label_width + lw->label.internal_width); 6229027f4a0Smrg break; 6239027f4a0Smrg 6249027f4a0Smrg case XtJustifyCenter : 6259027f4a0Smrg default: 6269027f4a0Smrg newPos = (int)(width - lw->label.label_width) / 2; 6279027f4a0Smrg break; 6289027f4a0Smrg } 6299027f4a0Smrg if (newPos < (Position)leftedge) 6309027f4a0Smrg newPos = leftedge; 6319027f4a0Smrg *dx = newPos - lw->label.label_x; 6329027f4a0Smrg lw->label.label_x = newPos; 6339027f4a0Smrg *dy = (newPos = (int)(height - lw->label.label_height) / 2) 6349027f4a0Smrg - lw->label.label_y; 6359027f4a0Smrg lw->label.label_y = newPos; 6369027f4a0Smrg return; 6379027f4a0Smrg} 6389027f4a0Smrg 6393a72f200Smrgstatic void Resize(Widget w) 6409027f4a0Smrg{ 6419027f4a0Smrg UCSLabelWidget lw = (UCSLabelWidget)w; 6429027f4a0Smrg Position dx, dy; 6439027f4a0Smrg 6449027f4a0Smrg _Reposition(lw, w->core.width, w->core.height, &dx, &dy); 6459027f4a0Smrg compute_bitmap_offsets (lw); 6469027f4a0Smrg} 6479027f4a0Smrg 6489027f4a0Smrg/* 6499027f4a0Smrg * Set specified arguments into widget 6509027f4a0Smrg */ 6519027f4a0Smrg 6529027f4a0Smrg#define PIXMAP 0 6539027f4a0Smrg#define WIDTH 1 6549027f4a0Smrg#define HEIGHT 2 6559027f4a0Smrg#define NUM_CHECKS 3 6569027f4a0Smrg 6573a72f200Smrgstatic Boolean 6583a72f200SmrgSetValues(Widget current, Widget request, Widget new, 6593a72f200Smrg ArgList args, Cardinal *num_args) 6609027f4a0Smrg{ 6619027f4a0Smrg UCSLabelWidget curlw = (UCSLabelWidget) current; 6629027f4a0Smrg UCSLabelWidget reqlw = (UCSLabelWidget) request; 6639027f4a0Smrg UCSLabelWidget newlw = (UCSLabelWidget) new; 6649027f4a0Smrg int i; 6659027f4a0Smrg Boolean was_resized = False, redisplay = False, checks[NUM_CHECKS]; 6669027f4a0Smrg 6679027f4a0Smrg for (i = 0; i < NUM_CHECKS; i++) 6689027f4a0Smrg checks[i] = FALSE; 6699027f4a0Smrg 6709027f4a0Smrg for (i = 0; i < *num_args; i++) { 6719027f4a0Smrg if (streq(XtNbitmap, args[i].name)) 6729027f4a0Smrg checks[PIXMAP] = TRUE; 6739027f4a0Smrg if (streq(XtNwidth, args[i].name)) 6749027f4a0Smrg checks[WIDTH] = TRUE; 6759027f4a0Smrg if (streq(XtNheight, args[i].name)) 6769027f4a0Smrg checks[HEIGHT] = TRUE; 6779027f4a0Smrg } 6789027f4a0Smrg 6799027f4a0Smrg if (newlw->label.label == NULL) { 6809027f4a0Smrg newlw->label.label = newlw->core.name; 6819027f4a0Smrg } 6829027f4a0Smrg 6839027f4a0Smrg /* 6849027f4a0Smrg * resize on bitmap change 6859027f4a0Smrg */ 6869027f4a0Smrg if (curlw->label.left_bitmap != newlw->label.left_bitmap) { 6879027f4a0Smrg was_resized = True; 6889027f4a0Smrg } 6899027f4a0Smrg 6909027f4a0Smrg if (curlw->label.encoding != newlw->label.encoding) 6919027f4a0Smrg was_resized = True; 6929027f4a0Smrg 6939027f4a0Smrg if ( (curlw->label.fontset != newlw->label.fontset) && 6949027f4a0Smrg curlw->simple.international ){ 6959027f4a0Smrg was_resized = True; 6969027f4a0Smrg } 6979027f4a0Smrg if (curlw->label.label != newlw->label.label) { 6989027f4a0Smrg if (curlw->label.label != curlw->core.name) 6999027f4a0Smrg XtFree( (char *)curlw->label.label ); 7009027f4a0Smrg 7019027f4a0Smrg if (newlw->label.label != newlw->core.name) { 7029027f4a0Smrg newlw->label.label = XtNewString( newlw->label.label ); 7039027f4a0Smrg } 7049027f4a0Smrg was_resized = True; 7059027f4a0Smrg } 7069027f4a0Smrg 7079027f4a0Smrg if (was_resized || (curlw->label.font != newlw->label.font) || 7089027f4a0Smrg (curlw->label.justify != newlw->label.justify) || checks[PIXMAP]) { 7099027f4a0Smrg 7109027f4a0Smrg SetTextWidthAndHeight(newlw); 7119027f4a0Smrg was_resized = True; 7129027f4a0Smrg } 7139027f4a0Smrg 7149027f4a0Smrg /* recalculate the window size if something has changed. */ 7159027f4a0Smrg if (newlw->label.resize && was_resized) { 7169027f4a0Smrg if ((curlw->core.height == reqlw->core.height) && !checks[HEIGHT]) 7179027f4a0Smrg newlw->core.height = (newlw->label.label_height + 7189027f4a0Smrg 2 * newlw->label.internal_height); 7199027f4a0Smrg 7209027f4a0Smrg set_bitmap_info (newlw); 7219027f4a0Smrg 7229027f4a0Smrg if ((curlw->core.width == reqlw->core.width) && !checks[WIDTH]) 7239027f4a0Smrg newlw->core.width = (newlw->label.label_width + 7249027f4a0Smrg LEFT_OFFSET(newlw) + 7259027f4a0Smrg 2 * newlw->label.internal_width); 7269027f4a0Smrg } 7279027f4a0Smrg 7289027f4a0Smrg if (curlw->label.foreground != newlw->label.foreground 7299027f4a0Smrg || curlw->core.background_pixel != newlw->core.background_pixel 7309027f4a0Smrg || curlw->label.font->fid != newlw->label.font->fid ) { 7319027f4a0Smrg 7329027f4a0Smrg /* The Fontset is not in the GC - don't make a new GC if FS changes! */ 7339027f4a0Smrg 7349027f4a0Smrg XtReleaseGC(new, curlw->label.normal_GC); 7359027f4a0Smrg XtReleaseGC(new, curlw->label.gray_GC); 7369027f4a0Smrg XmuReleaseStippledPixmap( XtScreen(current), curlw->label.stipple ); 7379027f4a0Smrg GetnormalGC(newlw); 7389027f4a0Smrg GetgrayGC(newlw); 7399027f4a0Smrg redisplay = True; 7409027f4a0Smrg } 7419027f4a0Smrg 7429027f4a0Smrg if ((curlw->label.internal_width != newlw->label.internal_width) 7439027f4a0Smrg || (curlw->label.internal_height != newlw->label.internal_height) 7449027f4a0Smrg || was_resized) { 7459027f4a0Smrg /* Resize() will be called if geometry changes succeed */ 7469027f4a0Smrg Position dx, dy; 7479027f4a0Smrg _Reposition(newlw, curlw->core.width, curlw->core.height, &dx, &dy); 7489027f4a0Smrg } 7499027f4a0Smrg 7509027f4a0Smrg return was_resized || redisplay || 7519027f4a0Smrg XtIsSensitive(current) != XtIsSensitive(new); 7529027f4a0Smrg} 7539027f4a0Smrg 7543a72f200Smrgstatic void Destroy(Widget w) 7559027f4a0Smrg{ 7569027f4a0Smrg UCSLabelWidget lw = (UCSLabelWidget)w; 7579027f4a0Smrg 7589027f4a0Smrg if ( lw->label.label != lw->core.name ) 7599027f4a0Smrg XtFree( lw->label.label ); 7609027f4a0Smrg XtReleaseGC( w, lw->label.normal_GC ); 7619027f4a0Smrg XtReleaseGC( w, lw->label.gray_GC); 7629027f4a0Smrg XmuReleaseStippledPixmap( XtScreen(w), lw->label.stipple ); 7639027f4a0Smrg} 7649027f4a0Smrg 7659027f4a0Smrg 7663a72f200Smrgstatic XtGeometryResult 7673a72f200SmrgQueryGeometry(Widget w, XtWidgetGeometry *intended, XtWidgetGeometry *preferred) 7689027f4a0Smrg{ 7699027f4a0Smrg UCSLabelWidget lw = (UCSLabelWidget)w; 7709027f4a0Smrg 7719027f4a0Smrg preferred->request_mode = CWWidth | CWHeight; 772fe2ac8d7Smrg preferred->width = (lw->label.label_width + 7739027f4a0Smrg 2 * lw->label.internal_width + 7749027f4a0Smrg LEFT_OFFSET(lw)); 775fe2ac8d7Smrg preferred->height = lw->label.label_height + 7769027f4a0Smrg 2 * lw->label.internal_height; 7779027f4a0Smrg if ( ((intended->request_mode & (CWWidth | CWHeight)) 7789027f4a0Smrg == (CWWidth | CWHeight)) && 7799027f4a0Smrg intended->width == preferred->width && 7809027f4a0Smrg intended->height == preferred->height) 7819027f4a0Smrg return XtGeometryYes; 7829027f4a0Smrg else if (preferred->width == w->core.width && 7839027f4a0Smrg preferred->height == w->core.height) 7849027f4a0Smrg return XtGeometryNo; 7859027f4a0Smrg else 7869027f4a0Smrg return XtGeometryAlmost; 7879027f4a0Smrg} 788