rsalz@uunet.UU.NET (Rich Salz) (09/22/87)
Submitted-by: "Alan W. Paeth" <awpaeth%watcgl.waterloo.edu@RELAY.CS.NET> Posting-number: Volume 11, Issue 63 Archive-name: lemming/Patch1 The "LEMMING - Little Editor for Mice and Other Rodents" editor has a fast- growing user community, and minor bug fixes and addenda are coming in. In addition, I've continued to extend the editor, hense these two postings. These patches, plus may latest features are in this first mail message In addition, I've added source code for PostScript output, and included a Silicon Graphics/IRIS driver. The second posting includes an installers guide, updates to the tutorial, a new font file, and sample *.lem documents. This posting contains source related code: new source modules (for PostScript and the IRIS), "diff"-style patch code, plus a shell script to run the latter. This code allows one to update the comp.sources.unix version of "lemming" to incorporate the latest features. # This is a shell archive. Remove anything before this line, # then unpack it by saving it in a file and typing "sh file". # # Contents: lemir.c lempost.c dif-.lemrc dif-Makefile dif-lem.h dif-lemedit.c # dif-lemgeo.c dif-lemhelp.c dif-lemio.c dif-lemline.c dif-lemmain.c # dif-lemmisc.c dif-lemobj.c dif-lemobjsup.c dif-lempic.c dif-lemselect.c # dif-lemspecial.c dif-lemstart.c dif-lemstop.c dif-lemtick.c dif-lemx.c # runpatches echo x - lemir.c sed 's/^@//' > "lemir.c" <<'@//E*O*F lemir.c//' /* * lemir.c - lemming driver for Iris package * * copyright (c) by Alan W. Paeth, 1987. All rights reserved. */ #include "lem.h" #include <gl.h> #include <device.h> #define SOLID 0 #define DASHES 1 #define DOTS 2 #define DEFWIDTH 512 #define DEFHEIGHT 512 #define SELMENU "Selections%t|none%x14|delete%x4|box%x2|ellipse%x5|vector%x22|undo%x21|refresh%x12" #define NOSELMENU "No Select%t|all%x1|read%x18|write%x23|output%x15|quit%x17|undo%x21|refresh%x12" int sysmsgloc; char sysmsg[120]; long winid, selmenu, noselmenu; long left, right, bottom, top, screenw, screenh; unsigned char maptab[256]; Cursor lemcur = { 0x0080, 0x0080, 0x0080, 0x0080, 0x03e0, 0x0630, 0x0410, 0x7c1f, 0x0410, 0x0630, 0x03e0, 0x0080, 0x0080, 0x0080, 0x0080, 0x0000 }; start() { #define NOWIND -1 winid = NOWIND; if (ismex()) { /* prefsize(DEFWIDTH, DEFHEIGHT); */ /* suggested, not mandated */ minsize(200, 200); winid = winopen("lemming 1.0"); if (winid == NOWIND) { fprintf(stderr, "can't open window"); exit(1); } wintitle("lemming 1.0"); } else ginit(); greset(); writemask(0x7); qdevice(KEYBD); qdevice(LEFTMOUSE); qdevice(MIDDLEMOUSE); if (ismex()) { qdevice(MENUBUTTON); /* add for popup menus */ selmenu = defpup(SELMENU); noselmenu = defpup(NOSELMENU); qdevice(REDRAW); /* must be done for MEX to post to queue! */ } tie(LEFTMOUSE, MOUSEX, MOUSEY); tie(MIDDLEMOUSE, MOUSEX, MOUSEY); cblack = BLACK; cwhite = WHITE; cred = RED; cgreen = GREEN; tickdot = 0; deflinestyle(1, 0x00ff); deflinestyle(2, 0x0303); lsbackup(1); defcursor(1, lemcur); curorigin(1, 8, 7); setcursor(1, 0x7, 0xffffff); resize(); } stop() { setcursor(0, 0x7, 0x7); if (ismex()) { if (winid != NOWIND) winclose(winid); } gexit(); } resize() { if (ismex()) { getsize(&screenw, &screenh); getorigin(&left, &bottom); right = left + screenw; top = bottom + screenh; ortho2(0.0, (float)(screenw), 0.0, (float)(screenh)); viewport(0, screenw, 0, screenh); } else { bottom = 128; top = bottom + DEFHEIGHT; left = 256; right = left + DEFWIDTH; screenw = right - left; screenh = top - bottom; ortho2(0.0, (float)(screenw), 0.0, (float)(screenh)); viewport(left, right, bottom, top); } } getevent(xdn, ydn, xup, yup, ch) int *xdn, *ydn, *xup, *yup; char *ch; { static mousedown, midflag, postflag, xd, xu, yd, yu; short val, m, type; int ret; /* * special test for pending selection on middle button */ if (midflag && postflag) { *ch = C(I); /* ^I == <TAB> */ midflag = postflag = 0; return(CNTRL); } /* * on to the conventional testing */ ret = NOEVT; if (type = qtest()) switch(qread(&val)) { case LEFTMOUSE: case MIDDLEMOUSE: midflag = ((type == MIDDLEMOUSE) && !val); mousedown = val; if (mousedown) postflag = m = 0; break; case MOUSEX: case MOUSEY: if ((type == MOUSEX) && mousedown) { m |= 1; xd = val-left; } if ((type == MOUSEX) && !mousedown) { m |= 2; xu = val-left; } if ((type == MOUSEY) && mousedown) { m |= 4; yd = val-bottom; } if ((type == MOUSEY) && !mousedown) { m |= 8; yu = val-bottom; } if (m == 15) { m = 0; ret = MOUSE; *xdn = MIN(MAX(xd, 0), screenw); *ydn = MIN(MAX(yd, 0), screenh); *xup = MIN(MAX(xu, 0), screenw); *yup = MIN(MAX(yu, 0), screenh); postflag = 1; } break; case MENUBUTTON: if (val) { char code; /* pupmode(); */ /* mex document lies! */ code = dopup(anysel ? selmenu : noselmenu); /* endpupmode(); */ /* see above */ setcursor(1, 0x7, 0xffffff); /* mex took it away */ if (code != -1) { *ch = code; ret = CNTRL; } } break; case KEYBD: *ch = val; if (*ch) { if ((*ch >= ' ') && (*ch != '\177')) ret = ALPHA; else if (*ch > 0) ret = CNTRL; } break; case REDRAW: resize(); redraw(); break; default: /* unknown event in queue */ break; } return(ret); } drawvec(x0, y0, x1, y1, col, wid, emph) { cursoff(); setlinestyle( (emph==EMPHNONE) ? SOLID:((emph==EMPHBOLD) ? DASHES:DOTS) ); linewidth(wid); color(col); move2i(x0, y0); draw2i(x1, y1); curson(); } charshow(str) char *str; { int i; for(i=0; i<strlen(str); i++) sysmsg[sysmsgloc++] = str[i]; sysmsg[sysmsgloc] = '\0'; fontwrite(SYSFONT, 10, 10, sysmsg, EMPHNONE, cgreen); } charunshow(n) { fontwrite(SYSFONT, 10, 10, sysmsg, EMPHNONE, cblack); while (n--) { if (sysmsgloc) sysmsg[--sysmsgloc] = '\0'; } fontwrite(SYSFONT, 10, 10, sysmsg, EMPHNONE, cgreen); } erase() { cursoff(); color(BLACK); clear(); if (!ismex()) /* add border in vanilla version */ { drawvec(0, 0, screenw-1, 0, cgreen, 1, EMPHNONE); drawvec(0, 0, 0, screenh-1, cgreen, 1, EMPHNONE); drawvec(screenw-1, 0, screenw-1, screenh-1, cgreen, 1, EMPHNONE); drawvec(0, screenh-1, screenw-1, screenh-1, cgreen, 1, EMPHNONE); } curson(); } writescan(x, y, pixels, outaddr, col) int x, y, pixels, col; long *outaddr; { int dx; long mask; cursoff(); /* * remap bits for IRIS byte conventions */ swapshorts(outaddr, (pixels+31)/8); mask = 0x1; color(col); for(dx=0; dx<pixels; dx++) { if (mask & *outaddr) pnti(x+dx, screenh-1-y, 0); mask<<=1; if (!mask) { mask = 0x1; outaddr++; } } curson(); } /* * byte reversal stuff */ swapshorts(buf, len) register unsigned char *buf; { unsigned char c1, c2, c3, c4; register int count, i; if (!maptab[1]) maptabinit(); count = len/4; for (i=0; i<count; i++) { c1 = *buf++; c2 = *buf++; c3 = *buf++; c4 = *buf; *buf-- = maptab[c1]; *buf-- = maptab[c2]; *buf-- = maptab[c3]; *buf = maptab[c4]; buf += 4; } } maptabinit() { register int i, j; unsigned char mask; for(i = 0; i<256; i++) { mask = 0; for(j = 0; j < 8; j++) if (i & (1<<j)) mask |= 1<<(7-j); maptab[i] = mask; } } @//E*O*F lemir.c// chmod u=rw,g=r,o= lemir.c echo x - lempost.c sed 's/^@//' > "lempost.c" <<'@//E*O*F lempost.c//' /* * lempost.c - PostScript output processor * * copyright (c) by Alan W. Paeth, 1987. All rights reserved. */ /* * NOTE: this file may be substituted for "lempic.c" to provide * PostScript output. The module is not complete in that the author * as no easy access to verify the PostScript macros which are defined * for each of the various lemming internal primitives. It is hoped that * this macros will be completed by a regular PostScript user. */ #include "lem.h" FILE *f; int psize, pthick, pemph; char *pfont; writepicint(fname) char *fname; { char msgstr[50]; int i; f = (fname && (strlen(fname) > 0)) ? fopen(fname, "w") : 0; if (f) { pthick = psize = pemph = -1; postopen(); forobjects { if (Odel) continue; switch (Otype) { case TEXT: ptext(i); break; case LINE: pline(i); break; case BOX: pbox(i); break; case ELLI: pelli(i); break; } } postclose(); fclose(f); sprintf(msgstr, "PostScript output done [%s]", fname); msgpost(msgstr); } else { sprintf(msgstr, "PostScript output failed [%s]", fname); msgpost(msgstr); } free(fname); } writepic() { char *fname; if (lastobj == 1) msgpost("work area empty -- no output"); else { fname = prompt("PostScript file: "); writepicint(fname); free(fname); } } thick(i) { if (pthick != lemfont[Osizer].thick) { pthick = lemfont[Osizer].thick; fprintf(f, "%d stwid\n", pthick); } } emph(i) { if (Oemph != pemph) { switch(Oemph) { case EMPHNONE: out("snone"); break; case EMPHBOLD: out("sbold"); break; case EMPHITAL: out("sital"); break; } pemph = Oemph; } } font(i) { if ((Oemph != pemph) || (lemfont[Osizer].psize != psize)) { switch(Oemph) { case EMPHNONE: pfont = lemfont[Osizer].psr; break; case EMPHBOLD: pfont = lemfont[Osizer].psb; break; case EMPHITAL: pfont = lemfont[Osizer].psi; break; } pemph = Oemph; psize = lemfont[Osizer].psize; fprintf(f, "/%s %d sfont\n", pfont, psize); } } ptext(i) { font(i); fprintf(f, "(%s) %d %d", Otext, Oxs, Oys); switch(Oalign) { case ALIGNLEFT: out(" ltext"); break; case ALIGNRGHT: out(" rtext"); break; case ALIGNCENT: out(" ctext"); break; } } pline(i) { thick(i); emph(i); fprintf(f, "%d %d %d %d ", Oxs, Oys, Oxe, Oye); switch(Oalign) { case ALIGNLEFT: out("lline"); case ALIGNRGHT: out("rline"); case ALIGNCENT: out("cline"); } } pbox(i) { thick(i); emph(i); fprintf(f, "%d %d %d %d boxer\n", Ox, Oy, ABS(Ow), ABS(Oh)); } pelli(i) { thick(i); emph(i); fprintf(f, "%d %d %d %d ellip\n", Ox, Oy, ABS(Ow), ABS(Oh)); } out(s) char *s; { fprintf(f, "%s\n", s); } postopen() { out("%!PSAdobe-1.0"); out("%%Creator: AWPaeth@watCGL"); out("%%Title: Lemming-PostScript"); out("%%Pages: 1"); out("%%DocumentFonts Times-Bold"); out("%%BoundingBox 0 0 612 792"); out("%%EndComments"); out("%%EndProlog"); out("%%Page: 0 1"); out("%"); out("% attribute macros"); out("/sbold {[4 4] 0 setdash} def"); out("/sital {[1 1] 0 setdash} def"); out("/snone {[ ] 0 setdash} def"); out("/swidt {setlinewidth} def"); out("/sfont {exch scalefont setfont} def"); out("%"); out("% object macros"); out("/ltext {moveto 5 0 8#040 4 3 roll widthshow} def"); out("/ctext {moveto dup stringwidth pop 2 div neg 0 rmoveto show} def"); out("/rtext {moveto dup stringwidth pop neg 0 rmoveto show} def"); out("/cline {newpath 2 4 roll moveto drawto stroke} def"); out("/lline {newpath 2 4 roll moveto drawto stroke} def"); out("/rline {newpath 2 4 roll moveto drawto stroke} def"); out("/boxer {lline} def"); out(" /edict {/edict 8 dict def"); out(" edict /mtrx matrix put"); out("/ellip { edict begin /endangle exch def /startangle exch def"); out(" yrad exch def xrad exch def /y exch def /x exch def"); out(" /savematrix mtrx currentmatrix def x y translate"); out(" x y translate xrad yrad scazle 0 0 1 startangle endangle arc"); out(" savematrix setmatrix end stroke }"); out("%"); out("% global defaults"); out("%"); out("1 setlinecap"); out("1 setlinejoin"); out("%"); out("% THE STUFF"); out("%"); } postclose() { out("showpage"); out("%"); out("%%Trailer"); out("%%Pages: 1"); } @//E*O*F lempost.c// chmod u=rw,g=r,o= lempost.c echo x - dif-.lemrc sed 's/^@//' > "dif-.lemrc" <<'@//E*O*F dif-.lemrc//' diff ./.lemrc /u/awpaeth/lem/src/.lemrc 11,19c11,19 < 12 1 TimesRoman TR TB TI Times-Bold Times-Bold Times-Bold < 10 2 TimesRoman TR TB TI Times-Bold Times-Bold Times-Bold < 18 3 TimesRoman TR TB TI Times-Bold Times-Bold Times-Bold < 12 4 Helvetica SR SB SI Times-Bold Times-Bold Times-Bold < 10 5 Helvetica SR SB SI Times-Bold Times-Bold Times-Bold < 18 6 Helvetica SR SB SI Times-Bold Times-Bold Times-Bold < 6 7 Helvetica SR SB SI Times-Bold Times-Bold Times-Bold < 10 8 Gacha CW CW CW Times-Bold Times-Bold Times-Bold < 12 9 Hippo GM GM GM Times-Bold Times-Bold Times-Bold --- > 12 1 TimesRoman TR TB TI Times-Roman Times-Bold Times-Italic > 10 2 TimesRoman TR TB TI Times-Roman Times-Bold Times-Italic > 18 3 TimesRoman TR TB TI Times-Roman Times-Bold Times-Italic > 12 4 Helvetica SR SB SI Helvetica Helvetica-Bold Helvetica-Oblique > 10 5 Helvetica SR SB SI Helvetica Helvetica-Bold Helvetica-Oblique > 18 6 Helvetica SR SB SI Helvetica Helvetica-Bold Helvetica-Oblique > 6 7 Helvetica SR SB SI Helvetica Helvetica-Bold Helvetica-Oblique > 10 8 Gacha CW CW CW Courier Courier-Bold Courier-Oblique > 12 9 Hippo GM GM GM Symbol Symbol Symbol 23c23 < 18 1 OldEnglish oe oe oe Times-Bold Times-Bold Times-Bold --- > 18 1 OldEnglish oe oe oe unknown unknown unknown @//E*O*F dif-.lemrc// chmod u=rw,g=r,o=r dif-.lemrc echo x - dif-Makefile sed 's/^@//' > "dif-Makefile" <<'@//E*O*F dif-Makefile//' diff ./Makefile /u/awpaeth/lem/src/Makefile 23d22 < lempic.o \ 31,32c30 < lemundo.o \ < lemvec.o --- > lemundo.o 34,35c32 < lemik:: $(OBJ) lemik.o < cc $(CFLAGS) $(OBJ) lemik.o -lIkonas -lLocator -lm -o /u/awpaeth/bin/lemik --- > NOVEC = lemvec.o 37,38c34,64 < lemx:: $(OBJ) lemx.o < cc $(CFLAGS) $(OBJ) lemx.o -lX -lm -o /u/awpaeth/bin/lemx --- > POST = lempost.o > PIC = lempic.o > > ADAGE = lemik.o > XWIND = lemx.o > IRIS = lemir.o > > > lemik:: $(OBJ) $(PIC) $(NOVEC) $(ADAGE) > cc $(CFLAGS) $(OBJ) $(PIC) $(NOVEC) $(ADAGE) \ > -lIkonas -lLocator -lm -o /u/awpaeth/bin/lemik > > lemikps:: $(OBJ) $(POST) $(NOVEC) $(ADAGE) > cc $(CFLAGS) $(OBJ) $(PIC) $(NOVEC) $(ADAGE) \ > -lIkonas -lLocator -lm -o /u/awpaeth/bin/lemikps > > lemx:: $(OBJ) $(PIC) $(NOVEC) $(XWIND) > cc $(CFLAGS) $(OBJ) $(PIC) $(NOVEC) $(XWIND) \ > -lXr -lX -lm -o /u/awpaeth/bin/lemx > > lemxps:: $(OBJ) $(POST) $(NOVEC) $(XWIND) > cc $(CFLAGS) $(OBJ) $(POST) $(NOVEC) $(XWIND) \ > -lXr -lX -lm -o /u/awpaeth/bin/lemxps > > lemir:: $(OBJ) $(PIC) $(IRIS) > cc $(CFLAGS) $(OBJ) $(PIC) $(IRIS) > -lm -Zg -o /u/awpaeth/bin/lemir > > lemirps:: $(OBJ) $(POST) $(IRIS) > cc $(CFLAGS) $(OBJ) $(POST) $(IRIS) > -lm -Zg -o /u/awpaeth/bin/lemirps @//E*O*F dif-Makefile// chmod u=rw,g=r,o=r dif-Makefile echo x - dif-lem.h sed 's/^@//' > "dif-lem.h" <<'@//E*O*F dif-lem.h//' diff ./lem.h /u/awpaeth/lem/src/lem.h 14c14 < * useful arithmetic functions --- > * useful ASCII functions 17,19d16 < #define MIN(a,b) ((a)<(b)?(a):(b)) < #define MAX(a,b) ((a)>(b)?(a):(b)) < #define ABS(a) ((a)>0?(a):(-(a))) 22a20,24 > /* see "lemmisc.c" */ > /* #define MIN(a,b) ((a)<(b)?(a):(b)) */ > /* #define MAX(a,b) ((a)>(b)?(a):(b)) */ > /* #define ABS(a) ((a)>0?(a):(-(a))) */ > 163a166 > #define SNAPTOL 8 /* max units to move when placing point along a line */ 276c279 < char *salloc(), *prompt(), getstroke(); --- > char *salloc(), *prompt(), *filefind(), getstroke(); @//E*O*F dif-lem.h// chmod u=rw,g=r,o=r dif-lem.h echo x - dif-lemedit.c sed 's/^@//' > "dif-lemedit.c" <<'@//E*O*F dif-lemedit.c//' diff ./lemedit.c /u/awpaeth/lem/src/lemedit.c 76,77c76 < int i, j, g, dx, dy; < if (!anysel) return; --- > int dx, dy; 79a79,85 > copyoffset(dx, dy); > } > > copyoffset(dx, dy) > { > int i, j, g; > if (!anysel) return; 96c102 < objectop(i, SEL, UNDEL); --- > /* objectop(i, SEL, SEL); */ @//E*O*F dif-lemedit.c// chmod u=rw,g=r,o=r dif-lemedit.c echo x - dif-lemgeo.c sed 's/^@//' > "dif-lemgeo.c" <<'@//E*O*F dif-lemgeo.c//' diff ./lemgeo.c /u/awpaeth/lem/src/lemgeo.c 18c18 < hypot(x, y) --- > ihypot(x, y) 28c28 < return(hypot(x1-x0, y1-y0)); --- > return(ihypot(x1-x0, y1-y0)); @//E*O*F dif-lemgeo.c// chmod u=rw,g=r,o=r dif-lemgeo.c echo x - dif-lemhelp.c sed 's/^@//' > "dif-lemhelp.c" <<'@//E*O*F dif-lemhelp.c//' diff ./lemhelp.c /u/awpaeth/lem/src/lemhelp.c 10c10 < #define HELPCHARS "[IHMABCDEFGLNOPRSTUVWX^?" --- > #define HELPCHARS "[IHMABDEFGKLNOPRSTUVWX^?" 15c15 < msgpost("[help]: <space> - all; \"/\" - fonts; <key> - function: "); --- > msgpost("[help]: ? - all; \"/\" - fonts; <key> - function: "); 17c17 < if (c == ' ') helpall(); --- > if (c == '?') helpall(); 32c32 < case 'C': s = "^C Copy selections (in place)"; break; --- > case 'C': s = "^C Curve (arc) line [unimplemented]"; break; 39d38 < case 'L': s = "^L Refresh display"; break; 41a41,42 > case 'K': s = "^K Copy selections (with offset)"; break; > case 'L': s = "^L Refresh display"; break; 47c48 < case 'S': s = "^Sc Special function escape"; break; --- > case 'S': s = "^Sc Special function escape (caps for copy)"; break; @//E*O*F dif-lemhelp.c// chmod u=rw,g=r,o=r dif-lemhelp.c echo x - dif-lemio.c sed 's/^@//' > "dif-lemio.c" <<'@//E*O*F dif-lemio.c//' diff ./lemio.c /u/awpaeth/lem/src/lemio.c 8a9,32 > char *filefind(fname) > char *fname; > { > FILE *f; > char filename[50]; > f = 0; > if (fname && (strlen(fname) > 0)) > { > sprintf(filename, "%s", fname, LEMEXTN); > f = fopen(filename, "r"); > if (!f) > { > sprintf(filename, "%s.%s", fname, LEMEXTN); > f = fopen(filename, "r"); > } > if (f) > { > fclose(f); > return(salloc(filename)); > } > } > return(0); > } > 11c35,66 < int i; --- > char *fname, *fname2, msgstr[50]; > FILE *f; > if (lastobj == 1) > { > msgpost("work area empty -- no write"); > return; /* nothing on display -- fast return */ > } > sprintf(msgstr, firstfile ? "output file [%s]:":"output file: ",firstfile); > fname = prompt(msgstr); > f = (fname && (strlen(fname) > 0)) ? fopen(fname, "r") : 0; > if (f) > { > sprintf(msgstr,"**write fail** file [%s] exists", fname); > msgpost(msgstr); > free(fname); > fclose(f); > return; > } > if (!fname || (strlen(fname) == 0)) > { > if (fname) free(fname); > fname = salloc(firstfile); > if (!fname) > { > msgpost("**write fail** no filename given"); > return; > } > } > writefileint(fname); > } > > writefileint(fname) 12a68,70 > { > int i; > char msgstr[50]; 14,16c72 < if (lastobj == 1) return; /* nothing on display -- fast return */ < fname = prompt("output file: "); < f = (fname && (strlen(fname) > 1)) ? fopen(fname, "w") : 0; --- > f = fopen(fname, "w"); 32c88,89 < msgpost("output done"); --- > sprintf(msgstr, "output done [%s]", fname); > msgpost(msgstr); 34c91,95 < else msgpost("output failed"); --- > else > { > sprintf(msgstr, "output failed [%s]", fname); > msgpost(msgstr); > } 42c103 < char *s, fline[MAXCHAR+50]; --- > char *s, msgstr[50], *goodname, fline[MAXCHAR+50]; 44,45c105,106 < f = 0; < if (fname && (strlen(fname) > 0)) --- > goodname = filefind(fname); > if (goodname) 47,56c108 < f = fopen(fname, "r"); < if (!f) < { < char filename[100]; < sprintf(filename, "%s.%s", fname, LEMEXTN); < f = fopen(filename, "r"); < } < } < if (f) < { --- > f = fopen(goodname, "r"); 91c143,145 < msgpost("input done"); --- > sprintf(msgstr, "input done [%s]", goodname); > free(goodname); > msgpost(msgstr); 93c147,152 < else msgpost("bogus input file"); --- > else > { > sprintf(msgstr, "bogus input file [%s]", goodname); > free(goodname); > msgpost(msgstr); > } 95c154,158 < else msgpost("input not found"); --- > else > { > sprintf(msgstr, "input not found [%s]", fname); > msgpost(msgstr); > } @//E*O*F dif-lemio.c// chmod u=rw,g=r,o=r dif-lemio.c echo x - dif-lemline.c sed 's/^@//' > "dif-lemline.c" <<'@//E*O*F dif-lemline.c//' diff ./lemline.c /u/awpaeth/lem/src/lemline.c 34c34 < hy = hypot(Ow, Oh); --- > hy = ihypot(Ow, Oh); 73,76c73,108 < int frac; < frac = (ABS(Ow) > ABS(Oh)) ? (12*(*x-Oxs)+6)/Ow : (12*(*y-Oys)+6)/Oh; < *x = ((12-frac)*Oxs + frac*Oxe)/12; < *y = ((12-frac)*Oys + frac*Oye)/12; --- > int j, prox, oldprox; > long fx, fy, oldfx, oldfy, snap; > static long frac, snapfrac[5] = { 150, 200, 300, 400, 450 }; > oldprox = SNAPTOL; > /* > * frac is fractional distance along segment in 1/600 units. Update (*x,*y) > * to the nearest point along the line. > */ > frac = (ABS(Ow)>ABS(Oh)) ? (600*(*x-Oxs)+300)/Ow:(600*(*y-Oys)+300)/Oh; > *x = ((600-frac)*Oxs + frac*Oxe)/600; > *y = ((600-frac)*Oys + frac*Oye)/600; > /* > * check to see if there is a nearby cardinal point along this line segment, > * and if so, snap to that point exactly. > */ > for (j=0; j<5; j++) > { > snap = snapfrac[j]; > fx = ((600-snap)*Oxs + snap*Oxe + 300)/600; > fy = ((600-snap)*Oys + snap*Oye + 300)/600; > prox = dist(*x, *y, fx, fy); > if (prox < oldprox) > { > oldfx = fx; > oldfy = fy; > oldprox = prox; > } > } > /* > * (oldfx, oldfy) have nearest approach to a cardinal point. Use it or lose it. > */ > if (oldprox < SNAPTOL) > { > *x = oldfx; > *y = oldfy; > } 99c131 < h = hypot(Ow, Oh)*13; --- > h = ihypot(Ow, Oh)*13; 112c144 < h = hypot(Ow, Oh)*13; --- > h = ihypot(Ow, Oh)*13; @//E*O*F dif-lemline.c// chmod u=rw,g=r,o=r dif-lemline.c echo x - dif-lemmain.c sed 's/^@//' > "dif-lemmain.c" <<'@//E*O*F dif-lemmain.c//' diff ./lemmain.c /u/awpaeth/lem/src/lemmain.c 31c31 < case C(C): copysel(); break; --- > /* case C(C): curveify(); break; */ 41c41 < /* case C(K): curveify(); break; */ --- > case C(K): copysel(); break; @//E*O*F dif-lemmain.c// chmod u=rw,g=r,o=r dif-lemmain.c echo x - dif-lemmisc.c sed 's/^@//' > "dif-lemmisc.c" <<'@//E*O*F dif-lemmisc.c//' diff ./lemmisc.c /u/awpaeth/lem/src/lemmisc.c 8a9,19 > > /* > * The following started life as #define's but some compilers couldn't > * swallow the complex nested expressions generated. If speed is an issue, > * then putting these back in "lem.h" might help a bit. > */ > > MIN(a,b) { return((a)<(b)?(a):(b)); } > MAX(a,b) { return((a)>(b)?(a):(b)); } > ABS(a) { return((a)>0?(a):(-(a))); } > @//E*O*F dif-lemmisc.c// chmod u=rw,g=r,o=r dif-lemmisc.c echo x - dif-lemobj.c sed 's/^@//' > "dif-lemobj.c" <<'@//E*O*F dif-lemobj.c//' diff ./lemobj.c /u/awpaeth/lem/src/lemobj.c 24,27c24,27 < case LINE: return(linenearpt(i, x, y)); break; < case TEXT: return(textnearpt(i, x, y)); break; < case BOX: return( boxnearpt(i, x, y)); break; < case ELLI: return(ellinearpt(i, x, y)); break; --- > case LINE: return(linenearpt(i, x, y)); > case TEXT: return(textnearpt(i, x, y)); > case BOX: return( boxnearpt(i, x, y)); > case ELLI: return(ellinearpt(i, x, y)); 35,38c35,38 < case TEXT: return(textinrect(i, xl, yl, xh, yh)); break; < case LINE: return(lineinrect(i, xl, yl, xh, yh)); break; < case BOX: return( boxinrect(i, xl, yl, xh, yh)); break; < case ELLI: return(elliinrect(i, xl, yl, xh, yh)); break; --- > case TEXT: return(textinrect(i, xl, yl, xh, yh)); > case LINE: return(lineinrect(i, xl, yl, xh, yh)); > case BOX: return( boxinrect(i, xl, yl, xh, yh)); > case ELLI: return(elliinrect(i, xl, yl, xh, yh)); 46,49c46,49 < case TEXT: return(textcantug(i, x, y)); break; < case LINE: return(linecantug(i, x, y)); break; < case BOX: return( boxcantug(i, x, y)); break; < case ELLI: return(ellicantug(i, x, y)); break; --- > case TEXT: return(textcantug(i, x, y)); > case LINE: return(linecantug(i, x, y)); > case BOX: return( boxcantug(i, x, y)); > case ELLI: return(ellicantug(i, x, y)); @//E*O*F dif-lemobj.c// chmod u=rw,g=r,o=r dif-lemobj.c echo x - dif-lemobjsup.c sed 's/^@//' > "dif-lemobjsup.c" <<'@//E*O*F dif-lemobjsup.c//' diff ./lemobjsup.c /u/awpaeth/lem/src/lemobjsup.c 7d6 < #include <math.h> /* to define "double floor()" */ 8a8,9 > > double floor(); /* from math library (we don't want y1() as well) */ @//E*O*F dif-lemobjsup.c// chmod u=rw,g=r,o=r dif-lemobjsup.c echo x - dif-lempic.c sed 's/^@//' > "dif-lempic.c" <<'@//E*O*F dif-lempic.c//' diff ./lempic.c /u/awpaeth/lem/src/lempic.c 18a19 > char msgstr[50]; 20c21 < f = (fname && (strlen(fname) > 1)) ? fopen(fname, "w") : 0; --- > f = (fname && (strlen(fname) > 0)) ? fopen(fname, "w") : 0; 56c57,58 < msgpost("pic output done"); --- > sprintf(msgstr, "pic output done [%s]", fname); > msgpost(msgstr); 58c60,64 < else msgpost("pic output failed"); --- > else > { > sprintf(msgstr, "pic output failed [%s]", fname); > msgpost(msgstr); > } 66,68c72,78 < fname = prompt("pic file: "); < writepicint(fname); < free(fname); --- > if (lastobj == 1) msgpost("work area empty -- no output"); > else > { > fname = prompt("pic file: "); > writepicint(fname); > free(fname); > } @//E*O*F dif-lempic.c// chmod u=rw,g=r,o=r dif-lempic.c echo x - dif-lemselect.c sed 's/^@//' > "dif-lemselect.c" <<'@//E*O*F dif-lemselect.c//' diff ./lemselect.c /u/awpaeth/lem/src/lemselect.c 11c11 < if (markobj) --- > if (markobj && objs[markobj]) @//E*O*F dif-lemselect.c// chmod u=rw,g=r,o=r dif-lemselect.c echo x - dif-lemspecial.c sed 's/^@//' > "dif-lemspecial.c" <<'@//E*O*F dif-lemspecial.c//' diff ./lemspecial.c /u/awpaeth/lem/src/lemspecial.c 9a10,14 > /* > * note: x1 and y1 renamed to X1 and Y1 because of conflict with > * Bessel functions of the same name (in the math.h library) > */ > 12a18 > int t; 14a21 > t = (UC(ch) == ch); 17,22c24,29 < case 'F': flip(); break; < case 'C': ccw(); break; < case 'M': magnify(); break; < case 'R': rotate(); break; < case 'S': stretch(); break; < case 'A': align(); break; --- > case 'F': if (t) copyoffset(0,0); flip(); if (t) redraw(); break; > case 'C': if (t) copyoffset(0,0); ccw(); if (t) redraw(); break; > case 'M': if (t) copyoffset(0,0); magnify(); if (t) redraw(); break; > case 'R': if (t) copyoffset(0,0); rotate(); if (t) redraw(); break; > case 'S': if (t) copyoffset(0,0); stretch(); if (t) redraw(); break; > case 'A': if (t) copyoffset(0,0); align(); if (t) redraw(); break; 80c87 < int x1, y1, x2, y2, xs, ys, xe, ye; --- > int X1, Y1, x2, y2, xs, ys, xe, ye; 82c89 < if (findmark(&x1, &y1, &x2, &y2)) --- > if (findmark(&X1, &Y1, &x2, &y2)) 86,87c93,94 < xe = x1-markx; < ye = y1-marky; --- > xe = X1-markx; > ye = Y1-marky; 102c109 < int x1, y1, x2, y2, xs, ys, xe, ye; --- > int X1, Y1, x2, y2, xs, ys, xe, ye; 104c111 < if (findmark(&x1, &y1, &x2, &y2)) --- > if (findmark(&X1, &Y1, &x2, &y2)) 108,109c115,116 < xe = x1-markx; < ye = y1-marky; --- > xe = X1-markx; > ye = Y1-marky; 121c128 < int x1, y1, x2, y2, xs, ys, xe, ye; --- > int X1, Y1, x2, y2, xs, ys, xe, ye; 123c130 < if (findmark(&x1, &y1, &x2, &y2)) --- > if (findmark(&X1, &Y1, &x2, &y2)) 127,128c134,135 < xe = x1-markx; < ye = y1-marky; --- > xe = X1-markx; > ye = Y1-marky; 143c150 < int x1, y1, x2, y2, xs, ys, xe, ye, scale; --- > int X1, Y1, x2, y2, xs, ys, xe, ye, scale; 145c152 < if (findmark(&x1, &y1, &x2, &y2)) --- > if (findmark(&X1, &Y1, &x2, &y2)) 149,150c156,157 < xe = x1-markx; < ye = y1-marky; --- > xe = X1-markx; > ye = Y1-marky; 162,163c169,170 < findmark(x1, y1, x2, y2) < int *x1, *y1, *x2, *y2; --- > findmark(X1, Y1, x2, y2) > int *X1, *Y1, *x2, *y2; 183,184c190,191 < case ALIGNCENT: *x1 = s ? Oxe : Oxs; < *y1 = s ? Oye : Oys; --- > case ALIGNCENT: *X1 = s ? Oxe : Oxs; > *Y1 = s ? Oye : Oys; @//E*O*F dif-lemspecial.c// chmod u=rw,g=r,o=r dif-lemspecial.c echo x - dif-lemstart.c sed 's/^@//' > "dif-lemstart.c" <<'@//E*O*F dif-lemstart.c//' diff ./lemstart.c /u/awpaeth/lem/src/lemstart.c 54c54 < if (!firstfile) firstfile = argv[i]; /* record first input file */ --- > if (!firstfile) firstfile=filefind(argv[i]); /* record 1st input */ @//E*O*F dif-lemstart.c// chmod u=rw,g=r,o=r dif-lemstart.c echo x - dif-lemstop.c sed 's/^@//' > "dif-lemstop.c" <<'@//E*O*F dif-lemstop.c//' diff ./lemstop.c /u/awpaeth/lem/src/lemstop.c 22a23 > msgclear(); @//E*O*F dif-lemstop.c// chmod u=rw,g=r,o=r dif-lemstop.c echo x - dif-lemtick.c sed 's/^@//' > "dif-lemtick.c" <<'@//E*O*F dif-lemtick.c//' diff ./lemtick.c /u/awpaeth/lem/src/lemtick.c 96,97c96,97 < y = tyoff; < for(iy=0; iy<ylim; iy++) --- > y = tyoff - 2*ty; > for(iy=0; y<screenh; iy++) @//E*O*F dif-lemtick.c// chmod u=rw,g=r,o=r dif-lemtick.c echo x - dif-lemx.c sed 's/^@//' > "dif-lemx.c" <<'@//E*O*F dif-lemx.c//' diff ./lemx.c /u/awpaeth/lem/src/lemx.c 6a7,22 > /* > Notes: there are two "#ifdef" statments in this code. > > [1] #ifdef title > This allows Xwindow toolkit titlebars to be added. They are > not well implemented, as they subtract live area from the > current window, and are not a true subwindow. Further, proper > timing of their redraw does not interact well with the redraw > signal and lemming window refresh fielded from the event queue. > [2] #ifdef vax > This allows proper byte ordering which allows the proper display > of text glyphs. If not true, an alternate byte ordering for a > 32-bit integer (halfword swap) is chosen as the most likely ordering > for the hardware. > */ > 8a25 > #include <X/Xr/Xrlib.h> 17a35,69 > xrWindowData windata; > #ifdef title > xrEditor *tbar; > xrTitleBarInfo titlebar = > { > 0, /* window Id */ > {0,0,0,0}, /* editor rectangle */ > XrVISIBLE | XrSENSITIVE, /* editor state */ > -1, -1, /* editor colors - use defaults */ > NULL, /* editor font - use defaults */ > "Hello World", /* Title name */ > NULL, /* gadget 1 - unused */ > NULL /* gadget 2 - unused */ > }; > #endif > > xrMenu *active_menu, *selmenu, *noselmenu; > > char noselmap[7] = { C(A), C(R), C(W), C(O), C(Q), C(U), C(L) }; > > INT8 *noselmenuItems[9] = > { > "\\KEAall", "\\KERread", "\\KEWwrite", "\\KEOoutput", > "\\KEQquit", "\\KEUundo", "\\KELrefresh" }; > > char selmap[7] = { C(N), C(D), C(B), C(E), C(V), C(U), C(L) }; > > INT8 *selmenuItems[9] = > { "\\KENnone", "\\KEDdelete", "\\KEBbox", "\\KEEellipse", > "\\KEVvector", "\\KEUundo", "\\KELrefresh" }; > > xrMenuInfo selmenuinfo = { "Selections", selmenuItems, 7, NULL, 0 }; > > xrMenuInfo noselmenuinfo = { "No Select", noselmenuItems, 7, NULL, 1 }; > 22a75 > if (!XrInit(NULL)) err("Xrlib open failed"); 27a81,98 > /* > * create title bar > */ > XrInput(win, MSG_ADDWINDOW, &windata); > #ifdef title > titlebar.editorWindowId = win; > tbar = XrTitleBar(NULL, MSG_NEW, &titlebar); > #endif > /* > * create menus > */ > selmenu = XrMenu(NULL, MSG_NEW, &selmenuinfo); > noselmenu = XrMenu(NULL, MSG_NEW, &noselmenuinfo); > active_menu = noselmenu; > XrMenu(active_menu, MSG_ACTIVATEMENU, win); > /* > * get input and colors > */ 52c123,134 < getevent(xdn, ydn, xup, yup, ch) --- > /* > The X interface is not nice in menu binding. Rather than allowing the > user to pop up a menu of his own chosing in response to an event, the > menu is bound to a button throughout the application. Because we allow > two menus (select and noselect) to be tied to one button, we must take > the time to rebind on each call to "getevent", as this is the routine > called from the lemming command interpreter inner loop. Addditionally, > we maintain the state of the last menu bound, to avoid the overhead > of redundant rebindings to identical menus, if menus need not be changed. > */ > > getevent(xdn, ydn, xup, yup, ch) 55a138 > static int selflag; 56a140 > char *chptr; 58c142,167 < XWindowEvent(win, EV, &ev); --- > /* > * check for quick return on select (middle) key > */ > if (selflag) > { > selflag = 0; > *ch = C(I); /* force a pending <TAB> */ > return(CNTRL); > } > /* > * bind the correct menu to the rightmost mouse key > */ > if ((active_menu == noselmenu) && anysel) > { > active_menu = selmenu; > XrMenu(active_menu, MSG_ACTIVATEMENU, win); > } > else if ((active_menu == selmenu) && !anysel) > { > active_menu = noselmenu; > XrMenu(active_menu, MSG_ACTIVATEMENU, win); > } > /* > * see if this was a popup menu event > */ > XrInput(0,MSG_BLKHOTREAD,&ev); /* like XWindowEvent(win, EV, &ev); */ 60c169 < switch(ev.type) --- > if (ev.type & XrXRAY) 62,82c171,226 < case ButtonPressed: xsave = mx(&ev); < ysave = my(&ev); < break; < case ButtonReleased: *xdn = xsave; < *ydn = ysave; < *xup = mx(&ev); < *yup = my(&ev); < ret = MOUSE; < break; < case KeyPressed: *ch = *XLookupMapping(&ev, &count); < if (*ch) < { < if ((*ch >= ' ') && (*ch != '\177')) < ret = ALPHA; < else if (*ch > 0) ret = CNTRL; < } < break; < case ExposeRegion: < case ExposeWindow: checkwindowsize(); < redraw(); < break; --- > xrEvent *xrev = (xrEvent*) &ev; > if( xrev->inputType == XrMENU ) > { > *ch = active_menu == selmenu ? > selmap[xrev->value3] : noselmap[xrev->value3]; > ret = CNTRL; > } > } > /* > * normal event -- field it > */ > else switch(ev.type) > { > case ButtonPressed: > if (mbutton(&ev) != RightButton) > { /* left or middle */ > xsave = mx(&ev); > ysave = my(&ev); > } > break; > case ButtonReleased: > if (mbutton(&ev) != RightButton) > { > /* > * must offset y coordinates by -2 in SUN X implementation > */ > *xdn = MIN(MAX(xsave,0), screenw); > *ydn = MIN(MAX(ysave-2*tickdot,0),screenh); > *xup = MIN(MAX(mx(&ev), 0), screenw); > *yup = MIN(MAX(my(&ev)-2*tickdot,0),screenh); > if (mbutton(&ev) == MiddleButton) selflag = 1; > ret = MOUSE; > } > break; > case KeyPressed: > *ch = 0; > chptr = XLookupMapping(&ev, &count); > if (chptr) *ch = *chptr; /* may return null ptr */ > if (*ch) > { > if ((*ch >= ' ') && (*ch != '\177')) ret = ALPHA; > else if (*ch > 0) ret = CNTRL; > } > break; > case ExposeRegion: > case ExposeWindow: > checkwindowsize(); > redraw(); > #ifdef title > XrTitleBar(tbar, MSG_REDRAW, XrREDRAW_ALL); > #endif > break; > default: > XFeep(0); > if (ev.type == 0) break; > if(ev.type & XrXRAY) { xrEvent *xrev = (xrEvent*) &ev; } 196a341,346 > mbutton(ev) > XKeyEvent *ev; > { > return(ev->detail & 0xff); > } > 238a389 > #ifdef vax 242a394,399 > #else > *buf-- = maptab[c3]; > *buf-- = maptab[c4]; > *buf-- = maptab[c1]; > *buf = maptab[c2]; > #endif @//E*O*F dif-lemx.c// chmod u=rw,g=r,o=r dif-lemx.c echo x - runpatches sed 's/^@//' > "runpatches" <<'@//E*O*F runpatches//' patch .lemrc dif-.lemrc patch Makefile dif-Makefile patch lem.h dif-lem.h patch lemedit.c dif-lemedit.c patch lemgeo.c dif-lemgeo.c patch lemhelp.c dif-lemhelp.c patch lemio.c dif-lemio.c patch lemline.c dif-lemline.c patch lemmain.c dif-lemmain.c patch lemmisc.c dif-lemmisc.c patch lemobj.c dif-lemobj.c patch lemobjsup.c dif-lemobjsup.c patch lempic.c dif-lempic.c patch lemselect.c dif-lemselect.c patch lemspecial.c dif-lemspecial.c patch lemstart.c dif-lemstart.c patch lemstop.c dif-lemstop.c patch lemtick.c dif-lemtick.c patch lemx.c dif-lemx.c @//E*O*F runpatches// chmod u=rwx,g=rwx,o=rwx runpatches exiboiro