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