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