ULabel.c revision fe2ac8d7
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#ifdef CRAY 71#define WORD64 72#endif 73 74/**************************************************************** 75 * 76 * Full class record constant 77 * 78 ****************************************************************/ 79 80/* Private Data */ 81 82#define offset(field) XtOffsetOf(UCSLabelRec, field) 83static XtResource resources[] = { 84 {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel), 85 offset(label.foreground), XtRString, XtDefaultForeground}, 86 {XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *), 87 offset(label.font),XtRString, XtDefaultFont}, 88 {XtNfontSet, XtCFontSet, XtRFontSet, sizeof(XFontSet ), 89 offset(label.fontset),XtRString, XtDefaultFontSet}, 90 {XtNlabel, XtCLabel, XtRString, sizeof(String), 91 offset(label.label), XtRString, NULL}, 92 {XtNencoding, XtCEncoding, XtRUnsignedChar, sizeof(unsigned char), 93 offset(label.encoding), XtRImmediate, (XtPointer)XawTextEncoding8bit}, 94 {XtNjustify, XtCJustify, XtRJustify, sizeof(XtJustify), 95 offset(label.justify), XtRImmediate, (XtPointer)XtJustifyCenter}, 96 {XtNinternalWidth, XtCWidth, XtRDimension, sizeof(Dimension), 97 offset(label.internal_width), XtRImmediate, (XtPointer)4}, 98 {XtNinternalHeight, XtCHeight, XtRDimension, sizeof(Dimension), 99 offset(label.internal_height), XtRImmediate, (XtPointer)2}, 100 {XtNleftBitmap, XtCLeftBitmap, XtRBitmap, sizeof(Pixmap), 101 offset(label.left_bitmap), XtRImmediate, (XtPointer) None}, 102 {XtNbitmap, XtCPixmap, XtRBitmap, sizeof(Pixmap), 103 offset(label.pixmap), XtRImmediate, (XtPointer)None}, 104 {XtNresize, XtCResize, XtRBoolean, sizeof(Boolean), 105 offset(label.resize), XtRImmediate, (XtPointer)True}, 106}; 107#undef offset 108 109static void Initialize(Widget request, Widget new, 110 ArgList args, Cardinal *num_args); 111static void Resize(Widget w); 112static void Redisplay(Widget gw, XEvent *event, Region region); 113static Boolean SetValues(Widget current, Widget request, Widget new, 114 ArgList args, Cardinal *num_args); 115static void ClassInitialize(void); 116static void Destroy(Widget w); 117static XtGeometryResult QueryGeometry(Widget w, XtWidgetGeometry *intended, 118 XtWidgetGeometry *preferred); 119 120UCSLabelClassRec ucsLabelClassRec = { 121 { 122/* core_class fields */ 123 /* superclass */ (WidgetClass) &simpleClassRec, 124 /* class_name */ "UCSLabel", 125 /* widget_size */ sizeof(UCSLabelRec), 126 /* class_initialize */ ClassInitialize, 127 /* class_part_initialize */ NULL, 128 /* class_inited */ FALSE, 129 /* initialize */ Initialize, 130 /* initialize_hook */ NULL, 131 /* realize */ XtInheritRealize, 132 /* actions */ NULL, 133 /* num_actions */ 0, 134 /* resources */ resources, 135 /* num_resources */ XtNumber(resources), 136 /* xrm_class */ NULLQUARK, 137 /* compress_motion */ TRUE, 138 /* compress_exposure */ TRUE, 139 /* compress_enterleave */ TRUE, 140 /* visible_interest */ FALSE, 141 /* destroy */ Destroy, 142 /* resize */ Resize, 143 /* expose */ Redisplay, 144 /* set_values */ SetValues, 145 /* set_values_hook */ NULL, 146 /* set_values_almost */ XtInheritSetValuesAlmost, 147 /* get_values_hook */ NULL, 148 /* accept_focus */ NULL, 149 /* version */ XtVersion, 150 /* callback_private */ NULL, 151 /* tm_table */ NULL, 152 /* query_geometry */ QueryGeometry, 153 /* display_accelerator */ XtInheritDisplayAccelerator, 154 /* extension */ NULL 155 }, 156/* Simple class fields initialization */ 157 { 158 /* change_sensitive */ XtInheritChangeSensitive 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 182#ifndef WORD64 183 184#define TXT16 XChar2b 185 186#else 187 188#define TXT16 char 189 190static int _XawLabelWidth16(XFontStruct *fs, char *str, int n) 191{ 192 int i; 193 XChar2b *ptr; 194 195 if (n > buf2blen) { 196 buf2b = (XChar2b *)XtRealloc((char *)buf2b, n * sizeof(XChar2b)); 197 buf2blen = n; 198 } 199 for (ptr = buf2b, i = n; --i >= 0; ptr++) { 200 ptr->byte1 = *str++; 201 ptr->byte2 = *str++; 202 } 203 return XTextWidth16(fs, buf2b, n); 204} 205 206static void _XawLabelDraw16(Display *dpy, Drawable d, GC gc, 207 int x, int y, char *str, int n) 208{ 209 int i; 210 XChar2b *ptr; 211 212 if (n > buf2blen) { 213 buf2b = (XChar2b *)XtRealloc((char *)buf2b, n * sizeof(XChar2b)); 214 buf2blen = n; 215 } 216 for (ptr = buf2b, i = n; --i >= 0; ptr++) { 217 ptr->byte1 = *str++; 218 ptr->byte2 = *str++; 219 } 220 XDrawString16(dpy, d, gc, x, y, buf2b, n); 221} 222 223#define XTextWidth16 _XawLabelWidth16 224#define XDrawString16 _XawLabelDraw16 225 226#endif /* WORD64 */ 227 228static void _XawLabelDrawUCS(Display *dpy, Drawable d, GC gc, 229 int x, int y, char *str, int n) 230{ 231 char *ep; 232 unsigned short codepoint; 233 XChar2b *ptr; 234 235 /* 236 * Convert to UCS2 string on the fly. 237 */ 238 239 if (n > buf2blen) { 240 buf2b = (XChar2b *)XtRealloc((char *)buf2b, n * sizeof(XChar2b)); 241 buf2blen = n; 242 } 243 ep = str + n; 244 for (ptr = buf2b; str < ep; ptr++) { 245 if((str[0]&0x80)==0) { 246 codepoint=str[0]; 247 str++; 248 } else if((str[0]&0x20)==0) { 249 codepoint=(str[0]&0x1F)<<6 | (str[1]&0x3F); 250 str+=2; 251 } else if((str[0]&0x10)==0) { 252 codepoint=(str[0]&0x0F)<<12 | (str[1]&0x3F)<<6 | (str[2]&0x3F); 253 str+=3; 254 } else { /* wrong UTF-8 */ 255 codepoint=(unsigned)'?'; 256 str++; 257 } 258 ptr->byte1 = (codepoint >> 8) & 0xff;; 259 ptr->byte2 = codepoint & 0xff; 260 } 261 XDrawString16(dpy, d, gc, x, y, buf2b, ptr - buf2b); 262} 263 264static int _XawLabelWidthUCS( 265 XFontStruct *fs, 266 char *str, 267 int n 268) 269{ 270 char *ep; 271 unsigned short codepoint; 272 XChar2b *ptr; 273 274 /* 275 * Convert to UCS2 string on the fly. 276 */ 277 278 if (n > buf2blen) { 279 buf2b = (XChar2b *)XtRealloc((char *)buf2b, n * sizeof(XChar2b)); 280 buf2blen = n; 281 } 282 ep = str + n; 283 for (ptr = buf2b; str < ep; ptr++) { 284 if((str[0]&0x80)==0) { 285 codepoint=str[0]; 286 str++; 287 } else if((str[0]&0x20)==0) { 288 codepoint=(str[0]&0x1F)<<6 | (str[1]&0x3F); 289 str+=2; 290 } else if((str[0]&0x10)==0) { 291 codepoint=(str[0]&0x0F)<<12 | (str[1]&0x3F)<<6 | (str[2]&0x3F); 292 str+=3; 293 } else { /* wrong UTF-8 */ 294 codepoint=(unsigned)'?'; 295 str++; 296 } 297 ptr->byte1 = (codepoint >> 8) & 0xff;; 298 ptr->byte2 = codepoint & 0xff; 299 } 300 return XTextWidth16(fs, buf2b, ptr - buf2b); 301} 302 303#define XTextWidthUCS _XawLabelWidthUCS 304#define XDrawStringUCS _XawLabelDrawUCS 305 306/* 307 * Calculate width and height of displayed text in pixels 308 */ 309 310static void SetTextWidthAndHeight(UCSLabelWidget lw) 311{ 312 XFontStruct *fs = lw->label.font; 313 314 char *nl; 315 316 if (lw->label.pixmap != None) { 317 Window root; 318 int x, y; 319 unsigned int width, height, bw, depth; 320 if (XGetGeometry(XtDisplay(lw), lw->label.pixmap, &root, &x, &y, 321 &width, &height, &bw, &depth)) { 322 lw->label.label_height = height; 323 lw->label.label_width = width; 324 lw->label.label_len = depth; 325 return; 326 } 327 } 328 if ( lw->simple.international == True ) { 329 330 XFontSet fset = lw->label.fontset; 331 XFontSetExtents *ext = XExtentsOfFontSet(fset); 332 333 lw->label.label_height = ext->max_ink_extent.height; 334 if (lw->label.label == NULL) { 335 lw->label.label_len = 0; 336 lw->label.label_width = 0; 337 } 338 else if ((nl = index(lw->label.label, '\n')) != NULL) { 339 char *label; 340 lw->label.label_len = MULTI_LINE_LABEL; 341 lw->label.label_width = 0; 342 for (label = lw->label.label; nl != NULL; nl = index(label, '\n')) { 343 int width = XmbTextEscapement(fset, label, (int)(nl - label)); 344 345 if (width > (int)lw->label.label_width) 346 lw->label.label_width = width; 347 label = nl + 1; 348 if (*label) 349 lw->label.label_height += 350 ext->max_ink_extent.height; 351 } 352 if (*label) { 353 int width = XmbTextEscapement(fset, label, strlen(label)); 354 355 if (width > (int) lw->label.label_width) 356 lw->label.label_width = width; 357 } 358 } else { 359 lw->label.label_len = strlen(lw->label.label); 360 lw->label.label_width = 361 XmbTextEscapement(fset, lw->label.label, (int) lw->label.label_len); 362 } 363 364 } else { 365 366 lw->label.label_height = fs->max_bounds.ascent + fs->max_bounds.descent; 367 if (lw->label.label == NULL) { 368 lw->label.label_len = 0; 369 lw->label.label_width = 0; 370 } 371 else if ((nl = index(lw->label.label, '\n')) != NULL) { 372 char *label; 373 lw->label.label_len = MULTI_LINE_LABEL; 374 lw->label.label_width = 0; 375 for (label = lw->label.label; nl != NULL; nl = index(label, '\n')) { 376 int width; 377 378 if (lw->label.encoding == XawTextEncodingChar2b) 379 width = XTextWidth16(fs, (TXT16*)label, (int)(nl - label)/2); 380 else if (lw->label.encoding == XawTextEncodingUCS) 381 width = XTextWidthUCS(fs, label, nl - label); 382 else 383 width = XTextWidth(fs, label, (int)(nl - label)); 384 if (width > (int)lw->label.label_width) 385 lw->label.label_width = width; 386 label = nl + 1; 387 if (*label) 388 lw->label.label_height += 389 fs->max_bounds.ascent + fs->max_bounds.descent; 390 } 391 if (*label) { 392 int width; 393 394 if (lw->label.encoding == XawTextEncodingChar2b) 395 width = XTextWidth16(fs, (TXT16*)label, (int)strlen(label)/2); 396 else if (lw->label.encoding == XawTextEncodingUCS) 397 width = XTextWidthUCS(fs, label, strlen(label)); 398 else 399 width = XTextWidth(fs, label, strlen(label)); 400 if (width > (int) lw->label.label_width) 401 lw->label.label_width = width; 402 } 403 } else { 404 lw->label.label_len = strlen(lw->label.label); 405 if (lw->label.encoding == XawTextEncodingChar2b) 406 lw->label.label_width = 407 XTextWidth16(fs, (TXT16*)lw->label.label, 408 (int) lw->label.label_len/2); 409 else if (lw->label.encoding == XawTextEncodingUCS) 410 lw->label.label_width = XTextWidthUCS(fs, lw->label.label, 411 lw->label.label_len); 412 else 413 lw->label.label_width = 414 XTextWidth(fs, lw->label.label, (int) lw->label.label_len); 415 } 416 417 } 418} 419 420static void GetnormalGC(UCSLabelWidget lw) 421{ 422 XGCValues values; 423 424 values.foreground = lw->label.foreground; 425 values.background = lw->core.background_pixel; 426 values.font = lw->label.font->fid; 427 values.graphics_exposures = False; 428 429 if ( lw->simple.international == True ) 430 /* Since Xmb/wcDrawString eats the font, I must use XtAllocateGC. */ 431 lw->label.normal_GC = XtAllocateGC( 432 (Widget)lw, 0, 433 (unsigned) GCForeground | GCBackground | GCGraphicsExposures, 434 &values, GCFont, 0 ); 435 else 436 lw->label.normal_GC = XtGetGC( 437 (Widget)lw, 438 (unsigned) GCForeground | GCBackground | GCFont | GCGraphicsExposures, 439 &values); 440} 441 442static void GetgrayGC(UCSLabelWidget lw) 443{ 444 XGCValues values; 445 446 values.foreground = lw->label.foreground; 447 values.background = lw->core.background_pixel; 448 values.font = lw->label.font->fid; 449 values.fill_style = FillTiled; 450 values.tile = XmuCreateStippledPixmap(XtScreen((Widget)lw), 451 lw->label.foreground, 452 lw->core.background_pixel, 453 lw->core.depth); 454 values.graphics_exposures = False; 455 456 lw->label.stipple = values.tile; 457 if ( lw->simple.international == True ) 458 /* Since Xmb/wcDrawString eats the font, I must use XtAllocateGC. */ 459 lw->label.gray_GC = XtAllocateGC((Widget)lw, 0, 460 (unsigned) GCForeground | GCBackground | 461 GCTile | GCFillStyle | 462 GCGraphicsExposures, 463 &values, GCFont, 0); 464 else 465 lw->label.gray_GC = XtGetGC((Widget)lw, 466 (unsigned) GCForeground | GCBackground | 467 GCFont | GCTile | GCFillStyle | 468 GCGraphicsExposures, 469 &values); 470} 471 472static void compute_bitmap_offsets(UCSLabelWidget lw) 473{ 474 /* 475 * bitmap will be eventually be displayed at 476 * (internal_width, internal_height + lbm_y) 477 */ 478 if (lw->label.lbm_height != 0) { 479 lw->label.lbm_y = (lw->core.height - 480 (lw->label.internal_height * 2 + 481 lw->label.lbm_height)) / 2; 482 } else { 483 lw->label.lbm_y = 0; 484 } 485} 486 487 488static void set_bitmap_info(UCSLabelWidget lw) 489{ 490 Window root; 491 int x, y; 492 unsigned int bw, depth; 493 494 if (!(lw->label.left_bitmap && 495 XGetGeometry (XtDisplay(lw), lw->label.left_bitmap, &root, &x, &y, 496 &lw->label.lbm_width, &lw->label.lbm_height, 497 &bw, &depth))) { 498 lw->label.lbm_width = lw->label.lbm_height = 0; 499 } 500 compute_bitmap_offsets (lw); 501} 502 503 504 505/* ARGSUSED */ 506static void 507Initialize(Widget request, Widget new, ArgList args, Cardinal *num_args) 508{ 509 UCSLabelWidget lw = (UCSLabelWidget) new; 510 511 if (lw->label.label == NULL) 512 lw->label.label = XtNewString(lw->core.name); 513 else { 514 lw->label.label = XtNewString(lw->label.label); 515 } 516 517 GetnormalGC(lw); 518 GetgrayGC(lw); 519 520 SetTextWidthAndHeight(lw); 521 522 if (lw->core.height == 0) 523 lw->core.height = lw->label.label_height + 524 2 * lw->label.internal_height; 525 526 set_bitmap_info (lw); /* need core.height */ 527 528 if (lw->core.width == 0) /* need label.lbm_width */ 529 lw->core.width = (lw->label.label_width + 530 2 * lw->label.internal_width + 531 LEFT_OFFSET(lw)); 532 533 lw->label.label_x = lw->label.label_y = 0; 534 (*XtClass(new)->core_class.resize) ((Widget)lw); 535 536} /* Initialize */ 537 538/* 539 * Repaint the widget window 540 */ 541 542/* ARGSUSED */ 543static void Redisplay(Widget gw, XEvent *event, Region region) 544{ 545 UCSLabelWidget w = (UCSLabelWidget) gw; 546 GC gc; 547 548 /* 549 * now we'll see if we need to draw the rest of the label 550 */ 551 if (region != NULL) { 552 int x = w->label.label_x; 553 unsigned int width = w->label.label_width; 554 if (w->label.lbm_width) { 555 if (w->label.label_x > (x = w->label.internal_width)) 556 width += w->label.label_x - x; 557 } 558 if (XRectInRegion(region, x, w->label.label_y, 559 width, w->label.label_height) == RectangleOut){ 560 return; 561 } 562 } 563 564 gc = XtIsSensitive(gw) ? w->label.normal_GC : w->label.gray_GC; 565#ifdef notdef 566 if (region != NULL) 567 XSetRegion(XtDisplay(gw), gc, region); 568#endif /*notdef*/ 569 570 if (w->label.pixmap == None) { 571 int len = w->label.label_len; 572 char *label = w->label.label; 573 Position y = w->label.label_y + w->label.font->max_bounds.ascent; 574 Position ksy = w->label.label_y; 575 576 /* display left bitmap */ 577 if (w->label.left_bitmap && w->label.lbm_width != 0) { 578 XCopyPlane (XtDisplay(gw), w->label.left_bitmap, XtWindow(gw), gc, 579 0, 0, w->label.lbm_width, w->label.lbm_height, 580 (int) w->label.internal_width, 581 (int) w->label.internal_height + w->label.lbm_y, 582 (unsigned long) 1L); 583 } 584 585 if ( w->simple.international == True ) { 586 587 XFontSetExtents *ext = XExtentsOfFontSet(w->label.fontset); 588 589 ksy += abs(ext->max_ink_extent.y); 590 591 if (len == MULTI_LINE_LABEL) { 592 char *nl; 593 while ((nl = index(label, '\n')) != NULL) { 594 XmbDrawString(XtDisplay(w), XtWindow(w), w->label.fontset, gc, 595 w->label.label_x, ksy, label, (int)(nl - label)); 596 ksy += ext->max_ink_extent.height; 597 label = nl + 1; 598 } 599 len = strlen(label); 600 } 601 if (len) 602 XmbDrawString(XtDisplay(w), XtWindow(w), w->label.fontset, gc, 603 w->label.label_x, ksy, label, len); 604 605 } else { /*international false, so use R5 routine */ 606 607 if (len == MULTI_LINE_LABEL) { 608 char *nl; 609 while ((nl = index(label, '\n')) != NULL) { 610 if (w->label.encoding == XawTextEncodingChar2b) 611 XDrawString16(XtDisplay(gw), XtWindow(gw), gc, 612 w->label.label_x, y, 613 (TXT16*)label, (int)(nl - label)/2); 614 else if (w->label.encoding == XawTextEncodingUCS) 615 XDrawStringUCS(XtDisplay(gw), XtWindow(gw), gc, 616 w->label.label_x, y, label, (int)(nl - label)); 617 else 618 XDrawString(XtDisplay(gw), XtWindow(gw), gc, 619 w->label.label_x, y, label, (int)(nl - label)); 620 y += w->label.font->max_bounds.ascent + 621 w->label.font->max_bounds.descent; 622 label = nl + 1; 623 } 624 len = strlen(label); 625 } 626 if (len) { 627 if (w->label.encoding == XawTextEncodingChar2b) 628 XDrawString16(XtDisplay(gw), XtWindow(gw), gc, 629 w->label.label_x, y, (TXT16*)label, len/2); 630 else if (w->label.encoding == XawTextEncodingUCS) 631 XDrawStringUCS(XtDisplay(gw), XtWindow(gw), gc, 632 w->label.label_x, y, label, len); 633 else 634 XDrawString(XtDisplay(gw), XtWindow(gw), gc, 635 w->label.label_x, y, label, len); 636 } 637 638 } /*endif international*/ 639 640 } else if (w->label.label_len == 1) { /* depth */ 641 XCopyPlane(XtDisplay(gw), w->label.pixmap, XtWindow(gw), gc, 642 0, 0, w->label.label_width, w->label.label_height, 643 w->label.label_x, w->label.label_y, 1L); 644 } else { 645 XCopyArea(XtDisplay(gw), w->label.pixmap, XtWindow(gw), gc, 646 0, 0, w->label.label_width, w->label.label_height, 647 w->label.label_x, w->label.label_y); 648 } 649 650#ifdef notdef 651 if (region != NULL) 652 XSetClipMask(XtDisplay(gw), gc, (Pixmap)None); 653#endif /* notdef */ 654} 655 656static void _Reposition(UCSLabelWidget lw, Dimension width, Dimension height, 657 Position *dx, Position *dy) 658{ 659 Position newPos; 660 Position leftedge = lw->label.internal_width + LEFT_OFFSET(lw); 661 662 switch (lw->label.justify) { 663 664 case XtJustifyLeft : 665 newPos = leftedge; 666 break; 667 668 case XtJustifyRight : 669 newPos = width - 670 (lw->label.label_width + lw->label.internal_width); 671 break; 672 673 case XtJustifyCenter : 674 default: 675 newPos = (int)(width - lw->label.label_width) / 2; 676 break; 677 } 678 if (newPos < (Position)leftedge) 679 newPos = leftedge; 680 *dx = newPos - lw->label.label_x; 681 lw->label.label_x = newPos; 682 *dy = (newPos = (int)(height - lw->label.label_height) / 2) 683 - lw->label.label_y; 684 lw->label.label_y = newPos; 685 return; 686} 687 688static void Resize(Widget w) 689{ 690 UCSLabelWidget lw = (UCSLabelWidget)w; 691 Position dx, dy; 692 693 _Reposition(lw, w->core.width, w->core.height, &dx, &dy); 694 compute_bitmap_offsets (lw); 695} 696 697/* 698 * Set specified arguments into widget 699 */ 700 701#define PIXMAP 0 702#define WIDTH 1 703#define HEIGHT 2 704#define NUM_CHECKS 3 705 706static Boolean 707SetValues(Widget current, Widget request, Widget new, 708 ArgList args, Cardinal *num_args) 709{ 710 UCSLabelWidget curlw = (UCSLabelWidget) current; 711 UCSLabelWidget reqlw = (UCSLabelWidget) request; 712 UCSLabelWidget newlw = (UCSLabelWidget) new; 713 int i; 714 Boolean was_resized = False, redisplay = False, checks[NUM_CHECKS]; 715 716 for (i = 0; i < NUM_CHECKS; i++) 717 checks[i] = FALSE; 718 719 for (i = 0; i < *num_args; i++) { 720 if (streq(XtNbitmap, args[i].name)) 721 checks[PIXMAP] = TRUE; 722 if (streq(XtNwidth, args[i].name)) 723 checks[WIDTH] = TRUE; 724 if (streq(XtNheight, args[i].name)) 725 checks[HEIGHT] = TRUE; 726 } 727 728 if (newlw->label.label == NULL) { 729 newlw->label.label = newlw->core.name; 730 } 731 732 /* 733 * resize on bitmap change 734 */ 735 if (curlw->label.left_bitmap != newlw->label.left_bitmap) { 736 was_resized = True; 737 } 738 739 if (curlw->label.encoding != newlw->label.encoding) 740 was_resized = True; 741 742 if ( (curlw->label.fontset != newlw->label.fontset) && 743 curlw->simple.international ){ 744 was_resized = True; 745 } 746 if (curlw->label.label != newlw->label.label) { 747 if (curlw->label.label != curlw->core.name) 748 XtFree( (char *)curlw->label.label ); 749 750 if (newlw->label.label != newlw->core.name) { 751 newlw->label.label = XtNewString( newlw->label.label ); 752 } 753 was_resized = True; 754 } 755 756 if (was_resized || (curlw->label.font != newlw->label.font) || 757 (curlw->label.justify != newlw->label.justify) || checks[PIXMAP]) { 758 759 SetTextWidthAndHeight(newlw); 760 was_resized = True; 761 } 762 763 /* recalculate the window size if something has changed. */ 764 if (newlw->label.resize && was_resized) { 765 if ((curlw->core.height == reqlw->core.height) && !checks[HEIGHT]) 766 newlw->core.height = (newlw->label.label_height + 767 2 * newlw->label.internal_height); 768 769 set_bitmap_info (newlw); 770 771 if ((curlw->core.width == reqlw->core.width) && !checks[WIDTH]) 772 newlw->core.width = (newlw->label.label_width + 773 LEFT_OFFSET(newlw) + 774 2 * newlw->label.internal_width); 775 } 776 777 if (curlw->label.foreground != newlw->label.foreground 778 || curlw->core.background_pixel != newlw->core.background_pixel 779 || curlw->label.font->fid != newlw->label.font->fid ) { 780 781 /* The Fontset is not in the GC - don't make a new GC if FS changes! */ 782 783 XtReleaseGC(new, curlw->label.normal_GC); 784 XtReleaseGC(new, curlw->label.gray_GC); 785 XmuReleaseStippledPixmap( XtScreen(current), curlw->label.stipple ); 786 GetnormalGC(newlw); 787 GetgrayGC(newlw); 788 redisplay = True; 789 } 790 791 if ((curlw->label.internal_width != newlw->label.internal_width) 792 || (curlw->label.internal_height != newlw->label.internal_height) 793 || was_resized) { 794 /* Resize() will be called if geometry changes succeed */ 795 Position dx, dy; 796 _Reposition(newlw, curlw->core.width, curlw->core.height, &dx, &dy); 797 } 798 799 return was_resized || redisplay || 800 XtIsSensitive(current) != XtIsSensitive(new); 801} 802 803static void Destroy(Widget w) 804{ 805 UCSLabelWidget lw = (UCSLabelWidget)w; 806 807 if ( lw->label.label != lw->core.name ) 808 XtFree( lw->label.label ); 809 XtReleaseGC( w, lw->label.normal_GC ); 810 XtReleaseGC( w, lw->label.gray_GC); 811 XmuReleaseStippledPixmap( XtScreen(w), lw->label.stipple ); 812} 813 814 815static XtGeometryResult 816QueryGeometry(Widget w, XtWidgetGeometry *intended, XtWidgetGeometry *preferred) 817{ 818 UCSLabelWidget lw = (UCSLabelWidget)w; 819 820 preferred->request_mode = CWWidth | CWHeight; 821 preferred->width = (lw->label.label_width + 822 2 * lw->label.internal_width + 823 LEFT_OFFSET(lw)); 824 preferred->height = lw->label.label_height + 825 2 * lw->label.internal_height; 826 if ( ((intended->request_mode & (CWWidth | CWHeight)) 827 == (CWWidth | CWHeight)) && 828 intended->width == preferred->width && 829 intended->height == preferred->height) 830 return XtGeometryYes; 831 else if (preferred->width == w->core.width && 832 preferred->height == w->core.height) 833 return XtGeometryNo; 834 else 835 return XtGeometryAlmost; 836} 837