1 /* Copyright (C) 1993 Nathan Sidwell */ 2 /* RCS $Id: Icon.c,v 4.13 1995/12/14 13:53:27 nathan Exp $ */ 3 /* this widget holds a pixmap which it can select a row/column from 4 * similar to a command widget, or initiate a drag on press and move 5 */ 6 /*{{{ includes*/ 7 #include "ansiknr.h" 8 #include <X11/X.h> 9 #include <X11/Xlib.h> 10 #include <X11/IntrinsicP.h> 11 #include <X11/StringDefs.h> 12 #include <X11/Xaw/SimpleP.h> 13 #include "Icon.h" 14 #include "Drag.h" 15 /*}}}*/ 16 /*{{{ structs*/ 17 /*{{{ typedef struct _IconClass*/ 18 typedef struct _IconClass 19 { 20 int ansi_compliance; /* not used */ 21 } IconClassPart; 22 /*}}}*/ 23 /*{{{ typedef struct _IconClassRec*/ 24 typedef struct _IconClassRec 25 { 26 CoreClassPart core_class; 27 SimpleClassPart simple_class; 28 IconClassPart icon_class; 29 } IconClassRec; 30 /*}}}*/ 31 /*{{{ typedef struct _IconPart*/ 32 typedef struct 33 { 34 /* resources */ 35 Pixmap pixmap; /* the icon to display */ 36 XtCallbackList callbacks; /* callbacks to notify */ 37 Dimension columns; /* cells across to highlight */ 38 Dimension rows; /* cells down to highlight */ 39 Dimension drag_sensitivity; /* sensitivity of drag callback */ 40 Dimension highlight_thickness; /* thickness of highlight bar */ 41 Pixel foreground; /* foreground pixel color */ 42 int flash_delay; /* time to flash */ 43 String drag_name; /* name of drag */ 44 45 /* private state */ 46 unsigned width; /* pixmap width */ 47 unsigned height; /* pixmap height */ 48 GC gc; /* GC to draw */ 49 Position x; /* corner of pixmap */ 50 Position y; /* corner of pixmap */ 51 Position drag_x; /* drag start x */ 52 Position drag_y; /* drag start y */ 53 Position selected; /* selected cell */ 54 Boolean drag_set; /* drag started */ 55 Boolean highlit; /* is it highlit? */ 56 Boolean solid; /* solid foreground */ 57 XtIntervalId timeout; /* timout id */ 58 } IconPart; 59 /*}}}*/ 60 /*{{{ typedef struct _IconRec*/ 61 typedef struct _IconRec 62 { 63 CorePart core; 64 SimplePart simple; 65 IconPart icon; 66 } IconRec; 67 /*}}}*/ 68 /*}}}*/ 69 /*{{{ resources*/ 70 static XtResource resources[] = 71 { 72 {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel), 73 XtOffsetOf(IconRec, icon.foreground), 74 XtRString, (XtPointer)XtDefaultForeground}, 75 {MredNhighlightThickness, XtCThickness, XtRDimension, sizeof(Dimension), 76 XtOffsetOf(IconRec, icon.highlight_thickness), 77 XtRImmediate, (XtPointer)1}, 78 {XtNpixmap, XtCPixmap, XtRBitmap, sizeof(Pixmap), 79 XtOffsetOf(IconRec, icon.pixmap), XtRImmediate, (XtPointer)None}, 80 {MredNcolumns, XtCWidth, XtRDimension, sizeof(Dimension), 81 XtOffsetOf(IconRec, icon.columns), XtRImmediate, (XtPointer)1}, 82 {MredNrows, XtCHeight, XtRDimension, sizeof(Dimension), 83 XtOffsetOf(IconRec, icon.rows), XtRImmediate, (XtPointer)1}, 84 {XtNcallback, XtCCallback, XtRCallback, sizeof(XtPointer), 85 XtOffsetOf(IconRec, icon.callbacks), XtRCallback, (XtPointer)NULL}, 86 {MredNdragSensitivity, XtCThickness, XtRDimension, sizeof(Dimension), 87 XtOffsetOf(IconRec, icon.drag_sensitivity), XtRImmediate, (XtPointer)4}, 88 {MredNflashDelay, XtCInterval, XtRInt, sizeof(int), 89 XtOffsetOf(IconRec, icon.flash_delay), XtRImmediate, (XtPointer)100}, 90 {MredNdragName, XtCLabel, XtRString, sizeof(String), 91 XtOffsetOf(IconRec, icon.drag_name), XtRImmediate, (XtPointer)"drag"}, 92 }; 93 /*}}}*/ 94 /*{{{ prototypes*/ 95 static VOIDFUNC Drag PROTOARG((Widget, XEvent *, String *, Cardinal *)); 96 static VOIDFUNC Highlight PROTOARG((Widget, XEvent *, String *, Cardinal *)); 97 static VOIDFUNC Notify PROTOARG((Widget, XEvent *, String *, Cardinal *)); 98 static VOIDFUNC Set PROTOARG((Widget, XEvent *, String *, Cardinal *)); 99 static VOIDFUNC Unhighlight PROTOARG((Widget, XEvent *, String *, Cardinal *)); 100 101 static VOIDFUNC Destroy PROTOARG((Widget)); 102 static VOIDFUNC Initialize PROTOARG((Widget, Widget, ArgList, Cardinal *)); 103 static XtGeometryResult QueryGeometry 104 PROTOARG((Widget, XtWidgetGeometry *, XtWidgetGeometry *)); 105 static VOIDFUNC Redisplay PROTOARG((Widget, XEvent *, Region)); 106 static VOIDFUNC Resize PROTOARG((Widget)); 107 static Boolean SetValues 108 PROTOARG((Widget, Widget, Widget, ArgList, Cardinal *)); 109 110 #define FakeExpose(iw) Redisplay((Widget)iw, NULL, NULL) 111 static VOIDFUNC GetGC PROTOARG((IconWidget)); 112 static VOIDFUNC GetPixmapSize PROTOARG((IconWidget)); 113 static unsigned GetPointerPosition 114 PROTOARG((IconWidget, XEvent *, Position *, Position *)); 115 static VOIDFUNC RemoveTimeOut PROTOARG((IconWidget)); 116 static VOIDFUNC TimeOut PROTOARG((XtPointer, XtIntervalId *)); 117 /*}}}*/ 118 /*{{{ translations*/ 119 static char translations[] = "\ 120 <BtnDown>:set()\n\ 121 <BtnUp>:notify()\n\ 122 <Motion>:highlight() drag()\n\ 123 <EnterWindow>:highlight()\n\ 124 <LeaveWindow>:unhighlight()\ 125 "; 126 /*}}}*/ 127 /*{{{ actions*/ 128 static XtActionsRec actions[] = 129 { 130 {"drag", Drag}, 131 {"highlight", Highlight}, 132 {"notify", Notify}, 133 {"set", Set}, 134 {"unhighlight", Unhighlight}, 135 }; 136 /*}}}*/ 137 #define SuperClass (WidgetClass)&simpleClassRec 138 /*{{{ IconClassRec iconClassRec =*/ 139 IconClassRec iconClassRec = 140 { 141 /*{{{ core class part*/ 142 { 143 SuperClass, /* superclass */ 144 "Icon", /* class_name */ 145 sizeof(IconRec), /* size */ 146 NULL, /* class_initialize */ 147 NULL, /* class_part_initialize */ 148 False, /* class_inited */ 149 Initialize, /* initialize */ 150 NULL, /* initialize_hook */ 151 XtInheritRealize, /* realize */ 152 actions, /* actions */ 153 XtNumber(actions), /* num_actions */ 154 resources, /* resources */ 155 XtNumber(resources), /* num_resources */ 156 NULLQUARK, /* xrm_class */ 157 True, /* compress_motion */ 158 XtExposeCompressMultiple, /* compress_exposure */ 159 True, /* compress_enterleave */ 160 False, /* visible_interest */ 161 Destroy, /* destroy */ 162 Resize, /* resize */ 163 Redisplay, /* expose */ 164 SetValues, /* set_values */ 165 NULL, /* set_values_hook */ 166 XtInheritSetValuesAlmost, /* set_values_almost */ 167 NULL, /* get_values_hook */ 168 NULL, /* accept_focus */ 169 XtVersion, /* version */ 170 NULL, /* callback_private */ 171 translations, /* default_translations */ 172 QueryGeometry, /* query_geometry */ 173 XtInheritDisplayAccelerator, /* display_accelerator */ 174 NULL, /* extension */ 175 }, 176 /*}}}*/ 177 /*{{{ simple class part*/ 178 { 179 XtInheritChangeSensitive /* change_sensitive */ 180 }, 181 /*}}}*/ 182 /*{{{ icon class part*/ 183 { 184 0, /* dummy */ 185 }, 186 /*}}}*/ 187 }; 188 /*}}}*/ 189 WidgetClass iconWidgetClass = (WidgetClass)&iconClassRec; 190 /* actions */ 191 /*{{{ void Drag(widget, event, params, num_params)*/ 192 static VOIDFUNC Drag 193 FUNCARG((widget, event, params, num_params), 194 Widget widget 195 ARGSEP XEvent *event 196 ARGSEP String *params 197 ARGSEP Cardinal *num_params 198 ) 199 /* detect dragging 200 * if we moved >= drag sensitivity since the button press then 201 * invoke a drag widget 202 * the drag widget is found by cheking each level of the widget tree 203 * for a drag child, going up from this widget. 204 * if started, any current selection is cleared 205 * Should be called on button type events 206 */ 207 { 208 IconWidget iw; 209 Position x, y; 210 211 iw = (IconWidget)widget; 212 x = y = 0; 213 if(event->type != MotionNotify && event->type != ButtonPress) 214 /* EMPTY */; 215 else if(event->type == MotionNotify && !(event->xmotion.state & 216 (Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask))) 217 /* EMPTY */; 218 else if(!GetPointerPosition(iw, event, &x, &y)) 219 /* EMPTY */; 220 else if(iw->icon.drag_set == False) 221 { 222 iw->icon.drag_x = x; 223 iw->icon.drag_y = y; 224 iw->icon.drag_set = True; 225 } 226 else if(iw->icon.drag_sensitivity && iw->icon.drag_name && 227 iw->icon.drag_sensitivity * iw->icon.drag_sensitivity <= 228 (x - iw->icon.drag_x) * (x - iw->icon.drag_x) + 229 (y - iw->icon.drag_y) * (y - iw->icon.drag_y)) 230 /*{{{ popup drag*/ 231 { 232 Widget drag; 233 Widget parent; 234 235 drag = NULL; 236 for(parent = (Widget)iw; parent; parent = XtParent(parent)) 237 { 238 drag = XtNameToWidget(parent, iw->icon.drag_name); 239 if(drag) 240 break; 241 } 242 if(drag) 243 { 244 Position rx, ry; 245 246 iw->icon.highlit = False; 247 FakeExpose(iw); 248 XtTranslateCoords((Widget)iw, iw->icon.x, iw->icon.y, &rx, &ry); 249 DragPopup((Widget)iw, (Widget)drag, iw->icon.pixmap, 250 iw->icon.drag_x, iw->icon.drag_y, 251 rx + x, ry + y, event->xmotion.time); 252 } 253 } 254 /*}}}*/ 255 return; 256 } 257 /*}}}*/ 258 /*{{{ void Highlight(widget, event, params, num_params)*/ 259 static VOIDFUNC Highlight 260 FUNCARG((widget, event, params, num_params), 261 Widget widget 262 ARGSEP XEvent *event 263 ARGSEP String *params 264 ARGSEP Cardinal *num_params 265 ) 266 /* Determines which cell of the widget is selected, and 267 * redraws if changed. 268 * The drag position is reset, if a new cell is selected. 269 * Should be invoked on pointer movement events. 270 */ 271 { 272 IconWidget iw; 273 Position x, y; 274 int selected; 275 276 iw = (IconWidget)widget; 277 selected = GetPointerPosition(iw, event, &x, &y); 278 if(selected) 279 { 280 if(selected > 1 || !iw->icon.highlight_thickness) 281 selected = -1; 282 else 283 selected = y / (iw->icon.height / iw->icon.rows) * iw->icon.columns + 284 x / (iw->icon.width / iw->icon.columns); 285 if(selected != iw->icon.selected || 286 (iw->icon.highlit == False && selected >= 0)) 287 { 288 iw->icon.drag_x = x; 289 iw->icon.drag_y = y; 290 iw->icon.selected = selected; 291 iw->icon.highlit = selected < 0 ? False : True; 292 if(selected >= 0) 293 RemoveTimeOut(iw); 294 FakeExpose(iw); 295 } 296 } 297 return; 298 } 299 /*}}}*/ 300 /*{{{ void Notify(widget, event, params, num_params)*/ 301 static VOIDFUNC Notify 302 FUNCARG((widget, event, params, num_params), 303 Widget widget 304 ARGSEP XEvent *event 305 ARGSEP String *params 306 ARGSEP Cardinal *num_params 307 ) 308 /* notifies of the current selection. 309 * If none is selected nothing happens. 310 * otherwise the callback is called, and the widget flashed 311 * in its foreground color 312 * Normally called on button release 313 */ 314 { 315 IconWidget iw; 316 317 iw = (IconWidget)widget; 318 iw->icon.drag_set = False; 319 if(iw->icon.selected >= 0) 320 { 321 IconCallback data; 322 323 if(iw->icon.flash_delay) 324 { 325 iw->icon.solid = True; 326 FakeExpose(iw); 327 iw->icon.timeout = 328 XtAppAddTimeOut(XtWidgetToApplicationContext((Widget)iw), 329 (unsigned long)iw->icon.flash_delay, TimeOut, (XtPointer)iw); 330 } 331 data.selection = iw->icon.selected; 332 if(event->type == ButtonPress || event->type == ButtonRelease) 333 data.button = event->xbutton.button; 334 else 335 data.button = -1; 336 XtCallCallbackList((Widget)iw, iw->icon.callbacks, (XtPointer)&data); 337 } 338 return; 339 } 340 /*}}}*/ 341 /*{{{ void Set(widget, event, params, num_params)*/ 342 static VOIDFUNC Set 343 FUNCARG((widget, event, params, num_params), 344 Widget widget 345 ARGSEP XEvent *event 346 ARGSEP String *params 347 ARGSEP Cardinal *num_params 348 ) 349 /* initialize the drag position 350 * normally called on button press 351 */ 352 { 353 IconWidget iw; 354 355 iw = (IconWidget)widget; 356 GetPointerPosition(iw, event, &iw->icon.drag_x, &iw->icon.drag_y); 357 iw->icon.drag_set = True; 358 return; 359 } 360 /*}}}*/ 361 /*{{{ void Unhighlight(widget, event, params, num_params)*/ 362 static VOIDFUNC Unhighlight 363 FUNCARG((widget, event, params, num_params), 364 Widget widget 365 ARGSEP XEvent *event 366 ARGSEP String *params 367 ARGSEP Cardinal *num_params 368 ) 369 /* deselect any selected area and reset the drag 370 * Normally called on LeaveWindow 371 */ 372 { 373 IconWidget iw; 374 375 iw = (IconWidget)widget; 376 if(iw->icon.highlit != False) 377 { 378 iw->icon.highlit = False; 379 FakeExpose(iw); 380 } 381 return; 382 } 383 /*}}}*/ 384 /* methods */ 385 /*{{{ void Destroy(widget)*/ 386 static VOIDFUNC Destroy 387 FUNCARG((widget), 388 Widget widget 389 ) 390 /* free the GC and remove the flash timeout 391 */ 392 { 393 IconWidget iw; 394 395 iw = (IconWidget)widget; 396 XtReleaseGC((Widget)iw, iw->icon.gc); 397 RemoveTimeOut(iw); 398 return; 399 } 400 /*}}}*/ 401 /*{{{ void Initialize(treq, tnew, args, num_args)*/ 402 static VOIDFUNC Initialize 403 FUNCARG((treq, tnew, args, num_args), 404 Widget treq 405 ARGSEP Widget tnew 406 ARGSEP ArgList args 407 ARGSEP Cardinal *num_args 408 ) 409 /* allocate ourselves a GC, and set out default size 410 */ 411 { 412 IconWidget niw; 413 414 niw = (IconWidget)tnew; 415 niw->icon.selected = -1; 416 niw->icon.highlit = False; 417 niw->icon.drag_set = False; 418 niw->icon.solid = False; 419 niw->icon.timeout = (XtIntervalId)0; 420 GetPixmapSize(niw); 421 if(!niw->core.width) 422 niw->core.width = niw->icon.width ? niw->icon.width : 16; 423 if(!niw->core.height) 424 niw->core.height = niw->icon.height ? niw->icon.height : 16; 425 GetGC(niw); 426 if(!niw->icon.columns) 427 niw->icon.columns = 1; 428 if(!niw->icon.rows) 429 niw->icon.rows = 1; 430 return; 431 } 432 /*}}}*/ 433 /*{{{ XtGeometryResult QueryGeometry(widget, proposed, answer)*/ 434 static XtGeometryResult QueryGeometry 435 FUNCARG((widget, proposed, answer), 436 Widget widget 437 ARGSEP XtWidgetGeometry *proposed 438 ARGSEP XtWidgetGeometry *answer 439 ) 440 /* tell out parent what size we'd like to be 441 */ 442 { 443 IconWidget iw; 444 445 iw = (IconWidget)widget; 446 answer->request_mode = CWWidth | CWHeight; 447 answer->height = iw->icon.width ? iw->icon.width : 16; 448 answer->width = iw->icon.height ? iw->icon.height : 16; 449 if((proposed->request_mode & (CWWidth | CWHeight)) == (CWWidth | CWHeight) && 450 proposed->width == answer->width && proposed->height == answer->height) 451 return XtGeometryYes; 452 else if(answer->width == iw->core.width && answer->height == iw->core.height) 453 return XtGeometryNo; 454 else 455 return XtGeometryAlmost; 456 } 457 /*}}}*/ 458 /*{{{ void Redisplay(widget, event, region)*/ 459 static VOIDFUNC Redisplay 460 FUNCARG((widget, event, region), 461 Widget widget 462 ARGSEP XEvent *event 463 ARGSEP Region region 464 ) 465 /* repaint ourselves 466 * We don't bother with a clip, just do the whole lot 467 * This involves blitting the pixmap 468 * drawing the select box 469 * Drawing the flash box 470 */ 471 { 472 IconWidget iw; 473 474 if(!XtIsRealized(widget)) 475 return; 476 iw = (IconWidget)widget; 477 if(iw->icon.pixmap != None) 478 XCopyArea(XtDisplay(iw), iw->icon.pixmap, XtWindow(iw), iw->icon.gc, 0, 0, 479 iw->icon.width, iw->icon.height, iw->icon.x, iw->icon.y); 480 if(iw->icon.solid != False) 481 XFillRectangle(XtDisplay(iw), XtWindow(iw), iw->icon.gc, 482 iw->icon.x + iw->icon.selected % iw->icon.columns * 483 iw->icon.width / iw->icon.columns, 484 iw->icon.y + iw->icon.selected / iw->icon.columns * 485 iw->icon.height / iw->icon.rows, 486 iw->icon.width / iw->icon.columns, iw->icon.height / iw->icon.rows); 487 else if(iw->icon.highlit != False) 488 XDrawRectangle(XtDisplay(iw), XtWindow(iw), iw->icon.gc, 489 iw->icon.x + iw->icon.selected % iw->icon.columns * 490 iw->icon.width / iw->icon.columns + 491 (iw->icon.highlight_thickness >> 1), 492 iw->icon.y + iw->icon.selected / iw->icon.columns * 493 iw->icon.height / iw->icon.rows + 494 (iw->icon.highlight_thickness >> 1), 495 iw->icon.width / iw->icon.columns - iw->icon.highlight_thickness, 496 iw->icon.height / iw->icon.rows - iw->icon.highlight_thickness); 497 return; 498 } 499 /*}}}*/ 500 /*{{{ void Resize(widget)*/ 501 static VOIDFUNC Resize 502 FUNCARG((widget), 503 Widget widget 504 ) 505 /* recenter the pixmap, when w get resized 506 */ 507 { 508 IconWidget iw; 509 510 iw = (IconWidget)widget; 511 iw->icon.x = (iw->core.width - iw->icon.width) / 2; 512 iw->icon.y = (iw->core.height - iw->icon.height) / 2; 513 return; 514 } 515 /*}}}*/ 516 /*{{{ Boolean SetValues(cw, rw, nw, args, num_args)*/ 517 static Boolean SetValues 518 FUNCARG((cw, rw, nw, args, num_args), 519 Widget cw 520 ARGSEP Widget rw 521 ARGSEP Widget nw 522 ARGSEP ArgList args 523 ARGSEP Cardinal *num_args 524 ) 525 /* need to get a new GC if color or highlight width changes 526 * need to calculate a new size if the pixmap changes 527 */ 528 { 529 Boolean redraw; 530 IconWidget ciw; 531 IconWidget niw; 532 533 redraw = False; 534 ciw = (IconWidget)cw; 535 niw = (IconWidget)nw; 536 if(ciw->icon.foreground != niw->icon.foreground || 537 ciw->icon.highlight_thickness != niw->icon.highlight_thickness) 538 { 539 redraw = True; 540 XtReleaseGC(cw, ciw->icon.gc); 541 GetGC(niw); 542 } 543 if(ciw->icon.pixmap != niw->icon.pixmap) 544 { 545 redraw = True; 546 GetPixmapSize(niw); 547 if(niw->icon.width) 548 { 549 niw->core.width = niw->icon.width; 550 niw->icon.x = 0; 551 } 552 if(niw->icon.height) 553 { 554 niw->core.height = niw->icon.height; 555 niw->icon.y = 0; 556 } 557 } 558 if(!niw->icon.columns) 559 niw->icon.columns = 1; 560 if(!niw->icon.rows) 561 niw->icon.rows = 1; 562 if(ciw->icon.columns != niw->icon.columns || 563 ciw->icon.rows != niw->icon.rows) 564 { 565 niw->icon.selected = -1; 566 niw->icon.highlit = False; 567 } 568 if(ciw->core.width != niw->core.width || 569 ciw->core.height != niw->core.height) 570 redraw = False; 571 return redraw; 572 } 573 /*}}}*/ 574 /* public routines */ 575 /*{{{ void IconRepaint(widget)*/ 576 extern VOIDFUNC IconRepaint 577 FUNCARG((widget), 578 Widget widget 579 ) 580 /* repaint the widget, without the anoying flicker caused by an expose 581 * event 582 */ 583 { 584 if(XtIsSubclass(widget, (WidgetClass)&iconClassRec)) 585 FakeExpose((IconWidget)widget); 586 return; 587 } 588 /*}}}*/ 589 /* private routines */ 590 /*{{{ void GetGC(iw)*/ 591 static VOIDFUNC GetGC 592 FUNCARG((widget), 593 IconWidget widget 594 ) 595 /* get an approptiate GC 596 */ 597 { 598 XGCValues values; 599 600 values.foreground = widget->icon.foreground; 601 values.line_width = widget->icon.highlight_thickness; 602 widget->icon.gc = XtGetGC((Widget)widget, GCForeground | GCLineWidth, 603 &values); 604 return; 605 } 606 /*}}}*/ 607 /*{{{ void GetPixmapSize(iw)*/ 608 static VOIDFUNC GetPixmapSize 609 FUNCARG((widget), 610 IconWidget widget 611 ) 612 /* find out the pixmap size 613 * if pixmap is None then set to 0 614 * note this interrogates the server 615 */ 616 { 617 if(widget->icon.pixmap != None) 618 { 619 Window root; 620 int x, y; 621 unsigned border; 622 unsigned depth; 623 Status status; 624 625 status = XGetGeometry(XtDisplay(widget), widget->icon.pixmap, &root, 626 &x, &y, &widget->icon.width, &widget->icon.height, &border, &depth); 627 } 628 else 629 widget->icon.width = widget->icon.height = 0; 630 return; 631 } 632 /*}}}*/ 633 /*{{{ unsigned GetPointerPosition(iw, event, x, y)*/ 634 static unsigned GetPointerPosition 635 FUNCARG((iw, event, xp, yp), 636 IconWidget iw 637 ARGSEP XEvent *event /* event to query */ 638 ARGSEP Position *xp /* x coordinate return */ 639 ARGSEP Position *yp /* y coordinate return */ 640 ) 641 /* find the pointer position on widget window. 642 * returns 0 if not a pointer event 643 * returns 1 if inside the pixmap 644 * returns 2 if outside pixmap && inside widget 645 * returns 3 if outisde widget 646 * clips to pixmap 647 */ 648 { 649 unsigned got; 650 Position x; 651 Position y; 652 653 /*{{{ get position from event*/ 654 switch(event->type) 655 { 656 case ButtonPress: 657 case ButtonRelease: 658 x = event->xbutton.x; 659 y = event->xbutton.y; 660 got = 1; 661 break; 662 case MotionNotify: 663 x = event->xmotion.x; 664 y = event->xmotion.y; 665 got = 1; 666 break; 667 case EnterNotify: 668 case LeaveNotify: 669 x = event->xcrossing.x; 670 y = event->xcrossing.y; 671 got = 1; 672 break; 673 default: 674 x = y = 0; 675 got = 0; 676 } 677 /*}}}*/ 678 if(got) 679 /*{{{ convert to pixmap coord*/ 680 { 681 unsigned out; 682 683 out = event->type != EnterNotify && 684 (x < 0 || x >= (Position)iw->core.width || 685 y < 0 || y >= (Position)iw->core.height); 686 x -= iw->icon.x; 687 y -= iw->icon.y; 688 if(x < 0) 689 { 690 x = 0; 691 got = 2; 692 } 693 else if(x >= iw->icon.width) 694 { 695 x = iw->icon.width - 1; 696 got = 2; 697 } 698 if(y < 0) 699 { 700 y = 0; 701 got = 2; 702 } 703 else if(y >= iw->icon.height) 704 { 705 y = iw->icon.height - 1; 706 got = 2; 707 } 708 if(out) 709 got = 3; 710 *xp = x; 711 *yp = y; 712 } 713 /*}}}*/ 714 return got; 715 } 716 /*}}}*/ 717 /*{{{ void RemoveTimeOut(iw)*/ 718 static VOIDFUNC RemoveTimeOut 719 FUNCARG((iw), 720 IconWidget iw 721 ) 722 /* remove the flash timeout, if its set 723 */ 724 { 725 if(iw->icon.timeout != (XtIntervalId)0) 726 { 727 XtRemoveTimeOut(iw->icon.timeout); 728 iw->icon.timeout = (XtIntervalId)0; 729 iw->icon.solid = False; 730 } 731 return; 732 } 733 /*}}}*/ 734 /*{{{ void TimeOut(data, id)*/ 735 static VOIDFUNC TimeOut 736 FUNCARG((data, id), 737 XtPointer data 738 ARGSEP XtIntervalId *id 739 ) 740 /* unflashes the widget 741 */ 742 { 743 IconWidget iw; 744 745 iw = (IconWidget)data; 746 iw->icon.solid = False; 747 iw->icon.timeout = (XtIntervalId)0; 748 FakeExpose(iw); 749 return; 750 } 751 /*}}}*/ 752