1010cdda0Smrg/************************************************************
2010cdda0Smrg Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc.
3010cdda0Smrg
4010cdda0Smrg Permission to use, copy, modify, and distribute this
5010cdda0Smrg software and its documentation for any purpose and without
6010cdda0Smrg fee is hereby granted, provided that the above copyright
7010cdda0Smrg notice appear in all copies and that both that copyright
8010cdda0Smrg notice and this permission notice appear in supporting
9010cdda0Smrg documentation, and that the name of Silicon Graphics not be
10010cdda0Smrg used in advertising or publicity pertaining to distribution
11010cdda0Smrg of the software without specific prior written permission.
12010cdda0Smrg Silicon Graphics makes no representation about the suitability
13010cdda0Smrg of this software for any purpose. It is provided "as is"
14010cdda0Smrg without any express or implied warranty.
15010cdda0Smrg
16010cdda0Smrg SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
17010cdda0Smrg SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
18010cdda0Smrg AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
19010cdda0Smrg GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
20010cdda0Smrg DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21010cdda0Smrg DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
22010cdda0Smrg OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
23010cdda0Smrg THE USE OR PERFORMANCE OF THIS SOFTWARE.
24010cdda0Smrg
25010cdda0Smrg ********************************************************/
26010cdda0Smrg
27010cdda0Smrg#include <X11/IntrinsicP.h>
28010cdda0Smrg#include <X11/StringDefs.h>
29010cdda0Smrg#include <X11/Xos.h>
30010cdda0Smrg#include <X11/Xaw/XawInit.h>
31010cdda0Smrg#include "LEDP.h"
32010cdda0Smrg#include <stdio.h>
33010cdda0Smrg#include <ctype.h>
34010cdda0Smrg#include <stdlib.h>
35010cdda0Smrg
36010cdda0Smrg/****************************************************************
37010cdda0Smrg *
38010cdda0Smrg * Full class record constant
39010cdda0Smrg *
40010cdda0Smrg ****************************************************************/
41010cdda0Smrg
42010cdda0Smrg/* Private Data */
43010cdda0Smrg
44010cdda0Smrg#define offset(field) XtOffsetOf(LEDRec, field)
45010cdda0Smrgstatic XtResource resources[] = {
46010cdda0Smrg    {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
47b4485a66Smrg     offset(led.foreground), XtRString, XtDefaultForeground},
48010cdda0Smrg    {XtNon, XtCOn, XtRBoolean, sizeof(Boolean),
49b4485a66Smrg     offset(led.on), XtRImmediate, (XtPointer) False},
50010cdda0Smrg    {XtNtopColor, XtCTopColor, XtRPixel, sizeof(Pixel),
51b4485a66Smrg     offset(led.top_color), XtRString, "black"},
52010cdda0Smrg    {XtNbottomColor, XtCBottomColor, XtRPixel, sizeof(Pixel),
53b4485a66Smrg     offset(led.bottom_color), XtRString, "white"},
54010cdda0Smrg    {XtNonColor, XtCOnColor, XtRPixel, sizeof(Pixel),
55b4485a66Smrg     offset(led.on_color), XtRString, "green"},
56010cdda0Smrg    {XtNoffColor, XtCOffColor, XtRPixel, sizeof(Pixel),
57b4485a66Smrg     offset(led.off_color), XtRString, "#005000"},
58010cdda0Smrg    {XtNbevel, XtCBevel, XtRDimension, sizeof(Dimension),
59b4485a66Smrg     offset(led.bevel), XtRImmediate, (XtPointer) 1},
60010cdda0Smrg    {XtNledWidth, XtCLedWidth, XtRDimension, sizeof(Dimension),
61b4485a66Smrg     offset(led.led_width), XtRImmediate, (XtPointer) 6},
62010cdda0Smrg    {XtNledHeight, XtCLedHeight, XtRDimension, sizeof(Dimension),
63b4485a66Smrg     offset(led.led_height), XtRImmediate, (XtPointer) 12}
64010cdda0Smrg};
65010cdda0Smrg#undef offset
66010cdda0Smrg
67b4485a66Smrgstatic void ClassInitialize(void);
68b4485a66Smrgstatic void Initialize(Widget request, Widget new, ArgList args,
69b4485a66Smrg                       Cardinal *num_args);
70b4485a66Smrgstatic void Realize(Widget w, Mask *mask, XSetWindowAttributes *xswa);
71b4485a66Smrgstatic void Resize(Widget w);
72b4485a66Smrgstatic Boolean SetValues(Widget current, Widget request, Widget new,
73b4485a66Smrg                         ArgList args, Cardinal *num_args);
74b4485a66Smrgstatic void Destroy(Widget w);
75b4485a66Smrgstatic XtGeometryResult QueryGeometry(Widget w, XtWidgetGeometry *intended,
76b4485a66Smrg                                      XtWidgetGeometry *preferred);
77010cdda0Smrg
78010cdda0SmrgLEDClassRec ledClassRec = {
79b4485a66Smrg    {
80b4485a66Smrg/* core_class fields */
81b4485a66Smrg     /* superclass               */ (WidgetClass) & simpleClassRec,
82b4485a66Smrg     /* class_name               */ "LED",
83b4485a66Smrg     /* widget_size              */ sizeof(LEDRec),
84b4485a66Smrg     /* class_initialize         */ ClassInitialize,
85b4485a66Smrg     /* class_part_initialize    */ NULL,
86b4485a66Smrg     /* class_inited             */ FALSE,
87b4485a66Smrg     /* initialize               */ Initialize,
88b4485a66Smrg     /* initialize_hook          */ NULL,
89b4485a66Smrg     /* realize                  */ Realize,
90b4485a66Smrg     /* actions                  */ NULL,
91b4485a66Smrg     /* num_actions              */ 0,
92b4485a66Smrg     /* resources                */ resources,
93b4485a66Smrg     /* num_resources            */ XtNumber(resources),
94b4485a66Smrg     /* xrm_class                */ NULLQUARK,
95b4485a66Smrg     /* compress_motion          */ TRUE,
96b4485a66Smrg     /* compress_exposure        */ TRUE,
97b4485a66Smrg     /* compress_enterleave      */ TRUE,
98b4485a66Smrg     /* visible_interest         */ FALSE,
99b4485a66Smrg     /* destroy                  */ Destroy,
100b4485a66Smrg     /* resize                   */ Resize,
101b4485a66Smrg     /* expose                   */ XtInheritExpose,
102b4485a66Smrg     /* set_values               */ SetValues,
103b4485a66Smrg     /* set_values_hook          */ NULL,
104b4485a66Smrg     /* set_values_almost        */ XtInheritSetValuesAlmost,
105b4485a66Smrg     /* get_values_hook          */ NULL,
106b4485a66Smrg     /* accept_focus             */ NULL,
107b4485a66Smrg     /* version                  */ XtVersion,
108b4485a66Smrg     /* callback_private         */ NULL,
109b4485a66Smrg     /* tm_table                 */ NULL,
110b4485a66Smrg     /* query_geometry           */ QueryGeometry,
111b4485a66Smrg     /* display_accelerator      */ XtInheritDisplayAccelerator,
112b4485a66Smrg     /* extension                */ NULL
113b4485a66Smrg    },
114010cdda0Smrg/* Simple class fields initialization */
115b4485a66Smrg    {
116b4485a66Smrg     /* change_sensitive         */ XtInheritChangeSensitive
117b4485a66Smrg    },
118010cdda0Smrg/* LED class fields initialization */
119b4485a66Smrg    {
120b4485a66Smrg     /* ignore                   */ 0
121b4485a66Smrg    }
122010cdda0Smrg};
123b4485a66SmrgWidgetClass ledWidgetClass = (WidgetClass) &ledClassRec;
124b4485a66Smrg
125010cdda0Smrg/****************************************************************
126010cdda0Smrg *
127010cdda0Smrg * Private Procedures
128010cdda0Smrg *
129010cdda0Smrg ****************************************************************/
130010cdda0Smrg
131b4485a66Smrgstatic void
132010cdda0SmrgClassInitialize(void)
133010cdda0Smrg{
134010cdda0Smrg    XawInitializeWidgetSet();
135010cdda0Smrg}
136010cdda0Smrg
137b4485a66Smrgstatic void
138010cdda0SmrgGetPixmaps(LEDWidget lw)
139010cdda0Smrg{
140b4485a66Smrg    XGCValues values;
141b4485a66Smrg    GC gc;
142b4485a66Smrg    Display *dpy;
143b4485a66Smrg    Window root;
144b4485a66Smrg    Pixmap pix, on_pixmap, off_pixmap;
145b4485a66Smrg    Dimension bevel, width, height;
146010cdda0Smrg
147b4485a66Smrg    dpy = XtDisplay((Widget) lw);
148b4485a66Smrg    root = RootWindowOfScreen(XtScreen((Widget) lw));
149b4485a66Smrg    if (lw->led.on_pixmap != None) {
150b4485a66Smrg        XFreePixmap(dpy, lw->led.on_pixmap);
151b4485a66Smrg        lw->led.on_pixmap = None;
152010cdda0Smrg    }
153b4485a66Smrg    if (lw->led.off_pixmap != None) {
154b4485a66Smrg        XFreePixmap(dpy, lw->led.off_pixmap);
155b4485a66Smrg        lw->led.off_pixmap = None;
156010cdda0Smrg    }
157b4485a66Smrg    lw->led.on_pixmap = on_pixmap =
158b4485a66Smrg        XCreatePixmap(dpy, root, lw->core.width, lw->core.height,
159b4485a66Smrg                      lw->core.depth);
160b4485a66Smrg    lw->led.off_pixmap = off_pixmap =
161b4485a66Smrg        XCreatePixmap(dpy, root, lw->core.width, lw->core.height,
162b4485a66Smrg                      lw->core.depth);
163010cdda0Smrg
164b4485a66Smrg    values.foreground = lw->led.top_color;
165b4485a66Smrg    gc = XCreateGC(dpy, lw->led.on_pixmap, (unsigned) GCForeground, &values);
166b4485a66Smrg    bevel = lw->led.bevel;
167b4485a66Smrg    width = lw->core.width;
168b4485a66Smrg    height = lw->core.height;
169b4485a66Smrg    XFillRectangle(dpy, on_pixmap, gc, 0, 0, width, height);
170b4485a66Smrg    XFillRectangle(dpy, off_pixmap, gc, 0, 0, width, height);
171b4485a66Smrg    XSetForeground(dpy, gc, lw->led.bottom_color);
172b4485a66Smrg    XFillRectangle(dpy, on_pixmap, gc, bevel, bevel, width - bevel,
173b4485a66Smrg                   height - bevel);
174b4485a66Smrg    XFillRectangle(dpy, off_pixmap, gc, bevel, bevel, width - bevel,
175b4485a66Smrg                   height - bevel);
176b4485a66Smrg    XSetForeground(dpy, gc, lw->led.on_color);
177b4485a66Smrg    XFillRectangle(dpy, on_pixmap, gc, bevel, bevel, width - 2 * bevel,
178b4485a66Smrg                   height - 2 * bevel);
179b4485a66Smrg    XSetForeground(dpy, gc, lw->led.off_color);
180b4485a66Smrg    XFillRectangle(dpy, off_pixmap, gc, bevel, bevel, width - 2 * bevel,
181b4485a66Smrg                   height - 2 * bevel);
182b4485a66Smrg    XFreeGC(dpy, gc);
183b4485a66Smrg    if (lw->led.on)
184b4485a66Smrg        pix = on_pixmap;
185b4485a66Smrg    else
186b4485a66Smrg        pix = off_pixmap;
187b4485a66Smrg    if (XtWindow((Widget) lw) != None)
188b4485a66Smrg        XSetWindowBackgroundPixmap(dpy, XtWindow((Widget) lw), pix);
189010cdda0Smrg    return;
190010cdda0Smrg}
191010cdda0Smrg
192010cdda0Smrg/* ARGSUSED */
193b3eb03f3Smrgstatic void
194b3eb03f3SmrgInitialize(Widget request, Widget new, ArgList args, Cardinal *num_args)
195010cdda0Smrg{
196010cdda0Smrg    LEDWidget lw = (LEDWidget) new;
197010cdda0Smrg
198010cdda0Smrg    if (lw->core.height == 0)
199010cdda0Smrg        lw->core.height = lw->led.led_height;
200010cdda0Smrg    if (lw->core.width == 0)
201010cdda0Smrg        lw->core.width = lw->led.led_width;
202b4485a66Smrg    lw->core.border_width = 0;
203b4485a66Smrg    if (lw->led.bevel == 0)
204b4485a66Smrg        lw->led.bevel = 1;
205b4485a66Smrg    lw->led.on_pixmap = lw->led.off_pixmap = None;
206b4485a66Smrg    (*XtClass(new)->core_class.resize) ((Widget) lw);
207010cdda0Smrg    GetPixmaps(lw);
208b4485a66Smrg}                               /* Initialize */
209010cdda0Smrg
210010cdda0Smrgstatic void
211010cdda0SmrgRealize(Widget w, Mask *mask, XSetWindowAttributes *xswa)
212010cdda0Smrg{
213b4485a66Smrg    LEDWidget lw = (LEDWidget) w;
214010cdda0Smrg    WidgetClass super = simpleWidgetClass;
215b4485a66Smrg    Pixmap pix;
216010cdda0Smrg
217b4485a66Smrg    (*super->core_class.realize) (w, mask, xswa);
218b4485a66Smrg    if (lw->led.on)
219b4485a66Smrg        pix = lw->led.on_pixmap;
220b4485a66Smrg    else
221b4485a66Smrg        pix = lw->led.off_pixmap;
222b4485a66Smrg    XSetWindowBackgroundPixmap(XtDisplay(w), XtWindow(w), pix);
223010cdda0Smrg    return;
224010cdda0Smrg}
225010cdda0Smrg
226b4485a66Smrgstatic void
227010cdda0SmrgResize(Widget w)
228010cdda0Smrg{
229b4485a66Smrg    GetPixmaps((LEDWidget) w);
230010cdda0Smrg    return;
231010cdda0Smrg}
232010cdda0Smrg
233010cdda0Smrg/*
234010cdda0Smrg * Set specified arguments into widget
235010cdda0Smrg */
236010cdda0Smrg
237b4485a66Smrgstatic Boolean
238b4485a66SmrgSetValues(Widget current, Widget request, Widget new,
239b4485a66Smrg          ArgList args, Cardinal *num_args)
240010cdda0Smrg{
241010cdda0Smrg    LEDWidget curlw = (LEDWidget) current;
242010cdda0Smrg    LEDWidget newlw = (LEDWidget) new;
243010cdda0Smrg    Boolean changed;
244010cdda0Smrg
245b4485a66Smrg    changed = FALSE;
246b4485a66Smrg    if (curlw->led.foreground != newlw->led.foreground
247b4485a66Smrg        || curlw->core.background_pixel != newlw->core.background_pixel
248b4485a66Smrg        || curlw->led.on_color != newlw->led.on_color
249b4485a66Smrg        || curlw->led.off_color != newlw->led.off_color
250b4485a66Smrg        || curlw->core.width != newlw->core.width
251b4485a66Smrg        || curlw->core.height != newlw->core.height) {
252b4485a66Smrg        GetPixmaps(newlw);
253b4485a66Smrg        changed = TRUE;
254010cdda0Smrg    }
255b4485a66Smrg    if (curlw->led.on != newlw->led.on) {
256b4485a66Smrg        Pixmap pix;
257010cdda0Smrg
258b4485a66Smrg        if (newlw->led.on)
259b4485a66Smrg            pix = newlw->led.on_pixmap;
260b4485a66Smrg        else
261b4485a66Smrg            pix = newlw->led.off_pixmap;
262010cdda0Smrg
263b4485a66Smrg        if (XtWindow(newlw) != None)
264b4485a66Smrg            XSetWindowBackgroundPixmap(XtDisplay(newlw), XtWindow(newlw), pix);
265b4485a66Smrg        changed = TRUE;
266010cdda0Smrg    }
267010cdda0Smrg    return changed;
268010cdda0Smrg}
269010cdda0Smrg
270b4485a66Smrgstatic void
271010cdda0SmrgDestroy(Widget w)
272010cdda0Smrg{
273b4485a66Smrg    LEDWidget lw = (LEDWidget) w;
274010cdda0Smrg
275b4485a66Smrg    if (lw->led.on_pixmap != None) {
276b4485a66Smrg        XFreePixmap(XtDisplay(w), lw->led.on_pixmap);
277b4485a66Smrg        lw->led.on_pixmap = None;
278010cdda0Smrg    }
279b4485a66Smrg    if (lw->led.off_pixmap != None) {
280b4485a66Smrg        XFreePixmap(XtDisplay(w), lw->led.off_pixmap);
281b4485a66Smrg        lw->led.off_pixmap = None;
282010cdda0Smrg    }
283010cdda0Smrg    return;
284010cdda0Smrg}
285010cdda0Smrg
286b4485a66Smrgstatic XtGeometryResult
287b4485a66SmrgQueryGeometry(Widget w, XtWidgetGeometry *intended,
288b4485a66Smrg              XtWidgetGeometry *preferred)
289010cdda0Smrg{
290b4485a66Smrg    LEDWidget lw = (LEDWidget) w;
291010cdda0Smrg
292010cdda0Smrg    preferred->request_mode = CWWidth | CWHeight;
293010cdda0Smrg    preferred->width = lw->led.led_height;
294010cdda0Smrg    preferred->height = lw->led.led_width;
295b4485a66Smrg    if (((intended->request_mode & (CWWidth | CWHeight))
296b4485a66Smrg         == (CWWidth | CWHeight)) &&
297b4485a66Smrg        intended->width == preferred->width &&
298b4485a66Smrg        intended->height == preferred->height)
299b4485a66Smrg        return XtGeometryYes;
300010cdda0Smrg    else if (preferred->width == w->core.width &&
301b4485a66Smrg             preferred->height == w->core.height)
302b4485a66Smrg        return XtGeometryNo;
303010cdda0Smrg    else
304b4485a66Smrg        return XtGeometryAlmost;
305010cdda0Smrg}
306