1 /*
2 Copyright (C) 1999-2001 Ulric Eriksson <ulric@siag.nu>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the Licence, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public
15 License along with this library; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston,
17 MA 02111-1307, USA.
18 */
19
20 #include <stdio.h>
21 #include <string.h>
22 #include <stdlib.h>
23 #include <sys/stat.h>
24
25 #include <X11/IntrinsicP.h>
26 #include <X11/StringDefs.h>
27
28 #include <X11/xpm.h>
29
30 #include "MwUtils.h"
31 #include "MwCheckP.h"
32
33 #include "pixmaps/check_motif_off.xpm"
34 #include "pixmaps/check_motif_on.xpm"
35 #include "pixmaps/radio_motif_off.xpm"
36 #include "pixmaps/radio_motif_on.xpm"
37 #include "pixmaps/tickbox_off.xpm"
38 #include "pixmaps/tickbox_on.xpm"
39 #include "pixmaps/radio_16_off.xpm"
40 #include "pixmaps/radio_16_on.xpm"
41
42 #define offset(field) XtOffsetOf(MwCheckRec, check.field)
43 static XtResource resources[] = {
44 {
45 XtNfont, /* name */
46 XtCFont, /* class */
47 XtRFontStruct, /* type */
48 sizeof(XFontStruct *), /* size */
49 offset(font), /* offset */
50 XtRString, /* default_type */
51 XtDefaultFont /* default_addr */
52 }, {
53 XtNstate,
54 XtCState,
55 XtRBoolean,
56 sizeof(Boolean),
57 offset(state),
58 XtRImmediate,
59 (XtPointer)False
60 }, {
61 XtNcheckStyle,
62 XtCCheckStyle,
63 XtRInt,
64 sizeof(int),
65 offset(style),
66 XtRImmediate,
67 (XtPointer)MwCheckWin
68 }, {
69 XtNradioStart,
70 XtCRadioStart,
71 XtRWidget,
72 sizeof(Widget),
73 offset(start),
74 XtRImmediate,
75 (Widget)None
76 }, {
77 XtNradioGroup,
78 XtCRadioGroup,
79 XtRWidget,
80 sizeof(Widget),
81 offset(group),
82 XtRImmediate,
83 (Widget)None
84 }, {
85 XtNlabel,
86 XtCLabel,
87 XtRString,
88 sizeof(String),
89 offset(label),
90 XtRImmediate,
91 (XtPointer)NULL
92 }, {
93 XtNcallback,
94 XtCCallback,
95 XtRCallback,
96 sizeof(XtPointer),
97 offset(callbacks),
98 XtRCallback,
99 (XtPointer)NULL
100 }
101 };
102 #undef offset
103
104 /* methods */
105 static void Redisplay(Widget, XEvent *, Region);
106 static void Realize(Widget, XtValueMask *, XSetWindowAttributes *);
107 static void Initialize(Widget, Widget, ArgList, Cardinal *);
108 static void Destroy(Widget);
109 static Boolean SetValues(Widget, Widget, Widget, ArgList, Cardinal *);
110 static void RadioResetGroup(Widget, Widget);
111
112 /* actions */
113 static void MwCheckAction(Widget, XEvent *, String *, Cardinal *);
114
115 static XtActionsRec actions[] =
116 {
117 {"check", MwCheckAction},
118 };
119
120 /* translations */
121 static char translations[] =
122 "<Btn1Down>: check()\n";
123
124 MwCheckClassRec mwCheckClassRec = {
125 { /* core fields */
126 /* superclass */ (WidgetClass) &widgetClassRec,
127 /* class_name */ "MwCheck",
128 /* widget_size */ sizeof(MwCheckRec),
129 /* class_initialize */ NULL,
130 /* class_part_initialize */ NULL,
131 /* class_inited */ FALSE,
132 /* initialize */ Initialize,
133 /* initialize_hook */ NULL,
134 /* realize */ Realize,
135 /* actions */ actions,
136 /* num_actions */ XtNumber(actions),
137 /* resources */ resources,
138 /* num_resources */ XtNumber(resources),
139 /* xrm_class */ NULLQUARK,
140 /* compress_motion */ TRUE,
141 /* compress_exposure */ TRUE,
142 /* compress_enterleave */ TRUE,
143 /* visible_interest */ FALSE,
144 /* destroy */ Destroy,
145 /* resize */ NULL,
146 /* expose */ Redisplay,
147 /* set_values */ SetValues,
148 /* set_values_hook */ NULL,
149 /* set_values_almost */ XtInheritSetValuesAlmost,
150 /* get_values_hook */ NULL,
151 /* accept_focus */ NULL,
152 /* version */ XtVersion,
153 /* callback_private */ NULL,
154 /* tm_table */ translations,
155 /* query_geometry */ XtInheritQueryGeometry,
156 /* display_accelerator */ XtInheritDisplayAccelerator,
157 /* extension */ NULL
158 },
159 { /* check fields */
160 /* empty */ 0
161 }
162 };
163
164 WidgetClass mwCheckWidgetClass = (WidgetClass)&mwCheckClassRec;
165
166 /* gw is any widget in the group, pw is where we start searching */
RadioResetGroup(Widget gw,Widget pw)167 static void RadioResetGroup(Widget gw, Widget pw)
168 {
169 int i;
170
171 if (XtIsSubclass(pw, mwCheckWidgetClass)) {
172 MwCheckWidget cw = (MwCheckWidget)pw;
173 MwCheckWidget gcw = (MwCheckWidget)gw;
174 if (pw != gw && cw->check.group == gcw->check.group)
175 XtVaSetValues(pw, XtNstate, False, (char *)0);
176 }
177 if (XtIsSubclass(pw, compositeWidgetClass)) {
178 CompositeWidget cw = (CompositeWidget)pw;
179 for (i = 0; i < cw->composite.num_children; i++)
180 RadioResetGroup(gw, cw->composite.children[i]);
181 }
182 }
183
MwCheckAction(Widget w,XEvent * event,String * params,Cardinal * n)184 static void MwCheckAction(Widget w, XEvent *event, String *params, Cardinal *n)
185 {
186 MwCheckWidget tw = (MwCheckWidget)w;
187
188 tw->check.state = !tw->check.state;
189 if (tw->check.start && tw->check.group)
190 RadioResetGroup(w, tw->check.start);
191 XtCallCallbackList(w, tw->check.callbacks, (XtPointer)NULL);
192 Redisplay(w, NULL, NULL);
193 }
194
195 #define MakePixmap(d,p) \
196 result = XpmCreatePixmapFromData(dpy, wi, (d), &(p), NULL, &xa); \
197 if (result != XpmSuccess) \
198 fprintf(stderr, "XpmCreatePixmapFromData returns %s\n", \
199 XpmGetErrorString(result));
200
Initialize(Widget req,Widget new,ArgList args,Cardinal * num)201 static void Initialize(Widget req, Widget new, ArgList args, Cardinal *num)
202 {
203 XpmAttributes xa;
204 int result;
205 XpmColorSymbol symbol;
206 Pixel color;
207 MwCheckWidget cw = (MwCheckWidget)new;
208 Display *dpy = XtDisplay(new);
209 Window wi = XRootWindowOfScreen(XtScreen(new));
210
211 if (cw->core.width == 0) cw->core.width = 80;
212 if (cw->core.height == 0) cw->core.height = 20;
213 XtVaGetValues(new,
214 XtNbackground, &color,
215 (char *)0);
216 xa.closeness = 40000;
217 xa.exactColors = FALSE;
218 xa.valuemask = XpmCloseness | XpmExactColors;
219 symbol.name = NULL;
220 symbol.value = "none";
221 symbol.pixel = color;
222 xa.colorsymbols = &symbol;
223 xa.numsymbols = 1;
224 xa.valuemask |= XpmColorSymbols;
225 MakePixmap(check_motif_off_xpm, cw->check.cmoff);
226 MakePixmap(check_motif_on_xpm, cw->check.cmon);
227 MakePixmap(radio_16_off_xpm, cw->check.r16off);
228 MakePixmap(radio_16_on_xpm, cw->check.r16on);
229 MakePixmap(radio_motif_off_xpm, cw->check.rmoff);
230 MakePixmap(radio_motif_on_xpm, cw->check.rmon);
231 MakePixmap(tickbox_off_xpm, cw->check.tboff);
232 MakePixmap(tickbox_on_xpm, cw->check.tbon);
233 }
234
get_gc(Widget w)235 static GC get_gc(Widget w)
236 {
237 MwCheckWidget tw = (MwCheckWidget)w;
238 unsigned long valuemask;
239 XGCValues values;
240 GC gc;
241
242 values.font = tw->check.font->fid;
243 valuemask = GCFont;
244 gc = XCreateGC(XtDisplay(w), XtWindow(w),
245 valuemask, &values);
246 return gc;
247 }
248
249 #define superclass (&coreClassRec)
Realize(Widget w,XtValueMask * valueMask,XSetWindowAttributes * attributes)250 static void Realize(Widget w, XtValueMask *valueMask,
251 XSetWindowAttributes *attributes)
252 {
253 MwCheckWidget tw = (MwCheckWidget) w;
254
255 (*superclass->core_class.realize) (w, valueMask, attributes);
256 tw->check.gc = get_gc(w);
257 }
258
Destroy(Widget w)259 static void Destroy(Widget w)
260 {
261 MwCheckWidget tw = (MwCheckWidget) w;
262 Display *dpy = XtDisplay(w);
263
264 XFreeGC(dpy, tw->check.gc);
265 XFreePixmap(dpy, tw->check.cmoff);
266 XFreePixmap(dpy, tw->check.cmon);
267 XFreePixmap(dpy, tw->check.r16on);
268 XFreePixmap(dpy, tw->check.r16off);
269 XFreePixmap(dpy, tw->check.rmoff);
270 XFreePixmap(dpy, tw->check.rmon);
271 XFreePixmap(dpy, tw->check.tbon);
272 XFreePixmap(dpy, tw->check.tboff);
273 }
274
Redisplay(Widget w,XEvent * event,Region r)275 static void Redisplay(Widget w, XEvent *event, Region r)
276 {
277 Pixmap scribble, icon;
278 Dimension h;
279 MwCheckWidget aw = (MwCheckWidget) w;
280 Display *dpy = XtDisplay(w);
281 Screen *s = XtScreen(w);
282 Window wi = XtWindow(w);
283 unsigned long black = BlackPixelOfScreen(s);
284 unsigned long grey;
285 XFontStruct *fs = aw->check.font;
286 char *word = aw->check.label;
287 int asc = fs->max_bounds.ascent;
288 int desc = fs->max_bounds.descent;
289 int height = asc-desc;
290 int y = (aw->core.height+height)/2;
291
292 XtVaGetValues(w,
293 XtNbackground, &grey,
294 XtNheight, &h,
295 (char *)0);
296 scribble = XCreatePixmap(dpy, wi, aw->core.width,
297 aw->core.height, aw->core.depth);
298 XSetForeground(dpy, aw->check.gc, grey);
299 XFillRectangle(dpy, scribble, aw->check.gc, 0, 0,
300 aw->core.width, aw->core.height);
301 XSetForeground(dpy, aw->check.gc, black);
302
303 switch (aw->check.style) {
304 case MwCheckWin:
305 if (aw->check.state) icon = aw->check.tbon;
306 else icon = aw->check.tboff;
307 break;
308 case MwRadioWin:
309 if (aw->check.state) icon = aw->check.r16on;
310 else icon = aw->check.r16off;
311 break;
312 case MwCheckMotif:
313 if (aw->check.state) icon = aw->check.cmon;
314 else icon = aw->check.cmoff;
315 break;
316 default: /* MwRadioMotif */
317 if (aw->check.state) icon = aw->check.rmon;
318 else icon = aw->check.rmoff;
319 break;
320 }
321 XCopyArea(dpy, icon, scribble, aw->check.gc,
322 0, 0, 16, 16, 2, (aw->core.height-16)/2);
323 if (word) {
324 XDrawString(dpy, scribble, aw->check.gc,
325 20, y, word, strlen(word));
326 }
327 XCopyArea(dpy, scribble, wi, aw->check.gc,
328 0, 0, aw->core.width, aw->core.height, 0, 0);
329 XFreePixmap(dpy, scribble);
330 }
331
SetValues(Widget current,Widget request,Widget new,ArgList args,Cardinal * nargs)332 static Boolean SetValues(Widget current, Widget request, Widget new,
333 ArgList args, Cardinal *nargs)
334 {
335 Boolean do_redisplay = True;
336 return do_redisplay;
337 }
338
339