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