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