424
+ − 1 /* Checkbox Widget for XEmacs.
+ − 2 Copyright (C) 1999 Edward A. Falk
+ − 3
+ − 4 This file is part of XEmacs.
+ − 5
+ − 6 XEmacs is free software; you can redistribute it and/or modify it
+ − 7 under the terms of the GNU General Public License as published by the
+ − 8 Free Software Foundation; either version 2, or (at your option) any
+ − 9 later version.
+ − 10
+ − 11 XEmacs is distributed in the hope that it will be useful, but WITHOUT
+ − 12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ − 13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ − 14 for more details.
+ − 15
+ − 16 You should have received a copy of the GNU General Public License
+ − 17 along with XEmacs; see the file COPYING. If not, write to
+ − 18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ − 19 Boston, MA 02111-1307, USA. */
+ − 20
+ − 21 /* Synched up with: Checkbox.c 1.1 */
+ − 22
+ − 23 /*
+ − 24 * Checkbox.c - Checkbox button widget
+ − 25 *
+ − 26 * Author: Edward A. Falk
+ − 27 * falk@falconer.vip.best.com
442
+ − 28 *
424
+ − 29 * Date: June 30, 1997
+ − 30 *
+ − 31 * Overview: This widget is identical to the Radio widget in behavior,
+ − 32 * except that the button is square and has a check mark.
+ − 33 */
+ − 34
+ − 35
+ − 36 #include <config.h>
+ − 37 #include <stdio.h>
+ − 38
+ − 39 #include <X11/IntrinsicP.h>
+ − 40 #include <X11/StringDefs.h>
442
+ − 41 #include ATHENA_XawInit_h_
424
+ − 42 #include "../src/xmu.h"
+ − 43 #include "xlwcheckboxP.h"
+ − 44
+ − 45
+ − 46 /* by using the same size for the checkbox as for the diamond box,
+ − 47 * we can let the Radio widget do the vast majority of the work.
+ − 48 */
+ − 49
+ − 50 #define BOX_SIZE 8
+ − 51 #define DRAW_CHECK 0 /* don't draw the check mark */
+ − 52
+ − 53 #define cclass(w) ((CheckboxWidgetClass)((w)->core.widget_class))
+ − 54
+ − 55 #ifdef _ThreeDP_h
+ − 56 #define swid(cw) ((cw)->threeD.shadow_width)
+ − 57 #else
+ − 58 #define swid(cw) ((cw)->core.border_width)
+ − 59 #endif
+ − 60
+ − 61 #define bsize(cw) (cclass(cw)->radio_class.dsize)
+ − 62 #define bs(cw) (bsize(cw) + 2*swid(cw))
+ − 63
+ − 64
+ − 65 #if DRAW_CHECK
+ − 66 #define check_width 14
+ − 67 #define check_height 14
458
+ − 68 static unsigned char check_bits[] = {
424
+ − 69 0x00, 0x00, 0x00, 0x20, 0x00, 0x18, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x03,
+ − 70 0x8c, 0x03, 0xde, 0x01, 0xff, 0x01, 0xfe, 0x00, 0xfc, 0x00, 0x78, 0x00,
+ − 71 0x70, 0x00, 0x20, 0x00};
+ − 72 #endif
+ − 73
+ − 74
+ − 75 /****************************************************************
+ − 76 *
+ − 77 * Full class record constant
+ − 78 *
+ − 79 ****************************************************************/
+ − 80
+ − 81
+ − 82 #if DRAW_CHECK
+ − 83 static char defaultTranslations[] =
+ − 84 "<EnterWindow>: highlight()\n\
+ − 85 <LeaveWindow>: unpress(draw) unhighlight()\n\
+ − 86 <Btn1Down>: press()\n\
+ − 87 <Btn1Down>,<Btn1Up>: unpress(nodraw) toggle() notify()";
+ − 88 #endif
+ − 89
+ − 90
+ − 91
+ − 92 #define offset(field) XtOffsetOf(CheckboxRec, field)
+ − 93 static XtResource resources[] = {
+ − 94 {XtNtristate, XtCTristate, XtRBoolean, sizeof(Boolean),
+ − 95 offset(checkbox.tristate), XtRImmediate, (XtPointer)FALSE},
+ − 96 } ;
+ − 97 #undef offset
+ − 98
+ − 99 /* Member functions */
+ − 100
+ − 101 static void CheckboxClassInit (void);
+ − 102 static void CheckboxInit (Widget, Widget, ArgList, Cardinal *);
+ − 103 #if DRAW_CHECK
+ − 104 static void CheckboxRealize (Widget, Mask *, XSetWindowAttributes *);
+ − 105 #endif
+ − 106 static void DrawCheck (Widget);
+ − 107
+ − 108
+ − 109 /* Action procs */
+ − 110 #if DRAW_CHECK
+ − 111 static void CheckboxPress (Widget, XEvent *, String *, Cardinal *);
+ − 112 static void CheckboxUnpress (Widget, XEvent *, String *, Cardinal *);
+ − 113 #endif
+ − 114
+ − 115 /* internal privates */
+ − 116
+ − 117 #if DRAW_CHECK
+ − 118 static XtActionsRec actionsList[] =
+ − 119 {
+ − 120 {"press", CheckboxPress},
+ − 121 {"unpress", CheckboxUnpress},
+ − 122 } ;
+ − 123 #endif
+ − 124
+ − 125 #define SuperClass ((RadioWidgetClass)&radioClassRec)
+ − 126
+ − 127 CheckboxClassRec checkboxClassRec = {
+ − 128 {
442
+ − 129 (WidgetClass) SuperClass, /* superclass */
424
+ − 130 "Checkbox", /* class_name */
+ − 131 sizeof(CheckboxRec), /* size */
+ − 132 CheckboxClassInit, /* class_initialize */
+ − 133 NULL, /* class_part_initialize */
+ − 134 FALSE, /* class_inited */
+ − 135 CheckboxInit, /* initialize */
+ − 136 NULL, /* initialize_hook */
+ − 137 #if DRAW_CHECK
+ − 138 CheckboxRealize, /* realize */
+ − 139 actionsList, /* actions */
+ − 140 XtNumber(actionsList), /* num_actions */
+ − 141 #else
+ − 142 XtInheritRealize, /* realize */
+ − 143 NULL, /* actions */
+ − 144 0, /* num_actions */
+ − 145 #endif
+ − 146 resources, /* resources */
+ − 147 XtNumber(resources), /* resource_count */
+ − 148 NULLQUARK, /* xrm_class */
+ − 149 TRUE, /* compress_motion */
+ − 150 TRUE, /* compress_exposure */
+ − 151 TRUE, /* compress_enterleave */
+ − 152 FALSE, /* visible_interest */
+ − 153 NULL, /* destroy */
+ − 154 XtInheritResize, /* resize */
+ − 155 XtInheritExpose, /* expose */
+ − 156 NULL, /* set_values */
+ − 157 NULL, /* set_values_hook */
+ − 158 XtInheritSetValuesAlmost, /* set_values_almost */
+ − 159 NULL, /* get_values_hook */
+ − 160 NULL, /* accept_focus */
+ − 161 XtVersion, /* version */
+ − 162 NULL, /* callback_private */
+ − 163 #if DRAW_CHECK
+ − 164 defaultTranslations, /* tm_table */
+ − 165 #else
+ − 166 XtInheritTranslations, /* tm_table */
+ − 167 #endif
+ − 168 XtInheritQueryGeometry, /* query_geometry */
+ − 169 XtInheritDisplayAccelerator, /* display_accelerator */
+ − 170 NULL /* extension */
+ − 171 }, /* CoreClass fields initialization */
+ − 172 {
442
+ − 173 XtInheritChangeSensitive /* change_sensitive */
424
+ − 174 }, /* SimpleClass fields initialization */
+ − 175 #ifdef _ThreeDP_h
+ − 176 {
+ − 177 XtInheritXaw3dShadowDraw /* field not used */
+ − 178 }, /* ThreeDClass fields initialization */
+ − 179 #endif
+ − 180 {
+ − 181 0 /* field not used */
+ − 182 }, /* LabelClass fields initialization */
+ − 183 {
+ − 184 0 /* field not used */
+ − 185 }, /* CommandClass fields initialization */
+ − 186 {
+ − 187 RadioSet, /* Set Procedure. */
+ − 188 RadioUnset, /* Unset Procedure. */
+ − 189 NULL /* extension. */
+ − 190 }, /* ToggleClass fields initialization */
+ − 191 {
+ − 192 BOX_SIZE,
+ − 193 DrawCheck, /* draw procedure */
+ − 194 NULL /* extension. */
+ − 195 }, /* RadioClass fields initialization */
+ − 196 {
+ − 197 NULL /* extension. */
+ − 198 }, /* CheckboxClass fields initialization */
+ − 199 };
+ − 200
+ − 201 /* for public consumption */
+ − 202 WidgetClass checkboxWidgetClass = (WidgetClass) &checkboxClassRec;
+ − 203
+ − 204
+ − 205
+ − 206
+ − 207
+ − 208
+ − 209 /****************************************************************
+ − 210 *
+ − 211 * Class Methods
+ − 212 *
+ − 213 ****************************************************************/
+ − 214
+ − 215 static void
+ − 216 CheckboxClassInit (void)
+ − 217 {
+ − 218 XawInitializeWidgetSet();
+ − 219 }
+ − 220
+ − 221
+ − 222 /*ARGSUSED*/
+ − 223 static void
2286
+ − 224 CheckboxInit (Widget UNUSED (request),
+ − 225 #if DRAW_CHECK
424
+ − 226 Widget new,
2286
+ − 227 #else
+ − 228 Widget UNUSED (new),
+ − 229 #endif
+ − 230 ArgList UNUSED (args),
+ − 231 Cardinal *UNUSED (num_args))
424
+ − 232 {
+ − 233 #if DRAW_CHECK
+ − 234 CheckboxWidget cw = (CheckboxWidget) new;
+ − 235 cw->checkbox.checkmark = None ;
+ − 236 cw->checkbox.checkmark_GC = None ;
+ − 237 #endif
+ − 238 }
+ − 239
+ − 240
+ − 241 #if DRAW_CHECK
+ − 242 static void
+ − 243 CheckboxRealize(Widget w,
+ − 244 Mask *valueMask,
+ − 245 XSetWindowAttributes *attributes)
+ − 246 {
+ − 247 CheckboxWidget cw = (CheckboxWidget) w;
+ − 248 XtGCMask value_mask, dynamic_mask, dontcare_mask ;
+ − 249 XGCValues values ;
+ − 250
+ − 251 /* first, call superclass realize */
+ − 252 (*checkboxWidgetClass->core_class.superclass->core_class.realize)
+ − 253 (w, valueMask, attributes);
+ − 254
+ − 255 /* TODO: cache this via xmu */
+ − 256 if( cw->checkbox.checkmark == None )
+ − 257 cw->checkbox.checkmark =
+ − 258 XCreateBitmapFromData( XtDisplay(w), XtWindow(w),
+ − 259 check_bits,check_width,check_height);
+ − 260
+ − 261 values.fill_style = FillStippled ;
+ − 262 values.stipple = cw->checkbox.checkmark ;
+ − 263 values.foreground = cw->label.foreground ;
+ − 264 value_mask = GCFillStyle | GCStipple | GCForeground ;
+ − 265 dynamic_mask = GCTileStipXOrigin | GCTileStipYOrigin ;
+ − 266 dontcare_mask = GCLineWidth | GCLineStyle | GCCapStyle | GCJoinStyle |
+ − 267 GCFont | GCSubwindowMode | GCGraphicsExposures |
+ − 268 GCDashOffset | GCDashList | GCArcMode ;
+ − 269 cw->checkbox.checkmark_GC =
+ − 270 XtAllocateGC(w, 0, value_mask, &values, dynamic_mask, dontcare_mask) ;
+ − 271 }
+ − 272 #endif
+ − 273
+ − 274
+ − 275 /* Function Name: CheckboxDestroy
+ − 276 * Description: Destroy Callback for checkbox widget.
+ − 277 * Arguments: w - the checkbox widget that is being destroyed.
442
+ − 278 * junk, garbage - not used.
424
+ − 279 * Returns: none.
+ − 280 */
+ − 281
+ − 282 /* ARGSUSED */
+ − 283 static void
2286
+ − 284 CheckboxDestroy (
+ − 285 #if DRAW_CHECK
+ − 286 Widget w,
+ − 287 #else
+ − 288 Widget UNUSED (w),
+ − 289 #endif
+ − 290 XtPointer UNUSED (junk),
+ − 291 XtPointer UNUSED (garbage))
424
+ − 292 {
+ − 293 #if DRAW_CHECK
+ − 294 CheckboxWidget cw = (CheckboxWidget) w;
+ − 295
+ − 296 /* TODO: cache this via xmu */
+ − 297 if( cw->checkbox.checkmark != None )
+ − 298 XFreePixmap( XtDisplay(w), cw->checkbox.checkmark ) ;
+ − 299 if( cw->checkbox.checkmark_GC != None )
+ − 300 XtReleaseGC(w, cw->checkbox.checkmark_GC) ;
+ − 301 #endif
+ − 302 }
+ − 303
+ − 304
+ − 305
+ − 306 #if DRAW_CHECK
+ − 307 /************************************************************
+ − 308 *
+ − 309 * Actions Procedures
+ − 310 *
+ − 311 ************************************************************/
+ − 312
+ − 313 /* ARGSUSED */
+ − 314 static void
+ − 315 CheckboxPress (Widget w,
+ − 316 XEvent *event,
+ − 317 String *params, /* unused */
+ − 318 Cardinal *num_params) /* unused */
+ − 319 {
+ − 320 CheckboxWidget cw = (CheckboxWidget) w ;
+ − 321 if( !cw->checkbox.pressed ) {
+ − 322 cw->checkbox.pressed = TRUE ;
+ − 323 ((CheckboxWidgetClass)(w->core.widget_class))->radio_class.drawDiamond(w) ;
+ − 324 }
+ − 325 }
+ − 326
+ − 327 static void
+ − 328 CheckboxUnpress (Widget w,
+ − 329 XEvent *event,
+ − 330 String *params, /* unused */
+ − 331 Cardinal *num_params) /* unused */
+ − 332 {
+ − 333 CheckboxWidget cw = (CheckboxWidget) w ;
+ − 334 int i ;
+ − 335
+ − 336 if( cw->checkbox.pressed ) {
+ − 337 cw->checkbox.pressed = FALSE ;
+ − 338 if( *num_params > 0 && **params == 'd' )
+ − 339 ((CheckboxWidgetClass)(w->core.widget_class))->radio_class.drawDiamond(w);
+ − 340 }
+ − 341 }
+ − 342 #endif
+ − 343
+ − 344
+ − 345
+ − 346
+ − 347
+ − 348 /************************************************************
+ − 349 *
+ − 350 * Internal Procedures
+ − 351 *
+ − 352 ************************************************************/
+ − 353
+ − 354 static void
+ − 355 DrawCheck (Widget w)
+ − 356 {
+ − 357 CheckboxWidget cw = (CheckboxWidget) w ;
+ − 358 Display *dpy = XtDisplay(w) ;
+ − 359 Window win = XtWindow(w) ;
+ − 360 GC gc ;
+ − 361
+ − 362 #ifdef _ThreeDP_h
+ − 363 XPoint pts[6] ;
+ − 364 #endif
+ − 365 Dimension s = swid(cw);
+ − 366 Dimension bsz = bsize(cw);
+ − 367 Position bx,by ; /* Check upper-left */
2286
+ − 368 Dimension bh ;
424
+ − 369 #ifdef _ThreeDP_h
2286
+ − 370 Dimension bw;
424
+ − 371 GC top, bot;
+ − 372 #endif
+ − 373 GC ctr ;
+ − 374
+ − 375 /* foreground GC */
+ − 376 gc = XtIsSensitive(w) ? cw->command.normal_GC : cw->label.gray_GC ;
+ − 377
2286
+ − 378 bh = bs(cw) ;
424
+ − 379 bx = cw->label.internal_width ;
+ − 380 by = cw->core.height/2 - bh/2 ;
+ − 381
+ − 382 #ifdef _ThreeDP_h
2286
+ − 383 bw = bh ;
+ − 384
424
+ − 385 if( !cw->command.set ) {
+ − 386 top = cw->threeD.top_shadow_GC ;
+ − 387 bot = cw->threeD.bot_shadow_GC ;
+ − 388 } else {
+ − 389 top = cw->threeD.bot_shadow_GC ;
+ − 390 bot = cw->threeD.top_shadow_GC ;
+ − 391 }
+ − 392 ctr = cw->command.inverse_GC ;
+ − 393 #else
+ − 394 ctr = cw->command.set ? cw->command.normal_GC : cw->command.inverse_GC ;
+ − 395 #endif
+ − 396
+ − 397 XFillRectangle(dpy,win,ctr, bx+s,by+s, bsz,bsz) ;
+ − 398
+ − 399 #ifdef _ThreeDP_h
+ − 400 /* top-left shadow */
+ − 401 pts[0].x = bx ; pts[0].y = by ;
+ − 402 pts[1].x = bw ; pts[1].y = 0 ;
+ − 403 pts[2].x = -s ; pts[2].y = s ;
+ − 404 pts[3].x = -bsz ; pts[3].y = 0 ;
+ − 405 pts[4].x = 0 ; pts[4].y = bsz ;
+ − 406 pts[5].x = -s ; pts[5].y = s ;
+ − 407 XFillPolygon(dpy,win,top, pts,6, Nonconvex,CoordModePrevious) ;
+ − 408 /* bottom-right shadow */
+ − 409 pts[0].x = bx+bw ; pts[0].y = by+bh ;
+ − 410 pts[1].x = -bw ; pts[1].y = 0 ;
+ − 411 pts[2].x = s ; pts[2].y = -s ;
+ − 412 pts[3].x = bsz ; pts[3].y = 0 ;
+ − 413 pts[4].x = 0 ; pts[4].y = -bsz ;
+ − 414 pts[5].x = s ; pts[5].y = -s ;
+ − 415 XFillPolygon(dpy,win,bot, pts,6, Nonconvex,CoordModePrevious) ;
+ − 416 #else
+ − 417 XDrawRectangle(dpy,win,gc, bx+s,by+s, bsz,bsz) ;
+ − 418 #endif
+ − 419
+ − 420 #if DRAW_CHECK
+ − 421 if( cw->command.set && cw->checkbox.checkmark_GC != None ) {
+ − 422 XSetTSOrigin(dpy,cw->checkbox.checkmark_GC, bx+s, by+s) ;
+ − 423 XFillRectangle(dpy,win,cw->checkbox.checkmark_GC,
+ − 424 bx+s, by+s, check_width,check_height) ;
+ − 425 }
+ − 426 #endif
+ − 427 }