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