dtwm: basic multihead(xinerama only) support
[oweals/cde.git] / cde / programs / dticon / event.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
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)
10  * any later version.
11  *
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
16  * details.
17  *
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
22  */
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
29 *      Novell, Inc.
30 **********************************************************************/
31 /******************************************************************************
32  **  Program:           dticon
33  **
34  **  Description:       X11-based multi-color icon editor
35  **
36  **  File:              event.c, which contains the following subroutines or
37  **                     functions:
38  **                       Clear_ClickCount()
39  **                       ProcessTabletEvent()
40  **                       Do_ButtonOp()
41  **                       iLine()
42  **                       iRectangle()
43  **                       iArc()
44  **                       iPolygon()
45  **
46  ******************************************************************************
47  **
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.
52  **
53  **  Hewlett-Packard makes no representations about the suitibility of this
54  **  software for any purpose.  It is provided "as is" without express or
55  **  implied warranty.
56  **
57  ******************************************************************************/
58 #include <stdio.h>
59
60 #include <Xm/Xm.h>
61 #include "externals.h"
62 #include "main.h"
63
64 #ifdef DEBUG
65 extern Widget iconForm;
66 #endif
67
68 static Boolean DoingHotBox=False;
69 static XtIntervalId polyTimerID;
70 Widget coordinateText;
71 static int Prev_x, Prev_y;
72
73 static void
74 Clear_ClickCount( void )
75 {
76 #ifdef DEBUG
77   if (debug)
78     stat_out(" - CLICK-COUNT ZEROED.\n");
79 #endif
80   ClickCount = 0;
81 }
82
83 /* Forward declarations */
84
85 void iArc(
86         int x,
87         int y,
88         int width,
89         int height,
90         Boolean backupFlag);
91 void iLine(
92         int x1,
93         int y1,
94         int x2,
95         int y2,
96         Boolean backupFlag);
97 void iRectangle(
98         int x,
99         int y,
100         int width,
101         int height,
102         Boolean backupFlag);
103 void iPolygon(void);
104 void Do_ButtonOp(XEvent *);
105
106 /***************************************************************************
107  *                                                                         *
108  * Routine:   ProcessTabletEvent                                           *
109  *                                                                         *
110  * Purpose:   Global event-handling routine for user input on the tablet.  *
111  *                                                                         *
112  ***************************************************************************/
113
114 void
115 ProcessTabletEvent(
116         Widget w,
117         XEvent *xptr,
118         String *params,
119         Cardinal num_params )
120 {
121 #ifdef DEBUG
122   Arg args[10];
123   Dimension db_width, db_height;
124 #endif
125   int x, y, width, height, i, n, xGrid, yGrid;
126   char tmpstr[20];
127   XmString str;
128
129   if (num_params == 3)
130     ClickCount = atoi(params[2]);
131 #ifdef DEBUG
132   if (debug)
133     printf("Event - ");
134 #endif
135   switch(xptr->type) {
136     case ButtonPress    : x = xptr->xbutton.x;
137                           y = xptr->xbutton.y;
138 #ifdef DEBUG
139   if (debug)
140     printf("Btn Press at [%d,%d]\n", x, y);
141 #endif
142                           if (xptr->xbutton.window == tablet_win)
143                             Do_ButtonOp(xptr);
144                           break;
145     case MotionNotify   : x = xptr->xmotion.x;
146                           y = xptr->xmotion.y;
147
148                           /* Adjust for the Magnification Factor */
149                           xGrid = x/MagFactor + 1;
150                           yGrid = y/MagFactor + 1;
151
152                           /*
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.
159                           */
160                           if (xGrid!=Prev_x || yGrid!=Prev_y){
161                              if (GraphicsOp == ERASER)
162                              {
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) );
169                              }
170                              Prev_x = xGrid;
171                              Prev_y = yGrid;
172                              tmpstr[0] = '\0';
173                              sprintf(tmpstr, "%dx%d", xGrid, yGrid);
174                              str= XmStringCreateLocalized (tmpstr);
175                              XtVaSetValues (coordinateText, XmNlabelString, str, NULL);
176                              XmStringFree(str);
177                           }
178 #ifdef DEBUG
179   if (debug)
180     printf("Btn Motion at [%d,%d]\n", x, y);
181 #endif
182                           if (xptr->xmotion.window == tablet_win)
183                             Do_ButtonOp(xptr);
184                           break;
185     case ButtonRelease  : x = xptr->xbutton.x;
186                           y = xptr->xbutton.y;
187 #ifdef DEBUG
188   if (debug) {
189     printf("Btn Release at [%d,%d]", x, y);
190     if (ClickCount)
191       printf(", CLICK COUNT = %d", ClickCount);
192     printf("\n");
193    }
194 #endif
195                           if (xptr->xbutton.window == tablet_win)
196                             Do_ButtonOp(xptr);
197                           break;
198     case Expose         : if (!tablet_win) {
199                             tablet_win = XtWindow(tablet_wid);
200                           }
201                           if (xptr->xexpose.window == tablet_win) {
202                             x = xptr->xexpose.x;
203                             y = xptr->xexpose.y;
204                             width = xptr->xexpose.width;
205                             height = xptr->xexpose.height;
206 #ifdef DEBUG
207   if (debug)
208     printf("Exposure at [%d,%d] of %dx%d\n", x, y, width, height);
209 #endif
210                             Repaint_Tablet(xptr->xexpose.window, x, y,
211                                         width, height);
212                            }
213                           else if (xptr->xexpose.window ==
214                                         XtWindow(iconImage)) {
215                             XCopyArea(dpy, color_icon,
216                                 XtWindow(iconImage),
217                                 Color_gc, 0, 0, icon_width, icon_height, 0, 0);
218 #ifdef DEBUG
219   if (debug)
220     printf("Exposure on iconImage: REPAINTING\n");
221 #endif
222                            }
223                           else if (xptr->xexpose.window ==
224                                         XtWindow(monoImage)) {
225                             XCopyArea(dpy, mono_icon,
226                                 XtWindow(monoImage),
227                                 Color_gc, 0, 0, icon_width, icon_height, 0, 0);
228 #ifdef DEBUG
229   if (debug)
230     printf("Exposure on monoImage: REPAINTING\n");
231 #endif
232                            }
233                           if (argsNeedProcessed)
234                             ProcessAppArgs();
235                           break;
236     case EnterNotify    : x = xptr->xcrossing.x;
237                           y = xptr->xcrossing.y;
238 #ifdef DEBUG
239   if (debug)
240     printf("Enter window at [%d,%d]\n", x, y);
241 #endif
242                           break;
243     case LeaveNotify    : x = xptr->xcrossing.x;
244                           y = xptr->xcrossing.y;
245
246                           /* if in ERASER mode
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)
253                             Do_ButtonOp(xptr);
254 #ifdef DEBUG
255   if (debug) {
256     printf("Leave window at [%d,%d]\n", x, y);
257     i = 0;
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);
262     i = 0;
263     XtSetArg(args[i], XmNwidth, &db_width); i++;
264     XtGetValues(iconImage, args, i);
265     stat_out(" - icon widths: %d\n", db_width);
266    }
267 #endif
268                           break;
269     case FocusIn        :
270     case FocusOut       :
271 #ifdef DEBUG
272   if (debug)
273     printf("Focus change\n");
274 #endif
275                           break;
276     default             :
277 #ifdef DEBUG
278   if (debug)
279     printf("UNKNOWN type: %d\n", xptr->type);
280 #endif
281                           break;
282     break;
283    } /* switch */
284 }
285
286
287 /***************************************************************************
288  *                                                                         *
289  * Routine:   Do_ButtonOp                                                  *
290  *                                                                         *
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. *
294  *                                                                         *
295  ***************************************************************************/
296
297 static int Pressed = False, First = False;
298
299 void
300 Do_ButtonOp(
301         XEvent *xptr )
302 {
303   Window lwin;
304   int e_type, x, y, i, j;
305   XRectangle box;
306   char tmpstr[20];
307   XmString str;
308
309   e_type = xptr->type;
310   switch (e_type) {
311     case ButtonPress   :
312     case ButtonRelease :  x = xptr->xbutton.x;
313                           y = xptr->xbutton.y;
314                           lwin = xptr->xbutton.window;
315                           break;
316     case MotionNotify  :  x = xptr->xmotion.x;
317                           y = xptr->xmotion.y;
318                           lwin = xptr->xmotion.window;
319                           break;
320    } /* switch */
321
322   switch (e_type) {
323     case ButtonPress :
324       switch (GraphicsOp) {
325          case S_HOTSPOT : if (xptr->xbutton.window == tablet_win) {
326                             tx = x;
327                             ty = y;
328                             Icon_Coords(tx, ty, &ix, &iy);
329                             X_Hot = ix;
330                             Y_Hot = iy;
331                             hotSpot = True;
332 #ifdef DEBUG
333   if (debug)
334     stat_out(" - HOTSPOT selected at [%d,%d]\n", ix, iy);
335 #endif
336                             Repaint_Exposed_Tablet();
337                            }
338                           break;
339          case S_PASTE   :
340          case S_ROTATE  :
341          case S_SCALE_2 : tx = x;
342                           ty = y;
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);
353                           else
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);
359                           Do_Paste(ix, iy);
360                           break;
361          case ERASER    :
362          case POINT     : Pressed = True;
363                           last_tx = tx;
364                           last_ty = ty;
365                           tx = x;
366                           ty = y;
367                           Icon_Coords(tx, ty, &ix, &iy);
368                           Backup_Icons();
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);
373                                 XDrawPoint(dpy,
374                                         XtWindow(iconImage),
375                                         Erase_gc, i, j);
376                                 XDrawPoint(dpy, mono_icon, Erase_gc, i, j);
377                                 XDrawPoint(dpy,
378                                         XtWindow(monoImage),
379                                         Erase_gc, i, j);
380                                 Paint_Tile(i, j, Erase_gc);
381                                }
382                            }
383                           else {
384                             XDrawPoint(dpy, color_icon, Color_gc, ix, iy);
385                             XDrawPoint(dpy, XtWindow(iconImage),
386                                 Color_gc, ix, iy);
387                             XDrawPoint(dpy, mono_icon, Mono_gc, ix, iy);
388                             XDrawPoint(dpy, XtWindow(monoImage),
389                                 Mono_gc, ix, iy);
390                             Paint_Tile(ix, iy, Color_gc);
391                            }
392          case FLOOD     : break;
393          case SELECT    : if (DoingHotBox) {
394                             DoingHotBox = False;
395                             Selected = False;
396                             Stop_HotBox();
397                           }
398          case LINE      :
399          case CIRCLE    :
400          case ELLIPSE   :
401          case S_SCALE_1 :
402          case RECTANGLE : Quantize(&x, &y, True);
403                           Pressed = True;
404                           tx = x;
405                           ty = y;
406                           last_tx = tx;
407                           last_ty = ty;
408                           First = True;
409 #ifdef DEBUG
410   if (debug)
411     stat_out(" - Quantized to [%d,%d]\n", x, y);
412 #endif
413                           break;
414          case S_GRAB    : XGrabServer(dpy);
415                           XSync(dpy, False);
416                           Pressed = True;
417                           tx = x;
418                           ty = y;
419                           last_tx = tx;
420                           last_ty = ty;
421                           First = True;
422                           break;
423          case POLYLINE  :
424          case POLYGON   :
425                           Quantize(&x, &y, True);
426                           tx = x;
427                           ty = y;
428                           First = True;
429                           Icon_Coords(tx, ty, &ix, &iy);
430                           pointList[pointCount].x = ix;
431                           pointList[pointCount].y = iy;
432                           if (pointCount < MAX_PTS) {
433                             pointCount++;
434 #ifdef DEBUG
435   if (debug)
436     stat_out(" - pointCount++ [%d]\n", pointCount);
437 #endif
438                            }
439                           if (!Anchored) {
440                             Anchored = True;
441                             pointCount = 1;
442                             Backup_Icons();
443                            }
444                           else {
445                             if (ClickCount) {
446                               Anchored = False;
447                               ClickCount = 0;
448                               if (GraphicsOp == POLYGON)
449                                 iPolygon();
450                               pointCount = 0;
451                              }
452                             Icon_Coords(last_tx, last_ty, &last_ix, &last_iy);
453                             iLine(ix, iy, last_ix, last_iy, False);
454                            }
455                           last_tx = tx;
456                           last_ty = ty;
457                           ClickCount++;
458                           polyTimerID = XtAppAddTimeOut( AppContext,
459                                                          multiClickTime,
460                                                          (XtTimerCallbackProc)
461                                                              Clear_ClickCount,
462                                                          NULL);
463                           break;
464        } /* switch(GraphicsOp) */
465     break;
466     case ButtonRelease :
467       switch (GraphicsOp) {
468          case ERASER    :
469          case POINT     : if (Pressed) {
470                             last_tx = tx;
471                             last_ty = ty;
472                             tx = x;
473                             ty = y;
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);
479                                   XDrawPoint(dpy,
480                                         XtWindow(iconImage),
481                                         Erase_gc, i, j);
482                                   XDrawPoint(dpy, mono_icon, Erase_gc, i, j);
483                                   XDrawPoint(dpy,
484                                         XtWindow(monoImage),
485                                         Erase_gc, i, j);
486                                   Paint_Tile(i, j, Erase_gc);
487                                  } /* for */
488                              } /* if(GraphicsOp...) */
489                             else {
490                               XDrawPoint(dpy, color_icon, Color_gc, ix, iy);
491                               XDrawPoint(dpy, XtWindow(iconImage),
492                                 Color_gc, ix, iy);
493                               XDrawPoint(dpy, mono_icon, Mono_gc, ix, iy);
494                               XDrawPoint(dpy, XtWindow(monoImage),
495                                 Mono_gc, ix, iy);
496                               Paint_Tile(ix, iy, Color_gc);
497                              } /* else */
498                             Pressed = False;
499                            } /* if(Pressed) */
500                           break;
501          case FLOOD     : tx = x;
502                           ty = y;
503                           Icon_Coords(tx, ty, &ix, &iy);
504                           Flood_Region(ix, iy);
505                           break;
506          case LINE      : if (Pressed) {
507                             Quantize(&x, &y, True);
508 #ifdef DEBUG
509   if (debug)
510     stat_out(" - Quantized to [%d,%d]\n", x, y);
511 #endif
512                             XDrawLine(dpy, tablet_win,
513                                 Flicker_gc, tx, ty, last_tx, last_ty);
514                             tx = x;
515                             ty = y;
516                             Pressed = False;
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);
520                            }
521                           break;
522          case S_SCALE_1 :
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));
528                             tx = x;
529                             ty = y;
530                             Pressed = False;
531                             Icon_Coords(tx, ty, &ix, &iy);
532                             Icon_Coords(last_tx, last_ty, &last_ix, &last_iy);
533                             if (GraphicsOp == SELECT) {
534                               DoingHotBox = True;
535                               Start_HotBox(INITIAL);
536                              }
537                             else {
538                               Scale_Image(); /***TAG***/
539                               GraphicsOp = S_SCALE_2;
540                              }
541                            }
542                           break;
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)
548                               tx = x;
549                             if (mag(last_ty, y) <= xrdb.maxIconHeight)
550                               ty = y;
551                             LoadGrabbedImage(
552                                 min(tx, last_tx), min(ty, last_ty),
553                                 abs(tx-last_tx), abs(ty-last_ty));
554                             GraphicsOp = Backup_G_Op;
555                             Backup_G_Op = 0;
556                             Pressed = False;
557                            }
558                           break;
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));
564                             tx = x;
565                             ty = y;
566                             Pressed = False;
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);
571                            }
572                           break;
573          case S_HOTSPOT :
574          case S_WAIT_RELEASE :
575                           GraphicsOp = Backup_G_Op;
576                           Backup_G_Op = 0;
577                           break;
578          case S_ROTATE  :
579          case S_SCALE_2 :
580          case POLYLINE  :
581          case POLYGON   :
582                           break;
583          case CIRCLE    : if (Pressed) {
584                             Quantize(&x, &y, True);
585                             Circle_Box(tablet_win,
586                                 last_tx, last_ty, tx, ty, &box);
587                             tx = x;
588                             ty = y;
589                             Pressed = False;
590                             box.x /= MagFactor;
591                             box.y /= MagFactor;
592                             box.width =
593                                 ((short)(box.width - 1) / MagFactor) + 1;
594                             box.height =
595                                 ((short)(box.height - 1) / MagFactor) + 1;
596                             iArc(box.x, box.y, box.width, box.height, True);
597                            }
598                           break;
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);
604                             tx = x;
605                             ty = y;
606                             Pressed = False;
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);
611                            }
612                           break;
613        } /* switch(GraphicsOp) */
614     break;
615     case MotionNotify :
616       switch (GraphicsOp) {
617          case S_PASTE   :
618          case S_ROTATE  :
619          case S_SCALE_2 : last_tx = tx;
620                           last_ty = ty;
621                           tx = x;
622                           ty = y;
623                           if (!FirstRigid) {
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);
634                             else
635                               XDrawRectangle(dpy, tablet_win,
636                                         Flicker_gc, last_tx, last_ty,
637                                         Scale->width*MagFactor - MagFactor,
638                                         Scale->height*MagFactor - MagFactor);
639                            }
640                           if (GraphicsOp == S_PASTE)
641                             XDrawRectangle(dpy, tablet_win,
642                                         Flicker_gc, tx, ty,
643                                         CutCopy->width*MagFactor - MagFactor,
644                                         CutCopy->height*MagFactor - MagFactor);
645                           else if (GraphicsOp == S_ROTATE)
646                             XDrawRectangle(dpy, tablet_win,
647                                         Flicker_gc, tx, ty,
648                                         Rotate->width*MagFactor - MagFactor,
649                                         Rotate->height*MagFactor - MagFactor);
650                           else
651                             XDrawRectangle(dpy, tablet_win,
652                                         Flicker_gc, tx, ty,
653                                         Scale->width*MagFactor - MagFactor,
654                                         Scale->height*MagFactor - MagFactor);
655                           FirstRigid = False;
656          case S_HOTSPOT : break;
657          case ERASER    :
658          case POINT     : if (Pressed) {
659                             last_tx = tx;
660                             last_ty = ty;
661                             tx = x;
662                             ty = y;
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);
668                                   XDrawPoint(dpy,
669                                         XtWindow(iconImage),
670                                         Erase_gc, i, j);
671                                   XDrawPoint(dpy, mono_icon, Erase_gc, i, j);
672                                   XDrawPoint(dpy,
673                                         XtWindow(monoImage),
674                                         Erase_gc, i, j);
675                                   Paint_Tile(i, j, Erase_gc);
676                                  } /* for */
677                              } /* if(GraphicsOp...) */
678                             else {
679                               XDrawPoint(dpy, color_icon, Color_gc, ix, iy);
680                               XDrawPoint(dpy, XtWindow(iconImage),
681                                 Color_gc, ix, iy);
682                               XDrawPoint(dpy, mono_icon, Mono_gc, ix, iy);
683                               XDrawPoint(dpy, XtWindow(monoImage),
684                                 Mono_gc, ix, iy);
685                               Paint_Tile(ix, iy, Color_gc);
686                              } /* else */
687                            }
688          case FLOOD     : break;
689          case POLYLINE  :
690          case POLYGON   : if (Anchored) {
691                             Quantize(&x, &y, True);
692                             if (!First)
693                               XDrawLine(dpy, tablet_win,
694                                 Flicker_gc, tx, ty, last_tx, last_ty);
695                             tx = x;
696                             ty = y;
697                             XDrawLine(dpy, tablet_win,
698                                 Flicker_gc, tx, ty, last_tx, last_ty);
699                             First = False;
700                            }
701                           break;
702          case LINE      : if (Pressed) {
703                             Quantize(&x, &y, True);
704                             if (!First)
705                               XDrawLine(dpy, tablet_win,
706                                 Flicker_gc, tx, ty, last_tx, last_ty);
707                             tx = x;
708                             ty = y;
709                             XDrawLine(dpy, tablet_win,
710                                 Flicker_gc, tx, ty, last_tx, last_ty);
711                             First = False;
712                            }
713                           break;
714          case ELLIPSE   :
715          case SELECT    :
716          case S_SCALE_1 :
717          case RECTANGLE : if (Pressed) {
718                             Quantize(&x, &y, True);
719                             if (!First) {
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));
724                               else
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),
728                                         0, 360*64);
729                              }
730                             tx = x;
731                             ty = y;
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));
736                             else
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);
740                             First = False;
741                            }
742                           break;
743          case S_GRAB    : if (Pressed) {
744                             if (!First)
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)
749                               tx = x;
750                             if (mag(last_ty, y) <= xrdb.maxIconHeight)
751                               ty = y;
752                             XDrawRectangle(dpy, lwin,
753                                 Flicker_gc, min(tx, last_tx), min(ty, last_ty),
754                                 abs(tx-last_tx), abs(ty-last_ty));
755                             First = False;
756                             /* Tell the user the size of the grabbed image
757                             */
758                              sprintf(tmpstr, 
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);
763                              XmStringFree(str);
764                            }
765                           break;
766          case CIRCLE    : if (Pressed) {
767                             Quantize(&x, &y, True);
768                             if (!First)
769                               Circle_Box(tablet_win,
770                                 last_tx, last_ty, tx, ty, &box);
771                             tx = x;
772                             ty = y;
773                             Circle_Box(tablet_win,
774                                 last_tx, last_ty, tx, ty, &box);
775                             First = False;
776                            }
777                           break;
778        } /* switch(GraphicsOp) */
779     break;
780     case LeaveNotify :
781       switch (GraphicsOp) {
782          case POLYLINE  :
783          case POLYGON   : if (Anchored) {
784                             if (!First)
785                               XDrawLine(dpy, tablet_win, Flicker_gc, tx, ty,
786                                         last_tx, last_ty);
787                             First = True;
788                            }
789                           break;
790        } /* switch(GraphicsOp) */
791     break;
792    } /* switch(e_type) */
793 }
794
795
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  ***************************************************************************/
803 void
804 EndPolyOp()
805 {
806     Anchored = False;
807     Clear_ClickCount();
808     pointCount = 0;
809 }
810
811 void
812 iLine(
813         int x1,
814         int y1,
815         int x2,
816         int y2,
817         Boolean backupFlag )
818 {
819   if (backupFlag)
820     Backup_Icons();
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);
825 #ifdef DEBUG
826   if (debug)
827     stat_out("Transferring from [%d,%d] to [%d,%d]\n", tx, ty,
828                 last_tx, last_ty);
829 #endif
830   Transfer_Back_Image(x1, y1, x2, y2, FILL);
831 }
832
833 void
834 iRectangle(
835         int x,
836         int y,
837         int width,
838         int height,
839         Boolean backupFlag )
840 {
841   if (backupFlag)
842     Backup_Icons();
843   if (FillSolids) {
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);
850    }
851   else {
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);
858    }
859   Transfer_Back_Image(x, y, x+width, y+height, FILL);
860 }
861
862 void
863 iArc(
864         int x,
865         int y,
866         int width,
867         int height,
868         Boolean backupFlag )
869 {
870   if (backupFlag)
871     Backup_Icons();
872   if (FillSolids) {
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);
879    }
880   else {
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);
887    }
888   Transfer_Back_Image(x, y, x+width, y+height, FILL);
889 }
890
891 void
892 iPolygon( void )
893 {
894   int min_x, min_y, max_x, max_y, i;
895
896 #ifdef DEBUG
897   if (debug)
898     stat_out("iPolygon: pointCount = %d\n", pointCount);
899 #endif
900
901   if (FillSolids) {
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);
910    }
911   else {
912     if (pointCount < MAX_PTS) {
913       pointList[pointCount].x = pointList[0].x;
914       pointList[pointCount].y = pointList[0].y;
915       pointCount++;
916      }
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);
923    }
924   min_x = pointList[0].x;
925   min_y = pointList[0].y;
926   max_x = min_x;
927   max_y = min_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;
933    }
934   Transfer_Back_Image(min_x, min_y, max_x, max_y, FILL);
935 }