1 /* Checkbox Widget for SXEmacs.
2 Copyright (C) 1999 Edward A. Falk
4 This file is part of SXEmacs.
6 SXEmacs is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 SXEmacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 /* Synched up with: Checkbox.c 1.1 */
22 * Checkbox.c - Checkbox button widget
24 * Author: Edward A. Falk
25 * falk@falconer.vip.best.com
29 * Overview: This widget is identical to the Radio widget in behavior,
30 * except that the button is square and has a check mark.
36 #include <X11/IntrinsicP.h>
37 #include <X11/StringDefs.h>
38 #include ATHENA_XawInit_h_
39 #include "ui/X11/xmu.h"
40 #include "xlwcheckboxP.h"
42 #include "sxe-utils.h"
44 /* by using the same size for the checkbox as for the diamond box,
45 * we can let the Radio widget do the vast majority of the work.
49 #define DRAW_CHECK 0 /* don't draw the check mark */
51 #define cclass(w) ((CheckboxWidgetClass)((w)->core.widget_class))
54 #define swid(cw) ((cw)->threeD.shadow_width)
56 #define swid(cw) ((cw)->core.border_width)
59 #define bsize(cw) (cclass(cw)->radio_class.dsize)
60 #define bs(cw) (bsize(cw) + 2*swid(cw))
63 #define check_width 14
64 #define check_height 14
65 static unsigned char check_bits[] = {
66 0x00, 0x00, 0x00, 0x20, 0x00, 0x18, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x03,
67 0x8c, 0x03, 0xde, 0x01, 0xff, 0x01, 0xfe, 0x00, 0xfc, 0x00, 0x78, 0x00,
68 0x70, 0x00, 0x20, 0x00
72 /****************************************************************
74 * Full class record constant
76 ****************************************************************/
79 static char defaultTranslations[] = "<EnterWindow>: highlight()\n\
80 <LeaveWindow>: unpress(draw) unhighlight()\n\
81 <Btn1Down>: press()\n\
82 <Btn1Down>,<Btn1Up>: unpress(nodraw) toggle() notify()";
85 #define offset(field) XtOffsetOf(CheckboxRec, field)
86 static XtResource resources[] = {
87 {XtNtristate, XtCTristate, XtRBoolean, sizeof(Boolean),
88 offset(checkbox.tristate), XtRImmediate, (XtPointer) FALSE}
93 /* Member functions */
95 static void CheckboxClassInit(void);
96 static void CheckboxInit(Widget, Widget, ArgList, Cardinal *);
98 static void CheckboxRealize(Widget, Mask *, XSetWindowAttributes *);
100 static void DrawCheck(Widget);
104 static void CheckboxPress(Widget, XEvent *, String *, Cardinal *);
105 static void CheckboxUnpress(Widget, XEvent *, String *, Cardinal *);
108 /* internal privates */
111 static XtActionsRec actionsList[] = {
112 {"press", CheckboxPress},
113 {"unpress", CheckboxUnpress},
117 #define SuperClass ((RadioWidgetClass)&radioClassRec)
119 CheckboxClassRec checkboxClassRec = {
121 (WidgetClass) SuperClass, /* superclass */
122 "Checkbox", /* class_name */
123 sizeof(CheckboxRec), /* size */
124 CheckboxClassInit, /* class_initialize */
125 NULL, /* class_part_initialize */
126 FALSE, /* class_inited */
127 CheckboxInit, /* initialize */
128 NULL, /* initialize_hook */
130 CheckboxRealize, /* realize */
131 actionsList, /* actions */
132 XtNumber(actionsList), /* num_actions */
134 XtInheritRealize, /* realize */
138 resources, /* resources */
139 XtNumber(resources), /* resource_count */
140 NULLQUARK, /* xrm_class */
141 TRUE, /* compress_motion */
142 TRUE, /* compress_exposure */
143 TRUE, /* compress_enterleave */
144 FALSE, /* visible_interest */
146 XtInheritResize, /* resize */
147 XtInheritExpose, /* expose */
148 NULL, /* set_values */
149 NULL, /* set_values_hook */
150 XtInheritSetValuesAlmost, /* set_values_almost */
151 NULL, /* get_values_hook */
152 NULL, /* accept_focus */
153 XtVersion, /* version */
154 NULL, /* callback_private */
156 defaultTranslations, /* tm_table */
158 XtInheritTranslations, /* tm_table */
160 XtInheritQueryGeometry, /* query_geometry */
161 XtInheritDisplayAccelerator, /* display_accelerator */
164 , /* CoreClass fields initialization */
166 XtInheritChangeSensitive /* change_sensitive */
168 , /* SimpleClass fields initialization */
171 XtInheritXaw3dShadowDraw /* field not used */
173 , /* ThreeDClass fields initialization */
176 0 /* field not used */
178 , /* LabelClass fields initialization */
180 0 /* field not used */
182 , /* CommandClass fields initialization */
184 RadioSet, /* Set Procedure. */
185 RadioUnset, /* Unset Procedure. */
186 NULL /* extension. */
188 , /* ToggleClass fields initialization */
191 DrawCheck, /* draw procedure */
192 NULL /* extension. */
194 , /* RadioClass fields initialization */
196 NULL /* extension. */
198 , /* CheckboxClass fields initialization */
201 /* for public consumption */
202 WidgetClass checkboxWidgetClass = (WidgetClass) & checkboxClassRec;
204 /****************************************************************
208 ****************************************************************/
210 static void CheckboxClassInit(void)
212 XawInitializeWidgetSet();
217 CheckboxInit(Widget request, Widget new, ArgList args, Cardinal * num_args)
220 CheckboxWidget cw = (CheckboxWidget) new;
221 cw->checkbox.checkmark = None;
222 cw->checkbox.checkmark_GC = None;
228 CheckboxRealize(Widget w, Mask * valueMask, XSetWindowAttributes * attributes)
230 CheckboxWidget cw = (CheckboxWidget) w;
231 XtGCMask value_mask, dynamic_mask, dontcare_mask;
234 /* first, call superclass realize */
235 (*checkboxWidgetClass->core_class.superclass->core_class.realize)
236 (w, valueMask, attributes);
238 /* TODO: cache this via xmu */
239 if (cw->checkbox.checkmark == None)
240 cw->checkbox.checkmark =
241 XCreateBitmapFromData(XtDisplay(w), XtWindow(w),
242 check_bits, check_width,
245 values.fill_style = FillStippled;
246 values.stipple = cw->checkbox.checkmark;
247 values.foreground = cw->label.foreground;
248 value_mask = GCFillStyle | GCStipple | GCForeground;
249 dynamic_mask = GCTileStipXOrigin | GCTileStipYOrigin;
250 dontcare_mask = GCLineWidth | GCLineStyle | GCCapStyle | GCJoinStyle |
251 GCFont | GCSubwindowMode | GCGraphicsExposures |
252 GCDashOffset | GCDashList | GCArcMode;
253 cw->checkbox.checkmark_GC =
254 XtAllocateGC(w, 0, value_mask, &values, dynamic_mask,
259 /* Function Name: CheckboxDestroy
260 * Description: Destroy Callback for checkbox widget.
261 * Arguments: w - the checkbox widget that is being destroyed.
262 * junk, garbage - not used.
269 CheckboxDestroy(Widget w, XtPointer junk, XtPointer garbage)
270 __attribute__((unused));
273 CheckboxDestroy(Widget w, XtPointer junk, XtPointer garbage)
276 CheckboxWidget cw = (CheckboxWidget) w;
278 /* TODO: cache this via xmu */
279 if (cw->checkbox.checkmark != None)
280 XFreePixmap(XtDisplay(w), cw->checkbox.checkmark);
281 if (cw->checkbox.checkmark_GC != None)
282 XtReleaseGC(w, cw->checkbox.checkmark_GC);
287 /************************************************************
291 ************************************************************/
294 static void CheckboxPress(Widget w, XEvent * event, String * params, /* unused */
295 Cardinal * num_params)
297 CheckboxWidget cw = (CheckboxWidget) w;
298 if (!cw->checkbox.pressed) {
299 cw->checkbox.pressed = TRUE;
300 ((CheckboxWidgetClass) (w->core.widget_class))->radio_class.
305 static void CheckboxUnpress(Widget w, XEvent * event, String * params, /* unused */
306 Cardinal * num_params)
308 CheckboxWidget cw = (CheckboxWidget) w;
311 if (cw->checkbox.pressed) {
312 cw->checkbox.pressed = FALSE;
313 if (*num_params > 0 && **params == 'd')
314 ((CheckboxWidgetClass) (w->core.widget_class))->
315 radio_class.drawDiamond(w);
320 /************************************************************
322 * Internal Procedures
324 ************************************************************/
326 static void DrawCheck(Widget w)
328 CheckboxWidget cw = (CheckboxWidget) w;
329 Display *dpy = XtDisplay(w);
330 Window win = XtWindow(w);
336 Dimension s = swid(cw);
337 Dimension bsz = bsize(cw);
338 Position bx, by; /* Check upper-left */
346 gc = XtIsSensitive(w) ? cw->command.normal_GC : cw->label.gray_GC;
349 bx = cw->label.internal_width;
350 by = cw->core.height / 2 - bh / 2;
353 if (!cw->command.set) {
354 top = cw->threeD.top_shadow_GC;
355 bot = cw->threeD.bot_shadow_GC;
357 top = cw->threeD.bot_shadow_GC;
358 bot = cw->threeD.top_shadow_GC;
360 ctr = cw->command.inverse_GC;
362 ctr = cw->command.set ? cw->command.normal_GC : cw->command.inverse_GC;
365 XFillRectangle(dpy, win, ctr, bx + s, by + s, bsz, bsz);
368 /* top-left shadow */
381 XFillPolygon(dpy, win, top, pts, 6, Nonconvex, CoordModePrevious);
382 /* bottom-right shadow */
395 XFillPolygon(dpy, win, bot, pts, 6, Nonconvex, CoordModePrevious);
398 XDrawRectangle(dpy, win, gc, bx + s, by + s, bsz, bsz);
402 if (cw->command.set && cw->checkbox.checkmark_GC != None) {
403 XSetTSOrigin(dpy, cw->checkbox.checkmark_GC, bx + s, by + s);
404 XFillRectangle(dpy, win, cw->checkbox.checkmark_GC,
405 bx + s, by + s, check_width, check_height);