mikew@wyse.wyse.com (Mike Wexler) (02/23/89)
Submitted-by: koblas@mips.com (David Koblas) Posting-number: Volume 3, Issue 32 Archive-name: xpaint/part02 #! /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 2 (of 3)." # Contents: Makefile ReadXBM.c action.c bitedit.c event.c main.c # pattern.c save.c # Wrapped by mikew@wyse on Wed Feb 22 13:37:41 1989 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'Makefile' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Makefile'\" else echo shar: Extracting \"'Makefile'\" \(6768 characters\) sed "s/^X//" >'Makefile' <<'END_OF_FILE' X# Makefile generated by imake - do not edit! X# $XConsortium: imake.c,v 1.37 88/10/08 20:08:30 jim Exp $ X# X# The cpp used on this machine replaces all newlines and multiple tabs and X# spaces in a macro expansion with a single space. Imake tries to compensate X# for this, but is not always successful. X# X X########################################################################### X# X Window System Makefile generated from template file Imake.tmpl X# $XConsortium: Imake.tmpl,v 1.91 88/10/23 22:37:10 jim Exp $ X# X# Do not change the body of the imake template file. Server-specific X# parameters may be set in the appropriate .macros file; site-specific X# parameters (but shared by all servers) may be set in site.def. If you X# make any changes, you'll need to rebuild the makefiles using X# "make World" (at best) or "make Makefile; make Makefiles" (at least) in X# the top level directory. X# X# If your C preprocessor doesn't define any unique symbols, you'll need X# to set BOOTSTRAPCFLAGS when rebuilding imake (usually when doing X# "make Makefile", "make Makefiles", or "make World"). X# X# If you absolutely can't get imake to work, you'll need to set the X# variables at the top of each Makefile as well as the dependencies at the X# bottom (makedepend will do this automatically). X# X X########################################################################### X# platform-specific configuration parameters - edit Sun.macros to change X X# platform: $XConsortium: Sun.macros,v 1.52 88/10/23 11:00:55 jim Exp $ X# operating system: SunOS 3.4 X XBOOTSTRAPCFLAGS = X AS = as X CC = cc X CPP = /lib/cpp X LD = ld X LINT = lint X INSTALL = install X TAGS = ctags X RM = rm -f X MV = mv X LN = ln -s X RANLIB = ranlib XRANLIBINSTFLAGS = -t X AR = ar clq X LS = ls X LINTOPTS = -xz X LINTLIBFLAG = -C X MAKE = make XSTD_CPP_DEFINES = X STD_DEFINES = X X########################################################################### X# site-specific configuration parameters - edit site.def to change X X# site: $XConsortium: site.def,v 1.16 88/10/12 10:30:24 jim Exp $ X X########################################################################### X# definitions common to all Makefiles - do not edit X X SHELL = /bin/sh X X DESTDIR = /global X USRLIBDIR = $(DESTDIR)/lib X BINDIR = $(DESTDIR)/bin/X11 X INCDIR = $(DESTDIR)/include X ADMDIR = $(DESTDIR)/usr/adm X LIBDIR = $(USRLIBDIR)/X11 X LINTLIBDIR = $(USRLIBDIR)/lint X FONTDIR = $(LIBDIR)/fonts X XINITDIR = $(LIBDIR)/xinit X XDMDIR = $(LIBDIR)/xdm X UWMDIR = $(LIBDIR)/uwm X AWMDIR = $(LIBDIR)/awm X TWMDIR = $(LIBDIR)/twm X DTDIR = $(LIBDIR)/dt X MANPATH = /usr/man X MANSOURCEPATH = $(MANPATH)/man X MANDIR = $(MANSOURCEPATH)n X LIBMANDIR = $(MANSOURCEPATH)n3 X XAPPLOADDIR = $(LIBDIR)/app-defaults X X INSTBINFLAGS = -m 0755 X INSTUIDFLAGS = -m 4755 X INSTLIBFLAGS = -m 0664 X INSTINCFLAGS = -m 0444 X INSTMANFLAGS = -m 0444 X INSTAPPFLAGS = -m 0444 X INSTKMEMFLAGS = -m 4755 X FCFLAGS = -t X CDEBUGFLAGS = -O X X PATHSEP = / X DEPEND = $(BINDIR)/makedepend X IMAKE = $(BINDIR)/imake X RGB = $(LIBDIR)/rgb X FC = $(BINDIR)/bdftosnf X MKFONTDIR = $(BINDIR)/mkfontdir X MKDIRHIER = $(BINDIR)/mkdirhier.sh X X CFLAGS = $(CDEBUGFLAGS) $(INCLUDES) $(STD_DEFINES) $(DEFINES) X LINTFLAGS = $(LINTOPTS) $(INCLUDES) $(STD_DEFINES) $(DEFINES) -DLINT X LDFLAGS = $(CDEBUGFLAGS) -L$(USRLIBDIR) $(SYS_LIBRARIES) $(SYSAUX_LIBRARIES) X X IRULESRC = $(LIBDIR)/imake.includes X X EXTENSIONLIB = $(USRLIBDIR)/libext.a X XLIB = $(USRLIBDIR)/libX11.a X XMULIB = $(USRLIBDIR)/libXmu.a X OLDXLIB = $(USRLIBDIR)/liboldX.a X XTOOLLIB = $(USRLIBDIR)/libXt.a X XAWLIB = $(USRLIBDIR)/libXaw.a X LINTXLIB = $(USRLIBDIR)/lint/llib-lX11.ln X LINTXMU = $(USRLIBDIR)/lint/llib-lXmu.ln X LINTXTOOL = $(USRLIBDIR)/lint/llib-lXt.ln X LINTXAW = $(USRLIBDIR)/lint/llib-lXaw.ln X INCLUDES = -I$(INCDIR) X MACROFILE = Sun.macros X ICONFIGFILES = $(IRULESRC)/Imake.tmpl \ X $(IRULESRC)/$(MACROFILE) $(IRULESRC)/site.def X IMAKE_DEFINES = X IMAKE_CMD = $(NEWTOP)$(IMAKE) -TImake.tmpl -I$(NEWTOP)$(IRULESRC) \ X -s Makefile $(IMAKE_DEFINES) X RM_CMD = $(RM) *.CKP *.ln *.BAK *.bak *.o core errs ,* *~ *.a \ X .emacs_* tags TAGS make.log MakeOut X X########################################################################### X# rules: $XConsortium: Imake.rules,v 1.71 88/10/23 22:46:34 jim Exp $ X X########################################################################### X# start of Imakefile X X SYS_LIBRARIES = -ll -lm $(XMULIB) $(XLIB) XLOCAL_LIBRARIES = X SRCS = ReadXBM.c draw.c menu.c save.c action.c event.c \ X pattern.c version.c bitedit.c main.c read.c X OBJS = ReadXBM.o draw.o menu.o save.o action.o event.o \ X pattern.o version.o bitedit.o main.o read.o X X PROGRAM = xpaint X Xall:: xpaint X Xxpaint: $(OBJS) $(LOCAL_LIBRARIES) X $(RM) $@ X $(CC) -o $@ $(OBJS) $(LOCAL_LIBRARIES) $(LDFLAGS) $(SYSLAST_LIBRARIES) X Xrelink:: X $(RM) $(PROGRAM) X $(MAKE) $(MFLAGS) $(PROGRAM) X Xinstall:: xpaint X $(INSTALL) -c $(INSTALLFLAGS) xpaint $(BINDIR) X Xinstall.man:: xpaint.man X $(INSTALL) -c $(INSTMANFLAGS) xpaint.man $(MANDIR)/xpaint.n X Xdepend:: $(DEPEND) X Xdepend:: X $(DEPEND) -s "# DO NOT DELETE" -- $(CFLAGS) -- $(SRCS) X X$(DEPEND): X @echo "making $@"; \ X cd $(DEPENDSRC); $(MAKE) X Xclean:: X $(RM) $(PROGRAM) X Xlint: X $(LINT) $(LINTFLAGS) $(SRCS) $(LINTLIBS) Xlint1: X $(LINT) $(LINTFLAGS) $(FILE) $(LINTLIBS) X X########################################################################### X# Imake.tmpl common rules for all Makefiles - do not edit X Xemptyrule:: X Xclean:: X $(RM_CMD) \#* X XMakefile:: $(IMAKE) X XMakefile:: Imakefile \ X $(IRULESRC)/Imake.tmpl \ X $(IRULESRC)/Imake.rules \ X $(IRULESRC)/site.def \ X $(IRULESRC)/$(MACROFILE) X -@if [ -f Makefile ]; then \ X echo "$(RM) Makefile.bak; $(MV) Makefile Makefile.bak"; \ X $(RM) Makefile.bak; $(MV) Makefile Makefile.bak; \ X else exit 0; fi X $(IMAKE_CMD) -DTOPDIR=$(TOP) X X$(IMAKE): X @echo "making $@"; \ X cd $(IMAKESRC); $(MAKE) BOOTSTRAPCFLAGS=$(BOOTSTRAPCFLAGS) X Xtags:: X $(TAGS) -w *.[ch] X $(TAGS) -xw *.[ch] > TAGS X X########################################################################### X# empty rules for directories that do not have SUBDIRS - do not edit X Xinstall:: X @echo "install done" X Xinstall.man:: X @echo "install.man done" X XMakefiles:: X X########################################################################### X# dependencies generated by makedepend X END_OF_FILE if test 6768 -ne `wc -c <'Makefile'`; then echo shar: \"'Makefile'\" unpacked with wrong size! fi # end of 'Makefile' fi if test -f 'ReadXBM.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'ReadXBM.c'\" else echo shar: Extracting \"'ReadXBM.c'\" \(5632 characters\) sed "s/^X//" >'ReadXBM.c' <<'END_OF_FILE' X/* Copyright, 1987, Massachusetts Institute of Technology */ X X#if 0 X#include "copyright.h" X#endif X X/* X * Code to read bitmaps from disk files. Interprets X * data from X10 and X11 bitmap files and creates X * Pixmap representations of files. Returns Pixmap X * ID and specifics about image. X * X * Modified for speedup by Jim Becker, changed image X * data parsing logic (removed some fscanf()s). X * Aug 5, 1988 X * X * Note that this file and ../Xmu/RdBitF.c look very similar.... Keep them X * that way (but don't use common source code so that people can have one X * without the other). X */ X X#include <stdio.h> X#include <ctype.h> X Xtypedef int Bool; X#define True 1 X#define False 0 Xchar *rindex(); X X X#define MAX_SIZE 255 X X/* shared data for the image read/parse logic */ Xstatic short hexTable[256]; /* conversion value */ Xstatic Bool initialized = False; /* easier to fill in at run time */ X X X/* X * Table index for the hex values. Initialized once, first time. X * Used for translation value or delimiter significance lookup. X */ Xstatic void initHexTable() X{ X /* X * We build the table at run time for several reasons: X * X * 1. portable to non-ASCII machines. X * 2. still reentrant since we set the init flag after setting table. X * 3. easier to extend. X * 4. less prone to bugs. X */ X hexTable['0'] = 0; hexTable['1'] = 1; X hexTable['2'] = 2; hexTable['3'] = 3; X hexTable['4'] = 4; hexTable['5'] = 5; X hexTable['6'] = 6; hexTable['7'] = 7; X hexTable['8'] = 8; hexTable['9'] = 9; X hexTable['A'] = 10; hexTable['B'] = 11; X hexTable['C'] = 12; hexTable['D'] = 13; X hexTable['E'] = 14; hexTable['F'] = 15; X hexTable['a'] = 10; hexTable['b'] = 11; X hexTable['c'] = 12; hexTable['d'] = 13; X hexTable['e'] = 14; hexTable['f'] = 15; X X /* delimiters of significance are flagged w/ negative value */ X hexTable[' '] = -1; hexTable[','] = -1; X hexTable['}'] = -1; hexTable['\n'] = -1; X hexTable['\t'] = -1; X X initialized = True; X} X X/* X * read next hex value in the input stream, return -1 if EOF X */ Xstatic NextInt (fstream) X FILE *fstream; X{ X int ch; X int value = 0; X int gotone = 0; X int done = 0; X X /* loop, accumulate hex value until find delimiter */ X /* skip any initial delimiters found in read stream */ X X while (!done) { X ch = getc(fstream); X if (ch == EOF) { X value = -1; X done++; X } else { X /* trim high bits, check type and accumulate */ X ch &= 0xff; X if (isascii(ch) && isxdigit(ch)) { X value = (value << 4) + hexTable[ch]; X gotone++; X } else if ((hexTable[ch]) < 0 && gotone) X done++; X } X } X return value; X} X X Xint ReadXBM (filename, width, height, data) X char *filename; X unsigned int *width, *height; /* RETURNED */ X char *data[]; /* RETURNED */ X{ X FILE *fstream; /* handle on file */ X char line[MAX_SIZE]; /* input line from file */ X int size; /* number of bytes of data */ X char name_and_type[MAX_SIZE]; /* an input line */ X char *type; /* for parsing */ X int value; /* from an input line */ X int version10p; /* boolean, old format */ X int padding; /* to handle alignment */ X int bytes_per_line; /* per scanline of data */ X unsigned int ww = 0; /* width */ X unsigned int hh = 0; /* height */ X int hx = -1; /* x hotspot */ X int hy = -1; /* y hotspot */ X X /* first time initialization */ X if (initialized == False) initHexTable(); X X if ((fstream = fopen(filename, "r")) == NULL) { X return -1; X } X X /* error cleanup and return macro */ X#define RETURN(code) { if (*data) free (*data); fclose (fstream); return code; } X X while (fgets(line, MAX_SIZE, fstream)) { X if (strlen(line) == MAX_SIZE-1) { X RETURN (-1); X } X if (sscanf(line,"#define %s %d",name_and_type,&value) == 2) { X if (!(type = rindex(name_and_type, '_'))) X type = name_and_type; X else X type++; X X if (!strcmp("width", type)) X ww = (unsigned int) value; X if (!strcmp("height", type)) X hh = (unsigned int) value; X if (!strcmp("hot", type)) { X if (type-- == name_and_type || type-- == name_and_type) X continue; X if (!strcmp("x_hot", type)) X hx = value; X if (!strcmp("y_hot", type)) X hy = value; X } X continue; X } X X if (sscanf(line, "static short %s = {", name_and_type) == 1) X version10p = 1; X else if (sscanf(line,"static unsigned char %s = {",name_and_type) == 1) X version10p = 0; X else if (sscanf(line, "static char %s = {", name_and_type) == 1) X version10p = 0; X else X continue; X X if (!(type = rindex(name_and_type, '_'))) X type = name_and_type; X else X type++; X X if (strcmp("bits[]", type)) X continue; X X if (!ww || !hh) X RETURN (-1); X X if ((ww % 16) && ((ww % 16) < 9) && version10p) X padding = 1; X else X padding = 0; X X bytes_per_line = (ww+7)/8 + padding; X X size = bytes_per_line * hh; X *data = (unsigned char *) malloc ((unsigned int) size); X if (!*data) X RETURN (-1); X X if (version10p) { X unsigned char *ptr; X int bytes; X X for (bytes=0, ptr= *data; bytes<size; (bytes += 2)) { X if ((value = NextInt(fstream)) < 0) X RETURN (-1); X *(ptr++) = value; X if (!padding || ((bytes+2) % bytes_per_line)) X *(ptr++) = value >> 8; X } X } else { X unsigned char *ptr; X int bytes; X X for (bytes=0, ptr= *data; bytes<size; bytes++, ptr++) { X if ((value = NextInt(fstream)) < 0) X RETURN (-1); X *ptr=value; X } X } X } /* end while */ X X if (*data == NULL) { X RETURN (-1); X } X X *width = ww; X *height = hh; X X fclose(fstream); X return 0; X} END_OF_FILE if test 5632 -ne `wc -c <'ReadXBM.c'`; then echo shar: \"'ReadXBM.c'\" unpacked with wrong size! fi # end of 'ReadXBM.c' fi if test -f 'action.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'action.c'\" else echo shar: Extracting \"'action.c'\" \(9179 characters\) sed "s/^X//" >'action.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 <X11/cursorfont.h> X#include "xpaint.h" X#include <X11/bitmaps/xlogo32> X Xstatic char rcsid[]="$Header: action.c,v 1.3 89/02/20 19:32:55 koblas Locked $"; X X#define Between(min,val,max) (((min)<=(val)) && ((val)<(max))) X X#include "scissor.xbm" X#include "dotbox.xbm" X#include "hand.xbm" X#include "arrow.xbm" X#include "line.xbm" X#include "arbline.xbm" X#include "rectfill.xbm" X#include "elipfill.xbm" X#include "rect.xbm" X#include "elipse.xbm" X#include "polygon.xbm" X#include "fill.xbm" X#include "brush.xbm" X#include "eraser.xbm" X#include "text.xbm" X#include "spray.xbm" X Xstatic struct { X int id; X int width,height; X char *bits; X int curid; X XImage *reg_image; X XImage *inv_image; X} actions[] = { X { C_ARROW,arrow_width,arrow_height,arrow_bits,XC_right_ptr, X NULL,NULL}, X { C_HAND,hand_width,hand_height,hand_bits,XC_fleur, X NULL,NULL}, X { C_DOTBOX,dottedbox_width,dottedbox_height,dottedbox_bits,XC_cross, X NULL,NULL}, X { C_NONE,scissor_width,scissor_height,scissor_bits,XC_X_cursor, X NULL,NULL}, X/* X { C_SCISSORS,scissor_width,scissor_height,scissor_bits,XC_X_cursor, X NULL,NULL}, X*/ X { C_LINE,line_width,line_height,line_bits,XC_crosshair, X NULL,NULL}, X { C_ARBLINE,arbline_width,arbline_height,arbline_bits,XC_pencil, X NULL,NULL}, X { C_RECTANGLE,rectangle_width,rectangle_height,rectangle_bits, X XC_crosshair,NULL,NULL}, X { C_ELIPSE,elipse_width,elipse_height,elipse_bits,XC_crosshair, X NULL,NULL}, X { C_NONE,polygon_width,polygon_height,polygon_bits,XC_crosshair, X NULL,NULL}, X/* X { C_POLYGON,polygon_width,polygon_height,polygon_bits,XC_crosshair, X NULL,NULL}, X*/ X { C_NONE,xlogo32_width,xlogo32_height,xlogo32_bits,XC_X_cursor, X NULL,NULL}, X { C_NONE,fill_width,fill_height,fill_bits,XC_crosshair, X NULL,NULL}, X/* X { C_FILL,fill_width,fill_height,fill_bits,XC_crosshair, X NULL,NULL}, X*/ X { C_BRUSH,brush_width,brush_height,brush_bits,XC_X_cursor, X NULL,NULL}, X { C_ERASER,eraser_width,eraser_height,eraser_bits,XC_X_cursor, X NULL,NULL}, X { C_TEXT,text_width,text_height,text_bits,XC_xterm, X NULL,NULL}, X { C_SPRAY,spray_width,spray_height,spray_bits,XC_spraycan, X NULL,NULL}, X { C_NONE,xlogo32_width,xlogo32_height,xlogo32_bits,XC_X_cursor, X NULL,NULL}, X { C_RECTF,rectfill_width,rectfill_height,rectfill_bits,XC_crosshair, X NULL,NULL}, X { C_ELIPF,elipfill_width,elipfill_height,elipfill_bits,XC_crosshair, X NULL,NULL}, X { C_NONE,xlogo32_width,xlogo32_height,xlogo32_bits,XC_X_cursor, X NULL,NULL}, X { C_NONE,xlogo32_width,xlogo32_height,xlogo32_bits,XC_X_cursor, X NULL,NULL}, X}; X Xstatic Cursor cursor_id[30]; X XWindow CreateAction() X{ X int i; X XSetWindowAttributes attr; X Window wind; X X for (i=0;i<sizeof(actions)/sizeof(actions[0]);i++) { X if (actions[i].id == C_NONE) X continue; X X actions[i].reg_image = BitmapToImage(actions[i].width, X actions[i].height,actions[i].bits,TRUE); X actions[i].inv_image = BitmapToImage(actions[i].width, X actions[i].height,actions[i].bits,FALSE); X X cursor_id[i] = XCreateFontCursor(CurrentWindow->display, X actions[i].curid); X } X X attr.background_pixel = CurrentWindow->black; X attr.event_mask = ExposureMask|ButtonPressMask| X ButtonReleaseMask|PointerMotionMask; X X wind = XCreateWindow(CurrentWindow->display,CurrentWindow->window, X DELTA_XPOS(ACTION_ID),DELTA_YPOS(ACTION_ID), X 32*2,32*10, X 1,0,0,0,CWBackPixel|CWEventMask,&attr); X XMapWindow(CurrentWindow->display,wind); X X return wind; X} X XEventAction(event) XXEvent *event; X{ X static int last_time = 0; X static int x=0,y=0; X X switch (event->type) { X case Expose: X redraw(event->xexpose.x,event->xexpose.y, X event->xexpose.width,event->xexpose.height); X break; X case ButtonPress: X if (((event->xbutton.time - last_time) < 500) && X Between(x-1,event->xbutton.x,x+1) && X Between(y-1,event->xbutton.y,y+1)) { X switch (CurrentActionID) { X case C_ARROW: X DrawFatbits(); X break; X case C_SPRAY: X EditSpray(); X break; X } X } else { X last_time = event->xbutton.time; X x=event->xbutton.x; X y=event->xbutton.y; X track_mouse(event); X } X break; X } X} X XSetAction(id) Xint id; X{ X int new,old; X int i; X X if (id == C_NONE) X return; X X for (i=0;i<sizeof(actions)/sizeof(actions[0]);i++) { X if (actions[i].id == CurrentActionID) X old = i; X if (actions[i].id == id) X new = i; X } X if (actions[new].id == id) { X XPutImage(CurrentWindow->display, X CurrentWindow->subwind[ACTION_ID].window, X CurrentWindow->gc, X actions[old].inv_image, X 0,0,(old%2)*32,(old/2)*32, X actions[old].width,actions[old].height); X XPutImage(CurrentWindow->display, X CurrentWindow->subwind[ACTION_ID].window, X CurrentWindow->gc, X actions[new].reg_image, X 0,0,(new%2)*32,(new/2)*32, X actions[new].width,actions[new].height); X CurrentActionID = new; X SetCursor(); X } X} X Xstatic redraw(x,y,w,h) Xint x,y,w,h; X{ X int i; X int c=((((w+31)/32)==2)?1:2),off=(x/32); X X for (i=(y/32)*2+off;i<((y+h+31)/32)*2+off;i+=c) { X if (actions[i].id == C_NONE) X continue; X XPutImage(CurrentWindow->display, X CurrentWindow->subwind[ACTION_ID].window, X CurrentWindow->gc, X CurrentActionID==actions[i].id? X actions[i].reg_image:actions[i].inv_image, X 0,0,(i%2)*32,(i/2)*32, X actions[i].width,actions[i].height); X } X} X Xstatic track_mouse(event) XXEvent *event; X{ X XEvent new_event,tmp_event; X int i; X int xpos,ypos; X int new_active,active; X X xpos = event->xbutton.x; X ypos = event->xbutton.y; X X for (i=0;;i++) { X if (actions[i].id==CurrentActionID) { X active=i; X break; X } X } X X do { X new_active = ((ypos/32)*2)+(xpos/32); X if ((new_active >= sizeof(actions)/sizeof(actions[0])) || X (actions[new_active].id == C_NONE)) X new_active = active; X if (new_active != active) { X XPutImage(CurrentWindow->display, X CurrentWindow->subwind[ACTION_ID].window, X CurrentWindow->gc, X actions[active].inv_image, X 0,0,(active%2)*32,(active/2)*32, X actions[active].width,actions[active].height); X active = new_active; X XPutImage(CurrentWindow->display, X CurrentWindow->subwind[ACTION_ID].window, X CurrentWindow->gc, X actions[active].reg_image, X 0,0,(active%2)*32,(active/2)*32, X actions[active].width,actions[active].height); X } X X XWindowEvent(CurrentWindow->display, X CurrentWindow->subwind[ACTION_ID].window, X ButtonReleaseMask|PointerMotionMask,&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 CurrentActionID = actions[active].id; X X SetCursor(); X} X XSetCursor() X{ X static XColor foreground = { 0, 0, 0, 0 }; /* black */ X static XColor background = { 0, 65535, 65535, 65535 }; /* white */ X static int eraser_made=FALSE,brush_made=FALSE; X Pixmap pix,pixmask; X extern char *SprayBitmap; X Cursor cur; X int pos,i; X X for (i=0;;i++) { X if (actions[i].id==CurrentActionID) { X pos=i; X break; X } X } X X switch (CurrentActionID) { X case C_SPRAY: X pix = XCreatePixmapFromBitmapData(CurrentWindow->display, X CurrentWindow->window, X SprayBitmap,16,16,CurrentWindow->black, X CurrentWindow->white,1); X XFreeCursor(CurrentWindow->display,cursor_id[pos]); X cursor_id[pos]=XCreatePixmapCursor(CurrentWindow->display, X pix,pix,&foreground,&background,0,0); X XFreePixmap(CurrentWindow->display,pix); X break; X case C_BRUSH: X if (!brush_made) { X brush_made = TRUE; X pix = XCreatePixmap(CurrentWindow->display, X CurrentWindow->window,18,18,1); X pixmask = XCreatePixmap(CurrentWindow->display, X CurrentWindow->window,18,18,1); X XDrawRectangle(CurrentWindow->display,pix, X CurrentWindow->igc,1,1,13,7); X XFillRectangle(CurrentWindow->display,pixmask, X CurrentWindow->igc,0,0,16,10); X cursor_id[pos]=XCreatePixmapCursor( X CurrentWindow->display, X pix,pixmask,&background,&foreground,0,0); X XFreePixmap(CurrentWindow->display,pix); X XFreePixmap(CurrentWindow->display,pixmask); X } X break; X case C_ERASER: X if (!eraser_made) { X eraser_made = TRUE; X pix = XCreatePixmap(CurrentWindow->display, X CurrentWindow->window,18,18,1); X pixmask = XCreatePixmap(CurrentWindow->display, X CurrentWindow->window,18,18,1); X XDrawRectangle(CurrentWindow->display,pix, X CurrentWindow->igc,1,1,13,7); X XFillRectangle(CurrentWindow->display,pixmask, X CurrentWindow->igc,0,0,16,10); X cursor_id[pos]=XCreatePixmapCursor( X CurrentWindow->display, X pix,pixmask,&foreground,&background,0,0); X XFreePixmap(CurrentWindow->display,pix); X XFreePixmap(CurrentWindow->display,pixmask); X } X break; X default: X break; X } X X XDefineCursor(CurrentWindow->display, X CurrentWindow->subwind[DRAW_ID].window, X cursor_id[pos]); X} END_OF_FILE if test 9179 -ne `wc -c <'action.c'`; then echo shar: \"'action.c'\" unpacked with wrong size! fi # end of 'action.c' fi if test -f 'bitedit.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'bitedit.c'\" else echo shar: Extracting \"'bitedit.c'\" \(4881 characters\) sed "s/^X//" >'bitedit.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 Xstatic char *bit_buffer=NULL; Xstatic int bit_width; Xstatic int bit_height; Xstatic Window bit_window; Xstatic XFontStruct *font_info; Xstatic GC bit_dot_gc; X X#define SIZE 8 X#define WIDTH (60+bit_width*(SIZE+1)) X#define HEIGHT (20+bit_height*(SIZE+1)) X X#define UPDATE(x,y) XFillRectangle(CurrentWindow->display,bit_window,\ X bit_buffer[y*bit_width+x]?\ X CurrentWindow->gc:CurrentWindow->igc,\ X 10+x*(SIZE+1),10+y*(SIZE+1),SIZE,SIZE);\ X XDrawPoint(CurrentWindow->display,bit_window,\ X bit_buffer[y*bit_width+x]?\ X CurrentWindow->gc:CurrentWindow->igc,\ X WIDTH-40+(x),15+(y)); X X XWindow CreateBitedit() X{ X Window wind; X XSetWindowAttributes attr; X XGCValues values; X static char list[2] = { 1 , 1 }; 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(ACTION_ID),DELTA_YPOS(ACTION_ID), X 20,20, X 1,0,0,0,CWBackPixel|CWEventMask,&attr); X X bit_window = wind; X 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 X values.background = CurrentWindow->white; X values.foreground = CurrentWindow->black; X values.line_style = LineOnOffDash; X values.font = font_info->fid; X X bit_dot_gc = XCreateGC(CurrentWindow->display,bit_window, X GCFont|GCForeground|GCBackground|GCLineStyle,&values); X XSetDashes(CurrentWindow->display,bit_dot_gc,0,list,sizeof(list)); X X return wind; X} X Xvoid EventBitedit(event) XXEvent *event; X{ X switch (event->type) { X case Expose: X break; X } X} X XBitedit(width,height,bits) Xint width,height; Xchar *bits; X{ X bit_width = width; X bit_height = height; X X bit_buffer = bits; X X XResizeWindow(CurrentWindow->display,bit_window,WIDTH,HEIGHT); X XMapWindow(CurrentWindow->display,bit_window); X XFlush(CurrentWindow->display); X X MyEventLoop(); X X clean_up(); X} X Xstatic clean_up() X{ X XUnmapWindow(CurrentWindow->display,bit_window); X XFlush(CurrentWindow->display); X} X Xstatic redraw() X{ X int x,y; X X for (y=0;y<bit_height;y++) X for (x=0;x<bit_width;x++) { X UPDATE(x,y); X } X for (x=0;x<=bit_width;x++) X XDrawLine(CurrentWindow->display,bit_window, X bit_dot_gc,9+(x*(SIZE+1)),9, X 9+(x*(SIZE+1)),10+(bit_height*(SIZE+1))); X for (y=0;y<=bit_height;y++) X XDrawLine(CurrentWindow->display,bit_window, X bit_dot_gc,9,9+(y*(SIZE+1)), X 9+(bit_width*(SIZE+1)),9+(y*(SIZE+1))); X X XDrawRectangle(CurrentWindow->display,bit_window, X CurrentWindow->igc,0,0,WIDTH-1,HEIGHT-1); X XDrawRectangle(CurrentWindow->display,bit_window, X CurrentWindow->igc,1,1,WIDTH-3,HEIGHT-3); X XDrawRectangle(CurrentWindow->display,bit_window, X CurrentWindow->igc,WIDTH-41,14,bit_width+1,bit_height+1); X X XDrawRectangle(CurrentWindow->display,bit_window, X CurrentWindow->igc,WIDTH-45,HEIGHT-45,40, X font_info->ascent+font_info->descent+6); X XDrawImageString(CurrentWindow->display,bit_window,bit_dot_gc, X WIDTH-40,(HEIGHT-45)+3+font_info->ascent,"Done",4); X} X Xstatic MyEventLoop() X{ X XEvent event; X int color = FALSE; X int xpos,ypos; X int new_pos,pos; X int done=FALSE,tracking=FALSE; X X while (!done) { X XWindowEvent(CurrentWindow->display,bit_window,-1,&event); X switch (event.type) { X case Expose: X redraw(); X break; X case ButtonPress: X if (Between(10,event.xbutton.x,WIDTH-50) && X Between(10,event.xbutton.y,HEIGHT-10)) { X tracking = TRUE; X xpos = (event.xbutton.x - 10)/(SIZE+1); X ypos = (event.xbutton.y - 10)/(SIZE+1); X pos = ypos*bit_height+xpos; X color = !bit_buffer[pos]; X bit_buffer[pos] = color; X UPDATE(xpos,ypos); X } else if (Between(HEIGHT-45,event.xbutton.y, X HEIGHT-45+(font_info->ascent+ X font_info->descent+6)) && X Between(WIDTH-45,event.xbutton.x,WIDTH-5)) { X done=TRUE; X } X break; X case ButtonRelease: X if (tracking) X tracking=FALSE; X break; X case MotionNotify: X if (tracking) { X if (Between(10,event.xmotion.x,WIDTH-50) && X Between(10,event.xmotion.y,HEIGHT-10)) { X xpos = (event.xmotion.x - 10)/(SIZE+1); X ypos = (event.xmotion.y - 10)/(SIZE+1); X new_pos = ypos*bit_height+xpos; X if (new_pos != pos) { X pos = new_pos; X bit_buffer[pos] = color; X UPDATE(xpos,ypos); X } X } X } X break; X } X } X} END_OF_FILE if test 4881 -ne `wc -c <'bitedit.c'`; then echo shar: \"'bitedit.c'\" unpacked with wrong size! fi # end of 'bitedit.c' fi if test -f 'event.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'event.c'\" else echo shar: Extracting \"'event.c'\" \(3617 characters\) sed "s/^X//" >'event.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 <sys/types.h> X#include <X11/Xos.h> X#include "xpaint.h" X X#ifndef FD_SET X#define FD_SET(n, s) (((s)->fds_bits[0]) |= (1 << n)) X#define FD_ZERO(s) bzero((char *)(s), sizeof (*(s))) X#endif X#define AllEventMask (-1) X X#define Between(min,val,max) (((min)<=(val)) && ((val)<(max))) X X#define MAXINTR 20 X Xstruct s_intr { X int used; X void (*func)(); X} interrupt_list[MAXINTR]; X Xstatic int ActiveItem = C_ARROW; Xstatic Cursor CurrentCursor = 0; X#ifndef lint Xstatic char rcsid[]="$Header: event.c,v 1.9 89/02/22 12:31:14 koblas Locked $"; X#endif X Xstatic int Done=FALSE; X XEventLoop() X{ X XEvent event; X int i,n; X static struct timeval tv = { 0,500000 }; X fd_set read_fd; X int nfd = getdtablesize(); X X for (i=0;i<MAXINTR;i++) { X interrupt_list[i].used=FALSE; X } X X goto start; X X while (!Done) { X X FD_ZERO(&read_fd); X FD_SET(ConnectionNumber(CurrentWindow->display),&read_fd); X if ((n=select(nfd,&read_fd,NULL,NULL,&tv))<0) { X perror("select"); X Done=TRUE; X continue; X } X if (n==0) { X tv.tv_sec = 0; X tv.tv_usec = 500000; X Interrupt(); X continue; X } Xstart: X while (XCheckMaskEvent(CurrentWindow->display, X AllEventMask,&event) && !Done) { X HandleEvent(&event); X } X } X} X XHandleEvent(event) XXEvent *event; X{ X int i,n; X char buf[80]; X X if (event->xany.window != CurrentWindow->window) { X for (i=0;i<CurrentWindow->numsub;i++) { X if (CurrentWindow->subwind[i].window== X event->xany.window) X break; X } X if ((i<CurrentWindow->numsub) && X (CurrentWindow->subwind[i].event_handler!=NULL)) X CurrentWindow->subwind[i]. X event_handler(event); X } X X switch(event->type) { X case NoExpose: /* probably want to do something about this one..*/ X case MapNotify: X case ReparentNotify: X break; X case ButtonPress: X break; X case ButtonRelease: X break; X case KeyPress : X case KeyRelease : X break; X case LeaveNotify: X break; X case EnterNotify: X break; X case FocusOut : X break; X case FocusIn : X break; X case MotionNotify: X break; X case ConfigureNotify: X if (event->xconfigure.window != CurrentWindow->window) X break; X CurrentWindow->width = event->xconfigure.width; X CurrentWindow->height = event->xconfigure.height; X for (i=0;i<CurrentWindow->numsub;i++) { X if (CurrentWindow->subwind[i].resize_handler X !=NULL) X CurrentWindow->subwind[i].resize_handler(); X else { X XMoveWindow(CurrentWindow->display, X CurrentWindow->subwind[i].window, X DELTA_XPOS(i),DELTA_YPOS(i)); X } X } X break; X case Expose: X break; X default: X fprintf(stderr,"Unknown event recieved == %d\n",event->type); X break; X } X} X XWindowEvent(wind,event) XWindow wind; XXEvent *event; X{ X int flag=FALSE; X do { X if (flag) X HandleEvent(event); X XNextEvent(CurrentWindow->display,event); X flag=TRUE; X } while (event->xany.window != wind); X} X Xvoid Quit() X{ X Done=TRUE; X} X XDeleteInterrupt(id) Xint id; X{ X interrupt_list[id].used = FALSE; X} X XAddInterrupt(func) Xvoid (*func)(); X{ X int i; X X for (i=0;i<MAXINTR;i++) X if (!interrupt_list[i].used) X break; X if (i==MAXINTR) X return -1; X interrupt_list[i].used = TRUE; X interrupt_list[i].func = func; X X return i; X} X XInterrupt() X{ X int i; X X for (i=0;i<MAXINTR;i++) X if (interrupt_list[i].used) X interrupt_list[i].func(); X} END_OF_FILE if test 3617 -ne `wc -c <'event.c'`; then echo shar: \"'event.c'\" unpacked with wrong size! fi # end of 'event.c' fi if test -f 'main.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'main.c'\" else echo shar: Extracting \"'main.c'\" \(6721 characters\) sed "s/^X//" >'main.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 <X11/cursorfont.h> X#include "xpaint.h" X#include <X11/bitmaps/xlogo32> X X#ifndef lint Xstatic char rcsid[]="$Header: main.c,v 1.7 89/02/20 19:32:58 koblas Locked $"; X#endif Xstatic char *Default_font="serif.r.14"; X Xt_window *CurrentWindow; Xint CurrentActionID = C_ARROW; Xint CurrentPatternID = 0; Xchar *FileName=NULL; Xint FileType=FT_NONE; Xint DefaultXsize=1024; Xint DefaultYsize=1024; X X#define EVENT_MASK (ExposureMask|KeyPressMask|FocusChangeMask|\ X StructureNotifyMask|PointerMotionMask|\ X ButtonPressMask|ButtonReleaseMask|\ X EnterWindowMask|LeaveWindowMask) X XWindow CreateDraw(),CreateAction(),CreatePattern(),CreateMenu(), X CreateBitedit(),CreateSave(); Xvoid EventDraw(),EventAction(),EventPattern(),EventMenu(),EventBitedit(); Xvoid ResizeDraw(),ResizeMenu(); X Xt_sub_window newwind[] = { X {CreateDraw,EventDraw,ResizeDraw,0, X 10+32+32+10,20,DELTA_TOP|DELTA_LEFT}, X {CreateAction,EventAction,NULL,0, X 10,20,DELTA_TOP|DELTA_LEFT}, X {CreatePattern,EventPattern,NULL,0, X 10+32+32+10,10+32,DELTA_LEFT|DELTA_BOTTOM}, X {CreateMenu,EventMenu,ResizeMenu,0, X 0,0,DELTA_LEFT|DELTA_TOP}, X {CreateBitedit,EventBitedit,NULL,0, X 64,64,DELTA_LEFT|DELTA_TOP}, X {CreateSave,NULL,NULL,0, X 64,64,DELTA_LEFT|DELTA_TOP}, X}; X X#define Between(min,val,max) (((min)<=(val)) && ((val)<(max))) X Xmain(argc,argv) Xint argc; Xchar **argv; X{ X extern char *optarg; X extern int optind; X int c; X char filename[80]; X char display_name[80]; X X filename[0]='\0'; X display_name[0]='\0'; X X while ((c=getopt(argc,argv,"d:v"))!=EOF) { X switch (c) { X case 'x': X DefaultXsize = atoi(optarg); X if (DefaultXsize==0) X DefaultXsize=1024; X break; X case 'y': X DefaultYsize = atoi(optarg); X if (DefaultYsize==0) X DefaultYsize=1024; X break; X case 'd': X strcpy(display_name,optarg); X break; X case 'v': X Version(); X exit(0); X } X } X X OpenAndInit((display_name[0]=='\0')?NULL:display_name, X (filename[0]=='\0')?TRUE:FALSE); X X if (filename[0]!='\0') { X ReadFile(filename,FT_XBM); X FileName = filename; X FileType = FT_XBM; X } X X EventLoop(); X} X XOpenAndInit(distxt,flag) Xchar *distxt; Xint flag; X{ X int i; X char *data; X X if ((CurrentWindow=(t_window *)malloc(sizeof(t_window)))==NULL) { X fprintf(stderr,"Unable to malloc space for window info\n"); X exit(1); X } X if ((CurrentWindow->display = XOpenDisplay(distxt))==NULL) { X fprintf(stderr,"Unable to open display (%s)\n", X (distxt==NULL)?"$DISPLAY":distxt); X exit(1); X } X CurrentWindow->screen = DefaultScreen(CurrentWindow->display); X CurrentWindow->rootwindow = DefaultRootWindow(CurrentWindow->display); X CurrentWindow->visual = DefaultVisual(CurrentWindow->display, X CurrentWindow->screen); X CurrentWindow->depth = DefaultDepth(CurrentWindow->display, X CurrentWindow->screen); X CurrentWindow->numsub = sizeof(newwind)/sizeof(newwind[0]); X CurrentWindow->subwind = newwind; X X OpenXWindow(640,480); X X for (i=0;i<CurrentWindow->numsub;i++) { X if (CurrentWindow->subwind[i].create_handler!=NULL) X CurrentWindow->subwind[i].window = X CurrentWindow->subwind[i].create_handler(); X } X X OpenDraw(); X XFlush(CurrentWindow->display); X} X XOpenXWindow(xsize,ysize) Xint xsize,ysize; X{ X XSetWindowAttributes attr; X Window wind; X XSizeHints hints; X Pixmap source,mask; X XColor foreground_color,background_color; X XGCValues values; X int i; X XEvent event; X X XParseColor(CurrentWindow->display, X DefaultColormap(CurrentWindow->display,CurrentWindow->screen), X "Black",&background_color); X XParseColor(CurrentWindow->display, X DefaultColormap(CurrentWindow->display,CurrentWindow->screen), X "White",&foreground_color); X XAllocColor(CurrentWindow->display, X DefaultColormap(CurrentWindow->display,CurrentWindow->screen), X &background_color); X XAllocColor(CurrentWindow->display, X DefaultColormap(CurrentWindow->display,CurrentWindow->screen), X &foreground_color); X X CurrentWindow->white = foreground_color.pixel; X CurrentWindow->black = background_color.pixel; X attr.background_pixel = background_color.pixel; X attr.event_mask = EVENT_MASK; X CurrentWindow->default_cursor = attr.cursor= X XCreateFontCursor(CurrentWindow->display,XC_arrow); X XRecolorCursor(CurrentWindow->display,CurrentWindow->default_cursor, X &foreground_color,&background_color); X X CurrentWindow->width = xsize; X CurrentWindow->height = ysize; X CurrentWindow->img_offx = 0; X CurrentWindow->img_offy = 0; X CurrentWindow->window = XCreateWindow(CurrentWindow->display, X CurrentWindow->rootwindow, X 0,0,xsize,ysize,2,0,0,0, X CWCursor|CWEventMask|CWBackPixel, X &attr); X X hints.flags = PMinSize|PResizeInc|PSize; X hints.width = xsize; X hints.height = ysize; X hints.min_width = 640; X hints.min_height = 480; X hints.width_inc = 1; X hints.height_inc = 1; X XSetNormalHints(CurrentWindow->display,CurrentWindow->window,&hints); X XStoreName(CurrentWindow->display,CurrentWindow->window,"xpaint"); X XSetIconName(CurrentWindow->display,CurrentWindow->window,"xpaintIcon"); X X XMapWindow(CurrentWindow->display,CurrentWindow->window); X XFlush(CurrentWindow->display); X XWindowEvent(CurrentWindow->display,CurrentWindow->window, X ExposureMask,&event); X X values.foreground = foreground_color.pixel; X values.background = background_color.pixel; X CurrentWindow->gc = XCreateGC(CurrentWindow->display, X CurrentWindow->window, X GCBackground|GCForeground, X &values); X values.foreground = background_color.pixel; X values.background = foreground_color.pixel; X CurrentWindow->igc= XCreateGC(CurrentWindow->display, X CurrentWindow->window, X GCBackground|GCForeground, X &values); X} X XXImage *BitmapToImage(xsize,ysize,data,flag) Xint xsize,ysize; Xchar *data; Xint flag; X{ X XImage *image; X char *pixels=(char *)malloc(xsize*ysize); X int x,y; X unsigned int v; X int xw = (xsize+7)/8; X X if (pixels==NULL) X return NULL; X image = XCreateImage(CurrentWindow->display,CurrentWindow->visual, X CurrentWindow->depth,XYPixmap,0,pixels,xsize,ysize,8,0); X if (image==NULL) X return NULL; X X for (y=0;y<ysize;y++) { X for (x=0;x<xsize;x++) { X v = data[(y*xw)+(x/8)]&(1<<(x%8)); X if ((flag && (v!=0)) || (!flag && (v==0))) { X XPutPixel(image,x,y,CurrentWindow->black); X } else { X XPutPixel(image,x,y,CurrentWindow->white); X } X } X } X return image; X} END_OF_FILE if test 6721 -ne `wc -c <'main.c'`; then echo shar: \"'main.c'\" unpacked with wrong size! fi # end of 'main.c' fi if test -f 'pattern.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'pattern.c'\" else echo shar: Extracting \"'pattern.c'\" \(6543 characters\) sed "s/^X//" >'pattern.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#ifndef lint Xstatic char rcsid[]= X "$Header: pattern.c,v 1.3 89/02/20 19:33:00 koblas Locked $"; X#endif X X#define Between(min,val,max) (((min)<=(val)) && ((val)<(max))) X X#include "pat_01.xbm" X#include "pat_02.xbm" X#include "pat_03.xbm" X#include "pat_04.xbm" X#include "pat_05.xbm" X#include "pat_06.xbm" X#include "pat_07.xbm" X#include "pat_08.xbm" X#include "pat_09.xbm" X#include "pat_10.xbm" X#include "pat_11.xbm" X#include "pat_12.xbm" X#include "pat_13.xbm" X#include "pat_14.xbm" X#include "pat_15.xbm" X#include "pat_16.xbm" X X Xstatic struct { X int width,height; X char *bits; X XImage *reg_image; X XImage *inv_image; X} pattern[] = { X { pattern_01_width, pattern_01_height, pattern_01_bits, NULL, NULL}, X { pattern_02_width, pattern_02_height, pattern_02_bits, NULL, NULL}, X { pattern_03_width, pattern_03_height, pattern_03_bits, NULL, NULL}, X { pattern_04_width, pattern_04_height, pattern_04_bits, NULL, NULL}, X { pattern_05_width, pattern_05_height, pattern_05_bits, NULL, NULL}, X { pattern_06_width, pattern_06_height, pattern_06_bits, NULL, NULL}, X { pattern_07_width, pattern_07_height, pattern_07_bits, NULL, NULL}, X { pattern_08_width, pattern_08_height, pattern_08_bits, NULL, NULL}, X { pattern_09_width, pattern_09_height, pattern_09_bits, NULL, NULL}, X { pattern_10_width, pattern_10_height, pattern_10_bits, NULL, NULL}, X { pattern_11_width, pattern_11_height, pattern_11_bits, NULL, NULL}, X { pattern_12_width, pattern_12_height, pattern_12_bits, NULL, NULL}, X { pattern_13_width, pattern_13_height, pattern_13_bits, NULL, NULL}, X { pattern_14_width, pattern_14_height, pattern_14_bits, NULL, NULL}, X { pattern_15_width, pattern_15_height, pattern_15_bits, NULL, NULL}, X { pattern_16_width, pattern_16_height, pattern_16_bits, NULL, NULL} X}; X Xchar PatternBits[32*32]; X XWindow CreatePattern() X{ X int i; X XSetWindowAttributes attr; X Window wind; X X for (i=0;i<sizeof(pattern)/sizeof(pattern[0]);i++) { X pattern[i].reg_image = BitmapToImage(pattern[i].width, X pattern[i].height, X pattern[i].bits,TRUE); X pattern[i].inv_image = BitmapToImage(pattern[i].width, X pattern[i].height, X pattern[i].bits,FALSE); X } X X attr.background_pixel = CurrentWindow->black; X attr.event_mask = ExposureMask|ButtonPressMask| X ButtonReleaseMask|PointerMotionMask; X X wind = XCreateWindow(CurrentWindow->display,CurrentWindow->window, X DELTA_XPOS(PATTERN_ID),DELTA_YPOS(PATTERN_ID), X 32*16,32,1,0,0,0,CWBackPixel|CWEventMask,&attr); X XMapWindow(CurrentWindow->display,wind); X X CurrentPatternID=0; X set_patternbits(); X X return wind; X} X Xvoid EventPattern(event) XXEvent *event; X{ X static int last_time = 0; X static int x=0,y=0; X static char bits[sizeof(PatternBits)]; X X switch (event->type) { X case Expose: X redraw(); X break; X case ButtonPress: X if (((event->xbutton.time - last_time) < 500) && X Between(x-1,event->xbutton.x,x+1) && X Between(y-1,event->xbutton.y,y+1)) { X bcopy(PatternBits,bits,sizeof(PatternBits)); X Bitedit(32,32,bits); X set_pattern(bits); X } else { X last_time = event->xbutton.time; X x = event->xbutton.x; X y = event->xbutton.y; X track_mouse(event); X } X break; X } X} X Xstatic redraw() X{ X int i; X X for (i=0;i<sizeof(pattern)/sizeof(pattern[0]);i++) { X XPutImage(CurrentWindow->display, X CurrentWindow->subwind[PATTERN_ID].window, X CurrentWindow->gc, X (i==CurrentPatternID)? X pattern[i].reg_image:pattern[i].inv_image, X 0,0,32*i,0,pattern[i].width,pattern[i].height); X } X XFlush(CurrentWindow->display); X} X Xstatic track_mouse(event) XXEvent *event; X{ X XEvent new_event,tmp_event; X int i; X int xpos,ypos; X int new_active,active=CurrentPatternID; X X xpos = event->xbutton.x; X ypos = event->xbutton.y; X X do { X new_active = (xpos/32); X if (new_active >= 16) X new_active = 15; X if (new_active != active) { X XPutImage(CurrentWindow->display, X CurrentWindow->subwind[PATTERN_ID].window, X CurrentWindow->gc, X pattern[active].inv_image, X 0,0,active*32,0, X pattern[active].width,pattern[active].height); X active = new_active; X XPutImage(CurrentWindow->display, X CurrentWindow->subwind[PATTERN_ID].window, X CurrentWindow->gc, X pattern[active].reg_image, X 0,0,active*32,0, X pattern[active].width,pattern[active].height); X } X X XWindowEvent(CurrentWindow->display, X CurrentWindow->subwind[PATTERN_ID].window, X ButtonReleaseMask|PointerMotionMask,&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 CurrentPatternID = active; X set_patternbits(); X} X Xstatic set_pattern(bits) Xchar *bits; X{ X int x,y,pos; X int xw = (pattern[CurrentPatternID].width+7)/8; X X for (y=0;y<pattern[CurrentPatternID].height;y++) X for (x=0;x<xw;x++) X pattern[CurrentPatternID].bits[x+y*xw]=0; X X for (pos=0;pos<pattern[CurrentPatternID].width* X pattern[CurrentPatternID].height;pos++) { X x = pos%pattern[CurrentPatternID].width; X y = pos/pattern[CurrentPatternID].height; X if (!bits[pos]) { X pattern[CurrentPatternID].bits[(y*xw)+(x/8)]|=1<<(x%8); X } X } X X XDestroyImage(pattern[CurrentPatternID].reg_image); X XDestroyImage(pattern[CurrentPatternID].inv_image); X X pattern[CurrentPatternID].reg_image = BitmapToImage( X pattern[CurrentPatternID].width, X pattern[CurrentPatternID].height, X pattern[CurrentPatternID].bits,TRUE); X pattern[CurrentPatternID].inv_image = BitmapToImage( X pattern[CurrentPatternID].width, X pattern[CurrentPatternID].height, X pattern[CurrentPatternID].bits,FALSE); X bcopy(bits,PatternBits,pattern[CurrentPatternID].width* X pattern[CurrentPatternID].height); X redraw(); X} X Xstatic set_patternbits() X{ X int xsize = pattern[CurrentPatternID].width; X int ysize = pattern[CurrentPatternID].height; X int xw = (xsize+7)/8; X int x,y; X X for (y=0;y<ysize;y++) { X for (x=0;x<xsize;x++) { X if ((pattern[CurrentPatternID].bits X [(y*xw)+(x/8)]&(1<<(x%8)))==0) X PatternBits[(y*32)+x]=TRUE; X else X PatternBits[(y*32)+x]=FALSE; X } X } X} END_OF_FILE if test 6543 -ne `wc -c <'pattern.c'`; then echo shar: \"'pattern.c'\" unpacked with wrong size! fi # end of 'pattern.c' fi if test -f 'save.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'save.c'\" else echo shar: Extracting \"'save.c'\" \(6741 characters\) sed "s/^X//" >'save.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 Xchar *rindex(); X X#ifndef lint Xstatic char rcsid[]="$Header: save.c,v 1.2 89/02/20 19:33:01 koblas Locked $"; X#endif X X#define MIN(a,b) ((a)<(b) ? (a) : (b)) X#define CTRL(x) ((x)-'A'+1) X#define DELETE 127 X Xstatic Window save_window; Xstatic XFontStruct *font_info; Xstatic GC save_gc; Xstatic int xstart,ystart; Xstatic int width,height; X#define XSIZE 300 X#define YSIZE 100 X XWindow CreateSave() X{ X XSetWindowAttributes attr; X Window wind; X XGCValues values; X X attr.background_pixel = CurrentWindow->white; X attr.event_mask = ExposureMask|ButtonPressMask|KeyPressMask; X X save_window=XCreateWindow(CurrentWindow->display,CurrentWindow->window, X DELTA_XPOS(SAVE_ID),DELTA_YPOS(SAVE_ID), X XSIZE,YSIZE, X 0,0,0,0,CWBackPixel|CWEventMask,&attr); X 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 X values.background = CurrentWindow->white; X values.foreground = CurrentWindow->black; X values.font = font_info->fid; X X save_gc = XCreateGC(CurrentWindow->display,save_window, X GCFont|GCForeground|GCBackground,&values); X X return save_window; X} X XSaveRegion() X{ X static char str[1024]; X X DrawGetRegion(&xstart,&ystart,&width,&height); X X if (GetString(str)) X SaveFile(str,FT_XBM); X} X XSaveMenuAs() X{ X static char str[1024]; X X xstart = ystart = 0; X width = CurrentWindow->img_width; X height = CurrentWindow->img_height; X X if (GetString(str)) X SaveFile(str,FT_XBM); X} X XGetString(str) Xchar *str; X{ X XEvent event; X int done=FALSE; X static char buf[80]; X int i,n; X int cancel=FALSE; X int index=0; X int c_width = font_info->max_bounds.width; X int c_height = font_info->max_bounds.ascent+ X font_info->max_bounds.descent; X X XMapWindow(CurrentWindow->display,save_window); X XFlush(CurrentWindow->display); X X while (!done) { X XWindowEvent(CurrentWindow->display,save_window,-1,&event); X switch (event.type) { X case Expose: X XDrawRectangle(CurrentWindow->display,save_window, X CurrentWindow->igc,1,1,XSIZE-3,YSIZE-3); X XDrawRectangle(CurrentWindow->display,save_window, X CurrentWindow->igc,0,0,XSIZE-1,YSIZE-1); X XDrawRectangle(CurrentWindow->display,save_window, X CurrentWindow->igc,10,10,XSIZE-20, X c_height+6); X XDrawRectangle(CurrentWindow->display,save_window, X CurrentWindow->igc,10,40, X c_width*8,c_height+6); X XDrawRectangle(CurrentWindow->display,save_window, X CurrentWindow->igc,10,65, X c_width*8,c_height+6); X XDrawImageString(CurrentWindow->display, X save_window,save_gc, X 10+c_width,40+3+font_info->ascent, X "Cancel",6); X XDrawImageString(CurrentWindow->display, X save_window,save_gc, X 10+c_width*3,65+3+font_info->ascent, X "OK",2); X XDrawImageString(CurrentWindow->display, X save_window,save_gc, X 10+c_width,10+3+font_info->ascent, X str,index); X break; X case ButtonPress: X if (Between(10,event.xbutton.x,10+c_width*8) && X Between(40,event.xbutton.y,40+6+c_height)) { X XFillRectangle(CurrentWindow->display, X save_window, X CurrentWindow->igc,10,40, X c_width*8,c_height+6); X done=TRUE; X cancel=TRUE; X } X if (Between(10,event.xbutton.x,10+c_width*8) && X Between(65,event.xbutton.y,65+6+c_height)) { X done=TRUE; X } 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 if (index!=0) X done=TRUE; X break; X case CTRL('U'): X break; X case CTRL('H'): X case DELETE: X if (index>0) X index--; X break; X default: X if (buf[i]>=' ') X str[index++]=buf[i]; X } X } X if (n!=0) { X XClearArea(CurrentWindow->display, X save_window,11,11,XSIZE-22,c_height+4, X FALSE); X XDrawImageString(CurrentWindow->display, X save_window,save_gc, X 10+c_width,10+3+font_info->ascent, X str,MIN(index,(XSIZE-22)/c_width)); X } X break; X } X } X X if (!cancel) { X XFillRectangle(CurrentWindow->display, X save_window, X CurrentWindow->igc,10,65, X c_width*8,c_height+6); X XDrawString(CurrentWindow->display, X save_window,CurrentWindow->gc, X 10+c_width*3,65+3+font_info->ascent, X "OK",2); X XFlush(CurrentWindow->display); X } X XUnmapWindow(CurrentWindow->display,save_window); X X if ((index==0) || (cancel)) X return FALSE; X str[index]='\0'; X return TRUE; X} X XSaveMenu() X{ X static char str[1024]; X X xstart = ystart = 0; X width = CurrentWindow->img_width; X height = CurrentWindow->img_height; X X if ((FileName==NULL) || (FileType==FT_NONE)) { X if (GetString(str)) X SaveFile(str,FT_XBM); X } else X SaveFile(FileName,FileType); X} X XSaveFile(filename,type) Xchar *filename; Xint type; X{ X int ret_code = -1; X X FlushBuffer(); X X switch (type) { X case FT_XBM: X ret_code = save_xbm(filename); X break; X case FT_UTAH: X fprintf(stderr,"file type not supported (UTAH RLE)\n"); X break; X case FT_GIF: X fprintf(stderr,"file type not supported (GIF)\n"); X break; X case FT_TIFF: X fprintf(stderr,"file type not supported (TIFF)\n"); X break; X case FT_PIC: X fprintf(stderr,"file type not supported (PIC)\n"); X break; X } X X return ret_code; X} X Xstatic save_xbm(filename) Xchar *filename; X{ X char *data; X int x,y; X int bitpos=0; X int byte; X int col = 0; X FILE *fd; X long pix; X static char hexdigits[]={'0','1','2','3','4','5','6','7','8', X '9','a','b','c','d','e','f'}; X X if ((fd=fopen(filename,"w"))==NULL) { X fprintf(stderr,"Unable to open %s for writing\n",filename); X return; X } X X fprintf(fd,"#define unknown_width %d\n#define unknown_height %d\n", X width,height); X fputs("static char unknown_bits[] = {\n",fd); X X for (y=0;y<height;y++) { X for (x=0;x<width;x++) { X pix=XGetPixel(CurrentWindow->master,x+xstart,y+ystart); X bitpos = x&7; X byte |= ((pix==CurrentWindow->black)?1:0)<<bitpos; X if (bitpos==7) { X putc('0',fd); X putc('x',fd); X putc(hexdigits[(byte>>4)&0xf],fd); X putc(hexdigits[(byte )&0xf],fd); X putc(',',fd); X col++; X if (col==15) { X putc('\n',fd); X col=0; X } X byte=0; X } X } X if (bitpos!=7) { X putc('0',fd); X putc('x',fd); X putc(hexdigits[(byte>>4)&0xf],fd); X putc(hexdigits[(byte )&0xf],fd); X putc(',',fd); X col++; X if (col==15) { X putc('\n',fd); X col=0; X } X byte=0; X } X } X X fputs("};\n",fd); X X fclose(fd); X} END_OF_FILE if test 6741 -ne `wc -c <'save.c'`; then echo shar: \"'save.c'\" unpacked with wrong size! fi # end of 'save.c' fi echo shar: End of archive 2 \(of 3\). cp /dev/null ark2isdone 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