Build Fix -- compatibility issue with newer autoconf
[sxemacs] / src / ui / lwlib / xlwcheckbox.c
1 /* Checkbox Widget for SXEmacs.
2    Copyright (C) 1999 Edward A. Falk
3
4 This file is part of SXEmacs.
5
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.
10
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.
15
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/>. */
18
19 /* Synched up with: Checkbox.c 1.1 */
20
21 /*
22  * Checkbox.c - Checkbox button widget
23  *
24  * Author: Edward A. Falk
25  *         falk@falconer.vip.best.com
26  *
27  * Date:   June 30, 1997
28  *
29  * Overview:  This widget is identical to the Radio widget in behavior,
30  * except that the button is square and has a check mark.
31  */
32
33 #include <config.h>
34 #include <stdio.h>
35
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"
41
42 #include "sxe-utils.h"
43
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.
46  */
47
48 #define BOX_SIZE        8
49 #define DRAW_CHECK      0       /* don't draw the check mark */
50
51 #define cclass(w)       ((CheckboxWidgetClass)((w)->core.widget_class))
52
53 #ifdef  _ThreeDP_h
54 #define swid(cw)        ((cw)->threeD.shadow_width)
55 #else
56 #define swid(cw)        ((cw)->core.border_width)
57 #endif
58
59 #define bsize(cw)       (cclass(cw)->radio_class.dsize)
60 #define bs(cw)          (bsize(cw) + 2*swid(cw))
61
62 #if     DRAW_CHECK
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
69 };
70 #endif
71
72 /****************************************************************
73  *
74  * Full class record constant
75  *
76  ****************************************************************/
77
78 #if DRAW_CHECK
79 static char defaultTranslations[] = "<EnterWindow>:     highlight()\n\
80      <LeaveWindow>:     unpress(draw) unhighlight()\n\
81      <Btn1Down>:        press()\n\
82      <Btn1Down>,<Btn1Up>:   unpress(nodraw) toggle() notify()";
83 #endif
84
85 #define offset(field)   XtOffsetOf(CheckboxRec, field)
86 static XtResource resources[] = {
87         {XtNtristate, XtCTristate, XtRBoolean, sizeof(Boolean),
88          offset(checkbox.tristate), XtRImmediate, (XtPointer) FALSE}
89         ,
90 };
91 #undef  offset
92
93         /* Member functions */
94
95 static void CheckboxClassInit(void);
96 static void CheckboxInit(Widget, Widget, ArgList, Cardinal *);
97 #if DRAW_CHECK
98 static void CheckboxRealize(Widget, Mask *, XSetWindowAttributes *);
99 #endif
100 static void DrawCheck(Widget);
101
102         /* Action procs */
103 #if DRAW_CHECK
104 static void CheckboxPress(Widget, XEvent *, String *, Cardinal *);
105 static void CheckboxUnpress(Widget, XEvent *, String *, Cardinal *);
106 #endif
107
108         /* internal privates */
109
110 #if DRAW_CHECK
111 static XtActionsRec actionsList[] = {
112         {"press", CheckboxPress},
113         {"unpress", CheckboxUnpress},
114 };
115 #endif
116
117 #define SuperClass ((RadioWidgetClass)&radioClassRec)
118
119 CheckboxClassRec checkboxClassRec = {
120         {
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      */
129 #if DRAW_CHECK
130          CheckboxRealize,       /* realize              */
131          actionsList,           /* actions              */
132          XtNumber(actionsList), /* num_actions          */
133 #else
134          XtInheritRealize,      /* realize              */
135          NULL,                  /* actions              */
136          0,                     /* num_actions          */
137 #endif
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     */
145          NULL,                  /* destroy              */
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     */
155 #if DRAW_CHECK
156          defaultTranslations,   /* tm_table             */
157 #else
158          XtInheritTranslations, /* tm_table             */
159 #endif
160          XtInheritQueryGeometry,        /* query_geometry       */
161          XtInheritDisplayAccelerator,   /* display_accelerator  */
162          NULL                   /* extension            */
163          }
164         ,                       /* CoreClass fields initialization */
165         {
166          XtInheritChangeSensitive       /* change_sensitive     */
167          }
168         ,                       /* SimpleClass fields initialization */
169 #ifdef  _ThreeDP_h
170         {
171          XtInheritXaw3dShadowDraw       /* field not used       */
172          }
173         ,                       /* ThreeDClass fields initialization */
174 #endif
175         {
176          0                      /* field not used     */
177          }
178         ,                       /* LabelClass fields initialization */
179         {
180          0                      /* field not used     */
181          }
182         ,                       /* CommandClass fields initialization */
183         {
184          RadioSet,              /* Set Procedure.       */
185          RadioUnset,            /* Unset Procedure.     */
186          NULL                   /* extension.           */
187          }
188         ,                       /* ToggleClass fields initialization */
189         {
190          BOX_SIZE,
191          DrawCheck,             /* draw procedure */
192          NULL                   /* extension. */
193          }
194         ,                       /* RadioClass fields initialization */
195         {
196          NULL                   /* extension. */
197          }
198         ,                       /* CheckboxClass fields initialization */
199 };
200
201   /* for public consumption */
202 WidgetClass checkboxWidgetClass = (WidgetClass) & checkboxClassRec;
203 \f
204 /****************************************************************
205  *
206  * Class Methods
207  *
208  ****************************************************************/
209
210 static void CheckboxClassInit(void)
211 {
212         XawInitializeWidgetSet();
213 }
214
215  /*ARGSUSED*/
216     static void
217 CheckboxInit(Widget request, Widget new, ArgList args, Cardinal * num_args)
218 {
219 #if DRAW_CHECK
220         CheckboxWidget cw = (CheckboxWidget) new;
221         cw->checkbox.checkmark = None;
222         cw->checkbox.checkmark_GC = None;
223 #endif
224 }
225
226 #if DRAW_CHECK
227 static void
228 CheckboxRealize(Widget w, Mask * valueMask, XSetWindowAttributes * attributes)
229 {
230         CheckboxWidget cw = (CheckboxWidget) w;
231         XtGCMask value_mask, dynamic_mask, dontcare_mask;
232         XGCValues values;
233
234         /* first, call superclass realize */
235         (*checkboxWidgetClass->core_class.superclass->core_class.realize)
236             (w, valueMask, attributes);
237
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,
243                                           check_height);
244
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,
255                          dontcare_mask);
256 }
257 #endif
258
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.
263  *      Returns: none.
264  */
265
266 /* ARGSUSED */
267 #if defined __GNUC__
268 static void
269 CheckboxDestroy(Widget w, XtPointer junk, XtPointer garbage)
270         __attribute__((unused));
271 #endif
272 static void
273 CheckboxDestroy(Widget w, XtPointer junk, XtPointer garbage)
274 {
275 #if DRAW_CHECK
276         CheckboxWidget cw = (CheckboxWidget) w;
277
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);
283 #endif
284 }
285 \f
286 #if DRAW_CHECK
287 /************************************************************
288  *
289  *  Actions Procedures
290  *
291  ************************************************************/
292
293 /* ARGSUSED */
294 static void CheckboxPress(Widget w, XEvent * event, String * params,    /* unused */
295                           Cardinal * num_params)
296 {                               /* unused */
297         CheckboxWidget cw = (CheckboxWidget) w;
298         if (!cw->checkbox.pressed) {
299                 cw->checkbox.pressed = TRUE;
300                 ((CheckboxWidgetClass) (w->core.widget_class))->radio_class.
301                     drawDiamond(w);
302         }
303 }
304
305 static void CheckboxUnpress(Widget w, XEvent * event, String * params,  /* unused */
306                             Cardinal * num_params)
307 {                               /* unused */
308         CheckboxWidget cw = (CheckboxWidget) w;
309         int i;
310
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);
316         }
317 }
318 #endif
319 \f
320 /************************************************************
321  *
322  *  Internal Procedures
323  *
324  ************************************************************/
325
326 static void DrawCheck(Widget w)
327 {
328         CheckboxWidget cw = (CheckboxWidget) w;
329         Display *dpy = XtDisplay(w);
330         Window win = XtWindow(w);
331         GC gc;
332
333 #ifdef  _ThreeDP_h
334         XPoint pts[6];
335 #endif
336         Dimension s = swid(cw);
337         Dimension bsz = bsize(cw);
338         Position bx, by;        /* Check upper-left */
339         Dimension bw, bh;
340 #ifdef  _ThreeDP_h
341         GC top, bot;
342 #endif
343         GC ctr;
344
345         /* foreground GC */
346         gc = XtIsSensitive(w) ? cw->command.normal_GC : cw->label.gray_GC;
347
348         bw = bh = bs(cw);
349         bx = cw->label.internal_width;
350         by = cw->core.height / 2 - bh / 2;
351
352 #ifdef  _ThreeDP_h
353         if (!cw->command.set) {
354                 top = cw->threeD.top_shadow_GC;
355                 bot = cw->threeD.bot_shadow_GC;
356         } else {
357                 top = cw->threeD.bot_shadow_GC;
358                 bot = cw->threeD.top_shadow_GC;
359         }
360         ctr = cw->command.inverse_GC;
361 #else
362         ctr = cw->command.set ? cw->command.normal_GC : cw->command.inverse_GC;
363 #endif
364
365         XFillRectangle(dpy, win, ctr, bx + s, by + s, bsz, bsz);
366
367 #ifdef  _ThreeDP_h
368         /* top-left shadow */
369         pts[0].x = bx;
370         pts[0].y = by;
371         pts[1].x = bw;
372         pts[1].y = 0;
373         pts[2].x = -s;
374         pts[2].y = s;
375         pts[3].x = -bsz;
376         pts[3].y = 0;
377         pts[4].x = 0;
378         pts[4].y = bsz;
379         pts[5].x = -s;
380         pts[5].y = s;
381         XFillPolygon(dpy, win, top, pts, 6, Nonconvex, CoordModePrevious);
382         /* bottom-right shadow */
383         pts[0].x = bx + bw;
384         pts[0].y = by + bh;
385         pts[1].x = -bw;
386         pts[1].y = 0;
387         pts[2].x = s;
388         pts[2].y = -s;
389         pts[3].x = bsz;
390         pts[3].y = 0;
391         pts[4].x = 0;
392         pts[4].y = -bsz;
393         pts[5].x = s;
394         pts[5].y = -s;
395         XFillPolygon(dpy, win, bot, pts, 6, Nonconvex, CoordModePrevious);
396 #else
397         SXE_SET_UNUSED(bw);
398         XDrawRectangle(dpy, win, gc, bx + s, by + s, bsz, bsz);
399 #endif
400
401 #if DRAW_CHECK
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);
406         }
407 #endif
408 }