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 libraries 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 ******************************************************************************/
61 #include "externals.h"
65 extern Widget iconForm;
68 static Boolean DoingHotBox=False;
69 static XtIntervalId polyTimerID;
70 Widget coordinateText;
71 static int Prev_x, Prev_y;
74 Clear_ClickCount( void )
78 stat_out(" - CLICK-COUNT ZEROED.\n");
83 /* Forward declarations */
104 void Do_ButtonOp(XEvent *);
106 /***************************************************************************
108 * Routine: ProcessTabletEvent *
110 * Purpose: Global event-handling routine for user input on the tablet. *
112 ***************************************************************************/
119 Cardinal num_params )
123 Dimension db_width, db_height;
125 int x, y, width, height, i, n, xGrid, yGrid;
130 ClickCount = atoi(params[2]);
136 case ButtonPress : x = xptr->xbutton.x;
140 printf("Btn Press at [%d,%d]\n", x, y);
142 if (xptr->xbutton.window == tablet_win)
145 case MotionNotify : x = xptr->xmotion.x;
148 /* Adjust for the Magnification Factor */
149 xGrid = x/MagFactor + 1;
150 yGrid = y/MagFactor + 1;
153 if coordinates are different then
154 update Previous x & y
155 Display new coordinates, but first...
156 If the ERASER is ON then
157 redraw the contents of the previous Rect.
158 Draw the bounding Rect.
160 if (xGrid!=Prev_x || yGrid!=Prev_y){
161 if (GraphicsOp == ERASER)
163 Transfer_Back_Image(Prev_x-2, Prev_y-2,
164 (Prev_x+1), (Prev_y+1), HOLLOW);
165 XDrawRectangle(dpy, tablet_win, Erase_gc,
166 xGrid*MagFactor-(2*MagFactor),
167 yGrid*MagFactor-(2*MagFactor),
168 (3*MagFactor), (3*MagFactor) );
173 sprintf(tmpstr, "%dx%d", xGrid, yGrid);
174 str= XmStringCreateLocalized (tmpstr);
175 XtVaSetValues (coordinateText, XmNlabelString, str, NULL);
180 printf("Btn Motion at [%d,%d]\n", x, y);
182 if (xptr->xmotion.window == tablet_win)
185 case ButtonRelease : x = xptr->xbutton.x;
189 printf("Btn Release at [%d,%d]", x, y);
191 printf(", CLICK COUNT = %d", ClickCount);
195 if (xptr->xbutton.window == tablet_win)
198 case Expose : if (!tablet_win) {
199 tablet_win = XtWindow(tablet_wid);
201 if (xptr->xexpose.window == tablet_win) {
204 width = xptr->xexpose.width;
205 height = xptr->xexpose.height;
208 printf("Exposure at [%d,%d] of %dx%d\n", x, y, width, height);
210 Repaint_Tablet(xptr->xexpose.window, x, y,
213 else if (xptr->xexpose.window ==
214 XtWindow(iconImage)) {
215 XCopyArea(dpy, color_icon,
217 Color_gc, 0, 0, icon_width, icon_height, 0, 0);
220 printf("Exposure on iconImage: REPAINTING\n");
223 else if (xptr->xexpose.window ==
224 XtWindow(monoImage)) {
225 XCopyArea(dpy, mono_icon,
227 Color_gc, 0, 0, icon_width, icon_height, 0, 0);
230 printf("Exposure on monoImage: REPAINTING\n");
233 if (argsNeedProcessed)
236 case EnterNotify : x = xptr->xcrossing.x;
237 y = xptr->xcrossing.y;
240 printf("Enter window at [%d,%d]\n", x, y);
243 case LeaveNotify : x = xptr->xcrossing.x;
244 y = xptr->xcrossing.y;
247 restore contents of bounding Rect when
248 leaving the tablet */
249 if (GraphicsOp == ERASER )
250 Transfer_Back_Image(Prev_x-2, Prev_y-2,
251 (Prev_x+1), (Prev_y+1), HOLLOW);
252 if (xptr->xcrossing.window == tablet_win)
256 printf("Leave window at [%d,%d]\n", x, y);
258 XtSetArg(args[i], XmNwidth, &db_width); i++;
259 XtSetArg(args[i], XmNheight, &db_height); i++;
260 XtGetValues(iconForm, args, i);
261 stat_out(" - iconForm dimensions: [%dx%d]\n", db_width, db_height);
263 XtSetArg(args[i], XmNwidth, &db_width); i++;
264 XtGetValues(iconImage, args, i);
265 stat_out(" - icon widths: %d\n", db_width);
273 printf("Focus change\n");
279 printf("UNKNOWN type: %d\n", xptr->type);
287 /***************************************************************************
289 * Routine: Do_ButtonOp *
291 * Purpose: Process ButtonPress/ButtonMotion/ButtonRelease events *
292 * generated by the user on the tablet. Switch between correct *
293 * behaviors depending on the current GraphicsOp tool selected. *
295 ***************************************************************************/
297 static int Pressed = False, First = False;
304 int e_type, x, y, i, j;
312 case ButtonRelease : x = xptr->xbutton.x;
314 lwin = xptr->xbutton.window;
316 case MotionNotify : x = xptr->xmotion.x;
318 lwin = xptr->xmotion.window;
324 switch (GraphicsOp) {
325 case S_HOTSPOT : if (xptr->xbutton.window == tablet_win) {
328 Icon_Coords(tx, ty, &ix, &iy);
334 stat_out(" - HOTSPOT selected at [%d,%d]\n", ix, iy);
336 Repaint_Exposed_Tablet();
341 case S_SCALE_2 : tx = x;
343 if (GraphicsOp == S_PASTE)
344 XDrawRectangle(dpy, tablet_win,
345 Flicker_gc, last_tx, last_ty,
346 CutCopy->width*MagFactor - MagFactor,
347 CutCopy->height*MagFactor - MagFactor);
348 else if (GraphicsOp == S_ROTATE)
349 XDrawRectangle(dpy, tablet_win,
350 Flicker_gc, last_tx, last_ty,
351 Rotate->width*MagFactor - MagFactor,
352 Rotate->height*MagFactor - MagFactor);
354 XDrawRectangle(dpy, tablet_win,
355 Flicker_gc, last_tx, last_ty,
356 Scale->width*MagFactor - MagFactor,
357 Scale->height*MagFactor - MagFactor);
358 Icon_Coords(tx, ty, &ix, &iy);
362 case POINT : Pressed = True;
367 Icon_Coords(tx, ty, &ix, &iy);
369 if (GraphicsOp == ERASER) {
370 for (i=ix-1; i<=ix+1; i++)
371 for (j=iy-1; j<=iy+1; j++) {
372 XDrawPoint(dpy, color_icon, Erase_gc, i, j);
376 XDrawPoint(dpy, mono_icon, Erase_gc, i, j);
380 Paint_Tile(i, j, Erase_gc);
384 XDrawPoint(dpy, color_icon, Color_gc, ix, iy);
385 XDrawPoint(dpy, XtWindow(iconImage),
387 XDrawPoint(dpy, mono_icon, Mono_gc, ix, iy);
388 XDrawPoint(dpy, XtWindow(monoImage),
390 Paint_Tile(ix, iy, Color_gc);
393 case SELECT : if (DoingHotBox) {
402 case RECTANGLE : Quantize(&x, &y, True);
411 stat_out(" - Quantized to [%d,%d]\n", x, y);
414 case S_GRAB : XGrabServer(dpy);
425 Quantize(&x, &y, True);
429 Icon_Coords(tx, ty, &ix, &iy);
430 pointList[pointCount].x = ix;
431 pointList[pointCount].y = iy;
432 if (pointCount < MAX_PTS) {
436 stat_out(" - pointCount++ [%d]\n", pointCount);
448 if (GraphicsOp == POLYGON)
452 Icon_Coords(last_tx, last_ty, &last_ix, &last_iy);
453 iLine(ix, iy, last_ix, last_iy, False);
458 polyTimerID = XtAppAddTimeOut( AppContext,
460 (XtTimerCallbackProc)
464 } /* switch(GraphicsOp) */
467 switch (GraphicsOp) {
469 case POINT : if (Pressed) {
474 Icon_Coords(tx, ty, &ix, &iy);
475 if (GraphicsOp == ERASER) {
476 for (i=ix-1; i<=ix+1; i++)
477 for (j=iy-1; j<=iy+1; j++) {
478 XDrawPoint(dpy, color_icon, Erase_gc, i, j);
482 XDrawPoint(dpy, mono_icon, Erase_gc, i, j);
486 Paint_Tile(i, j, Erase_gc);
488 } /* if(GraphicsOp...) */
490 XDrawPoint(dpy, color_icon, Color_gc, ix, iy);
491 XDrawPoint(dpy, XtWindow(iconImage),
493 XDrawPoint(dpy, mono_icon, Mono_gc, ix, iy);
494 XDrawPoint(dpy, XtWindow(monoImage),
496 Paint_Tile(ix, iy, Color_gc);
503 Icon_Coords(tx, ty, &ix, &iy);
504 Flood_Region(ix, iy);
506 case LINE : if (Pressed) {
507 Quantize(&x, &y, True);
510 stat_out(" - Quantized to [%d,%d]\n", x, y);
512 XDrawLine(dpy, tablet_win,
513 Flicker_gc, tx, ty, last_tx, last_ty);
517 Icon_Coords(tx, ty, &ix, &iy);
518 Icon_Coords(last_tx, last_ty, &last_ix, &last_iy);
519 iLine(ix, iy, last_ix, last_iy, True);
523 case SELECT : if (Pressed) {
524 Quantize(&x, &y, True);
525 XDrawRectangle(dpy, tablet_win,
526 Flicker_gc, min(tx, last_tx), min(ty, last_ty),
527 abs(tx-last_tx), abs(ty-last_ty));
531 Icon_Coords(tx, ty, &ix, &iy);
532 Icon_Coords(last_tx, last_ty, &last_ix, &last_iy);
533 if (GraphicsOp == SELECT) {
535 Start_HotBox(INITIAL);
538 Scale_Image(); /***TAG***/
539 GraphicsOp = S_SCALE_2;
543 case S_GRAB : if (Pressed) {
544 XDrawRectangle(dpy, lwin,
545 Flicker_gc, min(tx, last_tx), min(ty, last_ty),
546 abs(tx-last_tx), abs(ty-last_ty));
547 if (mag(last_tx, x) <= xrdb.maxIconWidth)
549 if (mag(last_ty, y) <= xrdb.maxIconHeight)
552 min(tx, last_tx), min(ty, last_ty),
553 abs(tx-last_tx), abs(ty-last_ty));
554 GraphicsOp = Backup_G_Op;
559 case RECTANGLE : if (Pressed) {
560 Quantize(&x, &y, True);
561 XDrawRectangle(dpy, tablet_win,
562 Flicker_gc, min(tx, last_tx), min(ty, last_ty),
563 abs(tx-last_tx), abs(ty-last_ty));
567 Icon_Coords(tx, ty, &ix, &iy);
568 Icon_Coords(last_tx, last_ty, &last_ix, &last_iy);
569 iRectangle(min(ix, last_ix), min(iy, last_iy),
570 abs(ix-last_ix), abs(iy-last_iy), True);
574 case S_WAIT_RELEASE :
575 GraphicsOp = Backup_G_Op;
583 case CIRCLE : if (Pressed) {
584 Quantize(&x, &y, True);
585 Circle_Box(tablet_win,
586 last_tx, last_ty, tx, ty, &box);
593 ((short)(box.width - 1) / MagFactor) + 1;
595 ((short)(box.height - 1) / MagFactor) + 1;
596 iArc(box.x, box.y, box.width, box.height, True);
599 case ELLIPSE : if (Pressed) {
600 Quantize(&x, &y, True);
601 XDrawArc(dpy, tablet_win,
602 Flicker_gc, min(tx, last_tx), min(ty, last_ty),
603 abs(tx-last_tx), abs(ty-last_ty), 0, 360*64);
607 Icon_Coords(tx, ty, &ix, &iy);
608 Icon_Coords(last_tx, last_ty, &last_ix, &last_iy);
609 iArc( min(ix, last_ix), min(iy, last_iy),
610 abs(ix-last_ix)+1, abs(iy-last_iy)+1, True);
613 } /* switch(GraphicsOp) */
616 switch (GraphicsOp) {
619 case S_SCALE_2 : last_tx = tx;
624 if (GraphicsOp == S_PASTE)
625 XDrawRectangle(dpy, tablet_win,
626 Flicker_gc, last_tx, last_ty,
627 CutCopy->width*MagFactor - MagFactor,
628 CutCopy->height*MagFactor - MagFactor);
629 else if (GraphicsOp == S_ROTATE)
630 XDrawRectangle(dpy, tablet_win,
631 Flicker_gc, last_tx, last_ty,
632 Rotate->width*MagFactor - MagFactor,
633 Rotate->height*MagFactor - MagFactor);
635 XDrawRectangle(dpy, tablet_win,
636 Flicker_gc, last_tx, last_ty,
637 Scale->width*MagFactor - MagFactor,
638 Scale->height*MagFactor - MagFactor);
640 if (GraphicsOp == S_PASTE)
641 XDrawRectangle(dpy, tablet_win,
643 CutCopy->width*MagFactor - MagFactor,
644 CutCopy->height*MagFactor - MagFactor);
645 else if (GraphicsOp == S_ROTATE)
646 XDrawRectangle(dpy, tablet_win,
648 Rotate->width*MagFactor - MagFactor,
649 Rotate->height*MagFactor - MagFactor);
651 XDrawRectangle(dpy, tablet_win,
653 Scale->width*MagFactor - MagFactor,
654 Scale->height*MagFactor - MagFactor);
656 case S_HOTSPOT : break;
658 case POINT : if (Pressed) {
663 Icon_Coords(tx, ty, &ix, &iy);
664 if (GraphicsOp == ERASER) {
665 for (i=ix-1; i<=ix+1; i++)
666 for (j=iy-1; j<=iy+1; j++) {
667 XDrawPoint(dpy, color_icon, Erase_gc, i, j);
671 XDrawPoint(dpy, mono_icon, Erase_gc, i, j);
675 Paint_Tile(i, j, Erase_gc);
677 } /* if(GraphicsOp...) */
679 XDrawPoint(dpy, color_icon, Color_gc, ix, iy);
680 XDrawPoint(dpy, XtWindow(iconImage),
682 XDrawPoint(dpy, mono_icon, Mono_gc, ix, iy);
683 XDrawPoint(dpy, XtWindow(monoImage),
685 Paint_Tile(ix, iy, Color_gc);
690 case POLYGON : if (Anchored) {
691 Quantize(&x, &y, True);
693 XDrawLine(dpy, tablet_win,
694 Flicker_gc, tx, ty, last_tx, last_ty);
697 XDrawLine(dpy, tablet_win,
698 Flicker_gc, tx, ty, last_tx, last_ty);
702 case LINE : if (Pressed) {
703 Quantize(&x, &y, True);
705 XDrawLine(dpy, tablet_win,
706 Flicker_gc, tx, ty, last_tx, last_ty);
709 XDrawLine(dpy, tablet_win,
710 Flicker_gc, tx, ty, last_tx, last_ty);
717 case RECTANGLE : if (Pressed) {
718 Quantize(&x, &y, True);
720 if (GraphicsOp != ELLIPSE)
721 XDrawRectangle(dpy, tablet_win, Flicker_gc,
722 min(tx, last_tx), min(ty, last_ty),
723 abs(tx-last_tx), abs(ty-last_ty));
725 XDrawArc(dpy, tablet_win, Flicker_gc,
726 min(tx, last_tx), min(ty, last_ty),
727 abs(tx-last_tx), abs(ty-last_ty),
732 if (GraphicsOp != ELLIPSE)
733 XDrawRectangle(dpy, tablet_win,
734 Flicker_gc, min(tx, last_tx), min(ty, last_ty),
735 abs(tx-last_tx), abs(ty-last_ty));
737 XDrawArc(dpy, tablet_win,
738 Flicker_gc, min(tx, last_tx), min(ty, last_ty),
739 abs(tx-last_tx), abs(ty-last_ty), 0, 360*64);
743 case S_GRAB : if (Pressed) {
745 XDrawRectangle(dpy, lwin, Flicker_gc,
746 min(tx, last_tx), min(ty, last_ty),
747 abs(tx-last_tx), abs(ty-last_ty));
748 if (mag(last_tx, x) <= xrdb.maxIconWidth)
750 if (mag(last_ty, y) <= xrdb.maxIconHeight)
752 XDrawRectangle(dpy, lwin,
753 Flicker_gc, min(tx, last_tx), min(ty, last_ty),
754 abs(tx-last_tx), abs(ty-last_ty));
756 /* Tell the user the size of the grabbed image
759 GETSTR(18,2,"Grabbed Image Size = %dx%d"),
760 abs(tx-last_tx), abs(ty-last_ty));
761 str= XmStringCreateLocalized (tmpstr);
762 XtVaSetValues (coordinateText, XmNlabelString, str, NULL);
766 case CIRCLE : if (Pressed) {
767 Quantize(&x, &y, True);
769 Circle_Box(tablet_win,
770 last_tx, last_ty, tx, ty, &box);
773 Circle_Box(tablet_win,
774 last_tx, last_ty, tx, ty, &box);
778 } /* switch(GraphicsOp) */
781 switch (GraphicsOp) {
783 case POLYGON : if (Anchored) {
785 XDrawLine(dpy, tablet_win, Flicker_gc, tx, ty,
790 } /* switch(GraphicsOp) */
792 } /* switch(e_type) */
796 /***************************************************************************
797 * Routine: EndPolyOp *
798 * Purpose: When user does a mouse action outside of the drawing window, *
799 * this implicitly ends the poly* operation. This means that *
800 * things like drawing circles and changing pen color while in *
801 * the middle of a polyline or polygon is no longer allowed. *
802 ***************************************************************************/
821 XDrawLine(dpy, color_icon, Color_gc, x1, y1, x2, y2);
822 XDrawLine(dpy, mono_icon, Mono_gc, x1, y1, x2, y2);
823 XDrawLine(dpy, XtWindow(iconImage), Color_gc, x1, y1, x2, y2);
824 XDrawLine(dpy, XtWindow(monoImage), Mono_gc, x1, y1, x2, y2);
827 stat_out("Transferring from [%d,%d] to [%d,%d]\n", tx, ty,
830 Transfer_Back_Image(x1, y1, x2, y2, FILL);
844 XFillRectangle(dpy, color_icon, Color_gc, x, y, width+1, height+1);
845 XFillRectangle(dpy, mono_icon, Mono_gc, x, y, width+1, height+1);
846 XFillRectangle(dpy, XtWindow(iconImage), Color_gc,
847 x, y, width+1, height+1);
848 XFillRectangle(dpy, XtWindow(monoImage), Mono_gc,
849 x, y, width+1, height+1);
852 XDrawRectangle(dpy, color_icon, Color_gc, x, y, width, height);
853 XDrawRectangle(dpy, mono_icon, Mono_gc, x, y, width, height);
854 XDrawRectangle(dpy, XtWindow(iconImage), Color_gc,
855 x, y, width, height);
856 XDrawRectangle(dpy, XtWindow(monoImage), Mono_gc,
857 x, y, width, height);
859 Transfer_Back_Image(x, y, x+width, y+height, FILL);
873 XFillArc(dpy, color_icon, Color_gc, x, y, width, height, 0, 360*64);
874 XFillArc(dpy, mono_icon, Mono_gc, x, y, width, height, 0, 360*64);
875 XFillArc(dpy, XtWindow(iconImage),
876 Color_gc, x, y, width, height, 0, 360*64);
877 XFillArc(dpy, XtWindow(monoImage),
878 Mono_gc, x, y, width, height, 0, 360*64);
881 XDrawArc(dpy, color_icon, Color_gc, x, y, width, height, 0, 360*64);
882 XDrawArc(dpy, mono_icon, Mono_gc, x, y, width, height, 0, 360*64);
883 XDrawArc(dpy, XtWindow(iconImage),
884 Color_gc, x, y, width, height, 0, 360*64);
885 XDrawArc(dpy, XtWindow(monoImage),
886 Mono_gc, x, y, width, height, 0, 360*64);
888 Transfer_Back_Image(x, y, x+width, y+height, FILL);
894 int min_x, min_y, max_x, max_y, i;
898 stat_out("iPolygon: pointCount = %d\n", pointCount);
902 XFillPolygon(dpy, color_icon, Color_gc, pointList, pointCount,
903 Complex, CoordModeOrigin);
904 XFillPolygon(dpy, mono_icon, Mono_gc, pointList, pointCount,
905 Complex, CoordModeOrigin);
906 XFillPolygon(dpy, XtWindow(iconImage),
907 Color_gc, pointList, pointCount, Complex, CoordModeOrigin);
908 XFillPolygon(dpy, XtWindow(monoImage),
909 Mono_gc, pointList, pointCount, Complex, CoordModeOrigin);
912 if (pointCount < MAX_PTS) {
913 pointList[pointCount].x = pointList[0].x;
914 pointList[pointCount].y = pointList[0].y;
917 XDrawLines(dpy, color_icon, Color_gc, pointList, pointCount, Complex);
918 XDrawLines(dpy, mono_icon, Mono_gc, pointList, pointCount, Complex);
919 XDrawLines(dpy, XtWindow(iconImage), Color_gc, pointList,
920 pointCount, Complex);
921 XDrawLines(dpy, XtWindow(monoImage), Mono_gc, pointList,
922 pointCount, Complex);
924 min_x = pointList[0].x;
925 min_y = pointList[0].y;
928 for (i=1; i<pointCount; i++) {
929 if (pointList[i].x < min_x) min_x = pointList[i].x;
930 if (pointList[i].y < min_y) min_y = pointList[i].y;
931 if (pointList[i].x > max_x) max_x = pointList[i].x;
932 if (pointList[i].y > max_y) max_y = pointList[i].y;
934 Transfer_Back_Image(min_x, min_y, max_x, max_y, FILL);