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