Handlers.c revision 2b32c8f7
1/* 2 3Copyright 1989, 1998 The Open Group 4 5Permission to use, copy, modify, distribute, and sell this software and its 6documentation for any purpose is hereby granted without fee, provided that 7the above copyright notice appear in all copies and that both that 8copyright notice and this permission notice appear in supporting 9documentation. 10 11The above copyright notice and this permission notice shall be included 12in all copies or substantial portions of the Software. 13 14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR 18OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20OTHER DEALINGS IN THE SOFTWARE. 21 22Except as contained in this notice, the name of The Open Group shall 23not be used in advertising or otherwise to promote the sale, use or 24other dealings in this Software without prior written authorization 25from The Open Group. 26 27*/ 28 29/* 30 * Author: Davor Matic, MIT X Consortium 31 */ 32 33#include <X11/IntrinsicP.h> 34#include <X11/StringDefs.h> 35#include "BitmapP.h" 36 37#include <stdio.h> 38#include <math.h> 39 40#define min(x, y) (((int)(x) < (int)(y)) ? (x) : (y)) 41#define max(x, y) (((int)(x) > (int)(y)) ? (x) : (y)) 42 43#include "Requests.h" 44 45 46/***************************************************************************** 47 * Handlers * 48 *****************************************************************************/ 49 50#define QueryInSquare(BW, x, y, square_x, square_y)\ 51 ((InBitmapX(BW, x) == (square_x)) &&\ 52 (InBitmapY(BW, y) == (square_y))) 53 54 55static void 56DragOnePointHandler(Widget w, 57 XtPointer client_data, 58 XEvent *event, 59 Boolean *cont) /* ARGSUSED */ 60{ 61 BWStatus *status = (BWStatus *)client_data; 62 BitmapWidget BW = (BitmapWidget) w; 63 64 if (DEBUG) 65 fprintf(stderr, "D1PH "); 66 67 switch (event->type) { 68 69 case ButtonPress: 70 if (event->xbutton.state != status->state) return; 71 if (!QuerySet(status->at_x, status->at_y)) { 72 BWStoreToBuffer(w); 73 status->value = Value(BW, event->xbutton.button); 74 status->btime = event->xbutton.time; 75 status->at_x = InBitmapX(BW, event->xbutton.x); 76 status->at_y = InBitmapY(BW, event->xbutton.y); 77 status->success = status->draw ? True : False; 78 if (status->draw) 79 (*(DrawOnePointProc)status->draw)(w, 80 status->at_x, status->at_y, status->value); 81 } 82 break; 83 84 case ButtonRelease: 85 if (QuerySet(status->at_x, status->at_y)) { 86 status->value = Value(BW, event->xbutton.button); 87 status->btime = event->xbutton.time; 88 status->at_x = InBitmapX(BW, event->xbutton.x); 89 status->at_y = InBitmapY(BW, event->xbutton.y); 90 status->success = status->draw ? True : False; 91 /* SUPPRESS 701 */ 92 BWTerminateRequest(w, TRUE); 93 } 94 break; 95 96 case MotionNotify: 97 if (QuerySet(status->at_x, status->at_y)) { 98 if (!QueryInSquare(BW, event->xmotion.x, event->xmotion.y, 99 status->at_x, status->at_y)) { 100 status->at_x = InBitmapX(BW, event->xmotion.x); 101 status->at_y = InBitmapY(BW, event->xmotion.y); 102 if (status->draw) 103 (*(DrawOnePointProc)status->draw)(w, 104 status->at_x, status->at_y, status->value); 105 } 106 } 107 break; 108 109 } 110} 111 112void 113DragOnePointEngage(Widget w, 114 BWStatus *status, 115 XtPointer draw, 116 int *state) 117{ 118 119 status->at_x = NotSet; 120 status->at_y = NotSet; 121 status->draw = draw; 122 status->success = False; 123 status->state = *state; 124 125 XtAddEventHandler(w, 126 ButtonPressMask | ButtonReleaseMask | PointerMotionMask, 127 FALSE, DragOnePointHandler, (XtPointer)status); 128} 129 130/* ARGSUSED */ 131void 132DragOnePointTerminate(Widget w, 133 BWStatus *status, 134 XtPointer draw) 135{ 136 137 if (status->success) { 138 BWChangeNotify(w); 139 BWSetChanged(w); 140 } 141 142 XtRemoveEventHandler(w, 143 ButtonPressMask | ButtonReleaseMask | PointerMotionMask, 144 FALSE, DragOnePointHandler, (XtPointer)status); 145 146} 147 148void 149OnePointHandler(Widget w, 150 XtPointer client_data, 151 XEvent *event, 152 Boolean *cont) /* ARGSUSED */ 153{ 154 BWStatus *status = (BWStatus *)client_data; 155 BitmapWidget BW = (BitmapWidget) w; 156 157 if (DEBUG) 158 fprintf(stderr, "1PH "); 159 160 switch (event->type) { 161 162 case Expose: 163 if (QuerySet(status->at_x, status->at_y)) { 164 BWClip(w, event->xexpose.x, event->xexpose.y, 165 event->xexpose.width, event->xexpose.height); 166 if (status->draw) 167 (*(DrawOnePointProc)status->draw)(w, 168 status->at_x, status->at_y, Highlight); 169 170 BWUnclip(w); 171 } 172 break; 173 174 case ButtonPress: 175 if (event->xbutton.state != status->state) return; 176 if (!QuerySet(status->at_x, status->at_y)) { 177 status->value = Value(BW, event->xbutton.button); 178 status->btime = event->xbutton.time; 179 status->at_x = InBitmapX(BW, event->xbutton.x); 180 status->at_y = InBitmapY(BW, event->xbutton.y); 181 if (status->draw) 182 (*(DrawOnePointProc)status->draw)(w, 183 status->at_x, status->at_y, Highlight); 184 } 185 break; 186 187 case ButtonRelease: 188 if (QuerySet(status->at_x, status->at_y)) { 189 if (status->draw) 190 (*(DrawOnePointProc)status->draw)(w, 191 status->at_x, status->at_y, Highlight); 192 193 status->value = Value(BW, event->xbutton.button); 194 status->btime = event->xbutton.time; 195 status->at_x = InBitmapX(BW, event->xbutton.x); 196 status->at_y = InBitmapY(BW, event->xbutton.y); 197 status->success = True; 198 199 BWTerminateRequest(w, TRUE); 200 } 201 break; 202 203 case MotionNotify: 204 if (QuerySet(status->at_x, status->at_y)) { 205 if (!QueryInSquare(BW, event->xmotion.x, event->xmotion.y, 206 status->at_x, status->at_y)) { 207 if (status->draw) 208 (*(DrawOnePointProc)status->draw)(w, 209 status->at_x, status->at_y, Highlight); 210 status->at_x = InBitmapX(BW, event->xmotion.x); 211 status->at_y = InBitmapY(BW, event->xmotion.y); 212 if (status->draw) 213 (*(DrawOnePointProc)status->draw)(w, 214 status->at_x, status->at_y, Highlight); 215 } 216 } 217 break; 218 } 219} 220 221void 222OnePointEngage(Widget w, 223 BWStatus *status, 224 XtPointer draw, 225 int *state) 226{ 227 status->at_x = NotSet; 228 status->at_y = NotSet; 229 status->draw = draw; 230 status->success = False; 231 status->state = *state; 232 233 XtAddEventHandler(w, 234 ButtonPressMask | ButtonReleaseMask | 235 ExposureMask | PointerMotionMask, 236 FALSE, OnePointHandler, (XtPointer)status); 237} 238 239#if 0 240void 241OnePointImmediateEngage(Widget w, 242 BWStatus *status, 243 XtPointer draw, 244 int *state) 245{ 246 status->at_x = 0; 247 status->at_y = 0; 248 status->draw = draw; 249 status->success = False; 250 status->state = *state; 251 252 if (status->draw) 253 (*(DrawOnePointProc)status->draw)(w, 254 status->at_x, status->at_y, Highlight); 255 256 XtAddEventHandler(w, 257 ButtonPressMask | ButtonReleaseMask | 258 ExposureMask | PointerMotionMask, 259 FALSE, OnePointHandler, (XtPointer)status); 260} 261#endif 262 263void 264OnePointTerminate(Widget w, 265 BWStatus *status, 266 XtPointer draw) 267{ 268 269 if (status->success && draw) { 270 BWStoreToBuffer(w); 271 (*(DrawOnePointProc)draw)(w, 272 status->at_x, status->at_y, 273 status->value); 274 BWChangeNotify(w); 275 BWSetChanged(w); 276 } 277 else 278 if (QuerySet(status->at_x, status->at_y)) 279 if (status->draw) 280 (*(DrawOnePointProc)status->draw)(w, 281 status->at_x, status->at_y, Highlight); 282 283 XtRemoveEventHandler(w, 284 ButtonPressMask | ButtonReleaseMask | 285 ExposureMask | PointerMotionMask, 286 FALSE, OnePointHandler, (XtPointer)status); 287} 288 289void 290OnePointTerminateTransparent(Widget w, 291 BWStatus *status, 292 XtPointer draw) 293{ 294 295 if (status->success && draw) 296 (*(DrawOnePointProc)draw)(w, 297 status->at_x, status->at_y, 298 status->value); 299 else 300 if (QuerySet(status->at_x, status->at_y)) 301 if (status->draw) 302 (*(DrawOnePointProc)status->draw)(w, 303 status->at_x, status->at_y, Highlight); 304 305 XtRemoveEventHandler(w, 306 ButtonPressMask | ButtonReleaseMask | 307 ExposureMask | PointerMotionMask, 308 FALSE, OnePointHandler, (XtPointer)status); 309 310} 311 312 313void 314TwoPointsHandler(Widget w, 315 XtPointer client_data, 316 XEvent *event, 317 Boolean *cont) /* ARGSUSED */ 318{ 319 BitmapWidget BW = (BitmapWidget) w; 320 BWStatus *status = (BWStatus *)client_data; 321 if (DEBUG) 322 fprintf(stderr, "2PH "); 323 324 switch (event->type) { 325 326 case Expose: 327 if (QuerySet(status->from_x, status->from_y) && 328 QuerySet(status->to_x, status->to_y)) { 329 BWClip(w, event->xexpose.x, event->xexpose.y, 330 event->xexpose.width, event->xexpose.height); 331 if (status->draw) 332 (*(DrawTwoPointProc)status->draw)(w, 333 status->from_x, status->from_y, 334 status->to_x, status->to_y, Highlight); 335 BWUnclip(w); 336 } 337 break; 338 339 case ButtonPress: 340 if (event->xbutton.state != status->state) return; 341 if (!QuerySet(status->from_x, status->from_y)) { 342 status->value = Value(BW, event->xbutton.button); 343 status->btime = event->xbutton.time; 344 status->from_x = InBitmapX(BW, event->xbutton.x); 345 status->from_y = InBitmapY(BW, event->xbutton.y); 346 status->to_x = InBitmapX(BW, event->xbutton.x); 347 status->to_y = InBitmapY(BW, event->xbutton.y); 348 if (status->draw) 349 (*(DrawTwoPointProc)status->draw)(w, 350 status->from_x, status->from_y, 351 status->to_x, status->to_y, Highlight); 352 } 353 break; 354 355 case ButtonRelease: 356 if (QuerySet(status->from_x, status->from_y)) { 357 if (status->draw) 358 (*(DrawTwoPointProc)status->draw)(w, 359 status->from_x, status->from_y, 360 status->to_x, status->to_y, Highlight); 361 status->value = Value(BW, event->xbutton.button); 362 status->btime = event->xbutton.time; 363 status->to_x = InBitmapX(BW, event->xbutton.x); 364 status->to_y = InBitmapY(BW, event->xbutton.y); 365 status->success = True; 366 367 BWTerminateRequest(w, TRUE); 368 } 369 break; 370 371 case MotionNotify: 372 if (QuerySet(status->from_x, status->from_y)) { 373 if (QuerySet(status->to_x, status->to_y)) { 374 if (!QueryInSquare(BW, event->xmotion.x, event->xmotion.y, 375 status->to_x, status->to_y)) { 376 if (status->draw) 377 (*(DrawTwoPointProc)status->draw)(w, 378 status->from_x, status->from_y, 379 status->to_x, status->to_y, Highlight); 380 status->to_x = InBitmapX(BW, event->xmotion.x); 381 status->to_y = InBitmapY(BW, event->xmotion.y); 382 if (status->draw) 383 (*(DrawTwoPointProc)status->draw)(w, 384 status->from_x, status->from_y, 385 status->to_x, status->to_y, Highlight); 386 } 387 } 388 else { 389 status->to_x = InBitmapX(BW, event->xmotion.x); 390 status->to_y = InBitmapY(BW, event->xmotion.y); 391 if (status->draw) 392 (*(DrawTwoPointProc)status->draw)(w, 393 status->from_x, status->from_y, 394 status->to_x, status->to_y, Highlight); 395 } 396 } 397 break; 398 } 399} 400 401void 402TwoPointsEngage(Widget w, 403 BWStatus *status, 404 XtPointer draw, 405 int *state) 406{ 407 408 status->from_x = NotSet; 409 status->from_y = NotSet; 410 status->to_x = NotSet; 411 status->to_y = NotSet; 412 status->draw = draw; 413 status->success = False; 414 status->state = *state; 415 416 XtAddEventHandler(w, 417 ButtonPressMask | ButtonReleaseMask | 418 ExposureMask | PointerMotionMask, 419 FALSE, TwoPointsHandler, (XtPointer)status); 420} 421 422void 423TwoPointsTerminate(Widget w, 424 BWStatus *status, 425 XtPointer draw) 426{ 427 428 if (status->success && draw) { 429 BWStoreToBuffer(w); 430 (*(DrawTwoPointProc)draw)(w, 431 status->from_x, status->from_y, 432 status->to_x, status->to_y, 433 status->value); 434 BWChangeNotify(w); 435 BWSetChanged(w); 436 } 437 else 438 if (QuerySet(status->from_x, status->from_y) && 439 QuerySet(status->to_x, status->to_y)) 440 if (status->draw) 441 (*(DrawTwoPointProc)status->draw)(w, 442 status->from_x, status->from_y, 443 status->to_x, status->to_y, Highlight); 444 445 XtRemoveEventHandler(w, 446 ButtonPressMask | ButtonReleaseMask | 447 ExposureMask | PointerMotionMask, 448 FALSE, TwoPointsHandler, (XtPointer)status); 449} 450 451void 452TwoPointsTerminateTransparent(Widget w, 453 BWStatus *status, 454 XtPointer draw) 455{ 456 457 if (status->success && draw) 458 (*(DrawTwoPointProc)draw)(w, 459 status->from_x, status->from_y, 460 status->to_x, status->to_y, 461 status->value); 462 else 463 if (QuerySet(status->from_x, status->from_y) && 464 QuerySet(status->to_x, status->to_y)) 465 if (status->draw) 466 (*(DrawTwoPointProc)status->draw)(w, 467 status->from_x, status->from_y, 468 status->to_x, status->to_y, Highlight); 469 470 XtRemoveEventHandler(w, 471 ButtonPressMask | ButtonReleaseMask | 472 ExposureMask | PointerMotionMask, 473 FALSE, TwoPointsHandler, (XtPointer)status); 474} 475 476void 477TwoPointsTerminateTimed(Widget w, 478 BWStatus *status, 479 XtPointer draw) 480{ 481 482 if (status->success && draw) 483 (*(DrawTwoPointProc)draw)(w, 484 status->from_x, status->from_y, 485 status->to_x, status->to_y, 486 status->btime); 487 else 488 if (QuerySet(status->from_x, status->from_y) && 489 QuerySet(status->to_x, status->to_y)) 490 if (status->draw) 491 (*(DrawTwoPointProc)status->draw)(w, 492 status->from_x, status->from_y, 493 status->to_x, status->to_y, Highlight); 494 495 XtRemoveEventHandler(w, 496 ButtonPressMask | ButtonReleaseMask | 497 ExposureMask | PointerMotionMask, 498 FALSE, TwoPointsHandler, (XtPointer)status); 499} 500 501/* ARGSUSED */ 502void 503Interface(Widget w, 504 BWStatus *status, 505 XtPointer action) 506{ 507 (*(InterfaceProc)action)(w); 508} 509 510void 511Paste(Widget w, 512 Position at_x, 513 Position at_y, 514 int value) 515{ 516 BitmapWidget BW = (BitmapWidget) w; 517 BWStatus *my_status; 518 BWRequest request; 519 520 my_status = (BWStatus *) 521 BW->bitmap.request_stack[BW->bitmap.current].status; 522 523 my_status->draw = NULL; 524 525 request = (BWRequest) 526 BW->bitmap.request_stack[BW->bitmap.current].request->terminate_client_data; 527 528 BWTerminateRequest(w, FALSE); 529 530 if ((at_x == max(BW->bitmap.mark.from_x, min(at_x, BW->bitmap.mark.to_x))) 531 && 532 (at_y == max(BW->bitmap.mark.from_y, min(at_y, BW->bitmap.mark.to_y)))) { 533 534 BWStatus *status; 535 536 if (DEBUG) 537 fprintf(stderr, "Prepaste request: %s\n", request); 538 539 BWEngageRequest(w, request, False, (char *)&(my_status->state), sizeof(int)); 540 541 status = (BWStatus *) 542 BW->bitmap.request_stack[BW->bitmap.current].status; 543 544 status->at_x = at_x; 545 status->at_y = at_y; 546 status->value = value; 547 (*(DrawOnePointProc)status->draw) (w, at_x, at_y, Highlight); 548 } 549 else { 550 551 BWStatus *status; 552 553 BWEngageRequest(w, MarkRequest, False, (char *)&(my_status->state), sizeof(int)); 554 555 status = (BWStatus *) 556 BW->bitmap.request_stack[BW->bitmap.current].status; 557 558 status->from_x = status->to_x = at_x; 559 status->from_y = status->to_y = at_y; 560 status->value = value; 561 (*(DrawTwoPointProc)status->draw) (w, at_x, at_y, at_x, at_y, Highlight); 562 } 563} 564 565 566void 567DragTwoPointsHandler(Widget w, 568 XtPointer client_data, 569 XEvent *event, 570 Boolean *cont) /* ARGSUSED */ 571{ 572 BitmapWidget BW = (BitmapWidget) w; 573 BWStatus *status = (BWStatus *)client_data; 574 575 if (DEBUG) 576 fprintf(stderr, "D2PH "); 577 578 switch (event->type) { 579 580 case ButtonPress: 581 if (event->xbutton.state != status->state) return; 582 if (!QuerySet(status->from_x, status->from_y)) { 583 BWStoreToBuffer(w); 584 status->value = Value(BW, event->xbutton.button); 585 status->btime = event->xbutton.time; 586 status->from_x = InBitmapX(BW, event->xbutton.x); 587 status->from_y = InBitmapY(BW, event->xbutton.y); 588 status->to_x = InBitmapX(BW, event->xbutton.x); 589 status->to_y = InBitmapY(BW, event->xbutton.y); 590 status->success = status->draw ? True : False; 591 if (status->draw) 592 (*(DrawTwoPointProc)status->draw)(w, 593 status->from_x, status->from_y, 594 status->to_x, status->to_y, status->value); 595 } 596 break; 597 598 case ButtonRelease: 599 if (QuerySet(status->from_x, status->from_y)) { 600 status->value = Value(BW, event->xbutton.button); 601 status->btime = event->xbutton.time; 602 status->from_x = status->to_x; 603 status->from_y = status->to_y; 604 status->to_x = InBitmapX(BW, event->xbutton.x); 605 status->to_y = InBitmapY(BW, event->xbutton.y); 606 status->success = True; 607 608 BWTerminateRequest(w, TRUE); 609 } 610 break; 611 612 case MotionNotify: 613 if (QuerySet(status->from_x, status->from_y)) { 614 if (QuerySet(status->to_x, status->to_y)) { 615 if (!QueryInSquare(BW, event->xmotion.x, event->xmotion.y, 616 status->to_x, status->to_y)) { 617 status->from_x = status->to_x; 618 status->from_y = status->to_y; 619 status->to_x = InBitmapX(BW, event->xmotion.x); 620 status->to_y = InBitmapY(BW, event->xmotion.y); 621 if (status->draw) 622 (*(DrawTwoPointProc)status->draw)(w, 623 status->from_x, status->from_y, 624 status->to_x, status->to_y, status->value); 625 } 626 } 627 } 628 break; 629 } 630} 631 632void 633DragTwoPointsEngage(Widget w, 634 BWStatus *status, 635 XtPointer draw, 636 int *state) 637{ 638 639 status->from_x = NotSet; 640 status->from_y = NotSet; 641 status->to_x = NotSet; 642 status->to_y = NotSet; 643 status->draw = draw; 644 status->success = False; 645 status->state = *state; 646 647 XtAddEventHandler(w, 648 ButtonPressMask | ButtonReleaseMask | PointerMotionMask, 649 FALSE, DragTwoPointsHandler, (XtPointer)status); 650} 651 652void 653DragTwoPointsTerminate(Widget w, 654 BWStatus *status, 655 XtPointer draw) 656{ 657 658 if (status->success && draw) { 659 if ((status->from_x != status->to_x) 660 || 661 (status->from_y != status->to_y)) 662 (*(DrawTwoPointProc)draw)(w, 663 status->from_x, status->from_y, 664 status->to_x, status->to_y, 665 status->value); 666 BWChangeNotify(w); 667 BWSetChanged(w); 668 } 669 670 XtRemoveEventHandler(w, 671 ButtonPressMask | ButtonReleaseMask | PointerMotionMask, 672 FALSE, DragTwoPointsHandler, (XtPointer)status); 673} 674 675/*****************************************************************************/ 676