home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
vsiftp.vmssoftware.com
/
VSIPUBLIC@vsiftp.vmssoftware.com.tar
/
FREEWARE
/
FREEWARE40.ZIP
/
xpaint-247
/
circleop.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-06-25
|
8KB
|
321 lines
/* +-------------------------------------------------------------------+ */
/* | Copyright 1992, 1993, David Koblas (koblas@netcom.com) | */
/* | Copyright 1995, 1996 Torsten Martinsen (bullestock@dk-online.dk) | */
/* | | */
/* | Permission to use, copy, modify, and to distribute this software | */
/* | and its documentation for any purpose is hereby granted without | */
/* | fee, provided that the above copyright notice appear in all | */
/* | copies and that both that copyright notice and this permission | */
/* | notice appear in supporting documentation. There is no | */
/* | representations about the suitability of this software for | */
/* | any purpose. this software is provided "as is" without express | */
/* | or implied warranty. | */
/* | | */
/* +-------------------------------------------------------------------+ */
/* $Id: circleOp.c,v 1.3 1996/04/19 09:06:03 torsten Exp $ */
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <math.h>
#include "xpaint.h"
#include "misc.h"
#include "Paint.h"
#include "ops.h"
#define FILL 0x02
#define CIRCLE 0x01
#define ISFILL(x) ((x) & FILL)
#define ISCIRCLE(x) ((x) & CIRCLE)
typedef struct {
Boolean typeFlag, swap;
int rx, ry, startX, startY, endX, endY, drawn, flag;
GC gcx;
} LocalInfo;
static int radiusMode = False;
static XRectangle *
draw(Widget w, Drawable d, GC lgc, GC fgc, LocalInfo * l)
{
static XRectangle rect;
XArc arc;
int sx = l->startX, sy = l->startY;
int ex = l->endX, ey = l->endY;
int dx = ABS(sx - ex), dy = ABS(sy - ey);
if ((sx == ex) && (sy == ey))
return NULL;
if (ISCIRCLE(l->typeFlag))
dx = dy = MAX(dx, dy);
if (radiusMode) {
arc.x = sx - dx;
arc.y = sy - dy;
arc.width = 2 * dx;
arc.height = 2 * dy;
} else {
if (sx > ex)
arc.x = ex;
else
arc.x = sx;
if (sy > ey)
arc.y = ey;
else
arc.y = sy;
arc.width = dx;
arc.height = dy;
}
arc.angle1 = 0;
arc.angle2 = 360 * 64;
if (fgc != None)
XFillArcs(XtDisplay(w), d, fgc, &arc, 1);
if (lgc != None)
XDrawArcs(XtDisplay(w), d, lgc, &arc, 1);
rect.x = arc.x;
rect.y = arc.y;
rect.width = arc.width + 1;
rect.height = arc.height + 1;
return ▭
}
static void
press(Widget w, LocalInfo * l,
XButtonEvent * event, OpInfo * info)
{
/*
** Check to make sure all buttons are up, before doing this
*/
if ((event->state & AllButtonsMask) != 0)
return;
l->rx = info->x;
l->ry = info->y;
l->endX = l->startX = event->x;
l->endY = l->startY = event->y;
l->swap = (event->button == Button2);
l->typeFlag = (event->state & ShiftMask) ? CIRCLE : 0;
l->drawn = False;
}
static void
motion(Widget w, LocalInfo * l,
XMotionEvent * event, OpInfo * info)
{
if (l->drawn)
draw(w, info->drawable, l->gcx, None, l);
l->endX = event->x;
l->endY = event->y;
/*
** Really set this flag in the if statement
*/
l->typeFlag = (event->state & ShiftMask) ? CIRCLE : 0;
l->drawn = (draw(w, info->drawable, l->gcx, None, l) != NULL);
}
static void
release(Widget w, LocalInfo * l,
XButtonEvent * event, OpInfo * info)
{
XRectangle *undo;
int mask;
GC fgc, lgc;
/*
** Check to make sure all buttons are up, before doing this
*/
mask = AllButtonsMask;
switch (event->button) {
case Button1:
mask ^= Button1Mask;
break;
case Button2:
mask ^= Button2Mask;
break;
case Button3:
mask ^= Button3Mask;
break;
case Button4:
mask ^= Button4Mask;
break;
case Button5:
mask ^= Button5Mask;
break;
}
if ((event->state & mask) != 0)
return;
if (l->drawn && info->surface == opWindow)
draw(w, info->drawable, l->gcx, None, l);
if (info->surface == opWindow && info->isFat)
return;
UndoStart(w, info);
l->startX = l->rx;
l->startY = l->ry;
l->endX = event->x;
l->endY = event->y;
if (l->swap) {
fgc = info->first_gc;
lgc = info->second_gc;
} else {
fgc = info->second_gc;
lgc = info->first_gc;
}
if (!ISFILL(l->flag))
fgc = None;
undo = draw(w, info->drawable, lgc, fgc, l);
if (info->surface == opPixmap && undo != NULL) {
UndoSetRectangle(w, undo);
PwUpdate(w, undo, False);
}
}
/*
** Those public functions
*/
void *
CircleAdd(Widget w)
{
LocalInfo *l = (LocalInfo *) XtMalloc(sizeof(LocalInfo));
l->flag = CIRCLE;
l->gcx = GetGCX(w);
XtVaSetValues(w, XtNcompress, True, NULL);
OpAddEventHandler(w, opWindow, ButtonPressMask, FALSE,
(OpEventProc) press, l);
OpAddEventHandler(w, opWindow, ButtonMotionMask, FALSE,
(OpEventProc) motion, l);
OpAddEventHandler(w, opWindow | opPixmap, ButtonReleaseMask, FALSE,
(OpEventProc) release, l);
SetCrossHairCursor(w);
return l;
}
void
CircleRemove(Widget w, void *l)
{
OpRemoveEventHandler(w, opWindow, ButtonPressMask, FALSE,
(OpEventProc) press, l);
OpRemoveEventHandler(w, opWindow, ButtonMotionMask, FALSE,
(OpEventProc) motion, l);
OpRemoveEventHandler(w, opWindow | opPixmap, ButtonReleaseMask, FALSE,
(OpEventProc) release, l);
XtFree((XtPointer) l);
}
void *
FCircleAdd(Widget w)
{
LocalInfo *l = (LocalInfo *) XtMalloc(sizeof(LocalInfo));
l->flag = CIRCLE | FILL;
l->gcx = GetGCX(w);
XtVaSetValues(w, XtNcompress, True, NULL);
OpAddEventHandler(w, opWindow, ButtonPressMask, FALSE,
(OpEventProc) press, l);
OpAddEventHandler(w, opWindow, ButtonMotionMask, FALSE,
(OpEventProc) motion, l);
OpAddEventHandler(w, opWindow | opPixmap, ButtonReleaseMask, FALSE,
(OpEventProc) release, l);
SetCrossHairCursor(w);
return l;
}
void
FCircleRemove(Widget w, void *l)
{
OpRemoveEventHandler(w, opWindow, ButtonPressMask, FALSE,
(OpEventProc) press, l);
OpRemoveEventHandler(w, opWindow, ButtonMotionMask, FALSE,
(OpEventProc) motion, l);
OpRemoveEventHandler(w, opWindow | opPixmap, ButtonReleaseMask, FALSE,
(OpEventProc) release, l);
XtFree((XtPointer) l);
}
void *
OvalAdd(Widget w)
{
LocalInfo *l = (LocalInfo *) XtMalloc(sizeof(LocalInfo));
l->flag = 0;
l->gcx = GetGCX(w);
XtVaSetValues(w, XtNcompress, True, NULL);
OpAddEventHandler(w, opWindow, ButtonPressMask, FALSE,
(OpEventProc) press, l);
OpAddEventHandler(w, opWindow, ButtonMotionMask, FALSE,
(OpEventProc) motion, l);
OpAddEventHandler(w, opWindow | opPixmap, ButtonReleaseMask, FALSE,
(OpEventProc) release, l);
SetCrossHairCursor(w);
return l;
}
void
OvalRemove(Widget w, void *l)
{
OpRemoveEventHandler(w, opWindow, ButtonPressMask, FALSE,
(OpEventProc) press, l);
OpRemoveEventHandler(w, opWindow, ButtonMotionMask, FALSE,
(OpEventProc) motion, l);
OpRemoveEventHandler(w, opWindow | opPixmap, ButtonReleaseMask, FALSE,
(OpEventProc) release, l);
XtFree((XtPointer) l);
}
void *
FOvalAdd(Widget w)
{
LocalInfo *l = (LocalInfo *) XtMalloc(sizeof(LocalInfo));
l->flag = FILL;
l->gcx = GetGCX(w);
XtVaSetValues(w, XtNcompress, True, NULL);
OpAddEventHandler(w, opWindow, ButtonPressMask, FALSE,
(OpEventProc) press, l);
OpAddEventHandler(w, opWindow, ButtonMotionMask, FALSE,
(OpEventProc) motion, l);
OpAddEventHandler(w, opWindow | opPixmap, ButtonReleaseMask, FALSE,
(OpEventProc) release, l);
SetCrossHairCursor(w);
return l;
}
void
FOvalRemove(Widget w, void *l)
{
OpRemoveEventHandler(w, opWindow, ButtonPressMask, FALSE,
(OpEventProc) press, l);
OpRemoveEventHandler(w, opWindow, ButtonMotionMask, FALSE,
(OpEventProc) motion, l);
OpRemoveEventHandler(w, opWindow | opPixmap, ButtonReleaseMask, FALSE,
(OpEventProc) release, l);
XtFree((XtPointer) l);
}
void
CircleSetStyle(Boolean value)
{
radiusMode = value;
}
Boolean
CircleGetStyle(void)
{
return radiusMode;
}