Home | History | Annotate | Line # | Download | only in dist
      1 /*
      2 
      3 Copyright 1989, 1998  The Open Group
      4 
      5 Permission to use, copy, modify, distribute, and sell this software and its
      6 documentation for any purpose is hereby granted without fee, provided that
      7 the above copyright notice appear in all copies and that both that
      8 copyright notice and this permission notice appear in supporting
      9 documentation.
     10 
     11 The above copyright notice and this permission notice shall be included
     12 in all copies or substantial portions of the Software.
     13 
     14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     15 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     16 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
     17 IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
     18 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     19 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     20 OTHER DEALINGS IN THE SOFTWARE.
     21 
     22 Except as contained in this notice, the name of The Open Group shall
     23 not be used in advertising or otherwise to promote the sale, use or
     24 other dealings in this Software without prior written authorization
     25 from 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 
     59 static void
     60 DragOnePointHandler(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 
    115 void
    116 DragOnePointEngage(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 */
    134 void
    135 DragOnePointTerminate(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 
    151 void
    152 OnePointHandler(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 
    224 void
    225 OnePointEngage(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
    243 void
    244 OnePointImmediateEngage(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 
    266 void
    267 OnePointTerminate(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 
    292 void
    293 OnePointTerminateTransparent(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 
    316 void
    317 TwoPointsHandler(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 
    404 void
    405 TwoPointsEngage(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 
    425 void
    426 TwoPointsTerminate(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 
    454 void
    455 TwoPointsTerminateTransparent(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 
    479 void
    480 TwoPointsTerminateTimed(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 */
    505 void
    506 Interface(Widget w,
    507 	  BWStatus *status,
    508 	  XtPointer action)
    509 {
    510     (*(InterfaceProc)action)(w);
    511 }
    512 
    513 void
    514 Paste(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 
    569 void
    570 DragTwoPointsHandler(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 
    635 void
    636 DragTwoPointsEngage(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 
    655 void
    656 DragTwoPointsTerminate(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