|
|
1.1 root 1: #ifndef lint
2: static char rcsid[] = "$Header: Label.c,v 1.25 87/09/13 22:09:43 newman Exp $";
3: #endif lint
4:
5: /*
6: * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
7: *
8: * All Rights Reserved
9: *
10: * Permission to use, copy, modify, and distribute this software and its
11: * documentation for any purpose and without fee is hereby granted,
12: * provided that the above copyright notice appear in all copies and that
13: * both that copyright notice and this permission notice appear in
14: * supporting documentation, and that the name of Digital Equipment
15: * Corporation not be used in advertising or publicity pertaining to
16: * distribution of the software without specific, written prior permission.
17: *
18: *
19: * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
20: * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
21: * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
22: * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
23: * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
24: * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
25: * SOFTWARE.
26: */
27: /*
28: * Label.c - Label widget
29: *
30: * Author: Charles Haynes
31: * Digital Equipment Corporation
32: * Western Research Laboratory
33: * Date: Sat Jan 24 1987
34: *
35: * Converted to classing toolkit on Wed Aug 26 by Charles Haynes
36: */
37:
38: #define XtStrlen(s) ((s) ? strlen(s) : 0)
39:
40: #include <stdio.h>
41: #include <string.h>
42: #include <ctype.h>
43: #include "Intrinsic.h"
44: #include "Label.h"
45: #include "LabelP.h"
46: #include "Atoms.h"
47:
48: /****************************************************************
49: *
50: * Full class record constant
51: *
52: ****************************************************************/
53:
54: /* Private Data */
55:
56: #define XtRjustify "Justify"
57:
58: static XtResource resources[] = {
59: {XtNforeground, XtCForeground, XrmRPixel, sizeof(Pixel),
60: XtOffset(LabelWidget, label.foreground), XrmRString, "Black"},
61: {XtNfont, XtCFont, XrmRFontStruct, sizeof(XFontStruct *),
62: XtOffset(LabelWidget, label.font),XrmRString, "Fixed"},
63: {XtNlabel, XtCLabel, XrmRString, sizeof(String),
64: XtOffset(LabelWidget, label.label), XrmRString, NULL},
65: {XtNjustify, XtCJustify, XtRJustify, sizeof(XtJustify),
66: XtOffset(LabelWidget, label.justify), XrmRString, "Center"},
67: {XtNinternalWidth, XtCWidth, XrmRInt, sizeof(Dimension),
68: XtOffset(LabelWidget, label.internal_width),XrmRString, "4"},
69: {XtNinternalHeight, XtCHeight, XrmRInt, sizeof(Dimension),
70: XtOffset(LabelWidget, label.internal_height),XrmRString, "2"},
71: };
72:
73: static void Initialize();
74: static void Realize();
75: static void Resize();
76: static void Redisplay();
77: static Boolean SetValues();
78: static void ClassInitialize();
79:
80: LabelClassRec labelClassRec = {
81: {
82: /* core_class fields */
83: /* superclass */ (WidgetClass) &widgetClassRec,
84: /* class_name */ "Label",
85: /* widget_size */ sizeof(LabelRec),
86: /* class_initialize */ ClassInitialize,
87: /* class_inited */ FALSE,
88: /* initialize */ Initialize,
89: /* realize */ Realize,
90: /* actions */ NULL,
91: /* num_actions */ 0,
92: /* resources */ resources,
93: /* num_resources */ XtNumber(resources),
94: /* xrm_class */ NULLQUARK,
95: /* compress_motion */ TRUE,
96: /* compress_exposure */ TRUE,
97: /* visible_interest */ FALSE,
98: /* destroy */ NULL,
99: /* resize */ Resize,
100: /* expose */ Redisplay,
101: /* set_values */ SetValues,
102: /* accept_focus */ NULL,
103: }
104: };
105: WidgetClass labelWidgetClass = (WidgetClass)&labelClassRec;
106: /****************************************************************
107: *
108: * Private Procedures
109: *
110: ****************************************************************/
111:
112: static void CvtStringToJustify();
113:
114: static XrmQuark XrmQEleft;
115: static XrmQuark XrmQEcenter;
116: static XrmQuark XrmQEright;
117:
118: static void ClassInitialize()
119: {
120:
121: XrmQEleft = XrmAtomToQuark("left");
122: XrmQEcenter = XrmAtomToQuark("center");
123: XrmQEright = XrmAtomToQuark("right");
124:
125: XrmRegisterTypeConverter(XrmRString, XtRJustify, CvtStringToJustify);
126: } /* ClassInitialize */
127:
128: /* ARGSUSED */
129: static void CvtStringToJustify(display, fromVal, toVal)
130: Display *display;
131: XrmValue fromVal;
132: XrmValue *toVal;
133: {
134: static XtJustify e;
135: XrmQuark q;
136: char *s = (char *) fromVal.addr;
137: char lowerName[1000];
138: int i;
139:
140: if (s == NULL) return;
141:
142: for (i=0; i<=strlen(s); i++) {
143: char c = s[i];
144: lowerName[i] = isupper(c) ? (char) tolower(c) : c;
145: }
146:
147: q = XrmAtomToQuark(lowerName);
148:
149: (*toVal).size = sizeof(XtJustify);
150: (*toVal).addr = (caddr_t) &e;
151:
152: if (q == XrmQEleft) { e = XtJustifyLeft; return; }
153: if (q == XrmQEcenter) { e = XtJustifyCenter; return; }
154: if (q == XrmQEright) { e = XtJustifyRight; return; }
155:
156: (*toVal).size = 0;
157: (*toVal).addr = NULL;
158: };
159:
160: /*
161: * Calculate width and height of displayed text in pixels
162: */
163:
164: static void SetTextWidthAndHeight(lw)
165: LabelWidget lw;
166: {
167: register XFontStruct *fs = lw->label.font;
168:
169: lw->label.label_len = XtStrlen(lw->label.label);
170: lw->label.label_height = fs->max_bounds.ascent + fs->max_bounds.descent;
171: lw->label.label_width = XTextWidth(
172: fs, lw->label.label, (int) lw->label.label_len);
173: }
174:
175: static void GetnormalGC(lw)
176: LabelWidget lw;
177: {
178: XGCValues values;
179:
180: values.foreground = lw->label.foreground;
181: values.font = lw->label.font->fid;
182:
183: lw->label.normal_GC = XtGetGC(
184: (Widget)lw,
185: (unsigned) GCForeground | GCFont,
186: &values);
187: }
188:
189: static void GetgrayGC(lw)
190: LabelWidget lw;
191: {
192: XGCValues values;
193:
194: lw->label.gray_pixmap = XtGrayPixmap(XtScreen((Widget)lw));
195:
196: values.foreground = lw->label.foreground;
197: values.font = lw->label.font->fid;
198: values.tile = lw->label.gray_pixmap;
199: values.fill_style = FillTiled;
200:
201: lw->label.gray_GC = XtGetGC(
202: (Widget)lw,
203: (unsigned) GCForeground | GCFont | GCTile | GCFillStyle,
204: &values);
205: }
206:
207: static void Initialize(request, new, args, num_args)
208: Widget request, new;
209: ArgList args;
210: Cardinal num_args;
211: {
212: LabelWidget lw = (LabelWidget) new;
213:
214: if (lw->label.label == NULL) {
215: unsigned int len = strlen(lw->core.name);
216: lw->label.label = XtMalloc(len+1);
217: (void) strcpy(lw->label.label, lw->core.name);
218: }
219:
220: GetnormalGC(lw);
221: GetgrayGC(lw);
222:
223: SetTextWidthAndHeight(lw);
224:
225: if (lw->core.width == 0)
226: lw->core.width = lw->label.label_width + 2 * lw->label.internal_width;
227: if (lw->core.height == 0)
228: lw->core.height = lw->label.label_height + 2*lw->label.internal_height;
229:
230: Resize((Widget)lw);
231:
232: lw->label.display_sensitive = FALSE;
233:
234: } /* Initialize */
235:
236:
237: static void Realize(w, valueMask, attributes)
238: register Widget w;
239: Mask valueMask;
240: XSetWindowAttributes *attributes;
241: {
242: LabelWidget lw = (LabelWidget)w;
243:
244: valueMask |= CWBitGravity;
245: switch (((LabelWidget)w)->label.justify) {
246: case XtJustifyLeft: attributes->bit_gravity = WestGravity; break;
247: case XtJustifyCenter: attributes->bit_gravity = CenterGravity; break;
248: case XtJustifyRight: attributes->bit_gravity = EastGravity; break;
249: }
250:
251: if (!(w->core.sensitive))
252: {
253: /* change border to gray */
254: lw->core.border_pixmap = lw->label.gray_pixmap;
255: attributes->border_pixmap = lw->label.gray_pixmap;
256: valueMask |= CWBorderPixmap;
257: lw->label.display_sensitive = TRUE;
258: }
259:
260:
261: w->core.window =
262: XCreateWindow(
263: XtDisplay(w), w->core.parent->core.window,
264: w->core.x, w->core.y,
265: w->core.width, w->core.height, w->core.border_width,
266: (int) w->core.depth,
267: InputOutput, (Visual *)CopyFromParent,
268: valueMask, attributes);
269: } /* Realize */
270:
271:
272:
273: /*
274: * Repaint the widget window
275: */
276:
277: /* ARGSUSED */
278: static void Redisplay(w, event)
279: Widget w;
280: XEvent *event;
281: {
282: LabelWidget lw = (LabelWidget) w;
283:
284: XDrawString(
285: XtDisplay(w), XtWindow(w), lw->label.normal_GC,
286: lw->label.label_x, lw->label.label_y,
287: lw->label.label, (int) lw->label.label_len);
288: }
289:
290:
291: static void Resize(w)
292: Widget w;
293: {
294: LabelWidget lw = (LabelWidget) w;
295:
296: switch (lw->label.justify) {
297:
298: case XtJustifyLeft :
299: lw->label.label_x = lw->label.internal_width;
300: break;
301:
302: case XtJustifyRight :
303: lw->label.label_x = lw->core.width -
304: (lw->label.label_width + lw->label.internal_width);
305: break;
306:
307: case XtJustifyCenter :
308: lw->label.label_x = (lw->core.width - lw->label.label_width) / 2;
309: break;
310: }
311: if (lw->label.label_x < 0) lw->label.label_x = 0;
312: lw->label.label_y = (lw->core.height - lw->label.label_height) / 2
313: + lw->label.font->max_bounds.ascent;
314: }
315:
316: /*
317: * Set specified arguments into widget
318: */
319:
320: static Boolean SetValues(current, request, new, last)
321: Widget current, request, new;
322: Boolean last;
323: {
324: LabelWidget curlw = (LabelWidget) current;
325: LabelWidget reqlw = (LabelWidget) request;
326: LabelWidget newlw = (LabelWidget) new;
327: XtWidgetGeometry reqGeo;
328:
329: if (newlw->label.label == NULL) {
330: /* the string will be copied below... */
331: newlw->label.label = newlw->core.name;
332: }
333:
334: if ((curlw->label.label != newlw->label.label)
335: || (curlw->label.font != newlw->label.font)
336: || (curlw->label.justify != newlw->label.justify)) {
337:
338: SetTextWidthAndHeight(newlw);
339:
340: }
341:
342: /* note that there is no way to change the label and force the window */
343: /* to keep it's current size (and possibly clip the text) perhaps we */
344: /* should make the user set width and height to 0 when they set the */
345: /* label if they want the label to recompute size based on the new */
346: /* label? */
347: if (curlw->label.label != newlw->label.label) {
348: if (newlw->label.label != NULL) {
349: newlw->label.label = strcpy(
350: XtMalloc((unsigned) newlw->label.label_len + 1),
351: newlw->label.label);
352: }
353: XtFree ((char *) curlw->label.label);
354: }
355:
356: /* calculate the window size */
357: if (curlw->core.width == newlw->core.width)
358: newlw->core.width =
359: newlw->label.label_width +2*newlw->label.internal_width;
360:
361: if (curlw->core.height == newlw->core.height)
362: newlw->core.height =
363: newlw->label.label_height + 2*newlw->label.internal_height;
364:
365: reqGeo.request_mode = NULL;
366:
367: if (curlw->core.x != newlw->core.x) {
368: reqGeo.request_mode |= CWX;
369: reqGeo.x = newlw->core.x;
370: }
371: if (curlw->core.y != newlw->core.y) {
372: reqGeo.request_mode |= CWY;
373: reqGeo.y = newlw->core.y;
374: }
375: if (curlw->core.width != newlw->core.width) {
376: reqGeo.request_mode |= CWWidth;
377: reqGeo.width = newlw->core.width;
378: }
379: if (curlw->core.height != newlw->core.height) {
380: reqGeo.request_mode |= CWHeight;
381: reqGeo.height = newlw->core.height;
382: }
383: if (curlw->core.border_width != newlw->core.border_width) {
384: reqGeo.request_mode |= CWBorderWidth;
385: reqGeo.border_width = newlw->core.border_width;
386: }
387:
388: if (reqGeo.request_mode != NULL) {
389: if (XtMakeGeometryRequest(
390: (Widget)curlw,
391: &reqGeo,
392: (XtWidgetGeometry *)NULL) != XtGeometryYes) {
393: /* punt, undo requested change */
394: newlw->core.x = curlw->core.x;
395: newlw->core.y = curlw->core.y;
396: newlw->core.width = curlw->core.width;
397: newlw->core.height = curlw->core.height;
398: newlw->core.border_width = curlw->core.border_width;
399: }
400: }
401:
402: if (newlw->core.depth != curlw->core.depth) {
403: XtWarning("SetValues: Attempt to change existing widget depth.");
404: newlw->core.depth = curlw->core.depth;
405: }
406:
407: if ((curlw->core.background_pixel != newlw->core.background_pixel)
408: || (curlw->core.border_pixel != newlw->core.border_pixel)) {
409:
410: Mask valueMask = 0;
411: XSetWindowAttributes attributes;
412:
413: if (curlw->core.background_pixel != newlw->core.background_pixel) {
414: valueMask |= CWBackPixel;
415: attributes.background_pixel = newlw->core.background_pixel;
416: }
417: if (curlw->core.border_pixel != newlw->core.border_pixel) {
418: valueMask |= CWBorderPixel;
419: attributes.border_pixel = newlw->core.border_pixel;
420: }
421: XChangeWindowAttributes(
422: XtDisplay(newlw), newlw->core.window, valueMask, &attributes);
423: }
424:
425: if (curlw->core.sensitive != newlw->core.sensitive) {
426: XtWarning("Setting Label sensitivity not implemented.");
427: }
428:
429: if (curlw->label.foreground != newlw->label.foreground
430: || curlw->label.font->fid != newlw->label.font->fid) {
431:
432: XtDestroyGC(curlw->label.normal_GC);
433: GetnormalGC(newlw);
434: GetgrayGC(newlw);
435: }
436:
437: if ((curlw->label.internal_width != newlw->label.internal_width)
438: || (curlw->label.internal_height != newlw->label.internal_height)) {
439: Resize((Widget)newlw);
440: }
441:
442: return( True ); /* want Redisplay */
443: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.