mikew@wyse.wyse.com (Mike Wexler) (02/23/89)
Submitted-by: koblas@mips.com (David Koblas) Posting-number: Volume 3, Issue 31 Archive-name: xpaint/part01 #! /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 1 (of 3)." # Contents: README draw.c menu.c pat_09.xbm # Wrapped by mikew@wyse on Wed Feb 22 13:37:38 1989 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'README' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'README'\" else echo shar: Extracting \"'README'\" \(1752 characters\) sed "s/^X//" >'README' <<'END_OF_FILE' X X XPAINT X X This intent of this program was a utility to edit images that XI generated, but very quickly I drifted from my orignal purpose and Xcreated something that closely resembles MacPaint [probably a trademark Xof Apple Computer]. I still intend to add some image enhancements Xfacilities (specifically Alpha channel data, and color support). X X Updates, and patches: Well yes I'm interested in what people Xdo to this, add, fix. There are whole regions of this program that Xare unmaintainable without a real rewrite. So fairly quickly after this Xinitial release of XPAINT I will begin to work on version 2.0 which will Xinclude color support and real image enhancements facilities. It Xwill be a 95% rewrite since now I know what the requirements for this Xtype of program are. If you didn't know better you might call this Xan alpha release but since I plan on tossing most of this code Xin favor of bigger and better things I though I would let the world Xplay with it until then. X X Also this program is based on the assuption that the client Xis faster than the server for some things (I use XImages instead of XPixmaps). Let me know how this works for you, is this a safe assumtion X[on a 11/750, on a cray, server on a PMAX, on a sun]. Another question Xis it a "nice" idea to open up many windows and take advantage of the Xserver handling things more me, or should I be reserving this and Xjust open up 1 or two and wave my hands alot... X X Finally, as I upgrade this program for color I REALLY want Xpeoples comments and sudgestions on how to make this very useful. XThis is your chance to see some of your wishes come true, why should Xall those PC users have all the fun. X X X David Koblas X X koblas@mips.com ...{ames,decwrl}!mips!koblas END_OF_FILE if test 1752 -ne `wc -c <'README'`; then echo shar: \"'README'\" unpacked with wrong size! fi # end of 'README' fi if test -f 'draw.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'draw.c'\" else echo shar: Extracting \"'draw.c'\" \(36994 characters\) sed "s/^X//" >'draw.c' <<'END_OF_FILE' X/* +------------------------------------------------------------------+ */ X/* | Copyright 1989, David Koblas. | */ X/* | You may copy this file in whole or in part as long as you | */ X/* | don't try to make money off it, or pretend that you wrote it. | */ X/* +------------------------------------------------------------------+ */ X X#include <stdio.h> X#include "xpaint.h" X X#define Between(min,val,max) (((min)<=(val)) && ((val)<(max))) X X#define ABS(x) (((x)<0) ? 0-(x) : (x)) X#define SIGN(x) (((x)==0) ? 0 : ((x)<0) ? -1 : 1) X#define MIN(a,b) ((a)<(b) ? (a) : (b)) X#define MAX(a,b) ((a)>(b) ? (a) : (b)) X#define CTRL(x) ((x)-'A'+1) X#define DELETE 127 X X#define PUT_P_PIXEL(x,y) PATTERN_VAL(x,y)?\ X PUT_C_PIXEL(CurrentWindow->white,x,y):\ X PUT_C_PIXEL(CurrentWindow->black,x,y) X#define PUT_C_PIXEL(c,x,y) XPutPixel(draw.buffer, \ X CurrentWindow->img_offx+(x),(y),c) X#define PUT_PIXEL(x,y) PUT_C_PIXEL(CurrentWindow->black,x,y); X Xstatic int buf_flag=FALSE; Xstatic int undo_flag=FALSE; Xstatic int dot_flag=FALSE; Xstatic int dot_inter_id; Xstatic int buf_xe,buf_ye,buf_xs,buf_ys; X X#ifndef lint Xstatic char rcsid[]="$Header: draw.c,v 1.7 89/02/20 19:32:56 koblas Locked $"; X#endif X Xstatic struct { X int width,height; X GC gc; X XFontStruct *font_info; X Window window; X XImage *buffer; X int mapped; X int lastx,lasty; X} draw; X Xstatic struct { X int flag; X int width,height; X int x,y; X} fatbits; X Xstatic struct { X XImage *image; X int xorig,yorig; X int x,y; X int xs; X int width,height; X} select_buffer; X XWindow CreateDraw() X{ X XGCValues values; X XSetWindowAttributes attr; X char *data; X X draw.width = CurrentWindow->width - (10+32+32+10) - (10+16+10); X draw.height= CurrentWindow->height - (10+60+10) - X CurrentWindow->subwind[DRAW_ID].delta_y; X X attr.do_not_propagate_mask = -1; X attr.background_pixel = CurrentWindow->white; X attr.event_mask = ExposureMask|ButtonPressMask| X KeyPressMask| X ButtonReleaseMask|PointerMotionMask; X X draw.window = XCreateWindow(CurrentWindow->display, X CurrentWindow->window, X DELTA_XPOS(DRAW_ID),DELTA_YPOS(DRAW_ID), X draw.width,draw.height, X 1,0,0,0, X CWDontPropagate|CWEventMask|CWBackPixel,&attr); X draw.mapped=FALSE; X draw.lastx=draw.lasty=0; X X draw.font_info = XLoadQueryFont(CurrentWindow->display,DEF_FONT); X if (draw.font_info == NULL) { X fprintf(stderr,"Unable to open font %s\n",DEF_FONT); X exit(1); X } X values.foreground = CurrentWindow->black; X values.background = CurrentWindow->white; X values.font = draw.font_info -> fid; X draw.gc = XCreateGC(CurrentWindow->display,draw.window, X GCFont|GCForeground|GCBackground,&values); X X if ((data=(char *)malloc(CurrentWindow->img_height*draw.height))==NULL){ X fprintf(stderr,"Malloc for buffer #1 failed\n"); X exit(1); X } X draw.buffer = XCreateImage(CurrentWindow->display,CurrentWindow->visual, X CurrentWindow->depth, X ZPixmap,0,data,CurrentWindow->img_width, X draw.height,8,0); X if ((data=(char *)malloc(CurrentWindow->img_height*draw.height))==NULL){ X fprintf(stderr,"Malloc for buffer #1 failed\n"); X exit(1); X } X select_buffer.image = XCreateImage(CurrentWindow->display, X CurrentWindow->visual, X CurrentWindow->depth, X ZPixmap,0,data, X CurrentWindow->img_width, X draw.height,8,0); X X return draw.window; X} X Xvoid OpenDraw() X{ X int x,y; X char *data; X X if (draw.mapped) X return; X X draw.mapped=TRUE; X buf_flag=FALSE; X undo_flag=FALSE; X dot_flag=FALSE; X fatbits.flag=FALSE; X XMapWindow(CurrentWindow->display,draw.window); X draw.lastx=draw.lasty=0; X X CurrentWindow->img_width = DefaultXsize; X CurrentWindow->img_height = DefaultYsize; X if ((data=(char *)malloc(DefaultXsize*DefaultYsize))==NULL) { X fprintf(stderr,"Malloc for buffer #2 failed\n"); X exit(1); X } X CurrentWindow->master = XCreateImage(CurrentWindow->display, X CurrentWindow->visual, X CurrentWindow->depth, X ZPixmap,0,data,DefaultXsize, X DefaultYsize,8,0); X for (x=0;x<DefaultXsize;x++) { X XPutPixel(CurrentWindow->master,x,0, X CurrentWindow->white); X } X for (y=1;y<DefaultYsize;y++) { X bcopy(CurrentWindow->master->data, X CurrentWindow->master->data+ X (y*CurrentWindow->master->bytes_per_line), X CurrentWindow->master->bytes_per_line); X } X X XFlush(CurrentWindow->display); X} X Xvoid CloseDraw() X{ X if (draw.mapped) { X XUnmapWindow(CurrentWindow->display,draw.window); X draw.mapped=FALSE; X } X XFlush(CurrentWindow->display); X} X Xvoid ResizeDraw() X{ X char *data; X X draw.width = CurrentWindow->width - (10+32+32+10) - (10+16+10); X draw.height= CurrentWindow->height - (10+60+10) - X CurrentWindow->subwind[DRAW_ID].delta_y; X X draw.width = MIN(draw.width, CurrentWindow->img_width); X draw.height = MIN(draw.height, CurrentWindow->img_height); X X XResizeWindow(CurrentWindow->display,draw.window, X draw.width,draw.height); X X XDestroyImage(draw.buffer); X if ((data=(char *)malloc(CurrentWindow->img_height*draw.height))==NULL){ X fprintf(stderr,"Malloc for buffer #1 failed\n"); X exit(1); X } X draw.buffer = XCreateImage(CurrentWindow->display,CurrentWindow->visual, X CurrentWindow->depth, X ZPixmap,0,data,CurrentWindow->img_width, X draw.height,8,0); X XDestroyImage(select_buffer.image); X if ((data=(char *)malloc(CurrentWindow->img_height*draw.height))==NULL){ X fprintf(stderr,"Malloc for buffer #1 failed\n"); X exit(1); X } X select_buffer.image = XCreateImage(CurrentWindow->display, X CurrentWindow->visual, X CurrentWindow->depth, X ZPixmap,0,data, X CurrentWindow->img_width, X draw.height,8,0); X} X XShowDraw() X{ X ResizeDraw(); X buf_flag=FALSE; X undo_flag=FALSE; X dot_flag=FALSE; X fatbits.flag=FALSE; X XMapWindow(CurrentWindow->display,draw.window); X draw.mapped=TRUE; X XFlush(CurrentWindow->display); X} X Xvoid EventDraw(event) XXEvent *event; X{ X int x,y; X long pix; X X switch (event->type) { X case ButtonPress: X OnGraphic(CurrentActionID,event); X break; X case Expose: X if (fatbits.flag) { X for (y=0;y<fatbits.height;y++) { X for (x=0;x<fatbits.width;x++) { X pix = XGetPixel(draw.buffer, X CurrentWindow->img_offx+fatbits.x+x, X fatbits.y+y); X if (pix!=CurrentWindow->white) X XFillRectangle(CurrentWindow->display, X draw.window,CurrentWindow->igc, X x*6,y*6,5,5); X } X } X XPutImage(CurrentWindow->display,draw.window, X draw.gc,CurrentWindow->master, X CurrentWindow->img_offx+fatbits.x, X CurrentWindow->img_offy+fatbits.y, X 0,0,fatbits.width,fatbits.height); X } else { X XPutImage(CurrentWindow->display,draw.window, X draw.gc,CurrentWindow->master, X CurrentWindow->img_offx+event->xexpose.x, X CurrentWindow->img_offy+event->xexpose.y, X event->xexpose.x,event->xexpose.y, X event->xexpose.width,event->xexpose.height); X if (buf_flag) { X ShowBuffer(); X } X if (dot_flag) { X XPutImage(CurrentWindow->display,draw.window, X draw.gc,select_buffer.image, X select_buffer.xs, X 0,select_buffer.x,select_buffer.y, X select_buffer.width, X select_buffer.height); X } X } X break; X } X} X XDrawFlipVert() X{ X int x,y,c=select_buffer.width/2; X long pixA,pixB; X X for (y=0;y<select_buffer.height;y++) X for (x=0;x<c;x++) { X pixA = XGetPixel(select_buffer.image, X select_buffer.xs+x,y); X pixB = XGetPixel(select_buffer.image, X select_buffer.xs+(select_buffer.width-x),y); X XPutPixel(select_buffer.image, X select_buffer.xs+x,y,pixB); X XPutPixel(select_buffer.image, X select_buffer.xs+(select_buffer.width-x),y,pixA); X } X XPutImage(CurrentWindow->display,draw.window, X draw.gc,select_buffer.image,select_buffer.xs, X 0,select_buffer.x,select_buffer.y, X select_buffer.width,select_buffer.height); X} X XDrawFlipHorz() X{ X int x,y,c=select_buffer.height/2; X long pixA,pixB; X X for (y=0;y<c;y++) X for (x=0;x<select_buffer.width;x++) { X pixA = XGetPixel(select_buffer.image, X select_buffer.xs+x,y); X pixB = XGetPixel(select_buffer.image, X select_buffer.xs+x,select_buffer.height-y); X XPutPixel(select_buffer.image, X select_buffer.xs+x,y,pixB); X XPutPixel(select_buffer.image, X select_buffer.xs+x,select_buffer.height-y,pixA); X } X XPutImage(CurrentWindow->display,draw.window, X draw.gc,select_buffer.image,select_buffer.xs, X 0,select_buffer.x,select_buffer.y, X select_buffer.width,select_buffer.height); X} X XDrawBufferInvert() X{ X int x,y; X long pix; X X if (!dot_flag) X return; X X for (y=0;y<select_buffer.height;y++) X for (x=0;x<select_buffer.width;x++) { X pix = XGetPixel(select_buffer.image, X x+select_buffer.xs,y); X if (pix == CurrentWindow->white) X XPutPixel(select_buffer.image, X x+select_buffer.xs,y,CurrentWindow->black); X else if (pix == CurrentWindow->black) X XPutPixel(select_buffer.image, X x+select_buffer.xs,y,CurrentWindow->white); X } X XPutImage(CurrentWindow->display,draw.window, X draw.gc,select_buffer.image,select_buffer.xs, X 0,select_buffer.x,select_buffer.y, X select_buffer.width,select_buffer.height); X} X Xvoid DrawUndo() X{ X if (!undo_flag && !buf_flag) X return; X X if (undo_flag) { X ShowBuffer(); X buf_flag = TRUE; X undo_flag=FALSE; X } else { X XPutImage(CurrentWindow->display,draw.window, X draw.gc,CurrentWindow->master, X CurrentWindow->img_offx+buf_xs, X CurrentWindow->img_offy+buf_ys, X buf_xs,buf_ys, X buf_xe-buf_xs,buf_ye-buf_ys); X buf_flag = FALSE; X undo_flag=TRUE; X } X if (dot_flag) { X int t; X X t = select_buffer.x ; X select_buffer.x = select_buffer.xorig; X select_buffer.xorig = t; X t = select_buffer.y ; X select_buffer.y = select_buffer.yorig; X select_buffer.yorig = t; X X XPutImage(CurrentWindow->display,draw.window, X draw.gc,CurrentWindow->master, X CurrentWindow->img_offx+select_buffer.xorig, X CurrentWindow->img_offy+select_buffer.yorig, X select_buffer.xorig,select_buffer.yorig, X select_buffer.width,select_buffer.height); X X XPutImage(CurrentWindow->display,draw.window, X draw.gc,select_buffer.image,select_buffer.xs, X 0,select_buffer.x,select_buffer.y, X select_buffer.width,select_buffer.height); X } X} X XDrawGetRegion(x,y,w,h) Xint *x,*y,*w,*h; X{ X *x = select_buffer.x; X *y = select_buffer.y; X *w = select_buffer.width; X *h = select_buffer.height; X} X XXeroxMaster() X{ X int len = draw.buffer->height* X CurrentWindow->master->bytes_per_line; X char *start=CurrentWindow->master->data+ X (CurrentWindow->master->bytes_per_line*CurrentWindow->img_offy); X X bcopy(start,draw.buffer->data,len); X} X XXeroxSubMaster(xs,ys,xe,ye) Xint xs,ys,xe,ye; X{ X int len = (ye-ys)*CurrentWindow->master->bytes_per_line; X char *start=CurrentWindow->master->data+ X (CurrentWindow->master->bytes_per_line* X (CurrentWindow->img_offy+ys)); X char *dst=draw.buffer->data+ X (draw.buffer->bytes_per_line*ys); X X bcopy(start,dst,len); X} X XGetBuffer(xs,ys,xe,ye) Xint xs,ys,xe,ye; X{ X static int buf_a_xs,buf_a_xe,buf_a_ys,buf_a_ye; X X if (xe<xs) { X int t = xs; xs = xe; xe = t; X } X if (ye<ys) { X int t = ys; ys = ye; ye = t; X } X xe++; X ye++; X if (xs<0) xs=0; X if (ys<0) ys=0; X X if (!buf_flag) { X buf_a_xs = buf_xs = xs; X buf_a_ys = buf_ys = ys; X buf_a_xe = buf_xe = xe; X buf_a_ye = buf_ye = ye; X XeroxSubMaster(xs,ys,xe,ye); X buf_flag = TRUE; X } else { X buf_xs = MIN(buf_a_xs,xs); X buf_ys = MIN(buf_a_ys,ys); X buf_xe = MAX(buf_a_xe,xe); X buf_ye = MAX(buf_a_ye,ye); X XeroxSubMaster(buf_xs,buf_ys,buf_xe,buf_ye); X buf_a_xs = xs; X buf_a_ys = ys; X buf_a_xe = xe; X buf_a_ye = ye; X } X} X XShowSubBuffer(xs,ys,xe,ye) Xint xs,ys,xe,ye; X{ X if (!buf_flag) return; X X if (xe<xs) { X int t = xs; xs = xe; xe = t; X } X if (ye<ys) { X int t = ys; ys = ye; ye = t; X } X xe++; X ye++; X X XPutImage(CurrentWindow->display,draw.window, X draw.gc,draw.buffer, X CurrentWindow->img_offx+buf_xs+xs,ys+buf_ys, X buf_xs+xs,buf_ys+ys,xe-xs,ye-ys); X XFlush(CurrentWindow->display); X} X XShowBuffer() X{ X if (!buf_flag) return; X X XPutImage(CurrentWindow->display,draw.window, X draw.gc,draw.buffer, X CurrentWindow->img_offx+buf_xs,buf_ys, X buf_xs,buf_ys,buf_xe-buf_xs,buf_ye-buf_ys); X XFlush(CurrentWindow->display); X} X XFlushBuffer() X{ X int len = (buf_ye-buf_ys)*CurrentWindow->master->bytes_per_line; X char *start=CurrentWindow->master->data+ X (CurrentWindow->master->bytes_per_line* X (CurrentWindow->img_offy+buf_ys)); X char *dst=draw.buffer->data+ X (draw.buffer->bytes_per_line*buf_ys); X X if (dot_flag) { X int x,y; X long pix; X X DeleteInterrupt(dot_inter_id); X dot_flag = FALSE; X buf_flag = FALSE; X for (y=0;y<select_buffer.height;y++) X for (x=0;x<select_buffer.width;x++) { X pix = XGetPixel(select_buffer.image, X x+select_buffer.xs,y); X XPutPixel(CurrentWindow->master, X select_buffer.x+CurrentWindow->img_offx+x, X select_buffer.y+CurrentWindow->img_offy+y,pix); X } X } X X undo_flag= FALSE; X X if (!buf_flag) return; X X bcopy(dst,start,len); X buf_flag=FALSE; X} X XDrawFatbits() X{ X int x,y; X int w=draw.width/6,h=draw.height/6; X long pix; X X if (fatbits.flag) X return; X FlushBuffer(); X fatbits.flag=TRUE; X X XClearWindow(CurrentWindow->display,draw.window); X X fatbits.width = w - 1; X fatbits.height = h - 1; X fatbits.x = draw.lastx; X fatbits.y = draw.lasty; X X for (y=0;y<h;y++) { X for (x=0;x<w;x++) { X pix = XGetPixel(CurrentWindow->master, X CurrentWindow->img_offx+fatbits.x+x, X CurrentWindow->img_offy+fatbits.y+y); X if (pix!=CurrentWindow->white) X XFillRectangle(CurrentWindow->display, X draw.window,CurrentWindow->igc, X x*6,y*6,5,5); X } X } X XPutImage(CurrentWindow->display,draw.window, X draw.gc,CurrentWindow->master, X CurrentWindow->img_offx+fatbits.x, X CurrentWindow->img_offy+fatbits.y, X 0,0,fatbits.width,fatbits.height); X} X X/****************************************************************************/ X/****************************************************************************/ X/****************************************************************************/ X/****************************************************************************/ X/****************************************************************************/ X XTrackLine(flag,x,y) Xint flag,x,y; X{ X static int xstart,ystart; X static long color; X X if (flag) { X xstart = x; X ystart = y; X color = (XGetPixel(draw.buffer,x,y) == CurrentWindow->white) ? X CurrentWindow->black : CurrentWindow->white; X return; X } X X GetBuffer(xstart,ystart,x,y); X DrawLine(xstart,ystart,x,y,color); X ShowBuffer(); X} X XTrackArbLine(flag,x,y) Xint flag,x,y; X{ X static int xstart,ystart; X static long color; X X if (flag) { X xstart = x; X ystart = y; X GetBuffer(0,0,draw.width,draw.height); X color = (XGetPixel(draw.buffer,CurrentWindow->img_offx+x,y) X == CurrentWindow->white) ? X CurrentWindow->black : CurrentWindow->white; X } X DrawLine(xstart,ystart,x,y,color); X ShowSubBuffer(xstart,ystart,x,y); X xstart=x; X ystart=y; X} X XTrackRectangle(flag,x,y) Xint flag,x,y; X{ X static int xstart,ystart; X int xs,ys,w,h; X X if (flag) { X xstart = x; X ystart = y; X return; X } X if (x<xstart) { X xs = x; X w = xstart - x; X } else { X xs = xstart; X w = x - xstart; X } X if (y<ystart) { X ys = y; X h = ystart - y; X } else { X ys = ystart; X h = y - ystart; X } X GetBuffer(xstart,ystart,x,y); X DrawRectangle(xs,ys,w,h,FALSE,0); X ShowBuffer(); X} X XTrackEllipse(flag,x,y) Xint flag,x,y; X{ X static int xstart,ystart; X int xs,ys,w,h; X X if (flag) { X xstart = x; X ystart = y; X return; X } X if (x<xstart) { X xs = x; X w = xstart - x; X } else { X xs = xstart; X w = x - xstart; X } X if (y<ystart) { X ys = y; X h = ystart - y; X } else { X ys = ystart; X h = y - ystart; X } X GetBuffer(xstart,ystart,x,y); X DrawEllipse(xs,ys,w,h); X ShowBuffer(); X} X XTrackEraser(flag,x,y) Xint flag,x,y; X{ X int xs=16,ys=10; X X if (flag) { X GetBuffer(0,0,draw.width,draw.height); X } X if (x+xs>draw.width) X xs=draw.width-x; X if (y+ys>draw.height) X ys=draw.height-y; X FillRectangle(x,y,xs,ys,CurrentWindow->white); X ShowSubBuffer(x,y,x+xs,y+ys); X} X X XTrackRectfill(flag,x,y) Xint flag,x,y; X{ X static int xstart,ystart; X int xs,ys,w,h; X X if (flag) { X xstart = x; X ystart = y; X return; X } X if (x<xstart) { X xs = x; X w = xstart - x; X } else { X xs = xstart; X w = x - xstart; X } X if (y<ystart) { X ys = y; X h = ystart - y; X } else { X ys = ystart; X h = y - ystart; X } X GetBuffer(xstart,ystart,x,y); X DrawRectangle(xs,ys,w,h,TRUE,0); X ShowBuffer(); X} X XTrackEllipfill(flag,x,y) Xint flag,x,y; X{ X static int xstart,ystart; X int xs,ys,w,h; X X if (flag) { X xstart = x; X ystart = y; X return; X } X if (x<xstart) { X xs = x; X w = xstart - x; X } else { X xs = xstart; X w = x - xstart; X } X if (y<ystart) { X ys = y; X h = ystart - y; X } else { X ys = ystart; X h = y - ystart; X } X GetBuffer(xstart,ystart,x,y); X DrawFillEllipse(xs,ys,w,h); X ShowBuffer(); X} X XTrackBrush(flag,x,y) Xint flag,x,y; X{ X int xs=16,ys=10; X X if (flag) { X GetBuffer(0,0,draw.width,draw.height); X } X if (x+xs>draw.width) X xs=draw.width-x; X if (y+ys>draw.height) X ys=draw.height-y; X FillRectangle(x,y,xs,ys,CurrentWindow->black); X ShowSubBuffer(x,y,x+xs,y+ys); X} X X#include "spraypat.xbm" Xstatic char SprayBits[spraypattern_height*spraypattern_width]; Xchar *SprayBitmap = spraypattern_bits; Xstatic int SprayFirst=TRUE; X XEditSpray() X{ X int x,y; X int xw=(spraypattern_width+7)/8; X X if (SprayFirst) { X for (y=0;y<spraypattern_height;y++) X for (x=0;x<spraypattern_width;x++) X if ((spraypattern_bits[(y*xw)+(x/8)]&(1<<(x%8)))!=0){ X SprayBits[x+y*spraypattern_width]=FALSE; X } else { X SprayBits[x+y*spraypattern_width]=TRUE; X } X SprayFirst=FALSE; X } X Bitedit(spraypattern_width,spraypattern_height,SprayBits); X} X XTrackSpray(flag,xp,yp) Xint flag,xp,yp; X{ X int x,y; X int xw = (spraypattern_width+7)/8; X X if (flag) { X GetBuffer(0,0,draw.width,draw.height); X if (SprayFirst) { X for (y=0;y<spraypattern_height;y++) X for (x=0;x<spraypattern_width;x++) X if ((spraypattern_bits[(y*xw)+(x/8)]&(1<<(x%8)))!=0){ X SprayBits[x+y*spraypattern_width] = FALSE; X } else { X SprayBits[x+y*spraypattern_width] = TRUE; X } X SprayFirst=FALSE; X } X } X for (y=0;y<spraypattern_height;y++) X for (x=0;x<spraypattern_width;x++) X if (!SprayBits[x+y*spraypattern_width]) X PUT_PIXEL(xp+x,yp+y); X ShowSubBuffer(xp,yp,xp+spraypattern_width,yp+spraypattern_height); X} X XTrackDotBox(flag,x,y) Xint flag,x,y; X{ X static int xstart,ystart; X int xs,ys,w,h; X X if (flag) { X xstart = x; X ystart = y; X return; X } X if (x<xstart) { X xs = x; X w = xstart - x; X } else { X xs = xstart; X w = x - xstart; X } X if (y<ystart) { X ys = y; X h = ystart - y; X } else { X ys = ystart; X h = y - ystart; X } X GetBuffer(xstart,ystart,x,y); X DrawRectangle(xs,ys,w,h,FALSE,1); X ShowBuffer(); X} X XTrackArrow(flag,x,y) Xint flag,x,y; X{ X static int work_flag; X static int dx,dy; X int xstart,ystart,xend,yend; X X if (flag) { X if (Between(select_buffer.x,x, X select_buffer.x+select_buffer.width) && X Between(select_buffer.y,y, X select_buffer.y+select_buffer.height)) { X dx = select_buffer.x - x; X dy = select_buffer.y - y; X work_flag = TRUE; X } else { X work_flag = FALSE; X } X return; X } X if (!work_flag) X return; X select_buffer.x = xstart = x + dx; X select_buffer.y = ystart = y + dy; X xend = xstart + select_buffer.width; X yend = ystart + select_buffer.height; X GetBuffer(xstart,ystart,xend,yend); X ShowBuffer(); X XPutImage(CurrentWindow->display,draw.window, X draw.gc,select_buffer.image, X select_buffer.xs,0,select_buffer.x,select_buffer.y, X select_buffer.width,select_buffer.height); X} X XTrackFatbits(flag,x,y) Xint flag,x,y; X{ X static long color; X int go=TRUE; X X if (Between(0,x,fatbits.width+6-fatbits.width%6) && X Between(0,y,fatbits.height+6-fatbits.height%6)) X go=FALSE; X x = x/6; X y = y/6; X if (flag) { X GetBuffer(fatbits.x,fatbits.y, X fatbits.x+fatbits.width,fatbits.y+fatbits.height); X color = (XGetPixel(draw.buffer, X CurrentWindow->img_offx+fatbits.x+x, X fatbits.y+y) X == CurrentWindow->white) ? X CurrentWindow->black : CurrentWindow->white; X } X X if (color==CurrentWindow->white) { X if (go) X XFillRectangle(CurrentWindow->display,draw.window, X CurrentWindow->gc,x*6,y*6,5,5); X XDrawPoint(CurrentWindow->display,draw.window, X CurrentWindow->gc,x,y); X } else { X if (go) X XFillRectangle(CurrentWindow->display,draw.window, X CurrentWindow->igc,x*6,y*6,5,5); X XDrawPoint(CurrentWindow->display,draw.window, X CurrentWindow->igc,x,y); X } X PUT_C_PIXEL(color,fatbits.x+x,fatbits.y+y); X} X XTrackFatHand(flag,x,y) Xint flag,x,y; X{ X static int xstart,ystart; X static int orig_offx,orig_offy; X int dx,dy; X int ddx,ddy; X long pix; X int xp,yp; X X x = x/6; X y = y/6; X if (flag) { X xstart = x; X ystart = y; X orig_offx = fatbits.x; X orig_offy = fatbits.y; X return; X } X X dx = xstart-x; X dy = ystart-y; X X if ((CurrentWindow->img_offx+orig_offx+dx)<0) { X dx = -(orig_offx+CurrentWindow->img_offx); X } X if ((orig_offx+dx+fatbits.width)>CurrentWindow->img_width) { X dx=CurrentWindow->img_width-fatbits.width-orig_offx; X } X if ((CurrentWindow->img_offy+orig_offy+dy)<0) { X dy = -(orig_offy+CurrentWindow->img_offy); X } X if ((orig_offy+dy+fatbits.height)>CurrentWindow->img_height) { X dy=CurrentWindow->img_height-fatbits.height-orig_offy; X } X X ddx = fatbits.x; X ddy = fatbits.y; X X fatbits.x = dx + orig_offx; X dx = ddx - fatbits.x ; X X XClearArea(CurrentWindow->display,draw.window, X 0,0,fatbits.width+6-fatbits.width%6, X fatbits.height+6-fatbits.height%6,False); X for (yp=0;yp<((fatbits.height+5)/6);yp++) { X for (xp=0;xp<((fatbits.width+5)/6);xp++) { X pix = XGetPixel(CurrentWindow->master, X CurrentWindow->img_offx+fatbits.x+xp, X CurrentWindow->img_offy+fatbits.y+yp); X if (pix!=CurrentWindow->white) X XFillRectangle(CurrentWindow->display, X draw.window,CurrentWindow->igc, X xp*6,yp*6,5,5); X } X } X X if (SIGN(dx) == -1) { X XCopyArea(CurrentWindow->display,draw.window, X draw.window,draw.gc, X -dx*6,0, X (fatbits.width+dx)*6, X draw.height, X 0,0); X XClearArea(CurrentWindow->display,draw.window, X (fatbits.width+dx-1)*6,0,(-dx+1)*6,draw.height,False); X for (yp=0;yp<fatbits.height;yp++) { X for (xp=fatbits.width+dx-1;xp<fatbits.width;xp++) { X pix = XGetPixel(CurrentWindow->master, X CurrentWindow->img_offx+fatbits.x+xp, X CurrentWindow->img_offy+fatbits.y+yp); X if (pix!=CurrentWindow->white) X XFillRectangle(CurrentWindow->display, X draw.window,CurrentWindow->igc, X xp*6,yp*6,5,5); X } X } X } else if (SIGN(dx) == 1) { X XCopyArea(CurrentWindow->display,draw.window, X draw.window,draw.gc, X 0,0, X (fatbits.width-dx)*6, X draw.height, X dx*6,0); X XClearArea(CurrentWindow->display,draw.window, X 0,0,dx*6,draw.height,False); X for (yp=0;yp<fatbits.height;yp++) { X for (xp=0;xp<dx;xp++) { X pix = XGetPixel(CurrentWindow->master, X CurrentWindow->img_offx+fatbits.x+xp, X CurrentWindow->img_offy+fatbits.y+yp); X if (pix!=CurrentWindow->white) X XFillRectangle(CurrentWindow->display, X draw.window,CurrentWindow->igc, X xp*6,yp*6,5,5); X } X } X } X X fatbits.y = dy + orig_offy; X dy = ddy - fatbits.y; X if (SIGN(dy) == -1) { X XCopyArea(CurrentWindow->display,draw.window, X draw.window,draw.gc, X 0,-dy*6, X draw.width, X (fatbits.height+dy)*6, X 0,0); X XClearArea(CurrentWindow->display,draw.window, X 0,(fatbits.height+dy-1)*6,draw.width,(-dy+1)*6,False); X for (yp=fatbits.height+dy-1;yp<fatbits.height;yp++) { X for (xp=0;xp<fatbits.width;xp++) { X pix = XGetPixel(CurrentWindow->master, X CurrentWindow->img_offx+fatbits.x+xp, X CurrentWindow->img_offy+fatbits.y+yp); X if (pix!=CurrentWindow->white) X XFillRectangle(CurrentWindow->display, X draw.window,CurrentWindow->igc, X xp*6,yp*6,5,5); X } X } X } else if (SIGN(dy) == 1) { X XCopyArea(CurrentWindow->display,draw.window, X draw.window,draw.gc, X 0,0, X draw.width, X (fatbits.height-dy)*6, X 0,dy*6); X XClearArea(CurrentWindow->display,draw.window, X 0,0,draw.width,dy*6,False); X for (yp=0;yp<dy;yp++) { X for (xp=0;xp<fatbits.width;xp++) { X pix = XGetPixel(CurrentWindow->master, X CurrentWindow->img_offx+fatbits.x+xp, X CurrentWindow->img_offy+fatbits.y+yp); X if (pix!=CurrentWindow->white) X XFillRectangle(CurrentWindow->display, X draw.window,CurrentWindow->igc, X xp*6,yp*6,5,5); X } X } X } X X XPutImage(CurrentWindow->display,draw.window, X draw.gc,CurrentWindow->master, X CurrentWindow->img_offx+fatbits.x, X CurrentWindow->img_offy+fatbits.y, X 0,0,fatbits.width,fatbits.height); X} X XTrackHand(flag,x,y) Xint flag,x,y; X{ X static int xstart,ystart; X static int orig_offx,orig_offy; X int dx,dy; X int ddx,ddy; X X if (flag) { X xstart=x; X ystart=y; X orig_offx = CurrentWindow->img_offx; X orig_offy = CurrentWindow->img_offy; X return; X } X dx = xstart-x; X dy = ystart-y; X if ((orig_offx+dx)<0) { X dx = - orig_offx; X } X if ((orig_offx+dx+draw.width)>CurrentWindow->img_width) { X dx=CurrentWindow->img_width-draw.width-orig_offx; X } X if ((orig_offy+dy)<0) { X dy = - orig_offy; X } X if ((orig_offy+dy+draw.height)> X CurrentWindow->img_height) { X dy=CurrentWindow->img_height-draw.height-orig_offy; X } X X ddx = CurrentWindow->img_offx ; X ddy = CurrentWindow->img_offy ; X X CurrentWindow->img_offx = dx + orig_offx; X dx = ddx - CurrentWindow->img_offx; X X if (SIGN(dx) == -1) { X XCopyArea(CurrentWindow->display,draw.window, X draw.window,draw.gc, X -dx,0, X draw.width+dx, X draw.height, X 0,0); X XPutImage(CurrentWindow->display,draw.window, X draw.gc,CurrentWindow->master, X CurrentWindow->img_offx+draw.width+dx-1, X CurrentWindow->img_offy, X draw.width+dx-1,0, X -dx,draw.height); X } else if (SIGN(dx) == 1) { X XCopyArea(CurrentWindow->display,draw.window, X draw.window,draw.gc, X 0,0, X draw.width-dx, X draw.height, X dx,0); X XPutImage(CurrentWindow->display,draw.window, X draw.gc,CurrentWindow->master, X CurrentWindow->img_offx,CurrentWindow->img_offy, X 0,0, X dx,draw.height); X } X X CurrentWindow->img_offy = dy + orig_offy; X dy = ddy - CurrentWindow->img_offy; X if (SIGN(dy) == -1) { X XCopyArea(CurrentWindow->display,draw.window, X draw.window,draw.gc, X 0,-dy, X draw.width, X draw.height+dy, X 0,0); X XPutImage(CurrentWindow->display,draw.window, X draw.gc,CurrentWindow->master, X CurrentWindow->img_offx, X CurrentWindow->img_offy+draw.height+dy-1, X 0,draw.height+dy-1, X draw.width,-dy); X } else if (SIGN(dy) == 1) { X XCopyArea(CurrentWindow->display,draw.window, X draw.window,draw.gc, X 0,0, X draw.width, X draw.height-dy, X 0,dy); X XPutImage(CurrentWindow->display,draw.window, X draw.gc,CurrentWindow->master, X CurrentWindow->img_offx,CurrentWindow->img_offy, X 0,0, X draw.width,dy); X } X} X XFlickerDot() X{ X static int val = 1; X int xs=buf_xs; X int ys=buf_ys; X int xe=buf_xe-1; X int ye=buf_ye-1; X int w=xe-xs; X int h=ye-ys; X X if (val==3) X val=0; X val++; X} X XDoneDotBox() X{ X select_buffer.width = buf_xe - buf_xs; X select_buffer.height = buf_ye - buf_ys; X select_buffer.xs = buf_xs+CurrentWindow->img_offx; X select_buffer.xorig = select_buffer.x = buf_xs; X select_buffer.yorig = select_buffer.y = buf_ys; X X bcopy(CurrentWindow->master->data+ X ((CurrentWindow->img_offy+buf_ys)* X CurrentWindow->master->bytes_per_line), X select_buffer.image->data, X select_buffer.image->bytes_per_line*select_buffer.height); X X XPutImage(CurrentWindow->display,draw.window, X draw.gc,CurrentWindow->master, X CurrentWindow->img_offx+buf_xs, X CurrentWindow->img_offy+buf_ys, X buf_xs,buf_ys, X buf_xe-buf_xs,buf_ye-buf_ys); X FillRectangle(select_buffer.x,select_buffer.y, X select_buffer.width,select_buffer.height,CurrentWindow->white); X FlushBuffer(); X X dot_flag=TRUE; X SetAction(C_ARROW); X dot_inter_id = AddInterrupt(FlickerDot); X} X XOnGraphic(act,event) Xint act; XXEvent *event; X{ X XEvent fake_event; X X if (fatbits.flag) { X X if (Between(0,event->xbutton.x,fatbits.width) && X Between(0,event->xbutton.y,fatbits.height)) { X fatbits.flag = FALSE; X fake_event.type = Expose; X fake_event.xexpose.x = 0; X fake_event.xexpose.y = 0; X fake_event.xexpose.width = draw.width; X fake_event.xexpose.height = draw.height; X EventDraw(&fake_event); X return; X } X } X X if (fatbits.flag) { X switch (act) { X case C_HAND: X Go(event,TrackFatHand,NULL,TRUE); X break; X default: X Go(event,TrackFatbits,NULL,FALSE); X break; X } X } else { X draw.lastx = event->xbutton.x; X draw.lasty = event->xbutton.y; X switch (act) { X case C_ARROW: X Go(event,TrackArrow,NULL,TRUE); X break; X case C_HAND: X Go(event,TrackHand,NULL,TRUE); X break; X case C_DOTBOX: X Go(event,TrackDotBox,DoneDotBox,TRUE); X break; X case C_SCISSORS: X break; X case C_LINE: X Go(event,TrackLine,NULL,TRUE); X break; X case C_ARBLINE: X Go(event,TrackArbLine,NULL,FALSE); X break; X case C_RECTANGLE: X Go(event,TrackRectangle,NULL,TRUE); X break; X case C_ELIPSE: X Go(event,TrackEllipse,NULL,TRUE); X break; X case C_RECTF: X Go(event,TrackRectfill,NULL,TRUE); X break; X case C_ELIPF: X Go(event,TrackEllipfill,NULL,TRUE); X break; X case C_POLYGON: X break; X case C_FILL: X break; X case C_BRUSH: X Go(event,TrackBrush,NULL,FALSE); X break; X case C_ERASER: X Go(event,TrackEraser,NULL,FALSE); X break; X case C_TEXT: X GoText(event); X break; X case C_SPRAY: X Go(event,TrackSpray,NULL,FALSE); X break; X } X } X} X XGo(event,track_func,done_func,flag) XXEvent *event; Xint (*track_func)(); Xint (*done_func)(); Xint flag; X{ X XEvent new_event,tmp_event; X int called=FALSE; X X if ((CurrentActionID != C_ARROW) || (fatbits.flag)) X FlushBuffer(); X X if (track_func!=NULL) X track_func(TRUE,event->xbutton.x,event->xbutton.y); X X do { X XWindowEvent(CurrentWindow->display,draw.window, X ButtonReleaseMask|PointerMotionMask,&new_event); X if (new_event.type == MotionNotify) { X if ((flag) && XCheckWindowEvent(CurrentWindow->display, X draw.window, X PointerMotionMask,&tmp_event)) { X XPutBackEvent(CurrentWindow->display, X &tmp_event); X continue; X } X if (Between(0,new_event.xbutton.x, X draw.width) && X Between(0,new_event.xbutton.y, X draw.height) && X (track_func!=NULL)) X track_func(FALSE,new_event.xmotion.x, X new_event.xmotion.y); X called=TRUE; X } X } while (!((new_event.type == ButtonRelease) && X (new_event.xbutton.button == event->xbutton.button))); X X if ((!called) && (track_func!=NULL)) { X track_func(FALSE,event->xbutton.x, X event->xbutton.y); X } X X if (done_func!=NULL) X done_func(); X} X XDrawSetFont(id,text) Xint id; Xchar *text; X{ X XFontStruct *font_info; X X font_info = XLoadQueryFont(CurrentWindow->display,text); X if (font_info != NULL) { X XUnloadFont(CurrentWindow->display,draw.font_info->fid); X draw.font_info = font_info; X XSetFont(CurrentWindow->display,draw.gc,font_info->fid); X } X} X XGoText(old_event) XXEvent *old_event; X{ X static char str[1024]; X int index=0; X long pix; X XImage *img; X int done=FALSE; X int xstart,ystart; X int i,n,height; X int x,y; X int maxx,maxy; X XEvent event; X char buf[80]; X int xpos,ypos; X X FlushBuffer(); X GetBuffer(0,0,draw.width,draw.height); X xpos = xstart = old_event->xbutton.x; X ypos = (ystart = old_event->xbutton.y)+draw.font_info->ascent; X maxx=xstart; X maxy=ystart; X height = draw.font_info->ascent+draw.font_info->descent; X X do { X WindowEvent(draw.window,&event); X switch (event.type) { X case Expose: X EventDraw(&event); X break; X case MotionNotify: X break; X case ButtonPress: X done=TRUE; X break; X case KeyPress: X n=XLookupString(&event,buf,sizeof(buf),NULL,NULL); X for (i=0;i<n;i++) { X switch (buf[i]) { X case '\r': X case '\n': X xpos=xstart; X ypos+=height; X break; X case CTRL('U'): X break; X case DELETE: X case CTRL('H'): X break; X default: X if (buf[i]>=' ') { X str[index++]=buf[i]; X XDrawString( X CurrentWindow->display, X draw.window,draw.gc, X xpos,ypos, X &buf[i],1); X xpos+=XTextWidth(draw.font_info, X &buf[i],1); X } X } X if (xpos>maxx) maxx=xpos; X if (ypos>maxy) maxy=ypos; X } X break; X } X } while (!done); X X img = XGetImage(CurrentWindow->display,draw.window, X xstart,ystart,maxx-xstart,maxy-ystart,-1,ZPixmap); X for (y=0;y<maxy-ystart;y++) X for (x=0;x<maxx-xstart;x++) { X pix = XGetPixel(img,x,y); X XPutPixel(draw.buffer, X xstart+x+CurrentWindow->img_offx,ystart+y,pix); X } X XDestroyImage(img); X OnGraphic(CurrentActionID,&event); X} X X/****************************************************************************/ X/****************************************************************************/ X/****************************************************************************/ X/****************************************************************************/ X/****************************************************************************/ X XDrawLine(xstart,ystart,xend,yend,color) Xint xstart,ystart,xend,yend; Xlong color; X{ X int x=xstart,y=ystart; X int dx=ABS(xend-xstart),dy=ABS(yend-ystart); X int sx=SIGN(xend-xstart),sy=SIGN(yend-ystart); X int interchange=0; X int e,i; X X if ((xstart==xend) && (yend==ystart)) { X PUT_PIXEL(xstart,ystart); X return; X } X X if (dy>dx) { X int t=dx; X dx = dy; X dy = t; X interchange = 1; X } X e=2*dy-dx; X for (i=0;i<dx;i++) { X PUT_C_PIXEL(color,x,y); X while (e>=0) { X if (interchange!=0) { X x=x+sx; X } else { X y=y+sy; X } X e=e-2*dx; X } X if (interchange!=0) { X y=y+sy; X } else { X x=x+sx; X } X e=e+2*dy; X } X} X X/* X * Draw an ellipse. X * X * The algorithm is from "An Efficient Ellipse-Drawing Algorithm" by X * Jerry R. Van Aken, IEEE CG&A, September 1984, pp. 24-35, X * specifically, Figure 10 on page 32. X */ X XDrawEllipse(xs,ys,width,height) Xint xs,ys,width,height; X{ X int a = width/2, b=height/2; X int cx = xs+a, cy=ys+b; X int d1,d2; X int x,y; X int t1,t2,t3,t4,t5,t6,t7,t8,t9; X X /* intermediate terms to speed up loop */ X t1 = a * a; t2 = t1 * 2; t3 = t2 * 2; X t4 = b * b; t5 = t4 * 2; t6 = t5 * 2; X t7 = a * t5; t8 = t7 * 2; t9 = 0; X X d1 = t2-t7+(t4/2); /* error terms */ X d2 = (t2/2)-t8+t5; X X x = a; X y = 0; X X while (d2 < 0 ) { X PUT_PIXEL(cx+x,cy+y); X PUT_PIXEL(cx+x,cy-y); X PUT_PIXEL(cx-x,cy+y); X PUT_PIXEL(cx-x,cy-y); X y++; X t9 += t3; X if (d1<0) { X d1 += t9+t2; X d2 += t9; X } else { X x--; X t8 -= t6; X d1 += t9+t2-t8; X d2 += t9+t5-t8; X } X } X do { X PUT_PIXEL(cx+x,cy+y); X PUT_PIXEL(cx+x,cy-y); X PUT_PIXEL(cx-x,cy+y); X PUT_PIXEL(cx-x,cy-y); X x--; X t8-=t6; X if (d2<0) { X y++; X t9 += t3; X d2 += t9+t5-t8; X } else { X d2 += t5-t8; X } X } while (x>=0); X} X XDrawFillEllipse(xs,ys,width,height) Xint xs,ys,width,height; X{ X int a = width/2, b=height/2; X int cx = xs+a, cy=ys+b, yp; X int d1,d2; X int x,y; X int t1,t2,t3,t4,t5,t6,t7,t8,t9; X X /* intermediate terms to speed up loop */ X t1 = a * a; t2 = t1 * 2; t3 = t2 * 2; X t4 = b * b; t5 = t4 * 2; t6 = t5 * 2; X t7 = a * t5; t8 = t7 * 2; t9 = 0; X X d1 = t2-t7+(t4/2); /* error terms */ X d2 = (t2/2)-t8+t5; X X x = a; X y = 0; X X while (d2 < 0 ) { X PUT_P_PIXEL(cx+x,cy+y); X PUT_P_PIXEL(cx+x,cy-y); X PUT_P_PIXEL(cx-x,cy+y); X PUT_P_PIXEL(cx-x,cy-y); X y++; X t9 += t3; X if (d1<0) { X d1 += t9+t2; X d2 += t9; X } else { X for (yp=cy-y-1;yp<cy+y;yp++) { X PUT_P_PIXEL(cx+x,yp); X PUT_P_PIXEL(cx-x,yp); X } X x--; X t8 -= t6; X d1 += t9+t2-t8; X d2 += t9+t5-t8; X } X } X do { X for (yp=cy-y;yp<=cy+y;yp++) { X PUT_P_PIXEL(cx+x,yp); X PUT_P_PIXEL(cx-x,yp); X } X x--; X t8-=t6; X if (d2<0) { X y++; X t9 += t3; X d2 += t9+t5-t8; X } else { X d2 += t5-t8; X } X } while (x>=0); X} X XDrawRectangle(xs,ys,width,height,flag,dot) Xint xs,ys,width,height,flag,dot; X{ X int xp,yp; X int xe=xs+width,ye=ys+height; X X if (!flag) { X if (dot == 0) { X for (xp=xs;xp<xe;xp++) { X PUT_PIXEL(xp,ye); X PUT_PIXEL(xp,ys); X } X for (yp=ys;yp<ye;yp++) { X PUT_PIXEL(xs,yp); X PUT_PIXEL(xe,yp); X } X PUT_PIXEL(xe,ye); X } else { X for (xp=xs+dot;xp<xe;xp+=3) { X PUT_PIXEL(xp,ye); X PUT_PIXEL(xp,ys); X } X for (yp=ys+dot;yp<ye;yp+=3) { X PUT_PIXEL(xs,yp); X PUT_PIXEL(xe,yp); X } X } X } else { X for (yp=ys;yp<ye;yp++) { X for (xp=xs;xp<xe;xp++) { X PUT_P_PIXEL(xp,yp); X } X } X } X} X XFillRectangle(xs,ys,width,height,color) Xint xs,ys,width,height; Xlong color; X{ X int xp,yp; X int xe=xs+width,ye=ys+height; X X for (xp=xs;xp<xe;xp++) X for (yp=ys;yp<ye;yp++) X PUT_C_PIXEL(color,xp,yp); X} END_OF_FILE if test 36994 -ne `wc -c <'draw.c'`; then echo shar: \"'draw.c'\" unpacked with wrong size! fi # end of 'draw.c' fi if test -f 'menu.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'menu.c'\" else echo shar: Extracting \"'menu.c'\" \(11231 characters\) sed "s/^X//" >'menu.c' <<'END_OF_FILE' X/* +------------------------------------------------------------------+ */ X/* | Copyright 1989, David Koblas. | */ X/* | You may copy this file in whole or in part as long as you | */ X/* | don't try to make money off it, or pretend that you wrote it. | */ X/* +------------------------------------------------------------------+ */ X X#include <stdio.h> X#include "xpaint.h" X X#define MAX(a,b) (((a)<(b))?(b):(a)) X Xstatic GC menu_gc,menu_igc; Xstatic XFontStruct *font_info; Xstatic Window item_window; Xstatic Pixmap buf_pixmap; Xstatic int buf_xs,buf_ys; X Xstatic void bogus_func() { ; } X Xvoid DrawUndo(); Xvoid Quit(); Xvoid DrawSetFont(); Xvoid DrawBufferInvert(),DrawFlipHorz(),DrawFlipVert(); Xvoid SaveMenu(),SaveMenuAs(); Xvoid SaveRegion(),CloseDraw(),OpenFile(),OpenDraw(); X X#ifndef lint Xstatic char rcsid[]="$Header: menu.c,v 1.2 89/02/20 19:32:59 koblas Locked $"; X#endif X Xstruct s_menu_items { X int id; X char *text; X int state; X void (*func)(); X}; X Xstruct s_menu_items file_items[] = { X {0, "Open", TRUE, OpenDraw}, X {0, "Close", TRUE, CloseDraw}, X {0, "Read", TRUE, OpenFile}, X {0, "Save", TRUE, SaveMenu}, X {0, "Save As", TRUE, SaveMenuAs}, X {0, "Save Region", TRUE, SaveRegion}, X {0, "Quit", TRUE , Quit}, X}; X Xstruct s_menu_items buffer_items[] = { X {0, "Undo", TRUE, DrawUndo}, X {0, "-", TRUE, NULL}, X {0, "Cut", TRUE, bogus_func}, X {0, "Copy", TRUE, bogus_func}, X {0, "Clear", TRUE, bogus_func}, X {0, "Invert", TRUE, DrawBufferInvert}, X {0, "Flip Horz.", TRUE, DrawFlipHorz}, X {0, "Flip Vert.", TRUE, DrawFlipVert}, X}; X Xstruct s_menu_items font_items[] = { X {0, "6x10", TRUE, DrawSetFont}, X {1, "6x12", TRUE, DrawSetFont}, X {2, "8x13", TRUE, DrawSetFont}, X {3, "8x13bold", TRUE, DrawSetFont}, X {4, "9x15", TRUE, DrawSetFont}, X {5, "cursor", TRUE, DrawSetFont}, X {6, "gallant.r.10", TRUE, DrawSetFont}, X {7, "gallant.r.19", TRUE, DrawSetFont}, X {8, "cmr.b.14", TRUE, DrawSetFont}, X {9, "cmr.b.8", TRUE, DrawSetFont}, X {10, "cmr.r.14", TRUE, DrawSetFont}, X {11, "cmr.r.8", TRUE, DrawSetFont}, X {12, "apl.r.10", TRUE, DrawSetFont}, X {13, "variable", TRUE, DrawSetFont}, X}; X Xstruct { X char *title; X int xstart,xend,width; X int item_width; X int item_height; X int n_items; X struct s_menu_items *items; X} menu[] = { X { "File", 0, 0, 0, 0, 0, X sizeof(file_items)/sizeof(file_items[0]), file_items }, X { "Buffer", 0, 0, 0, 0, 0, X sizeof(buffer_items)/sizeof(buffer_items[0]), buffer_items }, X { "Font", 0, 0, 0, 0, 0, X sizeof(font_items)/sizeof(font_items[0]), font_items }, X}; X X#define PAD 15 X#define HEIGHT 15 X XWindow CreateMenu() X{ X int i,w,x,j; X int max_w=0,max_h=0; X XSetWindowAttributes attr; X Window wind; X XGCValues values; X X attr.background_pixel = CurrentWindow->white; X attr.event_mask = ExposureMask|ButtonPressMask| X ButtonReleaseMask|PointerMotionMask; X X wind = XCreateWindow(CurrentWindow->display,CurrentWindow->window, X DELTA_XPOS(MENU_ID),DELTA_YPOS(MENU_ID), X CurrentWindow->width,HEIGHT, X 0,0,0,0,CWBackPixel|CWEventMask,&attr); X X item_window = XCreateWindow(CurrentWindow->display, X CurrentWindow->window, X DELTA_XPOS(MENU_ID),DELTA_YPOS(MENU_ID), X 1,1,0,0,0,0,CWBackPixel|CWEventMask,&attr); X X values.foreground = CurrentWindow->white; X values.background = CurrentWindow->black; X font_info = XLoadQueryFont(CurrentWindow->display,DEF_FONT); X if (font_info == NULL) { X fprintf(stderr,"Unable to open font %s\n",DEF_FONT); X exit(1); X } X values.font = font_info->fid; X X menu_igc = XCreateGC(CurrentWindow->display,wind, X GCForeground|GCBackground|GCFont,&values); X X values.foreground = CurrentWindow->black; X values.background = CurrentWindow->white; X menu_gc = XCreateGC(CurrentWindow->display,wind, X GCForeground|GCBackground|GCFont,&values); X X XMapWindow(CurrentWindow->display,wind); X X x=PAD; X for (i=0;i<sizeof(menu)/sizeof(menu[0]);i++) { X menu[i].xstart = x; X menu[i].width = XTextWidth(font_info,menu[i].title, X strlen(menu[i].title)); X menu[i].xend = x+menu[i].width; X x += menu[i].width+PAD; X X for (j=0;j<menu[i].n_items;j++) { X w=XTextWidth(font_info,menu[i].items[j].text, X strlen(menu[i].items[j].text)); X menu[i].item_width=MAX(w+10,menu[i].item_width); X } X menu[i].item_height = (font_info->max_bounds.ascent+ X font_info->max_bounds.descent)* X menu[i].n_items; X max_w=MAX(menu[i].item_width,max_w); X max_h=MAX(menu[i].item_height,max_h); X } X X buf_pixmap = XCreatePixmap(CurrentWindow->display, X CurrentWindow->window,max_w,max_h, X CurrentWindow->depth); X X return wind; X} X Xvoid ResizeMenu() X{ X XResizeWindow(CurrentWindow->display, X CurrentWindow->subwind[MENU_ID].window, X CurrentWindow->width,HEIGHT); X} X Xvoid EventMenu(event) XXEvent *event; X{ X switch (event->type) { X case Expose: X redraw(); X break; X case ButtonPress: X track_mouse(event); X break; X } X} X Xstatic redraw() X{ X int i; X X for (i=0;i<sizeof(menu)/sizeof(menu[0]);i++) { X XDrawImageString(CurrentWindow->display, X CurrentWindow->subwind[MENU_ID].window, X menu_gc,menu[i].xstart,font_info->ascent, X menu[i].title,strlen(menu[i].title)); X } X} X Xstatic track_mouse(event) XXEvent *event; X{ X XEvent new_event; X int i; X int xpos,ypos; X int active_menu= -1,new_active_menu= -1; X int active_item= -1,new_active_item= -1; X X xpos = event->xbutton.x; X ypos = event->xbutton.y; X X X do { X if (ypos<HEIGHT) { X new_active_menu = -1; X for (i=0;i<sizeof(menu)/sizeof(menu[0]);i++) { X if (Between(menu[i].xstart-5, X xpos,menu[i].xend+5)) { X new_active_menu = i; X } X } X new_active_item = -1; X } else if (active_menu != -1) { X if ((ypos-HEIGHT)<menu[active_menu].item_height) { X new_active_item = (ypos-HEIGHT)/ X (font_info->max_bounds.ascent+ X font_info->max_bounds.descent); X } else { X new_active_item = -1; X } X if ((menu[active_menu].items[new_active_item].func == NULL) || X (menu[active_menu].items[new_active_item].state == FALSE)) X new_active_item = -1; X } X X if (new_active_menu != active_menu) { X if (active_menu != -1) { X XUnmapWindow(CurrentWindow->display,item_window); X XFillRectangle(CurrentWindow->display, X CurrentWindow->subwind[MENU_ID].window, X menu_igc,menu[active_menu].xstart-5, X 0,menu[active_menu].width+10,HEIGHT); X XDrawImageString(CurrentWindow->display, X CurrentWindow->subwind[MENU_ID].window, X menu_gc,menu[active_menu].xstart, X font_info->ascent, X menu[active_menu].title, X strlen(menu[active_menu].title)); X XFlush(CurrentWindow->display); X } X active_menu = new_active_menu; X if (active_menu != -1) { X buf_xs = menu[active_menu].xstart-5; X buf_ys = HEIGHT; X XMoveResizeWindow(CurrentWindow->display, X item_window,menu[active_menu].xstart-5, X HEIGHT,menu[active_menu].item_width, X menu[active_menu].item_height); X XMapWindow(CurrentWindow->display,item_window); X XFillRectangle(CurrentWindow->display, X CurrentWindow->subwind[MENU_ID].window, X menu_gc,menu[active_menu].xstart-5, X 0,menu[active_menu].width+10,HEIGHT); X XDrawImageString(CurrentWindow->display, X CurrentWindow->subwind[MENU_ID].window, X menu_igc,menu[active_menu].xstart, X font_info->ascent, X menu[active_menu].title, X strlen(menu[active_menu].title)); X XFlush(CurrentWindow->display); X WindowEvent(item_window,&new_event); X for (i=0;i<menu[active_menu].n_items;i++) { X PutMenuItem(FALSE,active_menu,i); X } X } X } X X if ((active_menu != -1) && (new_active_item != active_item)) { X if (active_item != -1) { X PutMenuItem(FALSE,active_menu,active_item); X#if 0 X XFillRectangle(CurrentWindow->display, X item_window,menu_igc,0,active_item* X (font_info->max_bounds.ascent+ X font_info->max_bounds.descent), X menu[active_menu].item_width+10, X (font_info->max_bounds.ascent+ X font_info->max_bounds.descent)); X XDrawImageString(CurrentWindow->display, X item_window, X menu_gc,5, X font_info->ascent+active_item* X (font_info->max_bounds.ascent+ X font_info->max_bounds.descent), X menu[active_menu]. X items[active_item].text, X strlen(menu[active_menu]. X items[active_item].text)); X#endif X } X active_item = new_active_item; X if (active_item != -1) { X PutMenuItem(TRUE,active_menu,active_item); X#if 0 X XFillRectangle(CurrentWindow->display, X item_window,menu_gc,0,active_item* X (font_info->max_bounds.ascent+ X font_info->max_bounds.descent), X menu[active_menu].item_width+10, X (font_info->max_bounds.ascent+ X font_info->max_bounds.descent)); X XDrawImageString(CurrentWindow->display, X item_window, X menu_igc,5, X font_info->ascent+active_item* X (font_info->max_bounds.ascent+ X font_info->max_bounds.descent), X menu[active_menu]. X items[active_item].text, X strlen(menu[active_menu]. X items[active_item].text)); X XFlush(CurrentWindow->display); X#endif X } X } X X WindowEvent(CurrentWindow->subwind[MENU_ID].window,&new_event); X if (new_event.type == MotionNotify) { X xpos = new_event.xmotion.x; X ypos = new_event.xmotion.y; X } X } while (!((new_event.type == ButtonRelease) && X (new_event.xbutton.button == event->xbutton.button))); X X if (active_menu != -1) { X XUnmapWindow(CurrentWindow->display,item_window); X XFillRectangle(CurrentWindow->display, X CurrentWindow->subwind[MENU_ID].window, X menu_igc,menu[active_menu].xstart-5, X 0,menu[active_menu].width+10,HEIGHT); X XDrawImageString(CurrentWindow->display, X CurrentWindow->subwind[MENU_ID].window, X menu_gc,menu[active_menu].xstart, X font_info->ascent, X menu[active_menu].title, X strlen(menu[active_menu].title)); X if (active_item != -1) { X menu[active_menu].items[active_item].func( X menu[active_menu].items[active_item].id, X menu[active_menu].items[active_item].text); X } X } X} X Xstatic PutMenuItem(flag,menu_num,item) Xint flag,menu_num,item; X{ X GC gc,igc; X X if (flag) { X gc=menu_igc; X igc=menu_gc; X } else { X igc=menu_igc; X gc=menu_gc; X } X X X XFillRectangle(CurrentWindow->display,item_window,igc,0, X item*(font_info->max_bounds.ascent+ X font_info->max_bounds.descent), X menu[menu_num].item_width+10, X (font_info->max_bounds.ascent+ X font_info->max_bounds.descent)); X X if ((menu[menu_num].items[item].text[0]=='-') && X (menu[menu_num].items[item].text[1]=='\0')) { X XDrawLine(CurrentWindow->display,item_window,gc, X 0,((font_info->max_bounds.ascent+ X font_info->max_bounds.descent)/2)+ X (item*(font_info->max_bounds.ascent+ X font_info->max_bounds.descent)), X menu[menu_num].item_width, X ((font_info->max_bounds.ascent+ X font_info->max_bounds.descent)/2)+ X (item*(font_info->max_bounds.ascent+ X font_info->max_bounds.descent))); X return; X } X XDrawString(CurrentWindow->display,item_window,gc,5, X font_info->max_bounds.ascent+ X item*(font_info->max_bounds.ascent+ X font_info->max_bounds.descent), X menu[menu_num].items[item].text, X strlen(menu[menu_num].items[item].text)); X} END_OF_FILE if test 11231 -ne `wc -c <'menu.c'`; then echo shar: \"'menu.c'\" unpacked with wrong size! fi # end of 'menu.c' fi if test -f 'pat_09.xbm' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'pat_09.xbm'\" else echo shar: Extracting \"'pat_09.xbm'\" \(949 characters\) sed "s/^X//" >'pat_09.xbm' <<'END_OF_FILE' X#define pattern_09_width 32 X#define pattern_09_height 32 X#define pattern_09_x_hot -1 X#define pattern_09_y_hot -1 Xstatic char pattern_09_bits[] = { X 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, X 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, X 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0xff, 0xff, 0xff, 0xff, X 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, X 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, X 0x00, 0x01, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x01, 0x00, X 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, X 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, X 0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, X 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, X 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01}; END_OF_FILE if test 949 -ne `wc -c <'pat_09.xbm'`; then echo shar: \"'pat_09.xbm'\" unpacked with wrong size! fi # end of 'pat_09.xbm' fi echo shar: End of archive 1 \(of 3\). cp /dev/null ark1isdone MISSING="" for I in 1 2 3 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 3 archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- Mike Wexler(wyse!mikew) Phone: (408)433-1000 x1330 Moderator of comp.sources.x