|
|
1.1 root 1: #ifndef lint
2: static char rcsid[] = "$Header: Command.c,v 1.24 87/09/13 23:04:23 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: * Command.c - Command button widget
29: *
30: * Rewritten for beta toolkit
31: * Author: Mark Ackerman
32: * MIT/Project Athena
33: * Date: August 27, 1987
34: *
35: * from Command.c (XToolkit, alpha version)
36: * Charles Haynes
37: * Digital Equipment Corporation
38: * Western Research Laboratory
39: */
40:
41: #define XtStrlen(s) ((s) ? strlen(s) : 0)
42:
43: /* The following are defined for the reader's convenience. Any
44: Xt..Field macro in this code just refers to some field in
45: one of the substructures of the WidgetRec. */
46:
47: #include <stdio.h>
48: #include <string.h>
49: #include <ctype.h>
50: #include "Intrinsic.h"
51: #include "Label.h"
52: #include "LabelP.h"
53: #include "Command.h"
54: #include "CommandP.h"
55: #include "CommandInt.h"
56: #include "Atoms.h"
57:
58: /****************************************************************
59: *
60: * Full class record constant
61: *
62: ****************************************************************/
63:
64: /* Private Data */
65:
66: static char *defaultTranslation[] = {
67: "<Btn1Down>: set()",
68: "<Btn1Up>: notify() unset()",
69: "<EnterWindow>: highlight()",
70: "<LeaveWindow>: unhighlight()",
71: NULL
72: };
73: static caddr_t defaultTranslations = (caddr_t)defaultTranslation;
74: static XtResource resources[] = {
75:
76: {XtNfunction, XtCFunction, XtRFunction, sizeof(XtCallbackProc),
77: XtOffset(CommandWidget, command.callback), XtRFunction, (caddr_t)NULL},
78: {XtNparameter, XtCParameter, XtRPointer, sizeof(caddr_t),
79: XtOffset(CommandWidget,command.closure), XtRPointer, (caddr_t)NULL},
80:
81: {XtNhighlightThickness, XtCThickness, XrmRInt, sizeof(Dimension),
82: XtOffset(CommandWidget,command.highlight_thickness), XrmRString,"2"},
83: {XtNtranslations, XtCTranslations, XtRTranslationTable,
84: sizeof(_XtTranslations),
85: XtOffset(CommandWidget, core.translations),XtRTranslationTable,
86: (caddr_t)&defaultTranslations},
87: };
88:
89: static XtActionsRec actionsList[] =
90: {
91: {"set", (caddr_t) Set},
92: {"notify", (caddr_t) Notify},
93: {"highlight", (caddr_t) Highlight},
94: {"unset", (caddr_t) Unset},
95: {"unhighlight", (caddr_t) Unhighlight},
96: };
97:
98: /* ...ClassData must be initialized at compile time. Must
99: initialize all substructures. (Actually, last two here
100: need not be initialized since not used.)
101: */
102: CommandClassRec commandClassRec = {
103: {
104: (WidgetClass) &labelClassRec, /* superclass */
105: "Command", /* class_name */
106: sizeof(CommandRec), /* size */
107: ClassInitialize, /* class initialize */
108: FALSE, /* class_inited */
109: Initialize, /* initialize */
110: Realize, /* realize */
111: actionsList, /* actions */
112: XtNumber(actionsList),
113: resources, /* resources */
114: XtNumber(resources), /* resource_count */
115: NULLQUARK, /* xrm_class */
116: FALSE,
117: FALSE,
118: FALSE, /* visible_interest */
119: Destroy, /* destroy */
120: Resize, /* resize */
121: Redisplay, /* expose */
122: SetValues, /* set_values */
123: NULL, /* accept_focus */
124: }, /* CoreClass fields initialization */
125: {
126: 0, /* field not used */
127: }, /* LabelClass fields initialization */
128: {
129: 0, /* field not used */
130: }, /* CommandClass fields initialization */
131: };
132:
133: /* for public consumption */
134: WidgetClass commandWidgetClass = (WidgetClass) &commandClassRec;
135:
136: XtCallbackKind activateCommand; /* for public consumption*/
137: /****************************************************************
138: *
139: * Private Procedures
140: *
141: ****************************************************************/
142:
143: #ifdef saber_bug
144: static Cardinal commandCallbackOffset =
145: XtOffset(CommandWidget,command.callback_list);
146: static void ClassInitialize()
147: {
148: activateCommand = XtNewCallbackKind(
149: commandWidgetClass, commandCallbackOffset);
150:
151: }
152: #else
153: static void ClassInitialize()
154: {
155: activateCommand = XtNewCallbackKind(commandWidgetClass,
156: XtOffset(CommandWidget,command.callback_list));
157:
158: }
159: #endif
160:
161: static void Get_inverseGC(cbw)
162: CommandWidget cbw;
163: {
164: XGCValues values;
165:
166: /* Set up a GC for inverse (set) state */
167:
168: values.foreground = ComWforeground;
169: values.font = ComWfont->fid;
170: values.fill_style = FillSolid;
171:
172: ComWinverseGC = XtGetGC((Widget)cbw,
173: (unsigned) GCForeground | GCFont | GCFillStyle, &values);
174: }
175:
176: static void Get_inverseTextGC(cbw)
177: CommandWidget cbw;
178: {
179: XGCValues values;
180:
181: /* Set up a GC for inverse (set) state */
182:
183: values.foreground = ComWbackground; /* default is White */
184: values.font = ComWfont->fid;
185: values.fill_style = FillSolid;
186:
187: ComWinverseTextGC = XtGetGC((Widget)cbw,
188: (unsigned) GCForeground | GCFont | GCFillStyle, &values);
189: }
190:
191: static void Get_highlightGC(cbw)
192: CommandWidget cbw;
193: {
194: XGCValues values;
195:
196: /* Set up a GC for highlighted state. It has a thicker
197: line width for the highlight border */
198:
199: values.foreground = ComWforeground;
200: values.line_width = ComWhighlightThickness;
201:
202: ComWhighlightGC = XtGetGC((Widget)cbw,
203: (unsigned) GCForeground | GCLineWidth, &values);
204: }
205:
206:
207: /* ARGSUSED */
208: static void Initialize(request, new, args, num_args)
209: Widget request, new;
210: ArgList args;
211: Cardinal num_args;
212: {
213: CommandWidget cbw = (CommandWidget) new;
214:
215: Get_inverseGC(cbw);
216: Get_inverseTextGC(cbw);
217: Get_highlightGC(cbw);
218: /* Start the callback list if the client specified one in
219: the arglist */
220: ComWcallbackList = NULL;
221: if (ComWcallback != NULL)
222: XtAddCallback((Widget)cbw,activateCommand,ComWcallback,ComWclosure);
223:
224: /* init flags for state */
225: ComWset = FALSE;
226: ComWhighlighted = FALSE;
227: ComWdisplayHighlighted = FALSE;
228: ComWdisplaySet = FALSE;
229:
230: }
231:
232: static void Realize(w, valueMask, attributes)
233: /* This is the same as LabelWidget */
234: register Widget w;
235: Mask valueMask;
236: XSetWindowAttributes *attributes;
237: {
238: XtCallParentProcedure3Args(realize,w,valueMask,attributes);
239: }
240:
241:
242: /***************************
243: *
244: * EVENT HANDLERS
245: *
246: ***************************/
247:
248: /* ARGSUSED */
249: static void Set(w,event)
250: Widget w;
251: XEvent *event;
252: {
253: CommandWidget cbw = (CommandWidget)w;
254: ComWset = TRUE;
255: Redisplay(w, event);
256: }
257:
258: /* ARGSUSED */
259: static void Unset(w,event)
260: Widget w;
261: XEvent *event;
262: {
263: CommandWidget cbw = (CommandWidget)w;
264: ComWset = FALSE;
265: Redisplay(w, event);
266: }
267:
268: /* ARGSUSED */
269: static void Highlight(w,event)
270: Widget w;
271: XEvent *event;
272: {
273: CommandWidget cbw = (CommandWidget)w;
274: ComWhighlighted = TRUE;
275: Redisplay(w, event);
276: }
277:
278: /* ARGSUSED */
279: static void Unhighlight(w,event)
280: Widget w;
281: XEvent *event;
282: {
283: CommandWidget cbw = (CommandWidget)w;
284: ComWhighlighted = FALSE;
285: Redisplay(w, event);
286: }
287:
288: /* ARGSUSED */
289: static void Notify(w,event)
290: Widget w;
291: XEvent *event;
292: {
293: CommandWidget cbw = (CommandWidget)w;
294: XtCallCallbacks((Widget)cbw,activateCommand,NULL);
295: }
296: /*
297: * Repaint the widget window
298: */
299:
300: /************************
301: *
302: * REDISPLAY (DRAW)
303: *
304: ************************/
305:
306: /* ARGSUSED */
307: static void Redisplay(w, event)
308: Widget w;
309: XEvent *event;
310: {
311: CommandWidget cbw = (CommandWidget) w;
312: XSetWindowAttributes window_attributes;
313:
314: /* Here's the scoop: If the command button button is normal,
315: you show the text. If the command button is highlighted but
316: not set, you draw a thick border and show the text.
317: If the command button is set, draw the button and text
318: in inverse. */
319:
320: /* Just to make sure everything is okay, check for sensitivity,
321: too. If non-sensitive, then gray out the border. */
322:
323: /* Note that Redisplay must remember the state of its last
324: draw to determine whether to erase the window before
325: redrawing to avoid flicker. If the state is the same,
326: the window just needs to redraw (even on an expose). */
327:
328: if (!ComWsensitive && ComWdisplaySensitive)
329: {
330: /* change border to gray */
331: window_attributes.border_pixmap = ComWgrayPixmap;
332: XChangeWindowAttributes(XtDisplay(w),XtWindow(w),
333: CWBorderPixmap,&window_attributes);
334: }
335: else if (ComWsensitive && !ComWdisplaySensitive)
336: {
337: /* change border to black */
338: window_attributes.border_pixel = ComWforeground;
339: XChangeWindowAttributes(XtDisplay(w),XtWindow(w),
340: CWBorderPixel,&window_attributes);
341: }
342:
343: if ((!ComWhighlighted && ComWdisplayHighlighted) ||
344: ComWsensitive != ComWdisplaySensitive ||
345: (!ComWset && ComWdisplaySet))
346: XClearWindow(XtDisplay(w),XtWindow(w));
347: /* Don't clear the window if the button's in a set condition;
348: instead, fill it with black to avoid flicker. (Must fil
349: with black in case it was an expose */
350: else if (ComWset) /* && ComWdisplaySet) || (ComWset && !ComWdisplaySet))*/
351: XFillRectangle(XtDisplay(w),XtWindow(w), ComWinverseGC,
352: 0,0,ComWwidth,ComWheight);
353:
354: /* check whether border is taken out of size of rectangle or
355: is outside of rectangle */
356: if (ComWhighlighted)
357: XDrawRectangle(XtDisplay(w),XtWindow(w), ComWhighlightGC,
358: 0,0,ComWwidth,ComWheight);
359:
360: /* draw the string: there are three different "styles" for it,
361: all in separate GCs */
362: XDrawString(XtDisplay(w),XtWindow(w),
363: (ComWset ? ComWinverseTextGC :
364: (ComWsensitive ? ComWnormalGC : ComWgrayGC)),
365: ComWlabelX, ComWlabelY, ComWlabel, (int) ComWlabelLen);
366:
367: ComWdisplayHighlighted = ComWhighlighted;
368: ComWdisplaySet = ComWset;
369: ComWdisplaySensitive = ComWsensitive;
370: }
371:
372:
373: static void Resize(w)
374: Widget w;
375: {
376: /* Nothing changes specific to command. Label must change. */
377: XtCallParentProcedure(resize,w);
378: }
379:
380: static void Destroy(w)
381: Widget w;
382: {
383: /* must free GCs and pixmaps */
384: }
385:
386:
387: /*
388: * Set specified arguments into widget
389: */
390: static Boolean SetValues (current, request, new, last)
391: Widget current, request, new;
392: Boolean last;
393: {
394: CommandWidget cbw = (CommandWidget) current;
395: CommandWidget newcbw = (CommandWidget) new;
396:
397: if (XtLField(newcbw,foreground) != ComWforeground)
398: {
399: XtDestroyGC(ComWinverseGC);
400: Get_inverseGC(newcbw);
401: XtDestroyGC(ComWhighlightGC);
402: Get_highlightGC(newcbw);
403: }
404: else
405: {
406: if (XtCField(newcbw,background_pixel) != ComWbackground ||
407: XtLField(newcbw,font) != ComWfont) {
408: XtDestroyGC(ComWinverseTextGC);
409: Get_inverseTextGC(newcbw);
410: }
411: if (XtCBField(newcbw,highlight_thickness) != ComWhighlightThickness) {
412: XtDestroyGC(ComWhighlightGC);
413: Get_highlightGC(newcbw);
414: }
415: }
416:
417: /* NEED TO RESET PROC AND CLOSURE */
418:
419: /* ACTIONS */
420: /* Change Label to remove ClearWindow and Redisplay */
421: /* Change Label to change GCs if foreground, etc */
422:
423: return (FALSE); /* actually need to return TRUE if Redisplay is needed! */
424: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.