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