424
+ − 1 /* Radio 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: Radio.c 1.1 */
+ − 22
+ − 23 /*
+ − 24 * Radio.c - Radio button widget
+ − 25 *
+ − 26 * Author: Edward A. Falk
+ − 27 * falk@falconer.vip.best.com
442
+ − 28 *
424
+ − 29 * Date: June 30, 1997
+ − 30 *
+ − 31 *
+ − 32 * Overview: This widget is identical to the Toggle widget in behavior,
+ − 33 * but completely different in appearance. This widget looks like a small
+ − 34 * diamond-shaped button with a label to the right.
+ − 35 *
+ − 36 * To make this work, we subclass the Toggle widget to inherit its behavior
+ − 37 * and to inherit the label-drawing function from which Toggle is
+ − 38 * subclassed. We then completely replace the Expose, Set, Unset
+ − 39 * and Highlight member functions.
+ − 40 *
+ − 41 * The Set and Unset actions are slightly unorthodox. In Toggle's
+ − 42 * ClassInit function, Toggle searches the Command actions list and
+ − 43 * "steals" the Set and Unset functions, caching pointers to them in its
+ − 44 * class record. It then calls these functions from its own ToggleSet
+ − 45 * and Toggle actions.
+ − 46 *
+ − 47 * We, in turn, override the Set() and Unset() actions in our own ClassRec.
+ − 48 */
+ − 49
+ − 50
+ − 51 #include <config.h>
+ − 52 #include <stdio.h>
+ − 53
+ − 54 #include <X11/IntrinsicP.h>
+ − 55 #include <X11/StringDefs.h>
442
+ − 56 #include ATHENA_XawInit_h_
424
+ − 57 #include "../src/xmu.h"
+ − 58 #include "xlwradioP.h"
+ − 59
+ − 60 #define BOX_SIZE 13
+ − 61
+ − 62 #define rclass(w) ((RadioWidgetClass)((w)->core.widget_class))
+ − 63
+ − 64
+ − 65 #ifdef _ThreeDP_h
+ − 66 #define swid(rw) ((rw)->threeD.shadow_width)
+ − 67 #else
+ − 68 #define swid(rw) ((rw)->core.border_width)
+ − 69 #endif
+ − 70
+ − 71 #define bsize(rw) (rclass(rw)->radio_class.dsize)
+ − 72 #define bs(rw) (bsize(rw) + 2*swid(rw))
+ − 73
+ − 74
+ − 75
+ − 76 /****************************************************************
+ − 77 *
+ − 78 * Full class record constant
+ − 79 *
+ − 80 ****************************************************************/
+ − 81
+ − 82 /* The translations table from Toggle do not need to be
+ − 83 * overridden by Radio
+ − 84 */
+ − 85
+ − 86
+ − 87 /* Member functions */
+ − 88
+ − 89 static void RadioInit (Widget, Widget, ArgList, Cardinal *);
+ − 90 static void RadioExpose (Widget, XEvent *, Region);
+ − 91 static void RadioResize (Widget);
+ − 92 static void RadioClassInit (void);
+ − 93 static void RadioClassPartInit (WidgetClass);
+ − 94 static Boolean RadioSetValues (Widget, Widget, Widget, ArgList, Cardinal *);
+ − 95 static void DrawDiamond (Widget);
+ − 96 static XtGeometryResult RadioQueryGeometry (Widget, XtWidgetGeometry *,
+ − 97 XtWidgetGeometry *);
3072
+ − 98 #if 0
+ − 99 /* #### This function isn't used and is slated for destruction.
+ − 100 Can we just nuke it? */
+ − 101 static void RadioDestroy (Widget, XtPointer, XtPointer);
+ − 102 #endif
424
+ − 103
+ − 104 /* Action procs */
+ − 105
+ − 106 static void RadioHighlight (Widget, XEvent *, String *, Cardinal *);
+ − 107 static void RadioUnhighlight (Widget, XEvent *, String *, Cardinal *);
+ − 108
+ − 109 /* internal privates */
+ − 110
+ − 111 static void RadioSize (RadioWidget, Dimension *, Dimension *);
+ − 112
+ − 113 /* The actions table from Toggle is almost perfect, but we need
+ − 114 * to override Highlight, Set, and Unset.
+ − 115 */
+ − 116
+ − 117 static XtActionsRec actionsList[] =
+ − 118 {
+ − 119 {"highlight", RadioHighlight},
+ − 120 {"unhighlight", RadioUnhighlight},
+ − 121 };
+ − 122
+ − 123 #define SuperClass ((ToggleWidgetClass)&toggleClassRec)
+ − 124
+ − 125 RadioClassRec radioClassRec = {
+ − 126 {
442
+ − 127 (WidgetClass) SuperClass, /* superclass */
424
+ − 128 "Radio", /* class_name */
+ − 129 sizeof(RadioRec), /* size */
+ − 130 RadioClassInit, /* class_initialize */
+ − 131 RadioClassPartInit, /* class_part_initialize */
+ − 132 FALSE, /* class_inited */
+ − 133 RadioInit, /* initialize */
+ − 134 NULL, /* initialize_hook */
+ − 135 XtInheritRealize, /* realize */
+ − 136 actionsList, /* actions */
+ − 137 XtNumber(actionsList), /* num_actions */
+ − 138 NULL, /* resources */
+ − 139 0, /* 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 RadioResize, /* resize */
+ − 147 RadioExpose, /* expose */
+ − 148 RadioSetValues, /* 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 XtInheritTranslations, /* tm_table */
+ − 156 RadioQueryGeometry, /* query_geometry */
+ − 157 XtInheritDisplayAccelerator, /* display_accelerator */
+ − 158 NULL /* extension */
+ − 159 }, /* CoreClass fields initialization */
+ − 160 {
442
+ − 161 XtInheritChangeSensitive /* change_sensitive */
424
+ − 162 }, /* SimpleClass fields initialization */
+ − 163 #ifdef _ThreeDP_h
+ − 164 {
+ − 165 XtInheritXaw3dShadowDraw /* field not used */
+ − 166 }, /* ThreeDClass fields initialization */
+ − 167 #endif
+ − 168 {
+ − 169 0 /* field not used */
+ − 170 }, /* LabelClass fields initialization */
+ − 171 {
+ − 172 0 /* field not used */
+ − 173 }, /* CommandClass fields initialization */
+ − 174 {
+ − 175 RadioSet, /* Set Procedure. */
+ − 176 RadioUnset, /* Unset Procedure. */
+ − 177 NULL /* extension. */
+ − 178 }, /* ToggleClass fields initialization */
+ − 179 {
+ − 180 BOX_SIZE,
+ − 181 DrawDiamond, /* draw procedure */
+ − 182 NULL /* extension. */
+ − 183 } /* RadioClass fields initialization */
+ − 184 };
+ − 185
+ − 186 /* for public consumption */
+ − 187 WidgetClass radioWidgetClass = (WidgetClass) &radioClassRec;
+ − 188
+ − 189
+ − 190
+ − 191
+ − 192
+ − 193
+ − 194 /****************************************************************
+ − 195 *
+ − 196 * Class Methods
+ − 197 *
+ − 198 ****************************************************************/
+ − 199
+ − 200 static void
+ − 201 RadioClassInit (void)
+ − 202 {
+ − 203 XawInitializeWidgetSet();
+ − 204 }
+ − 205
+ − 206 static void
1201
+ − 207 RadioClassPartInit (WidgetClass class_)
424
+ − 208 {
1201
+ − 209 RadioWidgetClass c = (RadioWidgetClass) class_ ;
424
+ − 210 RadioWidgetClass super = (RadioWidgetClass)c->core_class.superclass ;
+ − 211
+ − 212 if( c->radio_class.drawDiamond == NULL ||
+ − 213 c->radio_class.drawDiamond == XtInheritDrawDiamond )
+ − 214 {
+ − 215 c->radio_class.drawDiamond = super->radio_class.drawDiamond ;
+ − 216 }
+ − 217 }
+ − 218
+ − 219
+ − 220
+ − 221
+ − 222 /*ARGSUSED*/
+ − 223 static void
+ − 224 RadioInit (Widget request,
3055
+ − 225 Widget new_,
2286
+ − 226 ArgList UNUSED (args),
+ − 227 Cardinal *UNUSED (num_args))
424
+ − 228 {
3055
+ − 229 RadioWidget rw = (RadioWidget) new_;
424
+ − 230 RadioWidget rw_req = (RadioWidget) request;
+ − 231 Dimension w,h ;
+ − 232
+ − 233 /* Select initial size for the widget */
+ − 234 if( rw_req->core.width == 0 || rw_req->core.height == 0 )
+ − 235 {
+ − 236 RadioSize(rw, &w,&h) ;
+ − 237 if( rw_req->core.width == 0 )
+ − 238 rw->core.width = w ;
+ − 239 if( rw_req->core.height == 0 )
+ − 240 rw->core.height = h ;
3055
+ − 241 rw->core.widget_class->core_class.resize(new_) ;
424
+ − 242 }
+ − 243 }
+ − 244
+ − 245 /* Function Name: RadioDestroy
+ − 246 * Description: Destroy Callback for radio widget.
+ − 247 * Arguments: w - the radio widget that is being destroyed.
442
+ − 248 * junk, garbage - not used.
424
+ − 249 * Returns: none.
+ − 250 */
+ − 251
3072
+ − 252 #if 0
+ − 253 /* #### This function isn't used and is slated for destruction.
+ − 254 Can we just nuke it? */
424
+ − 255 /* ARGSUSED */
+ − 256 static void
2286
+ − 257 RadioDestroy (Widget UNUSED (w),
+ − 258 XtPointer UNUSED (junk),
+ − 259 XtPointer UNUSED (garbage))
424
+ − 260 {
+ − 261 /* TODO: get rid of this */
+ − 262 }
3072
+ − 263 #endif
424
+ − 264
+ − 265 /* React to size change from manager. Label widget will compute some internal
+ − 266 * stuff, but we need to override. This code requires knowledge of the
+ − 267 * internals of the Label widget.
+ − 268 */
+ − 269
+ − 270 static void
+ − 271 RadioResize (Widget w)
+ − 272 {
+ − 273 RadioWidget rw = (RadioWidget)w ;
+ − 274
+ − 275 /* call parent resize proc */
+ − 276 SuperClass->core_class.resize(w) ;
+ − 277
+ − 278 /* override label offset */
+ − 279
+ − 280 switch( rw->label.justify ) {
+ − 281 case XtJustifyLeft:
442
+ − 282 rw->label.label_x += (bs(rw) + rw->label.internal_width) ;
424
+ − 283 break ;
+ − 284 case XtJustifyRight:
+ − 285 break ;
+ − 286 case XtJustifyCenter:
+ − 287 default:
442
+ − 288 rw->label.label_x += (bs(rw) + rw->label.internal_width)/2;
424
+ − 289 break ;
+ − 290 }
+ − 291 }
+ − 292
+ − 293
+ − 294 /*
+ − 295 * Repaint the widget window.
+ − 296 */
+ − 297
+ − 298 static void
+ − 299 RadioExpose (Widget w,
+ − 300 XEvent *event,
+ − 301 Region region)
+ − 302 {
+ − 303 RadioWidget rw = (RadioWidget) w ;
+ − 304 Display *dpy = XtDisplay(w) ;
+ − 305 Window win = XtWindow(w) ;
+ − 306 GC gc ;
+ − 307 Pixmap left_bitmap ;
+ − 308 extern WidgetClass labelWidgetClass ;
+ − 309
+ − 310 /* Note: the Label widget examines the region to decide if anything
+ − 311 * needs to be drawn. I'm not sure that this is worth the effort,
+ − 312 * but it bears thinking on.
+ − 313 */
+ − 314
+ − 315 /* Let label widget draw the label. If there was an lbm_x
+ − 316 * field, we could let Label draw the bitmap too. But there
+ − 317 * isn't, so we need to temporarily remove the bitmap and
+ − 318 * draw it ourself later.
+ − 319 */
+ − 320 left_bitmap = rw->label.left_bitmap ;
+ − 321 rw->label.left_bitmap = None ;
+ − 322 labelWidgetClass->core_class.expose(w,event,region) ;
+ − 323 rw->label.left_bitmap = left_bitmap ;
+ − 324
+ − 325 /* now manually draw the left bitmap. TODO: 3-d look, xaw-xpm */
+ − 326 gc = XtIsSensitive(w) ? rw->label.normal_GC : rw->label.gray_GC ;
+ − 327 if( left_bitmap != None && rw->label.lbm_width > 0 )
+ − 328 {
+ − 329 /* TODO: handle pixmaps */
+ − 330 XCopyPlane(dpy, left_bitmap, win, gc,
458
+ − 331 0,0, rw->label.lbm_width, rw->label.lbm_height,
+ − 332 (int) rw->label.internal_width*2 + bs(rw),
+ − 333 (int) rw->label.internal_height + rw->label.lbm_y,
+ − 334 1UL) ;
424
+ − 335 }
+ − 336
+ − 337 /* Finally, the button itself */
+ − 338 ((RadioWidgetClass)(w->core.widget_class))->radio_class.drawDiamond(w) ;
+ − 339 }
+ − 340
+ − 341
+ − 342
+ − 343
+ − 344 /************************************************************
+ − 345 *
+ − 346 * Set specified arguments into widget
+ − 347 *
+ − 348 ***********************************************************/
+ − 349
+ − 350
+ − 351 /* ARGSUSED */
+ − 352 static Boolean
+ − 353 RadioSetValues (Widget current,
2286
+ − 354 Widget UNUSED (request),
3055
+ − 355 Widget new_,
2286
+ − 356 ArgList UNUSED (args),
+ − 357 Cardinal *UNUSED (num_args))
424
+ − 358 {
+ − 359 RadioWidget oldrw = (RadioWidget) current;
3055
+ − 360 RadioWidget newrw = (RadioWidget) new_;
424
+ − 361
+ − 362 /* Need to find out if the size of the widget changed. Set new size
+ − 363 * if it did and resize is permitted. One way to determine of the
+ − 364 * widget changed size would be to scan the args list. Another way
+ − 365 * is to compare the old and new widgets and see if any of several
+ − 366 * size-related fields have been changed. The Label widget chose the
+ − 367 * former method, but I choose the latter.
+ − 368 */
+ − 369
+ − 370 if( newrw->label.resize &&
+ − 371 ( newrw->core.width != oldrw->core.width ||
+ − 372 newrw->core.height != oldrw->core.height ||
+ − 373 newrw->core.border_width != oldrw->core.border_width ) )
+ − 374 {
+ − 375 RadioSize(newrw, &newrw->core.width, &newrw->core.height) ;
+ − 376 }
+ − 377
442
+ − 378 /* The label set values routine can resize the widget. We need to
+ − 379 * recalculate if this is true.
+ − 380 */
+ − 381 if (newrw->label.label_x != oldrw->label.label_x)
+ − 382 {
3055
+ − 383 RadioResize (new_);
442
+ − 384 }
424
+ − 385 return FALSE ;
+ − 386 }
+ − 387
+ − 388 static XtGeometryResult
+ − 389 RadioQueryGeometry (Widget w,
+ − 390 XtWidgetGeometry *intended,
+ − 391 XtWidgetGeometry *preferred)
+ − 392 {
+ − 393 RadioWidget rw = (RadioWidget) w;
+ − 394
+ − 395 preferred->request_mode = CWWidth | CWHeight;
+ − 396 RadioSize(rw, &preferred->width, &preferred->height) ;
+ − 397
+ − 398 if ( ((intended->request_mode & (CWWidth | CWHeight))
+ − 399 == (CWWidth | CWHeight)) &&
+ − 400 intended->width == preferred->width &&
+ − 401 intended->height == preferred->height)
+ − 402 return XtGeometryYes;
+ − 403 else if (preferred->width == w->core.width &&
+ − 404 preferred->height == w->core.height)
+ − 405 return XtGeometryNo;
+ − 406 else
+ − 407 return XtGeometryAlmost;
+ − 408 }
+ − 409
+ − 410
+ − 411
+ − 412
+ − 413
+ − 414 /************************************************************
+ − 415 *
+ − 416 * Action Procedures
+ − 417 *
+ − 418 ************************************************************/
+ − 419
+ − 420 /*
+ − 421 * Draw the highlight border around the widget. The Command widget
+ − 422 * did this by drawing through a mask. We do it by just drawing the
+ − 423 * border.
+ − 424 */
+ − 425
442
+ − 426 static void
424
+ − 427 DrawHighlight (Widget w,
+ − 428 GC gc)
+ − 429 {
+ − 430 RadioWidget rw = (RadioWidget)w;
+ − 431 XRectangle rects[4] ;
+ − 432 Dimension ht = rw->command.highlight_thickness ;
+ − 433
+ − 434 if( ht <= 0 ||
+ − 435 ht > rw->core.width/2 ||
+ − 436 ht > rw->core.height/2 )
+ − 437 return ;
+ − 438
+ − 439 if( ! XtIsRealized(w) )
+ − 440 return ;
+ − 441
+ − 442 rects[0].x = 0 ; rects[0].y = 0 ;
+ − 443 rects[0].width = rw->core.width ; rects[0].height = ht ;
+ − 444 rects[1].x = 0 ; rects[1].y = rw->core.height - ht ;
+ − 445 rects[1].width = rw->core.width ; rects[1].height = ht ;
+ − 446 rects[2].x = 0 ; rects[2].y = ht ;
+ − 447 rects[2].width = ht ; rects[2].height = rw->core.height - ht*2 ;
+ − 448 rects[3].x = rw->core.width - ht ; rects[3].y = ht ;
+ − 449 rects[3].width = ht ; rects[3].height = rw->core.height - ht*2 ;
+ − 450 XFillRectangles( XtDisplay(w), XtWindow(w), gc, rects, 4) ;
+ − 451 }
+ − 452
+ − 453 static void
+ − 454 RadioHighlight (Widget w,
2286
+ − 455 XEvent *UNUSED (event),
+ − 456 String *UNUSED (params),
+ − 457 Cardinal *UNUSED (num_params))
424
+ − 458 {
+ − 459 RadioWidget rw = (RadioWidget)w;
+ − 460 DrawHighlight(w, rw->command.normal_GC) ;
+ − 461 }
+ − 462
+ − 463
+ − 464 static void
+ − 465 RadioUnhighlight (Widget w,
2286
+ − 466 XEvent *UNUSED (event),
+ − 467 String *UNUSED (params),
+ − 468 Cardinal *UNUSED (num_params))
424
+ − 469 {
+ − 470 RadioWidget rw = (RadioWidget)w;
+ − 471 DrawHighlight(w, rw->command.inverse_GC) ;
+ − 472 }
+ − 473
+ − 474
+ − 475 /* ARGSUSED */
442
+ − 476 void
424
+ − 477 RadioSet (Widget w,
2286
+ − 478 XEvent *UNUSED (event),
+ − 479 String *UNUSED (params),
+ − 480 Cardinal *UNUSED (num_params))
424
+ − 481 {
+ − 482 RadioWidget rw = (RadioWidget)w;
1201
+ − 483 RadioWidgetClass class_ = (RadioWidgetClass) w->core.widget_class ;
424
+ − 484
+ − 485 if( rw->command.set )
+ − 486 return ;
+ − 487
+ − 488 rw->command.set = TRUE ;
+ − 489 if( XtIsRealized(w) )
1201
+ − 490 class_->radio_class.drawDiamond(w) ;
424
+ − 491 }
+ − 492
+ − 493
+ − 494 /* ARGSUSED */
442
+ − 495 void
424
+ − 496 RadioUnset (Widget w,
2286
+ − 497 XEvent *UNUSED (event),
+ − 498 String *UNUSED (params),
+ − 499 Cardinal *UNUSED (num_params))
424
+ − 500 {
+ − 501 RadioWidget rw = (RadioWidget)w;
1201
+ − 502 RadioWidgetClass class_ = (RadioWidgetClass) w->core.widget_class ;
424
+ − 503
+ − 504 if( ! rw->command.set )
+ − 505 return ;
+ − 506
+ − 507 rw->command.set = FALSE ;
+ − 508 if( XtIsRealized(w) )
1201
+ − 509 class_->radio_class.drawDiamond(w) ;
424
+ − 510 }
+ − 511
+ − 512
+ − 513
+ − 514
+ − 515 /************************************************************
+ − 516 *
+ − 517 * Internal Procedures
+ − 518 *
+ − 519 ************************************************************/
+ − 520
+ − 521
+ − 522 /* Size of widget. Width is size of box plus width of border around
+ − 523 * box plus width of label plus three margins plus the size of the left
+ − 524 * bitmap, if any. Height is max(box,bitmap,label) plus two margins.
+ − 525 */
+ − 526
+ − 527 static void
+ − 528 RadioSize (RadioWidget rw,
+ − 529 Dimension *w,
+ − 530 Dimension *h)
+ − 531 {
+ − 532 *w = rw->label.label_width + bs(rw) + LEFT_OFFSET(rw) +
+ − 533 3 * rw->label.internal_width ;
+ − 534 *h = Max( rw->label.label_height, bs(rw) ) +
+ − 535 2 * rw->label.internal_width ;
+ − 536 }
+ − 537
+ − 538
+ − 539 static void
+ − 540 DrawDiamond (Widget w)
+ − 541 {
+ − 542 RadioWidget rw = (RadioWidget) w ;
+ − 543 Display *dpy = XtDisplay(w) ;
+ − 544 Window win = XtWindow(w) ;
+ − 545 GC gc, gci ;
+ − 546
+ − 547 XPoint pts[5] ;
+ − 548 Dimension del = bsize(rw)/2 ;
+ − 549 Position x,y ; /* diamond center */
+ − 550 #ifdef _ThreeDP_h
+ − 551 int i=0;
+ − 552 Dimension s = swid(rw) ;
+ − 553 GC top, bot, ctr ;
+ − 554 #endif
+ − 555 gc = XtIsSensitive(w) ? rw->command.normal_GC : rw->label.gray_GC ;
+ − 556
+ − 557 gci = rw->command.set ? rw->command.normal_GC : rw->command.inverse_GC ;
+ − 558
+ − 559 x = rw->label.internal_width + bs(rw)/2 ;
+ − 560 y = rw->core.height/2 ;
+ − 561
+ − 562 #ifdef _ThreeDP_h
+ − 563 if( ! rw->command.set ) {
+ − 564 top = rw->threeD.top_shadow_GC ;
+ − 565 bot = rw->threeD.bot_shadow_GC ;
+ − 566 ctr = gc ; /* TODO */
+ − 567 } else {
+ − 568 top = rw->threeD.bot_shadow_GC ;
+ − 569 bot = rw->threeD.top_shadow_GC ;
+ − 570 ctr = gc ; /* TODO */
+ − 571 }
+ − 572 #endif
+ − 573
+ − 574 pts[0].x = x - del ;
+ − 575 pts[0].y = y ;
+ − 576 pts[1].x = x ;
+ − 577 pts[1].y = y - del ;
+ − 578 pts[2].x = x + del ;
+ − 579 pts[2].y = y ;
+ − 580 pts[3].x = x ;
+ − 581 pts[3].y = y + del ;
+ − 582 pts[4] = pts[0] ;
+ − 583 XFillPolygon(dpy,win,gci, pts,4, Convex, CoordModeOrigin) ;
+ − 584
+ − 585 #ifdef _ThreeDP_h
+ − 586 for(i=0; i<s; ++i) {
+ − 587 XDrawLine(dpy,win,bot, x-i-del,y, x,y+del+i) ;
+ − 588 XDrawLine(dpy,win,bot, x+del+i,y, x,y+del+i) ;
+ − 589 }
+ − 590 for(i=0; i<s; ++i) {
+ − 591 XDrawLine(dpy,win,top, x-del-i,y, x,y-del-i) ;
+ − 592 XDrawLine(dpy,win,top, x+del+i,y, x,y-del-i) ;
+ − 593 }
+ − 594 #else
+ − 595 XDrawLines(dpy,win,gc, pts,5, CoordModeOrigin) ;
+ − 596 #endif
+ − 597 }