2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* $XConsortium: event.c /main/6 1996/10/21 15:28:00 mgreess $ */
24 /*********************************************************************
25 * (c) Copyright 1993, 1994 Hewlett-Packard Company
26 * (c) Copyright 1993, 1994 International Business Machines Corp.
27 * (c) Copyright 1993, 1994 Sun Microsystems, Inc.
28 * (c) Copyright 1993, 1994 Unix System Labs, Inc., a subsidiary of
30 **********************************************************************/
31 /******************************************************************************
34 ** Description: X11-based multi-color icon editor
36 ** File: event.c, which contains the following subroutines or
39 ** ProcessTabletEvent()
46 ******************************************************************************
48 ** Copyright Hewlett-Packard Company, 1990, 1991, 1992.
49 ** All rights are reserved. Copying or reproduction of this program,
50 ** except for archival purposes, is prohibited without prior written
51 ** consent of Hewlett-Packard Company.
53 ** Hewlett-Packard makes no representations about the suitibility of this
54 ** software for any purpose. It is provided "as is" without express or
57 ******************************************************************************/
59 #include "externals.h"
63 extern Widget iconForm;
66 static Boolean DoingHotBox=False;
67 static XtIntervalId polyTimerID;
68 Widget coordinateText;
69 static int Prev_x, Prev_y;
72 Clear_ClickCount( void )
76 stat_out(" - CLICK-COUNT ZEROED.\n");
81 /* Forward declarations */
102 void Do_ButtonOp(XEvent *);
104 /***************************************************************************
106 * Routine: ProcessTabletEvent *
108 * Purpose: Global event-handling routine for user input on the tablet. *
110 ***************************************************************************/
117 Cardinal num_params )
121 Dimension db_width, db_height;
123 int x, y, width, height, i, n, xGrid, yGrid;
128 ClickCount = atoi(params[2]);
134 case ButtonPress : x = xptr->xbutton.x;
138 printf("Btn Press at [%d,%d]\n", x, y);
140 if (xptr->xbutton.window == tablet_win)
143 case MotionNotify : x = xptr->xmotion.x;
146 /* Adjust for the Magnification Factor */
147 xGrid = x/MagFactor + 1;
148 yGrid = y/MagFactor + 1;
151 if coordinates are different then
152 update Previous x & y
153 Display new coordinates, but first...
154 If the ERASER is ON then
155 redraw the contents of the previous Rect.
156 Draw the bounding Rect.
158 if (xGrid!=Prev_x || yGrid!=Prev_y){
159 if (GraphicsOp == ERASER)
161 Transfer_Back_Image(Prev_x-2, Prev_y-2,
162 (Prev_x+1), (Prev_y+1), HOLLOW);
163 XDrawRectangle(dpy, tablet_win, Erase_gc,
164 xGrid*MagFactor-(2*MagFactor),
165 yGrid*MagFactor-(2*MagFactor),
166 (3*MagFactor), (3*MagFactor) );
171 sprintf(tmpstr, "%dx%d", xGrid, yGrid);
172 str= XmStringCreateLocalized (tmpstr);
173 XtVaSetValues (coordinateText, XmNlabelString, str, NULL);
178 printf("Btn Motion at [%d,%d]\n", x, y);
180 if (xptr->xmotion.window == tablet_win)
183 case ButtonRelease : x = xptr->xbutton.x;
187 printf("Btn Release at [%d,%d]", x, y);
189 printf(", CLICK COUNT = %d", ClickCount);
193 if (xptr->xbutton.window == tablet_win)
196 case Expose : if (!tablet_win) {
197 tablet_win = XtWindow(tablet_wid);
199 if (xptr->xexpose.window == tablet_win) {
202 width = xptr->xexpose.width;
203 height = xptr->xexpose.height;
206 printf("Exposure at [%d,%d] of %dx%d\n", x, y, width, height);
208 Repaint_Tablet(xptr->xexpose.window, x, y,
211 else if (xptr->xexpose.window ==
212 XtWindow(iconImage)) {
213 XCopyArea(dpy, color_icon,
215 Color_gc, 0, 0, icon_width, icon_height, 0, 0);
218 printf("Exposure on iconImage: REPAINTING\n");
221 else if (xptr->xexpose.window ==
222 XtWindow(monoImage)) {
223 XCopyArea(dpy, mono_icon,
225 Color_gc, 0, 0, icon_width, icon_height, 0, 0);
228 printf("Exposure on monoImage: REPAINTING\n");
231 if (argsNeedProcessed)
234 case EnterNotify : x = xptr->xcrossing.x;
235 y = xptr->xcrossing.y;
238 printf("Enter window at [%d,%d]\n", x, y);
241 case LeaveNotify : x = xptr->xcrossing.x;
242 y = xptr->xcrossing.y;
245 restore contents of bounding Rect when
246 leaving the tablet */
247 if (GraphicsOp == ERASER )
248 Transfer_Back_Image(Prev_x-2, Prev_y-2,
249 (Prev_x+1), (Prev_y+1), HOLLOW);
250 if (xptr->xcrossing.window == tablet_win)
254 printf("Leave window at [%d,%d]\n", x, y);
256 XtSetArg(args[i], XmNwidth, &db_width); i++;
257 XtSetArg(args[i], XmNheight, &db_height); i++;
258 XtGetValues(iconForm, args, i);
259 stat_out(" - iconForm dimensions: [%dx%d]\n", db_width, db_height);
261 XtSetArg(args[i], XmNwidth, &db_width); i++;
262 XtGetValues(iconImage, args, i);
263 stat_out(" - icon widths: %d\n", db_width);
271 printf("Focus change\n");
277 printf("UNKNOWN type: %d\n", xptr->type);
285 /***************************************************************************
287 * Routine: Do_ButtonOp *
289 * Purpose: Process ButtonPress/ButtonMotion/ButtonRelease events *
290 * generated by the user on the tablet. Switch between correct *
291 * behaviors depending on the current GraphicsOp tool selected. *
293 ***************************************************************************/
295 static int Pressed = False, First = False;
302 int e_type, x, y, i, j;
310 case ButtonRelease : x = xptr->xbutton.x;
312 lwin = xptr->xbutton.window;
314 case MotionNotify : x = xptr->xmotion.x;
316 lwin = xptr->xmotion.window;
322 switch (GraphicsOp) {
323 case S_HOTSPOT : if (xptr->xbutton.window == tablet_win) {
326 Icon_Coords(tx, ty, &ix, &iy);
332 stat_out(" - HOTSPOT selected at [%d,%d]\n", ix, iy);
334 Repaint_Exposed_Tablet();
339 case S_SCALE_2 : tx = x;
341 if (GraphicsOp == S_PASTE)
342 XDrawRectangle(dpy, tablet_win,
343 Flicker_gc, last_tx, last_ty,
344 CutCopy->width*MagFactor - MagFactor,
345 CutCopy->height*MagFactor - MagFactor);
346 else if (GraphicsOp == S_ROTATE)
347 XDrawRectangle(dpy, tablet_win,
348 Flicker_gc, last_tx, last_ty,
349 Rotate->width*MagFactor - MagFactor,
350 Rotate->height*MagFactor - MagFactor);
352 XDrawRectangle(dpy, tablet_win,
353 Flicker_gc, last_tx, last_ty,
354 Scale->width*MagFactor - MagFactor,
355 Scale->height*MagFactor - MagFactor);
356 Icon_Coords(tx, ty, &ix, &iy);
360 case POINT : Pressed = True;
365 Icon_Coords(tx, ty, &ix, &iy);
367 if (GraphicsOp == ERASER) {
368 for (i=ix-1; i<=ix+1; i++)
369 for (j=iy-1; j<=iy+1; j++) {
370 XDrawPoint(dpy, color_icon, Erase_gc, i, j);
374 XDrawPoint(dpy, mono_icon, Erase_gc, i, j);
378 Paint_Tile(i, j, Erase_gc);
382 XDrawPoint(dpy, color_icon, Color_gc, ix, iy);
383 XDrawPoint(dpy, XtWindow(iconImage),
385 XDrawPoint(dpy, mono_icon, Mono_gc, ix, iy);
386 XDrawPoint(dpy, XtWindow(monoImage),
388 Paint_Tile(ix, iy, Color_gc);
391 case SELECT : if (DoingHotBox) {
400 case RECTANGLE : Quantize(&x, &y, True);
409 stat_out(" - Quantized to [%d,%d]\n", x, y);
412 case S_GRAB : XGrabServer(dpy);
423 Quantize(&x, &y, True);
427 Icon_Coords(tx, ty, &ix, &iy);
428 pointList[pointCount].x = ix;
429 pointList[pointCount].y = iy;
430 if (pointCount < MAX_PTS) {
434 stat_out(" - pointCount++ [%d]\n", pointCount);
446 if (GraphicsOp == POLYGON)
450 Icon_Coords(last_tx, last_ty, &last_ix, &last_iy);
451 iLine(ix, iy, last_ix, last_iy, False);
456 polyTimerID = XtAppAddTimeOut( AppContext,
458 (XtTimerCallbackProc)
462 } /* switch(GraphicsOp) */
465 switch (GraphicsOp) {
467 case POINT : if (Pressed) {
472 Icon_Coords(tx, ty, &ix, &iy);
473 if (GraphicsOp == ERASER) {
474 for (i=ix-1; i<=ix+1; i++)
475 for (j=iy-1; j<=iy+1; j++) {
476 XDrawPoint(dpy, color_icon, Erase_gc, i, j);
480 XDrawPoint(dpy, mono_icon, Erase_gc, i, j);
484 Paint_Tile(i, j, Erase_gc);
486 } /* if(GraphicsOp...) */
488 XDrawPoint(dpy, color_icon, Color_gc, ix, iy);
489 XDrawPoint(dpy, XtWindow(iconImage),
491 XDrawPoint(dpy, mono_icon, Mono_gc, ix, iy);
492 XDrawPoint(dpy, XtWindow(monoImage),
494 Paint_Tile(ix, iy, Color_gc);
501 Icon_Coords(tx, ty, &ix, &iy);
502 Flood_Region(ix, iy);
504 case LINE : if (Pressed) {
505 Quantize(&x, &y, True);
508 stat_out(" - Quantized to [%d,%d]\n", x, y);
510 XDrawLine(dpy, tablet_win,
511 Flicker_gc, tx, ty, last_tx, last_ty);
515 Icon_Coords(tx, ty, &ix, &iy);
516 Icon_Coords(last_tx, last_ty, &last_ix, &last_iy);
517 iLine(ix, iy, last_ix, last_iy, True);
521 case SELECT : if (Pressed) {
522 Quantize(&x, &y, True);
523 XDrawRectangle(dpy, tablet_win,
524 Flicker_gc, min(tx, last_tx), min(ty, last_ty),
525 abs(tx-last_tx), abs(ty-last_ty));
529 Icon_Coords(tx, ty, &ix, &iy);
530 Icon_Coords(last_tx, last_ty, &last_ix, &last_iy);
531 if (GraphicsOp == SELECT) {
533 Start_HotBox(INITIAL);
536 Scale_Image(); /***TAG***/
537 GraphicsOp = S_SCALE_2;
541 case S_GRAB : if (Pressed) {
542 XDrawRectangle(dpy, lwin,
543 Flicker_gc, min(tx, last_tx), min(ty, last_ty),
544 abs(tx-last_tx), abs(ty-last_ty));
545 if (mag(last_tx, x) <= xrdb.maxIconWidth)
547 if (mag(last_ty, y) <= xrdb.maxIconHeight)
550 min(tx, last_tx), min(ty, last_ty),
551 abs(tx-last_tx), abs(ty-last_ty));
552 GraphicsOp = Backup_G_Op;
557 case RECTANGLE : if (Pressed) {
558 Quantize(&x, &y, True);
559 XDrawRectangle(dpy, tablet_win,
560 Flicker_gc, min(tx, last_tx), min(ty, last_ty),
561 abs(tx-last_tx), abs(ty-last_ty));
565 Icon_Coords(tx, ty, &ix, &iy);
566 Icon_Coords(last_tx, last_ty, &last_ix, &last_iy);
567 iRectangle(min(ix, last_ix), min(iy, last_iy),
568 abs(ix-last_ix), abs(iy-last_iy), True);
572 case S_WAIT_RELEASE :
573 GraphicsOp = Backup_G_Op;
581 case CIRCLE : if (Pressed) {
582 Quantize(&x, &y, True);
583 Circle_Box(tablet_win,
584 last_tx, last_ty, tx, ty, &box);
591 ((short)(box.width - 1) / MagFactor) + 1;
593 ((short)(box.height - 1) / MagFactor) + 1;
594 iArc(box.x, box.y, box.width, box.height, True);
597 case ELLIPSE : if (Pressed) {
598 Quantize(&x, &y, True);
599 XDrawArc(dpy, tablet_win,
600 Flicker_gc, min(tx, last_tx), min(ty, last_ty),
601 abs(tx-last_tx), abs(ty-last_ty), 0, 360*64);
605 Icon_Coords(tx, ty, &ix, &iy);
606 Icon_Coords(last_tx, last_ty, &last_ix, &last_iy);
607 iArc( min(ix, last_ix), min(iy, last_iy),
608 abs(ix-last_ix)+1, abs(iy-last_iy)+1, True);
611 } /* switch(GraphicsOp) */
614 switch (GraphicsOp) {
617 case S_SCALE_2 : last_tx = tx;
622 if (GraphicsOp == S_PASTE)
623 XDrawRectangle(dpy, tablet_win,
624 Flicker_gc, last_tx, last_ty,
625 CutCopy->width*MagFactor - MagFactor,
626 CutCopy->height*MagFactor - MagFactor);
627 else if (GraphicsOp == S_ROTATE)
628 XDrawRectangle(dpy, tablet_win,
629 Flicker_gc, last_tx, last_ty,
630 Rotate->width*MagFactor - MagFactor,
631 Rotate->height*MagFactor - MagFactor);
633 XDrawRectangle(dpy, tablet_win,
634 Flicker_gc, last_tx, last_ty,
635 Scale->width*MagFactor - MagFactor,
636 Scale->height*MagFactor - MagFactor);
638 if (GraphicsOp == S_PASTE)
639 XDrawRectangle(dpy, tablet_win,
641 CutCopy->width*MagFactor - MagFactor,
642 CutCopy->height*MagFactor - MagFactor);
643 else if (GraphicsOp == S_ROTATE)
644 XDrawRectangle(dpy, tablet_win,
646 Rotate->width*MagFactor - MagFactor,
647 Rotate->height*MagFactor - MagFactor);
649 XDrawRectangle(dpy, tablet_win,
651 Scale->width*MagFactor - MagFactor,
652 Scale->height*MagFactor - MagFactor);
654 case S_HOTSPOT : break;
656 case POINT : if (Pressed) {
661 Icon_Coords(tx, ty, &ix, &iy);
662 if (GraphicsOp == ERASER) {
663 for (i=ix-1; i<=ix+1; i++)
664 for (j=iy-1; j<=iy+1; j++) {
665 XDrawPoint(dpy, color_icon, Erase_gc, i, j);
669 XDrawPoint(dpy, mono_icon, Erase_gc, i, j);
673 Paint_Tile(i, j, Erase_gc);
675 } /* if(GraphicsOp...) */
677 XDrawPoint(dpy, color_icon, Color_gc, ix, iy);
678 XDrawPoint(dpy, XtWindow(iconImage),
680 XDrawPoint(dpy, mono_icon, Mono_gc, ix, iy);
681 XDrawPoint(dpy, XtWindow(monoImage),
683 Paint_Tile(ix, iy, Color_gc);
688 case POLYGON : if (Anchored) {
689 Quantize(&x, &y, True);
691 XDrawLine(dpy, tablet_win,
692 Flicker_gc, tx, ty, last_tx, last_ty);
695 XDrawLine(dpy, tablet_win,
696 Flicker_gc, tx, ty, last_tx, last_ty);
700 case LINE : if (Pressed) {
701 Quantize(&x, &y, True);
703 XDrawLine(dpy, tablet_win,
704 Flicker_gc, tx, ty, last_tx, last_ty);
707 XDrawLine(dpy, tablet_win,
708 Flicker_gc, tx, ty, last_tx, last_ty);
715 case RECTANGLE : if (Pressed) {
716 Quantize(&x, &y, True);
718 if (GraphicsOp != ELLIPSE)
719 XDrawRectangle(dpy, tablet_win, Flicker_gc,
720 min(tx, last_tx), min(ty, last_ty),
721 abs(tx-last_tx), abs(ty-last_ty));
723 XDrawArc(dpy, tablet_win, Flicker_gc,
724 min(tx, last_tx), min(ty, last_ty),
725 abs(tx-last_tx), abs(ty-last_ty),
730 if (GraphicsOp != ELLIPSE)
731 XDrawRectangle(dpy, tablet_win,
732 Flicker_gc, min(tx, last_tx), min(ty, last_ty),
733 abs(tx-last_tx), abs(ty-last_ty));
735 XDrawArc(dpy, tablet_win,
736 Flicker_gc, min(tx, last_tx), min(ty, last_ty),
737 abs(tx-last_tx), abs(ty-last_ty), 0, 360*64);
741 case S_GRAB : if (Pressed) {
743 XDrawRectangle(dpy, lwin, Flicker_gc,
744 min(tx, last_tx), min(ty, last_ty),
745 abs(tx-last_tx), abs(ty-last_ty));
746 if (mag(last_tx, x) <= xrdb.maxIconWidth)
748 if (mag(last_ty, y) <= xrdb.maxIconHeight)
750 XDrawRectangle(dpy, lwin,
751 Flicker_gc, min(tx, last_tx), min(ty, last_ty),
752 abs(tx-last_tx), abs(ty-last_ty));
754 /* Tell the user the size of the grabbed image
757 GETSTR(18,2,"Grabbed Image Size = %dx%d"),
758 abs(tx-last_tx), abs(ty-last_ty));
759 str= XmStringCreateLocalized (tmpstr);
760 XtVaSetValues (coordinateText, XmNlabelString, str, NULL);
764 case CIRCLE : if (Pressed) {
765 Quantize(&x, &y, True);
767 Circle_Box(tablet_win,
768 last_tx, last_ty, tx, ty, &box);
771 Circle_Box(tablet_win,
772 last_tx, last_ty, tx, ty, &box);
776 } /* switch(GraphicsOp) */
779 switch (GraphicsOp) {
781 case POLYGON : if (Anchored) {
783 XDrawLine(dpy, tablet_win, Flicker_gc, tx, ty,
788 } /* switch(GraphicsOp) */
790 } /* switch(e_type) */
794 /***************************************************************************
795 * Routine: EndPolyOp *
796 * Purpose: When user does a mouse action outside of the drawing window, *
797 * this implicitly ends the poly* operation. This means that *
798 * things like drawing circles and changing pen color while in *
799 * the middle of a polyline or polygon is no longer allowed. *
800 ***************************************************************************/
819 XDrawLine(dpy, color_icon, Color_gc, x1, y1, x2, y2);
820 XDrawLine(dpy, mono_icon, Mono_gc, x1, y1, x2, y2);
821 XDrawLine(dpy, XtWindow(iconImage), Color_gc, x1, y1, x2, y2);
822 XDrawLine(dpy, XtWindow(monoImage), Mono_gc, x1, y1, x2, y2);
825 stat_out("Transferring from [%d,%d] to [%d,%d]\n", tx, ty,
828 Transfer_Back_Image(x1, y1, x2, y2, FILL);
842 XFillRectangle(dpy, color_icon, Color_gc, x, y, width+1, height+1);
843 XFillRectangle(dpy, mono_icon, Mono_gc, x, y, width+1, height+1);
844 XFillRectangle(dpy, XtWindow(iconImage), Color_gc,
845 x, y, width+1, height+1);
846 XFillRectangle(dpy, XtWindow(monoImage), Mono_gc,
847 x, y, width+1, height+1);
850 XDrawRectangle(dpy, color_icon, Color_gc, x, y, width, height);
851 XDrawRectangle(dpy, mono_icon, Mono_gc, x, y, width, height);
852 XDrawRectangle(dpy, XtWindow(iconImage), Color_gc,
853 x, y, width, height);
854 XDrawRectangle(dpy, XtWindow(monoImage), Mono_gc,
855 x, y, width, height);
857 Transfer_Back_Image(x, y, x+width, y+height, FILL);
871 XFillArc(dpy, color_icon, Color_gc, x, y, width, height, 0, 360*64);
872 XFillArc(dpy, mono_icon, Mono_gc, x, y, width, height, 0, 360*64);
873 XFillArc(dpy, XtWindow(iconImage),
874 Color_gc, x, y, width, height, 0, 360*64);
875 XFillArc(dpy, XtWindow(monoImage),
876 Mono_gc, x, y, width, height, 0, 360*64);
879 XDrawArc(dpy, color_icon, Color_gc, x, y, width, height, 0, 360*64);
880 XDrawArc(dpy, mono_icon, Mono_gc, x, y, width, height, 0, 360*64);
881 XDrawArc(dpy, XtWindow(iconImage),
882 Color_gc, x, y, width, height, 0, 360*64);
883 XDrawArc(dpy, XtWindow(monoImage),
884 Mono_gc, x, y, width, height, 0, 360*64);
886 Transfer_Back_Image(x, y, x+width, y+height, FILL);
892 int min_x, min_y, max_x, max_y, i;
896 stat_out("iPolygon: pointCount = %d\n", pointCount);
900 XFillPolygon(dpy, color_icon, Color_gc, pointList, pointCount,
901 Complex, CoordModeOrigin);
902 XFillPolygon(dpy, mono_icon, Mono_gc, pointList, pointCount,
903 Complex, CoordModeOrigin);
904 XFillPolygon(dpy, XtWindow(iconImage),
905 Color_gc, pointList, pointCount, Complex, CoordModeOrigin);
906 XFillPolygon(dpy, XtWindow(monoImage),
907 Mono_gc, pointList, pointCount, Complex, CoordModeOrigin);
910 if (pointCount < MAX_PTS) {
911 pointList[pointCount].x = pointList[0].x;
912 pointList[pointCount].y = pointList[0].y;
915 XDrawLines(dpy, color_icon, Color_gc, pointList, pointCount, Complex);
916 XDrawLines(dpy, mono_icon, Mono_gc, pointList, pointCount, Complex);
917 XDrawLines(dpy, XtWindow(iconImage), Color_gc, pointList,
918 pointCount, Complex);
919 XDrawLines(dpy, XtWindow(monoImage), Mono_gc, pointList,
920 pointCount, Complex);
922 min_x = pointList[0].x;
923 min_y = pointList[0].y;
926 for (i=1; i<pointCount; i++) {
927 if (pointList[i].x < min_x) min_x = pointList[i].x;
928 if (pointList[i].y < min_y) min_y = pointList[i].y;
929 if (pointList[i].x > max_x) max_x = pointList[i].x;
930 if (pointList[i].y > max_y) max_y = pointList[i].y;
932 Transfer_Back_Image(min_x, min_y, max_x, max_y, FILL);