Initial import of the CDE 2.1.30 sources from the Open Group.
[oweals/cde.git] / cde / programs / dticon / event.c
1 /* $XConsortium: event.c /main/6 1996/10/21 15:28:00 mgreess $ */
2 /*********************************************************************
3 *  (c) Copyright 1993, 1994 Hewlett-Packard Company
4 *  (c) Copyright 1993, 1994 International Business Machines Corp.
5 *  (c) Copyright 1993, 1994 Sun Microsystems, Inc.
6 *  (c) Copyright 1993, 1994 Unix System Labs, Inc., a subsidiary of
7 *      Novell, Inc.
8 **********************************************************************/
9 /******************************************************************************
10  **  Program:           dticon
11  **
12  **  Description:       X11-based multi-color icon editor
13  **
14  **  File:              event.c, which contains the following subroutines or
15  **                     functions:
16  **                       Clear_ClickCount()
17  **                       ProcessTabletEvent()
18  **                       Do_ButtonOp()
19  **                       iLine()
20  **                       iRectangle()
21  **                       iArc()
22  **                       iPolygon()
23  **
24  ******************************************************************************
25  **
26  **  Copyright Hewlett-Packard Company, 1990, 1991, 1992.
27  **  All rights are reserved.  Copying or reproduction of this program,
28  **  except for archival purposes, is prohibited without prior written
29  **  consent of Hewlett-Packard Company.
30  **
31  **  Hewlett-Packard makes no representations about the suitibility of this
32  **  software for any purpose.  It is provided "as is" without express or
33  **  implied warranty.
34  **
35  ******************************************************************************/
36 #include <Xm/Xm.h>
37 #include "externals.h"
38 #include "main.h"
39
40 #ifdef DEBUG
41 extern Widget iconForm;
42 #endif
43
44 static Boolean DoingHotBox=False;
45 static XtIntervalId polyTimerID;
46 Widget coordinateText;
47 static int Prev_x, Prev_y;
48
49 static void
50 Clear_ClickCount( void )
51 {
52 #ifdef DEBUG
53   if (debug)
54     stat_out(" - CLICK-COUNT ZEROED.\n");
55 #endif
56   ClickCount = 0;
57 }
58
59 /* Forward declarations */
60
61 void iArc(
62         int x,
63         int y,
64         int width,
65         int height,
66         Boolean backupFlag);
67 void iLine(
68         int x1,
69         int y1,
70         int x2,
71         int y2,
72         Boolean backupFlag);
73 void iRectangle(
74         int x,
75         int y,
76         int width,
77         int height,
78         Boolean backupFlag);
79 void iPolygon(void);
80 void Do_ButtonOp(XEvent *);
81
82 /***************************************************************************
83  *                                                                         *
84  * Routine:   ProcessTabletEvent                                           *
85  *                                                                         *
86  * Purpose:   Global event-handling routine for user input on the tablet.  *
87  *                                                                         *
88  ***************************************************************************/
89
90 void
91 ProcessTabletEvent(
92         Widget w,
93         XEvent *xptr,
94         String *params,
95         Cardinal num_params )
96 {
97 #ifdef DEBUG
98   Arg args[10];
99   Dimension db_width, db_height;
100 #endif
101   int x, y, width, height, i, n, xGrid, yGrid;
102   char tmpstr[20];
103   XmString str;
104
105   if (num_params == 3)
106     ClickCount = atoi(params[2]);
107 #ifdef DEBUG
108   if (debug)
109     printf("Event - ");
110 #endif
111   switch(xptr->type) {
112     case ButtonPress    : x = xptr->xbutton.x;
113                           y = xptr->xbutton.y;
114 #ifdef DEBUG
115   if (debug)
116     printf("Btn Press at [%d,%d]\n", x, y);
117 #endif
118                           if (xptr->xbutton.window == tablet_win)
119                             Do_ButtonOp(xptr);
120                           break;
121     case MotionNotify   : x = xptr->xmotion.x;
122                           y = xptr->xmotion.y;
123
124                           /* Adjust for the Magnification Factor */
125                           xGrid = x/MagFactor + 1;
126                           yGrid = y/MagFactor + 1;
127
128                           /*
129                            if coordinates are different then
130                               update Previous x & y
131                               Display new coordinates, but first...
132                               If the ERASER is ON then
133                                  redraw the contents of the previous Rect.
134                                  Draw the bounding Rect.
135                           */
136                           if (xGrid!=Prev_x || yGrid!=Prev_y){
137                              if (GraphicsOp == ERASER)
138                              {
139                                  Transfer_Back_Image(Prev_x-2, Prev_y-2,
140                                                     (Prev_x+1), (Prev_y+1), HOLLOW);
141                                  XDrawRectangle(dpy, tablet_win, Erase_gc,
142                                                 xGrid*MagFactor-(2*MagFactor),
143                                                 yGrid*MagFactor-(2*MagFactor),
144                                                 (3*MagFactor), (3*MagFactor) );
145                              }
146                              Prev_x = xGrid;
147                              Prev_y = yGrid;
148                              tmpstr[0] = '\0';
149                              sprintf(tmpstr, "%dx%d", xGrid, yGrid);
150                              str= XmStringCreateLocalized (tmpstr);
151                              XtVaSetValues (coordinateText, XmNlabelString, str, NULL);
152                              XmStringFree(str);
153                           }
154 #ifdef DEBUG
155   if (debug)
156     printf("Btn Motion at [%d,%d]\n", x, y);
157 #endif
158                           if (xptr->xmotion.window == tablet_win)
159                             Do_ButtonOp(xptr);
160                           break;
161     case ButtonRelease  : x = xptr->xbutton.x;
162                           y = xptr->xbutton.y;
163 #ifdef DEBUG
164   if (debug) {
165     printf("Btn Release at [%d,%d]", x, y);
166     if (ClickCount)
167       printf(", CLICK COUNT = %d", ClickCount);
168     printf("\n");
169    }
170 #endif
171                           if (xptr->xbutton.window == tablet_win)
172                             Do_ButtonOp(xptr);
173                           break;
174     case Expose         : if (!tablet_win) {
175                             tablet_win = XtWindow(tablet_wid);
176                           }
177                           if (xptr->xexpose.window == tablet_win) {
178                             x = xptr->xexpose.x;
179                             y = xptr->xexpose.y;
180                             width = xptr->xexpose.width;
181                             height = xptr->xexpose.height;
182 #ifdef DEBUG
183   if (debug)
184     printf("Exposure at [%d,%d] of %dx%d\n", x, y, width, height);
185 #endif
186                             Repaint_Tablet(xptr->xexpose.window, x, y,
187                                         width, height);
188                            }
189                           else if (xptr->xexpose.window ==
190                                         XtWindow(iconImage)) {
191                             XCopyArea(dpy, color_icon,
192                                 XtWindow(iconImage),
193                                 Color_gc, 0, 0, icon_width, icon_height, 0, 0);
194 #ifdef DEBUG
195   if (debug)
196     printf("Exposure on iconImage: REPAINTING\n");
197 #endif
198                            }
199                           else if (xptr->xexpose.window ==
200                                         XtWindow(monoImage)) {
201                             XCopyArea(dpy, mono_icon,
202                                 XtWindow(monoImage),
203                                 Color_gc, 0, 0, icon_width, icon_height, 0, 0);
204 #ifdef DEBUG
205   if (debug)
206     printf("Exposure on monoImage: REPAINTING\n");
207 #endif
208                            }
209                           if (argsNeedProcessed)
210                             ProcessAppArgs();
211                           break;
212     case EnterNotify    : x = xptr->xcrossing.x;
213                           y = xptr->xcrossing.y;
214 #ifdef DEBUG
215   if (debug)
216     printf("Enter window at [%d,%d]\n", x, y);
217 #endif
218                           break;
219     case LeaveNotify    : x = xptr->xcrossing.x;
220                           y = xptr->xcrossing.y;
221
222                           /* if in ERASER mode
223                              restore contents of bounding Rect when
224                              leaving the tablet    */
225                           if (GraphicsOp == ERASER )
226                           Transfer_Back_Image(Prev_x-2, Prev_y-2,
227                                              (Prev_x+1), (Prev_y+1), HOLLOW);
228                           if (xptr->xcrossing.window == tablet_win)
229                             Do_ButtonOp(xptr);
230 #ifdef DEBUG
231   if (debug) {
232     printf("Leave window at [%d,%d]\n", x, y);
233     i = 0;
234     XtSetArg(args[i], XmNwidth, &db_width); i++;
235     XtSetArg(args[i], XmNheight, &db_height); i++;
236     XtGetValues(iconForm, args, i);
237     stat_out(" - iconForm dimensions: [%dx%d]\n", db_width, db_height);
238     i = 0;
239     XtSetArg(args[i], XmNwidth, &db_width); i++;
240     XtGetValues(iconImage, args, i);
241     stat_out(" - icon widths: %d\n", db_width);
242    }
243 #endif
244                           break;
245     case FocusIn        :
246     case FocusOut       :
247 #ifdef DEBUG
248   if (debug)
249     printf("Focus change\n");
250 #endif
251                           break;
252     default             :
253 #ifdef DEBUG
254   if (debug)
255     printf("UNKNOWN type: %d\n", xptr->type);
256 #endif
257                           break;
258     break;
259    } /* switch */
260 }
261
262
263 /***************************************************************************
264  *                                                                         *
265  * Routine:   Do_ButtonOp                                                  *
266  *                                                                         *
267  * Purpose:   Process ButtonPress/ButtonMotion/ButtonRelease events        *
268  *            generated by the user on the tablet.  Switch between correct *
269  *            behaviors depending on the current GraphicsOp tool selected. *
270  *                                                                         *
271  ***************************************************************************/
272
273 static int Pressed = False, First = False;
274
275 void
276 Do_ButtonOp(
277         XEvent *xptr )
278 {
279   Window lwin;
280   int e_type, x, y, i, j;
281   XRectangle box;
282   char tmpstr[20];
283   XmString str;
284
285   e_type = xptr->type;
286   switch (e_type) {
287     case ButtonPress   :
288     case ButtonRelease :  x = xptr->xbutton.x;
289                           y = xptr->xbutton.y;
290                           lwin = xptr->xbutton.window;
291                           break;
292     case MotionNotify  :  x = xptr->xmotion.x;
293                           y = xptr->xmotion.y;
294                           lwin = xptr->xmotion.window;
295                           break;
296    } /* switch */
297
298   switch (e_type) {
299     case ButtonPress :
300       switch (GraphicsOp) {
301          case S_HOTSPOT : if (xptr->xbutton.window == tablet_win) {
302                             tx = x;
303                             ty = y;
304                             Icon_Coords(tx, ty, &ix, &iy);
305                             X_Hot = ix;
306                             Y_Hot = iy;
307                             hotSpot = True;
308 #ifdef DEBUG
309   if (debug)
310     stat_out(" - HOTSPOT selected at [%d,%d]\n", ix, iy);
311 #endif
312                             Repaint_Exposed_Tablet();
313                            }
314                           break;
315          case S_PASTE   :
316          case S_ROTATE  :
317          case S_SCALE_2 : tx = x;
318                           ty = y;
319                           if (GraphicsOp == S_PASTE)
320                             XDrawRectangle(dpy, tablet_win,
321                                         Flicker_gc, last_tx, last_ty,
322                                         CutCopy->width*MagFactor - MagFactor,
323                                         CutCopy->height*MagFactor - MagFactor);
324                           else if (GraphicsOp == S_ROTATE)
325                             XDrawRectangle(dpy, tablet_win,
326                                         Flicker_gc, last_tx, last_ty,
327                                         Rotate->width*MagFactor - MagFactor,
328                                         Rotate->height*MagFactor - MagFactor);
329                           else
330                             XDrawRectangle(dpy, tablet_win,
331                                         Flicker_gc, last_tx, last_ty,
332                                         Scale->width*MagFactor - MagFactor,
333                                         Scale->height*MagFactor - MagFactor);
334                           Icon_Coords(tx, ty, &ix, &iy);
335                           Do_Paste(ix, iy);
336                           break;
337          case ERASER    :
338          case POINT     : Pressed = True;
339                           last_tx = tx;
340                           last_ty = ty;
341                           tx = x;
342                           ty = y;
343                           Icon_Coords(tx, ty, &ix, &iy);
344                           Backup_Icons();
345                           if (GraphicsOp == ERASER) {
346                             for (i=ix-1; i<=ix+1; i++)
347                               for (j=iy-1; j<=iy+1; j++) {
348                                 XDrawPoint(dpy, color_icon, Erase_gc, i, j);
349                                 XDrawPoint(dpy,
350                                         XtWindow(iconImage),
351                                         Erase_gc, i, j);
352                                 XDrawPoint(dpy, mono_icon, Erase_gc, i, j);
353                                 XDrawPoint(dpy,
354                                         XtWindow(monoImage),
355                                         Erase_gc, i, j);
356                                 Paint_Tile(i, j, Erase_gc);
357                                }
358                            }
359                           else {
360                             XDrawPoint(dpy, color_icon, Color_gc, ix, iy);
361                             XDrawPoint(dpy, XtWindow(iconImage),
362                                 Color_gc, ix, iy);
363                             XDrawPoint(dpy, mono_icon, Mono_gc, ix, iy);
364                             XDrawPoint(dpy, XtWindow(monoImage),
365                                 Mono_gc, ix, iy);
366                             Paint_Tile(ix, iy, Color_gc);
367                            }
368          case FLOOD     : break;
369          case SELECT    : if (DoingHotBox) {
370                             DoingHotBox = False;
371                             Selected = False;
372                             Stop_HotBox();
373                           }
374          case LINE      :
375          case CIRCLE    :
376          case ELLIPSE   :
377          case S_SCALE_1 :
378          case RECTANGLE : Quantize(&x, &y, True);
379                           Pressed = True;
380                           tx = x;
381                           ty = y;
382                           last_tx = tx;
383                           last_ty = ty;
384                           First = True;
385 #ifdef DEBUG
386   if (debug)
387     stat_out(" - Quantized to [%d,%d]\n", x, y);
388 #endif
389                           break;
390          case S_GRAB    : XGrabServer(dpy);
391                           XSync(dpy, False);
392                           Pressed = True;
393                           tx = x;
394                           ty = y;
395                           last_tx = tx;
396                           last_ty = ty;
397                           First = True;
398                           break;
399          case POLYLINE  :
400          case POLYGON   :
401                           Quantize(&x, &y, True);
402                           tx = x;
403                           ty = y;
404                           First = True;
405                           Icon_Coords(tx, ty, &ix, &iy);
406                           pointList[pointCount].x = ix;
407                           pointList[pointCount].y = iy;
408                           if (pointCount < MAX_PTS) {
409                             pointCount++;
410 #ifdef DEBUG
411   if (debug)
412     stat_out(" - pointCount++ [%d]\n", pointCount);
413 #endif
414                            }
415                           if (!Anchored) {
416                             Anchored = True;
417                             pointCount = 1;
418                             Backup_Icons();
419                            }
420                           else {
421                             if (ClickCount) {
422                               Anchored = False;
423                               ClickCount = 0;
424                               if (GraphicsOp == POLYGON)
425                                 iPolygon();
426                               pointCount = 0;
427                              }
428                             Icon_Coords(last_tx, last_ty, &last_ix, &last_iy);
429                             iLine(ix, iy, last_ix, last_iy, False);
430                            }
431                           last_tx = tx;
432                           last_ty = ty;
433                           ClickCount++;
434                           polyTimerID = XtAppAddTimeOut( AppContext,
435                                                          multiClickTime,
436                                                          (XtTimerCallbackProc)
437                                                              Clear_ClickCount,
438                                                          NULL);
439                           break;
440        } /* switch(GraphicsOp) */
441     break;
442     case ButtonRelease :
443       switch (GraphicsOp) {
444          case ERASER    :
445          case POINT     : if (Pressed) {
446                             last_tx = tx;
447                             last_ty = ty;
448                             tx = x;
449                             ty = y;
450                             Icon_Coords(tx, ty, &ix, &iy);
451                             if (GraphicsOp == ERASER) {
452                               for (i=ix-1; i<=ix+1; i++)
453                                 for (j=iy-1; j<=iy+1; j++) {
454                                   XDrawPoint(dpy, color_icon, Erase_gc, i, j);
455                                   XDrawPoint(dpy,
456                                         XtWindow(iconImage),
457                                         Erase_gc, i, j);
458                                   XDrawPoint(dpy, mono_icon, Erase_gc, i, j);
459                                   XDrawPoint(dpy,
460                                         XtWindow(monoImage),
461                                         Erase_gc, i, j);
462                                   Paint_Tile(i, j, Erase_gc);
463                                  } /* for */
464                              } /* if(GraphicsOp...) */
465                             else {
466                               XDrawPoint(dpy, color_icon, Color_gc, ix, iy);
467                               XDrawPoint(dpy, XtWindow(iconImage),
468                                 Color_gc, ix, iy);
469                               XDrawPoint(dpy, mono_icon, Mono_gc, ix, iy);
470                               XDrawPoint(dpy, XtWindow(monoImage),
471                                 Mono_gc, ix, iy);
472                               Paint_Tile(ix, iy, Color_gc);
473                              } /* else */
474                             Pressed = False;
475                            } /* if(Pressed) */
476                           break;
477          case FLOOD     : tx = x;
478                           ty = y;
479                           Icon_Coords(tx, ty, &ix, &iy);
480                           Flood_Region(ix, iy);
481                           break;
482          case LINE      : if (Pressed) {
483                             Quantize(&x, &y, True);
484 #ifdef DEBUG
485   if (debug)
486     stat_out(" - Quantized to [%d,%d]\n", x, y);
487 #endif
488                             XDrawLine(dpy, tablet_win,
489                                 Flicker_gc, tx, ty, last_tx, last_ty);
490                             tx = x;
491                             ty = y;
492                             Pressed = False;
493                             Icon_Coords(tx, ty, &ix, &iy);
494                             Icon_Coords(last_tx, last_ty, &last_ix, &last_iy);
495                             iLine(ix, iy, last_ix, last_iy, True);
496                            }
497                           break;
498          case S_SCALE_1 :
499          case SELECT    : if (Pressed) {
500                             Quantize(&x, &y, True);
501                             XDrawRectangle(dpy, tablet_win,
502                                 Flicker_gc, min(tx, last_tx), min(ty, last_ty),
503                                 abs(tx-last_tx), abs(ty-last_ty));
504                             tx = x;
505                             ty = y;
506                             Pressed = False;
507                             Icon_Coords(tx, ty, &ix, &iy);
508                             Icon_Coords(last_tx, last_ty, &last_ix, &last_iy);
509                             if (GraphicsOp == SELECT) {
510                               DoingHotBox = True;
511                               Start_HotBox(INITIAL);
512                              }
513                             else {
514                               Scale_Image(); /***TAG***/
515                               GraphicsOp = S_SCALE_2;
516                              }
517                            }
518                           break;
519          case S_GRAB    : if (Pressed) {
520                             XDrawRectangle(dpy, lwin,
521                                 Flicker_gc, min(tx, last_tx), min(ty, last_ty),
522                                 abs(tx-last_tx), abs(ty-last_ty));
523                             if (mag(last_tx, x) <= xrdb.maxIconWidth)
524                               tx = x;
525                             if (mag(last_ty, y) <= xrdb.maxIconHeight)
526                               ty = y;
527                             LoadGrabbedImage(
528                                 min(tx, last_tx), min(ty, last_ty),
529                                 abs(tx-last_tx), abs(ty-last_ty));
530                             GraphicsOp = Backup_G_Op;
531                             Backup_G_Op = NULL;
532                             Pressed = False;
533                            }
534                           break;
535          case RECTANGLE : if (Pressed) {
536                             Quantize(&x, &y, True);
537                             XDrawRectangle(dpy, tablet_win,
538                                 Flicker_gc, min(tx, last_tx), min(ty, last_ty),
539                                 abs(tx-last_tx), abs(ty-last_ty));
540                             tx = x;
541                             ty = y;
542                             Pressed = False;
543                             Icon_Coords(tx, ty, &ix, &iy);
544                             Icon_Coords(last_tx, last_ty, &last_ix, &last_iy);
545                             iRectangle(min(ix, last_ix), min(iy, last_iy),
546                                 abs(ix-last_ix), abs(iy-last_iy), True);
547                            }
548                           break;
549          case S_HOTSPOT :
550          case S_WAIT_RELEASE :
551                           GraphicsOp = Backup_G_Op;
552                           Backup_G_Op = NULL;
553                           break;
554          case S_ROTATE  :
555          case S_SCALE_2 :
556          case POLYLINE  :
557          case POLYGON   :
558                           break;
559          case CIRCLE    : if (Pressed) {
560                             Quantize(&x, &y, True);
561                             Circle_Box(tablet_win,
562                                 last_tx, last_ty, tx, ty, &box);
563                             tx = x;
564                             ty = y;
565                             Pressed = False;
566                             box.x /= MagFactor;
567                             box.y /= MagFactor;
568                             box.width =
569                                 ((short)(box.width - 1) / MagFactor) + 1;
570                             box.height =
571                                 ((short)(box.height - 1) / MagFactor) + 1;
572                             iArc(box.x, box.y, box.width, box.height, True);
573                            }
574                           break;
575          case ELLIPSE   : if (Pressed) {
576                             Quantize(&x, &y, True);
577                             XDrawArc(dpy, tablet_win,
578                                 Flicker_gc, min(tx, last_tx), min(ty, last_ty),
579                                 abs(tx-last_tx), abs(ty-last_ty), 0, 360*64);
580                             tx = x;
581                             ty = y;
582                             Pressed = False;
583                             Icon_Coords(tx, ty, &ix, &iy);
584                             Icon_Coords(last_tx, last_ty, &last_ix, &last_iy);
585                             iArc( min(ix, last_ix), min(iy, last_iy),
586                                 abs(ix-last_ix)+1, abs(iy-last_iy)+1, True);
587                            }
588                           break;
589        } /* switch(GraphicsOp) */
590     break;
591     case MotionNotify :
592       switch (GraphicsOp) {
593          case S_PASTE   :
594          case S_ROTATE  :
595          case S_SCALE_2 : last_tx = tx;
596                           last_ty = ty;
597                           tx = x;
598                           ty = y;
599                           if (!FirstRigid) {
600                             if (GraphicsOp == S_PASTE)
601                               XDrawRectangle(dpy, tablet_win,
602                                         Flicker_gc, last_tx, last_ty,
603                                         CutCopy->width*MagFactor - MagFactor,
604                                         CutCopy->height*MagFactor - MagFactor);
605                             else if (GraphicsOp == S_ROTATE)
606                               XDrawRectangle(dpy, tablet_win,
607                                         Flicker_gc, last_tx, last_ty,
608                                         Rotate->width*MagFactor - MagFactor,
609                                         Rotate->height*MagFactor - MagFactor);
610                             else
611                               XDrawRectangle(dpy, tablet_win,
612                                         Flicker_gc, last_tx, last_ty,
613                                         Scale->width*MagFactor - MagFactor,
614                                         Scale->height*MagFactor - MagFactor);
615                            }
616                           if (GraphicsOp == S_PASTE)
617                             XDrawRectangle(dpy, tablet_win,
618                                         Flicker_gc, tx, ty,
619                                         CutCopy->width*MagFactor - MagFactor,
620                                         CutCopy->height*MagFactor - MagFactor);
621                           else if (GraphicsOp == S_ROTATE)
622                             XDrawRectangle(dpy, tablet_win,
623                                         Flicker_gc, tx, ty,
624                                         Rotate->width*MagFactor - MagFactor,
625                                         Rotate->height*MagFactor - MagFactor);
626                           else
627                             XDrawRectangle(dpy, tablet_win,
628                                         Flicker_gc, tx, ty,
629                                         Scale->width*MagFactor - MagFactor,
630                                         Scale->height*MagFactor - MagFactor);
631                           FirstRigid = False;
632          case S_HOTSPOT : break;
633          case ERASER    :
634          case POINT     : if (Pressed) {
635                             last_tx = tx;
636                             last_ty = ty;
637                             tx = x;
638                             ty = y;
639                             Icon_Coords(tx, ty, &ix, &iy);
640                             if (GraphicsOp == ERASER) {
641                               for (i=ix-1; i<=ix+1; i++)
642                                 for (j=iy-1; j<=iy+1; j++) {
643                                   XDrawPoint(dpy, color_icon, Erase_gc, i, j);
644                                   XDrawPoint(dpy,
645                                         XtWindow(iconImage),
646                                         Erase_gc, i, j);
647                                   XDrawPoint(dpy, mono_icon, Erase_gc, i, j);
648                                   XDrawPoint(dpy,
649                                         XtWindow(monoImage),
650                                         Erase_gc, i, j);
651                                   Paint_Tile(i, j, Erase_gc);
652                                  } /* for */
653                              } /* if(GraphicsOp...) */
654                             else {
655                               XDrawPoint(dpy, color_icon, Color_gc, ix, iy);
656                               XDrawPoint(dpy, XtWindow(iconImage),
657                                 Color_gc, ix, iy);
658                               XDrawPoint(dpy, mono_icon, Mono_gc, ix, iy);
659                               XDrawPoint(dpy, XtWindow(monoImage),
660                                 Mono_gc, ix, iy);
661                               Paint_Tile(ix, iy, Color_gc);
662                              } /* else */
663                            }
664          case FLOOD     : break;
665          case POLYLINE  :
666          case POLYGON   : if (Anchored) {
667                             Quantize(&x, &y, True);
668                             if (!First)
669                               XDrawLine(dpy, tablet_win,
670                                 Flicker_gc, tx, ty, last_tx, last_ty);
671                             tx = x;
672                             ty = y;
673                             XDrawLine(dpy, tablet_win,
674                                 Flicker_gc, tx, ty, last_tx, last_ty);
675                             First = False;
676                            }
677                           break;
678          case LINE      : if (Pressed) {
679                             Quantize(&x, &y, True);
680                             if (!First)
681                               XDrawLine(dpy, tablet_win,
682                                 Flicker_gc, tx, ty, last_tx, last_ty);
683                             tx = x;
684                             ty = y;
685                             XDrawLine(dpy, tablet_win,
686                                 Flicker_gc, tx, ty, last_tx, last_ty);
687                             First = False;
688                            }
689                           break;
690          case ELLIPSE   :
691          case SELECT    :
692          case S_SCALE_1 :
693          case RECTANGLE : if (Pressed) {
694                             Quantize(&x, &y, True);
695                             if (!First) {
696                               if (GraphicsOp != ELLIPSE)
697                                 XDrawRectangle(dpy, tablet_win, Flicker_gc,
698                                         min(tx, last_tx), min(ty, last_ty),
699                                         abs(tx-last_tx), abs(ty-last_ty));
700                               else
701                                 XDrawArc(dpy, tablet_win, Flicker_gc,
702                                         min(tx, last_tx), min(ty, last_ty),
703                                         abs(tx-last_tx), abs(ty-last_ty),
704                                         0, 360*64);
705                              }
706                             tx = x;
707                             ty = y;
708                             if (GraphicsOp != ELLIPSE)
709                               XDrawRectangle(dpy, tablet_win,
710                                 Flicker_gc, min(tx, last_tx), min(ty, last_ty),
711                                 abs(tx-last_tx), abs(ty-last_ty));
712                             else
713                               XDrawArc(dpy, tablet_win,
714                                 Flicker_gc, min(tx, last_tx), min(ty, last_ty),
715                                 abs(tx-last_tx), abs(ty-last_ty), 0, 360*64);
716                             First = False;
717                            }
718                           break;
719          case S_GRAB    : if (Pressed) {
720                             if (!First)
721                                 XDrawRectangle(dpy, lwin, Flicker_gc,
722                                         min(tx, last_tx), min(ty, last_ty),
723                                         abs(tx-last_tx), abs(ty-last_ty));
724                             if (mag(last_tx, x) <= xrdb.maxIconWidth)
725                               tx = x;
726                             if (mag(last_ty, y) <= xrdb.maxIconHeight)
727                               ty = y;
728                             XDrawRectangle(dpy, lwin,
729                                 Flicker_gc, min(tx, last_tx), min(ty, last_ty),
730                                 abs(tx-last_tx), abs(ty-last_ty));
731                             First = False;
732                             /* Tell the user the size of the grabbed image
733                             */
734                              sprintf(tmpstr, 
735                                GETSTR(18,2,"Grabbed Image Size = %dx%d"), 
736                                abs(tx-last_tx), abs(ty-last_ty));
737                              str= XmStringCreateLocalized (tmpstr);
738                              XtVaSetValues (coordinateText, XmNlabelString, str, NULL);
739                              XmStringFree(str);
740                            }
741                           break;
742          case CIRCLE    : if (Pressed) {
743                             Quantize(&x, &y, True);
744                             if (!First)
745                               Circle_Box(tablet_win,
746                                 last_tx, last_ty, tx, ty, &box);
747                             tx = x;
748                             ty = y;
749                             Circle_Box(tablet_win,
750                                 last_tx, last_ty, tx, ty, &box);
751                             First = False;
752                            }
753                           break;
754        } /* switch(GraphicsOp) */
755     break;
756     case LeaveNotify :
757       switch (GraphicsOp) {
758          case POLYLINE  :
759          case POLYGON   : if (Anchored) {
760                             if (!First)
761                               XDrawLine(dpy, tablet_win, Flicker_gc, tx, ty,
762                                         last_tx, last_ty);
763                             First = True;
764                            }
765                           break;
766        } /* switch(GraphicsOp) */
767     break;
768    } /* switch(e_type) */
769 }
770
771
772 /***************************************************************************
773  * Routine:   EndPolyOp                                                    *
774  * Purpose:   When user does a mouse action outside of the drawing window, *
775  *            this implicitly ends the poly* operation.  This means that   *
776  *            things like drawing circles and changing pen color while in  *
777  *            the middle of a polyline or polygon is no longer allowed.    *
778  ***************************************************************************/
779 void
780 EndPolyOp()
781 {
782     Anchored = False;
783     Clear_ClickCount();
784     pointCount = 0;
785 }
786
787 void
788 iLine(
789         int x1,
790         int y1,
791         int x2,
792         int y2,
793         Boolean backupFlag )
794 {
795   if (backupFlag)
796     Backup_Icons();
797   XDrawLine(dpy, color_icon, Color_gc, x1, y1, x2, y2);
798   XDrawLine(dpy, mono_icon, Mono_gc, x1, y1, x2, y2);
799   XDrawLine(dpy, XtWindow(iconImage), Color_gc, x1, y1, x2, y2);
800   XDrawLine(dpy, XtWindow(monoImage), Mono_gc, x1, y1, x2, y2);
801 #ifdef DEBUG
802   if (debug)
803     stat_out("Transferring from [%d,%d] to [%d,%d]\n", tx, ty,
804                 last_tx, last_ty);
805 #endif
806   Transfer_Back_Image(x1, y1, x2, y2, FILL);
807 }
808
809 void
810 iRectangle(
811         int x,
812         int y,
813         int width,
814         int height,
815         Boolean backupFlag )
816 {
817   if (backupFlag)
818     Backup_Icons();
819   if (FillSolids) {
820     XFillRectangle(dpy, color_icon, Color_gc, x, y, width+1, height+1);
821     XFillRectangle(dpy, mono_icon, Mono_gc, x, y, width+1, height+1);
822     XFillRectangle(dpy, XtWindow(iconImage), Color_gc,
823                         x, y, width+1, height+1);
824     XFillRectangle(dpy, XtWindow(monoImage), Mono_gc,
825                         x, y, width+1, height+1);
826    }
827   else {
828     XDrawRectangle(dpy, color_icon, Color_gc, x, y, width, height);
829     XDrawRectangle(dpy, mono_icon, Mono_gc, x, y, width, height);
830     XDrawRectangle(dpy, XtWindow(iconImage), Color_gc,
831                         x, y, width, height);
832     XDrawRectangle(dpy, XtWindow(monoImage), Mono_gc,
833                         x, y, width, height);
834    }
835   Transfer_Back_Image(x, y, x+width, y+height, FILL);
836 }
837
838 void
839 iArc(
840         int x,
841         int y,
842         int width,
843         int height,
844         Boolean backupFlag )
845 {
846   if (backupFlag)
847     Backup_Icons();
848   if (FillSolids) {
849     XFillArc(dpy, color_icon, Color_gc, x, y, width, height, 0, 360*64);
850     XFillArc(dpy, mono_icon, Mono_gc, x, y, width, height, 0, 360*64);
851     XFillArc(dpy, XtWindow(iconImage),
852         Color_gc, x, y, width, height, 0, 360*64);
853     XFillArc(dpy, XtWindow(monoImage),
854         Mono_gc, x, y, width, height, 0, 360*64);
855    }
856   else {
857     XDrawArc(dpy, color_icon, Color_gc, x, y, width, height, 0, 360*64);
858     XDrawArc(dpy, mono_icon, Mono_gc, x, y, width, height, 0, 360*64);
859     XDrawArc(dpy, XtWindow(iconImage),
860         Color_gc, x, y, width, height, 0, 360*64);
861     XDrawArc(dpy, XtWindow(monoImage),
862         Mono_gc, x, y, width, height, 0, 360*64);
863    }
864   Transfer_Back_Image(x, y, x+width, y+height, FILL);
865 }
866
867 void
868 iPolygon( void )
869 {
870   int min_x, min_y, max_x, max_y, i;
871
872 #ifdef DEBUG
873   if (debug)
874     stat_out("iPolygon: pointCount = %d\n", pointCount);
875 #endif
876
877   if (FillSolids) {
878     XFillPolygon(dpy, color_icon, Color_gc, pointList, pointCount,
879         Complex, CoordModeOrigin);
880     XFillPolygon(dpy, mono_icon, Mono_gc, pointList, pointCount,
881         Complex, CoordModeOrigin);
882     XFillPolygon(dpy, XtWindow(iconImage),
883         Color_gc, pointList, pointCount, Complex, CoordModeOrigin);
884     XFillPolygon(dpy, XtWindow(monoImage),
885         Mono_gc, pointList, pointCount, Complex, CoordModeOrigin);
886    }
887   else {
888     if (pointCount < MAX_PTS) {
889       pointList[pointCount].x = pointList[0].x;
890       pointList[pointCount].y = pointList[0].y;
891       pointCount++;
892      }
893     XDrawLines(dpy, color_icon, Color_gc, pointList, pointCount, Complex);
894     XDrawLines(dpy, mono_icon, Mono_gc, pointList, pointCount, Complex);
895     XDrawLines(dpy, XtWindow(iconImage), Color_gc, pointList,
896         pointCount, Complex);
897     XDrawLines(dpy, XtWindow(monoImage), Mono_gc, pointList,
898         pointCount, Complex);
899    }
900   min_x = pointList[0].x;
901   min_y = pointList[0].y;
902   max_x = min_x;
903   max_y = min_y;
904   for (i=1; i<pointCount; i++) {
905     if (pointList[i].x < min_x) min_x = pointList[i].x;
906     if (pointList[i].y < min_y) min_y = pointList[i].y;
907     if (pointList[i].x > max_x) max_x = pointList[i].x;
908     if (pointList[i].y > max_y) max_y = pointList[i].y;
909    }
910   Transfer_Back_Image(min_x, min_y, max_x, max_y, FILL);
911 }