home *** CD-ROM | disk | FTP | other *** search
/ vsiftp.vmssoftware.com / VSIPUBLIC@vsiftp.vmssoftware.com.tar / FREEWARE / FREEWARE40.ZIP / xpaint-247 / arcop.c < prev    next >
C/C++ Source or Header  |  1996-06-25  |  5KB  |  200 lines

  1. /* +-------------------------------------------------------------------+ */
  2. /* | Copyright 1992, 1993, David Koblas (koblas@netcom.com)           | */
  3. /* |                                       | */
  4. /* | Permission to use, copy, modify, and to distribute this software  | */
  5. /* | and its documentation for any purpose is hereby granted without   | */
  6. /* | fee, provided that the above copyright notice appear in all       | */
  7. /* | copies and that both that copyright notice and this permission    | */
  8. /* | notice appear in supporting documentation.     There is no           | */
  9. /* | representations about the suitability of this software for           | */
  10. /* | any purpose.  this software is provided "as is" without express   | */
  11. /* | or implied warranty.                           | */
  12. /* |                                       | */
  13. /* +-------------------------------------------------------------------+ */
  14.  
  15. /* $Id: arcOp.c,v 1.3 1996/04/19 09:04:59 torsten Exp $ */
  16.  
  17. #include <X11/Intrinsic.h>
  18. #include <X11/StringDefs.h>
  19. #include "xpaint.h"
  20. #include "Paint.h"
  21. #include "misc.h"
  22. #include "ops.h"
  23.  
  24. typedef struct {
  25.     Boolean lastFlag;
  26.     int rx, ry, startX, startY, endX, endY, drawn;
  27.     GC gcx;
  28. } LocalInfo;
  29.  
  30. #define MKRECT(rect, sx, sy, ex, ey, flag) do {                \
  31.     (rect)->x      = MIN(sx, ex);                    \
  32.     (rect)->y      = MIN(sy, ey);                    \
  33.     (rect)->width  = MAX(sx, ex) - (rect)->x;            \
  34.     (rect)->height = MAX(sy, ey) - (rect)->y;            \
  35.     if (flag) {                            \
  36.         (rect)->width = MIN((rect)->width, (rect)->height);    \
  37.         (rect)->height = (rect)->width;                \
  38.         (rect)->x = (ex - sx) < 0 ? sx - (rect)->width : sx;    \
  39.         (rect)->y = (ey - sy) < 0 ? sy - (rect)->width : sy;    \
  40.     }                                \
  41.     if (sx < ex) {                            \
  42.         if (sy < ey) {                        \
  43.             /* +,+ */                    \
  44.             (rect)->x -= (rect)->width;            \
  45.             (rect)->angle1 =   0*64;            \
  46.             (rect)->angle2 =  90*64;            \
  47.         } else {                        \
  48.             /* +,- */                    \
  49.             /* No Change */                    \
  50.             (rect)->angle1 =  90*64;            \
  51.             (rect)->angle2 =  90*64;            \
  52.         }                            \
  53.     } else {                            \
  54.         if (sy < ey) {                        \
  55.             /* -,+ */                    \
  56.             (rect)->x -= (rect)->width;            \
  57.             (rect)->y -= (rect)->height;            \
  58.             (rect)->angle1 =   0*64;            \
  59.             (rect)->angle2 = -90*64;            \
  60.         } else {                        \
  61.             /* -,- */                    \
  62.             (rect)->y -= (rect)->height;            \
  63.             (rect)->angle1 = -90*64;            \
  64.             (rect)->angle2 = -90*64;            \
  65.         }                            \
  66.     }                                \
  67.     (rect)->width *= 2;                        \
  68.     (rect)->height *= 2;                        \
  69.     } while (0)
  70.  
  71. static void 
  72. press(Widget w, LocalInfo * l, XButtonEvent * event, OpInfo * info)
  73. {
  74.     /*
  75.     **    Check to make sure all buttons are up, before doing this
  76.      */
  77.     if ((event->state & AllButtonsMask) != 0)
  78.     return;
  79.  
  80.     l->rx = info->x;
  81.     l->ry = info->y;
  82.     l->endX = l->startX = event->x;
  83.     l->endY = l->startY = event->y;
  84.  
  85.     l->drawn = False;
  86. }
  87.  
  88.  
  89. static void 
  90. motion(Widget w, LocalInfo * l,
  91.        XMotionEvent * event, OpInfo * info)
  92. {
  93.     XArc rect;
  94.  
  95.     if (l->drawn) {
  96.     MKRECT(&rect, l->startX, l->startY, l->endX, l->endY, l->lastFlag);
  97.  
  98.     XDrawArcs(XtDisplay(w), XtWindow(w), l->gcx,
  99.           &rect, 1);
  100.     }
  101.     l->endX = event->x;
  102.     l->endY = event->y;
  103.     l->lastFlag = event->state & ShiftMask;
  104.  
  105.     /*
  106.     **    Really set this flag in the if statement
  107.      */
  108.     if ((l->drawn = (l->startX != l->endX && l->startY != l->endY))) {
  109.     MKRECT(&rect, l->startX, l->startY, l->endX, l->endY, l->lastFlag);
  110.  
  111.     XDrawArcs(XtDisplay(w), XtWindow(w), l->gcx,
  112.           &rect, 1);
  113.     }
  114. }
  115.  
  116. static void 
  117. release(Widget w, LocalInfo * l,
  118.     XButtonEvent * event, OpInfo * info)
  119. {
  120.     XArc rect;
  121.     XRectangle undo;
  122.     int mask;
  123.  
  124.     /*
  125.     **    Check to make sure all buttons are up, before doing this
  126.      */
  127.     mask = AllButtonsMask;
  128.     switch (event->button) {
  129.     case Button1:
  130.     mask ^= Button1Mask;
  131.     break;
  132.     case Button2:
  133.     mask ^= Button2Mask;
  134.     break;
  135.     case Button3:
  136.     mask ^= Button3Mask;
  137.     break;
  138.     case Button4:
  139.     mask ^= Button4Mask;
  140.     break;
  141.     case Button5:
  142.     mask ^= Button5Mask;
  143.     break;
  144.     }
  145.     if ((event->state & mask) != 0)
  146.     return;
  147.  
  148.     if (l->drawn && info->surface == opWindow) {
  149.     MKRECT(&rect, l->startX, l->startY, l->endX, l->endY, l->lastFlag);
  150.  
  151.     XDrawArcs(XtDisplay(w), XtWindow(w), l->gcx,
  152.           &rect, 1);
  153.     }
  154.     if (info->surface == opWindow && info->isFat)
  155.     return;
  156.  
  157.     UndoStart(w, info);
  158.  
  159.     MKRECT(&rect, l->rx, l->ry, event->x, event->y, l->lastFlag);
  160.     XDrawArcs(XtDisplay(w), info->drawable, info->first_gc, &rect, 1);
  161.  
  162.     if (info->surface == opPixmap) {
  163.     XYtoRECT(l->rx, l->ry, event->x, event->y, &undo);
  164.     UndoSetRectangle(w, &undo);
  165.     PwUpdate(w, &undo, False);
  166.     }
  167. }
  168.  
  169. /*
  170. **  Those public functions
  171.  */
  172. void *
  173. ArcAdd(Widget w)
  174. {
  175.     LocalInfo *l = (LocalInfo *) XtMalloc(sizeof(LocalInfo));
  176.  
  177.     XtVaSetValues(w, XtNcompress, True, NULL);
  178.     OpAddEventHandler(w, opWindow, ButtonPressMask, FALSE,
  179.               (OpEventProc) press, l);
  180.     OpAddEventHandler(w, opWindow, ButtonMotionMask, FALSE,
  181.               (OpEventProc) motion, l);
  182.     OpAddEventHandler(w, opWindow | opPixmap, ButtonReleaseMask, FALSE,
  183.               (OpEventProc) release, l);
  184.     SetCrossHairCursor(w);
  185.     l->gcx = GetGCX(w);
  186.     return l;
  187. }
  188.  
  189. void 
  190. ArcRemove(Widget w, void *l)
  191. {
  192.     OpRemoveEventHandler(w, opWindow, ButtonPressMask, FALSE,
  193.              (OpEventProc) press, l);
  194.     OpRemoveEventHandler(w, opWindow, ButtonMotionMask, FALSE,
  195.              (OpEventProc) motion, l);
  196.     OpRemoveEventHandler(w, opWindow | opPixmap, ButtonReleaseMask, FALSE,
  197.              (OpEventProc) release, l);
  198.     XtFree((XtPointer) l);
  199. }
  200.