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 /* by using the same size for the checkbox as for the diamond box,
43 * we can let the Radio widget do the vast majority of the work.
47 #define DRAW_CHECK 0 /* don't draw the check mark */
49 #define cclass(w) ((CheckboxWidgetClass)((w)->core.widget_class))
52 #define swid(cw) ((cw)->threeD.shadow_width)
54 #define swid(cw) ((cw)->core.border_width)
57 #define bsize(cw) (cclass(cw)->radio_class.dsize)
58 #define bs(cw) (bsize(cw) + 2*swid(cw))
61 #define check_width 14
62 #define check_height 14
63 static unsigned char check_bits[] = {
64 0x00, 0x00, 0x00, 0x20, 0x00, 0x18, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x03,
65 0x8c, 0x03, 0xde, 0x01, 0xff, 0x01, 0xfe, 0x00, 0xfc, 0x00, 0x78, 0x00,
66 0x70, 0x00, 0x20, 0x00
70 /****************************************************************
72 * Full class record constant
74 ****************************************************************/
77 static char defaultTranslations[] = "<EnterWindow>: highlight()\n\
78 <LeaveWindow>: unpress(draw) unhighlight()\n\
79 <Btn1Down>: press()\n\
80 <Btn1Down>,<Btn1Up>: unpress(nodraw) toggle() notify()";
83 #define offset(field) XtOffsetOf(CheckboxRec, field)
84 static XtResource resources[] = {
85 {XtNtristate, XtCTristate, XtRBoolean, sizeof(Boolean),
86 offset(checkbox.tristate), XtRImmediate, (XtPointer) FALSE}
91 /* Member functions */
93 static void CheckboxClassInit(void);
94 static void CheckboxInit(Widget, Widget, ArgList, Cardinal *);
96 static void CheckboxRealize(Widget, Mask *, XSetWindowAttributes *);
98 static void DrawCheck(Widget);
102 static void CheckboxPress(Widget, XEvent *, String *, Cardinal *);
103 static void CheckboxUnpress(Widget, XEvent *, String *, Cardinal *);
106 /* internal privates */
109 static XtActionsRec actionsList[] = {
110 {"press", CheckboxPress},
111 {"unpress", CheckboxUnpress},
115 #define SuperClass ((RadioWidgetClass)&radioClassRec)
117 CheckboxClassRec checkboxClassRec = {
119 (WidgetClass) SuperClass, /* superclass */
120 "Checkbox", /* class_name */
121 sizeof(CheckboxRec), /* size */
122 CheckboxClassInit, /* class_initialize */
123 NULL, /* class_part_initialize */
124 FALSE, /* class_inited */
125 CheckboxInit, /* initialize */
126 NULL, /* initialize_hook */
128 CheckboxRealize, /* realize */
129 actionsList, /* actions */
130 XtNumber(actionsList), /* num_actions */
132 XtInheritRealize, /* realize */
136 resources, /* resources */
137 XtNumber(resources), /* resource_count */
138 NULLQUARK, /* xrm_class */
139 TRUE, /* compress_motion */
140 TRUE, /* compress_exposure */
141 TRUE, /* compress_enterleave */
142 FALSE, /* visible_interest */
144 XtInheritResize, /* resize */
145 XtInheritExpose, /* expose */
146 NULL, /* set_values */
147 NULL, /* set_values_hook */
148 XtInheritSetValuesAlmost, /* set_values_almost */
149 NULL, /* get_values_hook */
150 NULL, /* accept_focus */
151 XtVersion, /* version */
152 NULL, /* callback_private */
154 defaultTranslations, /* tm_table */
156 XtInheritTranslations, /* tm_table */
158 XtInheritQueryGeometry, /* query_geometry */
159 XtInheritDisplayAccelerator, /* display_accelerator */
162 , /* CoreClass fields initialization */
164 XtInheritChangeSensitive /* change_sensitive */
166 , /* SimpleClass fields initialization */
169 XtInheritXaw3dShadowDraw /* field not used */
171 , /* ThreeDClass fields initialization */
174 0 /* field not used */
176 , /* LabelClass fields initialization */
178 0 /* field not used */
180 , /* CommandClass fields initialization */
182 RadioSet, /* Set Procedure. */
183 RadioUnset, /* Unset Procedure. */
184 NULL /* extension. */
186 , /* ToggleClass fields initialization */
189 DrawCheck, /* draw procedure */
190 NULL /* extension. */
192 , /* RadioClass fields initialization */
194 NULL /* extension. */
196 , /* CheckboxClass fields initialization */
199 /* for public consumption */
200 WidgetClass checkboxWidgetClass = (WidgetClass) & checkboxClassRec;
202 /****************************************************************
206 ****************************************************************/
208 static void CheckboxClassInit(void)
210 XawInitializeWidgetSet();
215 CheckboxInit(Widget request, Widget new, ArgList args, Cardinal * num_args)
218 CheckboxWidget cw = (CheckboxWidget) new;
219 cw->checkbox.checkmark = None;
220 cw->checkbox.checkmark_GC = None;
226 CheckboxRealize(Widget w, Mask * valueMask, XSetWindowAttributes * attributes)
228 CheckboxWidget cw = (CheckboxWidget) w;
229 XtGCMask value_mask, dynamic_mask, dontcare_mask;
232 /* first, call superclass realize */
233 (*checkboxWidgetClass->core_class.superclass->core_class.realize)
234 (w, valueMask, attributes);
236 /* TODO: cache this via xmu */
237 if (cw->checkbox.checkmark == None)
238 cw->checkbox.checkmark =
239 XCreateBitmapFromData(XtDisplay(w), XtWindow(w),
240 check_bits, check_width,
243 values.fill_style = FillStippled;
244 values.stipple = cw->checkbox.checkmark;
245 values.foreground = cw->label.foreground;
246 value_mask = GCFillStyle | GCStipple | GCForeground;
247 dynamic_mask = GCTileStipXOrigin | GCTileStipYOrigin;
248 dontcare_mask = GCLineWidth | GCLineStyle | GCCapStyle | GCJoinStyle |
249 GCFont | GCSubwindowMode | GCGraphicsExposures |
250 GCDashOffset | GCDashList | GCArcMode;
251 cw->checkbox.checkmark_GC =
252 XtAllocateGC(w, 0, value_mask, &values, dynamic_mask,
257 /* Function Name: CheckboxDestroy
258 * Description: Destroy Callback for checkbox widget.
259 * Arguments: w - the checkbox widget that is being destroyed.
260 * junk, garbage - not used.
267 CheckboxDestroy(Widget w, XtPointer junk, XtPointer garbage)
268 __attribute__((unused));
271 CheckboxDestroy(Widget w, XtPointer junk, XtPointer garbage)
274 CheckboxWidget cw = (CheckboxWidget) w;
276 /* TODO: cache this via xmu */
277 if (cw->checkbox.checkmark != None)
278 XFreePixmap(XtDisplay(w), cw->checkbox.checkmark);
279 if (cw->checkbox.checkmark_GC != None)
280 XtReleaseGC(w, cw->checkbox.checkmark_GC);
285 /************************************************************
289 ************************************************************/
292 static void CheckboxPress(Widget w, XEvent * event, String * params, /* unused */
293 Cardinal * num_params)
295 CheckboxWidget cw = (CheckboxWidget) w;
296 if (!cw->checkbox.pressed) {
297 cw->checkbox.pressed = TRUE;
298 ((CheckboxWidgetClass) (w->core.widget_class))->radio_class.
303 static void CheckboxUnpress(Widget w, XEvent * event, String * params, /* unused */
304 Cardinal * num_params)
306 CheckboxWidget cw = (CheckboxWidget) w;
309 if (cw->checkbox.pressed) {
310 cw->checkbox.pressed = FALSE;
311 if (*num_params > 0 && **params == 'd')
312 ((CheckboxWidgetClass) (w->core.widget_class))->
313 radio_class.drawDiamond(w);
318 /************************************************************
320 * Internal Procedures
322 ************************************************************/
324 static void DrawCheck(Widget w)
326 CheckboxWidget cw = (CheckboxWidget) w;
327 Display *dpy = XtDisplay(w);
328 Window win = XtWindow(w);
334 Dimension s = swid(cw);
335 Dimension bsz = bsize(cw);
336 Position bx, by; /* Check upper-left */
344 gc = XtIsSensitive(w) ? cw->command.normal_GC : cw->label.gray_GC;
347 bx = cw->label.internal_width;
348 by = cw->core.height / 2 - bh / 2;
351 if (!cw->command.set) {
352 top = cw->threeD.top_shadow_GC;
353 bot = cw->threeD.bot_shadow_GC;
355 top = cw->threeD.bot_shadow_GC;
356 bot = cw->threeD.top_shadow_GC;
358 ctr = cw->command.inverse_GC;
360 ctr = cw->command.set ? cw->command.normal_GC : cw->command.inverse_GC;
363 XFillRectangle(dpy, win, ctr, bx + s, by + s, bsz, bsz);
366 /* top-left shadow */
379 XFillPolygon(dpy, win, top, pts, 6, Nonconvex, CoordModePrevious);
380 /* bottom-right shadow */
393 XFillPolygon(dpy, win, bot, pts, 6, Nonconvex, CoordModePrevious);
395 XDrawRectangle(dpy, win, gc, bx + s, by + s, bsz, bsz);
399 if (cw->command.set && cw->checkbox.checkmark_GC != None) {
400 XSetTSOrigin(dpy, cw->checkbox.checkmark_GC, bx + s, by + s);
401 XFillRectangle(dpy, win, cw->checkbox.checkmark_GC,
402 bx + s, by + s, check_width, check_height);