v12i019: tgif, Part03/23
William Cheng
william at CS.UCLA.EDU
Mon Mar 11 08:38:18 AEST 1991
Submitted-by: william at CS.UCLA.EDU (William Cheng)
Posting-number: Volume 12, Issue 19
Archive-name: tgif/part03
---------------------------------> cut here <---------------------------------
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 3 (of 23)."
# Contents: drawing.c dup.c edit.c
# Wrapped by william at oahu on Wed Mar 6 09:57:03 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'drawing.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'drawing.c'\"
else
echo shar: Extracting \"'drawing.c'\" \(24657 characters\)
sed "s/^X//" >'drawing.c' <<'END_OF_FILE'
X/*
X * Author: William Chia-Wei Cheng (william at cs.ucla.edu)
X *
X * Copyright (C) 1990, 1991, William Cheng.
X */
X#ifndef lint
Xstatic char RCSid[] =
X "@(#)$Header: /tmp_mnt/n/kona/tangram/u/william/X11/TGIF2/RCS/drawing.c,v 2.0 91/03/05 15:26:27 william Exp $";
X#endif
X
X#include <X11/Xlib.h>
X#include <X11/Xutil.h>
X#include "const.h"
X#include "types.h"
X
X#include "align.e"
X#include "animate.e"
X#include "arc.e"
X#include "attr.e"
X#include "box.e"
X#include "choice.e"
X#include "copypaste.e"
X#include "cursor.e"
X#include "dialog.e"
X#include "dup.e"
X#include "edit.e"
X#include "file.e"
X#include "font.e"
X#include "grid.e"
X#include "group.e"
X#include "mark.e"
X#include "menu.e"
X#include "msg.e"
X#include "obj.e"
X#include "oval.e"
X#include "pattern.e"
X#include "poly.e"
X#include "polygon.e"
X#include "raster.e"
X#include "rcbox.e"
X#include "rect.e"
X#include "ruler.e"
X#include "scroll.e"
X#include "select.e"
X#include "setup.e"
X#include "special.e"
X#include "stk.e"
X#include "stretch.e"
X#include "text.e"
X#include "xbitmap.e"
X
X#define O_VIS 4
X#define O_INVIS 4
X#define O_GRID (O_VIS+O_INVIS)
X
Xvoid SetDefaultDrawWinClipRecs ()
X{
X XRectangle recs[1];
X
X SetRecVals (recs[0], 0, 0, drawWinW, drawWinH);
X XSetClipRectangles (mainDisplay, drawGC, 0, 0, recs, 1, YXBanded);
X}
X
Xvoid SetDefaultIconWinClipRecs ()
X{
X XRectangle recs[1];
X
X SetRecVals (recs[0], 0, 0, iconWindowW, iconWindowH);
X XSetClipRectangles (mainDisplay, drawGC, 0, 0, recs, 1, YXBanded);
X}
X
Xstatic
Xvoid DrawHorizOutline (Win, Y, X1, X2, XStart, XEnd, Pixel)
X Window Win;
X int Y, X1, X2, XStart, XEnd, Pixel;
X /* XStart and XEnd are the real place, X1 and X2 are on outline grid */
X{
X register int i;
X
X if (XStart-X1 < O_VIS)
X XDrawLine (mainDisplay, Win, defaultGC, XStart, Y, X1+O_VIS-1, Y);
X for (i = X1+O_GRID; i < X2-O_GRID; i+= O_GRID)
X XDrawLine (mainDisplay, Win, defaultGC, i, Y, i+O_VIS-1, Y);
X if (X2-XEnd < O_VIS)
X XDrawLine (mainDisplay, Win, defaultGC, X2-O_GRID, Y, XEnd, Y);
X else
X XDrawLine (mainDisplay, Win, defaultGC, X2-O_GRID, Y, X2-O_INVIS-1, Y);
X}
X
Xstatic
Xvoid DrawVertOutline (Win, X, Y1, Y2, YStart, YEnd, Pixel)
X Window Win;
X int X, Y1, Y2, YStart, YEnd, Pixel;
X /* YStart and YEnd are the real place, Y1 and Y2 are on outline grid */
X{
X register int i;
X
X if (YStart-Y1 < O_VIS)
X XDrawLine (mainDisplay, Win, defaultGC, X, YStart, X, Y1+O_VIS-1);
X for (i = Y1+O_GRID; i < Y2-O_GRID; i+= O_GRID)
X XDrawLine (mainDisplay, Win, defaultGC, X, i, X, i+O_VIS-1);
X if (Y2-YEnd < O_VIS)
X XDrawLine (mainDisplay, Win, defaultGC, X, Y2-O_GRID, X, YEnd);
X else
X XDrawLine (mainDisplay, Win, defaultGC, X, Y2-O_GRID, X, Y2-O_INVIS-1);
X}
X
Xstatic
Xvoid DrawSymOutline (Win, XOff, YOff, ObjPtr)
X Window Win;
X int XOff, YOff;
X struct ObjRec * ObjPtr;
X{
X int ltx, lty, rbx, rby, x_start, x_end, y_start, y_end, pixel;
X
X pixel = myFgPixel;
X
X ltx = ((ObjPtr->obbox.ltx - XOff - QUARTER_INCH) >> zoomScale) + 1;
X lty = ((ObjPtr->obbox.lty - YOff - QUARTER_INCH) >> zoomScale) + 1;
X rbx = ((ObjPtr->obbox.rbx - XOff + QUARTER_INCH) >> zoomScale) - 1;
X rby = ((ObjPtr->obbox.rby - YOff + QUARTER_INCH) >> zoomScale) - 1;
X
X x_start = (ltx % O_GRID == 0) ? ltx : (int)(ltx / O_GRID) * O_GRID;
X x_end = (rbx % O_GRID == 0) ? rbx : ((int)(rbx / O_GRID) + 1) * O_GRID;
X DrawHorizOutline (Win, lty, x_start, x_end, ltx, rbx, pixel);
X DrawHorizOutline (Win, rby, x_start, x_end, ltx, rbx, pixel);
X y_start = (lty % O_GRID == 0) ? lty : (int)(lty / O_GRID) * O_GRID;
X y_end = (rby % O_GRID == 0) ? rby : ((int)(rby / O_GRID) + 1) * O_GRID;
X DrawVertOutline (Win, ltx, y_start, y_end, lty, rby, pixel);
X DrawVertOutline (Win, rbx, y_start, y_end, lty, rby, pixel);
X}
X
Xvoid DrawObj (Win, ObjPtr)
X Window Win;
X register struct ObjRec * ObjPtr;
X{
X register struct ObjRec * obj_ptr;
X register struct AttrRec * attr_ptr;
X
X switch (ObjPtr->type)
X {
X case OBJ_POLY:
X DrawPolyObj (Win, drawOrigX, drawOrigY, ObjPtr);
X DrawAttrs(Win, drawOrigX, drawOrigY, ObjPtr->fattr);
X break;
X case OBJ_BOX:
X DrawBoxObj (Win, drawOrigX, drawOrigY, ObjPtr);
X DrawAttrs(Win, drawOrigX, drawOrigY, ObjPtr->fattr);
X break;
X case OBJ_OVAL:
X DrawOvalObj (Win, drawOrigX, drawOrigY, ObjPtr);
X DrawAttrs(Win, drawOrigX, drawOrigY, ObjPtr->fattr);
X break;
X case OBJ_TEXT: DrawTextObj (Win, drawOrigX, drawOrigY, ObjPtr); break;
X case OBJ_POLYGON:
X DrawPolygonObj (Win, drawOrigX, drawOrigY, ObjPtr);
X DrawAttrs(Win, drawOrigX, drawOrigY, ObjPtr->fattr);
X break;
X case OBJ_ARC:
X DrawArcObj (Win, drawOrigX, drawOrigY, ObjPtr);
X DrawAttrs(Win, drawOrigX, drawOrigY, ObjPtr->fattr);
X break;
X case OBJ_RCBOX:
X DrawRCBoxObj (Win, drawOrigX, drawOrigY, ObjPtr);
X DrawAttrs(Win, drawOrigX, drawOrigY, ObjPtr->fattr);
X break;
X case OBJ_XBM:
X DrawXBmObj (Win, drawOrigX, drawOrigY, ObjPtr);
X DrawAttrs(Win, drawOrigX, drawOrigY, ObjPtr->fattr);
X break;
X
X case OBJ_SYM:
X case OBJ_ICON:
X case OBJ_GROUP:
X obj_ptr = ObjPtr->detail.r->last;
X for ( ; obj_ptr != NULL; obj_ptr = obj_ptr->prev)
X if (BBoxIntersect (obj_ptr->bbox, drawWinBBox))
X DrawObj (Win, obj_ptr);
X if (ObjPtr->type == OBJ_ICON && ObjPtr->dirty)
X {
X attr_ptr = ObjPtr->fattr;
X for ( ; attr_ptr != NULL; attr_ptr = attr_ptr->next)
X UpdTextBBox (attr_ptr->obj);
X AdjObjBBox (ObjPtr);
X UpdSelBBox ();
X ObjPtr->dirty = FALSE;
X }
X DrawAttrs(Win, drawOrigX, drawOrigY, ObjPtr->fattr);
X if (ObjPtr->type == OBJ_SYM) DrawSymOutline (Win, drawOrigX, drawOrigY,
X ObjPtr);
X break;
X }
X}
X
Xvoid DrawPaperBoundary ()
X{
X register int x_end, y_end;
X
X if (drawOrigX+drawWinW > paperWidth)
X {
X x_end = OFFSET_X(paperWidth);
X if (drawOrigY+drawWinH > paperHeight)
X {
X y_end = OFFSET_Y(paperHeight);
X XDrawLine (mainDisplay, drawWindow, defaultGC, x_end, 0, x_end, y_end);
X XDrawLine (mainDisplay, drawWindow, defaultGC, 0, y_end, x_end, y_end);
X }
X else
X XDrawLine (mainDisplay, drawWindow, defaultGC, x_end, 0, x_end,
X drawWinH>>zoomScale);
X }
X else if (drawOrigY+drawWinH > paperHeight)
X {
X y_end = OFFSET_Y(paperHeight);
X XDrawLine (mainDisplay, drawWindow, defaultGC, 0, y_end,
X drawWinW>>zoomScale, y_end);
X }
X}
X
Xvoid RedrawAnArea (BotObj, LtX, LtY, RbX, RbY)
X struct ObjRec * BotObj;
X int LtX, LtY, RbX, RbY;
X /* LtX, LtY, RbX, RbY are absolute coordinates */
X{
X register struct ObjRec * obj_ptr;
X struct BBRec bbox;
X XRectangle recs[1];
X
X bbox.ltx = LtX; bbox.lty = LtY;
X bbox.rbx = min(RbX, paperWidth);
X bbox.rby = min(RbY, paperHeight);
X
X SetRecVals (recs[0], OFFSET_X(LtX), OFFSET_Y(LtY), ((RbX-LtX)>>zoomScale)+1,
X ((RbY-LtY)>>zoomScale)+1);
X XSetClipRectangles (mainDisplay, drawGC, 0, 0, recs, 1, YXBanded);
X
X XClearArea (mainDisplay, drawWindow, OFFSET_X(LtX), OFFSET_Y(LtY),
X ((RbX-LtX)>>zoomScale)+1, ((RbY-LtY)>>zoomScale)+1, FALSE);
X
X if (paperWidth >= LtX && paperWidth < RbX ||
X paperHeight >= LtY && paperHeight < RbY)
X DrawPaperBoundary ();
X
X DrawGridLines (drawWindow, LtX, LtY, RbX+(1<<zoomScale), RbY+(1<<zoomScale));
X
X for (obj_ptr = BotObj; obj_ptr != NULL; obj_ptr = obj_ptr->prev)
X if (BBoxIntersect (obj_ptr->bbox, bbox) &&
X BBoxIntersect (obj_ptr->bbox, drawWinBBox))
X DrawObj (drawWindow, obj_ptr);
X
X SetDefaultDrawWinClipRecs ();
X}
X
Xstatic
Xint Inside (BBox1, BBox2)
X struct BBRec BBox1, BBox2;
X{
X return (BBox1.ltx >= BBox2.ltx && BBox1.lty >= BBox2.lty &&
X BBox1.rbx <= BBox2.rbx && BBox1.rby <= BBox2.rby);
X}
X
Xvoid RedrawAreas (BotObj, LtX1, LtY1, RbX1, RbY1, LtX2, LtY2, RbX2, RbY2)
X struct ObjRec * BotObj;
X int LtX1, LtY1, RbX1, RbY1, LtX2, LtY2, RbX2, RbY2;
X /* note: these coordinates are absolute */
X{
X register struct ObjRec * obj_ptr;
X int ltx, lty, rbx, rby, rec1_slot, num;
X struct BBRec bbox1, bbox2;
X XRectangle recs[4];
X
X bbox1.ltx = LtX1; bbox1.lty = LtY1;
X bbox1.rbx = min(RbX1, paperWidth);
X bbox1.rby = min(RbY1, paperHeight);
X bbox2.ltx = LtX2; bbox2.lty = LtY2;
X bbox2.rbx = min(RbX2, paperWidth);
X bbox2.rby = min(RbY2, paperHeight);
X
X if (Inside (bbox1, bbox2))
X {
X RedrawAnArea (BotObj, LtX2, LtY2, RbX2, RbY2);
X return;
X }
X else if (Inside (bbox2, bbox1))
X {
X RedrawAnArea (BotObj, LtX1, LtY1, RbX1, RbY1);
X return;
X }
X
X XClearArea (mainDisplay, drawWindow, OFFSET_X(LtX1), OFFSET_Y(LtY1),
X ((RbX1-LtX1)>>zoomScale)+1, ((RbY1-LtY1)>>zoomScale)+1, FALSE);
X
X if (BBoxIntersect (bbox1, bbox2))
X {
X ltx = min(LtX1,LtX2); lty = min(LtY1,LtY2);
X rbx = max(RbX1,RbX2); rby = max(RbY1,RbY2);
X RedrawAnArea (BotObj, ltx, lty, rbx, rby);
X return;
X }
X
X if (LtY1 == LtY2)
X {
X rec1_slot = (LtX1 <= LtX2) ? 0 : 1;
X SetRecVals (recs[rec1_slot], OFFSET_X(LtX1), OFFSET_Y(LtY1),
X ((RbX1-LtX1)>>zoomScale)+1, ((RbY1-LtY1)>>zoomScale)+1);
X SetRecVals (recs[!rec1_slot], OFFSET_X(LtX2), OFFSET_Y(LtY2),
X ((RbX2-LtX2)>>zoomScale)+1, ((RbY2-LtY2)>>zoomScale)+1);
X num = 2;
X }
X else
X {
X if (LtY1 < LtY2)
X {
X if (RbY1 <= LtY2)
X { /* y-extents do not intersect */
X SetRecVals (recs[0], OFFSET_X(LtX1), OFFSET_Y(LtY1),
X ((RbX1-LtX1)>>zoomScale)+1, ((RbY1-LtY1)>>zoomScale)+1);
X SetRecVals (recs[1], OFFSET_X(LtX2), OFFSET_Y(LtY2),
X ((RbX2-LtX2)>>zoomScale)+1, ((RbY2-LtY2)>>zoomScale)+1);
X num = 2;
X }
X else if (RbY1 >= RbY2)
X { /* box 2's y-extents is inside box 1's y-extents */
X rec1_slot = (LtX1 < LtX2) ? 0 : 1;
X SetRecVals (recs[rec1_slot], OFFSET_X(LtX1), OFFSET_Y(LtY1),
X ((RbX1-LtX1)>>zoomScale)+1, ((RbY1-LtY1)>>zoomScale)+1);
X SetRecVals (recs[!rec1_slot], OFFSET_X(LtX2), OFFSET_Y(LtY2),
X ((RbX2-LtX2)>>zoomScale)+1, ((RbY2-LtY2)>>zoomScale)+1);
X num = 2;
X }
X else
X {
X SetRecVals (recs[0], OFFSET_X(LtX1), OFFSET_Y(LtY1),
X ((RbX1-LtX1)>>zoomScale)+1, ((LtY2-LtY1)>>zoomScale)+1);
X if (LtX1 < LtX2)
X {
X SetRecVals (recs[1], OFFSET_X(LtX1), OFFSET_Y(LtY2),
X ((RbX1-LtX1)>>zoomScale)+1, ((RbY1-LtY2)>>zoomScale)+1);
X SetRecVals (recs[2], OFFSET_X(LtX2), OFFSET_Y(LtY2),
X ((RbX2-LtX2)>>zoomScale)+1, ((RbY1-LtY2)>>zoomScale)+1);
X }
X else
X {
X SetRecVals (recs[1], OFFSET_X(LtX2), OFFSET_Y(LtY2),
X ((RbX2-LtX2)>>zoomScale)+1, ((RbY1-LtY2)>>zoomScale)+1);
X SetRecVals (recs[2], OFFSET_X(LtX1), OFFSET_Y(LtY2),
X ((RbX1-LtX1)>>zoomScale)+1, ((RbY1-LtY2)>>zoomScale)+1);
X }
X SetRecVals (recs[3], OFFSET_X(LtX2), OFFSET_Y(RbY1),
X ((RbX2-LtX2)>>zoomScale)+1, ((RbY2-RbY1)>>zoomScale)+1);
X num = 4;
X }
X }
X else
X {
X if (RbY2 <= LtY1)
X { /* y-extents do not intersect */
X SetRecVals (recs[0], OFFSET_X(LtX2), OFFSET_Y(LtY2),
X ((RbX2-LtX2)>>zoomScale)+1, ((RbY2-LtY2)>>zoomScale)+1);
X SetRecVals (recs[1], OFFSET_X(LtX1), OFFSET_Y(LtY1),
X ((RbX1-LtX1)>>zoomScale)+1, ((RbY1-LtY1)>>zoomScale)+1);
X num = 2;
X }
X else if (RbY2 >= RbY1)
X { /* box 1's y-extents is inside box 2's y-extents */
X rec1_slot = (LtX1 < LtX2) ? 0 : 1;
X SetRecVals (recs[rec1_slot], OFFSET_X(LtX1), OFFSET_Y(LtY1),
X ((RbX1-LtX1)>>zoomScale)+1, ((RbY1-LtY1)>>zoomScale)+1);
X SetRecVals (recs[!rec1_slot], OFFSET_X(LtX2), OFFSET_Y(LtY2),
X ((RbX2-LtX2)>>zoomScale)+1, ((RbY2-LtY2)>>zoomScale)+1);
X num = 2;
X }
X else
X {
X SetRecVals (recs[0], OFFSET_X(LtX2), OFFSET_Y(LtY2),
X ((RbX2-LtX2)>>zoomScale)+1, ((LtY1-LtY2)>>zoomScale)+1);
X if (LtX1 < LtX2)
X {
X SetRecVals (recs[1], OFFSET_X(LtX1), OFFSET_Y(LtY1),
X ((RbX1-LtX1)>>zoomScale)+1, ((RbY2-LtY1)>>zoomScale)+1);
X SetRecVals (recs[2], OFFSET_X(LtX2), OFFSET_Y(LtY1),
X ((RbX2-LtX2)>>zoomScale)+1, ((RbY2-LtY1)>>zoomScale)+1);
X }
X else
X {
X SetRecVals (recs[1], OFFSET_X(LtX2), OFFSET_Y(LtY1),
X ((RbX2-LtX2)>>zoomScale)+1, ((RbY2-LtY1)>>zoomScale)+1);
X SetRecVals (recs[2], OFFSET_X(LtX1), OFFSET_Y(LtY1),
X ((RbX1-LtX1)>>zoomScale)+1, ((RbY2-LtY1)>>zoomScale)+1);
X }
X SetRecVals (recs[3], OFFSET_X(LtX1), OFFSET_Y(RbY2),
X ((RbX1-LtX1)>>zoomScale)+1, ((RbY1-RbY2)>>zoomScale)+1);
X num = 4;
X }
X }
X }
X XSetClipRectangles (mainDisplay, drawGC, 0, 0, recs, num, YXSorted);
X
X if (paperWidth >= LtX1 && paperWidth < RbX1 ||
X paperHeight >= LtY1 && paperHeight < RbY1 ||
X paperWidth >= LtX2 && paperWidth < RbX2 ||
X paperHeight >= LtY2 && paperHeight < RbY2)
X DrawPaperBoundary ();
X
X DrawGridLines (drawWindow, LtX1, LtY1, RbX1+(1<<zoomScale),
X RbY1+(1<<zoomScale));
X DrawGridLines (drawWindow, LtX2, LtY2, RbX2+(1<<zoomScale),
X RbY2+(1<<zoomScale));
X
X for (obj_ptr = BotObj; obj_ptr != NULL; obj_ptr = obj_ptr->prev)
X {
X if (BBoxIntersect (obj_ptr->bbox, drawWinBBox) &&
X (BBoxIntersect (obj_ptr->bbox, bbox1) ||
X BBoxIntersect (obj_ptr->bbox, bbox2)))
X DrawObj (drawWindow, obj_ptr);
X }
X
X SetDefaultDrawWinClipRecs ();
X}
X
XPixmap DrawAllOnPixmap (LtX, LtY, W, H)
X int *LtX, *LtY, *W, *H;
X{
X register int i;
X register struct ObjRec * obj_ptr;
X int len, ltx, lty, rbx, rby, w, h;
X int saved_draw_orig_x, saved_draw_orig_y;
X int saved_draw_win_w, saved_draw_win_h;
X int saved_zoom_scale;
X char msg[MAXSTRING];
X Pixmap pixmap;
X XGCValues values;
X
X ltx = botObj->bbox.ltx; lty = botObj->bbox.lty;
X rbx = botObj->bbox.rbx; rby = botObj->bbox.rby;
X for (obj_ptr = botObj->prev; obj_ptr != NULL; obj_ptr = obj_ptr->prev)
X {
X if (obj_ptr->bbox.ltx < ltx) ltx = obj_ptr->bbox.ltx;
X if (obj_ptr->bbox.lty < lty) lty = obj_ptr->bbox.lty;
X if (obj_ptr->bbox.rbx > rbx) rbx = obj_ptr->bbox.rbx;
X if (obj_ptr->bbox.rby > rby) rby = obj_ptr->bbox.rby;
X }
X *W = w = rbx - ltx;
X *H = h = rby - lty;
X *LtX = ltx;
X *LtY = lty;
X
X saved_draw_orig_x = drawOrigX; saved_draw_orig_y = drawOrigY;
X saved_draw_win_w = drawWinW; saved_draw_win_h = drawWinH;
X saved_zoom_scale = zoomScale;
X
X drawOrigX = ltx; drawOrigY = lty;
X drawWinW = w; drawWinH = h;
X zoomScale = 0;
X
X pixmap = XCreatePixmap (mainDisplay, mainWindow, w, h, mainDepth);
X
X if (pixmap == None)
X {
X sprintf (msg, "Can not allocate pixmap of size %1dx%1d.", w, h);
X Msg (msg);
X return (None);
X }
X
X values.foreground = myBgPixel;
X values.function = GXcopy;
X values.fill_style = FillSolid;
X XChangeGC (mainDisplay, drawGC,
X GCForeground | GCFunction | GCFillStyle, &values);
X XFillRectangle (mainDisplay, pixmap, drawGC, 0, 0, w, h);
X
X AdjSplineVs ();
X
X for (obj_ptr = botObj; obj_ptr != NULL; obj_ptr = obj_ptr->prev)
X DrawObj (pixmap, obj_ptr);
X
X drawOrigX = saved_draw_orig_x; drawOrigY = saved_draw_orig_y;
X drawWinW = saved_draw_win_w; drawWinH = saved_draw_win_h;
X zoomScale = saved_zoom_scale;
X
X AdjSplineVs ();
X
X return (pixmap);
X}
X
Xvoid RedrawDrawWindow (BotObj)
X struct ObjRec * BotObj;
X{
X register struct ObjRec * obj_ptr;
X
X DrawPaperBoundary ();
X RedrawGridLines ();
X
X for (obj_ptr = BotObj; obj_ptr != NULL; obj_ptr = obj_ptr->prev)
X if (PointInBBox (obj_ptr->x, obj_ptr->y, drawWinBBox) ||
X BBoxIntersect (obj_ptr->bbox, drawWinBBox))
X DrawObj (drawWindow, obj_ptr);
X}
X
Xvoid ClearAndRedrawDrawWindow ()
X{
X XClearWindow (mainDisplay, drawWindow);
X RedrawDrawWindow (botObj);
X RedrawCurText ();
X HighLightForward ();
X}
X
Xvoid CleanUpDrawingWindow ()
X{
X HighLightReverse ();
X RemoveAllSel ();
X DelAllObj ();
X ClearCurText ();
X SetCurChoice (NOTHING);
X}
X
Xint ShortHand (input)
X XEvent * input;
X /* returns BAD if the character is a <CONTROL> or a <META> character */
X /* returns INVALID if the character is a normal character */
X /* otherwise, returns the value of sub-functions, such as QuitProc () */
X{
X int x, y;
X char buf[80];
X KeySym key_sym;
X XComposeStatus c_stat;
X XKeyEvent * key_ev;
X
X key_ev = &(input->xkey);
X XLookupString (key_ev, buf, 80, &key_sym, &c_stat);
X if ((key_sym>='\040' && key_sym<='\177' ||
X key_sym>='\240' && key_sym<='\377') &&
X (key_ev->state & (ControlMask | Mod1Mask)))
X {
X Msg ("");
X if ((key_ev->state & ControlMask) && (!(key_ev->state & Mod1Mask)))
X {
X switch (buf[0])
X {
X case '\001': /*^A*/ SelAllObj (); break;
X case '\002': /*^B*/ BackProc (); break;
X case '\003': /*^C*/ ChangeDomain (); break;
X case '\004': /*^D*/ DupSelObj (); break;
X case '\005': /*^E*/ break;
X case '\006': /*^F*/ FrontProc (); break;
X case '\007': /*^G*/ GroupSelObj (); break;
X case '\010': /*^H*/ return (INVALID);
X case '\011': /*^I*/ Instantiate (); break;
X case '\012': /*^J*/ return (INVALID);
X case '\013': /*^K*/ PopIcon (); break;
X case '\014': /*^L*/ AlignSelObjs (); break;
X case '\015': /*^M*/ return (INVALID);
X case '\016': /*^N*/ NewProc (); break;
X case '\017': /*^O*/ OpenProc (); break;
X case '\020': /*^P*/ Dump (FALSE, ""); break;
X case '\021': /*^Q*/ return (QuitProc ());
X case '\022': /*^R*/ ClearAndRedrawDrawWindow (); break;
X case '\023': /*^S*/ SaveFile (); break;
X case '\024': /*^T*/ AlignSelToGrid (); break;
X case '\025': /*^U*/ UngroupSelObj (); break;
X case '\026': /*^V*/ PushIcon (); break;
X case '\027': /*^W*/ SetCurChoice (DRAWTEXT); break;
X case '\030': /*^X*/ DelAllSelObj (); break;
X case '\031': /*^Y*/ CopyToCutBuffer (); break;
X case '\032': /*^Z*/ return (AnimateProc ());
X case ',': /*^,*/ ScrollLeft (); break;
X case '.': /*^.*/ ScrollRight (); break;
X case '-': /*^-*/ PrintWithCommand (FALSE, ""); break;
X }
X }
X else if ((key_ev->state & Mod1Mask) && (!(key_ev->state & ControlMask)))
X {
X switch (buf[0])
X {
X case 'a': /*#A*/ AddAttrs (); break;
X case 'b': /*#B*/ return (ProbeProc ());
X case 'c': /*#C*/ RotateCounter (); break;
X case 'd': /*#D*/ DecGrid (); break;
X case 'e': /*#E*/ AnimateSel (); break;
X case 'f': /*#F*/ FlashSelColor (); break;
X case 'g': /*#G*/ ToggleGridShown (); break;
X case 'h': /*#H*/ FlipHorizontal (); break;
X case 'i': /*#I*/ IncGrid (); break;
X case 'j': /*#J*/ HideAllAttrNames (); break;
X case 'k': /*#K*/ SetCurChoice (NOTHING); break;
X case 'l': /*#L*/ CornerLoop (&x, &y); LineStyleMenu (x, y); break;
X case 'm': /*#M*/ MoveAttr (); break;
X case 'n': /*#N*/ ShowAllAttrNames (); break;
X case 'o': /*#O*/ ZoomOut (); break;
X case 'p': /*#P*/ ImportFile (); break;
X case 'q': /*#Q*/ SetCurChoice (DRAWPOLY); break;
X case 'r': /*#R*/ SetCurChoice (DRAWBOX); break;
X case 's': /*#S*/ return (SolveProc ());
X case 't': /*#T*/ DetachAttrs (); break;
X case 'u': /*#U*/ UndoDelete (); break;
X case 'v': /*#V*/ FlipVertical (); break;
X case 'w': /*#W*/ RotateClockWise (); break;
X case 'x': /*#X*/ return (EscapeProc ());
X case 'y': /*#Y*/ return (SimulateProc ());
X case 'z': /*#Z*/ ZoomIn (); break;
X case '0': /*#0*/ ChangeFontSize (0); break;
X case '1': /*#1*/ ChangeFontSize (1); break;
X case '2': /*#2*/ ChangeFontSize (2); break;
X case '3': /*#3*/ ChangeFontSize (3); break;
X case '4': /*#4*/ ChangeFontSize (4); break;
X case '5': /*#5*/ ChangeFontSize (5); break;
X case ',': /*#,*/ ScrollUp (); break;
X case '.': /*#.*/ ScrollDown (); break;
X }
X }
X else if ((key_ev->state & Mod1Mask) && (key_ev->state & ControlMask))
X {
X switch (buf[0])
X {
X case '\001': /*^#A*/ AddPoint (); break;
X case '\002': /*^#B*/ ChangeFontStyle (STYLE_BR); break;
X case '\003': /*^#C*/ ChangeFontJust (JUST_C); break;
X case '\004': /*^#D*/ DeletePoint (); break;
X case '\005': /*^#E*/ SetCurChoice (DRAWRCBOX); break;
X case '\006': /*^#F*/ InvertXBitmaps (); break;
X case '\007': /*^#G*/ ToggleSnapOn (); break;
X case '\010': /*^#H*/ break;
X case '\011': /*^#I*/ MakeIconic (); break;
X case '\012': /*^#J*/ UnMakeIconic (); break;
X case '\013': /*^#K*/ ToggleColorPostScript (); break;
X case '\014': /*^#L*/ ChangeFontJust (JUST_L); break;
X case '\015': /*^#M*/ MakeSymbolic (); break;
X case '\016': /*^#N*/ UnMakeSymbolic (); break;
X case '\017': /*^#O*/ ChangeFontStyle (STYLE_NR); break;
X case '\020': /*^#P*/ ChangeFontStyle (STYLE_BI); break;
X case '\021': /*^#Q*/ SetCurChoice (DRAWPOLYGON); break;
X case '\022': /*^#R*/ ChangeFontJust (JUST_R); break;
X case '\023': /*^#S*/ SaveNewFile (); break;
X case '\024': /*^#T*/ ChangeFontStyle (STYLE_NI); break;
X case '\025': /*^#U*/ UpdateSymbols (); break;
X case '\026': /*^#V*/ SetCurChoice (DRAWCIRCLE); break;
X case '\027': /*^#W*/ ToggleAllSelLineType (); break;
X case '\030': /*^#X*/ ToggleWhereToPrint (); break;
X case '\031': /*^#Y*/ PasteFromCutBuffer (); break;
X case '\032': /*^#Z*/ SetCurChoice (DRAWARC); break;
X case '.': /*^#.*/ ImportXBitmapFile (); break;
X }
X }
X return (BAD);
X }
X return (INVALID);
X}
X
Xstatic
Xint SomethingDirty ()
X{
X register struct ObjRec * obj_ptr = topObj;
X
X for ( ; obj_ptr != NULL; obj_ptr = obj_ptr->next)
X if (obj_ptr->dirty)
X return (TRUE);
X return (FALSE);
X}
X
Xint DrawingEventHandler (input)
X XEvent * input;
X{
X int mouse_x, mouse_y, grid_x, grid_y;
X XEvent ev;
X XButtonEvent * button_ev;
X
X if (input->type == Expose)
X {
X XSync (mainDisplay, FALSE);
X while (XCheckWindowEvent (mainDisplay, drawWindow, ExposureMask, &ev)) ;
X
X if (topSel != NULL || SomethingDirty ())
X ClearAndRedrawDrawWindow ();
X else
X {
X RedrawDrawWindow (botObj);
X RedrawCurText ();
X }
X return (INVALID);
X }
X else if (input->type == MotionNotify)
X {
X while (XCheckWindowEvent (mainDisplay,drawWindow,PointerMotionMask,&ev)) ;
X
X mouse_x = (input->xmotion).x;
X mouse_y = (input->xmotion).y;
X GridXY (mouse_x, mouse_y, &grid_x, &grid_y);
X MarkRulers (grid_x, grid_y);
X return (INVALID);
X }
X
X if (input->type == ButtonPress)
X {
X button_ev = &(input->xbutton);
X if ((button_ev->button == Button3) && (button_ev->state & ShiftMask))
X {
X SetCurChoice (NOTHING);
X return (INVALID);
X }
X else if (button_ev->button == Button3)
X return (MainMenu (button_ev));
X }
X
X Msg ("");
X switch(curChoice)
X {
X case NOTHING: Select (input); break;
X case DRAWTEXT: DrawText (input); break;
X case DRAWBOX: DrawBox (input); break;
X case DRAWCIRCLE: DrawOval (input); break;
X case DRAWPOLY: DrawPoly (input); break;
X case DRAWPOLYGON: DrawPolygon (input); break;
X case DRAWARC: DrawArc (input); break;
X case DRAWRCBOX: DrawRCBox (input); break;
X }
X return (INVALID);
X}
END_OF_FILE
if test 24657 -ne `wc -c <'drawing.c'`; then
echo shar: \"'drawing.c'\" unpacked with wrong size!
fi
# end of 'drawing.c'
fi
if test -f 'dup.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'dup.c'\"
else
echo shar: Extracting \"'dup.c'\" \(11685 characters\)
sed "s/^X//" >'dup.c' <<'END_OF_FILE'
X/*
X * Author: William Chia-Wei Cheng (william at cs.ucla.edu)
X *
X * Copyright (C) 1990, 1991, William Cheng.
X */
X#ifndef lint
Xstatic char RCSid[] =
X "@(#)$Header: /tmp_mnt/n/kona/tangram/u/william/X11/TGIF2/RCS/dup.c,v 2.0 91/03/05 12:47:04 william Exp $";
X#endif
X
X#include <X11/Xlib.h>
X#include "const.h"
X#include "types.h"
X
X#include "attr.e"
X#include "drawing.e"
X#include "grid.e"
X#include "obj.e"
X#include "raster.e"
X#include "select.e"
X#include "setup.e"
X#include "xbitmap.e"
X
Xextern struct ObjRec * DupObj ();
X
Xint justDupped = FALSE;
Xint dupDx = INVALID, dupDy = INVALID;
X
Xvoid DupObjBasics (FromObjPtr, ToObjPtr)
X register struct ObjRec * FromObjPtr, * ToObjPtr;
X{
X ToObjPtr->x = FromObjPtr->x;
X ToObjPtr->y = FromObjPtr->y;
X ToObjPtr->color = FromObjPtr->color;
X ToObjPtr->id = objId++;
X ToObjPtr->dirty = FALSE;
X ToObjPtr->type = FromObjPtr->type;
X ToObjPtr->bbox.ltx = FromObjPtr->bbox.ltx;
X ToObjPtr->bbox.lty = FromObjPtr->bbox.lty;
X ToObjPtr->bbox.rbx = FromObjPtr->bbox.rbx;
X ToObjPtr->bbox.rby = FromObjPtr->bbox.rby;
X ToObjPtr->obbox.ltx = FromObjPtr->obbox.ltx;
X ToObjPtr->obbox.lty = FromObjPtr->obbox.lty;
X ToObjPtr->obbox.rbx = FromObjPtr->obbox.rbx;
X ToObjPtr->obbox.rby = FromObjPtr->obbox.rby;
X}
X
Xstatic
Xvoid DupPolyObj (PolyPtr, ObjPtr)
X struct PolyRec * PolyPtr;
X struct ObjRec * ObjPtr;
X{
X register int i, num_pts;
X register struct PolyRec * poly_ptr;
X register XPoint * v;
X
X poly_ptr = (struct PolyRec *) calloc (1, sizeof(struct PolyRec));
X num_pts = poly_ptr->n = PolyPtr->n;
X v = (XPoint *) calloc (num_pts+1, sizeof(XPoint));
X for (i = 0; i < num_pts; i++)
X {
X v[i].x = PolyPtr->vlist[i].x;
X v[i].y = PolyPtr->vlist[i].y;
X }
X poly_ptr->vlist = v;
X poly_ptr->style = PolyPtr->style;
X poly_ptr->width = PolyPtr->width;
X poly_ptr->pen = PolyPtr->pen;
X poly_ptr->fill = PolyPtr->fill;
X if ((poly_ptr->curved = PolyPtr->curved) == LT_SPLINE)
X {
X poly_ptr->sn = num_pts = PolyPtr->sn;
X v = (XPoint *) calloc (num_pts+1, sizeof(XPoint));
X for (i = 0; i < num_pts; i++)
X {
X v[i].x = PolyPtr->svlist[i].x;
X v[i].y = PolyPtr->svlist[i].y;
X }
X poly_ptr->svlist = v;
X }
X poly_ptr->dash = PolyPtr->dash;
X
X ObjPtr->detail.p = poly_ptr;
X}
X
Xstatic
Xvoid DupPolygonObj (PolygonPtr, ObjPtr)
X struct PolygonRec * PolygonPtr;
X struct ObjRec * ObjPtr;
X{
X register int i, num_pts;
X register struct PolygonRec * polygon_ptr;
X XPoint * v;
X
X polygon_ptr = (struct PolygonRec *) calloc (1, sizeof(struct PolygonRec));
X num_pts = polygon_ptr->n = PolygonPtr->n;
X v = (XPoint *) calloc (num_pts+1, sizeof(XPoint));
X for (i = 0; i < num_pts; i++)
X {
X v[i].x = PolygonPtr->vlist[i].x;
X v[i].y = PolygonPtr->vlist[i].y;
X }
X polygon_ptr->vlist = v;
X polygon_ptr->fill = PolygonPtr->fill;
X polygon_ptr->width = PolygonPtr->width;
X polygon_ptr->pen = PolygonPtr->pen;
X if ((polygon_ptr->curved = PolygonPtr->curved) == LT_SPLINE)
X {
X polygon_ptr->sn = num_pts = PolygonPtr->sn;
X v = (XPoint *) calloc (num_pts, sizeof(XPoint));
X for (i = 0; i < num_pts; i++)
X {
X v[i].x = PolygonPtr->svlist[i].x;
X v[i].y = PolygonPtr->svlist[i].y;
X }
X polygon_ptr->svlist = v;
X }
X polygon_ptr->dash = PolygonPtr->dash;
X
X ObjPtr->detail.g = polygon_ptr;
X}
X
Xstatic
Xvoid DupOvalObj (OvalPtr, ObjPtr)
X struct OvalRec * OvalPtr;
X struct ObjRec * ObjPtr;
X{
X register struct OvalRec * oval_ptr;
X
X oval_ptr = (struct OvalRec *) calloc (1, sizeof(struct OvalRec));
X oval_ptr->fill = OvalPtr->fill;
X oval_ptr->width = OvalPtr->width;
X oval_ptr->pen = OvalPtr->pen;
X oval_ptr->dash = OvalPtr->dash;
X
X ObjPtr->detail.o = oval_ptr;
X}
X
Xstatic
Xvoid DupBoxObj (BoxPtr, ObjPtr)
X struct BoxRec * BoxPtr;
X struct ObjRec * ObjPtr;
X{
X register struct BoxRec * box_ptr;
X
X box_ptr = (struct BoxRec *) calloc (1, sizeof(struct BoxRec));
X box_ptr->fill = BoxPtr->fill;
X box_ptr->width = BoxPtr->width;
X box_ptr->pen = BoxPtr->pen;
X box_ptr->dash = BoxPtr->dash;
X
X ObjPtr->detail.b = box_ptr;
X}
X
Xstatic
Xvoid DupRCBoxObj (RCBoxPtr, ObjPtr)
X struct RCBoxRec * RCBoxPtr;
X struct ObjRec * ObjPtr;
X{
X register struct RCBoxRec * rcbox_ptr;
X
X rcbox_ptr = (struct RCBoxRec *) calloc (1, sizeof(struct RCBoxRec));
X rcbox_ptr->fill = RCBoxPtr->fill;
X rcbox_ptr->width = RCBoxPtr->width;
X rcbox_ptr->pen = RCBoxPtr->pen;
X rcbox_ptr->dash = RCBoxPtr->dash;
X rcbox_ptr->radius = RCBoxPtr->radius;
X
X ObjPtr->detail.rcb = rcbox_ptr;
X}
X
Xstatic
Xvoid DupArcObj (ArcPtr, ObjPtr)
X struct ArcRec * ArcPtr;
X struct ObjRec * ObjPtr;
X{
X register struct ArcRec * arc_ptr;
X
X arc_ptr = (struct ArcRec *) calloc (1, sizeof(struct ArcRec));
X arc_ptr->fill = ArcPtr->fill;
X arc_ptr->width = ArcPtr->width;
X arc_ptr->pen = ArcPtr->pen;
X arc_ptr->dash = ArcPtr->dash;
X
X arc_ptr->xc = ArcPtr->xc; arc_ptr->yc = ArcPtr->yc;
X arc_ptr->x1 = ArcPtr->x1; arc_ptr->y1 = ArcPtr->y1;
X arc_ptr->x2 = ArcPtr->x2; arc_ptr->y2 = ArcPtr->y2;
X arc_ptr->dir = ArcPtr->dir;
X arc_ptr->ltx = ArcPtr->ltx; arc_ptr->lty = ArcPtr->lty;
X arc_ptr->w = ArcPtr->w; arc_ptr->h = ArcPtr->h;
X arc_ptr->angle1 = ArcPtr->angle1; arc_ptr->angle2 = ArcPtr->angle2;
X
X ObjPtr->detail.a = arc_ptr;
X}
X
Xstatic
Xvoid DupXBmObj (XBmPtr, ObjPtr)
X struct XBmRec * XBmPtr;
X struct ObjRec * ObjPtr;
X{
X register struct XBmRec * xbm_ptr;
X Pixmap bitmap;
X int w, h;
X
X w = ObjPtr->obbox.rbx - ObjPtr->obbox.ltx;
X h = ObjPtr->obbox.rby - ObjPtr->obbox.lty;
X
X bitmap = XCreatePixmap (mainDisplay, mainWindow, w, h, 1);
X XCopyArea (mainDisplay, XBmPtr->bitmap, bitmap, xbmGC, 0, 0, w, h, 0, 0);
X
X xbm_ptr = (struct XBmRec *) calloc (1, sizeof(struct XBmRec));
X xbm_ptr->bitmap = bitmap;
X xbm_ptr->data = NULL;
X xbm_ptr->fill = XBmPtr->fill;
X ObjPtr->detail.xbm = xbm_ptr;
X}
X
Xvoid DupTextObj (TextPtr, ObjPtr)
X struct TextRec * TextPtr;
X struct ObjRec * ObjPtr;
X{
X register int i, num_lines;
X register struct TextRec * text_ptr;
X struct StrRec * first_str;
X struct StrRec * from_str_ptr, * to_str_ptr;
X
X text_ptr = (struct TextRec *) calloc (1, sizeof(struct TextRec));
X text_ptr->just = TextPtr->just;
X num_lines = text_ptr->lines = TextPtr->lines;
X from_str_ptr = TextPtr->last;
X first_str = NULL;
X for (i = 0; i < num_lines; i++, from_str_ptr = from_str_ptr->prev)
X {
X to_str_ptr = (struct StrRec *) calloc (1, sizeof(struct StrRec));
X strcpy (to_str_ptr->s, from_str_ptr->s);
X to_str_ptr->next = first_str;
X if (first_str == NULL)
X text_ptr->last = to_str_ptr;
X else
X first_str->prev = to_str_ptr;
X first_str = to_str_ptr;
X }
X first_str->prev = NULL;
X text_ptr->first = first_str;
X
X text_ptr->font = TextPtr->font;
X text_ptr->dpi = TextPtr->dpi;
X text_ptr->style = TextPtr->style;
X text_ptr->size = TextPtr->size;
X text_ptr->rotate = TextPtr->rotate;
X text_ptr->pen = TextPtr->pen;
X text_ptr->asc = TextPtr->asc;
X text_ptr->des = TextPtr->des;
X
X ObjPtr->detail.t = text_ptr;
X}
X
Xstatic
Xvoid DupGroupObj (GroupPtr, ObjPtr)
X struct GroupRec * GroupPtr;
X struct ObjRec * ObjPtr;
X{
X register struct GroupRec * group_ptr;
X struct ObjRec * top_obj, * bot_obj;
X struct ObjRec * from_obj_ptr, * to_obj_ptr;
X
X group_ptr = (struct GroupRec *) calloc (1, sizeof(struct GroupRec));
X top_obj = bot_obj = NULL;
X from_obj_ptr = GroupPtr->last;
X for ( ; from_obj_ptr != NULL; from_obj_ptr = from_obj_ptr->prev)
X {
X to_obj_ptr = DupObj (from_obj_ptr);
X to_obj_ptr->next = top_obj;
X if (top_obj == NULL)
X group_ptr->last = to_obj_ptr;
X else
X top_obj->prev = to_obj_ptr;
X top_obj = to_obj_ptr;
X }
X top_obj->prev = NULL;
X group_ptr->first = top_obj;
X
X ObjPtr->detail.r = group_ptr;
X}
X
Xstruct ObjRec * DupObj (ObjPtr)
X struct ObjRec * ObjPtr;
X{
X struct ObjRec * obj_ptr;
X
X obj_ptr = (struct ObjRec *) calloc (1, sizeof(struct ObjRec));
X DupObjBasics (ObjPtr, obj_ptr);
X
X switch (ObjPtr->type)
X {
X case OBJ_POLY:
X DupPolyObj (ObjPtr->detail.p, obj_ptr);
X DupAttrs (ObjPtr, obj_ptr);
X break;
X case OBJ_BOX:
X DupBoxObj (ObjPtr->detail.b, obj_ptr);
X DupAttrs (ObjPtr, obj_ptr);
X break;
X case OBJ_OVAL:
X DupOvalObj (ObjPtr->detail.o, obj_ptr);
X DupAttrs (ObjPtr, obj_ptr);
X break;
X case OBJ_TEXT: DupTextObj (ObjPtr->detail.t, obj_ptr); break;
X case OBJ_POLYGON:
X DupPolygonObj (ObjPtr->detail.g, obj_ptr);
X DupAttrs (ObjPtr, obj_ptr);
X break;
X case OBJ_ARC:
X DupArcObj (ObjPtr->detail.a, obj_ptr);
X DupAttrs (ObjPtr, obj_ptr);
X break;
X case OBJ_RCBOX:
X DupRCBoxObj (ObjPtr->detail.rcb, obj_ptr);
X DupAttrs (ObjPtr, obj_ptr);
X break;
X case OBJ_XBM:
X DupXBmObj (ObjPtr->detail.xbm, obj_ptr);
X DupAttrs (ObjPtr, obj_ptr);
X break;
X case OBJ_SYM:
X case OBJ_GROUP:
X case OBJ_ICON:
X DupGroupObj (ObjPtr->detail.r, obj_ptr);
X DupAttrs (ObjPtr, obj_ptr);
X if (obj_ptr->type == OBJ_ICON)
X strcpy (obj_ptr->detail.r->s, ObjPtr->detail.r->s);
X break;
X }
X return (obj_ptr);
X}
X
Xvoid DupSelObj ()
X{
X struct SelRec * sel_ptr, * sel_ptr1;
X struct ObjRec * obj_ptr, * top_obj, * bot_obj;
X int dx, dy;
X
X if (topSel == NULL) return;
X
X top_obj = bot_obj = NULL;
X for (sel_ptr = botSel; sel_ptr != NULL; sel_ptr = sel_ptr->prev)
X {
X obj_ptr = DupObj (sel_ptr->obj);
X obj_ptr->next = top_obj;
X if (top_obj == NULL)
X bot_obj = obj_ptr;
X else
X top_obj->prev = obj_ptr;
X top_obj = obj_ptr;
X }
X top_obj->prev = NULL;
X
X HighLightReverse ();
X
X sel_ptr = botSel;
X sel_ptr1 = sel_ptr->prev;
X for (obj_ptr = bot_obj; sel_ptr1 != NULL; obj_ptr = obj_ptr->prev)
X {
X sel_ptr->obj = obj_ptr;
X sel_ptr = sel_ptr1;
X sel_ptr1 = sel_ptr1->prev;
X }
X sel_ptr->obj = obj_ptr;
X
X bot_obj->next = topObj;
X topObj->prev = bot_obj;
X topObj = top_obj;
X
X if (justDupped)
X {
X dx = dupDx;
X dy = dupDy;
X }
X else
X {
X if (gridOn)
X dupDx = dupDy = dx = dy = xyGrid << zoomScale;
X else
X dupDx = dupDy = dx = dy = DEFAULT_GRID << zoomScale;
X justDupped = TRUE;
X }
X
X selLtX += dx; selLtY += dy; selRbX += dx; selRbY += dy;
X selObjLtX += dx; selObjLtY += dy; selObjRbX += dx; selObjRbY += dy;
X
X MoveAllSel (dx, dy);
X RedrawAnArea (botObj, selLtX-(1<<zoomScale), selLtY-(1<<zoomScale),
X selRbX+(1<<zoomScale), selRbY+(1<<zoomScale));
X HighLightForward ();
X SetFileModified (TRUE);
X}
X
Xvoid JustDupSelObj (NewTopSel, NewBotSel)
X struct SelRec * * NewTopSel, * * NewBotSel;
X{
X struct SelRec * sel_ptr, * new_sel_ptr;
X struct ObjRec * obj_ptr, * top_obj, * bot_obj;
X
X *NewTopSel = *NewBotSel = NULL;
X if (topSel == NULL) return;
X
X top_obj = bot_obj = NULL;
X for (sel_ptr = botSel; sel_ptr != NULL; sel_ptr = sel_ptr->prev)
X {
X obj_ptr = DupObj (sel_ptr->obj);
X obj_ptr->next = top_obj;
X new_sel_ptr = (struct SelRec *) calloc (1, sizeof (struct SelRec));
X new_sel_ptr->next = *NewTopSel;
X new_sel_ptr->obj = obj_ptr;
X if (top_obj == NULL)
X {
X bot_obj = obj_ptr;
X *NewBotSel = new_sel_ptr;
X }
X else
X {
X top_obj->prev = obj_ptr;
X (*NewTopSel)->prev = new_sel_ptr;
X }
X top_obj = obj_ptr;
X *NewTopSel = new_sel_ptr;
X }
X top_obj->prev = NULL;
X (*NewTopSel)->prev = NULL;
X}
END_OF_FILE
if test 11685 -ne `wc -c <'dup.c'`; then
echo shar: \"'dup.c'\" unpacked with wrong size!
fi
# end of 'dup.c'
fi
if test -f 'edit.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'edit.c'\"
else
echo shar: Extracting \"'edit.c'\" \(29266 characters\)
sed "s/^X//" >'edit.c' <<'END_OF_FILE'
X/*
X * Author: William Chia-Wei Cheng (william at cs.ucla.edu)
X *
X * Copyright (C) 1990, 1991, William Cheng.
X */
X#ifndef lint
Xstatic char RCSid[] =
X "@(#)$Header: /tmp_mnt/n/kona/tangram/u/william/X11/TGIF2/RCS/edit.c,v 2.0 91/03/05 12:47:06 william Exp $";
X#endif
X
X#include <stdio.h>
X#include <math.h>
X#include <X11/Xlib.h>
X#include "const.h"
X#include "types.h"
X
X#include "align.e"
X#include "color.e"
X#include "copypaste.e"
X#include "cursor.e"
X#include "drawing.e"
X#include "dup.e"
X#include "font.e"
X#include "group.e"
X#include "mark.e"
X#include "obj.e"
X#include "poly.e"
X#include "raster.e"
X#include "select.e"
X#include "setup.e"
X#include "special.e"
X#include "spline.e"
X#include "stretch.e"
X#include "xbitmap.e"
X
X#ifndef M_PI
X#define M_PI 3.14159265358979323846
X#endif
X
X#define MARK(X,Y) \
X XFillRectangle(mainDisplay,drawWindow,revDefaultGC,(X)-2,(Y)-2,5,5)
X#define MyDashedLine(W,GC,V,N) XDrawLines (mainDisplay, W, GC, V, N, \
X CoordModeOrigin)
X
X#define EDIT_REDRAW 0
X#define EDIT_DUP 1
X#define EDIT_DELETE 2
X#define EDIT_SELALL 3
X#define EDIT_UNDODEL 4
X#define EDIT_DEL_POINT 5
X#define EDIT_ADD_POINT 6
X#define EDIT_COPY 7
X#define EDIT_PASTE 8
X#define EDIT_INV_XBM 9
X
X#define MAXEDITMENUS 10
X
Xstatic char * editMenuStr[] =
X { "Redraw ^R",
X "Duplicate ^D",
X "Delete ^X",
X "SelectAll ^A",
X "UndoDelete #U",
X "DeletePoint ^#D",
X "AddPoint ^#A",
X "Copy ^Y",
X "Paste ^#Y",
X "InvertXBitmap ^#F"
X };
X
Xvoid DeletePoint ()
X{
X register int i;
X register struct ObjRec * obj_ptr;
X struct PolyRec * poly_ptr = NULL;
X struct PolygonRec * polygon_ptr = NULL;
X int index, n, point_deleted, deleting = TRUE;
X int root_x, root_y, old_x, old_y;
X unsigned int status;
X Window root_win, child_win;
X XEvent input, ev;
X
X if (!(topSel != NULL && topSel == botSel &&
X (topSel->obj->type == OBJ_POLY || topSel->obj->type == OBJ_POLYGON)))
X {
X Msg ("Please select only one POLY or POLYGON object.");
X return;
X }
X
X obj_ptr = topSel->obj;
X switch (obj_ptr->type)
X {
X case OBJ_POLY: poly_ptr = obj_ptr->detail.p; break;
X case OBJ_POLYGON: polygon_ptr = obj_ptr->detail.g; break;
X }
X TwoLineMsg ("Click left mouse button to DELETE points.",
X "Click other buttons to quit.");
X
X XGrabPointer (mainDisplay, drawWindow, False,
X PointerMotionMask | ButtonPressMask,
X GrabModeAsync, GrabModeAsync, None, defaultCursor, CurrentTime);
X XQueryPointer (mainDisplay, drawWindow, &root_win, &child_win,
X &root_x, &root_y, &old_x, &old_y, &status);
X XSetFont (mainDisplay, revDefaultGC, defaultFontPtr->fid);
X XDrawString (mainDisplay, drawWindow, revDefaultGC,
X old_x+4, old_y+defaultFontAsc, "DEL", 3);
X MarkRulers (old_x, old_y);
X
X while (deleting)
X {
X XNextEvent (mainDisplay, &input);
X if (input.type == ButtonPress)
X {
X if (input.xbutton.button == Button1)
X {
X point_deleted = FALSE;
X if (obj_ptr->type == OBJ_POLY &&
X PtInPolyMark (input.xbutton.x, input.xbutton.y,
X poly_ptr->n, poly_ptr->vlist, &index) ||
X obj_ptr->type == OBJ_POLYGON &&
X PtInPolyMark (input.xbutton.x, input.xbutton.y,
X polygon_ptr->n-1, polygon_ptr->vlist, &index))
X {
X point_deleted = TRUE;
X HighLightReverse ();
X if (obj_ptr->type == OBJ_POLY && poly_ptr->n == 2 ||
X obj_ptr->type == OBJ_POLYGON && polygon_ptr->n == 4)
X {
X CopySelToCut ();
X DelObj (obj_ptr);
X deleting = FALSE;
X obj_ptr = NULL;
X cfree (topSel);
X topSel = botSel = NULL;
X }
X else
X {
X switch (obj_ptr->type)
X {
X case OBJ_POLY:
X n = poly_ptr->n;
X for (i = index+1; i < n; i++)
X poly_ptr->vlist[i-1] = poly_ptr->vlist[i];
X poly_ptr->n--;
X if (poly_ptr->curved)
X {
X cfree (poly_ptr->svlist);
X poly_ptr->svlist = MakeSplinePolyVertex (
X &(poly_ptr->sn), drawOrigX, drawOrigY,
X poly_ptr->n, poly_ptr->vlist);
X }
X UpdPolyBBox (obj_ptr, poly_ptr->n, poly_ptr->vlist);
X break;
X case OBJ_POLYGON:
X n = polygon_ptr->n;
X for (i = index+1; i < n; i++)
X polygon_ptr->vlist[i-1] = polygon_ptr->vlist[i];
X polygon_ptr->n--;
X n--;
X if (index == 0)
X polygon_ptr->vlist[n-1] = polygon_ptr->vlist[0];
X if (polygon_ptr->curved)
X {
X cfree (polygon_ptr->svlist);
X polygon_ptr->svlist = MakeSplinePolygonVertex (
X &(polygon_ptr->sn), drawOrigX, drawOrigY,
X polygon_ptr->n, polygon_ptr->vlist);
X }
X UpdPolyBBox (obj_ptr, polygon_ptr->n,
X polygon_ptr->vlist);
X break;
X }
X AdjObjBBox (obj_ptr);
X }
X }
X if (point_deleted)
X {
X XDrawString (mainDisplay, drawWindow, revDefaultGC, old_x+4,
X old_y+defaultFontAsc, "DEL", 3);
X old_x = input.xbutton.x;
X old_y = input.xbutton.y;
X RedrawAnArea (botObj,
X selLtX-(1<<zoomScale), selLtY-(1<<zoomScale),
X selRbX+(1<<zoomScale), selRbY+(1<<zoomScale));
X HighLightForward ();
X if (obj_ptr != NULL)
X XDrawString (mainDisplay, drawWindow, revDefaultGC, old_x+4,
X old_y+defaultFontAsc, "DEL", 3);
X UpdSelBBox ();
X SetFileModified (TRUE);
X }
X }
X else
X {
X deleting = FALSE;
X XDrawString (mainDisplay, drawWindow, revDefaultGC,
X old_x+4, old_y+defaultFontAsc, "DEL", 3);
X }
X }
X else if (input.type == MotionNotify)
X {
X XDrawString (mainDisplay, drawWindow, revDefaultGC,
X old_x+4, old_y+defaultFontAsc, "DEL", 3);
X old_x = input.xmotion.x;
X old_y = input.xmotion.y;
X XDrawString (mainDisplay, drawWindow, revDefaultGC,
X old_x+4, old_y+defaultFontAsc, "DEL", 3);
X MarkRulers (old_x, old_y);
X while (XCheckMaskEvent (mainDisplay, PointerMotionMask, &ev)) ;
X }
X }
X XUngrabPointer (mainDisplay, CurrentTime);
X Msg ("");
X}
X
Xstatic
Xvoid ContinueAddPolyPoint (ObjPtr, MouseX, MouseY, Index, PolyPtr,
X LastMouseX, LastMouseY)
X struct ObjRec * ObjPtr;
X int MouseX, MouseY, Index;
X struct PolyRec * PolyPtr;
X int * LastMouseX, * LastMouseY;
X /* (MouseX,MouseY) is the mouse's origin in screen offsets */
X{
X int n = PolyPtr->n;
X int already_moved = FALSE, done = FALSE, before = FALSE;
X XPoint * vs = PolyPtr->vlist, v[3];
X int prev_x, prev_y, x, y, next_x, next_y, new_x, new_y;
X int orig_x, orig_y, grid_x, grid_y, new_mouse_x, new_mouse_y;
X int sel_ltx, sel_lty, sel_rbx, sel_rby, num = 0, i;
X double prev_angle, next_angle, new_angle, theta_1, theta_2;
X XEvent input, ev;
X
X MARK(OFFSET_X(vs[Index].x), OFFSET_Y(vs[Index].y));
X
X sel_ltx = selLtX; sel_lty = selLtY;
X sel_rbx = selRbX; sel_rby = selRbY;
X
X x = vs[Index].x;
X y = vs[Index].y;
X
X if (Index == 0)
X {
X next_x = vs[1].x; next_y = vs[1].y;
X prev_x = 2*x-next_x; prev_y = 2*y-next_y;
X }
X else if (Index == n-1)
X {
X prev_x = vs[n-2].x; prev_y = vs[n-2].y;
X next_x = 2*x-prev_x; next_y = 2*y-prev_y;
X }
X else
X {
X prev_x = vs[Index-1].x; prev_y = vs[Index-1].y;
X next_x = vs[Index+1].x; next_y = vs[Index+1].y;
X }
X prev_angle = atan2 ((double)(prev_y-y), (double)(prev_x-x));
X next_angle = atan2 ((double)(next_y-y), (double)(next_x-x));
X
X GridXY (MouseX, MouseY, &orig_x, &orig_y);
X new_mouse_x = MouseX; new_mouse_y = MouseY;
X XDrawString (mainDisplay, drawWindow, revDefaultGC, new_mouse_x+4,
X new_mouse_y+defaultFontAsc, "ADD", 3);
X
X while (!done)
X {
X XNextEvent (mainDisplay, &input);
X if (input.type == MotionNotify)
X {
X XDrawString (mainDisplay, drawWindow, revDefaultGC, new_mouse_x+4,
X new_mouse_y+defaultFontAsc, "ADD", 3);
X new_mouse_x = input.xmotion.x;
X new_mouse_y = input.xmotion.y;
X XDrawString (mainDisplay, drawWindow, revDefaultGC, new_mouse_x+4,
X new_mouse_y+defaultFontAsc, "ADD", 3);
X
X GridXY (new_mouse_x, new_mouse_y, &grid_x, &grid_y);
X new_x = ((new_mouse_x-MouseX)<<zoomScale) + x;
X new_y = ((new_mouse_y-MouseY)<<zoomScale) + y;
X if (!already_moved)
X {
X already_moved = TRUE;
X
X new_angle = atan2 ((double)(new_y-y), (double)(new_x-x));
X theta_1 = fabs (prev_angle - new_angle);
X theta_2 = fabs (next_angle - new_angle);
X if (theta_1 > M_PI) theta_1 = 2*M_PI-theta_1;
X if (theta_2 > M_PI) theta_2 = 2*M_PI-theta_2;
X before = (theta_1 <= theta_2);
X
X if (before)
X { /* Add a point between the current and the previous point */
X if (Index == 0)
X {
X num = 2;
X v[0].x = OFFSET_X(x); v[0].y = OFFSET_Y(y);
X v[1].x = OFFSET_X(x); v[1].y = OFFSET_Y(y);
X }
X else
X {
X num = 3;
X v[0].x = OFFSET_X(prev_x); v[0].y = OFFSET_Y(prev_y);
X v[1].x = OFFSET_X(x); v[1].y = OFFSET_Y(y);
X v[2].x = OFFSET_X(x); v[2].y = OFFSET_Y(y);
X }
X }
X else
X { /* Add a point between the current and the next point */
X if (Index == n-1)
X {
X num = 2;
X v[0].x = OFFSET_X(x); v[0].y = OFFSET_Y(y);
X v[1].x = OFFSET_X(x); v[1].y = OFFSET_Y(y);
X }
X else
X {
X num = 3;
X v[0].x = OFFSET_X(x); v[0].y = OFFSET_Y(y);
X v[1].x = OFFSET_X(x); v[1].y = OFFSET_Y(y);
X v[2].x = OFFSET_X(next_x); v[2].y = OFFSET_Y(next_y);
X }
X }
X MyDashedLine (drawWindow, revDefaultGC, v, num);
X }
X else
X {
X MyDashedLine (drawWindow, revDefaultGC, v, num);
X v[1].x = OFFSET_X(x) + grid_x - orig_x;
X v[1].y = OFFSET_Y(y) + grid_y - orig_y;
X MyDashedLine (drawWindow, revDefaultGC, v, num);
X MarkRulers (grid_x, grid_y);
X }
X while (XCheckMaskEvent (mainDisplay, PointerMotionMask, &ev)) ;
X }
X else if (input.type == ButtonRelease)
X {
X done = TRUE;
X *LastMouseX = new_mouse_x; *LastMouseY = new_mouse_y;
X MARK(OFFSET_X(vs[Index].x), OFFSET_Y(vs[Index].y));
X XDrawString (mainDisplay, drawWindow, revDefaultGC, new_mouse_x+4,
X new_mouse_y+defaultFontAsc, "ADD", 3);
X
X if (!already_moved)
X continue;
X else
X {
X MyDashedLine (drawWindow, revDefaultGC, v, num);
X if (grid_x == orig_x && grid_y == orig_y)
X continue;
X }
X
X HighLightReverse ();
X vs = (XPoint *) realloc (vs, (n+2)*sizeof(XPoint));
X if (vs == NULL)
X {
X printf ("Can not realloc () in ContinueAddPolyPoint ().\n");
X exit (-1);
X }
X PolyPtr->vlist = vs;
X if (before)
X {
X for (i = n-1; i >= Index; i--) vs[i+1] = vs[i];
X vs[Index].x = x + ((grid_x-orig_x)<<zoomScale);
X vs[Index].y = y + ((grid_y-orig_y)<<zoomScale);
X }
X else
X {
X for (i = n-1; i > Index; i--) vs[i+1] = vs[i];
X vs[Index+1].x = x + ((grid_x-orig_x)<<zoomScale);
X vs[Index+1].y = y + ((grid_y-orig_y)<<zoomScale);
X }
X PolyPtr->n++;
X n++;
X if (PolyPtr->curved)
X {
X cfree (PolyPtr->svlist);
X PolyPtr->svlist = MakeSplinePolyVertex (&(PolyPtr->sn),
X drawOrigX, drawOrigY, PolyPtr->n, PolyPtr->vlist);
X }
X UpdPolyBBox (ObjPtr, PolyPtr->n, PolyPtr->vlist);
X AdjObjBBox (ObjPtr);
X
X UpdSelBBox ();
X RedrawAreas (botObj,
X sel_ltx-(1<<zoomScale), sel_lty-(1<<zoomScale),
X sel_rbx+(1<<zoomScale), sel_rby+(1<<zoomScale),
X selLtX-(1<<zoomScale), selLtY-(1<<zoomScale),
X selRbX+(1<<zoomScale), selRbY+(1<<zoomScale));
X HighLightForward ();
X SetFileModified (TRUE);
X }
X }
X}
X
Xstatic
Xvoid ContinueAddPolygonPoint (ObjPtr, MouseX, MouseY, Index, PolygonPtr,
X LastMouseX, LastMouseY)
X struct ObjRec * ObjPtr;
X int MouseX, MouseY, Index;
X struct PolygonRec * PolygonPtr;
X int * LastMouseX, * LastMouseY;
X /* (MouseX,MouseY) is the mouse's origin in screen offsets */
X{
X int n = PolygonPtr->n;
X int already_moved = FALSE, done = FALSE, before = FALSE;
X XPoint * vs = PolygonPtr->vlist, v[3];
X int prev_x, prev_y, x, y, next_x, next_y, new_x, new_y;
X int orig_x, orig_y, grid_x, grid_y, new_mouse_x, new_mouse_y;
X int sel_ltx, sel_lty, sel_rbx, sel_rby, i;
X double prev_angle, next_angle, new_angle, theta_1, theta_2;
X XEvent input, ev;
X
X MARK(OFFSET_X(vs[Index].x), OFFSET_Y(vs[Index].y));
X
X sel_ltx = selLtX; sel_lty = selLtY;
X sel_rbx = selRbX; sel_rby = selRbY;
X
X x = vs[Index].x;
X y = vs[Index].y;
X
X if (Index == 0 || Index == n-1)
X {
X next_x = vs[1].x; next_y = vs[1].y;
X prev_x = vs[n-2].x; prev_y = vs[n-2].y;
X }
X else
X {
X prev_x = vs[Index-1].x; prev_y = vs[Index-1].y;
X next_x = vs[Index+1].x; next_y = vs[Index+1].y;
X }
X prev_angle = atan2 ((double)(prev_y-y), (double)(prev_x-x));
X next_angle = atan2 ((double)(next_y-y), (double)(next_x-x));
X
X GridXY (MouseX, MouseY, &orig_x, &orig_y);
X new_mouse_x = MouseX; new_mouse_y = MouseY;
X XDrawString (mainDisplay, drawWindow, revDefaultGC, new_mouse_x+4,
X new_mouse_y+defaultFontAsc, "ADD", 3);
X
X while (!done)
X {
X XNextEvent (mainDisplay, &input);
X if (input.type == MotionNotify)
X {
X XDrawString (mainDisplay, drawWindow, revDefaultGC, new_mouse_x+4,
X new_mouse_y+defaultFontAsc, "ADD", 3);
X new_mouse_x = input.xmotion.x;
X new_mouse_y = input.xmotion.y;
X XDrawString (mainDisplay, drawWindow, revDefaultGC, new_mouse_x+4,
X new_mouse_y+defaultFontAsc, "ADD", 3);
X
X GridXY (new_mouse_x, new_mouse_y, &grid_x, &grid_y);
X new_x = ((new_mouse_x-MouseX)<<zoomScale) + x;
X new_y = ((new_mouse_y-MouseY)<<zoomScale) + y;
X if (!already_moved)
X {
X already_moved = TRUE;
X
X new_angle = atan2 ((double)(new_y-y), (double)(new_x-x));
X theta_1 = fabs (prev_angle - new_angle);
X theta_2 = fabs (next_angle - new_angle);
X if (theta_1 > M_PI) theta_1 = 2*M_PI-theta_1;
X if (theta_2 > M_PI) theta_2 = 2*M_PI-theta_2;
X before = (theta_1 <= theta_2);
X
X if (before)
X { /* Add a point between the current and the previous point */
X v[0].x = OFFSET_X(prev_x); v[0].y = OFFSET_Y(prev_y);
X v[1].x = OFFSET_X(x); v[1].y = OFFSET_Y(y);
X v[2].x = OFFSET_X(x); v[2].y = OFFSET_Y(y);
X }
X else
X { /* Add a point between the current and the next point */
X v[0].x = OFFSET_X(x); v[0].y = OFFSET_Y(y);
X v[1].x = OFFSET_X(x); v[1].y = OFFSET_Y(y);
X v[2].x = OFFSET_X(next_x); v[2].y = OFFSET_Y(next_y);
X }
X MyDashedLine (drawWindow, revDefaultGC, v, 3);
X }
X else
X {
X MyDashedLine (drawWindow, revDefaultGC, v, 3);
X v[1].x = OFFSET_X(x) + grid_x - orig_x;
X v[1].y = OFFSET_Y(y) + grid_y - orig_y;
X MyDashedLine (drawWindow, revDefaultGC, v, 3);
X MarkRulers (grid_x, grid_y);
X }
X while (XCheckMaskEvent (mainDisplay, PointerMotionMask, &ev)) ;
X }
X else if (input.type == ButtonRelease)
X {
X done = TRUE;
X *LastMouseX = new_mouse_x; *LastMouseY = new_mouse_y;
X MARK(OFFSET_X(vs[Index].x), OFFSET_Y(vs[Index].y));
X XDrawString (mainDisplay, drawWindow, revDefaultGC, new_mouse_x+4,
X new_mouse_y+defaultFontAsc, "ADD", 3);
X
X if (!already_moved)
X continue;
X else
X {
X MyDashedLine (drawWindow, revDefaultGC, v, 3);
X if (grid_x == orig_x && grid_y == orig_y)
X continue;
X }
X
X HighLightReverse ();
X vs = (XPoint *) realloc (vs, (n+2)*sizeof(XPoint));
X if (vs == NULL)
X {
X printf ("Can not realloc () in ContinueAddPolygonPoint ().\n");
X exit (-1);
X }
X PolygonPtr->vlist = vs;
X if (Index == 0 || Index == n-1)
X {
X if (before)
X {
X vs[n].x = vs[n-1].x;
X vs[n].y = vs[n-1].y;
X vs[n-1].x = x + ((grid_x-orig_x)<<zoomScale);
X vs[n-1].y = y + ((grid_y-orig_y)<<zoomScale);
X }
X else
X {
X for (i = n-1; i > 0; i--) vs[i+1] = vs[i];
X vs[1].x = x + ((grid_x-orig_x)<<zoomScale);
X vs[1].y = y + ((grid_y-orig_y)<<zoomScale);
X }
X }
X else
X {
X if (before)
X {
X for (i = n-1; i >= Index; i--) vs[i+1] = vs[i];
X vs[Index].x = x + ((grid_x-orig_x)<<zoomScale);
X vs[Index].y = y + ((grid_y-orig_y)<<zoomScale);
X }
X else
X {
X for (i = n-1; i > Index; i--) vs[i+1] = vs[i];
X vs[Index+1].x = x + ((grid_x-orig_x)<<zoomScale);
X vs[Index+1].y = y + ((grid_y-orig_y)<<zoomScale);
X }
X }
X PolygonPtr->n++;
X n++;
X if (PolygonPtr->curved)
X {
X cfree (PolygonPtr->svlist);
X PolygonPtr->svlist = MakeSplinePolygonVertex (&(PolygonPtr->sn),
X drawOrigX, drawOrigY, PolygonPtr->n, PolygonPtr->vlist);
X }
X UpdPolyBBox (ObjPtr, PolygonPtr->n, PolygonPtr->vlist);
X AdjObjBBox (ObjPtr);
X
X UpdSelBBox ();
X RedrawAreas (botObj,
X sel_ltx-(1<<zoomScale), sel_lty-(1<<zoomScale),
X sel_rbx+(1<<zoomScale), sel_rby+(1<<zoomScale),
X selLtX-(1<<zoomScale), selLtY-(1<<zoomScale),
X selRbX+(1<<zoomScale), selRbY+(1<<zoomScale));
X HighLightForward ();
X SetFileModified (TRUE);
X }
X }
X}
X
Xvoid AddPoint ()
X{
X register struct ObjRec * obj_ptr;
X struct PolyRec * poly_ptr = NULL;
X struct PolygonRec * polygon_ptr = NULL;
X int index, adding = TRUE;
X int root_x, root_y, old_x, old_y;
X unsigned int status;
X Window root_win, child_win;
X XEvent input, ev;
X
X if (!(topSel != NULL && topSel == botSel &&
X (topSel->obj->type == OBJ_POLY || topSel->obj->type == OBJ_POLYGON)))
X {
X Msg ("Please select only one POLY or POLYGON object.");
X return;
X }
X
X obj_ptr = topSel->obj;
X switch (obj_ptr->type)
X {
X case OBJ_POLY: poly_ptr = obj_ptr->detail.p; break;
X case OBJ_POLYGON: polygon_ptr = obj_ptr->detail.g; break;
X }
X TwoLineMsg ("Drag left mouse button to ADD points.",
X "Click other buttons to quit.");
X
X XGrabPointer (mainDisplay, drawWindow, False,
X PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
X GrabModeAsync, GrabModeAsync, None, defaultCursor, CurrentTime);
X XQueryPointer (mainDisplay, drawWindow, &root_win, &child_win,
X &root_x, &root_y, &old_x, &old_y, &status);
X XSetFont (mainDisplay, revDefaultGC, defaultFontPtr->fid);
X XDrawString (mainDisplay, drawWindow, revDefaultGC,
X old_x+4, old_y+defaultFontAsc, "ADD", 3);
X MarkRulers (old_x, old_y);
X
X while (adding)
X {
X XNextEvent (mainDisplay, &input);
X if (input.type == ButtonPress)
X {
X if (input.xbutton.button == Button1)
X {
X XDrawString (mainDisplay, drawWindow, revDefaultGC,
X old_x+4, old_y+defaultFontAsc, "ADD", 3);
X if (obj_ptr->type == OBJ_POLY &&
X PtInPolyMark (input.xbutton.x, input.xbutton.y,
X poly_ptr->n, poly_ptr->vlist, &index))
X ContinueAddPolyPoint (obj_ptr, input.xbutton.x, input.xbutton.y,
X index, poly_ptr, &old_x, &old_y);
X else if (obj_ptr->type == OBJ_POLYGON &&
X PtInPolyMark (input.xbutton.x, input.xbutton.y,
X polygon_ptr->n-1, polygon_ptr->vlist, &index))
X ContinueAddPolygonPoint (obj_ptr, input.xbutton.x,
X input.xbutton.y, index, polygon_ptr, &old_x, &old_y);
X XDrawString (mainDisplay, drawWindow, revDefaultGC,
X old_x+4, old_y+defaultFontAsc, "ADD", 3);
X }
X else
X {
X adding = FALSE;
X XDrawString (mainDisplay, drawWindow, revDefaultGC,
X old_x+4, old_y+defaultFontAsc, "ADD", 3);
X }
X }
X else if (input.type == MotionNotify)
X {
X XDrawString (mainDisplay, drawWindow, revDefaultGC,
X old_x+4, old_y+defaultFontAsc, "ADD", 3);
X old_x = input.xmotion.x;
X old_y = input.xmotion.y;
X XDrawString (mainDisplay, drawWindow, revDefaultGC,
X old_x+4, old_y+defaultFontAsc, "ADD", 3);
X MarkRulers (old_x, old_y);
X while (XCheckMaskEvent (mainDisplay, PointerMotionMask, &ev)) ;
X }
X }
X XUngrabPointer (mainDisplay, CurrentTime);
X Msg ("");
X}
X
Xvoid EditMenu (X, Y)
X int X, Y;
X{
X int index, * fore_colors, * valid;
X
X DefaultColorArrays (MAXEDITMENUS, &fore_colors, &valid);
X index = TextMenuLoop (X, Y, editMenuStr, MAXEDITMENUS, fore_colors, valid,
X SINGLECOLOR);
X
X switch (index)
X {
X case EDIT_REDRAW: ClearAndRedrawDrawWindow (); break;
X case EDIT_DUP: DupSelObj (); break;
X case EDIT_DELETE: DelAllSelObj (); break;
X case EDIT_SELALL: SelAllObj (); break;
X case EDIT_UNDODEL: UndoDelete (); break;
X case EDIT_DEL_POINT: DeletePoint (); break;
X case EDIT_ADD_POINT: AddPoint (); break;
X case EDIT_COPY: CopyToCutBuffer (); break;
X case EDIT_PASTE: PasteFromCutBuffer (); break;
X case EDIT_INV_XBM: InvertXBitmaps (); break;
X }
X}
X
Xvoid FrontProc ()
X{
X if (topSel != NULL)
X {
X HighLightReverse ();
X MoveSelToTop ();
X RedrawAnArea (botObj, selLtX-(1<<zoomScale), selLtY-(1<<zoomScale),
X selRbX+(1<<zoomScale), selRbY+(1<<zoomScale));
X HighLightForward ();
X SetFileModified (TRUE);
X }
X}
X
Xvoid BackProc ()
X{
X if (topSel != NULL)
X {
X HighLightReverse ();
X MoveSelToBot ();
X RedrawAnArea (botObj, selLtX-(1<<zoomScale), selLtY-(1<<zoomScale),
X selRbX+(1<<zoomScale), selRbY+(1<<zoomScale));
X HighLightForward ();
X SetFileModified (TRUE);
X }
X}
X
X#define ARRANGE_FRONT 0
X#define ARRANGE_BACK 1
X#define ARRANGE_GROUP 2
X#define ARRANGE_UNGROUP 3
X#define ARRANGE_ALIGNOBJ 4
X#define ARRANGE_ALIGNGRID 5
X#define FLIP_HORIZONTAL 6
X#define FLIP_VERTICAL 7
X#define ROTATE_CLOCKWISE 8
X#define ROTATE_COUNTER 9
X#define MAXARRANGEMENUS 10
X
Xstatic char * arrangeMenuStr[] =
X { "Front ^F",
X "Back ^B",
X "Group ^G",
X "UnGroup ^U",
X "AlignObjs ^L",
X "AlignToGrid ^T",
X "FlipHorizontal #H",
X "FlipVertical #V",
X "RotateClockWise #W",
X "RotateCounter #C",
X };
X
Xvoid ArrangeMenu (X, Y)
X int X, Y;
X{
X int index, * fore_colors, * valid;
X
X DefaultColorArrays (MAXARRANGEMENUS, &fore_colors, &valid);
X index = TextMenuLoop (X, Y, arrangeMenuStr, MAXARRANGEMENUS, fore_colors,
X valid, SINGLECOLOR);
X switch (index)
X {
X case ARRANGE_FRONT: FrontProc (); break;
X case ARRANGE_BACK: BackProc (); break;
X case ARRANGE_GROUP: GroupSelObj (); break;
X case ARRANGE_UNGROUP: UngroupSelObj (); break;
X case ARRANGE_ALIGNOBJ: AlignSelObjs (); break;
X case ARRANGE_ALIGNGRID: AlignSelToGrid (); break;
X case FLIP_HORIZONTAL: FlipHorizontal (); break;
X case FLIP_VERTICAL: FlipVertical (); break;
X case ROTATE_CLOCKWISE: RotateClockWise (); break;
X case ROTATE_COUNTER: RotateCounter (); break;
X }
X}
X
Xstatic struct ObjRec * tmpTopObj, * tmpBotObj;
Xstatic struct SelRec * tmpTopSel, * tmpBotSel;
X
Xstatic
Xvoid PushTmpSel (ObjPtr)
X struct ObjRec * ObjPtr;
X{
X struct SelRec * sel_ptr;
X
X ObjPtr->next = tmpTopObj;
X ObjPtr->prev = NULL;
X
X sel_ptr = (struct SelRec *) calloc (1, sizeof (struct SelRec));
X sel_ptr->next = tmpTopSel;
X sel_ptr->prev = NULL;
X sel_ptr->obj = ObjPtr;
X
X if (tmpTopObj == NULL)
X {
X tmpBotObj = ObjPtr;
X tmpBotSel = sel_ptr;
X }
X else
X {
X tmpTopObj->prev = ObjPtr;
X tmpTopSel->prev = sel_ptr;
X }
X tmpTopObj = ObjPtr;
X tmpTopSel = sel_ptr;
X}
X
Xvoid UpdateSymbols ()
X{
X int dx = 0, dy = 0, changed = FALSE;
X char path_name[MAXPATHLENGTH], sym_name[MAXPATHLENGTH];
X struct ObjRec * obj_ptr, * new_obj_ptr;
X struct SelRec * sel_ptr;
X
X if (topSel == NULL) return;
X
X tmpTopObj = tmpBotObj = NULL;
X tmpTopSel = tmpBotSel = NULL;
X
X HighLightReverse ();
X
X for (sel_ptr = botSel; sel_ptr != NULL; sel_ptr = sel_ptr->prev)
X {
X obj_ptr = sel_ptr->obj;
X if (obj_ptr->type != OBJ_ICON) continue;
X
X strcpy (sym_name, obj_ptr->detail.r->s);
X if (GetSymbolPath (obj_ptr->detail.r->s, path_name))
X {
X if ((new_obj_ptr = GetObjRepresentation (path_name, sym_name)) != NULL)
X {
X switch (horiAlign)
X {
X case ALIGN_L:
X dx = obj_ptr->obbox.ltx - new_obj_ptr->obbox.ltx;
X break;
X case ALIGN_N:
X case ALIGN_C:
X dx = (int)(((obj_ptr->obbox.ltx+obj_ptr->obbox.rbx) -
X (new_obj_ptr->obbox.ltx+new_obj_ptr->obbox.rbx))/2);
X break;
X case ALIGN_R:
X dx = obj_ptr->obbox.rbx - new_obj_ptr->obbox.rbx;
X break;
X }
X switch (vertAlign)
X {
X case ALIGN_T:
X dy = obj_ptr->obbox.lty - new_obj_ptr->obbox.lty;
X break;
X case ALIGN_N:
X case ALIGN_M:
X dy = (int)(((obj_ptr->obbox.lty+obj_ptr->obbox.rby) -
X (new_obj_ptr->obbox.lty+new_obj_ptr->obbox.rby))/2);
X break;
X case ALIGN_B:
X dy = obj_ptr->obbox.rby - new_obj_ptr->obbox.rby;
X break;
X }
X MoveObj (new_obj_ptr, dx, dy);
X
X changed = TRUE;
X
X UnlinkObj (obj_ptr);
X PushTmpSel (obj_ptr);
X CopyAndUpdateAttrs (new_obj_ptr, obj_ptr);
X
X if (new_obj_ptr->bbox.ltx < selLtX) selLtX = new_obj_ptr->bbox.ltx;
X if (new_obj_ptr->bbox.lty < selLtY) selLtY = new_obj_ptr->bbox.lty;
X if (new_obj_ptr->bbox.rbx < selRbX) selRbX = new_obj_ptr->bbox.rbx;
X if (new_obj_ptr->bbox.rby < selRbY) selRbY = new_obj_ptr->bbox.rby;
X if (new_obj_ptr->obbox.ltx < selObjLtX)
X selObjLtX = new_obj_ptr->obbox.ltx;
X if (new_obj_ptr->obbox.lty < selObjLtY)
X selObjLtY = new_obj_ptr->obbox.lty;
X if (new_obj_ptr->obbox.rbx < selObjRbX)
X selObjRbX = new_obj_ptr->obbox.rbx;
X if (new_obj_ptr->obbox.rby < selObjRbY)
X selObjRbY = new_obj_ptr->obbox.rby;
X
X sel_ptr->obj = new_obj_ptr;
X AddObj (NULL, topObj, new_obj_ptr);
X }
X }
X }
X
X PushToCutBuffer (tmpTopSel, tmpBotSel);
X
X if (changed)
X {
X RedrawAnArea (botObj, selLtX-(1<<zoomScale), selLtY-(1<<zoomScale),
X selRbX+(1<<zoomScale), selRbY+(1<<zoomScale));
X UpdSelBBox ();
X SetFileModified (TRUE);
X justDupped = FALSE;
X }
X HighLightForward ();
X}
END_OF_FILE
if test 29266 -ne `wc -c <'edit.c'`; then
echo shar: \"'edit.c'\" unpacked with wrong size!
fi
# end of 'edit.c'
fi
echo shar: End of archive 3 \(of 23\).
cp /dev/null ark3isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 23 archives.
rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0
---------------------------------> cut here <---------------------------------
--
Bill Cheng // UCLA Computer Science Department // (213) 206-7135
3277 Boelter Hall // Los Angeles, California 90024 // USA
william at CS.UCLA.EDU ...!{uunet|ucbvax}!cs.ucla.edu!william
More information about the Comp.sources.x
mailing list