LED.c revision b4485a66
1/************************************************************
2 Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc.
3
4 Permission to use, copy, modify, and distribute this
5 software and its documentation for any purpose and without
6 fee is hereby granted, provided that the above copyright
7 notice appear in all copies and that both that copyright
8 notice and this permission notice appear in supporting
9 documentation, and that the name of Silicon Graphics not be
10 used in advertising or publicity pertaining to distribution
11 of the software without specific prior written permission.
12 Silicon Graphics makes no representation about the suitability
13 of this software for any purpose. It is provided "as is"
14 without any express or implied warranty.
15
16 SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
17 SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
18 AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
19 GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
20 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21 DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
22 OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
23 THE USE OR PERFORMANCE OF THIS SOFTWARE.
24
25 ********************************************************/
26
27#include <X11/IntrinsicP.h>
28#include <X11/StringDefs.h>
29#include <X11/Xos.h>
30#include <X11/Xaw/XawInit.h>
31#include "LEDP.h"
32#include <stdio.h>
33#include <ctype.h>
34#include <stdlib.h>
35
36/****************************************************************
37 *
38 * Full class record constant
39 *
40 ****************************************************************/
41
42/* Private Data */
43
44#define offset(field) XtOffsetOf(LEDRec, field)
45static XtResource resources[] = {
46    {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
47     offset(led.foreground), XtRString, XtDefaultForeground},
48    {XtNon, XtCOn, XtRBoolean, sizeof(Boolean),
49     offset(led.on), XtRImmediate, (XtPointer) False},
50    {XtNtopColor, XtCTopColor, XtRPixel, sizeof(Pixel),
51     offset(led.top_color), XtRString, "black"},
52    {XtNbottomColor, XtCBottomColor, XtRPixel, sizeof(Pixel),
53     offset(led.bottom_color), XtRString, "white"},
54    {XtNonColor, XtCOnColor, XtRPixel, sizeof(Pixel),
55     offset(led.on_color), XtRString, "green"},
56    {XtNoffColor, XtCOffColor, XtRPixel, sizeof(Pixel),
57     offset(led.off_color), XtRString, "#005000"},
58    {XtNbevel, XtCBevel, XtRDimension, sizeof(Dimension),
59     offset(led.bevel), XtRImmediate, (XtPointer) 1},
60    {XtNledWidth, XtCLedWidth, XtRDimension, sizeof(Dimension),
61     offset(led.led_width), XtRImmediate, (XtPointer) 6},
62    {XtNledHeight, XtCLedHeight, XtRDimension, sizeof(Dimension),
63     offset(led.led_height), XtRImmediate, (XtPointer) 12}
64};
65#undef offset
66
67static void ClassInitialize(void);
68static void Initialize(Widget request, Widget new, ArgList args,
69                       Cardinal *num_args);
70static void Realize(Widget w, Mask *mask, XSetWindowAttributes *xswa);
71static void Resize(Widget w);
72static Boolean SetValues(Widget current, Widget request, Widget new,
73                         ArgList args, Cardinal *num_args);
74static void Destroy(Widget w);
75static XtGeometryResult QueryGeometry(Widget w, XtWidgetGeometry *intended,
76                                      XtWidgetGeometry *preferred);
77
78LEDClassRec ledClassRec = {
79    {
80/* core_class fields */
81     /* superclass               */ (WidgetClass) & simpleClassRec,
82     /* class_name               */ "LED",
83     /* widget_size              */ sizeof(LEDRec),
84     /* class_initialize         */ ClassInitialize,
85     /* class_part_initialize    */ NULL,
86     /* class_inited             */ FALSE,
87     /* initialize               */ Initialize,
88     /* initialize_hook          */ NULL,
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     /* compress_enterleave      */ TRUE,
98     /* visible_interest         */ FALSE,
99     /* destroy                  */ Destroy,
100     /* resize                   */ Resize,
101     /* expose                   */ XtInheritExpose,
102     /* set_values               */ SetValues,
103     /* set_values_hook          */ NULL,
104     /* set_values_almost        */ XtInheritSetValuesAlmost,
105     /* get_values_hook          */ NULL,
106     /* accept_focus             */ NULL,
107     /* version                  */ XtVersion,
108     /* callback_private         */ NULL,
109     /* tm_table                 */ NULL,
110     /* query_geometry           */ QueryGeometry,
111     /* display_accelerator      */ XtInheritDisplayAccelerator,
112     /* extension                */ NULL
113    },
114/* Simple class fields initialization */
115    {
116     /* change_sensitive         */ XtInheritChangeSensitive
117    },
118/* LED class fields initialization */
119    {
120     /* ignore                   */ 0
121    }
122};
123WidgetClass ledWidgetClass = (WidgetClass) &ledClassRec;
124
125/****************************************************************
126 *
127 * Private Procedures
128 *
129 ****************************************************************/
130
131static void
132ClassInitialize(void)
133{
134    XawInitializeWidgetSet();
135}
136
137static void
138GetPixmaps(LEDWidget lw)
139{
140    XGCValues values;
141    GC gc;
142    Display *dpy;
143    Window root;
144    Pixmap pix, on_pixmap, off_pixmap;
145    Dimension bevel, width, height;
146
147    dpy = XtDisplay((Widget) lw);
148    root = RootWindowOfScreen(XtScreen((Widget) lw));
149    if (lw->led.on_pixmap != None) {
150        XFreePixmap(dpy, lw->led.on_pixmap);
151        lw->led.on_pixmap = None;
152    }
153    if (lw->led.off_pixmap != None) {
154        XFreePixmap(dpy, lw->led.off_pixmap);
155        lw->led.off_pixmap = None;
156    }
157    lw->led.on_pixmap = on_pixmap =
158        XCreatePixmap(dpy, root, lw->core.width, lw->core.height,
159                      lw->core.depth);
160    lw->led.off_pixmap = off_pixmap =
161        XCreatePixmap(dpy, root, lw->core.width, lw->core.height,
162                      lw->core.depth);
163
164    values.foreground = lw->led.top_color;
165    gc = XCreateGC(dpy, lw->led.on_pixmap, (unsigned) GCForeground, &values);
166    bevel = lw->led.bevel;
167    width = lw->core.width;
168    height = lw->core.height;
169    XFillRectangle(dpy, on_pixmap, gc, 0, 0, width, height);
170    XFillRectangle(dpy, off_pixmap, gc, 0, 0, width, height);
171    XSetForeground(dpy, gc, lw->led.bottom_color);
172    XFillRectangle(dpy, on_pixmap, gc, bevel, bevel, width - bevel,
173                   height - bevel);
174    XFillRectangle(dpy, off_pixmap, gc, bevel, bevel, width - bevel,
175                   height - bevel);
176    XSetForeground(dpy, gc, lw->led.on_color);
177    XFillRectangle(dpy, on_pixmap, gc, bevel, bevel, width - 2 * bevel,
178                   height - 2 * bevel);
179    XSetForeground(dpy, gc, lw->led.off_color);
180    XFillRectangle(dpy, off_pixmap, gc, bevel, bevel, width - 2 * bevel,
181                   height - 2 * bevel);
182    XFreeGC(dpy, gc);
183    if (lw->led.on)
184        pix = on_pixmap;
185    else
186        pix = off_pixmap;
187    if (XtWindow((Widget) lw) != None)
188        XSetWindowBackgroundPixmap(dpy, XtWindow((Widget) lw), pix);
189    return;
190}
191
192/* ARGSUSED */
193static void
194Initialize(Widget request, Widget new, ArgList args, Cardinal *num_args)
195{
196    LEDWidget lw = (LEDWidget) new;
197
198    if (lw->core.height == 0)
199        lw->core.height = lw->led.led_height;
200    if (lw->core.width == 0)
201        lw->core.width = lw->led.led_width;
202    lw->core.border_width = 0;
203    if (lw->led.bevel == 0)
204        lw->led.bevel = 1;
205    lw->led.on_pixmap = lw->led.off_pixmap = None;
206    (*XtClass(new)->core_class.resize) ((Widget) lw);
207    GetPixmaps(lw);
208}                               /* Initialize */
209
210static void
211Realize(Widget w, Mask *mask, XSetWindowAttributes *xswa)
212{
213    LEDWidget lw = (LEDWidget) w;
214    WidgetClass super = simpleWidgetClass;
215    Pixmap pix;
216
217    (*super->core_class.realize) (w, mask, xswa);
218    if (lw->led.on)
219        pix = lw->led.on_pixmap;
220    else
221        pix = lw->led.off_pixmap;
222    XSetWindowBackgroundPixmap(XtDisplay(w), XtWindow(w), pix);
223    return;
224}
225
226static void
227Resize(Widget w)
228{
229    GetPixmaps((LEDWidget) w);
230    return;
231}
232
233/*
234 * Set specified arguments into widget
235 */
236
237static Boolean
238SetValues(Widget current, Widget request, Widget new,
239          ArgList args, Cardinal *num_args)
240{
241    LEDWidget curlw = (LEDWidget) current;
242    LEDWidget newlw = (LEDWidget) new;
243    Boolean changed;
244
245    changed = FALSE;
246    if (curlw->led.foreground != newlw->led.foreground
247        || curlw->core.background_pixel != newlw->core.background_pixel
248        || curlw->led.on_color != newlw->led.on_color
249        || curlw->led.off_color != newlw->led.off_color
250        || curlw->core.width != newlw->core.width
251        || curlw->core.height != newlw->core.height) {
252        GetPixmaps(newlw);
253        changed = TRUE;
254    }
255    if (curlw->led.on != newlw->led.on) {
256        Pixmap pix;
257
258        if (newlw->led.on)
259            pix = newlw->led.on_pixmap;
260        else
261            pix = newlw->led.off_pixmap;
262
263        if (XtWindow(newlw) != None)
264            XSetWindowBackgroundPixmap(XtDisplay(newlw), XtWindow(newlw), pix);
265        changed = TRUE;
266    }
267    return changed;
268}
269
270static void
271Destroy(Widget w)
272{
273    LEDWidget lw = (LEDWidget) w;
274
275    if (lw->led.on_pixmap != None) {
276        XFreePixmap(XtDisplay(w), lw->led.on_pixmap);
277        lw->led.on_pixmap = None;
278    }
279    if (lw->led.off_pixmap != None) {
280        XFreePixmap(XtDisplay(w), lw->led.off_pixmap);
281        lw->led.off_pixmap = None;
282    }
283    return;
284}
285
286static XtGeometryResult
287QueryGeometry(Widget w, XtWidgetGeometry *intended,
288              XtWidgetGeometry *preferred)
289{
290    LEDWidget lw = (LEDWidget) w;
291
292    preferred->request_mode = CWWidth | CWHeight;
293    preferred->width = lw->led.led_height;
294    preferred->height = lw->led.led_width;
295    if (((intended->request_mode & (CWWidth | CWHeight))
296         == (CWWidth | CWHeight)) &&
297        intended->width == preferred->width &&
298        intended->height == preferred->height)
299        return XtGeometryYes;
300    else if (preferred->width == w->core.width &&
301             preferred->height == w->core.height)
302        return XtGeometryNo;
303    else
304        return XtGeometryAlmost;
305}
306