1 /* $XConsortium: event.c /main/6 1996/10/21 15:28:00 mgreess $ */
2 /*********************************************************************
3 * (c) Copyright 1993, 1994 Hewlett-Packard Company
4 * (c) Copyright 1993, 1994 International Business Machines Corp.
5 * (c) Copyright 1993, 1994 Sun Microsystems, Inc.
6 * (c) Copyright 1993, 1994 Unix System Labs, Inc., a subsidiary of
8 **********************************************************************/
9 /******************************************************************************
12 ** Description: X11-based multi-color icon editor
14 ** File: event.c, which contains the following subroutines or
17 ** ProcessTabletEvent()
24 ******************************************************************************
26 ** Copyright Hewlett-Packard Company, 1990, 1991, 1992.
27 ** All rights are reserved. Copying or reproduction of this program,
28 ** except for archival purposes, is prohibited without prior written
29 ** consent of Hewlett-Packard Company.
31 ** Hewlett-Packard makes no representations about the suitibility of this
32 ** software for any purpose. It is provided "as is" without express or
35 ******************************************************************************/
37 #include "externals.h"
41 extern Widget iconForm;
44 static Boolean DoingHotBox=False;
45 static XtIntervalId polyTimerID;
46 Widget coordinateText;
47 static int Prev_x, Prev_y;
50 Clear_ClickCount( void )
54 stat_out(" - CLICK-COUNT ZEROED.\n");
59 /* Forward declarations */
80 void Do_ButtonOp(XEvent *);
82 /***************************************************************************
84 * Routine: ProcessTabletEvent *
86 * Purpose: Global event-handling routine for user input on the tablet. *
88 ***************************************************************************/
99 Dimension db_width, db_height;
101 int x, y, width, height, i, n, xGrid, yGrid;
106 ClickCount = atoi(params[2]);
112 case ButtonPress : x = xptr->xbutton.x;
116 printf("Btn Press at [%d,%d]\n", x, y);
118 if (xptr->xbutton.window == tablet_win)
121 case MotionNotify : x = xptr->xmotion.x;
124 /* Adjust for the Magnification Factor */
125 xGrid = x/MagFactor + 1;
126 yGrid = y/MagFactor + 1;
129 if coordinates are different then
130 update Previous x & y
131 Display new coordinates, but first...
132 If the ERASER is ON then
133 redraw the contents of the previous Rect.
134 Draw the bounding Rect.
136 if (xGrid!=Prev_x || yGrid!=Prev_y){
137 if (GraphicsOp == ERASER)
139 Transfer_Back_Image(Prev_x-2, Prev_y-2,
140 (Prev_x+1), (Prev_y+1), HOLLOW);
141 XDrawRectangle(dpy, tablet_win, Erase_gc,
142 xGrid*MagFactor-(2*MagFactor),
143 yGrid*MagFactor-(2*MagFactor),
144 (3*MagFactor), (3*MagFactor) );
149 sprintf(tmpstr, "%dx%d", xGrid, yGrid);
150 str= XmStringCreateLocalized (tmpstr);
151 XtVaSetValues (coordinateText, XmNlabelString, str, NULL);
156 printf("Btn Motion at [%d,%d]\n", x, y);
158 if (xptr->xmotion.window == tablet_win)
161 case ButtonRelease : x = xptr->xbutton.x;
165 printf("Btn Release at [%d,%d]", x, y);
167 printf(", CLICK COUNT = %d", ClickCount);
171 if (xptr->xbutton.window == tablet_win)
174 case Expose : if (!tablet_win) {
175 tablet_win = XtWindow(tablet_wid);
177 if (xptr->xexpose.window == tablet_win) {
180 width = xptr->xexpose.width;
181 height = xptr->xexpose.height;
184 printf("Exposure at [%d,%d] of %dx%d\n", x, y, width, height);
186 Repaint_Tablet(xptr->xexpose.window, x, y,
189 else if (xptr->xexpose.window ==
190 XtWindow(iconImage)) {
191 XCopyArea(dpy, color_icon,
193 Color_gc, 0, 0, icon_width, icon_height, 0, 0);
196 printf("Exposure on iconImage: REPAINTING\n");
199 else if (xptr->xexpose.window ==
200 XtWindow(monoImage)) {
201 XCopyArea(dpy, mono_icon,
203 Color_gc, 0, 0, icon_width, icon_height, 0, 0);
206 printf("Exposure on monoImage: REPAINTING\n");
209 if (argsNeedProcessed)
212 case EnterNotify : x = xptr->xcrossing.x;
213 y = xptr->xcrossing.y;
216 printf("Enter window at [%d,%d]\n", x, y);
219 case LeaveNotify : x = xptr->xcrossing.x;
220 y = xptr->xcrossing.y;
223 restore contents of bounding Rect when
224 leaving the tablet */
225 if (GraphicsOp == ERASER )
226 Transfer_Back_Image(Prev_x-2, Prev_y-2,
227 (Prev_x+1), (Prev_y+1), HOLLOW);
228 if (xptr->xcrossing.window == tablet_win)
232 printf("Leave window at [%d,%d]\n", x, y);
234 XtSetArg(args[i], XmNwidth, &db_width); i++;
235 XtSetArg(args[i], XmNheight, &db_height); i++;
236 XtGetValues(iconForm, args, i);
237 stat_out(" - iconForm dimensions: [%dx%d]\n", db_width, db_height);
239 XtSetArg(args[i], XmNwidth, &db_width); i++;
240 XtGetValues(iconImage, args, i);
241 stat_out(" - icon widths: %d\n", db_width);
249 printf("Focus change\n");
255 printf("UNKNOWN type: %d\n", xptr->type);
263 /***************************************************************************
265 * Routine: Do_ButtonOp *
267 * Purpose: Process ButtonPress/ButtonMotion/ButtonRelease events *
268 * generated by the user on the tablet. Switch between correct *
269 * behaviors depending on the current GraphicsOp tool selected. *
271 ***************************************************************************/
273 static int Pressed = False, First = False;
280 int e_type, x, y, i, j;
288 case ButtonRelease : x = xptr->xbutton.x;
290 lwin = xptr->xbutton.window;
292 case MotionNotify : x = xptr->xmotion.x;
294 lwin = xptr->xmotion.window;
300 switch (GraphicsOp) {
301 case S_HOTSPOT : if (xptr->xbutton.window == tablet_win) {
304 Icon_Coords(tx, ty, &ix, &iy);
310 stat_out(" - HOTSPOT selected at [%d,%d]\n", ix, iy);
312 Repaint_Exposed_Tablet();
317 case S_SCALE_2 : tx = x;
319 if (GraphicsOp == S_PASTE)
320 XDrawRectangle(dpy, tablet_win,
321 Flicker_gc, last_tx, last_ty,
322 CutCopy->width*MagFactor - MagFactor,
323 CutCopy->height*MagFactor - MagFactor);
324 else if (GraphicsOp == S_ROTATE)
325 XDrawRectangle(dpy, tablet_win,
326 Flicker_gc, last_tx, last_ty,
327 Rotate->width*MagFactor - MagFactor,
328 Rotate->height*MagFactor - MagFactor);
330 XDrawRectangle(dpy, tablet_win,
331 Flicker_gc, last_tx, last_ty,
332 Scale->width*MagFactor - MagFactor,
333 Scale->height*MagFactor - MagFactor);
334 Icon_Coords(tx, ty, &ix, &iy);
338 case POINT : Pressed = True;
343 Icon_Coords(tx, ty, &ix, &iy);
345 if (GraphicsOp == ERASER) {
346 for (i=ix-1; i<=ix+1; i++)
347 for (j=iy-1; j<=iy+1; j++) {
348 XDrawPoint(dpy, color_icon, Erase_gc, i, j);
352 XDrawPoint(dpy, mono_icon, Erase_gc, i, j);
356 Paint_Tile(i, j, Erase_gc);
360 XDrawPoint(dpy, color_icon, Color_gc, ix, iy);
361 XDrawPoint(dpy, XtWindow(iconImage),
363 XDrawPoint(dpy, mono_icon, Mono_gc, ix, iy);
364 XDrawPoint(dpy, XtWindow(monoImage),
366 Paint_Tile(ix, iy, Color_gc);
369 case SELECT : if (DoingHotBox) {
378 case RECTANGLE : Quantize(&x, &y, True);
387 stat_out(" - Quantized to [%d,%d]\n", x, y);
390 case S_GRAB : XGrabServer(dpy);
401 Quantize(&x, &y, True);
405 Icon_Coords(tx, ty, &ix, &iy);
406 pointList[pointCount].x = ix;
407 pointList[pointCount].y = iy;
408 if (pointCount < MAX_PTS) {
412 stat_out(" - pointCount++ [%d]\n", pointCount);
424 if (GraphicsOp == POLYGON)
428 Icon_Coords(last_tx, last_ty, &last_ix, &last_iy);
429 iLine(ix, iy, last_ix, last_iy, False);
434 polyTimerID = XtAppAddTimeOut( AppContext,
436 (XtTimerCallbackProc)
440 } /* switch(GraphicsOp) */
443 switch (GraphicsOp) {
445 case POINT : if (Pressed) {
450 Icon_Coords(tx, ty, &ix, &iy);
451 if (GraphicsOp == ERASER) {
452 for (i=ix-1; i<=ix+1; i++)
453 for (j=iy-1; j<=iy+1; j++) {
454 XDrawPoint(dpy, color_icon, Erase_gc, i, j);
458 XDrawPoint(dpy, mono_icon, Erase_gc, i, j);
462 Paint_Tile(i, j, Erase_gc);
464 } /* if(GraphicsOp...) */
466 XDrawPoint(dpy, color_icon, Color_gc, ix, iy);
467 XDrawPoint(dpy, XtWindow(iconImage),
469 XDrawPoint(dpy, mono_icon, Mono_gc, ix, iy);
470 XDrawPoint(dpy, XtWindow(monoImage),
472 Paint_Tile(ix, iy, Color_gc);
479 Icon_Coords(tx, ty, &ix, &iy);
480 Flood_Region(ix, iy);
482 case LINE : if (Pressed) {
483 Quantize(&x, &y, True);
486 stat_out(" - Quantized to [%d,%d]\n", x, y);
488 XDrawLine(dpy, tablet_win,
489 Flicker_gc, tx, ty, last_tx, last_ty);
493 Icon_Coords(tx, ty, &ix, &iy);
494 Icon_Coords(last_tx, last_ty, &last_ix, &last_iy);
495 iLine(ix, iy, last_ix, last_iy, True);
499 case SELECT : if (Pressed) {
500 Quantize(&x, &y, True);
501 XDrawRectangle(dpy, tablet_win,
502 Flicker_gc, min(tx, last_tx), min(ty, last_ty),
503 abs(tx-last_tx), abs(ty-last_ty));
507 Icon_Coords(tx, ty, &ix, &iy);
508 Icon_Coords(last_tx, last_ty, &last_ix, &last_iy);
509 if (GraphicsOp == SELECT) {
511 Start_HotBox(INITIAL);
514 Scale_Image(); /***TAG***/
515 GraphicsOp = S_SCALE_2;
519 case S_GRAB : if (Pressed) {
520 XDrawRectangle(dpy, lwin,
521 Flicker_gc, min(tx, last_tx), min(ty, last_ty),
522 abs(tx-last_tx), abs(ty-last_ty));
523 if (mag(last_tx, x) <= xrdb.maxIconWidth)
525 if (mag(last_ty, y) <= xrdb.maxIconHeight)
528 min(tx, last_tx), min(ty, last_ty),
529 abs(tx-last_tx), abs(ty-last_ty));
530 GraphicsOp = Backup_G_Op;
535 case RECTANGLE : if (Pressed) {
536 Quantize(&x, &y, True);
537 XDrawRectangle(dpy, tablet_win,
538 Flicker_gc, min(tx, last_tx), min(ty, last_ty),
539 abs(tx-last_tx), abs(ty-last_ty));
543 Icon_Coords(tx, ty, &ix, &iy);
544 Icon_Coords(last_tx, last_ty, &last_ix, &last_iy);
545 iRectangle(min(ix, last_ix), min(iy, last_iy),
546 abs(ix-last_ix), abs(iy-last_iy), True);
550 case S_WAIT_RELEASE :
551 GraphicsOp = Backup_G_Op;
559 case CIRCLE : if (Pressed) {
560 Quantize(&x, &y, True);
561 Circle_Box(tablet_win,
562 last_tx, last_ty, tx, ty, &box);
569 ((short)(box.width - 1) / MagFactor) + 1;
571 ((short)(box.height - 1) / MagFactor) + 1;
572 iArc(box.x, box.y, box.width, box.height, True);
575 case ELLIPSE : if (Pressed) {
576 Quantize(&x, &y, True);
577 XDrawArc(dpy, tablet_win,
578 Flicker_gc, min(tx, last_tx), min(ty, last_ty),
579 abs(tx-last_tx), abs(ty-last_ty), 0, 360*64);
583 Icon_Coords(tx, ty, &ix, &iy);
584 Icon_Coords(last_tx, last_ty, &last_ix, &last_iy);
585 iArc( min(ix, last_ix), min(iy, last_iy),
586 abs(ix-last_ix)+1, abs(iy-last_iy)+1, True);
589 } /* switch(GraphicsOp) */
592 switch (GraphicsOp) {
595 case S_SCALE_2 : last_tx = tx;
600 if (GraphicsOp == S_PASTE)
601 XDrawRectangle(dpy, tablet_win,
602 Flicker_gc, last_tx, last_ty,
603 CutCopy->width*MagFactor - MagFactor,
604 CutCopy->height*MagFactor - MagFactor);
605 else if (GraphicsOp == S_ROTATE)
606 XDrawRectangle(dpy, tablet_win,
607 Flicker_gc, last_tx, last_ty,
608 Rotate->width*MagFactor - MagFactor,
609 Rotate->height*MagFactor - MagFactor);
611 XDrawRectangle(dpy, tablet_win,
612 Flicker_gc, last_tx, last_ty,
613 Scale->width*MagFactor - MagFactor,
614 Scale->height*MagFactor - MagFactor);
616 if (GraphicsOp == S_PASTE)
617 XDrawRectangle(dpy, tablet_win,
619 CutCopy->width*MagFactor - MagFactor,
620 CutCopy->height*MagFactor - MagFactor);
621 else if (GraphicsOp == S_ROTATE)
622 XDrawRectangle(dpy, tablet_win,
624 Rotate->width*MagFactor - MagFactor,
625 Rotate->height*MagFactor - MagFactor);
627 XDrawRectangle(dpy, tablet_win,
629 Scale->width*MagFactor - MagFactor,
630 Scale->height*MagFactor - MagFactor);
632 case S_HOTSPOT : break;
634 case POINT : if (Pressed) {
639 Icon_Coords(tx, ty, &ix, &iy);
640 if (GraphicsOp == ERASER) {
641 for (i=ix-1; i<=ix+1; i++)
642 for (j=iy-1; j<=iy+1; j++) {
643 XDrawPoint(dpy, color_icon, Erase_gc, i, j);
647 XDrawPoint(dpy, mono_icon, Erase_gc, i, j);
651 Paint_Tile(i, j, Erase_gc);
653 } /* if(GraphicsOp...) */
655 XDrawPoint(dpy, color_icon, Color_gc, ix, iy);
656 XDrawPoint(dpy, XtWindow(iconImage),
658 XDrawPoint(dpy, mono_icon, Mono_gc, ix, iy);
659 XDrawPoint(dpy, XtWindow(monoImage),
661 Paint_Tile(ix, iy, Color_gc);
666 case POLYGON : if (Anchored) {
667 Quantize(&x, &y, True);
669 XDrawLine(dpy, tablet_win,
670 Flicker_gc, tx, ty, last_tx, last_ty);
673 XDrawLine(dpy, tablet_win,
674 Flicker_gc, tx, ty, last_tx, last_ty);
678 case LINE : if (Pressed) {
679 Quantize(&x, &y, True);
681 XDrawLine(dpy, tablet_win,
682 Flicker_gc, tx, ty, last_tx, last_ty);
685 XDrawLine(dpy, tablet_win,
686 Flicker_gc, tx, ty, last_tx, last_ty);
693 case RECTANGLE : if (Pressed) {
694 Quantize(&x, &y, True);
696 if (GraphicsOp != ELLIPSE)
697 XDrawRectangle(dpy, tablet_win, Flicker_gc,
698 min(tx, last_tx), min(ty, last_ty),
699 abs(tx-last_tx), abs(ty-last_ty));
701 XDrawArc(dpy, tablet_win, Flicker_gc,
702 min(tx, last_tx), min(ty, last_ty),
703 abs(tx-last_tx), abs(ty-last_ty),
708 if (GraphicsOp != ELLIPSE)
709 XDrawRectangle(dpy, tablet_win,
710 Flicker_gc, min(tx, last_tx), min(ty, last_ty),
711 abs(tx-last_tx), abs(ty-last_ty));
713 XDrawArc(dpy, tablet_win,
714 Flicker_gc, min(tx, last_tx), min(ty, last_ty),
715 abs(tx-last_tx), abs(ty-last_ty), 0, 360*64);
719 case S_GRAB : if (Pressed) {
721 XDrawRectangle(dpy, lwin, Flicker_gc,
722 min(tx, last_tx), min(ty, last_ty),
723 abs(tx-last_tx), abs(ty-last_ty));
724 if (mag(last_tx, x) <= xrdb.maxIconWidth)
726 if (mag(last_ty, y) <= xrdb.maxIconHeight)
728 XDrawRectangle(dpy, lwin,
729 Flicker_gc, min(tx, last_tx), min(ty, last_ty),
730 abs(tx-last_tx), abs(ty-last_ty));
732 /* Tell the user the size of the grabbed image
735 GETSTR(18,2,"Grabbed Image Size = %dx%d"),
736 abs(tx-last_tx), abs(ty-last_ty));
737 str= XmStringCreateLocalized (tmpstr);
738 XtVaSetValues (coordinateText, XmNlabelString, str, NULL);
742 case CIRCLE : if (Pressed) {
743 Quantize(&x, &y, True);
745 Circle_Box(tablet_win,
746 last_tx, last_ty, tx, ty, &box);
749 Circle_Box(tablet_win,
750 last_tx, last_ty, tx, ty, &box);
754 } /* switch(GraphicsOp) */
757 switch (GraphicsOp) {
759 case POLYGON : if (Anchored) {
761 XDrawLine(dpy, tablet_win, Flicker_gc, tx, ty,
766 } /* switch(GraphicsOp) */
768 } /* switch(e_type) */
772 /***************************************************************************
773 * Routine: EndPolyOp *
774 * Purpose: When user does a mouse action outside of the drawing window, *
775 * this implicitly ends the poly* operation. This means that *
776 * things like drawing circles and changing pen color while in *
777 * the middle of a polyline or polygon is no longer allowed. *
778 ***************************************************************************/
797 XDrawLine(dpy, color_icon, Color_gc, x1, y1, x2, y2);
798 XDrawLine(dpy, mono_icon, Mono_gc, x1, y1, x2, y2);
799 XDrawLine(dpy, XtWindow(iconImage), Color_gc, x1, y1, x2, y2);
800 XDrawLine(dpy, XtWindow(monoImage), Mono_gc, x1, y1, x2, y2);
803 stat_out("Transferring from [%d,%d] to [%d,%d]\n", tx, ty,
806 Transfer_Back_Image(x1, y1, x2, y2, FILL);
820 XFillRectangle(dpy, color_icon, Color_gc, x, y, width+1, height+1);
821 XFillRectangle(dpy, mono_icon, Mono_gc, x, y, width+1, height+1);
822 XFillRectangle(dpy, XtWindow(iconImage), Color_gc,
823 x, y, width+1, height+1);
824 XFillRectangle(dpy, XtWindow(monoImage), Mono_gc,
825 x, y, width+1, height+1);
828 XDrawRectangle(dpy, color_icon, Color_gc, x, y, width, height);
829 XDrawRectangle(dpy, mono_icon, Mono_gc, x, y, width, height);
830 XDrawRectangle(dpy, XtWindow(iconImage), Color_gc,
831 x, y, width, height);
832 XDrawRectangle(dpy, XtWindow(monoImage), Mono_gc,
833 x, y, width, height);
835 Transfer_Back_Image(x, y, x+width, y+height, FILL);
849 XFillArc(dpy, color_icon, Color_gc, x, y, width, height, 0, 360*64);
850 XFillArc(dpy, mono_icon, Mono_gc, x, y, width, height, 0, 360*64);
851 XFillArc(dpy, XtWindow(iconImage),
852 Color_gc, x, y, width, height, 0, 360*64);
853 XFillArc(dpy, XtWindow(monoImage),
854 Mono_gc, x, y, width, height, 0, 360*64);
857 XDrawArc(dpy, color_icon, Color_gc, x, y, width, height, 0, 360*64);
858 XDrawArc(dpy, mono_icon, Mono_gc, x, y, width, height, 0, 360*64);
859 XDrawArc(dpy, XtWindow(iconImage),
860 Color_gc, x, y, width, height, 0, 360*64);
861 XDrawArc(dpy, XtWindow(monoImage),
862 Mono_gc, x, y, width, height, 0, 360*64);
864 Transfer_Back_Image(x, y, x+width, y+height, FILL);
870 int min_x, min_y, max_x, max_y, i;
874 stat_out("iPolygon: pointCount = %d\n", pointCount);
878 XFillPolygon(dpy, color_icon, Color_gc, pointList, pointCount,
879 Complex, CoordModeOrigin);
880 XFillPolygon(dpy, mono_icon, Mono_gc, pointList, pointCount,
881 Complex, CoordModeOrigin);
882 XFillPolygon(dpy, XtWindow(iconImage),
883 Color_gc, pointList, pointCount, Complex, CoordModeOrigin);
884 XFillPolygon(dpy, XtWindow(monoImage),
885 Mono_gc, pointList, pointCount, Complex, CoordModeOrigin);
888 if (pointCount < MAX_PTS) {
889 pointList[pointCount].x = pointList[0].x;
890 pointList[pointCount].y = pointList[0].y;
893 XDrawLines(dpy, color_icon, Color_gc, pointList, pointCount, Complex);
894 XDrawLines(dpy, mono_icon, Mono_gc, pointList, pointCount, Complex);
895 XDrawLines(dpy, XtWindow(iconImage), Color_gc, pointList,
896 pointCount, Complex);
897 XDrawLines(dpy, XtWindow(monoImage), Mono_gc, pointList,
898 pointCount, Complex);
900 min_x = pointList[0].x;
901 min_y = pointList[0].y;
904 for (i=1; i<pointCount; i++) {
905 if (pointList[i].x < min_x) min_x = pointList[i].x;
906 if (pointList[i].y < min_y) min_y = pointList[i].y;
907 if (pointList[i].x > max_x) max_x = pointList[i].x;
908 if (pointList[i].y > max_y) max_y = pointList[i].y;
910 Transfer_Back_Image(min_x, min_y, max_x, max_y, FILL);