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