ULabel.c revision 0d6f290a
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#ifndef OLDXAW 157 /* extension */ ,NULL 158#endif 159 }, 160/* UCSLabel class fields initialization */ 161 { 162 /* ignore */ 0 163 } 164}; 165WidgetClass ucsLabelWidgetClass = (WidgetClass)&ucsLabelClassRec; 166/**************************************************************** 167 * 168 * Private Procedures 169 * 170 ****************************************************************/ 171 172static void ClassInitialize(void) 173{ 174 XawInitializeWidgetSet(); 175 XtAddConverter( XtRString, XtRJustify, XmuCvtStringToJustify, 176 (XtConvertArgList)NULL, 0 ); 177} 178 179static XChar2b *buf2b; 180static int buf2blen = 0; 181 182static void _XawLabelDrawUCS(Display *dpy, Drawable d, GC gc, 183 int x, int y, const char *str, int n) 184{ 185 const char *ep; 186 unsigned short codepoint; 187 XChar2b *ptr; 188 189 /* 190 * Convert to UCS2 string on the fly. 191 */ 192 193 if (n > buf2blen) { 194 buf2b = (XChar2b *)XtRealloc((char *)buf2b, n * sizeof(XChar2b)); 195 buf2blen = n; 196 } 197 ep = str + n; 198 for (ptr = buf2b; str < ep; ptr++) { 199 if((str[0]&0x80)==0) { 200 codepoint=str[0]; 201 str++; 202 } else if((str[0]&0x20)==0) { 203 codepoint=(str[0]&0x1F)<<6 | (str[1]&0x3F); 204 str+=2; 205 } else if((str[0]&0x10)==0) { 206 codepoint=(str[0]&0x0F)<<12 | (str[1]&0x3F)<<6 | (str[2]&0x3F); 207 str+=3; 208 } else { /* wrong UTF-8 */ 209 codepoint=(unsigned)'?'; 210 str++; 211 } 212 ptr->byte1 = (codepoint >> 8) & 0xff; 213 ptr->byte2 = codepoint & 0xff; 214 } 215 XDrawString16(dpy, d, gc, x, y, buf2b, ptr - buf2b); 216} 217 218static int _XawLabelWidthUCS( 219 XFontStruct *fs, 220 const char *str, 221 int n 222) 223{ 224 const char *ep; 225 unsigned short codepoint; 226 XChar2b *ptr; 227 228 /* 229 * Convert to UCS2 string on the fly. 230 */ 231 232 if (n > buf2blen) { 233 buf2b = (XChar2b *)XtRealloc((char *)buf2b, n * sizeof(XChar2b)); 234 buf2blen = n; 235 } 236 ep = str + n; 237 for (ptr = buf2b; str < ep; ptr++) { 238 if((str[0]&0x80)==0) { 239 codepoint=str[0]; 240 str++; 241 } else if((str[0]&0x20)==0) { 242 codepoint=(str[0]&0x1F)<<6 | (str[1]&0x3F); 243 str+=2; 244 } else if((str[0]&0x10)==0) { 245 codepoint=(str[0]&0x0F)<<12 | (str[1]&0x3F)<<6 | (str[2]&0x3F); 246 str+=3; 247 } else { /* wrong UTF-8 */ 248 codepoint=(unsigned)'?'; 249 str++; 250 } 251 ptr->byte1 = (codepoint >> 8) & 0xff; 252 ptr->byte2 = codepoint & 0xff; 253 } 254 return XTextWidth16(fs, buf2b, ptr - buf2b); 255} 256 257#define XTextWidthUCS _XawLabelWidthUCS 258#define XDrawStringUCS _XawLabelDrawUCS 259 260/* 261 * Calculate width and height of displayed text in pixels 262 */ 263 264static void SetTextWidthAndHeight(UCSLabelWidget lw) 265{ 266 XFontStruct *fs = lw->label.font; 267 268 char *nl; 269 270 if (lw->label.pixmap != None) { 271 Window root; 272 int x, y; 273 unsigned int width, height, bw, depth; 274 if (XGetGeometry(XtDisplay(lw), lw->label.pixmap, &root, &x, &y, 275 &width, &height, &bw, &depth)) { 276 lw->label.label_height = height; 277 lw->label.label_width = width; 278 lw->label.label_len = depth; 279 return; 280 } 281 } 282 if ( lw->simple.international == True ) { 283 284 XFontSet fset = lw->label.fontset; 285 XFontSetExtents *ext = XExtentsOfFontSet(fset); 286 287 lw->label.label_height = ext->max_ink_extent.height; 288 if (lw->label.label == NULL) { 289 lw->label.label_len = 0; 290 lw->label.label_width = 0; 291 } 292 else if ((nl = index(lw->label.label, '\n')) != NULL) { 293 const char *label; 294 lw->label.label_len = MULTI_LINE_LABEL; 295 lw->label.label_width = 0; 296 for (label = lw->label.label; nl != NULL; nl = index(label, '\n')) { 297 int width = XmbTextEscapement(fset, label, (int)(nl - label)); 298 299 if (width > (int)lw->label.label_width) 300 lw->label.label_width = width; 301 label = nl + 1; 302 if (*label) 303 lw->label.label_height += 304 ext->max_ink_extent.height; 305 } 306 if (*label) { 307 int width = XmbTextEscapement(fset, label, strlen(label)); 308 309 if (width > (int) lw->label.label_width) 310 lw->label.label_width = width; 311 } 312 } else { 313 lw->label.label_len = strlen(lw->label.label); 314 lw->label.label_width = 315 XmbTextEscapement(fset, lw->label.label, (int) lw->label.label_len); 316 } 317 318 } else { 319 320 lw->label.label_height = fs->max_bounds.ascent + fs->max_bounds.descent; 321 if (lw->label.label == NULL) { 322 lw->label.label_len = 0; 323 lw->label.label_width = 0; 324 } 325 else if ((nl = index(lw->label.label, '\n')) != NULL) { 326 const char *label; 327 lw->label.label_len = MULTI_LINE_LABEL; 328 lw->label.label_width = 0; 329 for (label = lw->label.label; nl != NULL; nl = index(label, '\n')) { 330 int width; 331 332 if (lw->label.encoding == XawTextEncodingChar2b) 333 width = XTextWidth16(fs, (XChar2b *)label, (int)(nl - label)/2); 334 else if (lw->label.encoding == XawTextEncodingUCS) 335 width = XTextWidthUCS(fs, label, nl - label); 336 else 337 width = XTextWidth(fs, label, (int)(nl - label)); 338 if (width > (int)lw->label.label_width) 339 lw->label.label_width = width; 340 label = nl + 1; 341 if (*label) 342 lw->label.label_height += 343 fs->max_bounds.ascent + fs->max_bounds.descent; 344 } 345 if (*label) { 346 int width; 347 348 if (lw->label.encoding == XawTextEncodingChar2b) 349 width = XTextWidth16(fs, (XChar2b *)label, (int)strlen(label)/2); 350 else if (lw->label.encoding == XawTextEncodingUCS) 351 width = XTextWidthUCS(fs, label, strlen(label)); 352 else 353 width = XTextWidth(fs, label, strlen(label)); 354 if (width > (int) lw->label.label_width) 355 lw->label.label_width = width; 356 } 357 } else { 358 lw->label.label_len = strlen(lw->label.label); 359 if (lw->label.encoding == XawTextEncodingChar2b) 360 lw->label.label_width = 361 XTextWidth16(fs, (XChar2b *)lw->label.label, 362 (int) lw->label.label_len/2); 363 else if (lw->label.encoding == XawTextEncodingUCS) 364 lw->label.label_width = XTextWidthUCS(fs, lw->label.label, 365 lw->label.label_len); 366 else 367 lw->label.label_width = 368 XTextWidth(fs, lw->label.label, (int) lw->label.label_len); 369 } 370 371 } 372} 373 374static void GetnormalGC(UCSLabelWidget lw) 375{ 376 XGCValues values; 377 378 values.foreground = lw->label.foreground; 379 values.background = lw->core.background_pixel; 380 values.font = lw->label.font->fid; 381 values.graphics_exposures = False; 382 383 if ( lw->simple.international == True ) 384 /* Since Xmb/wcDrawString eats the font, I must use XtAllocateGC. */ 385 lw->label.normal_GC = XtAllocateGC( 386 (Widget)lw, 0, 387 (unsigned) GCForeground | GCBackground | GCGraphicsExposures, 388 &values, GCFont, 0 ); 389 else 390 lw->label.normal_GC = XtGetGC( 391 (Widget)lw, 392 (unsigned) GCForeground | GCBackground | GCFont | GCGraphicsExposures, 393 &values); 394} 395 396static void GetgrayGC(UCSLabelWidget lw) 397{ 398 XGCValues values; 399 400 values.foreground = lw->label.foreground; 401 values.background = lw->core.background_pixel; 402 values.font = lw->label.font->fid; 403 values.fill_style = FillTiled; 404 values.tile = XmuCreateStippledPixmap(XtScreen((Widget)lw), 405 lw->label.foreground, 406 lw->core.background_pixel, 407 lw->core.depth); 408 values.graphics_exposures = False; 409 410 lw->label.stipple = values.tile; 411 if ( lw->simple.international == True ) 412 /* Since Xmb/wcDrawString eats the font, I must use XtAllocateGC. */ 413 lw->label.gray_GC = XtAllocateGC((Widget)lw, 0, 414 (unsigned) GCForeground | GCBackground | 415 GCTile | GCFillStyle | 416 GCGraphicsExposures, 417 &values, GCFont, 0); 418 else 419 lw->label.gray_GC = XtGetGC((Widget)lw, 420 (unsigned) GCForeground | GCBackground | 421 GCFont | GCTile | GCFillStyle | 422 GCGraphicsExposures, 423 &values); 424} 425 426static void compute_bitmap_offsets(UCSLabelWidget lw) 427{ 428 /* 429 * bitmap will be eventually be displayed at 430 * (internal_width, internal_height + lbm_y) 431 */ 432 if (lw->label.lbm_height != 0) { 433 lw->label.lbm_y = (lw->core.height - 434 (lw->label.internal_height * 2 + 435 lw->label.lbm_height)) / 2; 436 } else { 437 lw->label.lbm_y = 0; 438 } 439} 440 441 442static void set_bitmap_info(UCSLabelWidget lw) 443{ 444 Window root; 445 int x, y; 446 unsigned int bw, depth; 447 448 if (!(lw->label.left_bitmap && 449 XGetGeometry (XtDisplay(lw), lw->label.left_bitmap, &root, &x, &y, 450 &lw->label.lbm_width, &lw->label.lbm_height, 451 &bw, &depth))) { 452 lw->label.lbm_width = lw->label.lbm_height = 0; 453 } 454 compute_bitmap_offsets (lw); 455} 456 457 458 459/* ARGSUSED */ 460static void 461Initialize(Widget request, Widget new, ArgList args, Cardinal *num_args) 462{ 463 UCSLabelWidget lw = (UCSLabelWidget) new; 464 465 if (lw->label.label == NULL) 466 lw->label.label = XtNewString(lw->core.name); 467 else { 468 lw->label.label = XtNewString(lw->label.label); 469 } 470 471 GetnormalGC(lw); 472 GetgrayGC(lw); 473 474 SetTextWidthAndHeight(lw); 475 476 if (lw->core.height == 0) 477 lw->core.height = lw->label.label_height + 478 2 * lw->label.internal_height; 479 480 set_bitmap_info (lw); /* need core.height */ 481 482 if (lw->core.width == 0) /* need label.lbm_width */ 483 lw->core.width = (lw->label.label_width + 484 2 * lw->label.internal_width + 485 LEFT_OFFSET(lw)); 486 487 lw->label.label_x = lw->label.label_y = 0; 488 (*XtClass(new)->core_class.resize) ((Widget)lw); 489 490} /* Initialize */ 491 492/* 493 * Repaint the widget window 494 */ 495 496/* ARGSUSED */ 497static void Redisplay(Widget gw, XEvent *event, Region region) 498{ 499 UCSLabelWidget w = (UCSLabelWidget) gw; 500 GC gc; 501 502 /* 503 * now we'll see if we need to draw the rest of the label 504 */ 505 if (region != NULL) { 506 int x = w->label.label_x; 507 unsigned int width = w->label.label_width; 508 if (w->label.lbm_width) { 509 if (w->label.label_x > (x = w->label.internal_width)) 510 width += w->label.label_x - x; 511 } 512 if (XRectInRegion(region, x, w->label.label_y, 513 width, w->label.label_height) == RectangleOut){ 514 return; 515 } 516 } 517 518 gc = XtIsSensitive(gw) ? w->label.normal_GC : w->label.gray_GC; 519#ifdef notdef 520 if (region != NULL) 521 XSetRegion(XtDisplay(gw), gc, region); 522#endif /*notdef*/ 523 524 if (w->label.pixmap == None) { 525 int len = w->label.label_len; 526 const char *label = w->label.label; 527 Position y = w->label.label_y + w->label.font->max_bounds.ascent; 528 Position ksy = w->label.label_y; 529 530 /* display left bitmap */ 531 if (w->label.left_bitmap && w->label.lbm_width != 0) { 532 XCopyPlane (XtDisplay(gw), w->label.left_bitmap, XtWindow(gw), gc, 533 0, 0, w->label.lbm_width, w->label.lbm_height, 534 (int) w->label.internal_width, 535 (int) w->label.internal_height + w->label.lbm_y, 536 (unsigned long) 1L); 537 } 538 539 if ( w->simple.international == True ) { 540 541 XFontSetExtents *ext = XExtentsOfFontSet(w->label.fontset); 542 543 ksy += abs(ext->max_ink_extent.y); 544 545 if (len == MULTI_LINE_LABEL) { 546 char *nl; 547 while ((nl = index(label, '\n')) != NULL) { 548 XmbDrawString(XtDisplay(w), XtWindow(w), w->label.fontset, gc, 549 w->label.label_x, ksy, label, (int)(nl - label)); 550 ksy += ext->max_ink_extent.height; 551 label = nl + 1; 552 } 553 len = strlen(label); 554 } 555 if (len) 556 XmbDrawString(XtDisplay(w), XtWindow(w), w->label.fontset, gc, 557 w->label.label_x, ksy, label, len); 558 559 } else { /*international false, so use R5 routine */ 560 561 if (len == MULTI_LINE_LABEL) { 562 char *nl; 563 while ((nl = index(label, '\n')) != NULL) { 564 if (w->label.encoding == XawTextEncodingChar2b) 565 XDrawString16(XtDisplay(gw), XtWindow(gw), gc, 566 w->label.label_x, y, 567 (XChar2b *)label, (int)(nl - label)/2); 568 else if (w->label.encoding == XawTextEncodingUCS) 569 XDrawStringUCS(XtDisplay(gw), XtWindow(gw), gc, 570 w->label.label_x, y, label, (int)(nl - label)); 571 else 572 XDrawString(XtDisplay(gw), XtWindow(gw), gc, 573 w->label.label_x, y, label, (int)(nl - label)); 574 y += w->label.font->max_bounds.ascent + 575 w->label.font->max_bounds.descent; 576 label = nl + 1; 577 } 578 len = strlen(label); 579 } 580 if (len) { 581 if (w->label.encoding == XawTextEncodingChar2b) 582 XDrawString16(XtDisplay(gw), XtWindow(gw), gc, 583 w->label.label_x, y, (XChar2b *)label, len/2); 584 else if (w->label.encoding == XawTextEncodingUCS) 585 XDrawStringUCS(XtDisplay(gw), XtWindow(gw), gc, 586 w->label.label_x, y, label, len); 587 else 588 XDrawString(XtDisplay(gw), XtWindow(gw), gc, 589 w->label.label_x, y, label, len); 590 } 591 592 } /*endif international*/ 593 594 } else if (w->label.label_len == 1) { /* depth */ 595 XCopyPlane(XtDisplay(gw), w->label.pixmap, XtWindow(gw), gc, 596 0, 0, w->label.label_width, w->label.label_height, 597 w->label.label_x, w->label.label_y, 1L); 598 } else { 599 XCopyArea(XtDisplay(gw), w->label.pixmap, XtWindow(gw), gc, 600 0, 0, w->label.label_width, w->label.label_height, 601 w->label.label_x, w->label.label_y); 602 } 603 604#ifdef notdef 605 if (region != NULL) 606 XSetClipMask(XtDisplay(gw), gc, (Pixmap)None); 607#endif /* notdef */ 608} 609 610static void _Reposition(UCSLabelWidget lw, Dimension width, Dimension height, 611 Position *dx, Position *dy) 612{ 613 Position newPos; 614 Position leftedge = lw->label.internal_width + LEFT_OFFSET(lw); 615 616 switch (lw->label.justify) { 617 618 case XtJustifyLeft : 619 newPos = leftedge; 620 break; 621 622 case XtJustifyRight : 623 newPos = width - 624 (lw->label.label_width + lw->label.internal_width); 625 break; 626 627 case XtJustifyCenter : 628 default: 629 newPos = (int)(width - lw->label.label_width) / 2; 630 break; 631 } 632 if (newPos < (Position)leftedge) 633 newPos = leftedge; 634 *dx = newPos - lw->label.label_x; 635 lw->label.label_x = newPos; 636 *dy = (newPos = (int)(height - lw->label.label_height) / 2) 637 - lw->label.label_y; 638 lw->label.label_y = newPos; 639 return; 640} 641 642static void Resize(Widget w) 643{ 644 UCSLabelWidget lw = (UCSLabelWidget)w; 645 Position dx, dy; 646 647 _Reposition(lw, w->core.width, w->core.height, &dx, &dy); 648 compute_bitmap_offsets (lw); 649} 650 651/* 652 * Set specified arguments into widget 653 */ 654 655#define PIXMAP 0 656#define WIDTH 1 657#define HEIGHT 2 658#define NUM_CHECKS 3 659 660static Boolean 661SetValues(Widget current, Widget request, Widget new, 662 ArgList args, Cardinal *num_args) 663{ 664 UCSLabelWidget curlw = (UCSLabelWidget) current; 665 UCSLabelWidget reqlw = (UCSLabelWidget) request; 666 UCSLabelWidget newlw = (UCSLabelWidget) new; 667 unsigned int i; 668 Boolean was_resized = False, redisplay = False, checks[NUM_CHECKS]; 669 670 for (i = 0; i < NUM_CHECKS; i++) 671 checks[i] = FALSE; 672 673 for (i = 0; i < *num_args; i++) { 674 if (streq(XtNbitmap, args[i].name)) 675 checks[PIXMAP] = TRUE; 676 if (streq(XtNwidth, args[i].name)) 677 checks[WIDTH] = TRUE; 678 if (streq(XtNheight, args[i].name)) 679 checks[HEIGHT] = TRUE; 680 } 681 682 if (newlw->label.label == NULL) { 683 newlw->label.label = newlw->core.name; 684 } 685 686 /* 687 * resize on bitmap change 688 */ 689 if (curlw->label.left_bitmap != newlw->label.left_bitmap) { 690 was_resized = True; 691 } 692 693 if (curlw->label.encoding != newlw->label.encoding) 694 was_resized = True; 695 696 if ( (curlw->label.fontset != newlw->label.fontset) && 697 curlw->simple.international ){ 698 was_resized = True; 699 } 700 if (curlw->label.label != newlw->label.label) { 701 if (curlw->label.label != curlw->core.name) 702 XtFree( (char *)curlw->label.label ); 703 704 if (newlw->label.label != newlw->core.name) { 705 newlw->label.label = XtNewString( newlw->label.label ); 706 } 707 was_resized = True; 708 } 709 710 if (was_resized || (curlw->label.font != newlw->label.font) || 711 (curlw->label.justify != newlw->label.justify) || checks[PIXMAP]) { 712 713 SetTextWidthAndHeight(newlw); 714 was_resized = True; 715 } 716 717 /* recalculate the window size if something has changed. */ 718 if (newlw->label.resize && was_resized) { 719 if ((curlw->core.height == reqlw->core.height) && !checks[HEIGHT]) 720 newlw->core.height = (newlw->label.label_height + 721 2 * newlw->label.internal_height); 722 723 set_bitmap_info (newlw); 724 725 if ((curlw->core.width == reqlw->core.width) && !checks[WIDTH]) 726 newlw->core.width = (newlw->label.label_width + 727 LEFT_OFFSET(newlw) + 728 2 * newlw->label.internal_width); 729 } 730 731 if (curlw->label.foreground != newlw->label.foreground 732 || curlw->core.background_pixel != newlw->core.background_pixel 733 || curlw->label.font->fid != newlw->label.font->fid ) { 734 735 /* The Fontset is not in the GC - don't make a new GC if FS changes! */ 736 737 XtReleaseGC(new, curlw->label.normal_GC); 738 XtReleaseGC(new, curlw->label.gray_GC); 739 XmuReleaseStippledPixmap( XtScreen(current), curlw->label.stipple ); 740 GetnormalGC(newlw); 741 GetgrayGC(newlw); 742 redisplay = True; 743 } 744 745 if ((curlw->label.internal_width != newlw->label.internal_width) 746 || (curlw->label.internal_height != newlw->label.internal_height) 747 || was_resized) { 748 /* Resize() will be called if geometry changes succeed */ 749 Position dx, dy; 750 _Reposition(newlw, curlw->core.width, curlw->core.height, &dx, &dy); 751 } 752 753 return was_resized || redisplay || 754 XtIsSensitive(current) != XtIsSensitive(new); 755} 756 757static void Destroy(Widget w) 758{ 759 UCSLabelWidget lw = (UCSLabelWidget)w; 760 761 if ( lw->label.label != lw->core.name ) 762 XtFree( (char *) lw->label.label ); 763 XtReleaseGC( w, lw->label.normal_GC ); 764 XtReleaseGC( w, lw->label.gray_GC); 765 XmuReleaseStippledPixmap( XtScreen(w), lw->label.stipple ); 766} 767 768 769static XtGeometryResult 770QueryGeometry(Widget w, XtWidgetGeometry *intended, XtWidgetGeometry *preferred) 771{ 772 UCSLabelWidget lw = (UCSLabelWidget)w; 773 774 preferred->request_mode = CWWidth | CWHeight; 775 preferred->width = (lw->label.label_width + 776 2 * lw->label.internal_width + 777 LEFT_OFFSET(lw)); 778 preferred->height = lw->label.label_height + 779 2 * lw->label.internal_height; 780 if ( ((intended->request_mode & (CWWidth | CWHeight)) 781 == (CWWidth | CWHeight)) && 782 intended->width == preferred->width && 783 intended->height == preferred->height) 784 return XtGeometryYes; 785 else if (preferred->width == w->core.width && 786 preferred->height == w->core.height) 787 return XtGeometryNo; 788 else 789 return XtGeometryAlmost; 790} 791