rust/cargo-c: update to 0.10.7+cargo-0.84.0
[oi-userland.git] / components / x11 / libXaw4 / src / Xaw3_1Label.c
blob4f185222c7025feada7a3d9c3cc0869d22fe7e4d
1 #ifndef lint
2 static char Xrcsid[] = "$XConsortium: Label.c,v 1.77 89/12/08 12:35:36 swick Exp $";
3 #endif /* lint */
6 /***********************************************************
7 Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
8 and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
10 All Rights Reserved
12 Permission to use, copy, modify, and distribute this software and its
13 documentation for any purpose and without fee is hereby granted,
14 provided that the above copyright notice appear in all copies and that
15 both that copyright notice and this permission notice appear in
16 supporting documentation, and that the names of Digital or MIT not be
17 used in advertising or publicity pertaining to distribution of the
18 software without specific, written prior permission.
20 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
21 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
22 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
23 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
24 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
25 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
26 SOFTWARE.
28 ******************************************************************/
31 * Label.c - Label widget
35 #define XtStrlen(s) ((s) ? strlen(s) : 0)
37 #include <stdio.h>
38 #include <ctype.h>
39 #include <X11/IntrinsicP.h>
40 #include <X11/StringDefs.h>
41 #include <./Xaw3_1XawInit.h>
42 #include <./Xaw3_1LabelP.h>
44 #ifdef SYSV
45 #ifndef index
46 #define index(a,b) strchr(a,b)
47 #endif
48 #endif
50 #define streq(a,b) (strcmp( (a), (b) ) == 0)
52 #define MULTI_LINE_LABEL 32767
54 /****************************************************************
56 * Full class record constant
58 ****************************************************************/
60 /* Private Data */
62 #define offset(field) XtOffset(LabelWidget, field)
63 static XtResource resources[] = {
64 {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
65 offset(label.foreground), XtRString, "XtDefaultForeground"},
66 {XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *),
67 offset(label.font),XtRString, "XtDefaultFont"},
68 {XtNlabel, XtCLabel, XtRString, sizeof(String),
69 offset(label.label), XtRString, NULL},
70 {XtNjustify, XtCJustify, XtRJustify, sizeof(XtJustify),
71 offset(label.justify), XtRImmediate, (caddr_t)XtJustifyCenter},
72 {XtNinternalWidth, XtCWidth, XtRDimension, sizeof(Dimension),
73 offset(label.internal_width), XtRImmediate, (caddr_t)4},
74 {XtNinternalHeight, XtCHeight, XtRDimension, sizeof(Dimension),
75 offset(label.internal_height), XtRImmediate, (caddr_t)2},
76 {XtNbitmap, XtCPixmap, XtRBitmap, sizeof(Pixmap),
77 offset(label.pixmap), XtRImmediate, (caddr_t)None},
78 {XtNresize, XtCResize, XtRBoolean, sizeof(Boolean),
79 offset(label.resize), XtRImmediate, (caddr_t)True},
82 static void Initialize();
83 static void Resize();
84 static void Redisplay();
85 static Boolean SetValues();
86 static void ClassInitialize();
87 static void Destroy();
88 static XtGeometryResult QueryGeometry();
90 LabelClassRec labelClassRec = {
92 /* core_class fields */
93 #define superclass (&simpleClassRec)
94 /* superclass */ (WidgetClass) superclass,
95 /* class_name */ "Label",
96 /* widget_size */ sizeof(LabelRec),
97 /* class_initialize */ ClassInitialize,
98 /* class_part_initialize */ NULL,
99 /* class_inited */ FALSE,
100 /* initialize */ Initialize,
101 /* initialize_hook */ NULL,
102 /* realize */ XtInheritRealize,
103 /* actions */ NULL,
104 /* num_actions */ 0,
105 /* resources */ resources,
106 /* num_resources */ XtNumber(resources),
107 /* xrm_class */ NULLQUARK,
108 /* compress_motion */ TRUE,
109 /* compress_exposure */ TRUE,
110 /* compress_enterleave */ TRUE,
111 /* visible_interest */ FALSE,
112 /* destroy */ Destroy,
113 /* resize */ Resize,
114 /* expose */ Redisplay,
115 /* set_values */ SetValues,
116 /* set_values_hook */ NULL,
117 /* set_values_almost */ XtInheritSetValuesAlmost,
118 /* get_values_hook */ NULL,
119 /* accept_focus */ NULL,
120 /* version */ XtVersion,
121 /* callback_private */ NULL,
122 /* tm_table */ NULL,
123 /* query_geometry */ QueryGeometry,
124 /* display_accelerator */ XtInheritDisplayAccelerator,
125 /* extension */ NULL
127 /* Simple class fields initialization */
129 /* change_sensitive */ XtInheritChangeSensitive
132 WidgetClass labelWidgetClass = (WidgetClass)&labelClassRec;
133 /****************************************************************
135 * Private Procedures
137 ****************************************************************/
139 static void ClassInitialize()
141 extern void XmuCvtStringToJustify();
142 extern void XmuCvtStringToBitmap();
143 static XtConvertArgRec screenConvertArg[] = {
144 {XtWidgetBaseOffset, (caddr_t) XtOffset(Widget, core.screen),
145 sizeof(Screen *)}
147 XawInitializeWidgetSet();
148 XtAddConverter( XtRString, XtRJustify, XmuCvtStringToJustify, NULL, 0 );
149 XtAddConverter("String", "Bitmap", XmuCvtStringToBitmap,
150 screenConvertArg, XtNumber(screenConvertArg));
151 } /* ClassInitialize */
154 * Calculate width and height of displayed text in pixels
157 static void SetTextWidthAndHeight(lw)
158 LabelWidget lw;
160 register XFontStruct *fs = lw->label.font;
161 char *nl;
163 if (lw->label.pixmap != None) {
164 Window root;
165 int x, y;
166 unsigned int width, height, bw, depth;
167 if (XGetGeometry(XtDisplay(lw), lw->label.pixmap, &root, &x, &y,
168 &width, &height, &bw, &depth)) {
169 lw->label.label_height = height;
170 lw->label.label_width = width;
171 lw->label.label_len = depth;
172 return;
176 lw->label.label_height = fs->max_bounds.ascent + fs->max_bounds.descent;
177 if (lw->label.label == NULL) {
178 lw->label.label_len = 0;
179 lw->label.label_width = 0;
181 else if ((nl = index(lw->label.label, '\n')) != NULL) {
182 char *label;
183 lw->label.label_len = MULTI_LINE_LABEL;
184 lw->label.label_width = 0;
185 for (label = lw->label.label; nl != NULL; nl = index(label, '\n')) {
186 int width = XTextWidth(fs, label, (int)(nl - label));
187 if (width > lw->label.label_width) lw->label.label_width = width;
188 label = nl + 1;
189 if (*label)
190 lw->label.label_height +=
191 fs->max_bounds.ascent + fs->max_bounds.descent;
193 if (*label) {
194 int width = XTextWidth(fs, label, strlen(label));
195 if (width > lw->label.label_width) lw->label.label_width = width;
197 } else {
198 lw->label.label_len = strlen(lw->label.label);
199 lw->label.label_width =
200 XTextWidth(fs, lw->label.label, (int) lw->label.label_len);
204 static void GetnormalGC(lw)
205 LabelWidget lw;
207 XGCValues values;
209 values.foreground = lw->label.foreground;
210 values.background = lw->core.background_pixel;
211 values.font = lw->label.font->fid;
213 lw->label.normal_GC = XtGetGC(
214 (Widget)lw,
215 (unsigned) GCForeground | GCBackground | GCFont,
216 &values);
219 static void GetgrayGC(lw)
220 LabelWidget lw;
222 XGCValues values;
224 values.foreground = lw->label.foreground;
225 values.background = lw->core.background_pixel;
226 values.font = lw->label.font->fid;
227 values.fill_style = FillTiled;
228 values.tile = XmuCreateStippledPixmap(XtScreen((Widget)lw),
229 lw->label.foreground,
230 lw->core.background_pixel,
231 lw->core.depth);
233 lw->label.stipple = values.tile;
234 lw->label.gray_GC = XtGetGC((Widget)lw,
235 (unsigned) GCForeground | GCBackground |
236 GCFont | GCTile | GCFillStyle,
237 &values);
240 /* ARGSUSED */
241 static void Initialize(request, new)
242 Widget request, new;
244 LabelWidget lw = (LabelWidget) new;
246 if (lw->label.label == NULL)
247 lw->label.label = XtNewString(lw->core.name);
248 else {
249 lw->label.label = XtNewString(lw->label.label);
252 GetnormalGC(lw);
253 GetgrayGC(lw);
255 SetTextWidthAndHeight(lw);
257 if (lw->core.width == 0)
258 lw->core.width = lw->label.label_width + 2 * lw->label.internal_width;
259 if (lw->core.height == 0)
260 lw->core.height = lw->label.label_height + 2*lw->label.internal_height;
262 lw->label.label_x = lw->label.label_y = 0;
263 (*XtClass(new)->core_class.resize) ((Widget)lw);
265 } /* Initialize */
268 * Repaint the widget window
271 /* ARGSUSED */
272 static void Redisplay(w, event, region)
273 Widget w;
274 XEvent *event;
275 Region region;
277 LabelWidget lw = (LabelWidget) w;
278 GC gc;
280 if (region != NULL &&
281 XRectInRegion(region, lw->label.label_x, lw->label.label_y,
282 lw->label.label_width, lw->label.label_height)
283 == RectangleOut)
284 return;
286 gc = XtIsSensitive((Widget)lw) ? lw->label.normal_GC : lw->label.gray_GC;
287 #ifdef notdef
288 if (region != NULL) XSetRegion(XtDisplay(w), gc, region);
289 #endif /*notdef*/
290 if (lw->label.pixmap == None) {
291 int len = lw->label.label_len;
292 char *label = lw->label.label;
293 Position y = lw->label.label_y + lw->label.font->max_bounds.ascent;
294 if (len == MULTI_LINE_LABEL) {
295 char *nl;
296 while ((nl = index(label, '\n')) != NULL) {
297 XDrawString(
298 XtDisplay(w), XtWindow(w), gc, lw->label.label_x,
299 y, label, (int)(nl - label));
300 y += lw->label.font->max_bounds.ascent + lw->label.font->max_bounds.descent;
301 label = nl + 1;
303 len = strlen(label);
305 if (len)
306 XDrawString(
307 XtDisplay(w), XtWindow(w), gc, lw->label.label_x,
308 y, label, len);
309 } else if (lw->label.label_len == 1) { /* depth */
310 XCopyPlane(
311 XtDisplay(w), lw->label.pixmap, XtWindow(w), gc,
312 0, 0, lw->label.label_width, lw->label.label_height,
313 lw->label.label_x, lw->label.label_y, 1L);
314 } else {
315 XCopyArea(
316 XtDisplay(w), lw->label.pixmap, XtWindow(w), gc,
317 0, 0, lw->label.label_width, lw->label.label_height,
318 lw->label.label_x, lw->label.label_y);
320 #ifdef notdef
321 if (region != NULL) XSetClipMask(XtDisplay(w), gc, (Pixmap)None);
322 #endif /* notdef */
325 static void _Reposition(lw, width, height, dx, dy)
326 register LabelWidget lw;
327 Dimension width, height;
328 Position *dx, *dy;
330 Position newPos;
331 switch (lw->label.justify) {
333 case XtJustifyLeft :
334 newPos = lw->label.internal_width;
335 break;
337 case XtJustifyRight :
338 newPos = width -
339 (lw->label.label_width + lw->label.internal_width);
340 break;
342 case XtJustifyCenter :
343 newPos = (width - lw->label.label_width) / 2;
344 break;
346 if (newPos < (Position)lw->label.internal_width)
347 newPos = lw->label.internal_width;
348 *dx = newPos - lw->label.label_x;
349 lw->label.label_x = newPos;
350 *dy = (newPos = (height - lw->label.label_height) / 2) - lw->label.label_y;
351 lw->label.label_y = newPos;
352 return;
355 static void Resize(w)
356 Widget w;
358 LabelWidget lw = (LabelWidget)w;
359 Position dx, dy;
360 _Reposition(lw, w->core.width, w->core.height, &dx, &dy);
364 * Set specified arguments into widget
367 #define PIXMAP 0
368 #define WIDTH 1
369 #define HEIGHT 2
370 #define NUM_CHECKS 3
372 static Boolean SetValues(current, request, new, args, num_args)
373 Widget current, request, new;
374 ArgList args;
375 Cardinal *num_args;
377 LabelWidget curlw = (LabelWidget) current;
378 LabelWidget reqlw = (LabelWidget) request;
379 LabelWidget newlw = (LabelWidget) new;
380 int i;
381 Boolean was_resized = False, redisplay = False, checks[NUM_CHECKS];
383 for (i = 0; i < NUM_CHECKS; i++)
384 checks[i] = FALSE;
386 for (i = 0; i < *num_args; i++) {
387 if (streq(XtNbitmap, args[i].name))
388 checks[PIXMAP] = TRUE;
389 if (streq(XtNwidth, args[i].name))
390 checks[WIDTH] = TRUE;
391 if (streq(XtNheight, args[i].name))
392 checks[HEIGHT] = TRUE;
395 if (newlw->label.label == NULL) {
396 newlw->label.label = newlw->core.name;
399 if (curlw->label.label != newlw->label.label) {
400 if (curlw->label.label != curlw->core.name)
401 XtFree( (char *)curlw->label.label );
403 if (newlw->label.label != newlw->core.name) {
404 newlw->label.label = XtNewString( newlw->label.label );
406 was_resized = True;
409 if (was_resized || (curlw->label.font != newlw->label.font) ||
410 (curlw->label.justify != newlw->label.justify) || checks[PIXMAP]) {
412 SetTextWidthAndHeight(newlw);
413 was_resized = True;
416 /* recalculate the window size if something has changed. */
417 if (newlw->label.resize && was_resized) {
418 if ((curlw->core.width == reqlw->core.width) && !checks[WIDTH])
419 newlw->core.width = (newlw->label.label_width +
420 2 * newlw->label.internal_width);
422 if ((curlw->core.height == reqlw->core.height) && !checks[HEIGHT])
423 newlw->core.height = (newlw->label.label_height +
424 2 * newlw->label.internal_height);
427 if (curlw->label.foreground != newlw->label.foreground
428 || curlw->label.font->fid != newlw->label.font->fid) {
430 XtReleaseGC(new, curlw->label.normal_GC);
431 XtReleaseGC(new, curlw->label.gray_GC);
432 XmuReleaseStippledPixmap( XtScreen(current), curlw->label.stipple );
433 GetnormalGC(newlw);
434 GetgrayGC(newlw);
435 redisplay = True;
438 if ((curlw->label.internal_width != newlw->label.internal_width)
439 || (curlw->label.internal_height != newlw->label.internal_height)
440 || was_resized) {
441 /* Resize() will be called if geometry changes succeed */
442 Position dx, dy;
443 _Reposition(newlw, curlw->core.width, curlw->core.height, &dx, &dy);
446 return was_resized || redisplay ||
447 XtIsSensitive(current) != XtIsSensitive(new);
450 static void Destroy(w)
451 Widget w;
453 LabelWidget lw = (LabelWidget)w;
455 XtFree( lw->label.label );
456 XtReleaseGC( w, lw->label.normal_GC );
457 XtReleaseGC( w, lw->label.gray_GC);
458 XmuReleaseStippledPixmap( XtScreen(w), lw->label.stipple );
462 static XtGeometryResult QueryGeometry(w, intended, preferred)
463 Widget w;
464 XtWidgetGeometry *intended, *preferred;
466 register LabelWidget lw = (LabelWidget)w;
468 preferred->request_mode = CWWidth | CWHeight;
469 preferred->width = lw->label.label_width + 2 * lw->label.internal_width;
470 preferred->height = lw->label.label_height + 2*lw->label.internal_height;
471 if ( ((intended->request_mode & (CWWidth | CWHeight))
472 == (CWWidth | CWHeight)) &&
473 intended->width == preferred->width &&
474 intended->height == preferred->height)
475 return XtGeometryYes;
476 else if (preferred->width == w->core.width &&
477 preferred->height == w->core.height)
478 return XtGeometryNo;
479 else
480 return XtGeometryAlmost;