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