home *** CD-ROM | disk | FTP | other *** search
/ vsiftp.vmssoftware.com / VSIPUBLIC@vsiftp.vmssoftware.com.tar / FREEWARE / FREEWARE40.ZIP / xpaint-244 / src / circleop.c < prev    next >
C/C++ Source or Header  |  1996-04-19  |  8KB  |  321 lines

  1. /* +-------------------------------------------------------------------+ */
  2. /* | Copyright 1992, 1993, David Koblas (koblas@netcom.com)           | */
  3. /* | Copyright 1995, 1996 Torsten Martinsen (bullestock@dk-online.dk)  | */
  4. /* |                                       | */
  5. /* | Permission to use, copy, modify, and to distribute this software  | */
  6. /* | and its documentation for any purpose is hereby granted without   | */
  7. /* | fee, provided that the above copyright notice appear in all       | */
  8. /* | copies and that both that copyright notice and this permission    | */
  9. /* | notice appear in supporting documentation.     There is no           | */
  10. /* | representations about the suitability of this software for           | */
  11. /* | any purpose.  this software is provided "as is" without express   | */
  12. /* | or implied warranty.                           | */
  13. /* |                                       | */
  14. /* +-------------------------------------------------------------------+ */
  15.  
  16. /* $Id: circleOp.c,v 1.3 1996/04/19 09:06:03 torsten Exp $ */
  17.  
  18. #include <X11/Intrinsic.h>
  19. #include <X11/StringDefs.h>
  20. #include <math.h>
  21. #include "xpaint.h"
  22. #include "misc.h"
  23. #include "Paint.h"
  24. #include "ops.h"
  25.  
  26. #define    FILL        0x02
  27. #define CIRCLE        0x01
  28. #define    ISFILL(x)    ((x) & FILL)
  29. #define ISCIRCLE(x)    ((x) & CIRCLE)
  30.  
  31. typedef struct {
  32.     Boolean typeFlag, swap;
  33.     int rx, ry, startX, startY, endX, endY, drawn, flag;
  34.     GC gcx;
  35. } LocalInfo;
  36.  
  37. static int radiusMode = False;
  38.  
  39. static XRectangle *
  40. draw(Widget w, Drawable d, GC lgc, GC fgc, LocalInfo * l)
  41. {
  42.     static XRectangle rect;
  43.     XArc arc;
  44.     int sx = l->startX, sy = l->startY;
  45.     int ex = l->endX, ey = l->endY;
  46.     int dx = ABS(sx - ex), dy = ABS(sy - ey);
  47.  
  48.     if ((sx == ex) && (sy == ey))
  49.     return NULL;
  50.  
  51.     if (ISCIRCLE(l->typeFlag))
  52.     dx = dy = MAX(dx, dy);
  53.  
  54.     if (radiusMode) {
  55.     arc.x = sx - dx;
  56.     arc.y = sy - dy;
  57.     arc.width = 2 * dx;
  58.     arc.height = 2 * dy;
  59.     } else {
  60.     if (sx > ex)
  61.         arc.x = ex;
  62.     else
  63.         arc.x = sx;
  64.     if (sy > ey)
  65.         arc.y = ey;
  66.     else
  67.         arc.y = sy;
  68.     arc.width = dx;
  69.     arc.height = dy;
  70.     }
  71.     arc.angle1 = 0;
  72.     arc.angle2 = 360 * 64;
  73.  
  74.     if (fgc != None)
  75.     XFillArcs(XtDisplay(w), d, fgc, &arc, 1);
  76.     if (lgc != None)
  77.     XDrawArcs(XtDisplay(w), d, lgc, &arc, 1);
  78.  
  79.     rect.x = arc.x;
  80.     rect.y = arc.y;
  81.     rect.width = arc.width + 1;
  82.     rect.height = arc.height + 1;
  83.  
  84.     return ▭
  85. }
  86.  
  87. static void 
  88. press(Widget w, LocalInfo * l,
  89.       XButtonEvent * event, OpInfo * info)
  90. {
  91.     /*
  92.     **    Check to make sure all buttons are up, before doing this
  93.      */
  94.     if ((event->state & AllButtonsMask) != 0)
  95.     return;
  96.  
  97.     l->rx = info->x;
  98.     l->ry = info->y;
  99.     l->endX = l->startX = event->x;
  100.     l->endY = l->startY = event->y;
  101.  
  102.     l->swap = (event->button == Button2);
  103.  
  104.     l->typeFlag = (event->state & ShiftMask) ? CIRCLE : 0;
  105.  
  106.     l->drawn = False;
  107. }
  108.  
  109. static void 
  110. motion(Widget w, LocalInfo * l,
  111.        XMotionEvent * event, OpInfo * info)
  112. {
  113.     if (l->drawn)
  114.     draw(w, info->drawable, l->gcx, None, l);
  115.  
  116.     l->endX = event->x;
  117.     l->endY = event->y;
  118.  
  119.     /*
  120.     **    Really set this flag in the if statement
  121.      */
  122.     l->typeFlag = (event->state & ShiftMask) ? CIRCLE : 0;
  123.     l->drawn = (draw(w, info->drawable, l->gcx, None, l) != NULL);
  124. }
  125.  
  126. static void 
  127. release(Widget w, LocalInfo * l,
  128.     XButtonEvent * event, OpInfo * info)
  129. {
  130.     XRectangle *undo;
  131.     int mask;
  132.     GC fgc, lgc;
  133.  
  134.     /*
  135.     **    Check to make sure all buttons are up, before doing this
  136.      */
  137.     mask = AllButtonsMask;
  138.     switch (event->button) {
  139.     case Button1:
  140.     mask ^= Button1Mask;
  141.     break;
  142.     case Button2:
  143.     mask ^= Button2Mask;
  144.     break;
  145.     case Button3:
  146.     mask ^= Button3Mask;
  147.     break;
  148.     case Button4:
  149.     mask ^= Button4Mask;
  150.     break;
  151.     case Button5:
  152.     mask ^= Button5Mask;
  153.     break;
  154.     }
  155.     if ((event->state & mask) != 0)
  156.     return;
  157.  
  158.     if (l->drawn && info->surface == opWindow)
  159.     draw(w, info->drawable, l->gcx, None, l);
  160.  
  161.     if (info->surface == opWindow && info->isFat)
  162.     return;
  163.  
  164.     UndoStart(w, info);
  165.  
  166.     l->startX = l->rx;
  167.     l->startY = l->ry;
  168.     l->endX = event->x;
  169.     l->endY = event->y;
  170.  
  171.     if (l->swap) {
  172.     fgc = info->first_gc;
  173.     lgc = info->second_gc;
  174.     } else {
  175.     fgc = info->second_gc;
  176.     lgc = info->first_gc;
  177.     }
  178.  
  179.     if (!ISFILL(l->flag))
  180.     fgc = None;
  181.  
  182.     undo = draw(w, info->drawable, lgc, fgc, l);
  183.  
  184.     if (info->surface == opPixmap && undo != NULL) {
  185.     UndoSetRectangle(w, undo);
  186.     PwUpdate(w, undo, False);
  187.     }
  188. }
  189.  
  190. /*
  191. **  Those public functions
  192.  */
  193. void *
  194. CircleAdd(Widget w)
  195. {
  196.     LocalInfo *l = (LocalInfo *) XtMalloc(sizeof(LocalInfo));
  197.     l->flag = CIRCLE;
  198.     l->gcx = GetGCX(w);
  199.     XtVaSetValues(w, XtNcompress, True, NULL);
  200.     OpAddEventHandler(w, opWindow, ButtonPressMask, FALSE,
  201.               (OpEventProc) press, l);
  202.     OpAddEventHandler(w, opWindow, ButtonMotionMask, FALSE,
  203.               (OpEventProc) motion, l);
  204.     OpAddEventHandler(w, opWindow | opPixmap, ButtonReleaseMask, FALSE,
  205.               (OpEventProc) release, l);
  206.     SetCrossHairCursor(w);
  207.     return l;
  208. }
  209.  
  210. void 
  211. CircleRemove(Widget w, void *l)
  212. {
  213.     OpRemoveEventHandler(w, opWindow, ButtonPressMask, FALSE,
  214.              (OpEventProc) press, l);
  215.     OpRemoveEventHandler(w, opWindow, ButtonMotionMask, FALSE,
  216.              (OpEventProc) motion, l);
  217.     OpRemoveEventHandler(w, opWindow | opPixmap, ButtonReleaseMask, FALSE,
  218.              (OpEventProc) release, l);
  219.     XtFree((XtPointer) l);
  220. }
  221.  
  222. void *
  223. FCircleAdd(Widget w)
  224. {
  225.     LocalInfo *l = (LocalInfo *) XtMalloc(sizeof(LocalInfo));
  226.     l->flag = CIRCLE | FILL;
  227.     l->gcx = GetGCX(w);
  228.     XtVaSetValues(w, XtNcompress, True, NULL);
  229.     OpAddEventHandler(w, opWindow, ButtonPressMask, FALSE,
  230.               (OpEventProc) press, l);
  231.     OpAddEventHandler(w, opWindow, ButtonMotionMask, FALSE,
  232.               (OpEventProc) motion, l);
  233.     OpAddEventHandler(w, opWindow | opPixmap, ButtonReleaseMask, FALSE,
  234.               (OpEventProc) release, l);
  235.     SetCrossHairCursor(w);
  236.     return l;
  237. }
  238.  
  239. void 
  240. FCircleRemove(Widget w, void *l)
  241. {
  242.     OpRemoveEventHandler(w, opWindow, ButtonPressMask, FALSE,
  243.              (OpEventProc) press, l);
  244.     OpRemoveEventHandler(w, opWindow, ButtonMotionMask, FALSE,
  245.              (OpEventProc) motion, l);
  246.     OpRemoveEventHandler(w, opWindow | opPixmap, ButtonReleaseMask, FALSE,
  247.              (OpEventProc) release, l);
  248.     XtFree((XtPointer) l);
  249. }
  250.  
  251. void *
  252. OvalAdd(Widget w)
  253. {
  254.     LocalInfo *l = (LocalInfo *) XtMalloc(sizeof(LocalInfo));
  255.     l->flag = 0;
  256.     l->gcx = GetGCX(w);
  257.     XtVaSetValues(w, XtNcompress, True, NULL);
  258.     OpAddEventHandler(w, opWindow, ButtonPressMask, FALSE,
  259.               (OpEventProc) press, l);
  260.     OpAddEventHandler(w, opWindow, ButtonMotionMask, FALSE,
  261.               (OpEventProc) motion, l);
  262.     OpAddEventHandler(w, opWindow | opPixmap, ButtonReleaseMask, FALSE,
  263.               (OpEventProc) release, l);
  264.     SetCrossHairCursor(w);
  265.     return l;
  266. }
  267.  
  268. void 
  269. OvalRemove(Widget w, void *l)
  270. {
  271.     OpRemoveEventHandler(w, opWindow, ButtonPressMask, FALSE,
  272.              (OpEventProc) press, l);
  273.     OpRemoveEventHandler(w, opWindow, ButtonMotionMask, FALSE,
  274.              (OpEventProc) motion, l);
  275.     OpRemoveEventHandler(w, opWindow | opPixmap, ButtonReleaseMask, FALSE,
  276.              (OpEventProc) release, l);
  277.     XtFree((XtPointer) l);
  278. }
  279.  
  280. void *
  281. FOvalAdd(Widget w)
  282. {
  283.     LocalInfo *l = (LocalInfo *) XtMalloc(sizeof(LocalInfo));
  284.     l->flag = FILL;
  285.     l->gcx = GetGCX(w);
  286.     XtVaSetValues(w, XtNcompress, True, NULL);
  287.  
  288.     OpAddEventHandler(w, opWindow, ButtonPressMask, FALSE,
  289.               (OpEventProc) press, l);
  290.     OpAddEventHandler(w, opWindow, ButtonMotionMask, FALSE,
  291.               (OpEventProc) motion, l);
  292.     OpAddEventHandler(w, opWindow | opPixmap, ButtonReleaseMask, FALSE,
  293.               (OpEventProc) release, l);
  294.     SetCrossHairCursor(w);
  295.     return l;
  296. }
  297.  
  298. void 
  299. FOvalRemove(Widget w, void *l)
  300. {
  301.     OpRemoveEventHandler(w, opWindow, ButtonPressMask, FALSE,
  302.              (OpEventProc) press, l);
  303.     OpRemoveEventHandler(w, opWindow, ButtonMotionMask, FALSE,
  304.              (OpEventProc) motion, l);
  305.     OpRemoveEventHandler(w, opWindow | opPixmap, ButtonReleaseMask, FALSE,
  306.              (OpEventProc) release, l);
  307.     XtFree((XtPointer) l);
  308. }
  309.  
  310. void 
  311. CircleSetStyle(Boolean value)
  312. {
  313.     radiusMode = value;
  314. }
  315.  
  316. Boolean
  317. CircleGetStyle(void)
  318. {
  319.     return radiusMode;
  320. }
  321.