From don@brillig.umd.edu Sun Jan 1 23:04:52 1989 Date: Sun, 1 Jan 89 23:04:52 EST To: NeWS-makers@brillig.umd.edu Subject: RE: NeWS and DPS -- Analyzing Geschke's comments From: pacbell!hoptoad!gnu@ames.arc.nasa.gov (John Gilmore) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Dan Stenger quoted Charles Geschke of Adobe from a SIGGRAPH panel in an earlier message. I think Geschke's comments bear some careful analysis. I'm not saying that he intended to mislead, but he certainly said things in a way that leaves that possibility open: > "The technology of Display PostScript is something that we have actively been > working on as a graphics technology ever since the inception of our company > back in December of 1982. The technology of DPS is the PostScript interpreter, which they have indeed been working on since '82. It says nothing about when they started working on DPS itself. > ... It is a misconception that we did not want to > do Display PostScript, even though I'm certain that's the impression James had > [referring to an earlier comment about Adobe attempting to hire James Gosling > before he went to Sun]. This doesn't say that they DID want to do it. It says that if you think they DIDN'T want to do it, you are incorrect. They were not opposed to PostScript on screens; my recollection is that they were delighted by SunDEW; at that point PostScript was not a guaranteed success in the printer market, so a serious endorsement by Sun helped them. Later they realized that Sun's effort would make them no money because Sun wanted a product that would be licensable on terms like NFS, while Adobe's only terms are Draconian (NOBODY, BUT NOBODY gets source code). Kinda hard to do enough ports to make a 'standard', widely available window system, without source code. > Actually, from the very beginning, and our very first > licensees, many of them actively pursued the feasibility of PostScript for > displays." They may have "pursued the feasibility", but I guess they all decided it wasn't feasible -- until Sun went ahead and did it. -- John Gilmore {sun,pacbell,uunet,pyramid,amdahl}!hoptoad!gnu gnu@toad.com Love your country but never trust its government. -- from a hand-painted road sign in central Pennsylvania From don@brillig.umd.edu Mon Jan 2 00:47:29 1989 Date: Mon, 2 Jan 89 00:47:29 EST To: NeWS-makers@brillig.umd.edu Subject: RE: NeWS and DPS From: pacbell!hoptoad!gnu@ames.arc.nasa.gov (John Gilmore) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) After reading much of the DPS preliminary manual, my evaluation of the situation is that Adobe has largely reimplemented NeWS, but changed all the names of everything so that applications will not port between them. Clearly there are design differences in spots, and Adobe has made some performance hacks at the language level, where Sun didn't feel the need; but there is a strong fundamental similarity of design. Why Adobe chose to change all the names is less clear. Possibly a straight case of NIH (not invented here) combined with pretensions of control of the language. Possibly they, or their major customers DEC and NeXT, deliberately wanted to fragment the market to reduce its openness (ability of customers to move to competitors' equipment without breaking their software). I doubt DEC would shed a tear if PostScript on screens never quite took off, since that would leave their inferior X window system winner by default. What to do about it has me torn. In some ways I think Sun and other NeWS vendors (like me) should move to the DPS names, providing a compatability package for old NeWS applications. In other ways I think the NeWS community should thumb its nose at Adobe, let them remain incompatible, and beat them fair and square in the market instead. If they get away with making us play catch-up this time, they'll repeat it forever -- the standard IBM-style Fear/Uncertainty/Doubt game. -- John Gilmore {sun,pacbell,uunet,pyramid,amdahl}!hoptoad!gnu gnu@toad.com Love your country but never trust its government. -- from a hand-painted road sign in central Pennsylvania From don@brillig.umd.edu Tue Jan 3 19:45:39 1989 Date: Tue, 3 Jan 89 19:45:39 EST To: NeWS-makers@brillig.umd.edu Subject: RE: NeWS and DPS From: suntan!fajita!doc@Sun.COM (Tom Dockery) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) John Gilmore notes: >After reading much of the DPS preliminary manual, my evaluation of the >situation is that Adobe has largely reimplemented NeWS, but changed all >the names of everything so that applications will not port between them. > >Clearly there are design differences in spots, and Adobe has made some >performance hacks at the language level, where Sun didn't feel the >need; but there is a strong fundamental similarity of design. If the designs are that similar, then perhaps the solution, as others have already mentioned here, is for the user community to develop a de facto standard NeWS/DPS interface package. Owen Densmore's class.ps might fit here, as would a file (or files) of synonym and compatibility definitions. We have not yet begun to look at DPS, but as developers who desire as wide a range of hardware platforms as is reasonably supportable, it could be a fairly rational (or at least not too irrational) direction. Tom Dockery ...!sun!suntan!fajita!doc Market Focus Technologies, Inc. (but don't blame them for my opinions) From don@brillig.umd.edu Wed Jan 4 17:26:33 1989 Date: Wed, 4 Jan 89 17:26:33 EST To: NeWS-makers@brillig.umd.edu Subject: Dynamic Splines and tracking (track.ps) From: mcvax!cernvax!cui!pintado@uunet.uu.net (PINTADO Xavier) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) # This is a shell archive. Remove anything before this line, then # unpack it by saving it in a file and typing "sh file". (Files # unpacked will be owned by you and have default permissions.) # # This archive contains: # track.ps echo x - track.ps cat > "track.ps" << '//E*O*F track.ps//' #! /usr/NeWS/bin/psh % % This program illustrates some of the features of dynamic splines. % Dynamic splines with tracking have been presented in a paper % that has been published in the proceeedings of the Eurographics 88 % conference published by North-Holland. The reference is: % Xavier Pintado, Eugene Fiume, % Grafields: Field-Directed Dynamic Splines for interactive Motion % Control. % Proceedings of Eurographics 88, Nice France, North-Holland. % % Dynamic Splines and tracking are used here to mimic a pencil % with smothness control and inertia. In fact the trajectory is % tracking the position of the locator (mouse). It is not very % fast because everything has been implemented in postscript. % % from PINTADO@CGEUGE51 % have fun! % % TRACKER: version 0.1 Xavier Pintado CUI Universite de Geneve % Switzerland. % % How to run it: % You can run it in two ways: % 1-Start the NeWS server; make this program executable % with "chmod u+x "; type the program name. % 2-Start the NeWS server; type "psh ". % % Things to know: % The left mouse button is the pointing device. When you % press it the trajectory will be drawn. % The middle mouse button clears the screen. % The rigth mouse button pops-up the menus. % Frame Menus: % Destroy: Kills the program and the window. % Shrink : Shrinks the window to its minimal size (quite big) % and moves it to the lower left corner. % Stretch: Stretches the window to occupy the full size of the % screen. This is the comfortyable way to play with the % program. % Canvas Menu: % CONTROLS: displays the tracking parameters of the tracking % mechanism. Modify them interactively with the % sliders. % Raw Trajectory: Displays the poly-line described by the cursor % These buttons are in toggle mode. % % systemdict /Item known not {(NeWS/liteitem.ps) run} if /DrawWindow DefaultWindow dictbegin /P_cursor [0 0] def /P_begin [0 0] def /P_end [0 0] def /P_pres [0 0] def /D_begin [0 0] def /D_end [0 0] def /Tr_error [0 0] def /Tr_p_error [0 0] def /Field [0 0] def /Fi_aff .7 def /Err_aff .8 def /Err_resp .9 def /Friction .7 def % 1 - friction /State false def /Raw_Line? false def /Controls? false def /NbIntPts 2 def dictend classbegin /apoil {aload pop} def /herm_base 5 dict def /herm_table 10 array def /canvas_color 1 .8 .8 rgbcolor def /notify-friction { /Friction 1 panels /friction-slider get /ItemValue get 10 div sub def} def /notify-field-aff {/Fi_aff panels /field-aff-slider get /ItemValue get 10 div def} def /notify-err-aff {/Err_aff panels /error-aff-slider get /ItemValue get 10 div def} def /notify-err-resp {/Err_resp panels /error-resp-slider get /ItemValue get 10 div def} def /panels 4 dict def /make-sliders { panels begin /friction-slider (Friction: ) [0 10 3] /Right {{notify-friction} ThisWindow send} ClientCanvas 100 20 /new SliderItem send ClientCanvas setcanvas 0 0 /move 3 index send def /field-aff-slider (Field Aff:) [0 10 6] /Right {{notify-field-aff} ThisWindow send} ClientCanvas 100 20 /new SliderItem send ClientCanvas setcanvas 0 20 /move 3 index send def /error-aff-slider (Error Aff:) [0 10 7] /Right {{notify-err-aff} ThisWindow send} ClientCanvas 100 20 /new SliderItem send ClientCanvas setcanvas 0 40 /move 3 index send def /error-resp-slider (Error Resp:) [0 10 7] /Right {{notify-err-resp} ThisWindow send} ClientCanvas 100 20 /new SliderItem send ClientCanvas setcanvas 0 60 /move 3 index send def end panels forkitems } def %/new { % parentcanvas => drawindow % { % /new super send % init % } def /PaintClient { gsave ClientCanvas setcanvas ColorDisplay? {canvas_color}{0}ifelse fillcanvas % Controls? {panels paintitems} grestore } def /reshape { % x y w h => - /reshape super send /PaintClient self send } def /move-dynamics { % - => - gsave calculate-error calculate-field calculate-segment draw-segment grestore } def /update-cursor % - => - { gsave ClientCanvas setcanvas Raw_Line? {P_cursor apoil moveto} if /P_cursor [XLocation YLocation] def move-dynamics Raw_Line? {ColorDisplay? {.5 1 .5 setrgbcolor}{1 setgray} ifelse P_cursor apoil lineto stroke} if grestore } def /set-left-button { /State State not def } def /set-middle-button { gsave ClientCanvas setcanvas ColorDisplay? {canvas_color}{0}ifelse fillcanvas Controls? {panels paintitems} if grestore } def /enter-window { /State false def } def /exit-window { } def /hermite-base { % parameter [0.0 .. 1.0] => array [ 4 values ] herm_base begin /p exch def [ p dup dup 2 mul 3 sub mul mul 1 add p dup dup 2 neg mul 3 add mul mul p dup dup 2 sub mul 1 add mul p dup dup 1 sub mul mul ] end } def /hermite-table-fill { % - => - herm_base begin /c 0 def 1 NbIntPts 1 add div dup 1 { hermite-base herm_table exch c exch put /c c 1 add def} for end } def /calculate-error { /Tr_p_error Tr_error def /Tr_error [ P_end apoil P_cursor apoil exch 4 -1 roll sub 3 1 roll exch sub ] def } def /calculate-field { /Field [ Tr_error apoil Tr_p_error apoil 2 index exch sub Err_resp mul exch 3 index exch sub Err_resp mul 4 -1 roll add 3 1 roll add Err_aff mul exch Err_aff mul exch ] def } def /calculate-segment { /P_begin P_end def /D_begin D_end def /D_end [ D_end apoil Field apoil Fi_aff mul exch Fi_aff mul 4 -1 roll add 3 1 roll add Friction mul exch Friction mul exch] def /P_end [ P_begin apoil D_begin apoil D_end apoil exch 4 1 roll add .5 mul 3 1 roll add .5 mul 4 -1 roll add 3 1 roll add ] def } def /draw-segment { gsave 3 setlinewidth % width of trajectory ClientCanvas setcanvas P_begin apoil moveto herm_base begin 0 1 NbIntPts %1 sub { herm_table exch get apoil 4 -1 roll P_begin apoil 2 index mul /cy exch def mul /cx exch def 3 -1 roll P_end apoil 2 index mul /cy exch cy add def mul /cx exch cx add def exch D_begin apoil 2 index mul /cy exch cy add def mul /cx exch cx add def D_end apoil 2 index mul /cy exch cy add def mul /cx exch cx add def cx cy lineto } for end P_end apoil lineto State { ColorDisplay? {1 0 0 setrgbcolor}{1 setgray}ifelse stroke} if grestore } def /tracker { createevent dup begin /Name [ /LeftMouseButton /MiddleMouseButton /MouseDragged /EnterEvent /ExitEvent ] def /Priority 10 def /Exclusivity true def /Canvas ClientCanvas def end expressinterest createevent dup begin /Name /timereq def end expressinterest framebuffer setcanvas { awaitevent dup begin Name { /LeftMouseButton {set-left-button} /MiddleMouseButton {set-middle-button} /MouseDragged {update-cursor} /EnterEvent {enter-window} /ExitEvent {exit-window} /timereq {update-cursor} } case redistributeevent end } loop } def /track { /TrackProcess {tracker} fork def } def /timeinterrupt { createevent dup begin /Name /timereq def /TimeStamp currenttime 0.02 add def end sendevent } def % initialization /init {hermite-table-fill make-sliders track } def classend def /win framebuffer /new DrawWindow send def { /FrameLabel (Dynamic Splines demo) def /IconLabel (Dynamic) def /BorderRight 12 def /BorderLeft 12 def /ClientMinWidth 512 def /ClientMinHeight 512 def /ClientMenu [ (Destroy) { /destroy ThisWindow send} (CONTROLS) { {/Controls? Controls? not def} ThisWindow send {Controls? {panels paintitems} {}ifelse} ThisWindow send } (Raw Trajectory) {{/Raw_Line? Raw_Line? not def} ThisWindow send} ] /new DefaultMenu send def } win send /reshapefromuser win send /map win send { /FrameMenu [ (Destroy) { /destroy ThisWindow send} (shrink) {0 0 128 128 /reshape ThisWindow send} (stretch) {0 0 1152 900 /reshape ThisWindow send} ] /new DefaultMenu send def } win send /init win send //E*O*F track.ps// echo Possible errors detected by \'wc\' [hopefully none]: temp=/tmp/shar$$ trap "rm -f $temp; exit" 0 1 2 3 15 cat > $temp <<\!!! 325 1238 8105 track.ps !!! wc track.ps | sed 's=[^ ]*/==' | diff -b $temp - exit 0 From don@brillig.umd.edu Thu Jan 5 04:02:08 1989 Date: Thu, 5 Jan 89 04:02:08 EST To: NeWS-makers@brillig.umd.edu Subject: pspp version 0.04 From: siegel@hc.dspo.gov (josh Siegel) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) This is version 0.04 of my NeWS pritty printer. I hadn't had much time to work on it (only to use it) and so there were several bugs I had never gotten around to fixing that are now fixed. Hopefully, this should get them all. The most important change is that it should now handle things like class.ps correctly. I still don't have a manual page so you will have to look at README for all the info on how to use it. Please send comments, suggestions, flames to me as soon as possible since people are really beginning to look at this piece of uglyness and to use it. --Josh Siegel siegel@hc.dspo.gov #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # pspp # This archive created: Wed Jan 4 11:08:41 1989 export PATH; PATH=/bin:$PATH if test ! -d 'pspp' then echo shar: creating directory "'pspp'" mkdir 'pspp' fi echo shar: entering directory "'pspp'" cd 'pspp' echo shar: extracting "'pspp.l'" '(15737 characters)' if test -f 'pspp.l' then echo shar: will not over-write existing file "'pspp.l'" else sed 's/^ X//' << \SHAR_EOF > 'pspp.l' X X%{ X X/* X X Copyright (c) 1989, Josh Siegel X XYou may copy the pspp kit in whole or in part as long as you don't try to Xmake money off it, or pretend that you wrote it. X X Version 0.04 X Fixed a fix in 0.03 X Made it callable on files and sets of files. X X Version 0.03 X Fixed run away white space problem... X Fixed (()) matching X Fixed it turning (\(\)) into (\\(\\)) X X Version 0.02 X Added bracstack as well as fixing problems associated with class.ps X X Version 0.01 X initial release X*/ X X#define FLAG_BA 0x1 X#define FLAG_BB 0x2 X#define FLAG_BS 0x4 X#define FLAG_CBA 0x8 X#define FLAG_CBB 0x10 X#define FLAG_CEA 0x20 X#define FLAG_CEB 0x40 X#define FLAG_DA 0x80 X#define FLAG_DB 0x100 X#define FLAG_DBA 0x200 X#define FLAG_DBB 0x400 X#define FLAG_DEA 0x800 X#define FLAG_DEB 0x1000 X#define FLAG_EA 0x2000 X#define FLAG_EB 0x4000 X#define FLAG_LCA 0x8000 X#define FLAG_LCB 0x10000 X#define FLAG_RCA 0x20000 X#define FLAG_RCB 0x40000 X#define FLAG_PN 0x80000 X#define FLAG_IB 0x100000 X#define FLAG_IA 0x200000 X#define FLAG_LBB 0x400000 X#define FLAG_LBA 0x800000 X#define FLAG_RBB 0x1000000 X#define FLAG_RBA 0x2000000 X#define FLAG_GSB 0x4000000 X#define FLAG_GSA 0x8000000 X#define FLAG_GRB 0x10000000 X#define FLAG_GRA 0x20000000 X#define FLAG_GI 0x40000000 X#define FLAG_RA 0x80000000 X X#define DEFAULT_FLAG (FLAG_BA|FLAG_BB|FLAG_BS|FLAG_CBA|FLAG_CBB|\ X FLAG_CEA|FLAG_CEB|FLAG_DA|FLAG_DBA|FLAG_DBB|FLAG_DEA|\ X FLAG_DEB|FLAG_EA|FLAG_EB|FLAG_LCA|FLAG_RCB| \ X FLAG_PN | FLAG_IA | FLAG_GI) X X#define check_flag(x) ((x) & flags) X X#define STACK_LEVELS 32 X Xint neednew,i,level,braclevel,flags,minlevel; Xint minstack[STACK_LEVELS],flagstack[STACK_LEVELS],minstackpnt,flagstackpnt; Xint bracstack[STACK_LEVELS],bracpnt; X%} XW [ \t]+ X%% X\( { X int pcount; X X pcount=1; X i = 1; X X while(pcount) { X yytext[i]=input(); X switch(yytext[i]) { X case '\\': X i++; X yytext[i]=input(); X break; X case '(': X pcount++; X if(check_flag(FLAG_BS)) { X yytext[i++]='\\'; X yytext[i]='('; X } X break; X case ')': X pcount--; X if(pcount) { X if(check_flag(FLAG_BS)) { X yytext[i++]='\\'; X yytext[i]=')'; X } X } X break; X case '\n': X yytext[i++]='\\'; X yytext[i]='n'; X break; X default: break; X } X i++; X } X yytext[i]= '\0'; X newline(); X fprintf(yyout,"%s",yytext); X } X X\{[ \t]*\} { /* Yet another special case */ newline(); fprintf(yyout,yytext); } X X"def" { X if(check_flag(FLAG_DB)) X neednew=1; X newline(); X fprintf(yyout,"%s",yytext); X if(check_flag(FLAG_DA)) X neednew=1; X } X X"{" { X if(check_flag(FLAG_LCB)) X neednew=1; X newline(); X level++; X pushbraclevel(); X fprintf(yyout,"%s",yytext); X if(check_flag(FLAG_LCA)) X neednew=1; X } X X"}" { X if(check_flag(FLAG_RCB)) X neednew=1; X level--; X popbraclevel(); X newline(); X fprintf(yyout,"%s",yytext); X if(check_flag(FLAG_RCA)) X neednew=1; X } X X"begin"|"dictbegin"|"classbegin"|"["|"gsave" { X switch(yytext[0]) { X case 'd': X if(check_flag(FLAG_DBB)) X neednew=1; X break; X case 'b': X if(check_flag(FLAG_BB)) X neednew=1; X break; X case 'c': X if(check_flag(FLAG_CBB)) X neednew=1; X break; X case 'g': X if(check_flag(FLAG_GSB)) X neednew=1; X break; X case '[': X if(check_flag(FLAG_LBB)) X neednew=1; X break; X } X newline(); X X fprintf(yyout,"%s",yytext); X braclevel++; X switch(yytext[0]) { X case 'd': X if(check_flag(FLAG_DBA)) X neednew=1; X break; X case 'b': X if(check_flag(FLAG_BA)) X neednew=1; X break; X case 'c': X if(check_flag(FLAG_CBA)) X neednew=1; X break; X case 'g': X if(check_flag(FLAG_GSA)) X neednew=1; X if(!check_flag(FLAG_GI)) X braclevel--; X break; X case '[': X if(check_flag(FLAG_LBA)) X neednew=1; X break; X } X } X X X"end"|"dictend"|"classend"|"]"|"grestore" { X braclevel--; X switch(yytext[0]) { X case 'd': X if(check_flag(FLAG_DEB)) X neednew=1; X break; X case 'e': X if(check_flag(FLAG_EB)) X neednew=1; X break; X case 'c': X if(check_flag(FLAG_CEB)) X neednew=1; X break; X case 'g': X if(check_flag(FLAG_GRB)) X neednew=1; X if(!check_flag(FLAG_GI)) X braclevel++; X break; X case ']': X if(check_flag(FLAG_RBB)) X neednew=1; X break; X } X X newline(); X fprintf(yyout,"%s",yytext); X switch(yytext[0]) { X case 'd': X if(check_flag(FLAG_DEA)) X neednew=1; X break; X case 'e': X if(check_flag(FLAG_EA)) X neednew=1; X break; X case 'c': X if(check_flag(FLAG_CEA)) X neednew=1; X break; X case 'g': X if(check_flag(FLAG_GRA)) X neednew=1; X break; X case ']': X if(check_flag(FLAG_RBA)) X neednew=1; X break; X } X } X X(if|ifelse) { X X if(check_flag(FLAG_IB)) X neednew=1; X newline(); X fprintf(yyout,"%s",yytext); X if(check_flag(FLAG_IA)) X neednew=1; X } X^cdef { X level=0; X minlevel=0; X newline(); X fprintf(yyout,"%s",yytext); X level=1; /* Indent one so it looks ncie */ X braclevel=0; /* Reset the bracket level */ X bracpnt=0; /* Reset the stack */ X minlevel=1; X } X^\%\%=.*\n { X if(neednew) X fprintf(yyout,"\n"); X yytext[yyleng-1]='\0'; X fprintf(yyout,"%s",yytext); X parseflag(&yytext[3]); X neednew=1; X } X^#.*\n | X^\%.*\n { X if(neednew) X fprintf(yyout,"\n"); X yytext[yyleng-1]='\0'; X fprintf(yyout,"%s",yytext); X neednew=1; X } X^[ \t]+\%.*\n { X char *p; X X newline(); X yytext[yyleng-1]='\0'; X p = yytext; X while(*p!='%') p++; X fprintf(yyout,"%s",p); X neednew=1; X } X\%.*\n { X yytext[yyleng-1]='\0'; X fprintf(yyout,"%s",yytext); X neednew=1; X } X^{W} neednew=1; X{W} fprintf(yyout," "); X^[ \t]*\n { if(check_flag(FLAG_PN)) fprintf(yyout,"\n");} X\n neednew=1; X[^ \t\n\[\]\{\}\(]+ | X. {newline(); X fprintf(yyout,"%s",yytext); X ; /* Almost everything falls to this */ } X%% X X X Xmain(argc, argv) X int argc; X char *argv[]; X{ X X FILE *fp, *fopen(), *fpo; X char buff[255]; X int do_stdio; X X do_stdio = 1; X minstackpnt = 0; X flagstackpnt = 0; X bracpnt = 0; X neednew = 0; X level = 0; X braclevel = 0; X minlevel = 0; X flags = DEFAULT_FLAG; X X sprintf(buff, "%s/.pspp", getenv("HOME")); X X fp = fopen(buff, "r"); X X if(fp!=NULL) { X while(fgets(buff,255,fp)!=NULL) X parseflag(buff); X fclose(fp); X } X X while (--argc) { X if( argv[argc][0]=='-' || argv[argc][0]=='+' ) X parseflag(argv[argc]); X else X { X do_stdio = 0; X X sprintf(buff,"%s.BAK",argv[argc]); X unlink(buff); X if(rename(argv[argc],buff)!=0) { X perror("rename"); X exit(0); X } X fpo = fopen(argv[argc],"w"); X fp = fopen(buff,"r"); X yyin = fp; X yyout = fpo; X yylex(); X fprintf(fpo,"\n"); X fclose(fp); X fclose(fpo); X } X } X X if(do_stdio) { X yylex(); X fprintf(yyout,"\n"); X } X exit(0); X} Xnewline() X{ X int cnt; X X if (!neednew) X return; X X fprintf(yyout,"\n"); X X if (level < minlevel) /* Save ourselves from errors in the X postscript */ X level = minlevel; X X if(bracpnt>0) { X if(braclevel < bracstack[bracpnt-1]) X braclevel = bracstack[bracpnt-1]; X } else { X if(braclevel<0) X braclevel = 0; X } X X cnt = level + braclevel; X X while (cnt--) X fprintf(yyout," "); X X neednew = 0; X} Xparseflag(str) X char *str; X{ X char *p; X int effect, the_flag; X X X p = str; X X X while (*p) { X while (*p == ' ' || *p == '\t') X p++; X X effect = 1; /* Set flag (default) */ X the_flag = 0; X X switch (*p) { X case '+': X p++; X break; X case '-': X effect = 0; X p++; X break; X default: X break; X } X X /* X * I make no defense of the code below... later I will make a X * proper hash table (yes.. yes.. I know there are lots of X * incorrect sets ) X */ X X if(effect<2) X switch (p[0]) { X case 'b': X switch (p[1]) { X case 'a': X the_flag = FLAG_BA; X break; X case 'b': X the_flag = FLAG_BB; X break; X case 's': X the_flag = FLAG_BS; X break; X default: X break; X } X break; X case 'c': X if (p[1] == 'b') X if (p[2] == 'a') X the_flag = FLAG_CBA; X else X the_flag = FLAG_CBB; X else if (p[2] == 'a') X the_flag = FLAG_CEA; X else X the_flag = FLAG_CEB; X break; X case 'd': X switch (p[1]) { X case 'a': X the_flag = FLAG_DA; X break; X case 'b': X switch (p[2]) { X case 'a': X the_flag = FLAG_DBA; X break; X case 'b': X the_flag = FLAG_DBB; X break; X default: X the_flag = FLAG_DB; X break; X } X break; X case 'e': X if (p[2] == 'a') X the_flag = FLAG_DEA; X else X the_flag = FLAG_DEB; X break; X default: X break; X } X break; X case 'i': X if (p[1] == 'a') X the_flag = FLAG_IA; X else X the_flag = FLAG_IB; X break; X case 'e': X if (p[1] == 'a') X the_flag = FLAG_EA; X else X the_flag = FLAG_EB; X break; X case 'l': X if (p[1] == 'c') X if (p[2] == 'a') X the_flag = FLAG_LCA; X else X the_flag = FLAG_LCB; X else X if (p[2] == 'a') X the_flag = FLAG_LBA; X else X the_flag = FLAG_LBB; X break; X case 'g': X switch(p[1]) { X case 'i': X the_flag = FLAG_GI; X break; X case 's': X if(p[2]=='b') X the_flag = FLAG_GSB; X else X the_flag = FLAG_GSA; X break; X case 'r': X if(p[2]=='b') X the_flag = FLAG_GRB; X else X the_flag = FLAG_GRA; X break; X } X break; X case 'r': X switch(p[1]) { X case 'c': X if (p[2] == 'a') X the_flag = FLAG_RCA; X else X the_flag = FLAG_RCB; X break; X case 'b': X if (p[2] == 'a') X the_flag = FLAG_RBA; X else X the_flag = FLAG_RBB; X break; X case 'a': X the_flag = FLAG_RA; X break; X default: X break; X } X break; X case 'p': X the_flag = FLAG_PN; X break; X default: X break; X } X X if (the_flag) { X if (effect) X flags |= the_flag; X else X flags &= ~the_flag; X } X p++; X X while (*p >= 'a' && *p <= 'z') X p++; X } X} Xpushflag() X{ X flagstack[flagstackpnt]=flags; X X if(flagstackpnt0) X flagstackpnt--; X else X return; X X flags=flagstack[flagstackpnt]; X} Xpushmin() X{ X minstack[minstackpnt]=minlevel; X X if(minstackpnt0) X minstackpnt--; X else X return; X X minlevel=minstack[minstackpnt]; X} Xpushbraclevel() X{ X bracstack[bracpnt]=braclevel; X X if(bracpnt0) X bracpnt--; X else X return; X X braclevel=bracstack[bracpnt]; X} SHAR_EOF if test 15737 -ne "`wc -c < 'pspp.l'`" then echo shar: error transmitting "'pspp.l'" '(should have been 15737 characters)' fi fi # end of overwriting check echo shar: extracting "'Makefile'" '(897 characters)' if test -f 'Makefile' then echo shar: will not over-write existing file "'Makefile'" else sed 's/^ X//' << \SHAR_EOF > 'Makefile' XCFLAGS = -g X XLEX = lex -v X XDEST = . X XEXTHDRS = X XHDRS = X XLDFLAGS = X XLIBS = -ll X XLINKER = cc X XMAKEFILE = Makefile X XOBJS = pspp.o X XPRINT = pr X XPROGRAM = pspp X XSRCS = pspp.l X Xall: $(PROGRAM) X X${PROGRAM}.shar: $(SRCS) ${MAKEFILE} README test patchlevel.h X shar -a $(SRCS) ${MAKEFILE} README test patchlevel.h> ${PROGRAM}.shar X X$(PROGRAM): $(OBJS) X @echo -n "Loading $(PROGRAM) ... " X @$(LINKER) $(LDFLAGS) $(OBJS) $(LIBS) -o $(PROGRAM) X @echo "done" X Xclean:; @rm -f $(OBJS) X Xdepend:; @mkmf -f $(MAKEFILE) PROGRAM=$(PROGRAM) DEST=$(DEST) X Xindex:; @ctags -wx $(HDRS) $(SRCS) X Xinstall: $(PROGRAM) X @echo Installing $(PROGRAM) in $(DEST) X @install -s $(PROGRAM) $(DEST) X Xprint:; @$(PRINT) $(HDRS) $(SRCS) X Xprogram: $(PROGRAM) X Xtags: $(HDRS) $(SRCS); @ctags $(HDRS) $(SRCS) X Xupdate: $(DEST)/$(PROGRAM) X X### SHAR_EOF if test 897 -ne "`wc -c < 'Makefile'`" then echo shar: error transmitting "'Makefile'" '(should have been 897 characters)' fi fi # end of overwriting check echo shar: extracting "'README'" '(2828 characters)' if test -f 'README' then echo shar: will not over-write existing file "'README'" else sed 's/^ X//' << \SHAR_EOF > 'README' X X Copyright (c) 1989, Josh Siegel X XYou may copy the pspp kit in whole or in part as long as you don't try to Xmake money off it, or pretend that you wrote it. X X --Josh Siegel X siegel@hc.dspo.gov X XControlable things: X 1) Backslashing inner strings (\(\)) bs X 2) rearrange function definitions ra (not implemented) X Turn: X /foo { % bar X Into: X /foo % bar X { X 3) newline before X "def" db X "begin" bb X "classbegin" cbb X "dictbegin" dbb X "end" eb X "classend" ceb X "dictend" deb X "grestore" grb X "gsave" gsb X "if" ib X "{" lcb X "}" rcb X "[" lbb X "]" rbb X 4) newline after X "def" da X "begin" ba X "classbegin" cba X "dictbegin" dba X "end" ea X "classend" cea X "dictend" dea X "grestore" gra X "gsave" gsa X "if" ia X "[" lba X "]" rba X "{" lca X "}" rca X XDefault flags: X ba bb bs cba cbb cea ceb da dba dbb dea deb ea eb lca rcb pn ia gi X XWays to change flags: X X Put a command line into your PostScript code... X X example: X %%= -bs +cea -dba X X Put a command line into a .pspp in your home directory X X example: X -lba -rba -lca X X Set options when you call program... X X example: X pspp -rca X XTo run: X X% pspp [options files] < file.in > file.out X XOr, run it from vi... X X:%!pspp X XOr, X X% pspp -lba foo.cps +lba foobar.ps X XSpecial NeWS related features... X X lines beginning with cdef are assumed to be cdef calls under NeWS. X This causes the rest of the file (till the next cdef) to be indented one. X X Lines beginning with "#" or "%" are passed through unmodified. X XNote to hackers: X You may notice how I stuck lots of the keywords together into X a single lex rule... I am not going to explain this... there is X a reason for this... don't worry about it for now. The reason X doesn't show up in this version. X SHAR_EOF if test 2828 -ne "`wc -c < 'README'`" then echo shar: error transmitting "'README'" '(should have been 2828 characters)' fi fi # end of overwriting check echo shar: extracting "'.rlog2081'" '(342 characters)' if test -f '.rlog2081' then echo shar: will not over-write existing file "'.rlog2081'" else sed 's/^ X//' << \SHAR_EOF > '.rlog2081' X XRCS file: RCS/Makefile,v; Working file: Makefile Xhead: 1.1 Xbranch: Xlocks: siegel: 1.1; strict Xaccess list: Xsymbolic names: Xcomment leader: "# " Xtotal revisions: 1; selected revisions: 0 Xdescription: XThe makefile X============================================================================= SHAR_EOF if test 342 -ne "`wc -c < '.rlog2081'`" then echo shar: error transmitting "'.rlog2081'" '(should have been 342 characters)' fi fi # end of overwriting check echo shar: extracting "'.package'" '(319 characters)' if test -f '.package' then echo shar: will not over-write existing file "'.package'" else sed 's/^ X//' << \SHAR_EOF > '.package' X: basic variables Xpackage=psindent Xbaserev=1.1 Xpatchbranch=1 Xmydiff='' Xmaintname='Josh Siegel' Xmaintloc='siegel@hc.dspo.gov' Xftpsite='' Xorgname='Los Alamos National Labs, MEE-10' Xnewsgroups='comp.sources.bugs' Xrecipients='' Xftpdir='' X X: derivative variables--do not change Xrevbranch="$baserev.$patchbranch" Xpackver='1' SHAR_EOF if test 319 -ne "`wc -c < '.package'`" then echo shar: error transmitting "'.package'" '(should have been 319 characters)' fi fi # end of overwriting check echo shar: extracting "'patchlevel.h'" '(21 characters)' if test -f 'patchlevel.h' then echo shar: will not over-write existing file "'patchlevel.h'" else sed 's/^ X//' << \SHAR_EOF > 'patchlevel.h' X#define PATCHLEVEL 3 SHAR_EOF if test 21 -ne "`wc -c < 'patchlevel.h'`" then echo shar: error transmitting "'patchlevel.h'" '(should have been 21 characters)' fi fi # end of overwriting check echo shar: done with directory "'pspp'" cd .. # End of shell archive exit 0 -- Josh Siegel (siegel@hc.dspo.gov) I like using a C-47A "puff dragon" to go shooting beer cans with. From don@brillig.umd.edu Thu Jan 5 04:45:42 1989 Date: Thu, 5 Jan 89 04:45:42 EST To: NeWS-makers@brillig.umd.edu Subject: new and improved browser From: carlisle!bvs@sun.com (Bruce V. Schwartz / Marketing Technical Support) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) This is the new version of the browser that was hidden on the SUG SEX machine in a miscellaneous/unorganized directory. So you may not have seen this even if you got SEX at SUG. Many changes in November 1988. Integrated several of Richard Hess's improvements. New features include improved scrolling, caching of browsed classes, addition of the NoClass class for browsing the systemdict, better decompilation of dictionaries, process control (new request cancels previous), better error handling, faster sorting, and looks better on B/W screen. The browser is built on the classes defined in pw.ps. The class browser has 5 panes. It is similar in appearance to the Smalltalk browser. The first pane on the top of the window contains the list of classes in the server. The next 3 contain the list of methods, class variables, and instance variables associated with the selected class in the first pane. The bottom pane is used to display information about the current selection. Bruce V. Schwartz Sun Microsystems bvs@sun.com #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create: # browse # This archive created: Wed Jan 4 18:30:30 1989 export PATH; PATH=/bin:/usr/bin:$PATH if test -f 'browse' then echo shar: "will not over-write existing file 'browse'" else cat << \SHAR_EOF > 'browse' #!/usr/NeWS/bin/psh %% $Header: pw.ps,v 1.5 88/07/13 15:17:15 bvs Exp $ % % This file is a product of Sun Microsystems, Inc. and is provided for % unrestricted use provided that this legend is included on all tape % media and as a part of the software program in whole or part. % Users may copy, modify or distribute this file at will. % % THIS FILE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE % WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR % PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. % % This file is provided with no support and without any obligation on the % part of Sun Microsystems, Inc. to assist in its use, correction, % modification or enhancement. % % SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE % INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS FILE % OR ANY PART THEREOF. % % In no event will Sun Microsystems, Inc. be liable for any lost revenue % or profits or other special, indirect and consequential damages, even % if Sun has been advised of the possibility of such damages. % % Sun Microsystems, Inc. % 2550 Garcia Avenue % Mountain View, California 94043 % % Copyright (c) 1988 by Sun Microsystems, Inc. % This file contains the classes used by the class browser. % The classes included are: % Picture -- an Item similar in concept to the NeWS1.1 textcanvas % PicWindow -- a LiteWindow that holds Pictures % PicScroll -- a SimpleScrollbar with a few modifications (auto scrolling) % % This code was mostly written in August 1987 but was revised to work with % NeWS 1.1 in May 1988. % % Bruce V. Schwartz % Sun Microsystems % bvs@sun.com % /XNeWS? where { pop } { systemdict /XNeWS? false put } ifelse systemdict begin systemdict /Item known not { (NeWS/liteitem.ps) run } if systemdict /SimpleScrollbar known not { (NeWS/liteitem.ps) run } if end %% This file contains classes: PicWindow Picture PicScroll /PicWindow LiteWindow dictbegin /PicArray [] def dictend classbegin /BorderRight 1 def /BorderLeft 1 def /BorderBottom 1 def /PaintIcon { 1 fillcanvas 0 strokecanvas .8 setgray IconWidth 2 div 1 sub IconHeight 4 div 5 sub 5 Sunlogo } def /PaintClient { %% (paint client %\n) [ PicArray ] dbgprintf %% PicArray { ( %\n) [ 3 2 roll ] dbgprintf } forall PicArray paintitems } def /setpicarray { /PicArray exch def } def /destroy { %% (destroying arrays\n) [] dbgprintf PicArray { /destroy exch send } forall %% (destroying window\n) [] dbgprintf /destroy super send %% (destroyed window\n) [] dbgprintf } def classend def /PicScrollbar SimpleScrollbar dictbegin /Owner null def /MouseInItem? false def /ScrollMonitor null def /ScrollProcess null def /ScrollDelay 1 60 div 20 div def % 1/10 second /LastX null def /LastY null def dictend classbegin /ItemShadeColor .5 def /new { /new super send begin /ScrollMonitor createmonitor def currentdict end } def /setowner { /Owner exch def } def /ClientDown { % - => - CurrentEvent begin XLocation YLocation end /LastY exch def /LastX exch def SetScrollMotion /MouseInItem? true def HiliteItem DoScroll ScrollProcess null ne { ScrollMonitor { ScrollProcess killprocess } monitor } if /ScrollProcess { InteractiveScroll } fork pause def } def /InteractiveScroll { { ScrollDelay sleep ScrollMonitor { EventInItem? { DoScroll } if } monitor } loop } def /ClientUp { % - => - % (Clientup\n) [] dbgprintf % ScrollMonitor { ScrollProcess killprocess } monitor /ScrollProcess null def /MouseInItem? false def UnhiliteItem ItemValue ItemInitialValue ne { /Notify Owner send } if } def /ClientDrag { % - => - CurrentEvent begin XLocation YLocation end /LastY exch def /LastX exch def CheckItem } def /PaintBar { } def /EraseBox { } def /PaintButtons { BarViewPercent 1 gt true or { /PaintButtons super send } if } def /PaintBox { % - => - (paint box) %(PaintBox %\n) [ BarViewPercent ] dbgprintf %(pause...) [] dbgprintf 1 60 div sleep (!!\n) [] dbgprintf gsave 10 dict begin /x 1 def /w ItemWidth 1 sub def BarViewPercent 1 le { 1 setgray x ButtonSize w ItemHeight ButtonSize dup add sub rectpath fill } { 1 1 BarViewPercent div sub 1 ItemValue sub mul ItemHeight ButtonSize dup add sub mul ButtonSize add /y exch def 1 BarViewPercent div ItemHeight ButtonSize dup add sub mul /h exch def % % do the normal bar % ItemFillColor setcolor x ButtonSize w y ButtonSize sub rectpath fill x y h add w ItemHeight ButtonSize sub y sub h sub rectpath fill % % do the big scroll box % /ybut ItemValue ValueToY def ItemShadeColor setgray x y w ybut y sub rectpath fill x ybut ButtonSize add w h ButtonSize sub ybut sub y add rectpath fill % % do the little scroll box % ItemValue BoxPath BoxFillColor setcolor gsave fill grestore } ifelse end /ItemPaintedValue ItemValue def grestore /Notify Owner send } def /EventInItem? { % - => bool ScrollMotion { /ScrollAbsolute { false } /ScrollPageForward % top { LastX dup 0 ge exch ButtonSize le LastY ItemValue ValueToY ButtonSize add ge LastY ItemHeight ButtonSize sub le and and and } /ScrollPageBackward % bottom { LastX dup 0 ge exch ButtonSize le LastY ButtonSize ge LastY ItemValue ValueToY le and and and } /ScrollLineForward % top { LastX 0 ge LastX ButtonSize le LastY ItemHeight ButtonSize sub ge LastY ItemHeight le and and and } /ScrollLineBackward % bottom { LastX 0 ge LastX ButtonSize le LastY 0 ge LastY ButtonSize le and and and } } case BarViewPercent 1 le { pop false } if } def /CheckItem { ScrollMotion { /ScrollAbsolute {DoScroll} /ScrollPageForward % top { /MouseInItem? EventInItem? def } /ScrollPageBackward % bottom { /MouseInItem? EventInItem? def } /ScrollLineForward % top { EventInItem? dup { MouseInItem? not { HiliteItem } if } { MouseInItem? { UnhiliteItem } if } ifelse /MouseInItem? exch def } /ScrollLineBackward % bottom { EventInItem? dup { MouseInItem? not { HiliteItem } if } { MouseInItem? { UnhiliteItem } if } ifelse /MouseInItem? exch def } } case } def /HiliteItem { ScrollMotion { /ScrollAbsolute { } /ScrollPageForward { } /ScrollPageBackward { } /ScrollLineForward % top { 0 ItemHeight ButtonSize ButtonSize neg rectpath 5 setrasteropcode fill } /ScrollLineBackward % bottom { 0 0 ButtonSize ButtonSize rectpath 5 setrasteropcode fill } } case } def /UnhiliteItem { gsave ScrollMotion { /ScrollAbsolute {} /ScrollPageForward {} /ScrollPageBackward {} /ScrollLineForward % top { 0 ItemHeight ButtonSize sub ButtonSize ButtonSize rectpath clip PaintButtons } /ScrollLineBackward % bottom { 0 0 ButtonSize ButtonSize rectpath clip PaintButtons } } case grestore } def classend def /Picture Item dictbegin /BufferCanvas null def /BufferWidth 0 def /BufferHeight 0 def /HScrollbar null def /VScrollbar null def /HScrollbar? true def /VScrollbar? true def /HScrollWidth 0 def /VScrollWidth 0 def /ScrollWidth 16 def /NotifyUserDown { pop pop } def % x y => - /NotifyUserUp { pop pop } def % x y => - /NotifyUserDrag { pop pop } def % x y => - /NotifyUserEnter { pop pop } def % x y => - /NotifyUserExit { pop pop } def % x y => - dictend classbegin /new { % parentcanvas width height => instance % (new begin\n) [] dbgprintf /new super send begin /BufferHeight ItemHeight def /BufferWidth ItemWidth def CreateScrollbars CreateBuffer currentdict end % (new end\n) [] dbgprintf } def /destroy { HScrollbar null ne { null /setowner HScrollbar send } if VScrollbar null ne { null /setowner VScrollbar send } if %% BufferCanvas /Mapped false put %% /BufferCanvas null def } def /reshape { % x y w h => - /reshape super send ReshapeScrollbars } def /reshapebuffer { % w h => - /BufferHeight exch ItemHeight HScrollbar? { HScrollWidth sub } if max def /BufferWidth exch ItemWidth VScrollbar? { VScrollWidth sub } if max def ReshapeBuffer ReshapeScrollbars } def /getcanvas { BufferCanvas } def /updatecanvas { PaintBuffer } def /makestartinterests { /makestartinterests HScrollbar send /makestartinterests VScrollbar send [ exch aload length 2 add -1 roll aload pop ] % join 2 arrays /makestartinterests super send [ exch aload length 2 add -1 roll aload pop ] % join 2 arrays } def /PaintItem { %% (PaintItem begin\n) [] dbgprintf PaintBuffer /paint VScrollbar send /paint HScrollbar send %% (PaintItem end\n) [] dbgprintf } def /Notify { % (picture got notified\n) [] dbgprintf NotifyUser PaintBuffer } def /PaintBuffer { % (PaintBuffer begin \n) [ ] dbgprintf gsave ItemCanvas setcanvas % % Stroke canvas % 0 setgray 0 HScrollWidth ItemWidth VScrollWidth sub ItemHeight HScrollWidth sub rectpath stroke % % compute clipping region % 1 HScrollWidth 1 add ItemWidth VScrollWidth sub 2 sub ItemHeight HScrollWidth sub 2 sub rectpath % (clip to % % % %\n) [ pathbbox ] dbgprintf clip % % compute translation % BufferWidth ItemWidth sub VScrollWidth add neg dup 0 lt { 1 /getvalue HScrollbar send sub mul } { pop 0 } ifelse BufferHeight ItemHeight sub HScrollWidth add neg dup 0 lt { 1 /getvalue VScrollbar send sub mul } { } ifelse HScrollWidth add % 2 copy (translate by % %\n) [ 4 2 roll ] dbgprintf translate XNeWS? not { BufferWidth BufferHeight % 2 copy (scale by % %\n) [ 4 2 roll ] dbgprintf scale } if % (currentmatrix % % % % % %\n) [ matrix currentmatrix aload pop ] dbgprintf pause BufferCanvas imagecanvas pause grestore % (PaintBuffer end\n) [ ] dbgprintf } def /CreateBuffer { % - => - /BufferCanvas framebuffer newcanvas def BufferCanvas /Retained true put % BufferCanvas /Mapped true put ReshapeBuffer } def /ReshapeBuffer { % - => - gsave framebuffer setcanvas 0 0 BufferWidth BufferHeight rectpath BufferCanvas reshapecanvas grestore } def /CreateScrollbars { % - => - % (begin CreateScrollbars\n) [] dbgprintf /HScrollWidth HScrollbar? { ScrollWidth } { 0 } ifelse def /VScrollWidth VScrollbar? { ScrollWidth } { 0 } ifelse def ItemWidth VScrollWidth le { /VScrollWidth ScrollWidth 2 div def } if ItemHeight HScrollWidth le { /HScrollWidth ScrollWidth 2 div def } if /HScrollbar [1 0 .01 .1 BufferWidth ItemWidth VScrollWidth sub div ] 1 {} ItemCanvas /new PicScrollbar send dup /BarVertical? false put def /VScrollbar [1 0 .01 .1 BufferHeight ItemHeight HScrollWidth sub div ] 1 {} ItemCanvas /new PicScrollbar send def self /setowner HScrollbar send self /setowner VScrollbar send % (end CreateScrollbars\n) [] dbgprintf } def /ReshapeScrollbars { /HScrollWidth HScrollbar? { ScrollWidth } { 0 } ifelse def /VScrollWidth VScrollbar? { ScrollWidth } { 0 } ifelse def 10 dict begin /h ItemHeight def /w ItemWidth def /s ScrollWidth def [1 0 .01 .1 BufferWidth ItemWidth VScrollWidth sub div ] /setrange HScrollbar send [1 0 .01 .1 BufferHeight ItemHeight HScrollWidth sub div ] /setrange VScrollbar send HScrollbar? { 0 0 w VScrollWidth sub s } { 0 0 0 0 } ifelse % 4 copy (hscroll % % % %\n) [ 6 2 roll ] dbgprintf /reshape HScrollbar send VScrollbar? { w s sub HScrollWidth s h HScrollWidth sub } { 0 0 0 0 } ifelse % 4 copy (vscroll % % % %\n) [ 6 2 roll ] dbgprintf /reshape VScrollbar send end } def /ClientDown { % (Picture ClientDown\n) [] dbgprintf % compute translation % BufferWidth ItemWidth sub VScrollWidth add neg dup 0 lt { 1 /getvalue HScrollbar send sub mul } { pop 0 } ifelse BufferHeight ItemHeight sub HScrollWidth add neg dup 0 lt { 1 /getvalue VScrollbar send sub mul } { } ifelse HScrollWidth add % translatex translatey CurrentEvent /YLocation get sub neg exch CurrentEvent /XLocation get sub neg exch % (n: %\n) [ NotifyUserDown ] dbgprintf { NotifyUserDown } fork } def /ClientUp { % (Picture ClientUp\n) [] dbgprintf CurrentEvent begin XLocation YLocation end NotifyUserUp } def /ClientDrag { % (client drag\n) [] dbgprintf CurrentEvent begin XLocation YLocation end NotifyUserDrag } def /ClientEnter { %% (client enter\n) [] dbgprintf CurrentEvent begin XLocation YLocation end NotifyUserEnter } def /ClientExit { %% (client exit\n) [] dbgprintf CurrentEvent begin XLocation YLocation end NotifyUserExit } def classend def %% $Header: browseclass.ps,v 1.4 88/07/13 15:17:06 bvs Exp $ % % This file is a product of Sun Microsystems, Inc. and is provided for % unrestricted use provided that this legend is included on all tape % media and as a part of the software program in whole or part. % Users may copy, modify or distribute this file at will. % % THIS FILE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE % WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR % PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. % % This file is provided with no support and without any obligation on the % part of Sun Microsystems, Inc. to assist in its use, correction, % modification or enhancement. % % SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE % INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS FILE % OR ANY PART THEREOF. % % In no event will Sun Microsystems, Inc. be liable for any lost revenue % or profits or other special, indirect and consequential damages, even % if Sun has been advised of the possibility of such damages. % % Sun Microsystems, Inc. % 2550 Garcia Avenue % Mountain View, California 94043 % % Copyright (c) 1988 by Sun Microsystems, Inc. % % This file contains a NeWS server class browser. % % The browser is built on the classes defined in pw.ps. The class % browser has 5 panes. It is similar in appearance to the Smalltalk % browser. The first pane on the top of the window contains the list of % classes in the server. The next 3 contain the list of methods, class % variables, and instance variables associated with the selected class in % the first pane. The bottom pane is used to display information about % the current selection. % % This code was mostly written in August 1987 but was revised to work with % NeWS 1.1 in May 1988. % % Many changes in November 1988. Integrated several of Richard Hess's % improvements. New features include improved scrolling, caching of browsed % classes, addition of the NoClass class for browsing the systemdict, better % decompilation of dictionaries, and process control (new request cancels % previous, better error handling, and looks better on B/W screen. % % Bruce V. Schwartz % Sun Microsystems % bvs@sun.com % % % If you don't use the "browse" script, you will have to alter the % following line to reflect the location of the file "pw.ps" on your % system. % /PicWindow where { pop } { systemdict begin (NeWS/pw.ps) LoadFile pop end } ifelse /Font15 /Times-Roman findfont 15 scalefont def /PickProcess null def /PicArray [ ] def /win framebuffer /new PicWindow send def { /FrameLabel (NeWS Class Browser) def } /doit win send /can win /ClientCanvas get def /LastClassPick null def /LastInstPick null def /LastMethodPick null def /LastVarPick null def /ClassKeys [] def /InstKeys [] def /MethodKeys [] def /VarKeys [] def /W 200 def /H 300 def /TextW 800 def /TextH 300 def 100 100 TextW TextH H add 16 add /reshape win send /ClassPic win /ClientCanvas get W H /new Picture send def % classes /MethodPic win /ClientCanvas get W H /new Picture send def % methods /VarPic win /ClientCanvas get W H /new Picture send def % class var /InstPic win /ClientCanvas get W H /new Picture send def % ints var /TextPic win /ClientCanvas get TextW TextH /new Picture send def % text /PicArray [ ClassPic InstPic MethodPic VarPic TextPic ] def PicArray /setpicarray win send ClassPic /HScrollbar? false put InstPic /HScrollbar? false put MethodPic /HScrollbar? false put VarPic /HScrollbar? false put TextPic /HScrollbar? false put 000 TextH W H /reshape ClassPic send 200 TextH W H /reshape MethodPic send 400 TextH W H /reshape VarPic send 600 TextH W H /reshape InstPic send 0 0 TextW TextH /reshape TextPic send 0 /setvalue ClassPic /VScrollbar get send 0 /setvalue InstPic /VScrollbar get send 0 /setvalue MethodPic /VScrollbar get send 0 /setvalue VarPic /VScrollbar get send 0 /setvalue TextPic /VScrollbar get send /ClassColor 1 .8 .8 rgbcolor def /InstColor 1 .8 1 rgbcolor def /MethodColor .8 1 .8 rgbcolor def /VarColor .8 .8 1 rgbcolor def /TextColor 1 1 1 rgbcolor def ClassPic /NotifyUserDown { { ClassPick } HandlePick } put InstPic /NotifyUserDown { { InstPick } HandlePick } put MethodPic /NotifyUserDown { { MethodPick } HandlePick } put VarPic /NotifyUserDown { { VarPick } HandlePick } put %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Utilities for expanding NeWS object types /String256 256 string def /Expand % thing -> - { ExpandDict begin 10 dict begin /ArrayDepth 0 def /TabWidth ( ) stringwidth pop def () exch dup type exec end end } def /StartArray % string array -> string (string) array { /tmparray exch def StartLine ([) AddString /tmparray load /ArrayDepth ArrayDepth 1 add def } def /EndArray % string -> string (string) { /ArrayDepth ArrayDepth 1 sub def (] ) append StartLine } def /StartXArray % string array -> string (string) array { /tmparray exch def StartLine ({) AddString /tmparray load /ArrayDepth ArrayDepth 1 add def } def /EndXArray % string -> string (string) { /ArrayDepth ArrayDepth 1 sub def (} ) append StartLine } def /StartLine % string -> string (string) { dup stringwidth pop TabWidth ArrayDepth mul gt { () ArrayDepth { ( ) append } repeat } if } def /AddString % string string -> string (string) { append ( ) append dup stringwidth pop 700 gt { StartLine } if pause } def /ExpandDict 20 dict dup begin /arraytype { dup xcheck { StartXArray { dup type exec } forall EndXArray } { StartArray { dup type exec } forall EndArray } ifelse } def /dicttype { /tmp exch def StartLine (<>) AddString StartLine tmp { /tmp exch def dup type exec ( ) AddString /tmp load dup type dup /dicttype eq { pop pop (***Dictionary***) AddString } % no recursion here! { exec } ifelse StartLine } forall StartLine (<>) AddString StartLine } def /booleantype { String256 cvs AddString} def /filetype { String256 cvs AddString} def /fonttype { String256 cvs AddString} def /integertype { String256 cvs AddString} def /marktype { ([ ) AddString} def /nametype { dup String256 cvs exch xcheck not { (/) exch append } if AddString } def /nulltype { String256 cvs AddString} def /operatortype { String256 cvs dup length 2 sub 1 exch getinterval AddString} def /realtype { String256 cvs AddString} def /savetype { String256 cvs AddString} def /stringtype { String256 cvs (\() exch append (\)) append AddString} def %% NeWS types /canvastype { String256 cvs AddString} def /colortype { String256 cvs AddString} def /eventtype { String256 cvs AddString} def /graphicsstatetype { String256 cvs AddString} def /monitortype { String256 cvs AddString} def /processtype { String256 cvs AddString} def /shapetype { String256 cvs AddString} def end def %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Sorting Utilities /FindSmall % proc array -> int { 10 dict begin /a exch def /proc exch def /result 0 def /key a 0 get def /i 0 def 0 1 a length 1 sub { /j exch def key a j get proc { /i j def /key a j get def } if } for i end } def /FasterSort % proc array -> array { 10 dict begin /arrayin exch def /arrayout [] def /proc exch def { arrayin length 0 eq { arrayout exit } if /proc load arrayin FindSmall /i exch def arrayout arrayout length arrayin i get arrayinsert /arrayout exch def /arrayin arrayin i arraydelete def pause } loop end } def /Sort % array -> array { { gt } exch FasterSort } def /BubbleSort % array -> array { 20 dict begin /keys exch def /bound keys length 1 sub def /check 0 def { /t -1 def 0 1 bound 1 sub { /i exch def /j i 1 add def /keysi keys i get def /keysj keys j get def keysi keysj gt { keys i keysj put keys j keysi put /t j def } if } for t -1 eq { exit } { /bound t def } ifelse pause } loop keys end %% EndWait } def %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Main Class code /ShowArray { % array color pic % (showarray: count %\n) [ count ] dbgprintf 10 dict begin /pic exch def /color exch def /a exch def Font15 setfont W a length 18 mul 15 add /reshapebuffer pic send % { /paint VScrollbar send /paint HScrollbar send } pic send /getcanvas pic send setcanvas color fillcanvas mark /PaintItem pic send cleartomark % PaintItem seems to leave 2 things on the stack 0 0 0 rgbcolor setcolor /k pic /BufferHeight get def a { /k k 18 sub def 5 k moveto show } forall /updatecanvas pic send end } def /DoClasses { [ systemdict { /val exch cvlit def /key exch cvlit def val type /dicttype eq { val /ClassName known { key val /ClassName get eq { % leave this on the stack key 256 string cvs } if } if } if pause } forall ] Sort userdict begin /ClassKeys exch def end ClassKeys ClassColor ClassPic ShowArray userdict /ClassesDict ClassKeys length dict put [] MethodColor MethodPic ShowArray [] VarColor VarPic ShowArray [] InstColor InstPic ShowArray [] TextColor TextPic ShowArray % fork off a process to fill the ClassesDict for % all classes { ClassKeys { DoClass } forall } fork } def /DoClass % classname -> - (sorts all class attributes) { 10 dict begin /classname exch def ClassesDict classname known not { /classarrays 3 dict def /classdict systemdict classname get def classdict GetSortedMethods classdict GetSortedClassVars classdict GetSortedInstVars classarrays begin /InstVars exch def /ClassVars exch def /Methods exch def end ClassesDict classname classarrays put } if end } def /GetSortedMethods { % classdict => - [ exch { /val exch def /key exch def /val load type /arraytype eq /val load xcheck and { key 256 string cvs } if pause } forall ] Sort } def /GetSortedClassVars { % classdict => - [ exch { /val exch def /key exch def /val load type { /arraytype { /val load xcheck not } /operatortype { false } /dicttype { /val load /ClassName known not } /Default { true } } case { key 256 string cvs } if pause } forall ] Sort } def /GetSortedInstVars { % classdict => - [ exch /InstanceVarDict get dup null eq { pop [] } if { /val exch def /key exch def key 256 string cvs pause } forall ] Sort } def /DoMethods % classname => - { ClassesDict exch get /Methods get userdict begin /MethodKeys exch def end MethodKeys MethodColor MethodPic ShowArray } def /DoVars % classname => - { ClassesDict exch get /ClassVars get userdict begin /VarKeys exch def end VarKeys VarColor VarPic ShowArray } def /DoInsts % classname => - { ClassesDict exch get /InstVars get userdict begin /InstKeys exch def end InstKeys InstColor InstPic ShowArray } def /ClassPick % x y => - { 10 dict begin /y exch def /x exch def /k ClassPic /BufferHeight get y sub 18 div floor def /lastpick LastClassPick def userdict /LastClassPick k put Font15 setfont lastpick null ne { null SetMethodPick null SetVarPick null SetInstPick gsave %(unhilite %\n) [ lastpick ] dbgprintf /getcanvas ClassPic send setcanvas 0 ClassPic /BufferHeight get lastpick 1 add 18 mul sub 3 sub W 18 rectpath ClassColor setcolor fill 0 0 0 rgbcolor setcolor 5 ClassPic /BufferHeight get lastpick 1 add 18 mul sub moveto ClassKeys lastpick get show grestore } if lastpick null ne lastpick k ne and { %% put scroll bars back to top 0 /setvalue InstPic /VScrollbar get send 0 /setvalue MethodPic /VScrollbar get send 0 /setvalue VarPic /VScrollbar get send 0 /setvalue TextPic /VScrollbar get send } if %(pick is % \n ) [ k ] dbgprintf k ClassKeys length 1 sub le { % (pick is % '%' \n ) [ ClassKeys k get k ] dbgprintf % (Lastpick was '%' \n ) [ lastpick ] dbgprintf /getcanvas ClassPic send setcanvas %(hilite %\n) [ k ] dbgprintf 0 ClassPic /BufferHeight get k 1 add 18 mul sub 3 sub W 18 rectpath 0 0 0 rgbcolor setcolor fill ClassColor setcolor 0 5 ClassPic /BufferHeight get k 1 add 18 mul sub moveto ClassKeys k get show /updatecanvas ClassPic send lastpick k ne { [(Loading Menus...)] TextColor TextPic ShowArray [] MethodColor MethodPic ShowArray [] VarColor VarPic ShowArray [] InstColor InstPic ShowArray } if lastpick k ne { ClassKeys k get cvn dup DoClass dup DoMethods dup DoVars dup DoInsts pop } if [ (CLASS ") ClassKeys k get 256 string cvs (") append append systemdict ClassKeys k get cvn get /ParentDictArray known { systemdict ClassKeys k get cvn get /ParentDictArray get { /ClassName get 256 string cvs ( ) exch append } forall } if ] TextColor TextPic ShowArray k } { /updatecanvas ClassPic send null } ifelse end } def /SetInstPick % newpick => - { 10 dict begin Font15 setfont LastInstPick null ne { gsave /getcanvas InstPic send setcanvas 0 InstPic /BufferHeight get LastInstPick 1 add 18 mul sub 3 sub W 18 rectpath InstColor setcolor fill 0 0 0 rgbcolor setcolor 5 InstPic /BufferHeight get LastInstPick 1 add 18 mul sub moveto InstKeys LastInstPick get show grestore } if userdict begin /LastInstPick exch def end % pick up newpick %% (new InstPick is % \n ) [ LastInstPick ] dbgprintf LastInstPick null ne { /getcanvas InstPic send setcanvas 0 InstPic /BufferHeight get LastInstPick 1 add 18 mul sub 3 sub W 18 rectpath 0 0 0 rgbcolor setcolor fill InstColor setcolor 0 5 InstPic /BufferHeight get LastInstPick 1 add 18 mul sub moveto InstKeys LastInstPick get show } if /updatecanvas InstPic send LastInstPick null ne { /val systemdict ClassKeys LastClassPick get cvn get % class /InstanceVarDict get % instdict InstKeys LastInstPick get % class variable get def [] TextColor TextPic ShowArray [ (INSTANCE VARIABLE) ( ") InstKeys LastInstPick get 256 string cvs (") append append append val Expand ] TextColor TextPic ShowArray } if end } def /InstPick { null SetMethodPick null SetVarPick 10 dict begin /y exch def /x exch def /k InstPic /BufferHeight get y sub 18 div floor def %% (pick is % \n ) [ k ] dbgprintf k dup end InstKeys length 1 sub le { SetInstPick } { pop } ifelse } def /SetMethodPick % newpick => - { Font15 setfont LastMethodPick null ne { gsave /getcanvas MethodPic send setcanvas 0 MethodPic /BufferHeight get LastMethodPick 1 add 18 mul sub 3 sub W 18 rectpath MethodColor setcolor fill 0 0 0 rgbcolor setcolor 5 MethodPic /BufferHeight get LastMethodPick 1 add 18 mul sub moveto MethodKeys LastMethodPick get show grestore } if userdict begin /LastMethodPick exch def end % pick up newpick %% (new MethodPick is % \n ) [ LastMethodPick ] dbgprintf LastMethodPick null ne { /getcanvas MethodPic send setcanvas 0 MethodPic /BufferHeight get LastMethodPick 1 add 18 mul sub 3 sub W 18 rectpath 0 0 0 rgbcolor setcolor fill MethodColor setcolor 0 5 MethodPic /BufferHeight get LastMethodPick 1 add 18 mul sub moveto MethodKeys LastMethodPick get show } if /updatecanvas MethodPic send LastMethodPick null ne { [] TextColor TextPic ShowArray [ (METHOD ") MethodKeys LastMethodPick get 256 string cvs (") append append systemdict ClassKeys LastClassPick get cvn get % class MethodKeys LastMethodPick get % class method get Expand ] TextColor TextPic ShowArray } if } def /MethodPick { null SetVarPick null SetInstPick 10 dict begin /y exch def /x exch def /k MethodPic /BufferHeight get y sub 18 div floor def %% (pick is % \n ) [ k ] dbgprintf k dup end MethodKeys length 1 sub le { SetMethodPick } { pop } ifelse } def /SetVarPick % newpick => - { 10 dict begin Font15 setfont LastVarPick null ne { gsave /getcanvas VarPic send setcanvas 0 VarPic /BufferHeight get LastVarPick 1 add 18 mul sub 3 sub W 18 rectpath VarColor setcolor fill 0 0 0 rgbcolor setcolor 5 VarPic /BufferHeight get LastVarPick 1 add 18 mul sub moveto VarKeys LastVarPick get show grestore } if userdict begin /LastVarPick exch def end % pick up newpick %% (new VarPick is % \n ) [ LastVarPick ] dbgprintf LastVarPick null ne { /getcanvas VarPic send setcanvas %(hilite %\n) [ LastVarPick ] dbgprintf 0 VarPic /BufferHeight get LastVarPick 1 add 18 mul sub 3 sub W 18 rectpath 0 0 0 rgbcolor setcolor fill VarColor setcolor 0 5 VarPic /BufferHeight get LastVarPick 1 add 18 mul sub moveto VarKeys LastVarPick get show } if /updatecanvas VarPic send LastVarPick null ne { /val systemdict ClassKeys LastClassPick get cvn get % class VarKeys LastVarPick get % class variable get def [] TextColor TextPic ShowArray [ { (CLASS VARIABLE) ( ") VarKeys LastVarPick get 256 string cvs (") append append append val Expand } errored { cleartomark [ (CLASS VARIABLE) ( ") VarKeys LastVarPick get 256 string cvs (") append append append (Error in CLASS VARIABLE) () $error Expand } if ] TextColor TextPic ShowArray } if end } def /VarPick { null SetMethodPick null SetInstPick 10 dict begin /y exch def /x exch def /k VarPic /BufferHeight get y sub 18 div floor def % (pick is % %\n ) [ k VarKeys] dbgprintf k dup end VarKeys length 1 sub le { SetVarPick } { pop } ifelse } def /SetupNoClass { % - -> - Set up systemdict to look like a class systemdict /NoClass systemdict put NoClass /InstanceVarDict 0 dict put systemdict /ClassName (NoClass) put } def /HandlePick { % procedure -> - PickProcess null ne { PickProcess killprocess } if fork userdict begin /PickProcess exch def end } def SetupNoClass DoClasses PicArray forkitems pop /map win send SHAR_EOF chmod +x 'browse' fi exit 0 # End of shell archive From don@brillig.umd.edu Thu Jan 5 15:11:02 1989 Date: Thu, 5 Jan 89 15:11:02 EST To: NeWS-makers@brillig.umd.edu Subject: informal survey From: Eric Marshall Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) I would like to conduct an informal survey to find out how many people are using NeWS on a regular basis, and on what platforms. I am interested in how many people are using NeWS in your organization, and the manufacturer, model number and operating system of the platform which you run it on. If you would like to respond for your entire organization, please indicate this, so that I can watch for other members of your organization responding also. I will summarize and post the results to the net in a few weeks. Thanks in advance. Eric Marshall Software Productivity Consortium SPC Building 2214 Rock Hill Road Herndon, VA 22070 (703) 742-7237 CSNET: marshall@software.org ARPANET: marshall%software.org@relay.cs.net ---------------------------------------------------------------------- I'm just an X programmer gone straight. From don@brillig.umd.edu Fri Jan 6 01:57:20 1989 Date: Fri, 6 Jan 89 01:57:20 EST To: NeWS-makers@brillig.umd.edu Subject: Partial fix for NeWS security hassles From: gregc@cgl.ucsf.edu (Greg Couch) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) We have had many problems with the NeWS security mechanism not accepting connections because getsocketpeername returns the canonical name and the names in the RemoteHostRegistry are either host aliases or in a different case (i.e. .EDU vs. .edu). An ideal solution, that would require changes to the NeWS server, would be to add a canonicalizehostname function that would do a hostname lookup and return the canonical name. Then all of the putting of hosts into the RemoteHostRegistry would be of the form: RemoteHostRegistery hostname canonicalizehostname true put Unfortunatly, we don't have the NeWS source, so enclosed is a solution for fixing problems with localhost not be in domain form, and the hostname case problem. The former is fixed by adding localhost.domain if the localhostname is in domain form (all of our hosts). And the latter is fixed by converting all hostnames to lowercase. The files changed are /usr/NeWS/lib/NeWS/{util,init}.ps and /usr/NeWS/bin/newshost. - Greg Couch gregc@cgl.ucsf.edu ----- *** util.ps.orig Thu Jan 5 18:47:53 1989 --- util.ps Thu Jan 5 18:46:07 1989 *************** *** 263,268 **** --- 263,280 ---- pop } def + /UpperCaseDict 26 dict def + UpperCaseDict begin + (ABCDEFGHIJKLMNOPQRSTUVWXYZ) { dup def } forall + end + /strToLower { % string => string + [ exch % put string arg after [ + { + dup UpperCaseDict exch known { 32 add } if + } forall + ] cvas + } def + % % Mac-like bounding box graphics procs. Very useful for edge-critical drawing. % The graphics prinitives are rects, ovals and round rects. *** init.ps.orig Thu Jan 5 18:47:21 1989 --- init.ps Thu Jan 5 18:46:07 1989 *************** *** 561,568 **** /&main {go! DebuggingServer? {executive} if} def /RemoteHostRegistry 100 dict def % list of hosts allowed to connect to server. ! RemoteHostRegistry localhostname true put RemoteHostRegistry /localhost true put /NetSecurityWanted true def % false if everyone is allowed to connect % The server; note that the dict size is client's userdict! --- 561,576 ---- /&main {go! DebuggingServer? {executive} if} def /RemoteHostRegistry 100 dict def % list of hosts allowed to connect to server. ! RemoteHostRegistry localhostname strToLower true put RemoteHostRegistry /localhost true put + % Add localhost.domain if localhostname is domainized + localhostname (.) search + { + pop pop strToLower (localhost.) exch append + RemoteHostRegistry exch true put + } { + pop + } ifelse /NetSecurityWanted true def % false if everyone is allowed to connect % The server; note that the dict size is client's userdict! *************** *** 574,580 **** { dup mark exch acceptconnection { 200 dict begin initmatrix newprocessgroup exch pop exch pop dup ! getsocketpeername /OriginatingHost exch def % See if OriginatingHost is in the Registry RemoteHostRegistry OriginatingHost known --- 582,588 ---- { dup mark exch acceptconnection { 200 dict begin initmatrix newprocessgroup exch pop exch pop dup ! getsocketpeername strToLower /OriginatingHost exch def % See if OriginatingHost is in the Registry RemoteHostRegistry OriginatingHost known *** newshost.orig Thu Jan 5 18:47:40 1989 --- newshost Thu Jan 5 18:46:15 1989 *************** *** 47,57 **** ;; add) shift ! echo "{ $* } { RemoteHostRegistry exch cvlit true put } forall "|psh ;; remove|sub) shift ! echo "{ $* } { { RemoteHostRegistry exch undef } stopped clear } forall "|psh ;; *) echo "$0 manipulates the NeWS remote host access security facility." --- 47,57 ---- ;; add) shift ! echo "{ `echo $* | tr '[A-Z]' '[a-z]'` } { RemoteHostRegistry exch cvlit true put } forall "|psh ;; remove|sub) shift ! echo "{ `echo $* | tr '[A-Z]' '[a-z]'` } { { RemoteHostRegistry exch undef } stopped clear } forall "|psh ;; *) echo "$0 manipulates the NeWS remote host access security facility." From don@brillig.umd.edu Fri Jan 6 21:22:54 1989 Date: Fri, 6 Jan 89 21:22:54 EST To: NeWS-makers@brillig.umd.edu Subject: The New LaTeX From: toms@ncifcrf.gov Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) The following is a letter I just sent to Leslie Lamport. I thought it might be helpful to have discussion on it in this group. Dear Leslie: I understand you are or are considering a second version of LaTeX. Bravo! There is one thing that remains totally obscure to me from the current manual and this is the business about robustness, fragility and moving arguments. I've read the definitions and they seem all circular and refer to each other. I don't know what causes the problem, how to recognize it if it comes up. Maybe it has and I never recognized it. To make sure, I just scanned over all the references in the Index on fragile command, pages 24,27,34,151 and 119. All the terms are defined in terms of the other terms! THIS IS FRUSTRATING!!! A few paragraphs that REALLY say what's going on would be of great help! Also, it turns out that I write a LOT of letters which have references in them. So do other scientists. Since the letter environment does not support this, I have made up my own format. Please make it possible to have references in letters in the next version! Finally, controls for the form of a reference in the text would be quite useful, to avoid this proliferation of styles. (I now know how to program the format of the references, and I'm happy with that solution.) A simple switch would be useful: bracked, parenthesis, superscript for the reference. Also, getting rid of the word REFERENCES is a pain; this should be a switch. Finally, something within LaTeX must decide to put spaces between the references, I couldn't locate it (since I don't know TeX code) and to make my Nucleic Acids Research reference list work out properly I had to neutralize the blank lines with: \vspace{-\baselineskip}\vspace{4pt} in the bbl file. That doesn't seem to be quite right, but it works pretty well. Sure is an ugly solution. The point is that the bbl should have COMPLETE control over the format of the references!! Sincerely yours, Tom Schnesder National Cancer Institute Laboratory of Mathematical Biology Frederick, Maryland toms@ncifcrf.gov From don@brillig.umd.edu Fri Jan 6 21:23:11 1989 Date: Fri, 6 Jan 89 21:23:11 EST To: NeWS-makers@brillig.umd.edu Subject: Re: NeWS and DPS From: mcvax!ukc!harrier.ukc.ac.uk!eagle.ukc.ac.uk!icdoc!qmc-cs!liam@uunet.uu.net (William Roberts) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) If DPS reimplements NeWS with all the names changed, then Adobe's pre-release stuff was a lie from start to finish. The essential difference between DPS and NeWS is that DPS has *NO INPUT MODEL*. DPS is purely another graphics output language and so can be "totally compatible with Printer PostSCript" just like the Adobe blurb says. It also uses the underlying window system to provide fragments of drawing surface, so it doesn't include the window system aspects of NeWS: no silly-shaped windows. -- William Roberts ARPA: liam@cs.qmc.ac.uk (gw: cs.ucl.edu) Queen Mary College UUCP: liam@qmc-cs.UUCP LONDON, UK Tel: 01-975 5250 From don@brillig.umd.edu Fri Jan 6 22:52:52 1989 Date: Fri, 6 Jan 89 22:52:52 EST To: NeWS-makers@brillig.umd.edu Subject: NeWSillustrator From: mcvax!prlb2!bernard@uunet.uu.net (Bernard Yves) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) I am about to post 2 following articles with the complete source code of NeWSillustrator for NeWS 1.1. NeWSillustrator is an object-oriented drawing program (similar to fig or NewsDraw). It includes various object types (lines, polygons, curves, text,...) with full control on line width, line type, line color, font, font size, color filling... Objects can be moved, scaled, rotated, grouped, copied, edited, clipped, aligned, centered,... Objects can be saved and loaded, Postscript files can be imported (with the limitation of the NeWS postscript interpreter)to be manipulated as objects, and generated for laser printing. Full scrolling and zooming capabilities are available. Contrarly to NewsDraw, NeWSillustrator is entirely written in NeWS: there is no client program written in C or some other traditional language. One will note the equal code size of NeWSillustrator (i.e. 2600 lines of NeWS postscript) and NewsDraw (i.e. 500 lines of NeWS PS and 2000 lines of C) for much greater functionalities in NeWSillustrator. This is partly due to the object-oriented extension of NeWS. And that for the same performance... and with probably a much better readability and flexibility. For me, this raises the following remark : for this kind of application, it is easier to program in NeWS than in C. If I had to write some client program, I will not do it in C, but in higher level languages such as Objective-C or Prolog. Many improvments should be made to NeWSillustrator. The main one would be to replace the very long command menu with an iconic tool window. Try to do it or wait for the next version... I am waiting now for a better NeWS implementation (full Postscript compatible), good NeWS documentation, ...and an equivalent Display Postscript of NeWSillustrator. Manual (draft). -------------- After loading, NeWSillustrator will ask you to shape two windows. Make them big enough. The first one is the Control Panel, the second one is the Drawing Area. Drawing Area ------------ This is where the drawing is made. The dashed lines are the sides of the visible area of an A4 sheet on a laser printer. The command menu is activated in pressing the right mouse button. In this menu, the available operations are divided in 3 parts : edition operations, object creation operations and finally zoom, font and files operations Usually, once a command is selected, messages are printed in the control panel to explain you what to do and what happened. The message panel item is at the bottom of the control panel. If you don't see it, move or reshape the control panel window. For all commands requiring text input or file name (e.g. Text, ImportPS,...), enter the text or name in the corresponding control panel item (e.g. Text String, PS file name) BEFORE selecting the command. Object Creation Operations. --------------------------- These are : Rect, Line, Polygon, Curve, RoundedRect, Oval, Text, Group, ImportPS. For all these operations, you will be asked to input points with the mouse: a point is entered in clicking on any button. When asked for a sequence of points (e.g. line and curve), end the sequence by clicking twice (or double-clicking) on the last point. Once an object is successfuly created, it becomes the current object. Rect, Line, Polygon, RoundedRect, Oval : should be obvious. Curve : curves are made of Postscript elementary curves which are defined by 4 points. You will be asked to enter a sequence of points, and every time you input 3 points, a elementary curve is drawn connecting the 3 points with the last point of the previous curve. Text : before selecting this command, first enter the text to draw in the 'Text String' item of the control panel : just click in the Text String item with the left mouse button and insert text. Text editing is allowed with the DEL, ctrl-f, ctrl-b and ctrl-d keys with the usual emacs meaning. Once the text is input, select the text command in the drawing area window menu and position the text at the right place. Group : A group is a collection of any objects. A group is defined in two ways: by a box (the default) or by enumeration. The definition mode is changed in clicking in the 'Group Defined by' item of the control panel. by box: just enter a box enclosing completly the objects to group. by enumeration : enter the origin point of the group, and then select each object by clicking on it. End in double-clicking on any point. Objects in a group are not accessible individually : to select an object in a group, you have to delete the group. A group is depicted on the screen by drawing its components and small squares on its enclosing box (Sometime, after rotation and scaling the box is not correct). A group is selected by clicking a point in that box. ImportPS : This object type correspond to imported Postscript files. The range of importable files is limited by the NeWS Postscript omissions (fonts, pattern filling,...). PS files produced by Fig seem to work. Of course, PS files generated by NeWSillustrator can be imported. Files which NeWS can not display will cause errors -- see the message in the control panel -- and will be (or should be) refused. Again, before selecting ImportPS, define the PS file to import in the corresponding item in the Control Panel. If the file can be successfully loaded, it will be displayed on the screen and you will be asked to give its bounding box. An imported file is considered as an usual object : it can be moved, copied, rotated, scaled, grouped,... Importation of Postscript file is made by generating an intermediate file in your home directory with the same name as the imported file and ".wps" as extension. Edition Operations. ------------------- These operations always work on the current selection. To set an object as the current selection use the select command. Select : click in the inside of the object. NeWSillustrator will select the first object found under the clicked point. If it is not the one you want (because of many overlapping objects), move other objects or create a group that you will define by a box enclosing the object you want. Groups are selected by clicking in their enclosing box. Move, Rotate, Scale : obvious. Rotation and scaling use the origin point of the object as reference point. The origin point is usually the first point input when defining the object or a corner of the enclosing box. Copy : makes a copy of the current object. The copy becomes the new selection and you have to move it where you want. Redisplay : objects overlapping moved objects are not redrawn. Use Redisplay to redraw all the objects and redraw them in the current order. Move Up, Move Down : the display order defines how objects overlap each other. Move Up and Down change the display order and give full control on overlapping. Move Up (Down) will swap the current object with the next encountered object in the display list which is drawn after (before) it. If you continuously apply Move Up (Down) on an object, it should then become the last (first) displayed object (see the message in the control panel). Delete : delete the current selection. Delete a group but not its components (i.e. ungroup). Destroy : deletes a group AND all its components. Other => : a submenu of other editing operations: --------- Edit : only works for Lines, Polygons and Curves; allows to move points defining the selected objects. First, select a point by clicking on it and then move it. To stop edition double-click anywhere. Note that the first point of an item is not editable. Clip : clip the current selection object with another object which will have to be selected by the user. The clipping object should not be a group, a text or an ImportPS object. The inside of the clipping path is determined by the normal PostScript non-zero winding number rule. A clipped object is implemented as a special kind of group: many operations available on group can be used on clipped object (e.g. delete, destroy). Align Left, Right,..., Center : works for items in a selected group; Zoom Operations : easy ; use the scroll bar to scroll your drawing. ----------------- Font => ------- Choose the font in the font menu. It will be the default font of newly created text object and, change the font of the current selection. All the fonts listed are not available on the laser. Also, there are problems with some fonts in NeWS. Font Size => : obvious. ------------ Files Operations. ---------------- The 'Files IO =>' leads to a submenu with files operations. They require the corresponding file name to be defined in the control panel before selecting them. save PS file : generates a Postscript file printable on a laser and importable as an object in NeWSillustrator; save Objects file: save all the objects of the current drawing; load Object file: add all the objects in the file to the current drawing; (Object files can be used as a library) Control Panel ------------- There are three types of Control panel items : text and file name items, drawing parameters items and control items. Drawing parameters Items: They are : line width, style, join, cap, color, fill color, Rounded Corner Radius. Values of the drawing parameters are those of the curent selection. Change of a drawing parameter always affect the current selection. If it is a group, its components will be affected. Use of Sliding items (e.g line color): just click anywhere on the line or drag the cursor to the required value. line color : the gray level from 0 (black) to 100 (white). fill color : idem ; the -1 is used for no fill. Color of text is changed by the line color slide, but in NeWS text is always displayed as black on a monochrome screen. Control Items : grid size, grid on, group defined by, message item, line quality. The line quality controls the rendering quality of NeWS : 0 = low quality but faster, 10 = best quality but slower. Grid Size : the current unit is screen point. The grid will be displayed at the next repaint of the Drawing Area Window. File Items : obvious. ---------------------------------------------------------------------------- Yves Bernard Philips Research Lab Brussels, 2 av. Van Becelaere 1170 Brussels, Belgium bernard@prlb2.uucp From don@brillig.umd.edu Fri Jan 6 23:02:44 1989 Date: Fri, 6 Jan 89 23:02:44 EST To: NeWS-makers@brillig.umd.edu Subject: NeWSillustrator (part 1) From: mcvax!prlb2!bernard@uunet.uu.net (Bernard Yves) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) NeWSillustrator part 1 append it with part 2, put it in a file, do chmod u+x and run it. -------------------------------------------------------------------------- #!/usr/NeWS/bin/psh %========================================================================== % scrollable and zoomable window class definition systemdict /zapmenu known not {systemdict begin /zapmenu [ (No, not really) {} (Yes, really) {/destroy ThisWindow send} ] /new DefaultMenu send def end } if /ScrollAndZoomWindow ScrollWindow dictbegin /PictureWidth 0 def % for translating the client window /PictureHeight 0 def /LDivisions 10 def % number of scroll bad pieces/whole /PDivisions 3 def % number of scroll bad pieces/whole /ScrollH 0 def % cumulative translation factors /ScrollV 0 def % due to successive scrolling; /ZoomFactor 1 def % zooming factor; /newox 0 def /newoy 0 def /Nzoom 0 def /zoomstack 50 array def /overlaycan null def dictend classbegin /Resize { % width height => - size the backround canvas /PictureHeight exch def /PictureWidth exch def [%0 PictureWidth ClientWidth sub newox neg PictureWidth ClientWidth sub newox add %min max dup dup LDivisions div exch PDivisions div null] /setrange HScrollbar send [%0 PictureHeight ClientHeight sub newoy neg PictureHeight ClientHeight sub newoy add dup dup LDivisions div exch PDivisions div null] /setrange VScrollbar send } def /SetNotifiers { % Hnotifier Vnotifier => - VScrollbar /NotifyUser 3 -1 roll put HScrollbar /NotifyUser 3 -1 roll put } def /Scroll {ScrollProc} def /ZoomIn {/ZoomFactor ZoomFactor 2 mul def ZoomInProc} def /ZoomOut {ZoomFactor 1 ne {/ZoomFactor ZoomFactor 2 div def ZoomOutProc} if} def /ShapeClientCanvas { ClientCanvas null ne { ScrollAndZoomAxis} if } def /CreateFrameMenu { % - => - (Create frame menu) % Note: Store menu in class to share menus, especially if retained. /FrameMenu [ (Move) {/slide ThisWindow send} (Move Constrained) {getfbclick pop pop /slideconstrained ThisWindow send} (Top) {/totop ThisWindow send} (Bottom) {/tobottom ThisWindow send} (Zap => ) zapmenu (Resize) {/reshapefromuser ThisWindow send} (Stretch Corner) {getfbclick pop pop /stretchcorner ThisWindow send} (Stretch Edge) {getfbclick pop pop /stretchwindowedge ThisWindow send} (Close) {/flipiconic ThisWindow send} (Redisplay) {/paint ThisWindow send} ] /new DefaultMenu send def } def /ScrollAxis {%the scorllbar values are always in abs. coord. /ScrollH HScrollbar /ItemValue get def /ScrollV VScrollbar /ItemValue get def BorderLeft BorderBottom translate ScrollH neg ScrollV neg translate } def /ScrollProc { ScrollAndZoomAxis /PaintClient self send } def /pushzoomstack{% - => - zoomstack Nzoom [ScrollH ScrollV ] put /Nzoom Nzoom 1 add store } def /popzoomstack{% Nzoom 0 ne {/Nzoom Nzoom 1 sub store zoomstack Nzoom get aload pop %put that in the scroll bar value /ScrollV exch store /ScrollH exch store HScrollbar /ItemValue ScrollH put VScrollbar /ItemValue ScrollV put } if } def /ZoomInAxis { %zoom in by 1, 2, 4, 8,... /newox ClientWidth 2 div ClientWidth 2 ZoomFactor exp div sub def /newoy ClientHeight 2 div ClientHeight 2 ZoomFactor exp div sub def newox neg newoy neg translate ZoomFactor ZoomFactor scale % ScrollH ZoomFactor div newox ZoomFactor div add ScrollV ZoomFactor div newoy ZoomFactor div add ClientWidth ZoomFactor div ClientHeight ZoomFactor div ClientPath ClientCanvas reshapecanvas } def /ScrollAndZoomAxis { gsave FrameCanvas setcanvas ScrollAxis % modifies the transf. matrix of the client canvas: ZoomFactor 1 eq {/newox 0 store /newoy 0 store ScrollH ScrollV ClientWidth ClientHeight ClientPath ClientCanvas reshapecanvas} {ZoomInAxis} ifelse /overlaycan ClientCanvas createoverlay store grestore } def /ZoomInProc { pushzoomstack ScrollAndZoomAxis /PaintClient self send PictureWidth 2 mul PictureHeight 2 mul /Resize self send % HScrollbar dup /ItemValue exch /ItemValue get 2 mul put % VScrollbar dup /ItemValue exch /ItemValue get 2 mul put HScrollbar /ItemValue ScrollH newox add put VScrollbar /ItemValue ScrollV newoy add put /paintscrollbars self send } def /ZoomOutProc { popzoomstack ScrollAndZoomAxis /PaintClient self send PictureWidth 2 div PictureHeight 2 div /Resize self send % HScrollbar dup /ItemValue exch /ItemValue get 2 mul put % VScrollbar dup /ItemValue exch /ItemValue get 2 mul put HScrollbar /ItemValue ScrollH newox add put VScrollbar /ItemValue ScrollV newoy add put /paintscrollbars self send } def classend def %=========================================================================== % utilities %=========================================================================== /setoverlay {win begin overlaycan end setcanvas} def /prdebug false def /printdbg { prdebug {print} {pop} ifelse} def (Loading utilities \n) printdbg /drect { % x,y w, h => - : makes a path corresponding to the box 4 2 roll moveto rect } def %setting of the object coord. system /spos {translate rotate scale} def /printcoord { exch 3 string cvs print ( X\n) print 3 string cvs print ( Y\n) print} def /printpath { {printcoord} {printcoord} {printcoord printcoord printcoord} {} pathforall} def /b1 null def /boxpath { % [x1 y1 x2 y2] => - makes path of the box aload pop 3 index 3 index moveto %x1 y1 x2 y2 2 index sub %x1 y1 x2 (y2-y1) exch 3 index sub exch rect pop pop } def /box_in_box {% b1 b2 => bool ; true if b1 in b2; box = [x0, y0, x1, y1] gsave boxpath aload pop %x1 y1 x2 y2 pointinpath 3 1 roll pointinpath and grestore } def /box_of_box {% b1 b2 => b2 ;computes the box enclosing the 2 % gsave aload pop 5 -1 roll aload pop %4 points on the stack connect them in newpath moveto lineto lineto lineto [ pathbbox ] % grestore } def /o_dict dictbegin /x1 0 def /x2 0 def /y1 0 def /y2 0 def dictend def /overlapping_interval{ % x1 x2 y1 y2 => true if [x1 x1] inter [y1 y2] %non null o_dict begin /y2 exch store /y1 exch store /x2 exch store /x1 exch store { x1 y1 le x2 y1 ge and {true exit} if x1 y2 le x2 y2 ge and {true exit} if y1 x1 le y2 x2 ge and {true exit} if false exit } loop end } def /overlapping_box{% b1 b2 => bool; true if box overlaps aload pop 5 -1 roll aload pop 7 index 6 index %x11 x12 5 index 4 index %x21 x22 overlapping_interval {6 index 5 index 4 index 3 index overlapping_interval} {false} ifelse mark 10 2 roll cleartomark } def %working var. /mtrx0 matrix def /mtrx1 matrix def /newarray null def /tmparray 100 array def /Ntmp 0 def /N 0 def /tmpstr 50 string def /Angle2 0 def /Sx2 1 def /Sy2 1 def /Sx3 1 def /Sy3 1 def /X0 0 def /Y0 0 def /X1 0 def /Y1 0 def /X2 0 def /Y2 0 def /Xc 0 def /Yc 0 def /oldcanvas null def %=========================================================================== % object Table definition and management /SizeObjTable 1000 def /ObjTable SizeObjTable array def 0 1 199 {ObjTable exch null put} for /Nobj 0 def % /AddObject {% => - dup ObjTable exch Nobj exch put begin /tableindex Nobj store end /Nobj Nobj 1 add store Nobj SizeObjTable ge {(Object Table is full) prmessage} if } def /RepaintAll {% repaint all objects in table; gsave /display a4rect send 0 1 Nobj 1 sub {ObjTable exch get dup null ne {dup begin ingroup end {pop} {/display exch send} ifelse } {pop} ifelse} for grestore draw_grid } def /PrintPS_header{ %postscript utilities PSfile (/rect {dup 0 exch rlineto exch 0 rlineto neg 0 exch rlineto closepath } def /ovalpath { matrix currentmatrix 5 1 roll 4 2 roll translate scale .5 .5 translate 0 0 .5 0 360 arc closepath setmatrix} def\n) [] fprintf PSfile (/rrectpath { matrix currentmatrix 6 1 roll % m r x y w h 4 2 roll translate % m r w h 10 dict begin /h exch def /w exch def /r exch def mark r 0 moveto w 0 w h r arcto w h 0 h r arcto 0 h 0 0 r arcto 0 0 w 0 r arcto closepath cleartomark end setmatrix } def\n) writestring %dash patterns print_dasharray_ps PSfile (/setdashpat{% n => - dasharray exch get aload pop setdash} def\n) writestring PSfile (0 setlinewidth 0 setgray /privatedict 100 dict def /savemtrx matrix def /spos {translate rotate scale} def privatedict begin /showpage {} def end \n) writestring } def /dasharray [ [ [] 0 ] [ [3] 0 ] [ [6] 0 ] ] def /setdashpat{% n => - dasharray exch get aload pop setdash} def /print_dasharray_ps{% PSfile (/dasharray [\n) writestring dasharray {aload pop exch %offset array PSfile ([ [ ) writestring { PSfile exch ( % ) exch [ exch ] fprintf} forall PSfile ( ] ) writestring PSfile exch ( % ] ) exch [ exch ] fprintf } forall PSfile ( ] def\n) writestring } def /importfiledict null def %used when generating the postscript file %to remind what imported PS file have already been written /RepaintAll_ps {% generates postscript file PrintPS_header /importfiledict 50 dict store PSfile (gsave \n) [] fprintf 0 1 Nobj 1 sub {ObjTable exch get dup null ne {dup begin ingroup end {pop} {/display_ps exch send} ifelse } {pop} ifelse} for PSfile (grestore showpage\n) [] fprintf } def /SaveAllObjects {% generates NeWS files of object def; loaded with run 0 1 Nobj 1 sub {ObjTable exch get dup null ne {dup begin ingroup end {pop} {/saveobject exch send} ifelse } {pop} ifelse} for } def /loadobj{%used in loading obj files. counttomark 1 add index %obj mark var1... varn obj /loadivar exch send cleartomark dup begin ingroup not end {pop} if } def (Loading Class def \n) printdbg /DrawObject Object dictbegin /X 0 def %position /Y 0 def /Sx 1 def %scaling /Sy 1 def /Angle 0 def %rotation /bbox null def %bounding box [x1,y1,x2,y2] /color -1 def %filling pattern = -1 : no filling /linewidth 0 def %line width /linecolor 0 def %line color = black /linestyle 0 def %line style = plain or dashed /linejoin 0 def /linecap 0 def /geom null def % % default geom is a rect [w,h] /tableindex -1 def /ingroup false def % true if object part of a group dictend classbegin /new { /new super send begin /init self send currentdict end } def /init { /bbox 4 array store} def /delete { /erase self send ObjTable tableindex null put} def /destroy {} def /saveivar{%writes instance var. on File OSfile ( % % % % % ) [X Y Sx Sy Angle] fprintf OSfile ( [ % % % % ] \n) bbox fprintf OSfile ( % % % % % % \n) [color linewidth linecolor linestyle linejoin linecap] fprintf /save_geom self send OSfile ( % ) [ingroup] fprintf } def /loadivar {% mark objects instances var => self if ingroup else - %in the order in which they are defined /ingroup exch store %tableindex /geom exch store /linecap exch store /linejoin exch store /linestyle exch store /linecolor exch store /linewidth exch store /color exch store /bbox exch store /Angle exch store /Sy exch store /Sx exch store /Y exch store /X exch store } def /getclassname{%get the class name of the object ParentDictArray dup length 1 sub get begin ClassName end } def /saveobject{%saves object descr in OSfile OSfile (/new % send dup AddObject mark \n) [/getclassname self send] fprintf /saveivar self send OSfile ( loadobj\n) writestring } def /save_geom{%save geom descr OSfile ( [ % % ]\n) geom fprintf} def /setradcorner {pop} def /setlinestyle{/linestyle exch store} def /setlinejoin2 {/linejoin exch store} def /setlinecap2 {/linecap exch store} def /setlinewidth2 { /linewidth exch store } def /setlinecolor { /linecolor exch store } def /setcolor { /color exch store } def /changefont {} def /changefontsize {} def /update_control_panel{% put display param of objects in control panel linewidth linecolor color linestyle linejoin linecap putinControlPanel } def /bbox_path { %in absolute coord syst. bbox 0 get bbox 1 get moveto bbox 2 get bbox 0 get sub bbox 3 get bbox 1 get sub rect } def /make_path { % Sx Sy angle X Y => - %makes the path of the object : default is drawing a rect %of W, H geom null ne { spos % translate rotate scale newpath 0 0 moveto geom aload pop rect} if } def /make_path_ps{% - => - geom null ne { PSfile (spos newpath 0 0 moveto % % rect\n) geom fprintf} if } def /is_in_box {% x y => bool ; gsave /bbox_path self send pointinpath grestore } def /is_in_obj {% x y => bool ; geom null eq {pop pop false} {gsave newpath moveto X Y translate Angle rotate Sx Sy scale % {} {} {} {} pathforall %x y in object coord. sys. 1 1 0 0 0 /make_path self send pointinpath grestore} ifelse } def /dr { %low-level drawing : linewidth linecolor color linejoin linecap % linestyle => - %graphic state is preserved; dash not implemented in news %emulate it gsave setdashpat setlinecap setlinejoin Sx Sy Angle X Y /make_path self send dup -1 ne {gsave setgray fill grestore} {pop} ifelse setgray setlinewidth stroke grestore } def /dr_ps {% color => - PSfile (gsave setdashpat setlinecap setlinejoin % % % % %\n) [Sx Sy Angle X Y] fprintf /make_path_ps self send -1 ne { PSfile ( gsave setgray fill grestore ) [] fprintf} {PSfile ( pop ) [] fprintf} ifelse PSfile (setgray setlinewidth stroke grestore\n) [] fprintf } def /erase { % this will also erase parts of overlapping objects linewidth 1 color -1 eq {color} {1} ifelse linejoin linecap linestyle /dr self send } def /display { %display the object linewidth linecolor color linejoin linecap linestyle /dr self send} def /display_ps {%generation of postscript PSfile ( % % % % % % ) [linewidth linecolor color linejoin linecap linestyle] fprintf color /dr_ps self send } def /make_bbox { %computes the bounding box of the object in the current %coord system mtrx0 currentmatrix pop gsave Sx Sy Angle X Y /make_path self send %path made in trans,scaled,rotated %coord. sys; get coord in normal sys; mtrx0 setmatrix %path set in mtrx0 coord syst. pathbbox bbox astore pop grestore } def /move { % x' y' sx' sy' a' => moves to new position and orientation; % recomputes bbox; erase_flag {/erase self send} if /Angle exch def /Sy exch def /Sx exch def /Y exch def /X exch def /make_bbox self send /display self send } def /set_geom {% [p1,p2] => - ; new H and W /geom exch store } def /scale_geom { % sx sy => - geom 1 get mul geom exch 1 exch put geom 0 get mul geom exch 0 exch put } def /get_geom { % => geom } def /change_geom {%change geometry; => - %erases old shapes and redraws it; /erase self send exec %exec change proc on stack /make_bbox self send /display self send } def /make_opath{ %the outline path used in draging mode /make_path self send } def /drag { %drag outline of shape following cursor % returns dragged position of new origin X' Y' /oldcanvas currentcanvas store setoverlay /Angle2 Angle store /Sx2 Sx store /Sy2 Sy store 0 0 { newpath Sx2 Sy2 Angle2 x y gsave /make_opath self send stroke grestore } getanimated waitprocess aload pop oldcanvas setcanvas } def /bbox_center { % => xc, yc ; box center bbox 0 get bbox 2 get add 2 div bbox 1 get bbox 3 get add 2 div } def /drotate {%interactive rotation : put x y on stack /oldcanvas currentcanvas store setoverlay /Angle2 Angle store /Sx2 Sx store /Sy2 Sy store /X2 X store /Y2 Y store /bbox_center self send /Yc exch store /Xc exch store 0 0 { newpath % get angle of vector Xc,Yc - x,y Sx2 Sy2 Angle2 y Yc sub x Xc sub atan add X2 Y2 gsave /make_opath self send stroke grestore } getanimated waitprocess aload pop oldcanvas setcanvas } def /dscale { %interactive scaling from box lower left corner /oldcanvas currentcanvas store setoverlay /Angle2 Angle store /Sx2 Sx store /Sy2 Sy store /X2 X store /Y2 Y store /Xc bbox 2 get bbox 0 get sub store /Yc bbox 3 get bbox 1 get sub store % /get_geom self send bbox 0 get bbox 1 get { newpath Sx2 x x0 sub Xc div mul Sy2 y y0 sub Yc div mul Angle2 X2 Y2 gsave /make_opath self send stroke grestore } getanimated waitprocess aload pop oldcanvas setcanvas } def /drag_and_scale {%scale the geometry definition; preserve line width!! /dscale self send % [old_geom] ,x y of new bbox corner on stack /Y2 exch store /X2 exch store X2 bbox 0 get sub bbox 2 get bbox 0 get sub div %sx' Y2 bbox 1 get sub bbox 3 get bbox 1 get sub div %sy' % X Y Sx2 Sx mul Sy2 Sy mul Angle /move self send} def % this does not preserve line width ! {/scale_geom self send} /change_geom self send } def /drag_and_trans { /drag self send %x' y' on stack; move to that Sx Sy Angle /move self send} def /drag_and_rotate { /drotate self send %x' x' on stack; recompute angle; /Y2 exch store /X2 exch store X Y Sx Sy Angle Y2 Yc sub X2 Xc sub atan add /move self send} def /i_get_geom {%gets geom def. from user interaction ; - => X Y [geom def] getwholerect waitprocess % [x0 y0 x1 y1] aload pop /Y1 exch store /X1 exch store /Y0 exch store /X0 exch store X0 Y0 [X1 X0 sub Y1 Y0 sub] } def /i_def_geom {%interactive definition of geom /oldcanvas currentcanvas store setoverlay /i_get_geom self send % X Y 3 -2 roll oldcanvas setcanvas geom null ne {/erase self send} if /Y exch store /X exch store /set_geom self send geom null ne { /make_bbox self send /display self send} if } def /edit_geom {} def /clone_geom {%obj contains in its geom structured data which is %shared by other objects ; copies geom and bbox geom type (arraytype) eq {/geom geom dup length array copy store } if bbox 4 array copy /bbox exch store } def /clone { % -> returns a clone of self self length dict self exch copy %clone on stack dup /clone_geom exch send } def classend def (Oval \n) printdbg /Oval DrawObject %geom = [w,h] of oval dictbegin dictend classbegin /new { /new super send begin currentdict end } def /make_path {% geom contains radius; geom null ne { spos % translate rotate scale newpath 0 0 geom 0 get geom 1 get ovalpath } if } def /make_path_ps{ geom null ne { PSfile ( spos newpath 0 0 % % ovalpath\n) geom fprintf } if } def /i_get_geom { getclick /Y0 exch store /X0 exch store %center X0 Y0 {newpath x0 y0 x x0 sub y y0 sub ovalpath } getanimated waitprocess aload pop %x1 y1 /Y1 exch store /X1 exch store X0 Y0 [X1 X0 sub Y1 Y0 sub] %X,Y, w, h } def classend def (Group \n) printdbg /Group DrawObject dictbegin /Ngr 0 def %geom will contain an array with all the subobjects %position of subobjects are relative to the position %of the group /Ncopy 0 def %working var. for recursive cloning dictend classbegin /new { /new super send begin currentdict end } def /saveivar { /saveivar super send OSfile ( % ) [Ngr] fprintf } def /loadivar{ /Ngr exch store /loadivar super send } def /delete {% all components are defined in the group coord. syst. % put them back in the global syst. mtrx0 currentmatrix pop %translation correction gsave /components_path self send mtrx0 setmatrix %coord expressed in global syst. /N 0 store {pop pop} {%component position X Y geom N get begin /Y exch store /X exch store end /N N 1 add store} {} {} pathforall grestore %rotation /Angle2 Angle store geom {dup begin /Angle Angle Angle2 add store /ingroup false store end /make_bbox exch send } forall ObjTable tableindex null put ingroup not {gsave 1 setgray /contour_mark self send grestore} if } def /clone_geom{% makes a clone of each component /clone_geom super send /Ncopy 0 store geom { /clone exch send dup geom exch Ncopy exch put /Ncopy Ncopy 1 add store AddObject} forall } def /destroy {%deletes all compoments /erase self send geom {begin ObjTable tableindex null put end} forall ObjTable tableindex null put } def /setradcorner { /Xc exch store geom {Xc exch /setradcorner exch send} forall} def /setlinejoin2 { /Xc exch store geom {Xc exch /setlinejoin2 exch send} forall} def /setlinecap2 { /Xc exch store geom {Xc exch /setlinecap2 exch send} forall} def /setlinestyle { /Xc exch store geom {Xc exch /setlinestyle exch send} forall} def /setlinewidth2 { /Xc exch store geom {Xc exch /setlinewidth2 exch send} forall} def /setlinecolor { /Xc exch store geom {Xc exch /setlinecolor exch send} forall} def /setcolor { /Xc exch store geom {Xc exch /setcolor exch send} forall} def /make_path {%stroke the path of each object; used in draging mode %for scaling, we can not have at the same time good %scaling of objects positions and good scaling of their shapes geom null ne { spos geom {dup begin % Sx3 Sy3 Sx Sy Angle X Y end 6 -1 roll gsave /make_path exch send stroke grestore} forall } if } def /make_opath {%stroke the path of each object; used in draging mode %for scaling, we can not have at the same time good %scaling of objects positions and good scaling of their shapes geom null ne { spos geom {dup begin % Sx3 Sy3 Sx Sy Angle X Y end 6 -1 roll gsave /make_opath exch send stroke grestore} forall } if } def /is_in_obj { /is_in_box self send} def /set_geom {%[o1 o2 o3 ...] => %change X Y of Oi to X' Y' relative to X Y of group obj %set ingroup flag of each Oi % (set_geom\n) print dup length /geom exch array store geom copy pop /Ngr geom length store %get origin of group : first point of bbox /X 0 store /Y 0 store % /make_bbox_component self send /make_bbox self send bbox aload pop %x1 y1 x2 y2 pop pop /Y exch store /X exch store /X0 X store /Y0 Y store geom {begin /X X X0 sub store /Y Y Y0 sub store /ingroup true store end} forall /make_bbox_component self send ( % components put in group) [Ngr] prmessage } def /save_geom{% saves on OSfile an array composed of each object saving OSfile ([ %group geometry\n) writestring geom {/saveobject exch send} forall OSfile ( ] %end of group geometry\n) writestring } def /make_bbox_component{%compute bbox of comp. in this group coord. syst gsave X Y translate %Angle rotate Sx Sy scale geom { /make_bbox exch send} forall grestore } def /contour_mark{ bbox 0 get bbox 1 get moveto -2.5 dup rmoveto 5 5 rect fill bbox 0 get bbox 2 get add 2 div bbox 1 get moveto -2.5 dup rmoveto 5 dup rect fill bbox 2 get bbox 1 get moveto -2.5 dup rmoveto 5 dup rect fill bbox 2 get bbox 1 get bbox 3 get add 2 div moveto -2.5 dup rmoveto 5 dup rect fill bbox 2 get bbox 3 get moveto -2.5 dup rmoveto 5 dup rect fill bbox 0 get bbox 2 get add 2 div bbox 3 get moveto -2.5 dup rmoveto 5 dup rect fill bbox 0 get bbox 3 get moveto -2.5 dup rmoveto 5 dup rect fill bbox 0 get bbox 1 get bbox 3 get add 2 div moveto -2.5 dup rmoveto 5 dup rect fill } def /display { gsave Sx Sy Angle X Y spos geom {/display exch send} forall grestore ingroup not { gsave 0 setgray /contour_mark self send grestore} if } def /align_left{%align all elements on the left side of the bbox geom{begin /X X bbox 0 get sub store end} forall /make_bbox_component self send } def /align_bottom{ geom{begin /Y Y bbox 1 get sub store end} forall /make_bbox_component self send } def /align_right{% /X1 bbox 2 get bbox 0 get sub store geom {begin /X X X1 bbox 2 get sub add store end} forall /make_bbox_component self send } def /align_top{% /X1 bbox 3 get bbox 1 get sub store geom {begin /Y Y X1 bbox 3 get sub add store end} forall /make_bbox_component self send } def /center_vertical{ /X1 bbox 2 get bbox 0 get add 2 div bbox 0 get sub store geom {begin /X X X1 bbox 2 get bbox 0 get add 2 div sub add store end} forall /make_bbox_component self send } def /center_horizontal{ /X1 bbox 3 get bbox 1 get add 2 div bbox 1 get sub store geom {begin /Y Y X1 bbox 3 get bbox 1 get add 2 div sub add store end} forall /make_bbox_component self send } def /display_ps { PSfile (gsave % % translate % rotate % % scale\n) [X Y Angle Sx Sy] fprintf geom {/display_ps exch send} forall PSfile ( grestore\n) [] fprintf } def /erase { gsave X Y translate Angle rotate Sx Sy scale geom {/erase exch send} forall grestore ingroup not { gsave 1 setgray /contour_mark self send grestore} if } def /scale_geom {%sx sy /Sy2 exch store /Sx2 exch store geom {dup Sx2 Sy2 /scale_geom 4 -1 roll send begin /X X Sx2 mul store /Y Y Sy2 mul store end} forall /make_bbox_component self send } def /changefont { {geom { /changefont exch send} forall} /change_geom self send } def /changefontsize{ {geom {/changefontsize exch send} forall} /change_geom self send } def /components_path {%makes a path going from 0 0 to origins of components %relative to group coord. syst. X Y translate Angle rotate Sx Sy scale newpath 0 0 moveto geom {begin X Y lineto end} forall } def /make_bbox {% approximatively computed from the box of components %expressed relatively %to the group coord. syst. mtrx1 currentmatrix pop gsave %draws a path following all the boxex components X Y translate Angle rotate Sx Sy scale geom 0 get begin bbox aload pop %x1 y1 x2 y2 newpath moveto pop pop end geom 0 Ngr getinterval {begin bbox aload pop %x1 y1 x2 y2 2 copy lineto %x1 y1 x2 y2 ; x2 y2 1 index 3 index lineto % ; x2 y1 3 index 3 index lineto % ; x1 y1 3 index 1 index lineto % ; x1 y2 pop pop pop pop end} forall mtrx1 setmatrix pathbbox bbox astore pop grestore } def /i_get_geom_enum{%put selected objects as part of group getclick %X1 Y1 - group origin /Y1 exch store /X1 exch store /X2 X1 store /Y2 Y1 store /Ntmp 0 store %repeat { (enter origin point : ) prmessage getclick /Y0 exch store /X0 exch store (select objects - end with twice the same point :) prmessage X0 X2 ne Y0 Y2 ne and { X0 Y0 find_object_on_pt dup null ne { dup begin (% added in group) [tableindex] prmessage end tmparray exch Ntmp exch put /Ntmp Ntmp 1 add store } {pop} ifelse /X2 X0 store /Y2 Y0 store } {exit} ifelse } loop % Ntmp 3 string cvs print ( N\n) print X1 Y1 tmparray 0 Ntmp getinterval } def /i_get_geom_by_box{%define group in giving a box (enter box enclosing objects to group : ) prmessage getwholerect waitprocess %[x1 y1 x2 y2] /bbox exch store [ bbox find_objects_in_box /Ntmp exch store ] (% objects to group) [Ntmp] prmessage bbox 0 get bbox 1 get 3 -1 roll %the origin should be %the bounding box } def /i_get_geom{ group_def_mode (by box) eq {/i_get_geom_by_box self send} {/i_get_geom_enum self send} ifelse } def classend def (ClippingGroup \n) printdbg /ClippingGroup Group dictbegin %a clipping group is composed of 2 objects : the first one %is the clipping obj and the second one the clipped obj. The clipping obj %should be a line or curve; dictend classbegin /setclip{ mtrx1 currentmatrix pop geom 0 get begin Sx Sy Angle X Y end /make_path geom 0 get send clip %set the clip path mtrx1 setmatrix } def /set_geom {%[o1 o2 o3 ...] => %change X Y of Oi to X' Y' relative to X Y of group obj %set ingroup flag of each Oi % (set_geom\n) print dup length /geom exch array store geom copy pop /Ngr geom length store %get origin of group : first point of bbox of clipping geom 0 get begin bbox end aload pop %x1 y1 x2 y2 pop pop /Y exch store /X exch store /X0 X store /Y0 Y store geom {begin /X X X0 sub store /Y Y Y0 sub store /ingroup true store end} forall /make_bbox_component self send } def /delete{ geom 1 get begin /ingroup false store end gsave Sx Sy Angle X Y spos /display geom 1 get send grestore /delete super send } def /display { gsave Sx Sy Angle X Y spos /display geom 0 get send %dipslay clipping obj /setclip self send /display geom 1 get send %draws the clipped grestore } def /display_ps { PSfile (gsave % % % % % spos\n) [Sx Sy Angle X Y] fprintf /display_ps geom 0 get send PSfile ( % % % % % ) [geom 0 get begin Sx Sy Angle X Y end] fprintf /make_path_ps geom 0 get send PSfile ( clip ) [] fprintf /display_ps geom 1 get send PSfile ( grestore\n) [] fprintf } def /erase { gsave Sx Sy Angle X Y spos /erase geom 0 get send %dipslay clipping obj /setclip self send /erase geom 1 get send %draws the clipped grestore } def /make_bbox{ %the bounding box is the one of the clipping obj /Ngr 1 store /make_bbox super send /Ngr 2 store } def classend def (RoundedRect \n) printdbg /RoundedRect DrawObject dictbegin /radcorner 8 def dictend classbegin /new { /new super send begin currentdict end } def /setradcorner {/radcorner exch store} def /saveivar{ /saveivar super send OSfile ( % ) [radcorner] fprintf } def /loadivar{ /radcorner exch store /loadivar super send } def /make_path {% geom contains radius; geom null ne { spos % translate rotate scale newpath radcorner 0 0 geom 0 get geom 1 get rrectpath } if } def /make_path_ps{ geom null ne { PSfile (spos newpath % 0 0 % % rrectpath\n) [radcorner geom 0 get geom 1 get] fprintf } if } /i_get_geom { getclick /Y0 exch store /X0 exch store %center X0 Y0 {newpath radcorner x0 y0 x x0 sub y y0 sub rrectpath } getanimated waitprocess aload pop %x1 y1 /Y1 exch store /X1 exch store X0 Y0 [X1 X0 sub Y1 Y0 sub] %X,Y, w, h } def classend def /get_path {%ask a path to the user; path terminated by double-clicking %last point; %path put in tmparray as [ [x1,y1],.... ] , Ntmp elements %first point -origin - in X0, Y0, all xi,yi relative to origin %get points until two points are equal (enter points - enter twice the same point to end) prmessage getclick /Y0 exch store /X0 exch store %origin gsave X0 Y0 translate /X2 0 store /Y2 0 store /Ntmp 0 store %repeat { 0 0 { newpath 0 0 moveto tmparray 0 Ntmp getinterval {aload pop lineto} forall X2 Y2 moveto x y lineto stroke} getanimated waitprocess aload pop /Y1 exch store /X1 exch store X2 X1 eq Y2 Y1 eq and {exit} {tmparray Ntmp [X1 Y1] put /Ntmp Ntmp 1 add store /X2 X1 store /Y2 Y1 store } ifelse } loop grestore (% points path) [Ntmp] prmessage } def /edit_path{%edit path of a polyline {newpath 0 0 moveto tmparray 0 Ntmp getinterval {aload pop lineto} forall Closed {closepath} if stroke } g_edit_path } def ---------------------------------------------------------------------------- Yves Bernard Philips Research Lab Brussels, 2 av. Van Becelaere 1170 Brussels, Belgium bernard@prlb2.uucp From don@brillig.umd.edu Fri Jan 6 23:07:37 1989 Date: Fri, 6 Jan 89 23:07:37 EST To: NeWS-makers@brillig.umd.edu Subject: NeWSillustrator (part 2) From: mcvax!prlb2!bernard@uunet.uu.net (Bernard Yves) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) NeWSillustrator part 2 ---------------------------------------------------------------------------- /outline_proc {} def /Ne 0 def /g_edit_path{ %generic path edition %outline_proc => -; the outlining function %a path is in tmparray 0-Ntmp; %allows the user to edit %it by its moving points; /outline_proc exch store gsave Sx Sy Angle X Y spos /X2 0 store /Y2 0 store { %select point to move %equivalent to a getclick but with the good outlining function 0 0 {outline_proc} getanimated waitprocess aload pop /Y1 exch store /X1 exch store X2 X1 eq Y2 Y1 eq and {exit } %stop edition { /X2 X1 store /Y2 Y1 store X1 Y1 findpointofpath %=> -1 or N dup 0 ge %a point is selected {/Ne exch store (point selected -- move it) prmessage 0 0 {tmparray Ne [x y] put outline_proc} getanimated waitprocess pop } { (point not found) prmessage pop } ifelse } ifelse } loop grestore } def /findpointofpath{% X Y => N /N -1 store 0 1 Ntmp 1 sub {dup tmparray exch get aload pop %x y n x1 y1 3 index sub abs 3 lt exch %x y n b1 x1 4 index sub abs 3 lt %x y n b1 b2 and {/N exch store exit } {pop} ifelse } for pop pop N } def /outline_curve{ newpath 0 0 moveto /N 1 store /Xc 0 store /Yc 0 store tmparray 0 Ntmp getinterval {aload pop %x y N 3 eq {gsave Xc Yc moveto 2 copy /Yc exch store /Xc exch store curveto /N 1 store stroke grestore Xc Yc moveto} { 2 copy lineto /N N 1 add store} ifelse} forall } def /edit_curved_path{ {outline_curve stroke} g_edit_path } def /get_curved_path {%ask a path to the user; path terminated by double-clicking %last point; %path put in tmparray as [ [x1,y1],.... ] , Ntmp elements %first point -origin - in X0, Y0, all xi,yi relative to origin %get points until two points are equal (enter first point : ) prmessage getclick /Y0 exch store /X0 exch store %origin gsave (enter points 3 by 3 - enter twice the same point to end) prmessage X0 Y0 translate /X2 0 store /Y2 0 store /Ntmp 0 store /N 1 store %repeat { 0 0 { outline_curve X2 Y2 moveto x y lineto stroke} getanimated waitprocess aload pop /Y1 exch store /X1 exch store X2 X1 eq Y2 Y1 eq and {exit} {tmparray Ntmp [X1 Y1] put /Ntmp Ntmp 1 add store /X2 X1 store /Y2 Y1 store } ifelse } loop /Ntmp Ntmp Ntmp 3 mod sub store %Ntmp a multiple of 4 grestore (% curves path) [ Ntmp 3 div ] prmessage } def (Polyline \n) printdbg /Polyline DrawObject dictbegin /Npoint 0 def %nbre de points /Closed false def %if true -> polygon dictend classbegin /new { /new super send begin currentdict end } def /saveivar{ /saveivar super send OSfile ( % % ) [Npoint Closed] fprintf } def /loadivar{ /Closed exch store /Npoint exch store /loadivar super send } def /make_path {%the path coord relative to 0,0 are stored in an array in geom geom null ne { spos newpath 0 0 moveto geom {aload pop lineto} forall Closed {closepath} if } if } def /make_path_ps{ geom null ne { PSfile (spos newpath 0 0 moveto \n) [] fprintf geom {PSfile exch ( % % lineto \n) exch fprintf} forall Closed {PSfile ( closepath\n) [] fprintf} if } if } def /scale_geom { %sx sy => - mtrx0 currentmatrix pop gsave 0 0 0 /make_path self send %path mtrx0 setmatrix %path is scaled /N 0 store {pop pop} { %x y geom N get astore pop /N N 1 add store} {} {} pathforall grestore } def /i_get_geom { get_path %path introduced by user in tmparray; X0 Y0 tmparray 0 Ntmp getinterval %x y [array of [xi yi] ] on stack } def /edit_proc {edit_path} def /edit_geom {%interactive edition of geom (select point of line and move it -- click twice on same point to end) prmessage /oldcanvas currentcanvas store setoverlay /Ntmp Npoint store tmparray 0 geom putinterval /edit_proc self send oldcanvas setcanvas geom null ne {/erase self send} if tmparray 0 Ntmp getinterval /set_geom self send geom null ne { /make_bbox self send /display self send} if } def /set_geom { %[ [x1 y1] [x2 y2] ... ] => - dup length array /geom exch store geom copy length /Npoint exch store } def /save_geom{% OSfile ([ %polyg. geom\n) writestring geom {OSfile exch ( [ % % ] ) exch fprintf} forall OSfile ( ] %end of polyg. geom\n) writestring } def /clone_geom { %here the geom is an array of array geom type (arraytype) eq {/newarray geom length array store /N 0 store geom {2 array copy newarray exch N exch put /N N 1 add store} forall /geom newarray store} if /newarray 4 array store bbox newarray copy /bbox exch store } def classend def (Curve \n) printdbg /Curve Polyline dictbegin /iter 1 def dictend classbegin /new { /new super send begin currentdict end } def /make_path {%the path coord relative to 0,0 are stored in an array in geom geom null ne { spos % translate rotate scale newpath 0 0 moveto /iter 1 def geom { aload pop iter 3 eq {curveto /iter 1 store } {/iter iter 1 add store} ifelse } forall Closed {closepath} if } if } def /make_path_ps {%the path coord relative to 0,0 are stored in an array in geom geom null ne { PSfile (spos newpath 0 0 moveto\n) [] fprintf /iter 1 def geom { PSfile exch ( % % ) exch fprintf % aload pop iter 3 eq { PSfile ( curveto\n) [] fprintf /iter 1 store } {/iter iter 1 add store} ifelse } forall Closed {PSfile ( closepath\n) [] fprintf} if } if } def /scale_geom { %sx sy => - mtrx0 currentmatrix pop gsave 0 0 0 /make_path super send %path mtrx0 setmatrix %path is scaled /N 0 store {pop pop} { %x y geom N get astore pop /N N 1 add store} {} {} pathforall grestore } def /edit_proc {edit_curved_path} def /i_get_geom { get_curved_path %path introduced by user in tmparray; X0 Y0 tmparray 0 Ntmp getinterval %x y [array of [xi yi] ] on stack } def classend def /FontName /Times-Roman def /pointsize 30 def (Text\n) printdbg /TextObject DrawObject dictbegin /Fontname /Times-Roman def /Size 30 def /font null def /Sh 0 def %the height, width of the box enclosing the /Sw 0 def %string in global coord. sys. (non scaled and non rot.) dictend classbegin /new { /new super send begin currentdict end } def /init{ /init super send /Fontname FontName store /Size pointsize store /color 0 store %black } def /saveivar{ /saveivar super send OSfile (/% % % %) [Fontname Size Sh Sw] fprintf } def /loadivar{ /Sw exch store /Sh exch store /Size exch store /Fontname exch store /loadivar super send } def /save_geom{ OSfile ( \() writestring OSfile geom writestring OSfile (\) \n) writestring } def /make_font {% sets the font entry /font Fontname findfont Size scalefont store} def /set_font_and_size {% /fontname size => /Size exch def /Fontname exch def /make_font self send} def /changefont{ % change the font {/Fontname FontName store} /change_geom self send } def /changefontsize{% change font size {/Size pointsize store} /change_geom self send } def /make_path { geom null ne { spos Fontname findfont Size scalefont setfont newpath 0 0 moveto geom show } if } def /make_path_ps { geom null ne { PSfile (spos\n) [] fprintf PSfile ( /% findfont % scalefont setfont\n) [Fontname Size] fprintf PSfile (newpath 0 0 moveto (%) show\n) [geom] fprintf } if } def /is_in_obj { /is_in_box self send} def /dr {% linewidth linecolor color linejoin linecap linestyle => - only %color is important gsave pop pop pop setgray pop pop Sx Sy Angle X Y /make_path self send grestore } def /dr_ps{ PSfile (gsave pop pop pop setgray pop pop % % % % % \n) [Sx Sy Angle X Y] fprintf /make_path_ps self send PSfile (grestore\n) writestring } def /make_bbox{ %there seems to be problem with charpath and rotation; %therefore finds the box and draws it in the object coord. %system and extracts its bbox in the current coord. syst geom null ne { gsave mtrx0 currentmatrix pop Fontname findfont Size scalefont setfont 0 0 moveto geom stringbbox %here we have the box x,y,w,h 2 copy /Sh exch store /Sw exch store X Y translate Angle rotate Sx Sy scale 0 0 moveto rect pop pop mtrx0 setmatrix pathbbox bbox astore pop grestore} if } def /make_opath{ spos 0 0 moveto Sw Sh rect} def /scale_geom { %sx sy % max Size mul /Size exch store /Sy exch store /Sx exch store } def /i_get_geom {%the string is in textstring; /geom get_textstring store 0 0 {newpath Sx Sy Angle x y gsave /make_path self send grestore } getanimated waitprocess aload pop %x y textstring } def classend def (PostScriptImport\n) printdbg %the local bbox of the object is stored in the geom variable /alreadyimporteddict 50 dict def %for each imported file, will contain %a PostScript object for which the corresponding %drawproc has been correctly defined /PSFileCycle{ % filename => bool ; true if filename is an already % imported PS file false alreadyimporteddict { %key, value is an PS object %filename false key obj exch pop % obj /filename get %filename false filename2 2 index eq { %filename false pop true exit} if } forall exch pop } def %utilities /add_extension{% filename (.extension) => filename.extension exch %ext filename ( ) search %ext post match pre true { 4 -1 roll %post match pre ext 4 2 roll %pre ext post match pop pop append } { %ext pre exch append } ifelse } def /extract_fname{% /.../.../.../toto.xxx => toto.xxx { (/) search { % post match pre pop pop} {exit} ifelse } loop } def /make_wrappedfname{%filename => PWD/fname.wps (PWD) getenv (/) append exch extract_fname append (.wps) add_extension } def /achar 1 string def /linestring2 256 string def /make_procname{ % filename => - %from a filename make a postscript name %by repacing all / by a _ /N 0 store 0 1 linestring2 length 1 sub {linestring2 exch 32 put} for { achar 0 3 -1 roll put achar dup (/) eq {pop (_)} if %char or _ linestring2 N 3 -1 roll putinterval /N N 1 add store } forall linestring2 ( ) search pop %post match pre 3 1 roll pop pop cvn } def /linestring 256 string def /TmpFile null def /PS2file null def /errorstring 30 string def /copytofile{% filename file => bool ; true if error exch %file filename { (r) file /TmpFile exch store % file { dup % file file TmpFile linestring readline % file file subst bool {writestring % file dup (\n) writestring % file } {pop exit} ifelse } loop TmpFile closefile } stopped dup {get_errorstr} if } def /get_errorstr{%gets current errorname and puts it in errorstring $error begin errorname end errorstring cvs pop } def /fileerrorpr{% operation filename => - %print last file error message exch (file error : ) errorstring append exch append exch append prmessage } def /PostScript DrawObject dictbegin /drawproc nullproc def %the drawing code; any legal ps? /filename 100 string def %the imported file /privatedict null def /procname null def /savemtrx null def dictend classbegin /new { /new super send begin currentdict end } def /init{ /init super send % /geom 4 array store /privatedict 50 dict store %a private dict for drawproc def and store /savemtrx matrix store } def /clone_geom{ /clone_geom super send privatedict 50 dict copy /privatedict exch store } def /display{%drawing param are set; it is the responsability %of the drawing proc to reset them to its own values savemtrx currentmatrix pop gsave Sx Sy Angle X Y spos geom 0 get neg geom 1 get neg translate linewidth setlinewidth linecolor setgray linecap setlinecap linejoin setlinejoin linestyle setdashpat mark privatedict begin drawproc end cleartomark grestore savemtrx setmatrix } def /display_ps {%for each imported file a procedure / is %defined and called procname null eq {/procname filename make_procname store} if importfiledict procname known not {% the procedure is not yet defined in the ps file %procname procname self /drawproc get length 300 lt { PSfile (\n/%{\n) [ procname ] fprintf filename PSfile copytofile pop %procname PSfile (\n} def\n) writestring importfiledict procname 1 put %procname } if %if the proc is too long %do not create a proc, but write %the imported file each time it is needed } if PSfile (savemtrx currentmatrix pop gsave % % % % % spos % % translate\n) [Sx Sy Angle X Y geom 0 get neg geom 1 get neg] fprintf PSfile (% % % % % setdashpat setlinejoin setlinecap setgray setlinewidth\n) [linewidth linecolor linecap linejoin linestyle] fprintf self /drawproc get length 300 lt {PSfile (mark privatedict begin % end cleartomark grestore savemtrx setmatrix\n) [procname] fprintf } {PSfile (mark privatedict begin\n) writestring filename PSfile copytofile PSfile (end cleartomark grestore savemtrx setmatrix\n) writestring } ifelse } def /scale_geom{ Sy mul /Sy exch store Sx mul /Sx exch store } def /make_opath{%draws the local bbox spos % geom 0 get geom 1 get moveto 0 0 moveto geom 2 get geom 0 get sub geom 3 get geom 1 get sub rect } def /make_path{ /make_opath self send} def %will be used in is_in_obj; /erase{%erases the local bounding box gsave 1 setgray Sx Sy Angle X Y make_opath fill grestore } def /make_bbox{%computes the global bbox gsave mtrx0 currentmatrix pop Sx Sy Angle X Y /make_opath self send mtrx0 setmatrix pathbbox bbox astore pop grestore } def /load_drawproc{ % - => bool; true if ok; %if not already made, makes the wrapped file and loads it %the wrapped file is created in the user Home directory %with the same name as the user file and *.wps as extension /procname filename make_procname store alreadyimporteddict procname known %the dict entry contains the Postscript object %for which the corresponding drawproc has been defined {/drawproc {alreadyimporteddict procname get /drawproc get exec} def true } { /PS2file filename make_wrappedfname (w) file store PS2file (/drawproc{ \n) writestring filename PS2file copytofile %copies filename to the %end of PS2file {%error in copying file false } { PS2file (\n} def \n) writestring PS2file closefile (loading wrapped file ) filename make_wrappedfname append prmessage filename make_wrappedfname LoadFile dup {alreadyimporteddict procname self put} if } ifelse } ifelse } def /i_get_geom{ %reads the imported filename * and loads it %makes a 'wrapped' file *.wps %where the ps code is embedded : /drawproc{ } def %then loads it with LoadFile /filename get_ps_filename dup length string copy store (making wrapped file ) filename make_wrappedfname append prmessage /load_drawproc self send %true if ok; { (enter the bounding box : ) prmessage currentcanvas %the overlay canvas oldcanvas setcanvas %the win canvas {savemtrx currentmatrix pop gsave mark privatedict begin drawproc end cleartomark grestore savemtrx setmatrix} stopped {(error in executing PS file ) filename append prmessage setcanvas 0 0 null } { setcanvas %reset the overlay getwholerect waitprocess %box dup aload pop %box x1 y1 x2 y2 pop pop 3 -1 roll %x1 y1 box (PS file imported: ) filename append prmessage } ifelse } {( in loading ) filename fileerrorpr 0 0 null } ifelse }def /save_geom{ OSfile ( [ % % % % ] \n) geom fprintf} def /saveivar{ /saveivar super send OSfile ( \() writestring OSfile filename writestring OSfile (\) \n) writestring } def /loadivar{ /filename exch store mark /load_drawproc self send {} %ok {(error in importing) filename append prmessage)} ifelse cleartomark /loadivar super send } def classend def %building of an A4 size rectangle /a4rect /new DrawObject send def { /X 100 35 div 3 mul def /Y 100 35 div 3 mul def /geom [100 35 div 197 mul 100 35 div 282 mul] def /linecolor .85 def /linewidth 2 def /ingroup true def %so that it is not selectable by user; } a4rect send %============================================================================= %drawing area window definition %=========================================================================== /win framebuffer /new ScrollAndZoomWindow send def (main interaction routines\n) printdbg /selected_obj null def /old_selection null def /create_object {%class => obj {ClientCanvas} win send setcanvas /new exch send /selected_obj exch store /i_def_geom selected_obj send selected_obj begin geom end null ne {selected_obj AddObject} {/selected_obj null store} ifelse } def /create_polygon { {ClientCanvas} win send setcanvas /new Polyline send /selected_obj exch store selected_obj AddObject selected_obj begin /Closed true store end /i_def_geom selected_obj send } def /find_object_on_pt {%x y => obj | null %only objects which are not in a group can be found /Y0 exch store /X0 exch store /Xc null store /Yc null store ObjTable 0 Nobj getinterval { /Xc exch store Xc null ne {Xc begin ingroup end not {X0 Y0 /is_in_obj Xc send {/Yc Xc store exit} if} if} if} forall Yc } def /find_objects_in_box {% [x1 y1 x2 y2] => o1 o2.... on n /b1 exch store /N 0 def ObjTable 0 Nobj getinterval { /Xc exch store Xc null ne {Xc begin ingroup end not {Xc begin bbox end b1 box_in_box {Xc /N N 1 add store} if} if} if} forall N } def /select_object { {ClientCanvas} win send setcanvas gsave /oldcanvas currentcanvas store (select object by clicking on it : ) prmessage setoverlay getclick oldcanvas setcanvas find_object_on_pt grestore dup null ne {dup /erase exch send /selected_obj exch store pause /display selected_obj send selected_obj begin [tableindex] end (% is selected) exch prmessage /getclassname selected_obj send /Group ne {/update_control_panel selected_obj send} if } {pop (no object selected) prmessage} ifelse } def /i1 0 def /i2 0 def /swap_obj{ % o1 o2 => - ; swaps the 2 obj in ObjTable; dup begin /i2 tableindex store end exch dup begin /i1 tableindex store end %o2 o1 dup begin /tableindex i2 store end ObjTable exch i2 exch put dup begin /tableindex i1 store end ObjTable exch i1 exch put (% and % swapped) [i1 i2] prmessage } def /find_overlapping_obj{ % fromindex step toindex obj => first_over_obj %obj in X1, overlap in Xc /X1 exch store /Xc null store {ObjTable exch get dup /X2 exch store null ne {X2 begin ingroup end not {X1 begin bbox end X2 begin bbox end overlapping_box {/Xc X2 store exit} if } if } if } for Xc } def /move_down{ % obj => obj2 ; invert position of obj in ObjTable with % the next object behind it overlapping it dup begin tableindex end 1 sub -1 0 4 -1 roll find_overlapping_obj dup null ne {X1 Xc swap_obj} if } def /move_up{ % obj => obj2 ; invert position of obj in ObjTable with % the next object over it overlapping it obj2 dup begin tableindex end 1 add 1 Nobj 1 sub 4 -1 roll find_overlapping_obj dup null ne {X1 Xc swap_obj} if } def /apply_on_sel {% proc => - ; apply proc on selection if non null selected_obj null ne {{ClientCanvas} win send setcanvas exec } {pop (no object selected !) prmessage} ifelse } def /notifyselection true def /apply_on_sel2 {% proc => - ; apply proc on selection if non null selected_obj null ne notifyselection and {{ClientCanvas} win send setcanvas exec % (selection notified\n) print } {pop} ifelse } def /current_linecolor 0 def %black /current_linewidth 0 def %hair line /current_fill 0 def /current_linecap 0 def /current_linejoin 0 def /current_linestyle 0 def /current_radcorner 8 def /erase_flag true def /group_def_mode (by box) def /fontmenu [ FontDirectory { % include all fonts except /Cursor pop dup /Cursor ne { 25 string cvs dup length 3 le { pop } if } { pop } ifelse } forall ] [{/FontName currentkey store { /changefont selected_obj send} apply_on_sel2}] /new DefaultMenu send def /pointsizemenu [( 6 ) (8) (10) (12) (14) (16) (18) (24) (30) (32) (64)] [{/pointsize currentkey cvi store { /changefontsize selected_obj send} apply_on_sel2}] /new DefaultMenu send def /filemenu [ (save PS file) {generate_ps} (save Objects file) {generate_os} (load Objects file) {load_osfile} ] /new DefaultMenu send def /align_op{%align_proc => - selected_obj null ne {{ClientCanvas} win send setcanvas /getclassname selected_obj send /Group eq {/change_geom selected_obj send} if } {pop (no group object selected !) prmessage} ifelse } def /clipped_obj null def /clipping_obj null def /make_clip{%the current selection contains the clipped object %ask for the clipping obj and creates a ClippingGroup /clipped_obj selected_obj store clipped_obj begin /ingroup true store end select_object clipped_obj begin /ingroup false store end selected_obj null ne { /getclassname selected_obj send /Group ne /getclassname selected_obj send /TextObject ne and /getclassname selected_obj send /PostScript ne and { /clipping_obj selected_obj store /erase clipped_obj send /new ClippingGroup send /selected_obj exch store [clipping_obj clipped_obj] /set_geom selected_obj send /make_bbox selected_obj send /display selected_obj send selected_obj AddObject } { (error : the clipping obj can not be a group, a text or an importPS) prmessage /selected_obj clipped_obj store } ifelse } if } def /othermenu [ (edit line or curve) {{/edit_geom selected_obj send} apply_on_sel} (clip) {{make_clip} apply_on_sel} (align left) {{/align_left self send} align_op} (align bottom) {{/align_bottom self send} align_op} (align right) {{/align_right self send} align_op} (align top) {{/align_top self send} align_op} (center vertical) {{/center_vertical self send} align_op} (center horizontal) {{/center_horizontal self send} align_op} ] /new DefaultMenu send def /psfilename null def /get_ps_filename{ items /psfilename get /ItemValue get} def /notifypsfname{ /psfilename ItemValue store} def /PSfile null def /generate_ps { {ClientCanvas} win send setcanvas get_ps_filename PSFileCycle not { {get_ps_filename (w) file /PSfile exch store RepaintAll_ps PSfile closefile} stopped {get_errorstr ( in writing ) get_ps_filename fileerrorpr} {(PS file is written: ) get_ps_filename append prmessage} ifelse } {(can not write PS file: cycle,same name as an imported PS file ) get_ps_filename append prmessage } ifelse } def /osfilename null def /get_os_filename{ items /osfilename get /ItemValue get} def /notifyosfname{ /osfilename ItemValue store} def /OSfile null def /generate_os { {ClientCanvas} win send setcanvas {get_os_filename (w) file /OSfile exch store SaveAllObjects OSfile closefile} stopped {get_errorstr ( in writing ) get_os_filename fileerrorpr} {(Objects file is written: ) get_os_filename append prmessage} ifelse } def /load_osfile{ {ClientCanvas} win send setcanvas (loading...) prmessage get_os_filename LoadFile {(Object file loaded: ) get_os_filename append prmessage /PaintClient win send } {get_errorstr ( in loading ) get_os_filename fileerrorpr} ifelse } def (Window definition \n) printdbg { /PaintClient { ClientCanvas setcanvas 1 fillcanvas RepaintAll } def /FrameLabel (Drawing Area) def /ClientMenu [ (Redisplay) {/PaintClient ThisWindow send} (Select) {select_object} (Move) {{/drag_and_trans selected_obj send} apply_on_sel} (Rotate) {{/drag_and_rotate selected_obj send} apply_on_sel} (Scale) {{/drag_and_scale selected_obj send} apply_on_sel} (Copy) {{ /old_selection selected_obj store /selected_obj /clone selected_obj send store selected_obj AddObject /erase_flag false store /drag_and_trans selected_obj send /erase_flag true store } apply_on_sel} (Move Up) {{ selected_obj move_up dup null ne {/display exch send /display selected_obj send} {(no overlapping object over selection) prmessage} ifelse } apply_on_sel } (Move Down) {{ selected_obj move_down dup null ne {/display selected_obj send /display exch send} {(no overlapping object behind selection) prmessage} ifelse } apply_on_sel } (Delete) {{ /delete selected_obj send /selected_obj null store} apply_on_sel} (Destroy) {{ /destroy selected_obj send /selected_obj null store} apply_on_sel} (Other =>) othermenu (------) {} (Rect) { DrawObject create_object } (Line) { Polyline create_object } (Polygon) {Polyline create_object selected_obj begin /Closed true store end /display selected_obj send } (Curve) { Curve create_object } (RoundedRect) {RoundedRect create_object} (Oval) {Oval create_object} (Text) {TextObject create_object} (Group) {Group create_object} (Import PS) {PostScript create_object} (------) {} (Zoom In) {/ZoomIn win send} (Zoom Out) {/ZoomOut win send} (Font => ) fontmenu (FontSize => ) pointsizemenu (Files IO => ) filemenu ] /new DefaultMenu send def } win send %============================================================================ %control panel window definition %============================================================================ (Control Panel definition\n) printdbg systemdict /Item known not { (NeWS/liteitem.ps) run } if %systemdict /Item known not { (NeWS/liteitem.ps) LoadFile pop } if /notify? true def /notify { notify? {(Notify: Value=%) [ItemValue] /printf messages send} if } def /FillColor .75 def /prmessage { % sting => - print messages in Control Panel gsave /printf messages send grestore } def /notifylq {ItemValue 10 div setlinequality} def /notifylw {/current_linewidth ItemValue store { {current_linewidth /setlinewidth2 self send} /change_geom selected_obj send} apply_on_sel2 } def /notifylc {/current_linecolor ItemValue 100 div store { {current_linecolor /setlinecolor self send} /change_geom selected_obj send} apply_on_sel2 } def /notifyfc {/current_fill ItemValue 0 lt {-1} {ItemValue 100 div} ifelse store { {current_fill /setcolor self send} /change_geom selected_obj send} apply_on_sel2 } def /notifygroupdefmode {/group_def_mode ItemValue 0 eq (by box) (by enumeration) ifelse store } def /notifylcap{/current_linecap ItemValue store {{current_linecap /setlinecap2 self send} /change_geom selected_obj send} apply_on_sel2 } def /notifyljoin{/current_linejoin ItemValue store {{current_linejoin /setlinejoin2 self send} /change_geom selected_obj send} apply_on_sel2 } def /notifylstyle{/current_linestyle ItemValue store {{current_linestyle /setlinestyle self send} /change_geom selected_obj send} apply_on_sel2 } def /notifyradcorner {/current_radcorner ItemValue cvr dup 0 eq {pop 8} if store {{current_radcorner /setradcorner self send} /change_geom selected_obj send} apply_on_sel2 } def /textstring (enter string) def /notifytext{/textstring ItemValue store} def /gridon false def /gridsize 100 def /notifygridsize {/gridsize ItemValue cvr store} def /notifygridon {/gridon ItemValue 1 eq store } def /get_textstring{%gets the ItemValue of the text liteitem items /textstring get /ItemValue get dup /textstring exch store } def /draw_grid{% draws the grid gridon gridsize 0 gt and {gsave 0 setgray [2 5] 0 setdash 0 gridsize 1000 {dup 0 moveto 1000 lineto stroke} for 0 gridsize 1000 {dup 0 exch moveto 1000 exch lineto stroke} for grestore} if } def /putinControlPanel{%linewidth linecolor color linestyle linejoin linecap /notifyselection false store /oldcanvas currentcanvas store {ClientCanvas} controlpanel send setcanvas items begin linecap /ItemValue 3 -1 roll put /paint linecap send linejoin /ItemValue 3 -1 roll put /paint linejoin send linestyle /ItemValue 3 -1 roll put /paint linestyle send dup -1 ne {100 mul} if fillcolor /ItemValue 3 -1 roll put /paint fillcolor send 100 mul linecolor /ItemValue 3 -1 roll put /paint linecolor send linewidth /ItemValue 3 -1 roll put /paint linewidth send end oldcanvas setcanvas pause /notifyselection true store } def %Items creation /createitems { /items 15 dict dup begin /messages /panel_text () /Right {} can 700 0 /new MessageItem send dup begin /ItemFrame 1 def /ItemBorder 4 def end 20 20 /move 3 index send def /textstring (Text String:) (Text string) /Right /notifytext can 500 0 /new TextItem send 20 290 /move 3 index send def /osfilename (Objects file name:) (PWD) getenv % (/u3/bernard/NeWS/PrologNeWS/obj) /Right /notifyosfname can 500 0 /new TextItem send 20 260 /move 3 index send def /psfilename (PS file name:) (PWD) getenv %(/u3/bernard/NeWS/PrologNeWS/ps0) /Right /notifypsfname can 500 0 /new TextItem send 20 230 /move 3 index send def /gridsize (Grid Size:) (100) /Right /notifygridsize can 220 0 /new TextItem send 20 200 /move 3 index send def /gridbutton (Grid on:) [/panel_check_off /panel_check_on] /Right /notifygridon can 0 0 /new CycleItem send dup /LabelY -4 put 250 200 /move 3 index send def /linequality (line quality:) [0 10 10] /Right /notifylq can 220 20 /new SliderItem send 20 170 /move 3 index send def /linecap (line cap:) [(butt) (round) (square) ] /Right /notifylcap can 0 0 /new CycleItem send 250 140 /move 3 index send def /linejoin (line join:) [(miter) (round) (belevel) ] /Right /notifyljoin can 0 0 /new CycleItem send 355 170 /move 3 index send def /linestyle (line style:) [(plain) (dash1) (dash2) ] /Right /notifylstyle can 0 0 /new CycleItem send 250 170 /move 3 index send def /linewidth (line width:) [0 10 0] /Right /notifylw can 220 20 /new SliderItem send dup /ItemFrame 1 put 20 140 /move 3 index send def /linecolor (line color:) [0 100 0] /Right /notifylc can 220 20 /new SliderItem send dup /ItemFrame 1 put 20 110 /move 3 index send def /fillcolor (fill color:) [-1 100 -1] /Right /notifyfc can 220 20 /new SliderItem send dup /ItemFrame 1 put 20 80 /move 3 index send def /groupdef (Group Defined by :) [ ( box) ( enumeration) ] /Right /notifygroupdefmode can 220 0 /new CycleItem send 20 50 /move 3 index send def /radcorner (Rounded Corner Radius:) (8) /Right /notifyradcorner can 220 0 /new TextItem send 250 50 /move 3 index send def end def /messages items /messages get def } def /slideitem { % items fillcolor item => - gsave dup 4 1 roll % item items fillcolor item /moveinteractive exch send % item /bbox exch send % x y w h (Item: x=%, y=%, w=%, h=% Canvas: w=%, h=%) [ 6 2 roll win begin FrameWidth FrameHeight end ] /printf messages send grestore } def /MakeControlPanel { % Create and size a window. The size is chosen to accommodate the % items we are creating. Right before we map the window, we ask the % user to reshape the window. This is atypical, but gets the items % positioned the way we want them. /controlpanel framebuffer /new DefaultWindow send def % Create a window { /PaintClient {FillColor fillcanvas items paintitems} def /FrameLabel (Control Panel) def /IconImage /galaxy def /ClientMenu [ (White Background) {/FillColor 1 store /paintclient controlpanel send} (Light Background) {/FillColor .75 store /paintclient controlpanel send} (Medium Background) {/FillColor .50 store /paintclient controlpanel send} (Dark Background) {/FillColor .25 store /paintclient controlpanel send} (Black Background) {/FillColor 0 store /paintclient controlpanel send} (Flip Verbose) {/notify? notify? not store} ] /new DefaultMenu send def } controlpanel send % Install my stuff. 200 200 700 350 /reshape controlpanel send % Shape it. /can controlpanel /ClientCanvas get def % Get the window canvas % Create all the items. createitems % Create event manager to slide around the items. % Create a bunch of interests to move the items. % Note we actually create toe call-back proc to have the arguments we need. % The proc looks like: {items color "thisitem" slideitem}. % We could also have used the interest's clientdata dict. /slidemgr [ items { % key item exch pop dup /ItemCanvas get % item can MiddleMouseButton [items FillColor % item can name [ dict color 6 -1 roll /slideitem cvx] cvx % can name proc DownTransition % can name proc action 4 -1 roll eventmgrinterest % interest } forall ] forkeventmgr def % Now let the user specify the window's size and position. Then map % the window. (See above) Then activate the items. % /ptr /ptr_m framebuffer setstandardcursor /reshapefromuser controlpanel send % Reshape from user. /map controlpanel send % Map the window & install window event manager. % (Damage causes PaintClient to be called) /itemmgr items forkitems def } def MakeControlPanel 1 setlinequality a4rect AddObject %obj1 AddObject %obj2 AddObject %s1 AddObject /make_bbox a4rect send %/make_bbox obj1 send %/make_bbox obj2 send %/make_bbox s1 send /reshapefromuser win send /map win send 1000 1000 /Resize win send {/Scroll win send} {/Scroll win send} /SetNotifiers win send win /ClientCanvas get setcanvas win begin /overlaycan ClientCanvas createoverlay store end ---------------------------------------------------------------------------- Yves Bernard Philips Research Lab Brussels, 2 av. Van Becelaere 1170 Brussels, Belgium bernard@prlb2.uucp From don@brillig.umd.edu Fri Jan 6 23:08:56 1989 Date: Fri, 6 Jan 89 23:08:56 EST To: NeWS-makers@brillig.umd.edu Subject: Amiga Port of NeWS From: asuvax!nud!dover!fullmer@noao.edu (Glen Fullmer) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) The NeWS documentation says that there has been a NeWS port to the Amiga and the Atari ST. A Sun Rep said that their next (no relation) newsletter will have a listing of all the NeWS ports to foreign (no relation) machines. Rather than wait, I am requesting any information from those who have ported it, especially to the Amiga. Any information about NeWS ports would be appreciated. -- _____ _ "For a successful technology, reality must take precedence" {____/ // "over public relations, for Nature cannot be fooled." \ // _ __Richard P. Feynman, Appendix F of Shuttle Disaster Report {____/ , marshall@software.org (Eric Marshall) writes: > > I would like to conduct an informal survey to find out > how many people are using NeWS on a regular basis, and on what > platforms. I am interested in how many people are using NeWS > in your organization, and the manufacturer, model number and > operating system of the platform which you run it on. If you > would like to respond for your entire organization, please indicate > this, so that I can watch for other members of your organization > responding also. I will summarize and post the results to the > net in a few weeks. > The Silicon Graphics IRIS-4D series runs 4Sight which based on NeWS with extensions for Graphics Library canvases. As of software release 4D1-3.0, 4Sight (NeWS+...) replaced mex as the windowing system for the IRIS-4Ds thus almost all IRIS-4D users are 4Sight (NeWS) users. Silicon Graphics just announce shipment of it's 1000th Personal Iris (the 4D/20) so all their users are 4Sight (NeWS) users. I've been told by marketing that I can say conservatively 3000 IRIS-4Ds of the other varieties (4D/50/60/70/80/1xx/2xx) are in use. Most but not all of these IRIS-4Ds are running release 4D1-3.0 with 4Sight. I don't have any breakdown of the particular models or what percentage have not upgraded to 4D1-3.0. The IRIS-4D operating system is IRIX - AT&T System V rel 2 derived with BSD extensions. Other IRIX extensions include a multiprocessing kernel and NFS (as an option). So, I'd (unofficially) say, there are 3000-4000 IRIS-4D 4Sight (NeWS) users out there. Personally, I use 4Sight (NeWS) on a IRIS-4D/70GT. -- ciemo (pronounced SEE-MO) "Language is a virus" Ciemiewicz (pronounced SI-MI-WITZ) --- Laurie Anderson Dave (pronounced DAYV) From don@brillig.umd.edu Sat Jan 7 16:31:45 1989 Date: Sat, 7 Jan 89 16:31:45 EST To: NeWS-makers@brillig.umd.edu Subject: news neophyte From: nyit!michael@sbcs.sunysb.edu (Michael Gwilliam) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) I'm just beginning to program in NeWS using the NeWS Manual and the NeWS Application Senario that come with Sun Workstations. I'm begining to bog down in getting my application to do mouse dragging. Are there any other sources of information out there (like books or more tutorials or more sample source code). Any help would be appreciated. Thanks, Michael Gwilliam (philabs!nyit!michael) From don@brillig.umd.edu Mon Jan 9 17:08:29 1989 Date: Mon, 9 Jan 89 17:08:29 EST To: NeWS-makers@brillig.umd.edu Subject: Re: Amiga Port of NeWS From: rneill@sbcs.sunysb.edu (Richard Neill) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) In article <636@dover.uucp>, fullmer@dover.uucp (Glen Fullmer) writes: > The NeWS documentation says that there has been a NeWS port to the Amiga and > the Atari ST. A Sun Rep said that their next (no relation) newsletter will have > a listing of all the NeWS ports to foreign (no relation) machines. > > Rather than wait, I am requesting any information from those who have ported it, > especially to the Amiga. Any information about NeWS ports would be appreciated. > Ameristar technologies (516-698-0834) has ported and demonstrated at trade shows a port of NeWS 1.0 on both an Amiga 2000 and 500. Both run under AmigaDOS and communicate via ethernet. The port was demonstrated at last years Siggraph (with support from Sun) at the Commodore booth. The port was to show how NeWS could run on a "low cost" system" such as the Amiga 500. That's the good news. The bad news is that the product is not available to end users at this time due to market considerations. You can call Ameristar if you wish to chat about NeWS on the Amiga or if you have any specific questions. Richard Neill From don@brillig.umd.edu Mon Jan 9 17:12:39 1989 Date: Mon, 9 Jan 89 17:12:39 EST To: NeWS-makers@brillig.umd.edu Subject: Re: news neophyte From: frame!gergle!greg@Sun.COM Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) 2 drawing programs were just recently posted. The first looked like it was largely in C. It must have some useful sample code. If this doesn't help, you might try posting your code fragments to the mailing list. -greg. From don@brillig.umd.edu Mon Jan 9 17:13:16 1989 Date: Mon, 9 Jan 89 17:13:16 EST To: NeWS-makers@brillig.umd.edu Subject: availability of NeWS From: attcan!utgpu!jarvis.csri.toronto.edu!me!ecf!apollo@uunet.uu.net (Vince Pugliese) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) does anyone, Sun perhaps, have a list of the various platforms that are either currently running NeWS or that will be running NeWS in the future. please e-mail or post as you see fit. thanks in advance vince pugliese apollo@ecf.utoronto.ca apollo@ecf.toronto.edu From don@brillig.umd.edu Mon Jan 9 17:16:28 1989 Date: Mon, 9 Jan 89 17:16:28 EST To: NeWS-makers@brillig.umd.edu Subject: NeWS From: attcan!utgpu!jarvis.csri.toronto.edu!me!ecf!apollo@uunet.uu.net (Vince Pugliese) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) now that several firms have announced X terminals i was curious to know if a similar type of thing is going to occur with respect to NeWS. if anyone knows anything either e-mail or post as you see fit. thanks in advance vince pugliese apollo@ecf.utoronto.edu apollo@ecf.toronto.edu From don@brillig.umd.edu Mon Jan 9 21:07:55 1989 Date: Mon, 9 Jan 89 21:07:55 EST To: NeWS-makers@brillig.umd.edu Subject: SUG NeWS SIG Minutes From: erika!marilyn@unipress.unipress.com (Marilyn Kilinski) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) To: NeWS-makers@brillig.umd.edu From: rutgers!unipress!pookie (Marilyn R. Kilinski) Subject: SUG NeWS SIG Minutes NeWS SIG Minutes ================ WHAT: 2nd NeWS Special Interest Group Meeting, sponsored by UniPress Software WHERE: 6th Annual Sun User Group Conference, Miami Beach, Florida WHEN: Tuesday, 6 December, 2:30-4:30 p.m. SUBMITTED BY: Marilyn R. Kilinski, NeWS SIG Secretary-by-Default, UniPress WHAT HAPPENED: The SIG convened at about 2:30 p.m. Approximately 130 people showed up for the SIG. Representing Sun, Steve Messino (Corporate Marketing - NeWS) and Bruce Schwartz (Technical Services) participated in the SIG; Tony Hoeber (OPENLOOK Product Manager) was also in attendance. Marilyn Kilinski from UniPress welcomed the group; speakers were as follows: Mark Krieger, President of UniPress Software, gave a presentation on C2PS, UniPress' new C-to-PostScript compiler. Don Hopkins, University of Maryland, talked about NeWS-makers, the discussion group he moderates on the net, and the SUG software exchange tape. Hugh Daniel, Grasshopper Group, spoke about MacNews, which is NeWS for Mac IIs running A/UX. Rich Morin stood up and went off on a SCSI tangent. He was shushed by Saul Wold (Sun Micro ;=) Maurice Balick, ArchiTec, discussed his company's product, OS/2 NeWS. Steve Messino introduced himself to the group and indicated he would field questions later in the SIG. Bruce Schwartz gave a presentation on NeWS Draw, a NeWS draw program he had written, and NeWS-on-Wire (NeWS running over serial lines). A Q&A/discussion period then began, which lasted for an hour or so. Topics included: * Establishing NeWS more firmly by making it a window system that runs on many machines and operating systems. These included Amiga, Mac, MS-DOS, NeXT. Also, the idea of NeWS on an Amiga with an IBM mainframe client. * NeWS Development Environment (NDE) Toolkit source will be available to licensees, said Steve Messino. * Transputer-based workstations are a big thing in the U.K.; this should be considered for NeWS ports. * Questions/comments for Steve Messino (smessino@sun.com, 415/336-2017) * NeWS needs to be better promoted by Sun's PR department; there are a few technical articles about it, but never any news items in the UNIX trade press. X is much more visible. * Unbundle NeWS and make it free! (It will be on the AT&T Sys. V.4 tape, replied Steve.) * Steve said the NeWS community needs to produce as many ports of/applications running under NeWS as possible. His three main points were: - Sun will work w/developers to jointly market their NeWS products. - Leveraging staff and resources at Sun. - We need more NeWS applications! * Release date for X11/NeWS merge is 28 July 1989. Release date for NDE Toolkit is Fall 1989. Other group discussion topics: * Has anyone thought about an X-to-NeWS compiler? * There aren't any development tools for NeWS! (Sun is interested is getting such tools from outside sources, said Steve.) * Political problems remain - X remains the windowing environment of choice, so it's hard to make a good business decision by going w/NeWS. * How NeWS fits into the business scheme of things - developers and consultants spoke of their experience w/trying to sell NeWS-based solutions to clients. * Two big problems from developers' point of view: lack of PR for NeWS, and NDE Toolkit's thrice-delayed Fall 89 availability (too late). * Getting NeWS represented in the standards world - can we get this to happen? * Piggybacking NeWS onto OPENLOOK as the development environment? Meeting adjourned at 4:40 p.m. so we could go downstairs and listen to Bill Joy. SUBJECTIVE SUMMARY: Last year, NeWS was very new, and much of the group discussion centered on improving NeWS technically. This year, business issues (Sun backing NeWS better and how developers can succeed with NeWS-based products) were the subject of much lively exchange. NEXT MEETING: The NeWS SIG will meet again at the 7th Annual Sun User Group Conference in Anaheim, December 1989. -- Marilyn R. Kilinski, UniPress Software 23 December 1988 From don@brillig.umd.edu Tue Jan 10 18:03:09 1989 Date: Tue, 10 Jan 89 18:03:09 EST To: NeWS-makers@brillig.umd.edu Subject: Re: NeWS From: mws@aplpy.jhuapl.edu (Michael W. Stalnaker) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Vince; Can you give me an idea as to who has announced X terminal? I'm looking for bit-mapped terminals (NeWS or X) in general, and any info you can give me would be helpful.... Thanks in Advance. Mike Stalnaker mws@aplvax.jhuapl.edu From don@brillig.umd.edu Tue Jan 10 18:03:57 1989 Date: Tue, 10 Jan 89 18:03:57 EST To: NeWS-makers@brillig.umd.edu Subject: FrameMaker 1.3 psview... From: siegel@hc.dspo.gov (josh Siegel) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) I noticed that FrameMaker produced files that couldn't be viewed by psview under NeWS... If you apply the following to .../FrameMaker/.makerinit/postscript_prolog, you can both psview and print the postscript files. Note, the setpattern command has been gutted since the functions that would be needed havn't been implemented under NeWS. This has only been tested with FrameMaker 1.3.. --Josh Siegel *** postscript_prolog.working Tue Jan 10 13:20:21 1989 --- postscript_prolog Tue Jan 10 13:44:48 1989 *************** *** 245,250 **** --- 245,266 ---- {} settransfer offbits offbits onbits add div setgray } bind def + + version (1.1) eq { + /defaultmatrix { + gsave + initmatrix + currentmatrix + grestore + } bind def + + /setpattern { + pop pop pop pop + + .25 setgray + } bind store + } if + /grayness { setgray orgxfer cvx settransfer -- Josh Siegel (siegel@hc.dspo.gov) I like using a C-47A "puff dragon" to go shooting beer cans with. From don@brillig.umd.edu Thu Jan 12 10:45:35 1989 Date: Thu, 12 Jan 89 10:45:35 EST To: NeWS-makers@brillig.umd.edu Subject: Re: SUG NeWS SIG Minutes From: xanth!hoptoad!cfcl!rdm@ames.arc.nasa.gov (Rich Morin) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) I feel that I must respond to Marilyn's analysis of my NeWS BOF presentation: > Rich Morin stood up and went off on a SCSI tangent. He was shushed by Saul > Wold (Sun Micro ;=) I was introduced at the BOF by Hugh Daniel, of Grasshopper Group. This was not accidental - I have been working closely with the Grasshopper Group for the past several months. Hugh and I share a vision of NeWS as a mechanism for controlling and linking a wide variety of useful I/O devices. My own contribution, /dev/scsi, allows user-mode programs to talk to arbitrary SCSI devices. We have already printed NeWS images on an Apple LaserWriter II SC, and have also sent NeWS images successfully to a Mirus FilmPrinter. Future software will support the Apple Scanner and the General Computer Personal LaserPrinter. We feel that this sort of I/O capability enhances the utility of NeWS and empowers NeWS users. I may not have been clear on the relationship between NeWS and /dev/scsi. I depended somewhat on the background information in Hugh's introduction, and so the focus of my own presentation may not have been clear. Certainly Saul and Marilyn failed to see the connection. Others probably did, as well. In any event, my already short presentation (less than three minutes) was indeed shortened further in response to Saul's remarks. Persons wishing to know more about /dev/scsi are invited to attend the planned BOF at Usenix in San Diego. P.S. In contrast to the presentations made by UniPress and some other firms, my /dev/scsi presentation made no attempt to sell product. Indeed, /dev/scsi will be freely redistributable, since we would like it to be accepted as a standard. ;-} -- _ o _ |_ _ _ _ _ o _ Canta Forda Computer Laboratory | | | | | | | | | | | | | | UNIX software consulting and training | | |_ | | | | | |_| | | | | {hoptoad,pacbell}!cfcl!rdm +1 415 873 7841 From don@brillig.umd.edu Thu Jan 12 10:45:46 1989 Date: Thu, 12 Jan 89 10:45:46 EST To: NeWS-makers@brillig.umd.edu Subject: writescreen and writecanvas format question From: "Michael_Powers.Henr801M"@Xerox.COM Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Greetings. Anyone out there understand the format of the rasterfile that these use and why they don't write out areas smaller than 35x35???? For large bitmaps the format used in encoded. I use one of the sun conversion filters to create a standard format file (and then I convert that to X bitmap format - Phew). The large bitmaps come out fine. (except for small chunks of data being lost at the end of the rasterfile?) Any help in understanding the idiosyncrasies of these commands and formats would be most appreciated. MIke powers.henr801m@xerox.com From don@brillig.umd.edu Thu Jan 12 11:03:22 1989 Date: Thu, 12 Jan 89 11:03:22 EST To: NeWS-makers@brillig.umd.edu Subject: NeWSillustrator depends on ksh From: sgi!msc%ramoth.SGI.COM@ucbvax.Berkeley.EDU (Mark Callow) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) The recently posted NeWSillustrator attempts to (PWD) getenv The only shell (of the three we ship) that puts a PWD in its environment is ksh. Since I'm a csh user illustrator exited with an "undefined" error. -- -Mark From don@brillig.umd.edu Thu Jan 12 11:03:29 1989 Date: Thu, 12 Jan 89 11:03:29 EST To: NeWS-makers@brillig.umd.edu Subject: retained canvases - application writers please read From: sgi!msc%ramoth.SGI.COM@ucbvax.Berkeley.EDU (Mark Callow) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Almost every NeWS application that I have seen that uses retained canvases fails to respond correctly to /Damaged events. The most common problem is that the program paints into an unmapped retained canvas then maps the canvas. The program expects mapping to cause its bits to be transferred to the screen from the retained buffer. However to quote the NeWS manual Section 2.2, Page 14 "All programs have to cope with damage and must be able to reconstruct the damaged part" ... "retained canvases are purely a performance enhancement". and from Section 11.3, Page 120 "For color displays the cost of retaining canvases is often prohibitive". And to quote from "The NeWS Book" (not yet published) "Retained canvases are purely a performance enhancement. A server may choose to stop supporting retained canvases at any time, such as when running out of memory. Programs must always be ready to cope with damage." The Silicon Graphics 4Sight (NeWS) server, when running in RGB mode (the default mode on most of our systems) chooses not to support retained canvases. This is because of the memory cost of 24-bit deep pixels especially given our fast rendering speed. Therefore there may not be a retained buffer so the program had better be able to respond to damage when it maps a "retained" canvas. Those that don't will not work on a large class of machines running NeWS. Application writers please take note. -- -Mark From don@brillig.umd.edu Thu Jan 12 11:17:06 1989 Date: Thu, 12 Jan 89 11:17:06 EST To: NeWS-makers@brillig.umd.edu Subject: Printing NeWSIllustrator PostScript Files From: sgi!ciemo%bananapc.SGI.COM@ucbvax.Berkeley.EDU (Dave Ciemiewicz) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Silicon Graphics (and I believe Sun) uses Adobe's TranScript software for printing text on PostScript printers like the Apple LaserWriter. To print the files generated by Bernard Yves NeWSIllustrator, I've had to add '%!' PostScript magic number to the files by hand. To quote the Red Book (PostScript Language Reference Manual, p. 265, Comment Conventions), The very first line of every PostScript program (whether it is conforming or nonconforming) should be a comment that begins with the characters `%!'. By adding the line in the contextual illustrated in the contextual diff below, NeWSIllustrator will now generate PostScript files with the '%!' magic number allowing users to do things (on SGI boxes) like "lp ps0". *** Old stuff --- New lines with magic number code (don't forget to remove the '+' character) *************** *** 302,307 /PrintPS_header{ %postscript utilities PSfile (/rect {dup 0 exch rlineto exch 0 rlineto neg 0 exch rlineto closepath } def /ovalpath { matrix currentmatrix 5 1 roll --- 302,308 ----- /PrintPS_header{ %postscript utilities + PSfile (%!\n) writestring % PostScript header magic number PSfile (/rect {dup 0 exch rlineto exch 0 rlineto neg 0 exch rlineto closepath } def /ovalpath { matrix currentmatrix 5 1 roll *************** -- ciemo (pronounced SEE-MO) "Language is a virus" Ciemiewicz (pronounced SI-MI-WITZ) --- Laurie Anderson Dave (pronounced DAYV) From don@brillig.umd.edu Thu Jan 12 11:17:12 1989 Date: Thu, 12 Jan 89 11:17:12 EST To: NeWS-makers@brillig.umd.edu Subject: Re: retained canvases - application writers please read From: munnari!murtoa.cs.mu.oz.au!mwp%murtoa@uunet.uu.net (Michael Paddon) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) >From article <24631@sgi.SGI.COM>, by msc@ramoth.SGI.COM (Mark Callow): > > However to quote the NeWS manual Section 2.2, Page 14 > > "All programs have to cope with damage and must be able to > reconstruct the damaged part" ... "retained canvases are > purely a performance enhancement". Sometimes it is extremely useful to have a canvas that you *know* is retained. This, in fact, can be achieved under NeWS. To quote the NeWS 1.1 "READ THIS FIRST" document, Page 8 "One exception to this rule (that the NeWS server may ignore retained hints) is that the NeWS server must honor the /Retained setting of parent-less canvases" I presume that a parent-less canvas is one with a null value in its /Parent entry, although this is not explicitly stated. Note that any canvas may be made parent-less at any time. The major drawback of using parent-less canvases is that the functions of the window hieracrchy are not available (ie. child canvases moving with parent; child canvases clipped by parent). It's not at all clear why Sun defined this one special case for retained canvases. It would be much more useful to make the /Retained entry tri-valued (yes, no and maybe) so that if you *really* want offscreen bitmaps you don't have to write bizarre code. ======================================================== | Michael Paddon (mwp@munnari.oz.au) | | Department of Computer Science, Melbourne University | ======================================================== From don@brillig.umd.edu Thu Jan 12 23:00:12 1989 Date: Thu, 12 Jan 89 23:00:12 EST To: NeWS-makers@brillig.umd.edu Subject: Re: retained canvases - application writers please read From: spectral!sjs@bellcore.com (Stan Switzer) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) In article <11090@ulysses.homer.nj.att.com> cjc@ulysses.homer.nj.att.com (Chris Calabrese[mav]) writes: > In article <1154@murtoa.cs.mu.oz.au>, mwp@murtoa (Michael Paddon) writes: > | [...] > | To quote the NeWS 1.1 "READ THIS FIRST" document, Page 8 > | > | "One exception to this rule (that the NeWS server may ignore > | retained hints) is that the NeWS server must honor the > | /Retained setting of parent-less canvases" > | > | I presume that a parent-less canvas is one with a null value in > | its /Parent entry, although this is not explicitly stated. Note > | that any canvas may be made parent-less at any time. > | [...] > > I just tried changing `framebuffer' to a `null' in one > of my program segments (to draw a window), and got: > [an error] Well, there ARE parentless canvases, but as Chris discovered and as I have just confirmed, you can't create them with "newcanvas" or even mutate a parented canvas into one. The only retained, parentless canvases that I can find are the result of "readcanvas." Interestingly, these canvases need never actually exist as bitmaps since they can always be recreated from the original file (my guess is that this is indeed what happens on SGI 4Sight and possibly even in the Sun version). Unfortunately, this means is that there isn't any good way of doing double-buffered displaying (as in my wbounce demo). I really don't need a full 8 to 24 bit deep backing store for this but I do need some off-screen drawing space. What I would like to be able to do is to create a retained 1 plane deep canvas that I can subsequently use for imagemaskcanvas operations. Although it seems like there must be a way to do this, I haveso far been unable to find it. Alternatively, having some canvas attribute such as /Freeze that could be toggled to batch complex operations and then display the net result when unfrozen would be very useful. A very common scenario for a graphical tool is to erase some changed area and redraw it back-to-front. It is exceedingly annoying to have to watch this tedious process--especially if it destroys an illusion of continuous change. Perhaps someone knows of a supported approach to do double buffering? Stan Switzer sjs@ctt.bellcore.com "If you can't be just, be arbitrary." From don@brillig.umd.edu Thu Jan 12 23:00:20 1989 Date: Thu, 12 Jan 89 23:00:20 EST To: NeWS-makers@brillig.umd.edu Subject: Re: retained canvases - application writers please read From: spectral!sjs@bellcore.com (Stan Switzer) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) In article <13402@bellcore.bellcore.com> I write: > Well, there ARE parentless canvases, but as Chris discovered and as I > have just confirmed, you can't create them with "newcanvas" or even > mutate a parented canvas into one. The only retained, parentless > canvases that I can find are the result of "readcanvas." I have looked into this a bit further and it seems that I overlooked "buildimage" which seems to be able to build a non-parented, retained canvas of just about any size and depth. You seem to be able to reparent this canvas and map it (it worked for me). Interestingly, though, trying to set the parent back to null (canvas /Parent null put) both works and doesn't. It does reset the parent to null but gives you a "typecheck" error after having done so. I guess you could use "errored" to get around it if it mattered. I guess I answered my own question about how I can create a 1 pixel deep canvas to use with imagemaskcanvas that works regardless of whether your workstation is color or not. Now back to the original question. Is this the exception to the "retained is only an optimization" rule? Stan Switzer sjs@ctt.bellcore.com "What's this big red button do?" From don@brillig.umd.edu Thu Jan 12 23:04:48 1989 Date: Thu, 12 Jan 89 23:04:48 EST To: NeWS-makers@brillig.umd.edu Subject: news_server crash From: tktk@physics.att.com Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) I've been using NeWS (1.1) on my color 4/110 (OS 4.0) as a graphics server for several remote hosts on a production basis for about 6 months. I generate a lot of xy plots and histograms in PostScript and display them using psview. One small change was made to psview - if it finds an environment variable NeWSwidth it opens a square window of NeWSwidth size rather than asking the user to sweep one ( I got really tired of sweeping windows ). The problem is that occasionally ( ~ 1 in 100 ) I generate a postscript plot that crases the server - usually with an illegal instruction. If I restart the server and send the same plot it crashes again but if I change the plot in a trivial way ( rotate it by putting in a 90 rotate at the appropriate place or change the arguments to the initial scale call) the problem goes away. Anybody have any idea what might be going on? Terry tktk@physics.att.com From don@brillig.umd.edu Thu Jan 12 23:04:56 1989 Date: Thu, 12 Jan 89 23:04:56 EST To: NeWS-makers@brillig.umd.edu Subject: Re: The New LaTeX From: toms@ncifcrf.gov Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) OOPS!! Sorry that message was to go to a different news group; I typed the wrong mail alias. Thanks to those who pointed out the error. Tom From don@brillig.umd.edu Thu Jan 12 23:06:16 1989 Date: Thu, 12 Jan 89 23:06:16 EST To: NeWS-makers@brillig.umd.edu Subject: Re: retained canvases - application writers please read From: sgi!msc%ramoth.SGI.COM@ucbvax.Berkeley.EDU (Mark Callow) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) In article <13402@bellcore.bellcore.com>, sjs@spectral.ctt.bellcore.com (Stan Switzer) writes: > Well, there ARE parentless canvases, but as Chris discovered and as I > have just confirmed, you can't create them with "newcanvas" or even > mutate a parented canvas into one. The only retained, parentless > canvases that I can find are the result of "readcanvas." > Interestingly, these canvases need never actually exist as bitmaps > since they can always be recreated from the original file (my guess is > that this is indeed what happens on SGI 4Sight and possibly even in > the Sun version). > I think you've hit on the reason for the exception noted in the "READ ME FIRST" document. I can breath a sigh of relief. We have it right. On both Sun and SGI implementations readcanvas reads the file into an offscreen pixrect structure. It then plugs that pixrect into a canvas data structure as the "retained part" of the canvas. This has to be imaged using imagecanvas. You can't map this kind of canvas. > What I would like to be able to do is to create a retained 1 plane > deep canvas that I can subsequently use for imagemaskcanvas > operations. Although it seems like there must be a way to do this, I > haveso far been unable to find it. > I agree that some way to have Retained canvases with different depths from the display would be nice. The spin demo is a good example of where you could use this. Since the server has code to support 1-bit and 8-bit deep canvases adding this feature wouldn't be hard. > Perhaps someone knows of a supported approach to do double buffering? We'd love an approach to double buffering since we have the hardware to support it and would be able to use that. Servers without double buffering hardware could use the /Retained canvas code to simulate it. If anyone has any proposals for a double buffering spec, let me know. -- -Mark From don@brillig.umd.edu Fri Jan 13 10:59:28 1989 Date: Fri, 13 Jan 89 10:59:28 EST To: NeWS-makers@brillig.umd.edu Subject: Menu description languages From: brillig.umd.edu!don@mimsy.umd.edu (Don Hopkins) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) In article <550@island.uu.net> daniel@island.uu.net (Dan "yes that is my real name" Smith) writes: [...] >As long as I'm writing: I'd like to see menuing systems more like the >Info reader in Gnu Emacs - there are some situations where it makes >sense to have a menu item in two or more places; also, the users should >be able to redefine their menus. I'm not talking about specific systems, >just a general direction that I know I'd find more convenient to use. > > dan I did something along those lines for the UniPress's Emacs NeWS interface (NeMACS). I wrote a menu compiler that lets you create popup menus for NeWS by describing them in Emacs INFO nodes. Each node describes one menu. Each selection is specified by one line of text. Submenus are represented as links to other INFO nodes. Menu selections are pseudo-links that describe the action of a menu item. Actions include things like calling a PostScript function, typing in a string, calling an Emacs functions, popping up a message, etc. The menu compiler translates the info nodes into PostScript code for NeWS, and MLisp code that interfaces them to Emacs. The PostScript is loaded into NeWS to define popup menus that run independantly in the window server. The menu description language has the same syntax as INFO menus, so a selection that invokes a submenu is also an INFO link to the node describing that submenu, and a selection that invokes an action is just a link to a fake node whose name is the action. The menu compiler traverses the tree of nodes, so the tree of popup menus it creates reflects the structure of the INFO nodes. Users can edit the info nodes, and recompile and reload them on the fly to customize their menus. They can make popup menus for NeWS and interface them to Emacs without ever having to touch or even look at the PostScript and MLisp code produced by the compiler. I wrote it while I was working for UniPress on the Emacs NeWS interface, last summer, and it comes with Emacs version 2.20. Yes, it's a supported commercial product, but no, this isn't a commercial for it. I'd certianly like to hear about other peoples' experiences with menu description languages. -Don From don@brillig.umd.edu Sat Jan 14 01:24:36 1989 Date: Sat, 14 Jan 89 01:24:36 EST To: NeWS-makers@brillig.umd.edu Subject: help with charpath From: suneast!lite!byennaco@Sun.COM (Robert Yennaco) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) I'm new to the Postscript/NeWS world, just running in a terminal emulator, following the BLUE BOOK and interactively trying things out. I have a simple question that one of you NeWS hackers can probably answer for me. The path construction operator, `charpath', doesn't seem to work. Instead of getting character outlines, I get the string's bounding box. Anybody shed some light on this? From don@brillig.umd.edu Sat Jan 14 01:25:02 1989 Date: Sat, 14 Jan 89 01:25:02 EST To: NeWS-makers@brillig.umd.edu Subject: Psterm Loses Characters From: emory!km@gatech.edu (Ken Mandelberg) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) I've just started using the Grasshopper Group psterm and have noticed a problem. This is on a color Sun 3/60 running SunOS 4.0 and NeWS 1.1. The symptom is that psterm sometimes loses a hunk of output. I can't reproduce it consistantly but it happens most when: * I am using it to rlogin to another system * The window is partially covered or partially off screen * There is a relatively large burst of output. I thought at first that it might be that data was lost between rlogin and the pty or psterm and the ttyp, but that is not the case. If I refresh the window, the lost data shows up. Has anyone seen this problem? Are there any fixes to psterm that I missed? I'm running the code as posted. -- Ken Mandelberg | km@mathcs.emory.edu PREFERRED Emory University | {decvax,gatech}!emory!km UUCP Dept of Math and CS | km@emory.bitnet NON-DOMAIN BITNET Atlanta, GA 30322 | Phone: (404) 727-7963 From don@brillig.umd.edu Sat Jan 14 01:26:50 1989 Date: Sat, 14 Jan 89 01:26:50 EST To: NeWS-makers@brillig.umd.edu Subject: Adobe Illustrator88 From: suntan!fajita!doc@Sun.COM (Tom Dockery) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Is anybody else out there using Adobe Illustrator88 to generate Post- Script for use in NeWS? After you save your file (NOT EPS) on the MacIntosh, and get to your real computer :-) (we use TOPS, but there are other ways), all of Adobe's document definitions tend to make NeWS throw up. Here's the solution we've developed: strip the header and trailer information from the Ill88 file, and prepend the stuff you see listed below. We haven't yet dealt with everything, notably text and Pantone colors. You will also note that, due to differences in the MacII and NeWS color maps, your colors won't be quite what you expected. If anyone else out there is doing similar stuff, we'd be very interested in what you've done. Feel free to do to this what you want, but leave the notice attached, and please send to us or post here any neat stuff you do with it. Tom Dockery %! %%Illustrator88 header %%Creator: DRH, TWD, SP %%For: (Market Focus Technologies, Inc.) () % % Copyright (c) 1989 by Market Focus Technologies, Inc. % % This is a product of Market Focus Technologies, Inc. and is % provided for unrestricted use provided that this notice is left % intact as a part of the software program in whole or part. % % Users may copy, modify or distribute this file at will. % % THIS FILE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND. % % This is a replacement header to enable the use of files from % Adobe Illustrator88 in NeWS. Delete everything preceding the % line "%%EndSetup" and following the line "%%Trailer" from the % Illustrator file, and prepend this header. It doesn't work % with everything, notably with text, and it assumes the cmyk % color schema. Feel free to modify it for your needs, but % please keep us posted with any nifty additions or completions. % % % Tom Dockery % ...!sun!suntan!fajita!doc % % Market Focus Technologies, Inc. % 5964 La Place Ct., Ste. 100 % Carlsbad, California 92008 % % (Illustrator88 is an Adobe Trademark, but then you knew that.) %begin MFTI stuff /bdef {bind def} bind def /ldef {load def} bdef /xdef {exch def} bdef % graphic state operators /A {pop} bdef /a {pop} /R {0 ne /false exch def /none /none def} bdef /O {0 ne /false exch def /none /none def} bdef /_K {3 index add neg dup 0 lt {pop 0} if 3 1 roll} bdef /_k /setcmybcolor where {/setcmybcolor get} {{1 sub 4 1 roll _K _K _K setrgbcolor pop} bind} ifelse def /g {/_b xdef /p {_b setgray} def} bdef /G {/_B xdef /P {_B setgray} def} bdef /k {/_b xdef /_y xdef /_m xdef /_c xdef /p {_c _m _y _b _k} def} bdef /K {/_B xdef /_Y xdef /_M xdef /_C xdef /P {_C _M _Y _B _k} def} bdef /d /setdash ldef /_i currentflat def /i {dup 0 eq {pop _i} if setflat} bdef /j /setlinejoin ldef /J /setlinecap ldef /M /setmiterlimit ldef /w /setlinewidth ldef % path construction operators /c {transform .25 sub round .25 add exch .25 sub round .25 add exch itransform curveto} bdef /C /c ldef /v {currentpoint 6 2 roll transform .25 sub round .25 add exch .25 sub round .25 add exch itransform curveto} bdef /V /v ldef /y {transform .25 sub round .25 add exch .25 sub round .25 add exch itransform 2 copy curveto} bdef /Y /y ldef /l {transform .25 sub round .25 add exch .25 sub round .25 add exch itransform lineto} bdef /L /l ldef /m {transform .25 sub round .25 add exch .25 sub round .25 add exch itransform moveto} bdef % error operators /_e [] def /_E {_e length 0 ne {gsave 0 g 0 G 0 i 0 J 0 j 1 w 10 M [] 0 d /Courier 20 0 0 1 z [0.966 0.259 -0.259 0.966 _e 0 get _e 2 get add 2 div _e 1 get _e 3 get add 2 div] e _f t T grestore} if} bdef /_fill {{fill} stopped {/_e [pathbbox] def /_f (ERROR: can't fill, increase flatness) def %n _E} if} bdef /_stroke {{stroke} stopped {/_e [pathbbox] def /_f (ERROR: can't stroke, increase flatness) de%f n _E} if} bdef % path painting operators /n /newpath ldef /N /n ldef /P {0 setgray} bdef /p {1 setgray} bdef /F {p _fill} bdef /f {closepath F} bdef /S {P _stroke} bdef /s {closepath S} bdef /B {gsave F grestore S} bdef /b {closepath B} bdef % group construction operators /u {} bdef /U {} bdef %---- the end, remove any mail junk after this line ---- From don@brillig.umd.edu Sat Jan 14 20:13:06 1989 Date: Sat, 14 Jan 89 20:13:06 EST To: NeWS-makers@brillig.umd.edu Subject: Wanted Comments on Windows For Data on UNIX From: attcan!utzoo!dciem!trigraph!henry@uunet.uu.net (Henry Cheung) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) This is a re-posting. Has anybody out there used Windows for Data on a UNIX machine ? If yes, could you give me your comments on how the package performs ? Thanks in advance. Email: henry@trigraph.UUCP From don@brillig.umd.edu Sat Jan 14 20:13:26 1989 Date: Sat, 14 Jan 89 20:13:26 EST To: NeWS-makers@brillig.umd.edu Subject: Re: help with charpath From: uw-entropy!mica!charlie@june.cs.washington.edu (Charlie Geyer) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) In article <8901131858.AA05919@lite.sunecd.com> byennaco@lite.UUCP (Robert Yennaco) writes: >The path construction operator, `charpath', doesn't seem to work. Instead >of getting character outlines, I get the string's bounding box. >Anybody shed some light on this? It works. Try /Helvetica findfont 100 scalefont setfont newpath 100 300 moveto (Woof) false charpath flattenpath 5 setlinewidth 1 setlinejoin stroke showpage From don@brillig.umd.edu Sun Jan 15 04:52:19 1989 Date: Sun, 15 Jan 89 04:52:19 EST To: NeWS-makers@brillig.umd.edu Subject: Addendum to SUG NeWS SIG Minutes From: Don Hopkins Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Unfortunatly, one of the scheduled speakers never showed up for the SUG NeWS SIG... Alas, Elvis couldn't make it. How about trying to get Jimmy Hendrix to speak at NeWS SUG at San Diego Usenix? (We have a LaserWriter named Shirley Maclaine... Would that help? ;-) -Don From don@brillig.umd.edu Mon Jan 16 14:57:48 1989 Date: Mon, 16 Jan 89 14:57:48 EST To: NeWS-makers@brillig.umd.edu Subject: Some useful window subclasses From: dennis!dennis@boulder.colorado.edu Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) % -------------------------------------------------- % This file contains two major windowing subclasses: % 1. PlaneWindow - makes it look like the window is a view into % a client canvas of large size. The window can pan and scroll % over this larger canvas using scrollbars % 2. ControlWindow - PlaneWindow plus a message panel % plus a panel for providing input. % This document is explicity placed into the public domain. % Author: Dennis Heimbigner % Organization: Computer Science Dept. % University of Colorado, Boulder % -------------------------------------------------- systemdict /LiteWindow known not { (NeWS/litewin.ps) run } if systemdict /LiteMenu known not { (NeWS/litemenu.ps) run } if systemdict /Item known not { (NeWS/liteitem.ps) run } if % Define a subwindow of scroll window in which % the client canvas acts like a window onto a larger canvas (called the plane). % Moving the scrollbars appears to pan and scroll over the plane canvas. % When the scroll bar buttons are in the bottom and left, then they % cause the origin of the client canvas to appear in the bottom left. % As the canvas grows, the scale and location of the scroll bar % buttons may change independent of user actions % This relies on the assumption all drawing is done on the client % canvas and that no canvases overlay the client canvas % (except when rubberbanding or dragging). % This operates by redrawing onto the client canvas with appropriate % scale and translation. % Methods: % 1. "minx miny maxx maxy SetPlaneSize => -" % Set the size of the plane canvasover which the client % canvas can pan/scroll. % This may visibly affect the scroll bar button locations. % 2. "xscale yscale SetPlaneScale => -" % Set the scale used on the plane. % Changing this will have the effect of a zoom. % 3. "- CenterPlane => -" % Put center of the plane at the center of the client canvas % 4. "factor ExpandPlane => -" % Expand the size of the plane by the factor as a multiplier % in the +X -X, +Y -Y directions. % 5. "x y MovePlane => -" % Put origin of the client canvas at x,y of the plane. % Notes: % 1. Pan and Scroll are not smooth. % 2. A better way to do this might be % to have a separate canvas (the basecanvas) % which clients write on. Then the Client Canvas % truly becomes a view on the ase canvas. % I experimented with this, but have not succeeded % in making it work. /PlaneWindow ScrollWindow dictbegin /InstanceClass /PlaneWindow def % portion of the plane currently in use (needed for scrollbars) /minX 0 def /minY 0 def /maxX 1 def /maxY 1 def /ScaleX 1.0 def /ScaleY 1.0 def % Client origin wrt plane origin /PlaneX 0 def /PlaneY 0 def % Make the following a per-object value % because it will change as scale changes /ClientFont /Screen-Bold findfont 16 scalefont def dictend classbegin % /ForkPaintClient? false def % ??????????????????? /PlaneWidth {maxX minX sub} def /PlaneHeight {maxY minY sub} def /Xrange { [minX maxX PlaneWidth .01 mul round PlaneWidth .1 mul round null] %(Xrange: [ % % % % % ]\n) 1 index printf } def /Yrange { [minY maxY PlaneHeight .01 mul round PlaneHeight .1 mul round null] %(Yrange: [ % % % % % ]\n) 1 index printf } def % Enlarge (or shrink) the plane canvas by specifying new x and y dimensions % This will visibly affect only the scroll bar button locations /SetPlaneSize { % minx miny maxx maxy => - %4 array astore dup %(planewindow.SetPlaneSize: minx=% miny=% maxx=% maxy=%\n) exch printf %aload pop % keep things to integers 0.5 add truncate /maxY exch store 0.5 add truncate /maxX exch store 0.5 sub truncate /minY exch store 0.5 sub truncate /minX exch store % Make sure that the plane size is at least as big as % the client canvas. Extend equally in +x/y and -x/y directions to % achieve this affect ClientWidth PlaneWidth sub dup 0 gt { % deltax 2 div 0.5 add truncate dup maxX add /maxX exch store % deltax/2 minX exch sub /minX exch store } if ClientHeight PlaneHeight sub dup 0 gt { 2 div 0.5 add truncate dup maxY add /maxY exch store minY exch sub /minY exch store } if %(planewindow.SetPlaneSize.final: minx=% miny=% maxx=% maxy=%\n) %[minX minY maxX maxY] printf rerange } def /SetPlaneScale { % scalex scaley => - /ScaleY exch store /ScaleX exch store /ClientFont ClientFont ScaleX ScaleY min 16 mul scalefont store redisplay } def /reshape { % x y w h => - %4 array astore dup %(planewindow.reshape: x=% y=% w=% h=%\n) exch printf %aload pop /reshape super send % when the client canvas is reshaped, we need to % make sure that some portion of the previous % view is left visible. % We will assume that the point in the plane % that is at the client canvas origin before the reshape % is still at the origin after the reshape % This means that % if the client canvas gets bigger than the plane, % then the plane is extended in the positive x and % y directions only. % Doing it this way does have the funny effect % that the window may be refreshed twice. Seems no obvious fix. minX minY maxX maxY SetPlaneSize % will enforce constraint % and may force redisplay } def /rerange { % - => - Xrange /setrange HScrollbar send Yrange /setrange VScrollbar send % re paint scrollbars in toto PlaneX {/Itemvalue exch store paint} HScrollbar send PlaneY {/Itemvalue exch store paint} VScrollbar send } def /redisplay { % - => - eraseclient ShapeClientCanvas paintclient } def /setplaneorigin { % x y => - /PlaneY exch def /PlaneX exch def } def /MovePlane { % x y => - (set client canvas origin wrt plane origin setplaneorigin PlaneX HScrollbar movescroll PlaneY VScrollbar movescroll redisplay } def /CenterPlane { % - => - (put center of the plane at center of clientcanvas) minX PlaneWidth 2 div add % xc minY PlaneHeight 2 div add % xc yc MovePlane } def /ExpandPlane { % expansion => - [/minX /minY /maxX /maxY] { % expansion variable dup load % expansion var val 2 index mul store } forall rerange } def % client canvas manipulation /ClientPath { %(planewindow.clientpath: FrameHeight=% BorderBottom=% BorderTop=%\nClientHeight(calc)=% ClientHeight(actual)=%\n) %[FrameHeight BorderBottom BorderTop 3 copy add sub ClientHeight] printf /ClientPath super send PlaneX neg PlaneY neg translate ScaleX ScaleY scale } def /PaintClient { % - => - /PaintClient super send ClientFont setfont } def /eraseclient { % - => - gsave ClientCanvas setcanvas erasepage grestore } def % scroll bar manipulations /createscrollbars { % - => - (Create scrollbar canvases/items) /HScrollbar Xrange PlaneX {/planenotify MyPlane send} FrameCanvas /new SimpleScrollbar send dup /BarVertical? false put dup /MyPlane self put % Kludge: connect bar to this window store /VScrollbar Yrange PlaneY {/planenotify MyPlane send} FrameCanvas /new SimpleScrollbar send dup /MyPlane self put % Kludge: connect bar to this window store } def % repaint the button at a given location /movescroll { % value scrollbar => - { CheckValueBounds % setvalue /ItemValue exch store gsave ItemCanvas setcanvas ItemPaintedValue null ne {EraseBox} if PaintBox grestore /ItemPaintedValue ItemValue store } % value bar proc exch send } def /planenotify { % - => - /getvalue HScrollbar send /getvalue VScrollbar send MovePlane } def classend def pause %-------------------------------------------------- % Create a version of the PlaneWindow which has two panels at the bottom. % One is for displaying messages, and the other is for accepting % a line of text input by the user. % Several methods in the msgwindow class % are provided to write to the display area: % 1. "string DisplayString" % The DisplayString method clears the display panel % and prints the string in the panel. % 2. "format argarray DisplayFormat" % The DisplayFormat method clears the display panel, % formats the argarray using format string % and prints the result in the panel. % % Access to the reader panel is a bit more complicated: % 1. "string SetPrompt" % The SetPrompt method sets the prompt to be displayed % on the reader panel. % 2. "string SetInput" % The SetInput method sets the initial value of text % on the reader panel. % 3. "GetInput => string" % The GetInput method gets the current string contents % on the reader panel. % % Notification is handled in the following fashion. % The user invokes the following method to specify how he is to be notified % when the user hits in the reader panel. % 4. "[arg1 arg2 ... /operator client] SetReaderNotifier" % When return is hit in the reader panel, effectively the following occurs % arg0 arg1 ... /operator client send. % Note that this may occur asynchronously, which means that % the user might edit the reader panel, do a bunch of other stuff % and then later hit return. /ControlWindow PlaneWindow dictbegin /InstanceClass /IdControlWindow def /Display null def % Will be a msgitem /Reader null def % Will be a textitem /MsgWinEventMgr null def /ReaderAction null def dictend classbegin % Class Constants % Approximate constant for figuring out the placement of % the control elements (reader,display,scrollbar) /VerticalMeasure currentfont fontheight def % needs to be constant % Number of Vertical Measures used by the panels in Bottom Border % See /MoveFrameControls below. /VerticalCount 8 def % Fudge factor for sizing the borderbottom (if needed) /BBFudge 0 def /BorderLeft {/BorderRight super send} def /BorderBottom { VerticalMeasure VerticalCount mul /BorderBottom super send add BBFudge add round } def /DefaultPrompt (Input: ) def /destroy { % - => - (Create frame control canvases/items) /Display null def /Reader null def % break the reader/window cycle /destroy super send } def /CreateFrameControls { % - => - (Create frame control canvases/items) /CreateFrameControls super send () (Messages) /Right nullproc FrameCanvas /new MessageItem send /Display exch store {/EraseToUpdate true store} Display send {/ItemFrame 1 store} Display send (Input: ) () /Right {} FrameCanvas /new LineTextItem send /Reader exch store self { /ReaderClient exch def % (connect to parent window) /NotifyUser {/ReaderHandler ReaderClient send} store /ItemFrame 1 store % (to pretty up reader panel) } Reader send } def /CreateFrameInterests { % - => - (Create frame control interests) /CreateFrameInterests super send /MsgWinEventMgr [Reader] forkitems store } def /MoveFrameControls { % - => - ([Re]set frame control shapes) /MoveFrameControls super send 10 dict begin % track height used by each control as it is placed % order (and size) from bottom to top is : % margin 1/2 * VerticalMeasure % reader 3 * VerticalMeasure % margin 1/2 * VerticalMeasure % display 3 * VerticalMeasure % margin 1 * VerticalMeasure % hscrollbar 18 % Total should be less than the Border bottom defined at % beginning of this class /CurrentBottom VerticalMeasure 2 div def /Width ClientWidth 2 add def % same for everybody /X BorderLeft 1 sub def % same for everybody % Adjust label and object position Reader InitItemPosition % form x y w h for reader X CurrentBottom Width VerticalMeasure 3 mul %4 array astore dup %(reader.reshape: x=% y=% w=% h=%\n) exch printf %aload pop /reshape Reader send /OldDisplayY /LabelY Reader send store /CurrentBottom CurrentBottom /ItemHeight Reader send add VerticalMeasure 2 div add % inter control spacing store % Adjust label and object position Display InitItemPosition % form x y w h for Display X CurrentBottom Width VerticalMeasure 3 mul %4 array astore dup %(display.reshape: x=% y=% w=% h=%\n) exch printf %aload pop /reshape Display send /OldDisplayY /LabelY Reader send store /CurrentBottom CurrentBottom /ItemHeight Reader send add VerticalMeasure add % inter control spacing store % now move the horizontal bar to correct location BorderLeft 1 sub CurrentBottom FrameWidth BorderRight sub BorderLeft sub 2 add /BorderBottom super send %4 array astore dup %(hscrollbar.reshape: x=% y=% w=% h=%\n) exch printf %aload pop /reshape HScrollbar send /CurrentBottom CurrentBottom /ItemHeight Reader send add VerticalMeasure 2 div add % inter control spacing store end } def /PaintFrameControls { % - => - (Paint frame control areas) gsave % Display InitItemPosition % Reader InitItemPosition /PaintFrameControls super send [Display Reader] { dup InitItemPosition {location ItemWidth ItemHeight reshape paint} exch send pause } forall grestore } def /InitItemPosition { % Display/Reader => - {/LabelY 0 store /ObjectY 0 store /ObjectX 0 store /LabelX 0 store} exch send } def /SetPrompt { % readerprompt => - Reader InitItemPosition { %removefocus /ItemLabel exch store paint location ItemWidth ItemHeight reshape paint %restorefocus } Reader send } def /SetInput { % string => - Reader InitItemPosition { dup /ItemObject exch store dup /ItemValue exch store 21 inserttext % send ^U to clear line inserttext % insert string } Reader send } def /GetInput { % - => string /ItemValue Reader send % (reader contents) dup length string copy % return a copy of the string } def /DisplayString { % string => - (displays string in the display panel) /printstring Display send } def /DisplayFormat { % format argarray => - (formats args and displays in the display panel) /printf Display send } def /SetReaderNotifier { % [ ar0...argn /operator target] SetReaderNotifier => - /ReaderAction exch store } def /ReaderHandler{ % - => - ReaderAction null ne { %(reader action: /% %\n) %ReaderAction aload pop /Id get 2 array astore printf ReaderAction % [args operator target] /ReaderAction null store % clear ReaderAction data aload pop send % reset reader's prompt and input after the action is performed DefaultPrompt SetPrompt () SetInput % [action] } if } def classend def % ControlWindow pause % -------------------------------------------------- % The above code needs some utilities to repair deficiencies % in other NeWS classes % define a subclass of LiteText that has a some deficiencies removed /MyLiteText LiteText [] classbegin % Original LINEKILL is will not work unless textstr and % textbuf are in synchronization. /LINEKILL { 0 0 moveto TextBuf false charpath TextFill setcolor fill TextColor setcolor /Left 0 def /Right 0 def } def /reshape { % x0 y0 reshape => - /TextY exch store /TextX exch store gsave TextCanvas setcanvas TextX TextY translate % TextFont setfont BeginTextEvent EndTextEvent grestore } def classend def % MyLiteText % Define a textitem that only notifies at the end of a line % LiteItems and Litetext are very poorly designed, so % some bugfixes: % 1. the current version of textitem (re)creates its % Litetext object on every reshape. This is wrong, it should % only do it once: corrected here. % 2. if the prompt is changed, the lite text item % does not properly reshape, and caret does not move % to correct position. % Known bugs not fixed: % 1. Sizing of strings in font doesnt seem to be quite right, % so garbage gets left on line when line is erased. /LineTextItem TextItem [] classbegin % define the characters that signal end of line /IsEOL { % char => boolean [10 13 27] % \n \r \e { % char char 1 index eq {pop true exit} if } forall dup true ne {pop false} if } def /inserttext { % str/char -> - TextBegin dup type /stringtype eq { {/inserttext self send} forall } { % char dup /inserttext ItemText send IsEOL {SetTextValue NotifyUser} if } ifelse TextEnd } def /reshape { % x y w h /ItemHeight exch def /ItemWidth exch def LabelSize /LabelHeight exch def /LabelWidth exch def ItemValue ItemFont ThingSize /ObjectHeight exch def /ObjectWidth exch def AdjustItemSize /ObjectWidth ItemWidth 2 ItemBorder mul sub def ObjectLoc /Right eq ObjectLoc /Left eq or { /ObjectWidth ObjectWidth LabelWidth sub ItemGap sub def } if CalcObj&LabelXY /ItemBaseline ObjectY ItemFont fontdescent add def % need to skip over the /reshape code of normal TextItem ItemWidth ItemHeight /reshape LabeledItem supersend ItemFont setfont % this is so the text caret will be right! ItemText null eq { TextBegin /ItemText ItemCanvas ObjectX ItemBaseline ItemValue /new MyLiteText send store TextEnd } { ObjectX ItemBaseline /reshape ItemText send } ifelse } def classend def % LineTextItem pause From don@brillig.umd.edu Mon Jan 16 15:56:58 1989 Date: Mon, 16 Jan 89 15:56:58 EST To: NeWS-makers@brillig.umd.edu Subject: Re: Menu description languages From: trantor.harris-atd.com!melmac!chuck@sdcsvax.ucsd.edu (Chuck Musciano) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) In article <15453@mimsy.UUCP> don@brillig.umd.edu.UUCP (Don Hopkins) writes: >In article <550@island.uu.net> daniel@island.uu.net (Dan "yes that is my real name" Smith) writes: >[...] >>As long as I'm writing: I'd like to see menuing systems more like the >>Info reader in Gnu Emacs - there are some situations where it makes >>sense to have a menu item in two or more places; also, the users should >>be able to redefine their menus. I'm not talking about specific systems, >>just a general direction that I know I'd find more convenient to use. >> >> dan > >I did something along those lines for the UniPress's Emacs NeWS >interface (NeMACS). I wrote a menu compiler that lets you create >popup menus for NeWS by describing them in Emacs INFO nodes. I'd certianly >like to hear about other peoples' experiences with menu description languages. My tooltool software lets you build relatively complex user interfaces using English-like commands and runs under SunView. Menus are one of the interface elements it lets you manipulate. I know of at least one person who was using tooltool to build alternate sets of menus to evaluate the speed with which users could navigate the menu system. Tooltool lets you redefine and rebuild an interface in just minutes, without recompilation. Tooltool is in the public domain, and is now up to version 2.0. It is available via anonymous ftp from trantor.harris-atd.com. If you can't ftp, send me mail and I'll try to get you a copy. Chuck Musciano Advanced Technology Department Harris Corporation (407) 727-6131 ARPA: chuck@trantor.harris-atd.com From don@brillig.umd.edu Mon Jan 16 20:34:09 1989 Date: Mon, 16 Jan 89 20:34:09 EST To: NeWS-makers@brillig.umd.edu Subject: Toolplaces? From: emory!km@gatech.edu (Ken Mandelberg) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Is there a "toolplaces" type of application for NeWS? -- Ken Mandelberg | km@mathcs.emory.edu PREFERRED Emory University | {decvax,gatech}!emory!km UUCP Dept of Math and CS | km@emory.bitnet NON-DOMAIN BITNET Atlanta, GA 30322 | Phone: (404) 727-7963 From don@brillig.umd.edu Tue Jan 17 11:33:30 1989 Date: Tue, 17 Jan 89 11:33:30 EST To: NeWS-makers@brillig.umd.edu Subject: Forcing NeWS *NOT* to interpolate colors canvases From: alexis%yummy@gateway.mitre.org Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Is there a way to stop NeWS from interpolate between pixels of a color canvas? I'm trying to draw something which I'd like to look like a bunch of colored squares. If I use a color canvas, NeWS is "helpful" and spends lots of time and energy interpolating. It's all very pretty ... but it's very slow and not what I want. You end up with star-bursts and colors where you never put them. As a quick example try running the following. It's quite pretty, but first time you try it make the window SMALL (as in postage stamp size). It's most interesting big, but it tends to break due to the time it takes to compute (my sun 4 can do about a 5x5). %%%%%%%%%%%% Try This Sample Code, It's Fun And Easy %%%%%%%%%%%%% #!/usr/NeWS/bin/psh /img 16 16 24 [16 0 0 -16 0 16] {random 0.5 gt {(\000)} {(\377)} ifelse} buildimage def /win framebuffer /new DefaultWindow send def { /PaintClient { ClientCanvas setcanvas clippath pathbbox scale pop pop img imagecanvas } def } win send /reshapefromuser win send /map win send %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Please don't tell me to: a) make a canvas the same size that I'm going to display [one of the whole reasons for using NeWS is so the window can be resized.] b) draw actual squares [that's what I do now -- it works, but for large images it's even slower than the above.] c) go editing NeWS or any other fool thing. I just want a way to turn off this interpolation "feature" occasionally. Alexis P. Wieland MITRE Corporation 7525 Colshire Dr. McLean, VA 22102 (703) 883-7476 alexis%yummy@gateway.mitre.org From don@brillig.umd.edu Wed Jan 18 15:54:04 1989 Date: Wed, 18 Jan 89 15:54:04 EST To: NeWS-makers@brillig.umd.edu Subject: Making X10.4 applications work under NeWS 1.0 - Do you know how ? From: jpl-devvax!rich@elroy.jpl.nasa.gov (Richard Pettit) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) If you have successfully made a number of X10.4 applications work under NeWS 1.0, could you please send me some e-mail yielding inspiration. I could really appreciate it a lot. Thank you. Rich -- rich@jpl-devvax.Jpl.Nasa.Gov From don@brillig.umd.edu Fri Jan 20 16:19:49 1989 Date: Fri, 20 Jan 89 16:19:49 EST To: NeWS-makers@brillig.umd.edu Subject: testing cps message queue From: "bryan_kramer.TORHO"@Xerox.COM Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) I have C plus CPS code that would really benefit from knowing when there is no input waiting on PostScriptInput (ie. all the current cps commands from the NeWS server have been handled). One application involves holding a repaint request until all other current requests (user input) have been handled. Could someone please tell me how to do this? I am using a sun4-110 with OS4.01? From my search of the manuals I gather that using SYSTEM V reads might solve the problem although I haven't really studied the details. Of course, the CPS calls use regular io. Any light that can be shed on this topic would be very much appreciated. Thanks Bryan Kramer Xerox Canada Inc. bryan_kramer.torho@xerox.com (416) 733-6377 From don@brillig.umd.edu Sat Jan 21 01:03:17 1989 Date: Sat, 21 Jan 89 01:03:17 EST To: NeWS-makers@brillig.umd.edu Subject: NeWS interface to Logo? From: Don Hopkins Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Has anybody made a NeWS interface to the Logo interpreter that was posted to comp.sources.unix a while ago? It would be really neat to extend Logo turtle graphics to support the entire PostScript stencil/paint imaging model! You could implement sprites and turtles as lightweight NeWS processes that pushed canvases around on the screen! -Don From don@brillig.umd.edu Mon Jan 23 15:02:59 1989 Date: Mon, 23 Jan 89 15:02:59 EST To: NeWS-makers@brillig.umd.edu Subject: Re: testing cps message queue From: frame!gergle!greg@Sun.COM Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) >I have C plus CPS code that would really benefit from knowing when there is >no input waiting on PostScriptInput (ie. all the current cps commands from >the NeWS server have been handled). One application involves holding a >repaint request until all other current requests (user input) have been >handled. >Could someone please tell me how to do this? I am using a sun4-110 with >OS4.01? Here is a code frag which works for me. I have never tried running under OS4.0. Please let me know if it works. block would be false in your case. EVENTL is the minimum event length you expect to read. -greg. if(block) avail = EVENTL; else { avail = psio_availinputbytes(PostScriptInput); if(avail < EVENTL) { ioctl(psio_fileno(PostScriptInput),FIONREAD,&bytes); avail += bytes; } } while(avail >= EVENTL) { if(psio_error(PostScriptInput)) { fprintf(stderr,"PostScriptInput error\n"); exit(1); } c = psio_getc(PostScriptInput); /* handling of input, CPS typed reads */ /* handling of input, CPS typed reads */ /* handling of input, CPS typed reads */ /* handling of input, CPS typed reads */ avail = psio_availinputbytes(PostScriptInput); } From don@brillig.umd.edu Mon Jan 23 15:29:07 1989 Date: Mon, 23 Jan 89 15:29:07 EST To: NeWS-makers@brillig.umd.edu Subject: Meta keys under NeWS From: b.gp.cs.cmu.edu!gleicher@pt.cs.cmu.edu (Michael Gleicher) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Can someone please tell me how to get the meta keys on my keyboard to act like meta keys (set the high bit of the character so emacs can understand it). I am running NeWS on a Sun 3/60 and on an SGI Personal Iris. I am using the Grasshopper group psterm on the sun and wsh on the Iris. Thanks for the help, Mike -- Michael Lee Gleicher gleicher@cs.cmu.edu (-: Of course I believe Carnegie Mellon University 5610 Elmer St. Apt 10 (-: in miracles, Pittsburgh, PA 15232 (-: its my job. -- From don@brillig.umd.edu Mon Jan 23 15:29:53 1989 Date: Mon, 23 Jan 89 15:29:53 EST To: NeWS-makers@brillig.umd.edu Subject: keyboard bugs in NeWS From: mcvax!enea!naggum!isncr!m2cs!frode@uunet.uu.net (Frode Odegard) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) From time to time NeWS seems to lapse into torturing me by making the SHIFT and [more seldom] CONTROL keys go dead. I press 'em, they don't work. Since I now do all my development under NeWS, this is slowly driving me insane. I've got a Sun-3/60C.....can anyone help ? - Frode -- | Frode L. Odegard |"The world is coming to an end! Repent and| | Modula-2 CASE Systems |rm /bin/cc" | | NORWAY (EUROPE) | | | Email: frode@m2cs.uu.no | | From don@brillig.umd.edu Mon Jan 23 17:37:19 1989 Date: Mon, 23 Jan 89 17:37:19 EST To: NeWS-makers@brillig.umd.edu Subject: Example of use of PlaneWindow From: dennis!dennis@boulder.colorado.edu Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) I have had a number of requests to show an example using the PlaneWindow that I posted earlier. The following code creates a planewindow, maps a bit map image to it and allow you to pan/scroll over that image. This example should make it clearer that the way that pan/scroll is achieved is by changing the translation/scale of the ClientCanvas and rewriting the image to the canvas after the transformation. This has the advantage that almost any existing application can easily be converted to using the PlaneWindow if it currently uses LiteWindow. It has the drawback (among many) that smooth scrolling is difficult. If anyone can come up with a modification or replacement to PlaneWindow that would make smooth scrolling possible, I would be glad to use it. p.s. I notice that the comment about /CenterPlane is incorrect. CenterPlane places the center of the plane canvas at the origin (not center) of the view canvas. p.p.s. I talk about the Plane canvas and the View canvas, but remember, both are the same canvas: the ClientCanvas. The effect is achieved by changing the transformation matrix associated with the ClientCanvas. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% (msgscroll.ps) run % Test out plane window % This test class operates as follows: % 1.The user creates the window % 2. The user gives a bitmap to the window using SetBackGround % 3. the user pans/scrolls over the image using the scroll bars % Note that if dithering is invoked (by zoom in/out), % and the image is complicated, then the refresh time will be very slow. /testclass PlaneWindow [] classbegin /Background null def /ZoomFactor 2 def /SetBackGround { % imagefilename => - (load file into /BackGround) readcanvas pause % get actual image /BackGround exch def % save the image canvas } def /PaintClient { /PaintClient super send PaintBackGround } def /PaintBackGround { % - => - gsave ClientCanvas setcanvas minX neg minY neg translate PlaneWidth PlaneHeight scale BackGround imagecanvas pause grestore } def /Enlarge { ScaleX ZoomFactor mul ScaleY ZoomFactor mul SetPlaneScale } def /Reduce { ScaleX ZoomFactor div ScaleY ZoomFactor div SetPlaneScale } def /Normal { 1.0 1.0 SetPlaneScale } def /ClientMenu [ (Center) {/CenterPlane testwin send} (Zoom Normal) {/Normal testwin send} (Zoom Out) {/Reduce testwin send} (Zoom In) {/Enlarge testwin send} ] /new DefaultMenu send store classend def /testwin framebuffer /new testclass send def % set location and shape of the window % Make it a 1192/2 by 900/2 window located at location (400,400) 400 400 1192 2 div 900 2 div /reshape testwin send % Make the plane window with x coordinates ranging over 0 -> 1192 % and y coordinates ranging over 0 -> 900 % This is same as framebuffer size, which means that no dithering occurs, % and so screen rewrite speed is fast. % Origin of the plane window will be at the origin of the view. 0 0 1152 900 /SetPlaneSize testwin send % Fill in the path for some image in the following string (/piper/staff/dennis/.background) /SetBackGround testwin send /map testwin send From don@brillig.umd.edu Mon Jan 23 17:37:46 1989 Date: Mon, 23 Jan 89 17:37:46 EST To: NeWS-makers@brillig.umd.edu Subject: an example using ControlWindow From: dennis!dennis@boulder.colorado.edu Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Below is a simpel example using the ControlWindow class I posted earlier. I had intended this code to demonstrate that fonts were scaled by plane window, but apparently I do not understand font scaling well enough. In any case, the messages stay the same size. If there are any font experts out there, perhaps they can tell me what I am doing wrong. The scaling occurs in PlaneWindow.SetPlaneScale. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % load the PlaneWindow and ControlWindow definitions (msgscroll.ps) run % Test out control window % This test class operates as follows: % 1. the user clicks left button on the reader window % 2. the user types a string into the reader window % 3. when the user types a , the message in the reader % window is displayed at the origin of the plane canvas. % 4. the scroll bars may be moved to pan/scroll over % the plane window. The visible effect is to move % the text with respect to the view on the window. % 5. A menu is provided to do the following things: % Center - put origin of the plane window at center % of the client canvas % Zoom - do a number of zoom actions: % Normal - reset the window to normal size % Reduce - zoom out by a factor of two % Enlarge - zoom in by a factor of two /testclass ControlWindow dictbegin /oldmessage null def dictend classbegin /DefaultPrompt (new message:) def /ZoomFactor 8 def % When reader is constructed, set the notifier /CreateFrameControls { /CreateFrameControls super send % save old message /oldmessage () store % arm reader notifier [/SetMessage self] SetReaderNotifier } def /PaintClient { /PaintClient super send PaintMessage } def /PaintMessage { gsave ClientCanvas setcanvas 0 0 moveto oldmessage show grestore } def % When reader message is changed, display old message, % erase from client canvas, and display new msg at (0,0) /SetMessage { % - => - % display old message (old message: %) [oldmessage] DisplayFormat % save new message as old message /oldmessage GetInput store % erase old message by erasing whole client canvas gsave ClientCanvas setcanvas erasepage grestore % write new (now old) message at origin of client canvas PaintMessage % re-arm reader notifier [/SetMessage self] SetReaderNotifier } def /Enlarge { ScaleX ZoomFactor mul ScaleY ZoomFactor mul SetPlaneScale } def /Reduce { ScaleX ZoomFactor div ScaleY ZoomFactor div SetPlaneScale } def /Normal { 1.0 1.0 SetPlaneScale } def /ClientMenu [ (Center) {/CenterPlane testwin send} (Normal) {/Normal testwin send} (Reduce) {/Reduce testwin send} (Enlarge) {/Enlarge testwin send} ] /new DefaultMenu send store classend def /testwin framebuffer /new testclass send def % set location and shape of the window % Make it a 500 by 500 window located at location (400,400) 400 400 500 500 /reshape testwin send % Make the plane window with x coordinates ranging over -1000 -> 1000 % and y coordinates ranging over -500 -> 500 % Origin of the plane window will be at the origin of the view. -1000 -500 1000 500 /SetPlaneSize testwin send /map testwin send From don@brillig.umd.edu Mon Jan 23 18:51:42 1989 Date: Mon, 23 Jan 89 18:51:42 EST To: NeWS-makers@brillig.umd.edu Subject: keyboard bugs in NeWS From: Don Hopkins Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Try bopping on the L1 key a few times. That usually resets the keyboard when it gets confused about the state of the shift keys. (Like when you're typing real fast and it chirps and resets.) -Don From don@brillig.umd.edu Wed Jan 25 19:29:35 1989 Date: Wed, 25 Jan 89 19:29:35 EST To: NeWS-makers@brillig.umd.edu Subject: Variable brightness/shape cursors in NeWS From: oliveb!pyramid!leadsv!esl!tlp@ames.arc.nasa.gov (Lincoln Perry) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) We are currently doing a project using NeWS and need to have a desktop cursor which can have variable shape and color/brightness. The NeWS 1.1 manual, in the section on cursor fonts (p. 167 I think) states that cursors can be arbitrary Postscript procedures with their own shape, color and transformation, but that NeWS does not guarantee that the procedure will be executed on each mouse movement. This seems to be just what we need, but I can't find any other references to it. The rest of the chapter only talks about bitmap cursor fonts. If anyone has installed their own desktop cursor, with user-specifed shape and color, we'd appeciate hearing how its done. I assume that the comment about not guaranteeing that the procedure is re-executed on every mouse movement means that the procedure is converted to a bitmap and cached for reuse by NeWS. This is fine for our application. We just need to a way to alter the color and shape. Thanks in advance. Link Perry ESL tlp@esl.com From don@brillig.umd.edu Wed Jan 25 19:31:06 1989 Date: Wed, 25 Jan 89 19:31:06 EST To: NeWS-makers@brillig.umd.edu Subject: the final word on "Why non-rectangular canvases?" From: tinman.cis.ohio-state.edu!bob@tut.cis.ohio-state.edu (Bob Sutterfield) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) I loaded /usr/NeWS/smi/mona-hires.im8 as the background on this 4/110C. Then I invoked eye.ps by Mark Fanty/Jeremy Huxtable, and placed the eyes, appropriately ovaled, in the appropriate spots. I haven't laughed so hard in a very, very long time. It's like bad Monty Python. I always knew there was a good reason for non- rectangular canvases! Now, to really deface some art, we need a moustache.ps ... From don@brillig.umd.edu Wed Jan 25 19:31:18 1989 Date: Wed, 25 Jan 89 19:31:18 EST To: NeWS-makers@brillig.umd.edu Subject: Is "transform" in NeWS 1.1 OK ? From: munnari!otc!metro!ditsyda!natmlab!ronb@uunet.uu.net (Ron Baxter) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) The following session with psh puzzles me and I wonder what I am missing. executive Welcome to NeWS Version 1.1 matrix currentmatrix pstack [1 0 0 1 0 0] clear 100 200 transform pstack 100 700 clear -20 -40 transform pstack -20 940 clear 50 70 itransform pstack 50 830 Since the CTM is an identity matrix I would have expected transform, itransform, etc to make no change to x and y. The LaserWriter behaves as I expected, so is this a NeWS 1.1 funny? -- ____ ____ Ron Baxter, CSIRO Div Maths & Stats, | } /\ |\ | | } PO Box 218, Lindfield, NSW, Australia. |-< { }|\\| |-< Phone: +61 2 467 6059 | \ \/ | \| _|__} Email: ronb@natmlab.oz.au D From don@brillig.umd.edu Wed Jan 25 20:12:23 1989 Date: Wed, 25 Jan 89 20:12:23 EST To: NeWS-makers@brillig.umd.edu Subject: Variable brightness/shape cursors in NeWS From: Don Hopkins Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Here's some code that tests out user definable fonts as cursors. The cursor machinery seems to use the font cache, which only supports bitmap images, not color. (I leave it up to someone with a color display to test that theory.) Note that the "hot spot" of the cursor is the character's origin. Unfortunatly you can't change the origin of the characters in a font by giving a predefined bitmap font and a translation matrix to makefont (that's a bug), so you have to make your own user defined font. (I had wanted to use a Times-Roman "?", with the dot as the hot spot, but the hot spot was always the lower left corner no matter how much I translated with makefont. I suppose I could just make my own question mark outline in a user defined font. That would rotate better anyway.) It would be nice if NeWS had an operator, some variaton of setcanvascursor, to move the cursor hot spot around independant of the character origin. -Don %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% systemdict begin /newfont 50 dict def newfont begin /FontType 3 def /FontMatrix [1 0 0 1 0 0] def /FontBBox [-1 -1 1 1] def /BuildChar { 10 dict begin 2 0 -1 -1 1 1 setcachedevice /char exch 256 div 360 mul def /font exch def newpath 0 0 char 17 mul cos dup mul 0 360 arc closepath 0 0 char 32 mul cos dup mul 0 360 arc closepath 0 0 char 21 mul sin dup mul 0 360 arc closepath 0 0 char 5 mul sin dup mul 0 360 arc closepath 0 0 char 8 mul sin dup mul 0 360 arc closepath stroke end } def end % newfont /Drip newfont definefont pop end % systemdict /f /Drip findfont 30 scalefont def 5 { 0 5 255 { f exch dup setcanvascursor .002 sleep } for } repeat From don@brillig.umd.edu Wed Jan 25 20:12:27 1989 Date: Wed, 25 Jan 89 20:12:27 EST To: NeWS-makers@brillig.umd.edu Subject: Is "transform" in NeWS 1.1 OK ? From: Don Hopkins Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) The reason transform is giving unexpected results is that it takes into account the height of the canvas you're on, flipping the y-coordinate to pixrect "device" coordinates. The pixrect origin is the upper left corner, while the default NeWS origin is the lower left. This is a pain, and probably the reason why the matrix args to transform, scale, etc, are not implemented. A transformation matrix for one canvas will not work the same on a another canvas of a different height, because there is this implicit transformation and y scale flip. I've recently run into a bug with setting the /XLocation and /YLocation fields of events. When I am on a canvas other than the frame buffer, and I set them to some value, then immediatly read them back, THEY'RE DIFFERENT!! To correctly set the event coordinates to a position relative to my canvas, I have to setcanvas to the frame buffer, manually subtract my canvas's offset from the lower left corner of the framebuffer from my coordinates, and THEN def the /XLocation and /YLocation fields. I think my problem is also related to the pixrect origin -vs- PostScript origin problem. Pixrects are *EVIL*. -Don From don@brillig.umd.edu Fri Jan 27 11:25:43 1989 Date: Fri, 27 Jan 89 11:25:43 EST To: NeWS-makers@brillig.umd.edu Subject: A silly animation From: spectral!sjs@bellcore.com (Stan Switzer) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) On a tip from a well-known NeWS jockey, I made a simple but quite interesting change to my "bouncing world demo." After firing this off, play around with some of the menu options. Of particular interest are the "Bump" and "Boing" controls. If you are using non-retained canvases (color) it'll work better when it's over a simple background (the root screen, for instance). Be sure to check out the icon too. Stan Switzer sjs@ctt.bellcore.com "However glorous the mind's conception, alien matter will in time intrude. Whenever we achieve some good on our earth, the better things are labeled frauds and fantasies. The ecstasies that launched us on this life congeal in the muddled business of living." -- Goethe ---------------- #!/usr/NeWS/bin/psh % % wbounce: Drop everything % % Copyright (C) 1988, 1989 by Stan Switzer. All rights reserved. % This program is provided for unrestricted use, provided that this % copyright message is preserved. There is no warranty, and no author % or distributer accepts responsibility for any damage caused by this % program. % % Credit where credit's due: % Bump and Boing concept suggested by Don Hopkins. % various useful GP utilities: /outside { % x lowx highx => false -or- closest true dup 3 index lt { 3 1 roll pop pop true } { pop dup 2 index gt { exch pop true } { pop pop false } ifelse } ifelse } def /decrease { % n decr => n' -- decrease n toward zero, not beyond exch dup 0 lt { add dup 0 gt { pop 0 } if } { exch sub dup 0 lt { pop 0 } if } ifelse } def % Sleazy way to modify enclosing window variables /W+ { % /name incr => ThisWindow begin exch dup load 3 -1 roll add store end } def /W* { % /name factor => ThisWindow begin exch dup load 3 -1 roll mul store end } def /W= { % /name val => ThisWindow begin store end } def /BouncingThing DefaultWindow dictbegin /ThingWidth 32 def /ThingHeight 32 def /SqueezeX 0 def /SqueezeY 0 def /UnSqueeze 3 def /Bump 0 def /Boing 0 def /Bcount 0 def /MovingAllowed? true def /Xcount 0 def /Ycount 0 def /MaxCount 12 def /X 0 def /Y 0 def /dX 16 def /dY 0 def /d2X 0 def /d2Y -2 def /dT .10 60 div def /dragX 0 def /dragY .25 def /ClientFillColor 1 def /ThingColor 0 def /FrameLabel (Bouncing Thing) def /CanW 0 def /CanH 0 def /AnimateProcess null def /PaintClient { ClientFillColor fillcanvas show-thing } def /wheredrawn null def dictend classbegin /new { /new super send begin /wheredrawn 4 array store /ClientMenu [ (Bigger) { /ThingWidth 4 W+ /ThingHeight 4 W+ } (Smaller) { /ThingWidth -4 W+ /ThingHeight -4 W+ } (Flatter) { /ThingWidth 4 W+ } (Taller) { /ThingHeight 4 W+ } (Faster) { /dT 1 1.5 div W* } (Slower) { /dT 1.5 W* } (More Gravity) { /d2Y -1 W+ } (Less Gravity) { /d2Y 1 W+ } (More Drag) { /dragY .05 W+ } (Less Drag) { /dragY -.05 W+ } (More Bump) { /Bump 2 W+ } (Less Bump) { /Bump -2 W+ } (More Boing) { /Boing 1 W+ } (Less Boing) { /Boing -1 W+ } (Zap!) { /destroy ThisWindow send } (Zap!) { /destroy ThisWindow send } ] /new DefaultMenu send dup begin /LayoutStyle [ 8 2 ] def end def currentdict end } def /flipiconic { /flipiconic super send } def /start { true animate } def /stop { false animate } def /animate { { AnimateProcess null eq { /AnimateProcess { animateproc } fork store } { AnimateProcess continueprocess } ifelse } { AnimateProcess null ne { AnimateProcess suspendprocess } if } ifelse } def /reshape { % x y w h => - /reshape super send gsave ClientCanvas setcanvas clippath pathbbox 4 -2 roll pop pop % w h /CanH exch store /CanW exch store grestore } def /erase-thing { % X Y Width Heigth => - rectpath ClientFillColor setshade fill } def /compute-thing nullproc def % X Y Width Heigth => X Y Width Height /draw-thing { % X Y Width Height => - % intended to be overriden rectpath fill } def /show-thing { % - => - X cvi Y cvi Width cvi Height cvi /compute-thing self send wheredrawn aload pop /erase-thing self send ThingColor setshade 4 copy wheredrawn astore pop /draw-thing self send } def /animate-step { % - => - % flags /DoBump false def /DoBoing false def % acceleration /dX dX d2X add store /dY dY d2Y add store % velocity /X X dX add store /Y Y dY add store % "friction" /dX dX dragX decrease store /dY dY dragY decrease store % position (bounce off of walls) 123 X 0 CanW Width sub outside { % X rebound /X exch store /dX dX neg store Xcount 1 add dup /Xcount exch store MaxCount gt { /dX dX kickX add X 0 ne { neg } if store } if /SqueezeX ThingWidth .5 mul store X 0 ne { /X X SqueezeX add store } if Bump 0 ne { /DoBump true def } if } { % no rebound /Xcount 0 store /SqueezeX SqueezeX UnSqueeze sub dup 0 lt { pop 0 } if store } ifelse Y 0 CanH Height sub outside { % Y rebound /Y exch store /dY dY neg store Ycount 1 add dup /Ycount exch store MaxCount gt { /dY dY kickY add Y 0 ne { neg } if store } if /SqueezeY ThingHeight .5 mul store Y 0 ne { /Y Y SqueezeY add store } if Boing 0 ne { /DoBoing true def } if } { % no rebound /Ycount 0 store /SqueezeY SqueezeY UnSqueeze sub dup 0 lt { pop 0 } if store } ifelse % draw it ClientCanvas setcanvas show-thing MovingAllowed? { DoBump { Iconic? { IconX IconY } { FrameX FrameY } ifelse Bump X 0 eq { neg } if 3 -1 roll add exch move } if DoBoing { /BoingFac Boing Y 0 eq { neg } if dY 2 sub dup 0 lt { pop 0 } if dup mul .01 mul mul cvi def Iconic? { IconX IconY } { FrameX FrameY } ifelse BoingFac add move /Bcount Bcount BoingFac add def } { Bcount 0 ne { Iconic? { IconX IconY } { FrameX FrameY } ifelse Bcount 0 lt 1 -1 ifelse add move /Bcount Bcount dup 0 gt -1 1 ifelse add def } if } ifelse } if 123 ne { ZZZ } if } def /slide { % avoid problem with bounce and boing { /MovingAllowed? false store GetCanvas setcanvas InteractionLock { interactivemove } monitor currentcanvas ParentCanvas setcanvas getcanvaslocation /move self send /MovingAllowed? true store } fork pop } def /kickX { CanW Width sub d2X mul abs dup add sqrt } def /kickY { CanH Height sub d2Y mul abs dup add sqrt } def /Width { ThingWidth SqueezeX sub } def /Height { ThingHeight SqueezeY sub } def /animateproc { % - => - % initial conditions /X 0 store /Y CanH Height sub store X Y ThingWidth ThingHeight wheredrawn astore pop % create a timer event event interest /TimerInterest createevent store TimerInterest begin /Name /DelayOver def currentdict end dup expressinterest % create a timer event and start it off createevent copy begin /TimeStamp currenttime dT add def currentdict end sendevent { % loop awaitevent begin /TimeStamp % TimeStamp % Makes up for lost time currenttime % Accepts its loss dT add def currentdict end sendevent % and do a step animate-step } loop } def classend def /BouncingWorld BouncingThing dictbegin /ClientFillColor 0 def /ThingColor ColorDisplay? { 0 1 0 rgbcolor } { 1 } ifelse def /FrameLabel (Bouncing World) def /NImages 30 def /ImageNo 0 def /ImageVec null def dictend classbegin /new { /new super send begin /ImageVec [ 1 1 NImages { pop null } for ] store currentdict end } def /IconImage /globe def /IconPath { scale .5 .5 .5 0 360 arc } def /LoadImage { % nbr => image -- side-effect, saves image in vec ImageVec exch dup 1 add 10 string cvs (/usr/NeWS/smi/globes/globe) exch append (.im1) append readcanvas dup 4 1 roll put } def /Image { % - => image ImageNo dup ImageVec exch get % nbr image-or-null dup null eq { pop dup LoadImage } if % nbr image exch 1 add dup NImages ge { pop 0 } if /ImageNo exch store % image } def /draw-thing { % X Y W H => - gsave 4 2 roll translate scale false Image imagemaskcanvas grestore } def classend def % Following is same w/ double-buffering. /FasterBouncingWorld BouncingWorld dictbegin /FrameLabel (Double-Buffered Bouncing World) def /TmpCan null def dictend classbegin /new { /new super send begin /TmpCan framebuffer newcanvas store TmpCan /Transparent false put TmpCan /Retained true put currentdict end } def /compute-thing { % X Y W H => X Y W H -- precompute the image gsave framebuffer setcanvas 0 0 moveto 2 copy rect TmpCan reshapecanvas TmpCan setcanvas ClientFillColor fillcanvas ThingColor setshade 0 0 moveto 2 copy scale false Image imagemaskcanvas grestore } def /draw-thing { % X Y W H => gsave 4 2 roll translate scale TmpCan imagecanvas grestore } def classend def % Tilted bouncing world /TiltedBouncingWorld BouncingWorld dictbegin /FrameLabel (Tilted Bouncing World) def dictend classbegin % draw it tilted /draw-thing { % X Y W H => - gsave 4 2 roll translate scale .5 .5 translate -22.5 rotate -.5 -.5 translate true Image imagemaskcanvas grestore } def % eliminate screen sh*t /erase-thing { % X Y Width Heigth => - 4 add 4 1 roll 4 add 4 1 roll 2 sub 4 1 roll 2 sub 4 1 roll rectpath ClientFillColor setshade fill } def classend def /win framebuffer /new FasterBouncingWorld send def /reshapefromuser win send /map win send /start win send % win begin AnimateProcess waitprocess % to wait, if we want to use == for dbg From don@brillig.umd.edu Fri Jan 27 11:26:19 1989 Date: Fri, 27 Jan 89 11:26:19 EST To: NeWS-makers@brillig.umd.edu Subject: Wallpaper again (fixed for 1.1) From: pterodactyl.cis.ohio-state.edu!zwicky@tut.cis.ohio-state.edu (Elizabeth D. Zwicky) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Now that we have release NeWS 1.1, I have fixed wallpaper to avoid the zombie window problem (I would have fixed it before, had I been able to reproduce it before.) Here is the corrected version. For those of you who have not seen wallpaper before, it colors in a window, point by point, picking the color for each point by calculating the value for that x and y of a formula you give it. It produces unexpectedly beautiful designs, some of which look remarkably irregular, and the effect is a little hypnotic - good for those brain-dead days, or impressing random visitors. Especially in color. ------- Cut Here -------------------------------------------- #!/usr/NeWS/bin/psh % Send comments to Elizabeth Zwicky (zwicky@cis.ohio-state.edu) % Set up LiteItem if nothing else has systemdict /Item known not { (NeWS/liteitem.ps) run } if % If I redefine something, I want it redefined! false setautobind % Predefinitions /height null def /width null def /Red 1 0 0 rgbcolor def /Blue 0 0 1 rgbcolor def /Green .2 1 .4 rgbcolor def /Yellow 1 1 0 rgbcolor def /Purple .7 0 1 rgbcolor def /Orange 1 .5 0 rgbcolor def /colors [Red Blue Green Yellow Purple Orange] def /startx{1} def /starty{1} def /div*{ dup 0 eq {pop pop 0}{div}ifelse}def /magnify 1 def /x{realx magnify div}def /y{realy magnify div} def /detail 1 def /formula{x cos y mul y sin x mul add} def /function{ formula detail mul}def /first true def /helpwindow null def % Draw a dot; works with linecap 1 or 2 on NeWS, but only with 1 in standard /dot{ 0 0 rlineto stroke pause} def % Draw a row of dots /line{ width{ gsave colorcanvas {colors function cvi 6 mod abs get setcolor dot} {function cvi 2 mod abs 1 eq {dot} if} ifelse grestore 1 0 rmoveto /realx realx 1 add def }repeat }def % Draw a windowfull of rows /square{ width 0 rmoveto height{ width neg 1 rmoveto /realx startx def /realy realy 1 add def line }repeat }def % Create window to draw in /paperwindow framebuffer /new DefaultWindow send def {% Set up main window /PaintClient{ % Clear, reset size, position, color, current point, % and redraw erasepage clipcanvaspath pathbbox /height exch store /width exch store 0 setgray 1 1 moveto /realx startx def /realy starty def square } def /FrameLabel (Wallpaper) def /destroy{ % Kill subwindows /destroy formulawindow send first {/destroy helpwindow send} if % Will die even during redraw PaintProcess null ne {PaintProcess killprocessgroup} if FrameEventMgr null ne {FrameEventMgr killprocessgroup} if } def /ClientMenu [ (Zoom In) {/magnify magnify 2 mul store /paint paperwindow send} (Zoom Out) {/magnify magnify 2 div store /paint paperwindow send} (Add Detail) {/detail detail 2 mul store /paint paperwindow send} (Remove Detail) {/detail detail 2 div store /paint paperwindow send} (Move Bottom Left Corner) { /xhair /xhair_m paperwindow /ClientCanvas get setstandardcursor getclick /starty exch starty add store /startx exch startx add store /ptr /ptr_m paperwindow /ClientCanvas get setstandardcursor /paint paperwindow send } (Help) {first {help} if } ] /new DefaultMenu send def }paperwindow send /help {% Put up help file in window % Make help window /helpwindow framebuffer /new DefaultWindow send store (Times-Roman) findfont 14 scalefont setfont 0 0 310 460 /reshape helpwindow send framebuffer setcanvas paperwindow /FrameCanvas get getcanvaslocation 570 sub /move helpwindow send helpwindow /ClientCanvas get setcanvas { /PaintClient{ clippath pathbbox /place exch def pop pop pop helptext { /place place 14 sub def 5 place moveto show } forall } def /destroy { % Gentle destroy; does not take other things with it helpwindow /IconCanvas get /Mapped false put helpwindow /FrameCanvas get /Mapped false put helpwindow /ClientCanvas get /Mapped false put helpwindow /FrameEventMgr get killprocess /first true store }def } helpwindow send /first false store /map helpwindow send } def % Actually put main window up /reshapefromuser paperwindow send /map paperwindow send % Create, position and size formulawindow /formulawindow framebuffer /new DefaultWindow send def 100 100 300 110 /reshape formulawindow send paperwindow /FrameCanvas get getcanvaslocation 110 sub /move formulawindow send % Don't want the string every time it's changed; gonotify really % does the notification /formulanotify {} def /gonotify{/formula itemdict /formulaitem get /ItemValue get dup length string copy cvx store /paint paperwindow send} def /itemdict dictbegin /formulaitem (Formula:)(x cos y mul y sin x mul add) /Right /formulanotify formulawindow /ClientCanvas get 1500 10 %Plenty long for real complex formulas! /new TextItem send dup 0 0 /move 3 index send pop def /goitem (Press When Formula Is Correct) /gonotify formulawindow /ClientCanvas get 10 40 /new ButtonItem send dup 0 30 /move 3 index send pop def dictend def itemdict paintitems itemdict forkitems {/PaintClient {itemdict paintitems} def /destroy{paperwindow /PaintProcess get null ne {paperwindow /PaintProcess get killprocessgroup} if paperwindow /FrameEventMgr get null ne {paperwindow /FrameEventMgr get killprocessgroup} if} def } formulawindow send /map formulawindow send /helptext[ ("Wallpaper" was inspired by one of Martin) (Gardner's Mathematical Recreations columns) (in the magazine "Scientific American". It) (colors in a coordinate plane by) (calculating the value of formula in x and) (y for the x and y values of that point,) (and picking a color based on that value.) (On a color display it uses 6 colors, which) (are meant to be red, blue, yellow, purple,) (green and orange. On a monochrome screen) (it uses only black and white.) ( ) (The formula is specified in the lower) (window in PostScript. A special function,) (div*, is available; it is exactly like) ("div" except that if you attempt to divide) (by zero it returns zero instead of an) (error.) ( ) (The "Zoom In" and "Zoom Out" menu options) (change the magnification of the plane by) (factors of 2; it starts out at device) (resolution. Similarly, the "Add Detail") (and "Remove Detail" menu options change a) (multiplier that is applied to the result) (of the formula by factors of 2. The) (multiplier starts at 1. "Move Bottom Left) (Corner" places the bottom left corner at) (the point on the plane indicated by your) (next click (it starts at 0,0).) ]def From don@brillig.umd.edu Fri Jan 27 11:29:36 1989 Date: Fri, 27 Jan 89 11:29:36 EST To: NeWS-makers@brillig.umd.edu Subject: No class whatsoever From: spectral!sjs@bellcore.com (Stan Switzer) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) This is another silly little program to amuse you and annoy your friends. Though it serves no useful purpose (my specialty!), it does illustrate how to play with canvases, events, interests, etc. directly -- it does not use any of the higher-level NeWS mechanisms like classes or event managers. The idea comes from a program by Chris Warth (ihnp4!ulysses!csw). As always, enjoy! Stan Switzer sjs@ctt.bellcore.com "Work is the curse of the drinking class." ------------------- #!/bin/sh # # Catch me if you can! # # Copyright (C) 1989 by Stan Switzer. All rights reserved. # This program is provided for unrestricted use, provided that this # copyright message is preserved. There is no warranty, and no author # or distributer accepts responsibility for any damage caused by this # program. # # Stan Switzer sjs@ctt.bellcore.com # # This program is an elaboration on a theme by # Chris Warth (ihnp4!ulysses!csw) # # usage: # catchme [options] [message] # options: # @system run it on someone else's system # @@system a sneakier way to do the same SYS= CMD=psh N=/usr/NeWS/bin STR= for ARG do case "$ARG" in @@* ) SYS=`expr "$ARG" : '..\(.*\)'` CMD="rsh $SYS sh -c 'NEWSSERVER=\"`setnewshost $SYS`\" $N/psh'";; @* ) SYS=`expr "$ARG" : '.\(.*\)'`;; * ) STR="$STR $ARG";; esac done if test -z "$NEWSHOME"; then NEWSHOME=/usr/NeWS; fi case $PATH in */NeWS/bin ) ;; * ) PATH=$PATH:$NEWSHOME/bin; export PATH;; esac if test -n "$SYS" then if NEWSSERVER=`setnewshost $SYS` then export NEWSSERVER else exit 1 fi fi if test -z "$STR"; then STR=" Catch Me!"; fi { echo "/Str ($STR ) def"; cat < Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Date: Fri, 27 Jan 89 18:21:00 EST From: mcvax!enea!peabd!ptve@uunet.uu.net (Peter Verst{ndig) I want to do changes to NeWS-fonts within a NeWS-session (using fontedit, bldfamily, dumpfont). My question is : how can I make the font change WITHOUT logging out ?? As it is now, the font doesn't seem to change until I get out of NeWS and back again. I think 'findfilefont' should do the trick for you. It takes the name of a font file, reads it in, and returns the font. (Or something like that. I don't have the manual on hand. It's used with 'enumeratefontdicts' in init.ps.) -Don From don@brillig.umd.edu Fri Jan 27 19:24:54 1989 Date: Fri, 27 Jan 89 19:24:54 EST To: NeWS-makers@brillig.umd.edu Subject: NeWS on VMS... From: siegel@hc.dspo.gov (josh Siegel) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Has anybody ported NeWS to VMS yet? How about to a Microvax 2000 running VMS? Did you change NeWS to use Decnet? thanks --Josh Siegel -- Josh Siegel (siegel@hc.dspo.gov) I like using a C-47A "puff dragon" to go shooting beer cans with. From don@brillig.umd.edu Sat Jan 28 10:55:06 1989 Date: Sat, 28 Jan 89 10:55:06 EST To: NeWS-makers@brillig.umd.edu Subject: nesting windows doesn't work From: mcvax!enea!naggum!isncr!m2cs!frode@uunet.uu.net (Frode Odegard) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Oh no! It turns out that windows don't nest properly. I tried the following code: /win {} makewindowfromuser def /can win /ClientCanvas get def /win2 can /new LiteWindow send def 20 20 100 100 /reshape win2 send /map win2 send but win2 doesn't appear. Does anyone have a subclass of LiteWindow or anything that will fix this?? - Frode -- | Frode L. Odegard |"The world is coming to an end! Repent and| | Modula-2 CASE Systems |rm /bin/cc" | | NORWAY (EUROPE) | | | Email: frode@m2cs.uu.no | | From don@brillig.umd.edu Sat Jan 28 23:37:39 1989 Date: Sat, 28 Jan 89 23:37:39 EST To: NeWS-makers@brillig.umd.edu Subject: Re: nesting windows doesn't work From: siegel@hc.dspo.gov (josh Siegel) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) In article <126@m2cs.uu.no> frode@m2cs.uu.no (Frode Odegard) writes: >Oh no! It turns out that windows don't nest properly. > I tried the following code: > >/win {} makewindowfromuser def >/can win /ClientCanvas get def >/win2 can /new LiteWindow send def >20 20 100 100 /reshape win2 send >/map win2 send Add: win2 /FrameCanvas get /Transparent false put > >but win2 doesn't appear. Does anyone have a subclass of LiteWindow or >anything that will fix this?? No need... > > - Frode --Josh Siegel -- Josh Siegel (siegel@hc.dspo.gov) I like using a C-47A "puff dragon" to go shooting beer cans with. From don@brillig.umd.edu Sat Jan 28 23:39:53 1989 Date: Sat, 28 Jan 89 23:39:53 EST To: NeWS-makers@brillig.umd.edu Subject: NeWSillustrator version 1.0 (part 1 of 5) From: mcvax!prlb2!bernard@uunet.uu.net (Bernard Yves) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Although I do not want to start a software maintenance activity, but due to the many encouraging mails I received and to the very buggy state of the previoulsy posted version, I finally decided to send a new version of NeWSillustrator I finished some times ago. Most of the known bugs have been corrected and the interface has been completely redesigned : it uses the 3 buttons of the mouse and an iconic tool palette. More sophisticated functions have been added for lines and curves edition. Some NeWS bugs (e.g. pointinpath --> unexpected SIGSEV signal) which used to crash the news server have been carefully bypassed. This posting includes a new manual. ----------------------------------------------------------------------------- NeWSillustrator --------------- NeWSillustrator is an object-oriented drawing program completely written in NeWS. It includes various object types with full control on line width, line type, line color, font, font size, color filling... Objects can be moved, scaled, rotated, grouped, copied, edited, clipped, aligned, centered,... Postscript files can be imported (with the limitation of the NeWS postscript interpreter) and generated for printing. Full scrolling and zooming capabilities are available at any time. Graphical input items (e.g. point, angle, ...) can be defined indifferently with the mouse or alphanumerically. Due to the interpreted feature of NeWS Postscript, many functions of NeWSillustrator can be redefined to your convenience and loaded at any time. However, this requires some programming experience with Postscript and NeWS. NeWSillustrator is written in NeWS, a superset of PostScript: NeWS = PostScript (a forth-like language with powerful graphics primitives) + Window Management concepts (events, processes,canvas) + object-oriented extensions (classes, inheritance,...) For those interested, look at the code and expand it as you want. NeWSillustrator runs with Sun NeWS window management system, release 1.1. It requires the existence of two shell variables : HOME and PWD (current directory of the news_server process). Starting. --------- After loading, NeWSillustrator will ask you to shape 3 windows : the Control Panel, the Drawing Area and the Tool Palette. Make them big enough. Place them at your convenience. Mouse Usage. ------------ Most of the input is made with mouse clicks except for text objects. The general functions of the 3 mouse buttons are the following: - Left button (LB) : to make an action such as inputting a point, selecting an object, selecting a control panel item, confirming, selecting a command icon. - Right button (RB) : The right button gives access to the menu associated to the window except for the Drawing Area where it can have various meanings: - in a started command needing an undefined number of clicks, the right button is used to end the click sequence. For instance, during the definition of a polygon the sequence of clicked points is stopped in clicking on the right button. - in a started command with a known number of clicks, the right button is used to abort it. - in some commands (e.g. Select), the right button gives access to the window menu. - Middle button (MB) : used in complex edition operations (e.g. to delete a point) in the Drawing Area. Other baroque usage in the other windows. Tool Selection. ------------------ A tool is selected by clicking with the LB on its icon in the tool palette. The tool layout in the palette is the following: Select Move Align Left Rectangle Rotate Align Down Polyline Scale Align ... Polygon Copy Align ... Curve Move Up Center Vertical RoundedRect Move Down Center ... Oval Delete/Ungroup Repeat Text Destroy Undo Group Edit Import PS Clip A tool is always applied on the current object. The Select tool is used to change the current object. A newly created object always become the current one. The Undo tool is implemented for Delete and Destroy. The Repeat tool repeats the last tool executed. It only works for Copy. This allows to place objects at a regular distance. There is a default tool which is by default Select : any time a command is terminated, the default tool is started. The default tool is changed by selecting a tool with the Middle button. Not all tools can be the default one : only object creation tools and Select. Usually, once a tool is selected, messages are printed in the control panel to explain you what to do and what happened. The message panel item is at the bottom of the control panel. If you don't see it, move or reshape the control panel window. Error messages come in the item item. For all tools and commands requiring file names (e.g. ImportPS,...), enter the name in the corresponding control panel item (e.g. PS file name) BEFORE selecting the command. For file savings, if the file already exists, you will have to confirm: a explanation appears in the message panel. Confirmation is made by clicking anywhere with LB. Commands Menu. ------------- Pressing the RB button in the Tool Palette or the Drawing Area (when the select tool is activated) gives access to the menu of commands associated to the window. The upper part of these menus are filled with the same commands. You can use the Scroll bar to scroll and the Zoom commands in the menu at any time: Zoom In enlarges by a factor 2, Zoom Out by 1/2. The Drawing Area ---------------- This is where the drawing is made. The dashed lines are the sides of the visible area of an A4 sheet on a laser printer. Tools and Commands Descriptions. -------------------------------- Object Creation Tools. ---------------------- These are : Rect, Polyline, Polygon, Curve, RoundedRect, Oval, Text, Group, ImportPS. Rect, RoundedRect, Oval : should be obvious; input points with LB; abort with RB. Line, Polygon: points are input with the Left mouse button. End with the Right mouse button. Use the Middle button to cancel the last input point. Curve : curves are made of Postscript elementary curves which are defined by 4 points. You will be asked to enter a sequence of points, and every time you input 3 points, a elementary curve is drawn connecting the 3 points with the last point of the previous curve. The curve is ended in clicking on the Right button. The middle button deletes the last entered point. With some practice, it is easy to make complex curves with straight segments (input the same control points). Text : The current text in control panel item labelled 'Text String' will follow the cursor in the Drawing Area. Click with the LB to place it, with the RB to abort the command. The text can be edited before placing it in going in the corresponding the item in the Control Panel: just click in the Text String item with the left mouse button and insert text. Text editing is allowed with the DEL, ctrl-f, ctrl-b and ctrl-d keys with the usual emacs meaning. Group : A group is a collection of any objects. A group is defined in two ways: by a box (the default) or by enumeration. The definition mode is changed in clicking in the 'Group Defined by' item of the control panel. by box: just enter a box enclosing completely the objects to group. by enumeration : select each object by clicking on it. End in clicking with the Right button. Cancel the last selected object with the middle button. Objects in a group are not accessible individually : to select an object in a group, you have to delete the group. A group is depicted on the screen by drawing its components and small squares on its enclosing box. A group is selected by clicking in that box. ImportPS : This object type correspond to imported Postscript files. The range of importable files is limited by the NeWS Postscript omissions (fonts, pattern filling,...). PS files produced by Fig seem to work. Of course, PS files generated by NeWSillustrator can be imported. Files which NeWS can not display will cause errors -- see the message in the control panel -- and will be (or should be) refused. Again, before selecting ImportPS, define the PS file to import in the corresponding item in the Control Panel. If the file can be successfully loaded, it will be displayed on the screen and you will be asked to give its bounding box. If nothing has appeared in the Drawing Area, then maybe the drawing is not in the displayed part of the sheet space: use the scroll bars or the zoom out command (by accessing the command menu in pressing RB in the Tool Palette). An imported file is considered as an usual object : it can be moved, copied, rotated, scaled, grouped,... Importation of Postscript file is made by generating an intermediate file in your home directory with the same name as the imported file and ".wps" as extension. These files are not deleted. Edition Tools. -------------- These operations always work on the current selection. To set an object as the current selection use the select command. Select : click in the inside of the object with the LB or MB. NeWSillustrator will select the 'smallest' object found under the clicked point. If it is not the one you want (because of many overlapping objects), move other objects or create a group that you will define by a box enclosing the object you want. Groups are selected by clicking in their enclosing box. Move, Rotate, Scale : obvious; use the RB to abort the operation. Rotation and scaling use the origin point of the object as reference point. The origin point is usually the first point input when defining the object or a corner of the enclosing box. Scale factors and Rotation angles are displayed in the Control Panel. Rotation and scaling of Text is not perfect with some fonts and sizes: this a bug in NeWS 1.1. Copy : makes a copy of the current object. The copy becomes the current object and you have to move it where you want. Move Up, Move Down : the display order defines how objects overlap each other. Move Up and Down change the display order and give full control on overlapping. Move Up (Down) will swap the current object with the next encountered object in the display list which is drawn after (before) it. If you continuously apply Move Up (Down) on an object, it should then become the last (first) displayed object (see the message in the control panel). Delete : delete the current selection. Delete a group but not its components (i.e. ungroup). Destroy : deletes a group AND all its components. Edit : only works for Lines, Polygons, Curves (and Text); allows to move, delete and insert points defining the selected objects. First, select a point by clicking on it with the Left button, move it and click with LB to accept the move or with the RB to cancel it. Delete it with MB. Insert a point in clicking on the line segment where you want to insert it. To stop edition click with the RB. Note that the first point of an item is not editable. For Text, simply correct the text in the 'Text String' Control Panel item. Clip : clip the current selection object with another object which will have to be selected by the user. The clipping object should not be a group, a text or an ImportPS object. The inside of the clipping path is determined by the normal PostScript non-zero winding number rule. A clipped object is implemented as a special kind of group: many operations available on group can be used on clipped object (e.g. delete, destroy). Align Left, Right,..., Center : works for items in a selected group; Drawing Area Menu Commands -------------------------- Redisplay : objects overlapping moved objects are not redrawn when these are moved. Use Redisplay to redraw all the objects and redraw them in the current order. Zoom Operations : Zoom In and Out by a factor 2 ; use the scroll bar to scroll your drawing. Font => Choose the font in the font menu. It will be the default font of newly created text object and the font of the current selection. All the fonts listed are not available on the laser. Also, there are problems with some fonts in NeWS. Font Size => : obvious. Files Operations. The 'Files IO =>' leads to a submenu with files operations. They require the corresponding file name to be defined in the control panel before selecting them. save PS file : generates a Postscript file printable on a laser and importable as an object in NeWSillustrator; save Objects file: save all the objects of the current drawing; load Object file: add all the objects in the file to the current drawing; (Object files can be used as a library) There are two other entries in the file menu: Window Pos. : gives the positions and dimensions of the three windows. See the Customization section. Info : displays a short copyright notice in the Control Panel message item. The generated PostScript files are prefixed with a header string. By default, this header is the standard Adobe starting line. However, for including PS files in other applications (e.g. LaTeX), it is generally useful to have a starting line containing the dimensions of the drawing. There is a switch called '/LatexFile?' that when set to true will generate as first line: % Rotation=0,Width=...,Height=...,Xoff=...,Yoff=... where the dots will be replaced by the adequate values. See the Customization section for setting this switch. Change the format according to your PostScript inclusion facilities of your Latex system in modifying the format string in the source code. Control Panel ------------- There are three main types of Control panel items : text and file name items, drawing parameters items and control items. Drawing parameters Items: -------------------------- They are : line width, style, join, cap, color, fill color, Rounded Corner Radius, line arrow, arrow size. Values of the drawing parameters are those of the current selection. Change of a drawing parameter always affect the current selection. If it is a group, its components will be affected. Use of Sliding items (e.g line color): just click anywhere on the line or drag the cursor to the required value. line color : the gray level from 0 (black) to 100 (white). fill color : idem ; the -1 is used for no fill. Color of text is changed by the line color slide, but in NeWS text is always displayed as black on a monochrome screen. In the Menu associated with the Control Panel, there is the "Set as Default" command which will set the current display parameters as the default ones for newly created objects. Control Items : ---------------- These are: grid size, grid on, snap to grid, group defined by, line quality, click to move, and Message, Values and Error items. Message Item : where message appear. Look at it. Just below it is the Values item, which display mouse coordinates, rotation angle, scaling factor,... Note that coordinates values are labelled according to the fact that they are relative (e.g. the second point of a rectangle is given relatively to the first one) or absolute coordinates. Just below the 'Values' item is the error message item. The line quality controls the rendering quality of NeWS : 0 = low quality but faster, 10 = best quality but slower. Grid Size : the current unit is screen point. Snap To Grid : clicked points will be snapped to the grid. 'Snap To Grid' is independent of the 'Grid On' item, except for the animation mode in interaction which changes whether the grid is on or not. Click To Move : the default mode when you select the Move tool on the current selection is that the object follows the cursor and you click with LB to place it. In Click To Move, you will first have to click an anchor point and then move the object. This is sometimes needed to place objects partly outside the window. File Items: obvious ------------------- For writing operations, if the file already exists, you will have to confirm by clicking on LB. Alphanumeric Input. ------------------- Alphanumeric input is to be used when you want to define accurate geometric informations or when it is physically impossible to define what you want with the mouse (e.g. scaling a big object by 200...) In the lower part of the Control Panel, there is an item labelled 'Data'. At any time where the program is waiting for a mouse click defining a point, an angle or a scaling, you can instead of clicking the mouse, click with LB in this item and type the values you want. The data will be sent after you have pressed the big button labelled 'SendIt'. For instance, if you want to make a circle with a diameter of 100 units, you can type '100 100' in the 'Data' item and 'SendIts' instead of clicking the second point of the oval in the drawing area. If you make an error (e.g. typing error, bad number of arguments), you will be warned by a message. Be careful to send coordinates matching the kind of coordinates the program is awaiting for : relative or absolute. (In general, the first point defining an object is absolute and the other ones are relative to it). User Customization. ------------------- At the end of its loading, before opening all windows, NeWSillustrator will load a file ~/.NeWSillustrator if it exists. In this file, you can write postscript code to change the behavior of NeWSillustrator. This requires some knowledge of NeWS postscript and of the NeWSillustrator code, but many useful customizations can be done by just recopying and modifying to your needs the existing procedures (the complete code of NeWSillustrator is the executable file itself). Here is an example where the following changes and settings are made: the drawing of arrows is changed to filled arrows, the default font to Courrier, the default font size and the crosshair cursor are redefined, the 'dash2' line style is changed, the 'Click To Move' switch is set on, the Move command is redefined, starting positions and dimensions are given for the 3 windows (the 'Window Pos.' options in the file menu will display in the message item the positions and dimensions of all windows), and finally the /LatexFile? switch is set to true console (arrow\n) [] fprintf %useful for debugging %arrow change /drarrow { % size x0 y0 x1 y1 => - ; draws an arrow % at end of seg %this code will be copied in saved postscript files. gsave [] 0 setdash %plain line dup 3 index sub %s x0 y0 x1 y1 yr 2 index 5 index sub atan %s x0 y0 x1 y1 a 3 1 roll %s x0 y0 a x1 y1 translate rotate pop pop %s dup neg dup neg %s -s s moveto 0 0 lineto %s neg dup lineto % stroke fill grestore } def %font and pointsize /FontName /Courier def /pointsize 10 def %crosshair /crosshair { crosshair? {x y 20 sub moveto 0 5 rlineto x y 20 add moveto 0 -5 rlineto x 20 sub y moveto 5 0 rlineto x 20 add y moveto -5 0 rlineto} if } def % plain - dash1 - dash2 /dasharray [ [ [] 0 ] [ [3] 0 ] [ [6 3] 0 ] ] def console (ClickToMove?\n) [] fprintf /ClickToMove? true def %update control panel item value; as CP items are not yet defined, fork %a little process which will do the update after the Control Panel items %will be created { { pause NeWSillustratorDict /Started known {items begin ClickToMove? /ItemValue 1 put /paint ClickToMove? send end exit} if pause pause %let other processes run } loop } fork pop console (Move redefinition\n) [] fprintf %redefines the tool Move to erase the object before moving it. CommandDict /Move get %the Move Tool begin /execproc { /crosshair? true def /erase fapply_on_sel /drag_and_trans fapply_on_sel Abort? {/display fapply_on_sel} if /crosshair? false def /commandswitch [/ClickToMove? ClickToMove?] store } def end console (Window Positions\n) [] fprintf /ControlPanelPosition [600 2 550 476] store /DrawingAreaPosition [15 147 586 671] store /ToolPalettePosition [847 253 302 619] store /LatexFile? true store Making New Tools. ----------------- The menu associated to the Tool Palette contains a 'Make Tool' option. In this distributed version, this is the only interactive extension mechanism. It allows to create a tool template with its icon for which you have to write the adequate NeWS code. A tool is just an icon with some associated code. The icon is in fact a group of objects made with NeWSillustrator. For the code, it is a bit more complicated. The procedure to make a tool is the following: 1. draw its icon (it should be a group) or select an existing group; 2. type in the 'Text String' item of the Control Panel the code of your tool. For instance: { mytoolproc } where my 'mytoolproc' is a Postscript procedure to write. 4. select the 'Make Tool' option in the tool palette menu. 5. Confirm for the code text 6. Position the icon in the tool palette. 7. save the tool in a file 8. edit this file and write the code for /mytoolproc. Example : make a tool with the following code { (CouCou!!) prvalue pause pause} select its icon: 'CouCou!!' will be displayed for a short time in the 'Value' control panel item. Tools can be saved in and loaded from files. Look at the corresponding options in the file menu. Frequently used tools files can be included in your ~/.NeWSillustrator file. Bugs. ---- There are surely many bugs. For instance, there is a bug in saving text objects: if the text contains a '(' opening parenthesis and not the closing one, the saved file (PS or Object) will not be usable. In that case, use you editor and replace the '(' with '\('. Performance. ----------- On my old Sun3/60 -- with its own disk --, performance is quite good. However, on Sun3/50 or others connected to a heavily loaded server, you may have problems, the most irritating one being the lost of mouse clicks due to the slowness of the system. On a Sun3/260, it's a real pleasure. Author ------ Yves Bernard Philips Research Lab, Brussels 2 avenue Van Becelare, 1170 Brussels e-mail: bernard@prlb2.uucp Copyright and Warranty : read the notice in the source file. ---------------------- From don@brillig.umd.edu Sat Jan 28 23:40:34 1989 Date: Sat, 28 Jan 89 23:40:34 EST To: NeWS-makers@brillig.umd.edu Subject: NeWSillustrator (part 2 of 5) From: mcvax!prlb2!bernard@uunet.uu.net (Bernard Yves) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) append the other parts together, make a chmod a+x on the file. -------------------------------------------------------------------------- #!/usr/NeWS/bin/psh %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % NeWSillustrator version 1.0 % % Copyright : Yves Bernard, Philips Research Lab Brussels % e-mail : bernard@prlb2.uucp % 2 avenue Van Becelaere 1170 Brussels Belgium % % 1. You may freely copy and distribute copies of NeWSillustrator as you % receive it, provided that you appropriately publish on each file this % entire copyright notice % % 2. You may modify your copy or NeWSillustrator and copy and distribute % such modifications under the terms of Paragraph 1 provided that you % also include a notice stating what changes you made, and provided that % your copy does not change the mention to NeWSillustrator in the % windows labels and does not delete the original 'Info' copyright entry % of the file menu. % % 3. You are not allowed to sell or distribute for any commercial purposes % this software or any copies derived directly or indirectly from it. % % 4. For other licensing policies, contact the author at the above % address % % 6. This copyright notice is clearly derived from the Free Software % Foundation licensing policy (-:) % % This software is provided without warranty of any kind, of course. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % scrollable and zoomable window class definition systemdict /zapmenu known not {systemdict begin /zapmenu [ (No, not really) {} (Yes, really) {/destroy ThisWindow send} ] /new DefaultMenu send def end } if /marksize 5 def %size of mark for group box /ScrollAndZoomWindow ScrollWindow dictbegin /PictureWidth 0 def % for translating the client window /PictureHeight 0 def /LDivisions 10 def % number of scroll bad pieces/whole /PDivisions 3 def % number of scroll bad pieces/whole /ScrollH 0 def % cumulative translation factors /ScrollV 0 def % due to successive scrolling; /ZoomFactor 1 def % zooming factor; /newox 0 def /newoy 0 def /Nzoom 0 def /zoomstack 50 array def /overlaycan null def dictend classbegin /Resize { % width height => - size the backround canvas /PictureHeight exch def /PictureWidth exch def [%0 PictureWidth ClientWidth sub newox neg PictureWidth ClientWidth sub newox add %min max dup dup LDivisions div exch PDivisions div null] /setrange HScrollbar send [%0 PictureHeight ClientHeight sub newoy neg PictureHeight ClientHeight sub newoy add dup dup LDivisions div exch PDivisions div null] /setrange VScrollbar send } def /SetNotifiers { % Hnotifier Vnotifier => - VScrollbar /NotifyUser 3 -1 roll put HScrollbar /NotifyUser 3 -1 roll put } def /Scroll {ScrollProc} def /ZoomIn {/marksize marksize 2 div store /ZoomFactor ZoomFactor 2 mul def ZoomInProc} def /ZoomOut {ZoomFactor 1 ne {/marksize marksize 2 mul store /ZoomFactor ZoomFactor 2 div def ZoomOutProc} if} def /ShapeClientCanvas { ClientCanvas null ne { ScrollAndZoomAxis} if } def /CreateFrameMenu { % - => - (Create frame menu) % Note: Store menu in class to share menus, especially if retained. /FrameMenu [ (Move) {/slide ThisWindow send} (Move Constrained) {getfbclick pop pop /slideconstrained ThisWindow send} (Top) {/totop ThisWindow send} (Bottom) {/tobottom ThisWindow send} (Zap => ) zapmenu (Resize) {/reshapefromuser ThisWindow send} (Stretch Corner) {getfbclick pop pop /stretchcorner ThisWindow send} (Stretch Edge) {getfbclick pop pop /stretchwindowedge ThisWindow send} (Close) {/flipiconic ThisWindow send} (Redisplay) {/paint ThisWindow send} ] /new DefaultMenu send def } def /ScrollAxis {%the scorllbar values are always in abs. coord. /ScrollH HScrollbar /ItemValue get def /ScrollV VScrollbar /ItemValue get def BorderLeft BorderBottom translate ScrollH neg ScrollV neg translate } def /ScrollProc { ScrollAndZoomAxis /PaintClient self send } def /pushzoomstack{% - => - zoomstack Nzoom [ScrollH ScrollV ] put /Nzoom Nzoom 1 add store } def /popzoomstack{% Nzoom 0 ne {/Nzoom Nzoom 1 sub store zoomstack Nzoom get aload pop %put that in the scroll bar value /ScrollV exch store /ScrollH exch store HScrollbar /ItemValue ScrollH put VScrollbar /ItemValue ScrollV put } if } def /ZoomInAxis { %zoom in by 1, 2, 4, 8,... /newox ClientWidth 2 div ClientWidth 2 ZoomFactor exp div sub def /newoy ClientHeight 2 div ClientHeight 2 ZoomFactor exp div sub def newox neg newoy neg translate ZoomFactor ZoomFactor scale ScrollH ZoomFactor div newox ZoomFactor div add ScrollV ZoomFactor div newoy ZoomFactor div add ClientWidth ZoomFactor div ClientHeight ZoomFactor div ClientPath ClientCanvas reshapecanvas } def /ScrollAndZoomAxis { gsave FrameCanvas setcanvas ScrollAxis % modifies the transf. matrix of the client canvas: ZoomFactor 1 eq {/newox 0 store /newoy 0 store ScrollH ScrollV ClientWidth ClientHeight ClientPath ClientCanvas reshapecanvas} {ZoomInAxis} ifelse /overlaycan ClientCanvas createoverlay store grestore MakeScrollEvent sendevent } def /reshape{ pause KillDefComProcess pause /reshape super send /overlaycan ClientCanvas createoverlay store NeWSillustratorDict /Started known {MakeDefComProcess pause} if } def /ZoomInProc { pushzoomstack ScrollAndZoomAxis /PaintClient self send PictureWidth 2 mul PictureHeight 2 mul /Resize self send HScrollbar /ItemValue ScrollH newox add put VScrollbar /ItemValue ScrollV newoy add put /paintscrollbars self send } def /ZoomOutProc { popzoomstack ScrollAndZoomAxis /PaintClient self send PictureWidth 2 div PictureHeight 2 div /Resize self send HScrollbar /ItemValue ScrollH newox add put VScrollbar /ItemValue ScrollV newoy add put /paintscrollbars self send } def /destroy{ % typical to NeWSillustrator KillDefComProcess /destroy super send } def classend def /MyWindowClass DefaultWindow dictbegin dictend classbegin /reshape {KillDefComProcess pause /reshape super send pause pause NeWSillustratorDict /Started known {MakeDefComProcess} if } def /destroy{ % KillDefComProcess /destroy super send } def classend def %private dict for all definitions /NeWSillustratorDict 400 dict def NeWSillustratorDict begin %if user wants to redefine that... /LeftMouseButton /LeftMouseButton def /RightMouseButton /RightMouseButton def /MiddleMouseButton /MiddleMouseButton def /snap_to_grid{% x y => xg yg gridsize div round gridsize mul %x yg exch gridsize div round gridsize mul %yg xg exch } def /SnapToGrid? false def /animate_event null def /crosshair? false def /Cancel? {animate_event RightMouseButton eq} def /Abort? false def /Confirm? {% message => true | false ( Confirm by Left, Abort with R. or M. button) append prmessage .033333 blockinputqueue { createevent dup begin /Action [ /DownTransition /UpTransition] def /Exclusivity true def end expressinterest createevent dup /Name /MouseDragged put expressinterest unblockinputqueue { awaitevent begin Action UpTransition eq { Name end exit } if end } loop } fork waitprocess LeftMouseButton eq } def /MakeScrollEvent{ createevent dup begin /Name /WindowScrolled def end} def /ThisObj null def /RedisplayWhenScroll {} def /mygetanimated { % x0 y0 proc => x y; puts button name in % animate_event { 3 copy false SnapToGrid? mygetanimated_2 dup % dup /CurAniProc exch store waitprocess %p [x y] animate_event /WindowScrolled ne {pop exit} %p {pause pop pop /RedisplayWhenScroll load length 0 ne { {ClientCanvas} win send setcanvas RedisplayWhenScroll } if setoverlay X0 Y0 translate } ifelse } loop %x0 y0 proc p 4 -3 roll pop pop pop %p waitprocess aload pop %x y }def %x y ; animate_event /mygetanimated_2 { %x0 y0 proc LetMenu? snap? => [ x y ]; %puts button name in animate_event 20 dict begin /snap? exch store /LetMenu? exch def /proc exch def /y0 exch def /x0 exch def currentcursorlocation /y exch def /x exch def /gridoff? gridon not def %this should accelerate dragging a little.. /X2 X2 def /Y2 Y2 def /Sx2 Sx2 def /Sy2 Sy2 def /Angle2 Angle2 def /LB LeftMouseButton def /RB RightMouseButton def /MB MiddleMouseButton def /crosshair? crosshair? def .033333 blockinputqueue { %newprocessgroup createevent dup begin /Canvas {ClientCanvas} win send def /Action [ /DownTransition /UpTransition ] def /Exclusivity true def end expressinterest createevent dup begin /Name /MouseDragged def /Canvas {ClientCanvas} win send def /Exclusivity true def end expressinterest MakeScrollEvent expressinterest WaitForEvent expressinterest unblockinputqueue { snap? gridoff? and {x y snap_to_grid /y exch store /x exch store} if erasepage x0 y0 moveto x y /proc load exec crosshair stroke awaitevent dup begin %ev Name dup /WindowScrolled eq {pop /animate_event /WindowScrolled store end exit} if dup /AlphaEvent eq %ev Name {pop Action dup /Point eq exch /Stop eq or {/animate_event Action /Point eq {LB} {RB} ifelse store ClientData aload pop /y exch store /x exch store} {/animate_event Name store WaitForEvent /ClientData ClientData put} ifelse end exit} if pop Action /UpTransition eq {end exit} if LetMenu? Name RB eq and Action /DownTransition eq and {redistributeevent} if %downtransition /x XLocation store /y YLocation store /animate_event Name store end %end dict event pop %pop } loop %event erasepage /cur_event exch store snap? {x y snap_to_grid 2 array astore} { [x y] } ifelse } fork % [x y] end %end mygetanimated_2 dict } def /crosshair { crosshair? {x -1000 moveto 0 2000 rlineto -1000 y moveto 2000 0 rlineto} if } def /mygetclick { % - => x y 0 0 { (X, Y : %, %) [x y] sprintf prvalue } mygetanimated } def /getclickwithmenu{ 0 0 { (X, Y : %, %) [x y] sprintf prvalue } true false mygetanimated_2 waitprocess aload pop } def /mygetwholerect { % - => [x, y, w, h] { x0 y lineto lineto x y0 lineto closepath (dX, dY : %, %) [x y ] sprintf prvalue } getrectthing %x y [w h] aload pop 4 array astore } def /getrectdict dictbegin /XR0 0 def /YR0 0 def /proca null def dictend def /getrectthing{% proc => [x, y, w, h] ; proc = oval, rect, rrect getrectdict begin /proca exch store mygetclick % x y /Relative? true store Cancel? { pop pop /Abort? true store 0 0 [0 0]} { /YR0 exch store /XR0 exch store %origin XR0 YR0 translate 0 0 /proca load mygetanimated %w h 2 array astore XR0 YR0 3 -1 roll %x y [w h] Cancel? {/Abort? true store} if } ifelse end /Relative? false store } def %=========================================================================== % utilities %=========================================================================== /setoverlay {win begin overlaycan end setcanvas} def /prdebug false def /printdbg { prdebug {console exch [] fprintf} {pop} ifelse} def (Loading utilities \n) printdbg /drect { % x,y w, h => - : makes a path corresponding to the box 4 2 roll moveto rect } def /myrrectpath { %because NeWS rrectpath uses arcto which does not %work with dashed lines... matrix currentmatrix 6 1 roll % m r x y w h 4 2 roll translate % m r w h 10 dict begin /h exch def /w exch def /r exch def h 0 lt { 1 -1 scale /h h neg store} if w 0 lt { -1 1 scale /w w neg store} if r 0 moveto w r sub r r 270 0 arc w r sub h r sub r 0 90 arc r h r sub r 90 180 arc r r r 180 270 arc closepath end setmatrix } def %setting of the object coord. system /spos {translate rotate scale} def /b1 null def /boxpath { % [x1 y1 x2 y2] => - makes path of the box aload pop 3 index 3 index moveto %x1 y1 x2 y2 2 index sub %x1 y1 x2 (y2-y1) exch 3 index sub exch rect pop pop } def /box_in_box {% b1 b2 => bool ; true if b1 in b2; box = [x0, y0, x1, y1] gsave boxpath aload pop %x1 y1 x2 y2 pointinpath 3 1 roll pointinpath and grestore } def /box_of_box {% b1 b2 => b3 ;computes the box enclosing the 2 aload pop 5 -1 roll aload pop %4 points on the stack connect them in newpath moveto lineto lineto lineto [ pathbbox ] } def /o_dict dictbegin /x1 0 def /x2 0 def /y1 0 def /y2 0 def dictend def /overlapping_interval{ % x1 x2 y1 y2 => true if [x1 x2] inter [y1 y2] %non null o_dict begin /y2 exch store /y1 exch store /x2 exch store /x1 exch store x1 y1 y2 in_interval x2 y1 y2 in_interval or {true} {y1 x1 x2 in_interval y2 x1 x2 in_interval or} ifelse end } def /in_interval{% x y1 y2 => bool 2 copy min %x y1 y2 min 3 1 roll max %x min max 2 index gt %x min b1 3 1 roll gt and } def /overlapping_box{% b1 b2 => bool; true if box overlaps aload pop 5 -1 roll aload pop 7 index 6 index %x11 x12 5 index 4 index %x21 x22 overlapping_interval {6 index 5 index 4 index 3 index overlapping_interval} {false} ifelse mark 10 2 roll cleartomark } def /on_seg_dict 10 dict def /neareq{%x1 x2 => bool sub abs 3 lt } def /is_on_segment{% x y x0 y0 x1 y1 => bool ; true % if x y on segment x0 y0 x1 y1 on_seg_dict begin /y1 exch def /x1 exch def /y0 exch def /x0 exch def /y exch def /x exch def /dist 0 def false x0 x1 neareq %vertical {pop x x0 neareq y y0 y1 in_interval and} {y0 y1 neareq %horiz {pop y y0 neareq x x0 x1 in_interval and} { %oblique x x0 x1 in_interval {y y0 y1 in_interval {x1 x0 sub y y0 sub mul %p1x * py y1 y0 sub x x0 sub mul %p1y * px sub abs dup /dist exch store 500 lt {pop true} if } if} if } ifelse } ifelse end } def /drarrow { % size x0 y0 x1 y1 => - ; draws an arrow % at end of seg gsave [] 0 setdash %plain line dup 3 index sub %s x0 y0 x1 y1 yr 2 index 5 index sub atan %s x0 y0 x1 y1 a 3 1 roll %s x0 y0 a x1 y1 translate rotate pop pop %s dup neg dup neg %s -s s moveto 0 0 lineto %s neg dup lineto stroke grestore } def %working var. %/mtrx0 matrix def %/mtrx1 matrix def %/newarray null def %/tmparray 100 array def %/Ntmp 0 def /N 0 def /tmpstr 50 string def %/Angle2 0 def %/Sx2 1 def %/Sy2 1 def %/Sx3 1 def %/Sy3 1 def /X0 0 def /Y0 0 def %/X1 0 def %/Y1 0 def %/X2 0 def %/Y2 0 def %/Xc 0 def %/Yc 0 def /oldcanvas null def %=========================================================================== % object Table definition and management /SizeObjTable 1000 def /ObjTable SizeObjTable array def 0 1 SizeObjTable 1 sub {ObjTable exch null put} for /FreeObj 10 array def /FreeObjTop 0 def /AddFreeEntry {% free obj table entry => - FreeObjTop 9 le {FreeObj exch FreeObjTop exch put /FreeObjTop FreeObjTop 1 add store} {pop} ifelse } def /DeleteFreeEntries{ /FreeObjTop 0 store } def /GetFreeEntry{ FreeObjTop 0 gt {/FreeObjTop FreeObjTop 1 sub store FreeObj FreeObjTop get} {Nobj /Nobj Nobj 1 add store} ifelse } def /Nobj 0 def % /AddObject {% => - GetFreeEntry 2 copy exch ObjTable 3 1 roll put %obj index exch begin /tableindex exch store end Nobj SizeObjTable ge {(Object Table is full) prmessage} if } def /ForProc {} def /ForEachObj {% proc = ->; apply proc on each object in the table %which is not in a group /ForProc exch store 0 1 Nobj 1 sub {ObjTable exch get dup null ne {dup begin ingroup end {pop} {ForProc} ifelse } {pop} ifelse} for } def /RepaintAll {% repaint all objects in table; gsave /display a4rect send {/display exch send} ForEachObj grestore draw_grid } def /procfile null def /procstr 50 string def /token_in_line 0 def /c_writestring{% string => - procfile exch writestring procfile ( ) writestring token_in_line 10 gt {procfile (\n) writestring /token_in_line 0 store} {/token_in_line token_in_line 1 add store} ifelse } def /print_any{ %any => postscript code to procfile dup type /operatortype eq {dup procstr cvs dup ('mark) eq { pop ([) c_writestring } { dup (') search { % s post match pre ; a postscrip op. pop pop pop dup length 2 sub 1 exch getinterval c_writestring} {% s s ; a /name procfile (/) writestring c_writestring pop } ifelse} ifelse } {dup type /arraytype eq 1 index xcheck and %code array { ({) c_writestring procfile print_procdef (}) c_writestring } {dup type /nametype eq %a name {dup xcheck {procstr cvs c_writestring} {procfile (/) writestring procstr cvs c_writestring } ifelse} {dup type /arraytype eq %an array value {([) c_writestring {print_any} forall (]) c_writestring } {dup type /stringtype eq {procfile exch ( (%) ) exch [ exch ] fprintf} {procstr cvs c_writestring} ifelse } ifelse } ifelse } ifelse } ifelse } def /print_procdef { % proc file => - ; print the text of proc in file /procfile exch store cvlit { print_any } forall } def /print_code { % /name => - ; in PSfile /token_in_line 0 store dup NeWSillustratorDict exch known {% /name dup procstr cvs PSfile exch (/% { \n) exch [ exch ] fprintf NeWSillustratorDict exch get PSfile print_procdef PSfile (\n } def \n) writestring } {pop} ifelse } def /PSsignature (%! %%NeWSillustrator -- Y. Bernard, Philips Research\n) def % Rotation=0,Width=540,Height=384,Xoff=13,Yoff=219 /psbox null def /PSbox{%computes the bounding box of the drawing Nobj 0 gt {%get first box ObjTable 0 get /bbox get 4 array copy /psbox exch store {begin bbox end psbox box_of_box /psbox exch store} ForEachObj psbox aload pop %x1 y1 x2 y2 2 index sub exch %x1 y1 h x2 3 index sub exch %x1 y1 w h 4 2 roll %w h x1 y1 4 array astore } {[0 0 0 0 ]} ifelse } def /LatexFile? false def /PrintPS_header{ %postscript utilities %this is not standard but is used here for inclusion in Latex LatexFile? {PSfile (% ) writestring PSfile (Rotation=0,Width=%,Height=%,Xoff=%,Yoff=%\n) PSbox fprintf} if PSfile PSsignature writestring PSfile (/rect {dup 0 exch rlineto exch 0 rlineto neg 0 exch rlineto closepath } def /ovalpath { matrix currentmatrix 5 1 roll 4 2 roll translate scale .5 .5 translate 0 0 .5 0 360 arc closepath setmatrix} def\n) [] fprintf /myrrectpath print_code %dash patterns print_dasharray_ps /setdashpat print_code /drarrow print_code /spos print_code PSfile (0 setlinewidth 0 setgray /privatedict 100 dict def /mtrx1 matrix def /savemtrx matrix def privatedict begin /showpage {} def end \n) writestring } def /dasharray [ [ [] 0 ] [ [3] 0 ] [ [6] 0 ] ] def /setdashpat{% n => - dasharray exch get aload pop setdash} def /print_dasharray_ps{% PSfile (/dasharray \n) writestring dasharray print_any PSfile ( def\n) writestring } def /importfiledict null def %used when generating the postscript file %to remind what imported PS file have already been written /RepaintAll_ps {% generates postscript file PrintPS_header /importfiledict 50 dict store PSfile (gsave \n) [] fprintf {/display_ps exch send} ForEachObj PSfile (grestore showpage\n) [] fprintf } def /saveobjprelude null def /SaveAllObjects {% generates NeWS files of object def; loaded with run /saveobjprelude ( dup AddObject mark \n) store {/saveobject exch send} ForEachObj } def /loadobj{%used in loading obj files. counttomark 1 add index %obj mark var1... varn obj /loadivar exch send cleartomark dup begin ingroup not end {pop} if } def %Default display parameters /current_linecolor 0 def %black /current_linewidth 0 def %hair line /current_fill -1 def /current_linecap 0 def /current_linejoin 0 def /current_linestyle 0 def /current_arrowsize 5 def /current_startarrow? false def /current_endarrow? false def /current_radcorner 8 def /erase_flag true def /group_def_mode (by box) def % Root Class -- Defines the protocol of all other object classes (Loading Class def \n) printdbg /DrawObject Object dictbegin /X 0 def %position /Y 0 def /Sx 1 def %scaling /Sy 1 def /Angle 0 def %rotation /bbox null def %bounding box [x1,y1,x2,y2] /color -1 def %filling pattern = -1 : no filling /linewidth 0 def %line width /linecolor 0 def %line color = black /linestyle 0 def %line style = plain or dashed /linejoin 0 def /linecap 0 def /geom null def % % default geom is a rect [w,h] /tableindex -1 def /ingroup false def % true if object part of a group dictend classbegin %some working var. put as class variables /mtrx0 matrix def /mtrx1 matrix def /newarray null def /tmparray 100 array def /Ntmp 0 def /Angle2 0 def /Sx2 1 def /Sy2 1 def /Sx3 1 def /Sy3 1 def /X1 0 def /Y1 0 def /X2 0 def /Y2 0 def /Xc 0 def /Yc 0 def /new { /new super send begin /init self send currentdict end } def /init { /bbox 4 array store /getcurrentdisplayparam self send} def /delete { /erase self send ObjTable tableindex null put tableindex AddFreeEntry} def /destroy {} def /saveivar{%writes instance var. on File OSfile ( % % % % % ) [X Y Sx Sy Angle] fprintf OSfile ( [ % % % % ] \n) bbox fprintf OSfile ( % % % % % % \n) [color linewidth linecolor linestyle linejoin linecap] fprintf /save_geom self send OSfile ( % ) [ingroup] fprintf } def /loadivar {% mark objects instances var => self if ingroup else - %in the order in which they are defined /ingroup exch store %tableindex /geom exch store /linecap exch store /linejoin exch store /linestyle exch store /linecolor exch store /linewidth exch store /color exch store /bbox exch store /Angle exch store /Sy exch store /Sx exch store /Y exch store /X exch store } def /getclassname{%get the class name of the object ParentDictArray dup length 1 sub get begin ClassName end } def /saveobject{%saves object descr in OSfile OSfile (/new % send ) [/getclassname self send] fprintf OSfile saveobjprelude writestring /saveivar self send OSfile ( loadobj\n) writestring } def /save_geom{%save geom descr OSfile ( [ % % ]\n) geom fprintf} def /setradcorner {pop} def /setlinestyle{/linestyle exch store} def /setlinejoin2 {/linejoin exch store} def /setlinecap2 {/linecap exch store} def /setlinewidth2 { /linewidth exch store } def /setlinecolor { /linecolor exch store } def /setcolor { /color exch store } def /changefont {} def /changefontsize {} def /setarrowsize {} def /setarrow {} def /setdisplayparam{% /linewidth exch store /linecolor exch store /color exch store /linestyle exch store /linejoin exch store /linecap exch store } def /getcurrentdisplayparam{ current_linecap current_linejoin current_linestyle current_fill current_linecolor current_linewidth /setdisplayparam self send } def /update_control_panel{% put display param of objects in control panel linewidth linecolor color linestyle linejoin linecap putinControlPanel } def /bbox_path { %in absolute coord syst. bbox 0 get bbox 1 get moveto bbox 2 get bbox 0 get sub bbox 3 get bbox 1 get sub rect } def /make_path { % Sx Sy angle X Y => - %makes the path of the object : default is drawing a rect %of W, H geom null ne { spos % translate rotate scale newpath 0 0 moveto geom aload pop rect} if } def /make_path_ps{% - => - geom null ne { PSfile (spos newpath 0 0 moveto % % rect\n) geom fprintf} if } def /BoxSize{% gives box surface bbox aload pop %x1 y1 x2 y2 2 index sub %x1 y1 x2 (y2-y1) exch 3 index sub exch mul abs } def /is_in_box {% x y => bool ; bbox 1 get bbox 3 get in_interval %x by exch bbox 0 get bbox 2 get in_interval and } def /is_in_obj {% x y => bool ; geom null eq {pop pop false} {gsave newpath moveto X Y translate Angle rotate Sx Sy scale % {} {} {} {} pathforall %x y in object coord. sys. 1 1 0 0 0 /make_path self send pointinpath grestore} ifelse } def /dr { %low-level drawing : linewidth linecolor color linejoin linecap % linestyle => - %graphic state is preserved; gsave setdashpat setlinecap setlinejoin Sx Sy Angle X Y /make_path self send dup -1 ne {gsave setgray fill grestore} {pop} ifelse setgray setlinewidth stroke grestore } def /dr_ps {% color => - PSfile (gsave setdashpat setlinecap setlinejoin % % % % %\n) [Sx Sy Angle X Y] fprintf /make_path_ps self send -1 ne { PSfile ( gsave setgray fill grestore ) [] fprintf} {PSfile ( pop ) [] fprintf} ifelse PSfile (setgray setlinewidth stroke grestore\n) [] fprintf } def /erase { % this will also erase parts of overlapping objects linewidth 1 color -1 eq {color} {1} ifelse linejoin linecap linestyle /dr self send } def /display { %display the object linewidth linecolor color linejoin linecap linestyle /dr self send} def /display_ps {%generation of postscript PSfile ( % % % % % % ) [linewidth linecolor color linejoin linecap linestyle] fprintf color /dr_ps self send } def /make_bbox { %computes the bounding box of the object in the current %coord system mtrx0 currentmatrix pop gsave Sx Sy Angle X Y /make_path self send %path made in trans,scaled,rotated %coord. sys; get coord in normal sys; mtrx0 setmatrix %path set in mtrx0 coord syst. pathbbox bbox astore pop grestore } def /move { % x' y' sx' sy' a' => moves to new position and orientation; % recomputes bbox; Cancel? not { erase_flag {/erase self send} if /Angle exch def /Sy exch def /Sx exch def /Y exch def /X exch def /make_bbox self send /display self send} if } def /set_geom {% [p1,p2] => - ; new H and W /geom exch store } def /scale_geom { % sx sy => - geom 1 get mul geom exch 1 exch put geom 0 get mul geom exch 0 exch put } def /get_geom { % => geom } def /change_geom {%change geometry; => - %erases old shapes and redraws it; /erase self send exec %exec change proc on stack /make_bbox self send /display self send } def /make_opath{ %the outline path used in draging mode /make_path self send } def /drag { %drag outline of shape following cursor % returns dragged position of new origin X' Y' /oldcanvas currentcanvas store setoverlay /Angle2 Angle store /Sx2 Sx store /Sy2 Sy store /xoff 0 store /yoff 0 store ClickToMove? { (enter starting point of move) prmessage mygetclick /yoff exch store /xoff exch store /xoff xoff X sub store /yoff yoff Y sub store (move object now) prmessage setoverlay} if /WaitForEvent MoveEvent store 0 0 { newpath Sx2 Sy2 Angle2 x xoff sub y yoff sub gsave /make_opath self send stroke grestore (X, Y : %, % ) [x y] sprintf prvalue } mygetanimated %x y animate_event /AlphaEvent eq %gets the data {pop pop WaitForEvent /ClientData get aload pop %xr yr Y add exch %Y' xr X add exch} if /WaitForEvent PointEvent store yoff sub exch xoff sub exch oldcanvas setcanvas } def /bbox_center { % => xc, yc ; box center bbox 0 get bbox 2 get add 2 div bbox 1 get bbox 3 get add 2 div } def /drotate {%interactive rotation : put x y on stack /oldcanvas currentcanvas store setoverlay /Angle2 Angle store /Sx2 Sx store /Sy2 Sy store /X2 X store /Y2 Y store /bbox_center self send /Yc exch store /Xc exch store /WaitForEvent RotateEvent store 0 0 { newpath % get angle of vector Xc,Yc - x,y Sx2 Sy2 Angle2 y Yc sub x Xc sub atan add %sx sy angle dup [ exch ] (Angle : %) exch sprintf prvalue X2 Y2 gsave /make_opath self send stroke grestore } mygetanimated %x y oldcanvas setcanvas } def /dscale { %interactive scaling from box lower left corner /oldcanvas currentcanvas store setoverlay /Angle2 Angle store /Sx2 Sx store /Sy2 Sy store /X2 X store /Y2 Y store /Xc bbox 2 get bbox 0 get sub store /Yc bbox 3 get bbox 1 get sub store /WaitForEvent ScaleEvent store bbox 0 get bbox 1 get { newpath Sx2 x x0 sub Xc div mul Sy2 y y0 sub Yc div mul %sx sy [ 2 index 2 index ] (Sx, Sy : %, %) exch sprintf prvalue Angle2 X2 Y2 gsave /make_opath self send stroke grestore } mygetanimated %x y oldcanvas setcanvas } def /drag_and_scale {% scale the geometry definition; preserve line width!! (scale) prmessage /dscale self send % x y Cancel? not { animate_event /AlphaEvent eq %gets the data {pop pop WaitForEvent /ClientData get aload pop} %sx sy { /Y2 exch store /X2 exch store X2 bbox 0 get sub bbox 2 get bbox 0 get sub div %sx' Y2 bbox 1 get sub bbox 3 get bbox 1 get sub div %sy' } ifelse {/scale_geom self send} /change_geom self send } if /WaitForEvent PointEvent store } def /drag_and_trans { (move) prmessage /crosshair? true store /drag self send %x' y' on stack; move to that Sx Sy Angle /move self send /crosshair? false store} def /drag_and_rotate { (rotate) prmessage /drotate self send %x' x' on stack; recompute angle; /Y2 exch store /X2 exch store X Y Sx Sy Angle animate_event /AlphaEvent eq %gets the data { WaitForEvent /ClientData get} { Y2 Yc sub X2 Xc sub atan } ifelse %the angle RecordEvents? {dup /AlphaEvent /Rotate exch MakeEventToRecord AddEvent} if add /move self send /WaitForEvent PointEvent store } def /i_get_geom {%gets geom def. from user interaction ; - => X Y [geom def] (Rectangle) prmessage mygetwholerect % [x0 y0 w h] aload pop % x0 y0 w h 2 array astore % X0 Y0 [w h ] /Abort? Cancel? store } def /i_def_geom {%interactive definition of geom /oldcanvas currentcanvas store setoverlay /crosshair? true store /i_get_geom self send % X Y oldcanvas setcanvas Abort? not { 3 -2 roll geom null ne {/erase self send} if /Y exch store /X exch store /set_geom self send geom null ne { /make_bbox self send /display self send} if /crosshair? false store } {/geom null store /Abort? false store} ifelse } def /edit_geom {} def /clone_geom {%obj contains in its geom structured data which is %shared by other objects ; copies geom and bbox geom type (arraytype) eq From don@brillig.umd.edu Sat Jan 28 23:41:25 1989 Date: Sat, 28 Jan 89 23:41:25 EST To: NeWS-makers@brillig.umd.edu Subject: NeWSillustrator (part 3 of 5) From: mcvax!prlb2!bernard@uunet.uu.net (Bernard Yves) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) %----------------------------------------------------------------------------- {/geom geom dup length array copy store } if bbox 4 array copy /bbox exch store } def /clone { % -> returns a clone of self self length dict self exch copy %clone on stack dup /clone_geom exch send } def classend def (Oval \n) printdbg /Oval DrawObject %geom = [w,h] of oval dictbegin dictend classbegin /new { /new super send begin currentdict end } def /make_path {% geom contains radius; geom null ne { spos newpath 0 0 geom 0 get geom 1 get ovalpath } if } def /make_path_ps{ geom null ne { PSfile ( spos newpath 0 0 % % ovalpath\n) geom fprintf } if } def /i_get_geom { (Oval) prmessage {newpath x0 y0 x y ovalpath (dX, dY : %, %) [x y] sprintf prvalue } getrectthing % X0 Y0 [X1 Y1 ] %X,Y, [w, h] } def classend def (Group \n) printdbg /Group DrawObject dictbegin /Ngr 0 def %geom will contain an array with all the subobjects %position of subobjects are relative to the position %of the group /Ncopy 0 def %working var. for recursive cloning dictend classbegin /new { /new super send begin currentdict end } def /saveivar { /saveivar super send OSfile ( % ) [Ngr] fprintf } def /loadivar{ /Ngr exch store /loadivar super send } def /components_path {%makes a path going from 0 0 to origins of components %relative to group coord. syst. X Y translate Angle rotate Sx Sy scale newpath 0 0 moveto geom {begin X Y lineto end} forall } def /delete {% all components are defined in the group coord. syst. % put them back in the global syst. mtrx0 currentmatrix pop %translation correction gsave /components_path self send mtrx0 setmatrix %coord expressed in global syst. /N 0 store {pop pop} {%component position X Y geom N get begin /Y exch store /X exch store end /N N 1 add store} {} {} pathforall grestore %rotation ingroup not {gsave 1 setgray /contour_mark self send grestore} if /Angle2 Angle store gsave 0 setgray geom {dup begin /Angle Angle Angle2 add store /ingroup false store end dup /make_bbox exch send dup /getclassname exch send /Group eq {/contour_mark exch send} {pop} ifelse } forall grestore ObjTable tableindex null put tableindex AddFreeEntry } def /clone_geom{% makes a clone of each component /clone_geom super send /Ncopy 0 store geom { /clone exch send dup geom exch Ncopy exch put /Ncopy Ncopy 1 add store AddObject} forall } def /destroy {%deletes all compoments /erase self send geom {begin ObjTable tableindex null put tableindex AddFreeEntry end} forall ObjTable tableindex null put tableindex AddFreeEntry } def /undestroy{% undo the destroy geom {dup begin tableindex end exch ObjTable 3 1 roll put} forall } def /setarrowsize{ /Xc exch store geom {Xc exch /setarrowsize exch send} forall} def /setarrow{% [ s? e?] geom {1 index %[s e] o [s e] exch %[s e] [s e] o /setarrow exch send} forall pop } def /setradcorner { /Xc exch store geom {Xc exch /setradcorner exch send} forall} def /setlinejoin2 { /Xc exch store geom {Xc exch /setlinejoin2 exch send} forall} def /setlinecap2 { /Xc exch store geom {Xc exch /setlinecap2 exch send} forall} def /setlinestyle { /Xc exch store geom {Xc exch /setlinestyle exch send} forall} def /setlinewidth2 { /Xc exch store geom {Xc exch /setlinewidth2 exch send} forall} def /setlinecolor { /Xc exch store geom {Xc exch /setlinecolor exch send} forall} def /setcolor { /Xc exch store geom {Xc exch /setcolor exch send} forall} def /make_path {%stroke the path of each object; used in draging mode %for scaling, we can not have at the same time good %scaling of objects positions and good scaling of their shapes geom null ne { spos geom {dup begin % Sx3 Sy3 Sx Sy Angle X Y end 6 -1 roll gsave /make_path exch send stroke grestore} forall } if } def /make_opath {%stroke the path of each object; used in draging mode %for scaling, we can not have at the same time good %scaling of objects positions and good scaling of their shapes geom null ne { spos geom {dup begin % Sx3 Sy3 Sx Sy Angle X Y end 6 -1 roll gsave /make_opath exch send stroke grestore} forall } if } def /is_in_obj { /is_in_box self send} def /set_geom {%[o1 o2 o3 ...] => %change X Y of Oi to X' Y' relative to X Y of group obj %set ingroup flag of each Oi dup length /geom exch array store geom copy pop /Ngr geom length store Ngr 0 ne { %get origin of group : first point of bbox gsave 1 setgray geom {dup /getclassname exch send /Group eq {/contour_mark exch send} {pop} ifelse} forall grestore /X 0 store /Y 0 store /make_bbox self send bbox aload pop %x1 y1 x2 y2 pop pop /Y exch store /X exch store /X0 X store /Y0 Y store geom {begin /X X X0 sub store /Y Y Y0 sub store /ingroup true store end} forall /make_bbox_component self send ( % components put in group) [Ngr] prmessage } {/geom null store} ifelse } def /save_geom{% saves on OSfile an array composed of each object saving OSfile ([ %group geometry\n) writestring geom {/saveobject exch send} forall OSfile ( ] %end of group geometry\n) writestring } def /make_bbox_component{%compute bbox of comp. in this group coord. syst gsave X Y translate %Angle rotate Sx Sy scale geom { /make_bbox exch send} forall grestore } def /contour_mark{ bbox 0 get bbox 1 get moveto drawmark fill bbox 0 get bbox 2 get add 2 div bbox 1 get moveto drawmark fill bbox 2 get bbox 1 get moveto drawmark fill bbox 2 get bbox 1 get bbox 3 get add 2 div moveto drawmark fill bbox 2 get bbox 3 get moveto drawmark fill bbox 0 get bbox 2 get add 2 div bbox 3 get moveto drawmark fill bbox 0 get bbox 3 get moveto drawmark fill bbox 0 get bbox 1 get bbox 3 get add 2 div moveto drawmark fill } def /display { gsave Sx Sy Angle X Y spos geom {/display exch send} forall grestore ingroup not { gsave 0 setgray /contour_mark self send grestore} if } def /align_left{%align all elements on the left side of the bbox (align left) prmessage geom{begin /X X bbox 0 get sub store end} forall /make_bbox_component self send } def /align_bottom{ (align bottom) prmessage geom{begin /Y Y bbox 1 get sub store end} forall /make_bbox_component self send } def /align_right{% (align right) prmessage /X1 bbox 2 get bbox 0 get sub store geom {begin /X X X1 bbox 2 get sub add store end} forall /make_bbox_component self send } def /align_top{% (align top) prmessage /X1 bbox 3 get bbox 1 get sub store geom {begin /Y Y X1 bbox 3 get sub add store end} forall /make_bbox_component self send } def /center_vertical{ (center vertical) prmessage /X1 bbox 2 get bbox 0 get add 2 div bbox 0 get sub store geom {begin /X X X1 bbox 2 get bbox 0 get add 2 div sub add store end} forall /make_bbox_component self send } def /center_horizontal{ (center horizontal) prmessage /X1 bbox 3 get bbox 1 get add 2 div bbox 1 get sub store geom {begin /Y Y X1 bbox 3 get bbox 1 get add 2 div sub add store end} forall /make_bbox_component self send } def /display_ps { PSfile (gsave % % translate % rotate % % scale\n) [X Y Angle Sx Sy] fprintf geom {/display_ps exch send} forall PSfile ( grestore\n) [] fprintf } def /erase { gsave X Y translate Angle rotate Sx Sy scale geom {/erase exch send} forall grestore ingroup not { gsave 1 setgray /contour_mark self send grestore} if } def /scale_geom {%sx sy /Sy2 exch store /Sx2 exch store geom {dup Sx2 Sy2 /scale_geom 4 -1 roll send begin /X X Sx2 mul store /Y Y Sy2 mul store end} forall /make_bbox_component self send } def /changefont {% fontname geom{ % font obj 1 index exch /changefont exch send} forall pop } def /changefontsize{% size geom{ % font obj 1 index exch /changefontsize exch send} forall pop } def /make_bbox {% approximatively computed from the box of components %expressed relatively %to the group coord. syst. mtrx1 currentmatrix pop gsave %draws a path following all the boxex components X Y translate Angle rotate Sx Sy scale geom 0 get begin bbox aload pop %x1 y1 x2 y2 newpath moveto pop pop end geom 0 Ngr getinterval {begin bbox aload pop %x1 y1 x2 y2 2 copy lineto %x1 y1 x2 y2 ; x2 y2 1 index 3 index lineto % ; x2 y1 3 index 3 index lineto % ; x1 y1 3 index 1 index lineto % ; x1 y2 pop pop pop pop end} forall mtrx1 setmatrix pathbbox bbox astore pop grestore } def /i_get_geom_enum{%put selected objects as part of group %end with Left button, Middle button cancels last object. /Ntmp 0 store %repeat { (select component object with Left button - end with Right button :) prmessage mygetclick /Y0 exch store /X0 exch store animate_event LeftMouseButton eq { X0 Y0 find_object_on_pt dup null ne { dup begin (% added in group) [tableindex] prmessage end dup /erase exch send pause dup /display exch send tmparray exch Ntmp exch put /Ntmp Ntmp 1 add store } {pop} ifelse } if animate_event MiddleMouseButton eq %suppress last object {Ntmp 0 gt {/Ntmp Ntmp 1 sub store} if} if Cancel? {exit} if } loop X0 Y0 tmparray 0 Ntmp getinterval } def /i_get_geom_by_box{%define group in giving a box (enter box enclosing objects to group : ) prmessage mygetwholerect %[x1 y1 w h] aload pop %x1 y1 w h 2 index add %x1 y1 w y2 exch 3 index add %x1 y1 y2 x2 exch 4 array astore /bbox exch store [ bbox find_objects_in_box /Ntmp exch store ] (% objects to group) [Ntmp] prmessage bbox 0 get bbox 1 get 3 -1 roll %the origin should be %the bounding box } def /i_get_geom{ (Group) prmessage group_def_mode (by box) eq {/i_get_geom_by_box self send} {/i_get_geom_enum self send} ifelse } def classend def (ClippingGroup \n) printdbg /ClippingGroup Group dictbegin %a clipping group is composed of 2 objects : the first one %is the clipping obj and the second one the clipped obj. The clipping obj %should be a line or curve; dictend classbegin /setclip{ mtrx1 currentmatrix pop geom 0 get begin Sx Sy Angle X Y end /make_path geom 0 get send clip %set the clip path mtrx1 setmatrix } def /set_geom {%[o1 o2 o3 ...] => %change X Y of Oi to X' Y' relative to X Y of group obj %set ingroup flag of each Oi % (set_geom\n) print dup length /geom exch array store geom copy pop /Ngr geom length store %get origin of group : first point of bbox of clipping geom 0 get begin bbox end aload pop %x1 y1 x2 y2 pop pop /Y exch store /X exch store /X0 X store /Y0 Y store geom {begin /X X X0 sub store /Y Y Y0 sub store /ingroup true store end} forall /make_bbox_component self send } def /display { gsave Sx Sy Angle X Y spos /display geom 0 get send %dipslay clipping obj /setclip self send /display geom 1 get send %draws the clipped grestore } def /display_ps { PSfile (gsave % % % % % spos\n) [Sx Sy Angle X Y] fprintf /display_ps geom 0 get send PSfile (mtrx1 currentmatrix pop % % % % % \n) [geom 0 get begin Sx Sy Angle X Y end] fprintf /make_path_ps geom 0 get send PSfile ( clip mtrx1 setmatrix \n) [] fprintf /display_ps geom 1 get send PSfile ( grestore\n) [] fprintf } def /erase { gsave Sx Sy Angle X Y spos /erase geom 0 get send %dipslay clipping obj /setclip self send /erase geom 1 get send %draws the clipped grestore } def /make_bbox{ %the bounding box is the one of the clipping obj /Ngr 1 store /make_bbox super send /Ngr 2 store } def classend def (RoundedRect \n) printdbg /RoundedRect DrawObject dictbegin /radcorner 8 def dictend classbegin /new { /new super send begin currentdict end } def /setradcorner {/radcorner exch store} def /saveivar{ /saveivar super send OSfile ( % ) [radcorner] fprintf } def /loadivar{ /radcorner exch store /loadivar super send } def /make_path {% geom null ne { spos newpath radcorner 0 0 geom 0 get geom 1 get myrrectpath } if } def /make_path_ps { geom null ne { PSfile (spos newpath % 0 0 % % myrrectpath\n) [radcorner geom 0 get geom 1 get] fprintf } if } def /i_get_geom { (RoundedRect) prmessage /radcorner current_radcorner store {newpath radcorner x0 y0 x y myrrectpath (dX, dY : %, %) [x y ] sprintf prvalue } getrectthing } def classend def /path_action{ Cancel? {% animate_event RightButton eq RecordEvents? {[0 0] /Stop /AlphaEvent MakeEventToRecord AddEvent} if exit } if animate_event LeftMouseButton eq { aload pop /Y1 exch store /X1 exch store tmparray Ntmp [X1 Y1] put /Ntmp Ntmp 1 add store /X2 X1 store /Y2 Y1 store } if animate_event MiddleMouseButton eq {Ntmp 0 gt {/Ntmp Ntmp 1 sub store Ntmp 0 gt { tmparray Ntmp 1 sub get aload pop} {0 0} ifelse /Y2 exch store /X2 exch store} if} if } def /get_path {%ask a path to the user; path terminated by right button; %point entered with left and suppressed with middle %path put in tmparray as [ [x1,y1],.... ] , Ntmp elements %first point -origin - in X0, Y0, all xi,yi relative to origin (enter points with Left button, Right to stop, Middle to delete Last) prmessage mygetclick /Y0 exch store /X0 exch store %origin /Relative? true store gsave X0 Y0 translate /X2 0 store /Y2 0 store /Ntmp 0 store Cancel? not { %repeat { 0 0 { newpath 0 0 moveto tmparray 0 Ntmp getinterval {aload pop lineto} forall X2 Y2 moveto x y lineto stroke (Xr, Yr : %, %) [x y] sprintf prvalue } mygetanimated mark %x y mark 3 1 roll ] %[x y] path_action %add points, waits stop, record it if needed } loop } {/Abort? true store} ifelse grestore (% points path) [Ntmp] prmessage /Relative? false store } def /drawmark{ marksize 2 div neg dup rmoveto marksize dup rect} def /edit_path{%edit path of a polyline {newpath 0 0 moveto tmparray 0 Ntmp getinterval {aload pop lineto} forall Closed {closepath} if stroke x y moveto drawmark stroke } g_edit_path } def /outline_proc {} def /oldmarksize 0 def /Ne 0 def /g_edit_path{ %generic path edition %outline_proc => -; the outlining function %a path is in tmparray 0-Ntmp; %allows the user to edit %it by its moving points; %Left to select a point or insert a point % ; confirm move by Left click %Middle to delete a selected point %Right to stop /outline_proc exch store /oldmarksize marksize store /marksize marksize 2 mul store /Relative? true store gsave Sx Sy Angle X Y spos /X2 0 store /Y2 0 store { %select point to move %equivalent to a getclick but with the good outlining function 0 0 {outline_proc} mygetanimated %x y Cancel? {pop pop RecordEvents? {[0 0 ] /Stop /AlphaEvent MakeEventToRecord AddEvent} if exit } if /Y1 exch store /X1 exch store animate_event LeftMouseButton eq {%try to find a point or a segment X1 Y1 findpointofpath %0 nothing, 1 a point, 2 a seg pop fstatus 1 eq %a point is selected {/Ne exch store tmparray Ne get aload pop /Y2 exch store /X2 exch store (point selected -- move or delete it) prmessage 0 0 {tmparray Ne [x y] put outline_proc} mygetanimated 2 array astore %[x y] Cancel? {tmparray Ne [X2 Y2] put} if animate_event MiddleMouseButton eq {delete_point} if } if fstatus 2 eq %a point on a seg {/Ne exch store %seg start point index [X1 Y1] add_point /Ne Ne 1 add store (new point inserted -- move it) prmessage 0 0 {tmparray Ne [x y] put outline_proc} mygetanimated 2 array astore % [x y] Cancel? animate_event MiddleMouseButton eq or {delete_point} if } if fstatus 0 eq { (point or seg not found) prmessage pop } if } if } loop grestore /marksize oldmarksize store /Relative? false store } def /add_point{% [x y] => - ;adds a point in tmparray at position found in Ne tmparray Ne 2 add %shift 1 in tmp tmparray Ne 1 add Ntmp Ne sub 1 sub getinterval putinterval tmparray exch Ne 1 add exch put /Ntmp Ntmp 1 add store } def /delete_point{% Ne is the index of the point to delete (point deleted) prmessage tmparray Ne %shift 1 left tmparray Ne 1 add Ntmp Ne sub 1 sub getinterval putinterval /Ntmp Ntmp 1 sub store } def /fstatus 0 def /findpointofpath{% X Y => pointindex 1 | startsegindex 2 | 0 /fstatus 0 store 0 1 Ntmp 1 sub {dup tmparray exch get aload pop %x y n x1 y1 3 index sub abs 3 lt exch %x y n b1 x1 4 index sub abs 3 lt %x y n b1 b2 and {/N exch store /fstatus 1 store exit } {%if not last point try if on a seg %x y n /N exch store N Ntmp 1 sub lt { 2 copy tmparray N get aload pop %x y x1 y1 tmparray N 1 add get aload pop % ... x2 y2 is_on_segment {/fstatus 2 store exit} if } if } ifelse } for pop pop fstatus 0 eq {fstatus} {N fstatus} ifelse } def /outline_curve{ newpath 0 0 moveto /N 1 store /Xc 0 store /Yc 0 store tmparray 0 Ntmp getinterval {aload pop %x y N 3 eq {gsave Xc Yc moveto 2 copy /Yc exch store /Xc exch store curveto /N 1 store stroke grestore Xc Yc moveto} { 2 copy lineto /N N 1 add store} ifelse} forall } def /edit_curved_path{ {outline_curve stroke x y moveto drawmark stroke} g_edit_path } def /get_curved_path {%ask a path to the user; path terminated by double-clicking %last point; %path put in tmparray as [ [x1,y1],.... ] , Ntmp elements %first point -origin - in X0, Y0, all xi,yi relative to origin %get points until two points are equal (enter first point : ) prmessage mygetclick /Y0 exch store /X0 exch store %origin /Relative? true store gsave (enter points 3 by 3 - Right button to end, Middle to delete Last) prmessage X0 Y0 translate /X2 0 store /Y2 0 store /Ntmp 0 store /N 1 store Cancel? not { %repeat { 0 0 { outline_curve X2 Y2 moveto x y lineto stroke (Xr, Yr : %, %) [x y] sprintf prvalue} mygetanimated 2 array astore %[x y] path_action } loop /Ntmp Ntmp Ntmp 3 mod sub store %Ntmp a multiple of 4 } {/Abort? true store} ifelse grestore (% curves path) [ Ntmp 3 div ] prmessage /Relative? false store } def (Polyline \n) printdbg /Polyline DrawObject dictbegin /Npoint 0 def %nbre de points /Closed false def %if true -> polygon /arrowsize 5 def /startarrow? false def /endarrow? false def dictend classbegin /new { /new super send begin currentdict end } def /setarrowsize{ /arrowsize exch store} def /setarrow{% [start? end?] aload pop /endarrow? exch store /startarrow? exch store } def /getcurrentdisplayparam{ /getcurrentdisplayparam super send /arrowsize current_arrowsize store /startarrow? current_startarrow? store /endarrow? current_endarrow? store } def /saveivar{ /saveivar super send OSfile ( % % % % % \n ) [Npoint Closed arrowsize startarrow? endarrow? ] fprintf } def /loadivar{ /endarrow? exch store /startarrow? exch store /arrowsize exch store /Closed exch store /Npoint exch store /loadivar super send } def /make_path {%the path coord relative to 0,0 are stored in an array in geom geom null ne { spos newpath 0 0 moveto geom {aload pop lineto} forall Closed {closepath} if } if } def /make_path_ps{ geom null ne { PSfile (spos newpath 0 0 moveto \n) [] fprintf geom {PSfile exch ( % % lineto \n) exch fprintf} forall Closed {PSfile ( closepath\n) [] fprintf} if } if } def /dr { gsave setdashpat setlinecap setlinejoin Sx Sy Angle X Y /make_path self send dup -1 ne {gsave setgray fill grestore} {pop} ifelse setgray setlinewidth stroke startarrow? {arrowsize geom 0 get aload pop 0 0 drarrow} if endarrow? {arrowsize Npoint 1 eq {0 0} {geom Npoint 2 sub get aload pop} ifelse geom Npoint 1 sub get aload pop drarrow} if grestore } def /dr_ps {% color => - PSfile (gsave setdashpat setlinecap setlinejoin % % % % %\n) [Sx Sy Angle X Y] fprintf /make_path_ps self send -1 ne { PSfile ( gsave setgray fill grestore ) [] fprintf} {PSfile ( pop ) [] fprintf} ifelse PSfile (setgray setlinewidth stroke \n) [] fprintf startarrow? { PSfile ( % % % % % drarrow\n) [arrowsize geom 0 get aload pop 0 0 ] fprintf} if endarrow? { PSfile ( % % % % % drarrow\n) [arrowsize Npoint 1 eq {0 0} {geom Npoint 2 sub get aload pop} ifelse geom Npoint 1 sub get aload pop] fprintf} if PSfile ( grestore\n) [] fprintf } def /BoxSize {%if it is a segment than 0 Npoint 1 le {0} {/BoxSize super send} ifelse } def /is_in_obj {% x y => bool ; problem with pointinpath;; % seems to crash the news_server (unexpected sigsegv signal...) geom null eq {pop pop false} { Npoint 1 gt %x y b 2 index 2 index /is_in_box self send not and %not a line and not in box {pop pop false} {gsave newpath moveto X Y translate Angle rotate Sx Sy scale % {} {} {} {} pathforall %x y in object coord. sys. Npoint 1 le %we have a line segment {0 0 geom 0 get aload pop %x y 0 0 x1 y1 is_on_segment} { 1 1 0 0 0 /make_path self send Closed not {closepath} if pointinpath } ifelse grestore} ifelse } ifelse } def /scale_geom { %sx sy => - 2 copy max arrowsize mul /arrowsize exch store mtrx0 currentmatrix pop gsave 0 0 0 /make_path self send %path mtrx0 setmatrix %path is scaled /N 0 store {pop pop} { %x y geom N get astore pop /N N 1 add store} {} {} pathforall grestore } def /i_get_geom { get_path %path introduced by user in tmparray; X0 Y0 tmparray 0 Ntmp getinterval %x y [array of [xi yi] ] on stack Ntmp 0 eq {/Abort? true store} if } def /edit_proc {edit_path} def /edit_geom {%interactive edition of geom (select point of line and move it -- end with Right button) prmessage /erase self send /oldcanvas currentcanvas store setoverlay /crosshair? true store /Ntmp Npoint store tmparray 0 geom putinterval /edit_proc self send oldcanvas setcanvas geom null ne {/erase self send} if tmparray 0 Ntmp getinterval /set_geom self send geom null ne { /make_bbox self send /display self send} if /crosshair? false store } def /set_geom { %[ [x1 y1] [x2 y2] ... ] => - dup length array /geom exch store geom copy length /Npoint exch store } def /save_geom{% OSfile ([ %polyg. geom\n) writestring geom {OSfile exch ( [ % % ] ) exch fprintf} forall OSfile ( ] %end of polyg. geom\n) writestring } def /clone_geom { %here the geom is an array of array geom type (arraytype) eq {/newarray geom length array store /N 0 store geom {2 array copy newarray exch N exch put /N N 1 add store} forall /geom newarray store} if /newarray 4 array store bbox newarray copy /bbox exch store } def classend def (Curve \n) printdbg /Curve Polyline dictbegin /iter 1 def dictend classbegin /new { /new super send begin currentdict end } def /make_path {%the path coord relative to 0,0 are stored in an array in geom geom null ne { spos % translate rotate scale newpath 0 0 moveto /iter 1 def geom { aload pop iter 3 eq {curveto /iter 1 store } {/iter iter 1 add store} ifelse } forall Closed {closepath} if } if } def /make_path_ps {%the path coord relative to 0,0 are stored in an array in geom geom null ne { PSfile (spos newpath 0 0 moveto\n) [] fprintf /iter 1 def geom { PSfile exch ( % % ) exch fprintf % aload pop iter 3 eq { PSfile ( curveto\n) [] fprintf /iter 1 store } {/iter iter 1 add store} ifelse } forall Closed {PSfile ( closepath\n) [] fprintf} if } if } def /scale_geom { %sx sy => - mtrx0 currentmatrix pop gsave 0 0 0 /make_path super send %path mtrx0 setmatrix %path is scaled /N 0 store {pop pop} { %x y geom N get astore pop /N N 1 add store} {} {} pathforall grestore } def /edit_proc {edit_curved_path /Ntmp Ntmp Ntmp 3 mod sub store %Ntmp a multiple of 4 } def /i_get_geom { get_curved_path %path introduced by user in tmparray; X0 Y0 tmparray 0 Ntmp getinterval %x y [array of [xi yi] ] on stack Ntmp 0 eq {/Abort? true store} if } def classend def /FontName /Times-Roman def /pointsize 30 def (Text\n) printdbg /TextObject DrawObject dictbegin /Fontname FontName def /Size pointsize def /font null def /Sh 0 def %the height, width of the box enclosing the /Sw 0 def %string in global coord. sys. (non scaled and non rot.) dictend classbegin /new { /new super send begin currentdict end } def /init{ /init super send /Fontname FontName store /Size pointsize store /color 0 store %black } def /saveivar{ /saveivar super send OSfile (/% % % %) [Fontname Size Sh Sw] fprintf } def /loadivar{ /Sw exch store /Sh exch store /Size exch store /Fontname exch store /loadivar super send } def /save_geom{ OSfile ( \() writestring OSfile geom writestring OSfile (\) \n) writestring } def /make_font {% sets the font entry /font Fontname findfont Size scalefont store} def /set_font_and_size {% /fontname size => /Size exch def /Fontname exch def /make_font self send} def /changefont{ % FontName -- change the font /Fontname exch store } def /changefontsize{% change font size -- font size /Size exch store } def /make_path { geom null ne { spos Fontname findfont Size scalefont setfont newpath 0 0 moveto geom show } if } def /make_path_ps { geom null ne { PSfile (spos\n) [] fprintf PSfile ( /% findfont % scalefont setfont\n) [Fontname Size] fprintf PSfile (newpath 0 0 moveto (%) show\n) [geom] fprintf } if } def /is_in_obj { /is_in_box self send} def /dr {% linewidth linecolor color linejoin linecap linestyle => - only %color is important gsave pop pop pop setgray pop pop Sx Sy Angle X Y /make_path self send grestore } def /dr_ps{ PSfile (gsave pop pop pop setgray pop pop % % % % % \n) [Sx Sy Angle X Y] fprintf /make_path_ps self send PSfile (grestore\n) writestring } def /make_bbox{ %there seems to be problem with charpath and rotation; %therefore finds the box and draws it in the object coord. %system and extracts its bbox in the current coord. syst geom null ne { gsave mtrx0 currentmatrix pop Fontname findfont Size scalefont setfont 0 0 moveto geom stringbbox %here we have the box x,y,w,h 2 copy /Sh exch store /Sw exch store X Y translate Angle rotate Sx Sy scale 0 0 moveto rect pop pop mtrx0 setmatrix pathbbox bbox astore pop grestore} if } def /make_opath{ spos 0 0 moveto Sw Sh rect} def /scale_geom { %sx sy % max Size mul /Size exch store /Sy exch store /Sx exch store } def /i_get_geom {%the string is in textstring; (Text) prmessage 0 0 {newpath Sx Sy Angle x y gsave /geom get_textstring store /make_path self send grestore } mygetanimated % x y Cancel? {null /Abort true store} {/geom get_textstring length string store get_textstring geom copy } ifelse } def /edit_geom {%interactive edition of geom (Edit Text) prmessage /erase self send /oldcanvas currentcanvas store setoverlay items /textstring get /ItemValue geom geom length string copy put geom %oldgeom 0 0 {newpath Sx Sy Angle X Y gsave /geom get_textstring store /make_path self send grestore } mygetanimated %x y Cancel? {/geom exch store} {pop /geom get_textstring length string store get_textstring geom copy } ifelse oldcanvas setcanvas geom null ne { /make_bbox self send /display self send} if } def classend def (PostScriptImport\n) printdbg %the local bbox of the object is stored in the geom variable /alreadyimporteddict 50 dict def %for each imported file, we will have % /procname [ codearray filename ] /savefname null def /SaveImportedFiles {% OSfile (alreadyimporteddict begin \n) writestring alreadyimporteddict {% key [ code filename ] exch OSfile exch (/% [ { \n) exch [ exch procstr cvs ] fprintf aload pop %code fname exch pop /savefname exch store % - (copying PS file ) savefname append prmessage savefname OSfile copytofile {(error in copying PS imported file ) prmessage} if %fname OSfile ( } \n) writestring OSfile ( (%) ) [ savefname] fprintf OSfile (\n ] def \n) writestring } forall OSfile (\n end \n) writestring } def /PSFileCycle{ % filename => bool ; true if filename is an already % imported PS file false alreadyimporteddict { %key, [ codearray filename ] exch pop % aload pop exch pop %filename false filename2 2 index eq { %filename false pop true exit} if From don@brillig.umd.edu Sat Jan 28 23:42:42 1989 Date: Sat, 28 Jan 89 23:42:42 EST To: NeWS-makers@brillig.umd.edu Subject: NeWSillustrator (part 4 of 5) From: mcvax!prlb2!bernard@uunet.uu.net (Bernard Yves) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) %--------------------------------------------------------------------- } forall exch pop } def %utilities /add_extension{% filename (.extension) => filename.extension exch %ext filename ( ) search %ext post match pre true { 4 -1 roll %post match pre ext 4 2 roll %pre ext post match pop pop append } { %ext pre exch append } ifelse } def /extract_fname{% /.../.../.../toto.xxx => toto.xxx { (/) search { % post match pre pop pop} {exit} ifelse } loop } def /make_wrappedfname{%filename => PWD/fname.wps (PWD) getenv (/) append exch extract_fname append (.wps) add_extension } def /achar 1 string def /linestring2 256 string def /make_procname{ % filename => - %from a filename make a postscript name %by repacing all / by a _ /N 0 store 0 1 linestring2 length 1 sub {linestring2 exch 32 put} for { achar 0 3 -1 roll put achar dup (/) eq {pop (_)} if %char or _ linestring2 N 3 -1 roll putinterval /N N 1 add store } forall linestring2 ( ) search pop %post match pre 3 1 roll pop pop cvn } def /linestring 256 string def /TmpFile null def /PS2file null def /errorstring 30 string def /copytofile{% filename file => bool ; true if error exch %file filename { (r) file /TmpFile exch store % file { dup % file file TmpFile linestring readline % file file subst bool {writestring % file dup (\n) writestring % file } {pop exit} ifelse } loop TmpFile closefile } stopped dup {get_errorstr} if } def /get_errorstr{%gets current errorname and puts it in errorstring $error begin errorname end errorstring cvs pop } def /fileerrorpr{% operation filename => - %print last file error message exch (file error : ) errorstring append exch append exch append prerror } def /FileExist? {% filename => true | false { (r) file} stopped {false} {closefile true} ifelse } def /PostScript DrawObject dictbegin /drawproc nullproc def %the drawing code; any legal ps? /filename 100 string def %the imported file /privatedict2 null def /procname null def /savemtrx null def /RedisplayIfScroll {} def dictend classbegin /new { /new super send begin currentdict end } def /init{ /init super send % /geom 4 array store /privatedict2 50 dict store %a private dict for drawproc def and store /savemtrx matrix store } def /clone_geom{ /clone_geom super send privatedict2 50 dict copy /privatedict2 exch store } def /display{%drawing param are set; it is the responsability %of the drawing proc to reset them to its own values savemtrx currentmatrix pop gsave Sx Sy Angle X Y spos geom 0 get neg geom 1 get neg translate linewidth setlinewidth linecolor setgray linecap setlinecap linejoin setlinejoin linestyle setdashpat mark privatedict2 begin drawproc end cleartomark grestore savemtrx setmatrix } def /display_ps {%for each imported file a procedure / is %defined and called procname null eq {/procname filename make_procname store} if importfiledict procname known not {% the procedure is not yet defined in the ps file %procname procname self /drawproc get length 300 lt { PSfile (\n/%{\n) [ procname ] fprintf filename PSfile copytofile pop %procname PSfile (\n} def\n) writestring importfiledict procname 1 put %procname } if %if the proc is too long %do not create a proc, but write %the imported file each time it is needed } if PSfile (savemtrx currentmatrix pop gsave % % % % % spos % % translate\n) [Sx Sy Angle X Y geom 0 get neg geom 1 get neg] fprintf PSfile (% % % % % setdashpat setlinejoin setlinecap setgray setlinewidth\n) [linewidth linecolor linecap linejoin linestyle] fprintf self /drawproc get length 300 lt {PSfile (mark privatedict begin % end cleartomark grestore savemtrx setmatrix\n) [procname] fprintf } {PSfile (mark privatedict begin\n) writestring filename PSfile copytofile pop PSfile (end cleartomark grestore savemtrx setmatrix\n) writestring } ifelse } def /scale_geom{ Sy mul /Sy exch store Sx mul /Sx exch store } def /make_opath{%draws the local bbox spos % geom 0 get geom 1 get moveto 0 0 moveto geom 2 get geom 0 get sub geom 3 get geom 1 get sub rect } def /make_path{ /make_opath self send} def %will be used in is_in_obj; /erase{%erases the local bounding box gsave 1 setgray Sx Sy Angle X Y make_opath fill grestore } def /make_bbox{%computes the global bbox gsave mtrx0 currentmatrix pop Sx Sy Angle X Y /make_opath self send mtrx0 setmatrix pathbbox bbox astore pop grestore } def /load_drawproc{ % - => bool; true if ok; %if not already made, makes the wrapped file and loads it %the wrapped file is created in the user Home directory %with the same name as the user file and *.wps as extension /procname filename make_procname store alreadyimporteddict procname known %the dict entry contains the Postscript object %for which the corresponding drawproc has been defined {/drawproc alreadyimporteddict procname get aload pop pop def true } {%the PS file is not yet loaded /PS2file filename make_wrappedfname (w) file store PS2file (/drawproc{ \n) writestring filename PS2file copytofile %copies filename to the %end of PS2file {%error in copying file false PS2file closefile } {%close it and load it to define /drawproc PS2file (\n} def \n) writestring PS2file closefile (loading wrapped file ) filename make_wrappedfname append prmessage filename make_wrappedfname LoadFile dup {alreadyimporteddict procname [/drawproc load filename ] put} if } ifelse } ifelse } def /i_get_geom{ %reads the imported filename * and loads it %makes a 'wrapped' file *.wps %where the ps code is embedded : /drawproc{ } def %then loads it with LoadFile (Import PostScript) prmessage /filename get_ps_filename dup length string copy store filename extract_fname length 0 gt { (making wrapped file ) filename make_wrappedfname append prmessage /load_drawproc self send %true if ok; { (enter the bounding box : ) prmessage currentcanvas %the overlay canvas oldcanvas setcanvas %the win canvas /X0 0 store /Y0 0 store /RedisplayIfScroll {gsave 0 0 translate savemtrx currentmatrix pop gsave mark privatedict2 begin drawproc end cleartomark grestore savemtrx setmatrix grestore } store /ThisObj self store /RedisplayWhenScroll { {RedisplayIfScroll} ThisObj send } store {RedisplayIfScroll} stopped {(error in executing PS file ) filename append prerror setcanvas 0 0 null } { setcanvas %reset the overlay mygetwholerect %[x y w h] aload pop %x1 y1 w h 2 index add %x1 y1 w y2 exch 3 index add %x1 y1 y2 x2 exch 3 index 3 index %x1 y1 x2 y2 x1 y1 6 2 roll 4 array astore %x1 y1 box (PS file imported: ) filename append prmessage } ifelse } {( in loading ) filename fileerrorpr 0 0 null } ifelse } {( in loading ) filename fileerrorpr 0 0 null } ifelse /RedisplayWhenScroll {} store }def /save_geom{ OSfile ( [ % % % % ] \n) geom fprintf} def /saveivar{ /saveivar super send OSfile ( \() writestring OSfile filename writestring OSfile (\) \n) writestring } def /loadivar{ /filename exch store mark /load_drawproc self send {} %ok {(error in importing) filename append prerror)} ifelse cleartomark /loadivar super send } def classend def %building of an A4 size rectangle /a4rect /new DrawObject send def { /X 100 35 div 3 mul def /Y 100 35 div 3 mul def /geom [100 35 div 197 mul 100 35 div 282 mul] def /linecolor .85 def /linewidth 2 def /ingroup true def %so that it is not selectable by user; } a4rect send %============================================================================= %drawing area window definition %=========================================================================== %/win framebuffer /new ScrollAndZoomWindow send def (main interaction routines\n) printdbg /previous_selection null def /current_selection null def /old_selection null def /push_selection{% obj /previous_selection current_selection store /current_selection exch store } def /pop_selection{% /current_selection previous_selection store /previous_selection null store } def /ClosedPath? false def /create_object {%class => obj {ClientCanvas} win send setcanvas /new exch send push_selection % /current_selection exch store ClosedPath? {current_selection begin /Closed true store end /ClosedPath? false store} if /i_def_geom current_selection send current_selection begin geom end null ne {current_selection AddObject} {pop_selection} ifelse } def /foundlist 100 array def /Nfound 0 def /MaxBoxSize 0 def /find_object_on_pt {%x y => obj | null %only objects which are not in a group can be found /Y0 exch store /X0 exch store /Xc null store /Yc null store /Nfound 0 store ObjTable 0 Nobj getinterval { /Xc exch store Xc null ne {Xc begin ingroup end not {X0 Y0 /is_in_obj Xc send { foundlist Nfound Xc put /Nfound Nfound 1 add store } if} if} if} forall Nfound 0 eq { null} { /MaxBoxSize 10000000 store foundlist 0 Nfound getinterval { /Xc exch store /BoxSize Xc send dup MaxBoxSize le {/Yc Xc store /MaxBoxSize exch store MaxBoxSize 0 eq {exit} if} {pop} ifelse } forall Yc } ifelse } def /find_objects_in_box {% [x1 y1 x2 y2] => o1 o2.... on n /b1 exch store /N 0 def ObjTable 0 Nobj getinterval { /Xc exch store Xc null ne {Xc begin ingroup end not {Xc begin bbox end b1 box_in_box {Xc /N N 1 add store} if} if} if} forall N } def /select_object { {ClientCanvas} win send setcanvas gsave /oldcanvas currentcanvas store (select object by clicking on it : ) prmessage setoverlay getclickwithmenu oldcanvas setcanvas find_object_on_pt grestore dup null ne {dup /erase exch send push_selection pause /display current_selection send current_selection begin [tableindex] end (% is selected) exch prmessage /getclassname current_selection send /Group ne {/update_control_panel current_selection send} if } {pop (no object selected) prmessage} ifelse } def /i1 0 def /i2 0 def /swap_obj{ % o1 o2 => - ; swaps the 2 obj in ObjTable; dup begin /i2 tableindex store end exch dup begin /i1 tableindex store end %o2 o1 dup begin /tableindex i2 store end ObjTable exch i2 exch put dup begin /tableindex i1 store end ObjTable exch i1 exch put (% and % swapped) [i1 i2] prmessage } def /find_overlapping_obj{ % fromindex step toindex obj => first_over_obj %obj in X1, overlap in Xc /X1 exch store /Xc null store {ObjTable exch get dup /X2 exch store null ne {X2 begin ingroup end not {X1 begin bbox end X2 begin bbox end overlapping_box {/Xc X2 store exit} if } if } if } for Xc } def /move_down{ % obj => obj2 ; invert position of obj in ObjTable with % the next object behind it overlapping it dup begin tableindex end 1 sub -1 0 4 -1 roll find_overlapping_obj dup null ne {X1 Xc swap_obj} if } def /move_up{ % obj => obj2 ; invert position of obj in ObjTable with % the next object over it overlapping it obj2 dup begin tableindex end 1 add 1 Nobj 1 sub 4 -1 roll find_overlapping_obj dup null ne {X1 Xc swap_obj} if } def /apply_on_sel {% proc => - ; apply proc on selection if non null current_selection null ne {{ClientCanvas} win send setcanvas exec } {pop (no object selected !) prmessage} ifelse } def /fapply_on_sel{% /message -> apply it on current selection current_selection dup null ne %/message obj {{ClientCanvas} win send setcanvas send } {pop pop (no object selected !) prmessage} ifelse } def /notifyselection true def /setdpar {% value /paramfunct => - ; %apply change of param on selection if non null 2 copy %arg1 arg2 arg1 arg2 current_selection null ne notifyselection and {{ClientCanvas} win send setcanvas {self send} /change_geom current_selection send pop pop } {pop pop } ifelse } def /fontmenu [ FontDirectory { % include all fonts except /Cursor pop dup /Cursor ne { 25 string cvs dup length 3 le { pop } if } { pop } ifelse } forall ] [{/FontName currentkey store FontName /changefont setdpar} ] /new DefaultMenu send def /pointsizemenu [( 6 ) (8) (10) (12) (14) (16) (18) (24) (30) (32) (64)] [{/pointsize currentkey cvi store pointsize /changefontsize setdpar} ] /new DefaultMenu send def /filemenu [ (save PS file) {generate_ps} (------) {} (save Objects file) {generate_os} (load Objects file) {load_osfile} (------) {} (save Tools file) {SaveTools} (load Tools file) {LoadToolFile} (------) {} (Windows Pos.) {WindowPositions} (Info) {CopyrightNotice prmessage {ClientCanvas} win send setcanvas} ] /new DefaultMenu send def /CopyrightNotice (NeWSillustrator 1.0.p, jan 89, Yves Bernard, Philips Research Lab, Brussels) def /align_op{%align_proc => - current_selection null ne {{ClientCanvas} win send setcanvas /getclassname current_selection send /Group eq {/change_geom current_selection send} if } {pop (no group object selected !) prmessage} ifelse } def /clipped_obj null def /clipping_obj null def /make_clip{%the current selection contains the clipping object %the previous selection should contain the object to clip current_selection null eq previous_selection null eq or {(error : no objects for making clip) prerror} { /clipped_obj previous_selection store /getclassname current_selection send dup /Group ne %class b 1 index /TextObject ne and %class b 1 index /PostScript ne and %class b exch pop { /clipping_obj current_selection store /erase clipped_obj send /new ClippingGroup send push_selection [clipping_obj clipped_obj] /set_geom current_selection send /make_bbox current_selection send /display current_selection send current_selection AddObject } { (error : the clipping obj can not be a group, a text or an importPS) prerror } ifelse } ifelse } def /psfilename null def /get_ps_filename{ items /psfilename get /ItemValue get} def /notifypsfname{ /psfilename ItemValue store} def /ConfirmWriteFile? {% filename FileExist? {(Overwrite Existing File ?? ) Confirm?} {true} ifelse } def /PSfile null def /generate_ps { {ClientCanvas} win send setcanvas get_ps_filename PSFileCycle not { get_ps_filename ConfirmWriteFile? { {get_ps_filename (w) file /PSfile exch store (writing PS file...) prmessage RepaintAll_ps PSfile closefile} stopped {get_errorstr ( in writing ) get_ps_filename fileerrorpr} {(PS file is written: ) get_ps_filename append prmessage} ifelse } {(writing aborted...) prmessage} ifelse } {(can not write PS file: cycle,same name as an imported PS file ) get_ps_filename append prerror } ifelse } def /osfilename null def /get_os_filename{ items /osfilename get /ItemValue get} def /notifyosfname{ /osfilename ItemValue store} def /saveproc null def /GenericSave{% proc => -; to file OSfile /saveproc exch store get_os_filename ConfirmWriteFile? { { /OSfile get_os_filename (w) file store /procfile OSfile store saveproc OSfile (\n) writestring OSfile closefile } stopped {get_errorstr ( in writing ) get_os_filename fileerrorpr} {(file is written) prmessage} ifelse } if } def /OSfile null def /generate_os { {ClientCanvas} win send setcanvas {(writing object files...) prmessage SaveImportedFiles SaveAllObjects} GenericSave } def /load_osfile{ {ClientCanvas} win send setcanvas (loading...) prmessage get_os_filename LoadFile {(Object file loaded: ) get_os_filename append prmessage /PaintClient win send } {get_errorstr ( in loading ) get_os_filename fileerrorpr} ifelse } def %============================================================================ %control panel window definition %============================================================================ (Control Panel definition\n) printdbg systemdict /Item known not { (NeWS/liteitem.ps) run } if %systemdict /Item known not { (NeWS/liteitem.ps) LoadFile pop } if /notify? true def /notify { notify? {(Notify: Value=%) [ItemValue] /printf messages send} if } def /FillColor .75 def /prmessage { % sting => - print messages in Control Panel gsave /printf messages send grestore } def /prerror { % sting => - print messages in Control Panel gsave /printf errormessage send grestore } def /prvalue { % string => - print in Control Panel gsave /printf valuemessage send grestore } def /recstr 30 string def /notifylq {ItemValue 10 div setlinequality} def /ParValue 0 def /notifylw {ItemValue /setlinewidth2 setdpar} def /notifylc {ItemValue 100 div /setlinecolor setdpar} def /notifyfc {ItemValue 0 lt {-1} {ItemValue 100 div} ifelse /setcolor setdpar} def /notifygroupdefmode {/group_def_mode ItemValue 0 eq (by box) (by enumeration) ifelse store } def /notifylcap{ItemValue /setlinecap2 setdpar} def /notifyljoin{ItemValue /setlinejoin2 setdpar} def /notifylstyle{ItemValue /setlinestyle setdpar} def /notifyarrowsize{ItemValue cvr /setarrowsize setdpar} def /arrowstartend? { % - => startarrow endarrow ParValue 0 eq {false false} if ParValue 1 eq {true false} if ParValue 2 eq {false true} if ParValue 3 eq {true true} if } def /Pend false def /Pstart false def /notifylarrow{/ParValue ItemValue store arrowstartend? /Pend exch store /Pstart exch store [Pstart Pend] /setarrow setdpar} def /notifyradcorner {ItemValue cvr dup 0 eq {pop 8} if /setradcorner setdpar} def /textstring (enter string) def /notifytext{/textstring ItemValue store} def /gridon false def /gridsize 100 def /notifygridsize {/gridsize ItemValue cvr dup 0 eq {pop 100} if store} def /notifysnap {/SnapToGrid? ItemValue 1 eq store } def /updateCPitem{% newvalue /name items exch get %newvalue it dup 2 index /ItemValue exch put %v it exch pop /paint exch send } def /ClickToMove? false def /xoff 0 def /yoff 0 def /notifyclicktomove{/ClickToMove? ItemValue 1 eq store} def /notifygridon {/gridon ItemValue 1 eq store gridon {{ClientCanvas} win send setcanvas draw_grid} {/PaintClient win send} ifelse } def /get_textstring{%gets the ItemValue of the text liteitem items /textstring get /ItemValue get dup /textstring exch store } def /notifyalphadata {} def /draw_grid{% draws the grid gridon gridsize 0 gt and {gsave 0 setgray [2 5] 0 setdash 0 gridsize 1000 {dup 0 moveto 1000 lineto stroke} for 0 gridsize 1000 {dup 0 exch moveto 1000 exch lineto stroke} for grestore} if } def /putinControlPanel{%linewidth linecolor color linestyle linejoin linecap /notifyselection false store /oldcanvas currentcanvas store {ClientCanvas} controlpanel send setcanvas items begin linecap /ItemValue 3 -1 roll put /paint linecap send linejoin /ItemValue 3 -1 roll put /paint linejoin send linestyle /ItemValue 3 -1 roll put /paint linestyle send dup -1 ne {100 mul} if fillcolor /ItemValue 3 -1 roll put /paint fillcolor send 100 mul linecolor /ItemValue 3 -1 roll put /paint linecolor send linewidth /ItemValue 3 -1 roll put /paint linewidth send end oldcanvas setcanvas pause /notifyselection true store } def /setcurrentdisplayparam{%set control parameters as default items begin linecap /ItemValue get /current_linecap exch store linejoin /ItemValue get /current_linejoin exch store linestyle /ItemValue get /current_linestyle exch store fillcolor /ItemValue get dup 0 lt {pop -1} {100 div} ifelse /current_fill exch store linecolor /ItemValue get 100 div /current_linecolor exch store linewidth /ItemValue get /current_linewidth exch store arrowsize /ItemValue get cvr /current_arrowsize exch store linearrow /ItemValue get /ParValue exch store arrowstartend? /current_arrowend? exch store /current_arrowstart? exch store end } def %Items creation /createitems { /items 30 dict dup begin /messages /panel_text () /Right {} can 700 0 /new MessageItem send dup begin /ItemFrame 1 def /ItemBorder 4 def end 20 20 /move 3 index send def /value /panel_text () /Right {} can 700 0 /new MessageItem send dup begin /ItemFrame 1 def /ItemBorder 4 def end 20 0 /move 3 index send def /errormessage /panel_text () /Right {} can 700 0 /new MessageItem send dup begin /ItemFrame 1 def /ItemBorder 4 def end 20 -20 /move 3 index send def /textstring (Text String:) (Text string) /Right /notifytext can 500 0 /new TextItem send 20 290 /move 3 index send def /osfilename (Objects file name:) (PWD) getenv (/) append /Right /notifyosfname can 500 0 /new TextItem send 20 260 /move 3 index send def /psfilename (PS file name:) (PWD) getenv (/) append /Right /notifypsfname can 500 0 /new TextItem send 20 230 /move 3 index send def /gridsize (Grid Size:) (100) /Right /notifygridsize can 220 0 /new TextItem send 20 200 /move 3 index send def /gridbutton (Grid on:) [/panel_check_off /panel_check_on] /Right /notifygridon can 0 0 /new CycleItem send dup /LabelY -4 put 250 200 /move 3 index send def /SnapToGrid? (Snap To Grid:) [/panel_check_off /panel_check_on] /Right /notifysnap can 0 0 /new CycleItem send dup /LabelY -4 put 355 200 /move 3 index send def /linequality (line quality:) [0 10 10] /Right /notifylq can 220 20 /new SliderItem send 20 170 /move 3 index send def /linecap (line cap:) [(butt) (round) (square) ] /Right /notifylcap can 0 0 /new CycleItem send 250 140 /move 3 index send def /linejoin (line join:) [(miter) (round) (belevel) ] /Right /notifyljoin can 0 0 /new CycleItem send 355 170 /move 3 index send def /linestyle (line style:) [(plain) (dash1) (dash2) ] /Right /notifylstyle can 0 0 /new CycleItem send 250 170 /move 3 index send def /linearrow (line arrow:) [(no) (at start) (at end) (at start and end) ] /Right /notifylarrow can 0 0 /new CycleItem send 355 140 /move 3 index send def /linewidth (line width:) [0 10 0] /Right /notifylw can 220 20 /new SliderItem send dup /ItemFrame 1 put 20 140 /move 3 index send def /linecolor (line color:) [0 100 0] /Right /notifylc can 220 20 /new SliderItem send dup /ItemFrame 1 put 20 110 /move 3 index send def /fillcolor (fill color:) [-1 100 -1] /Right /notifyfc can 220 20 /new SliderItem send dup /ItemFrame 1 put 20 80 /move 3 index send def /groupdef (Group Defined by :) [ ( box) ( enumeration) ] /Right /notifygroupdefmode can 220 0 /new CycleItem send 20 50 /move 3 index send def /radcorner (Rounded Corner Radius:) (8) /Right /notifyradcorner can 220 0 /new TextItem send 250 50 /move 3 index send def /arrowsize (Arrow Size :) (5) /Right /notifyarrowsize can 165 0 /new TextItem send 250 110 /move 3 index send def /ClickToMove? (Click To Move:) [/panel_check_off /panel_check_on] /Right /notifyclicktomove can 0 0 /new CycleItem send dup /LabelY -4 put 250 80 /move 3 index send def /alphadata (Data :) (arguments) /Right /notifyalphadata can 220 0 /new TextItem send 20 -50 /move 3 index send def /doitbutton (SendIt!) /SendAlphaEvent can 100 0 /new ButtonItem send dup /ItemBorderColor .5 .5 .5 rgbcolor put 130 -90 /move 3 index send def end def /messages items /messages get def /valuemessage items /value get def /errormessage items /errormessage get def } def /slideitem { % items fillcolor item => - gsave dup 4 1 roll % item items fillcolor item /moveinteractive exch send % item /bbox exch send % x y w h (Item: x=%, y=%, w=%, h=% Canvas: w=%, h=%) [ 6 2 roll win begin FrameWidth FrameHeight end ] /printf messages send grestore } def /MakeControlPanel { % Create and size a window. The size is chosen to accommodate the % items we are creating. Right before we map the window, we ask the % user to reshape the window. This is atypical, but gets the items % positioned the way we want them. /controlpanel framebuffer /new MyWindowClass send def { /PaintClient {FillColor fillcanvas items paintitems} def /FrameLabel (NeWSillustrator - Control Panel) def /IconLabel (Control Panel) def /IconImage /galaxy def /ClientMenu [ (set as Default) {setcurrentdisplayparam} (White Background) {/FillColor 1 store /paintclient controlpanel send} (Light Background) {/FillColor .75 store /paintclient controlpanel send} (Medium Background) {/FillColor .50 store /paintclient controlpanel send} (Dark Background) {/FillColor .25 store /paintclient controlpanel send} (Black Background) {/FillColor 0 store /paintclient controlpanel send} ] /new DefaultMenu send def } controlpanel send 30 30 700 350 /reshape controlpanel send /can controlpanel /ClientCanvas get def % Create all the items. createitems % Create event manager to slide around the items. /slidemgr [ items { % key item exch pop dup /ItemCanvas get % item can MiddleMouseButton [items FillColor % item can name [ dict color 6 -1 roll /slideitem cvx] cvx % can name proc DownTransition % can name proc action 4 -1 roll eventmgrinterest % interest } forall ] forkeventmgr def ControlPanelPosition null eq {/reshapefromuser controlpanel send } {ControlPanelPosition aload pop /reshape controlpanel send} ifelse /map controlpanel send /itemmgr items forkitems def } def 1 setlinequality /make_bbox a4rect send %------------------------------------------------------------------------- % Iconic command window or Tool Palette %------------------------------------------------------------------------- (CommandObj Class\n) printdbg /CommandObj Group %a command is a group ; the geom of the group is the icon of the command dictbegin /name null def /ident 0 def %use to identify command in macro /param null def /execproc nullproc def /undoproc {} def /repeatproc {} def /CanBeDefault? false def /kind /Standard def dictend classbegin /new { /new super send begin /CanBeDefault? false def currentdict end } def /display { gsave Sx Sy Angle X Y spos geom {/display exch send} forall grestore } def /execcommand {% /hilite self send pause {ClientCanvas} win send setcanvas execproc RepeatCommand self ne {/LastCommand self store /LastCommand? true store} if /deshilite self send } def /saveivar{% /saveivar super send OSfile (/%) [name] fprintf } def /loadivar{% /name exch def name null ne { CommandDict name self put} if %tool built from macro are not put in the commanddict /loadivar super send } def /saveobject{ OSfile (/new CommandObj send dup AddCommand mark\n) writestring /saveivar self send OSfile ( loadobj\n) writestring OSfile ({\n) writestring OSfile (/kind /% def\n) [kind] fprintf OSfile (/execproc \n) writestring /execproc load print_any OSfile ( def\n) writestring OSfile (/undoproc \n) writestring /undoproc load print_any OSfile ( def\n) writestring OSfile (/repeatproc \n) writestring /repeatproc load print_any OSfile ( def\n) writestring OSfile (/CanBeDefault? % def\n) [CanBeDefault?] fprintf OSfile (} topcom send\n) writestring } def /undo{ undoproc } def /borderpath{% bbox 0 get bbox 1 get moveto -7 -7 rmoveto bbox 2 get bbox 0 get sub 14 add %w bbox 3 get bbox 1 get sub 14 add rect } def /hilite{% when a command is selected, it is highlighted % by drawing a thick rect around it {ClientCanvas} CommandWindow send setcanvas gsave 0 setgray 4 setlinewidth /borderpath self send stroke grestore } def /deshilite{ {ClientCanvas} CommandWindow send setcanvas gsave 1 setgray 4 setlinewidth /borderpath self send stroke grestore } def classend def %/DefaultCommand select_command def /LastCommand null def /LastCommand? false def /CommandDict 100 dict def /CommandTable 100 array def /Ncommand 0 def /AddCommand {% => - dup CommandTable exch Ncommand exch put %obj begin /ident Ncommand store end /Ncommand Ncommand 1 add store } def (MakeNeWCommand\n) printdbg /NewComDict dictbegin /toolerror {(error: the valid expressions are: (1) (macroname) CallMacro (2) {PScode}) prerror } def /thenewcom null def /itscode null def /theGroup null def dictend def /MakeNewCommand{%makes a command from the current_selection if %it is a group; %ask the place in the tool palette and the code %for its exec proc NewComDict begin current_selection null ne { /getclassname current_selection send /Group eq { /itscode null store current_selection GroupToCommand /thenewcom exch store %ask the code (ok with this code: ) ConfirmText? {%parse it mark get_textstring {token {exch} {exit} ifelse} loop %codearray or (macroname) CallMacro { %case loop %mark {} or mark (name) /CallMacro counttomark 2 gt {toolerror exit} if dup type /nametype eq %macroname CallMacro {(macro call) prmessage dup /CallMacro eq %macroname CallMacro {exec /itscode exch store /itscode load 10 string cvs prvalue thenewcom begin /kind /MacroTool def end} {pop toolerror} ifelse exit} if %codearray dup type /arraytype eq 1 index xcheck and %mark {} {(code array) prmessage /itscode exch store itscode 10 string cvs prvalue exit } if %mark xxx pop } loop %mark -- itscode cleartomark /itscode load null ne {%save it and give position /itscode load thenewcom begin /execproc exch store end PlaceCommand theGroup begin ObjTable tableindex null put end /erase theGroup send (The tool is added) prmessage } {(tool creation aborted) prmessage /Ncommand Ncommand 1 sub store } ifelse } if %Confirm } {(command icons are made from group!!) prerror} ifelse } {(no selected object) prerror} ifelse end } def /PlaceCommand{% thenewcom => - place it on Tool Palette (place the icon in the tool palette -- click with any button) prmessage {ClientCanvas} CommandWindow send createoverlay setcanvas thenewcom begin bbox aload pop end %x1 y1 x2 y2 2 index sub %x1 y1 x2 h exch 3 index sub %x1 y1 h w /X2 exch store /Y2 exch store 0 0 {x y moveto X2 Y2 rect} getanimated waitprocess aload pop %x y thenewcom begin /Y exch store /X exch store end {ClientCanvas} CommandWindow send setcanvas /make_bbox thenewcom send /display thenewcom send {ClientCanvas} win send setcanvas } def /GroupToCommand {%group => command /theGroup exch store /new CommandObj send dup AddCommand /thenewcom exch store theGroup begin bbox X Y Angle geom Ngr end thenewcom begin /Ngr exch store /geom exch store /Angle exch store /Y exch store /X exch store /bbox exch store end thenewcom } def /SaveTools{% save new added tools in a file /saveobjprelude ( mark\n) store {(writing tool file...) prmessage CommandTable FirstUserCommand dup Ncommand exch sub getinterval {/saveobject exch send} forall } GenericSave } def /LoadToolFile{% (Loading tool file ) get_os_filename append ( ??) append Confirm? {get_os_filename LoadFile {(tool file loaded) prmessage pause {ClientCanvas} CommandWindow send setcanvas /PaintClient CommandWindow send } {(in loading) get_os_filename fileerrorpr} ifelse } if } def /DefComProcess null store /MakeDefComProcess{% DefComProcess null eq {/DefComProcess { newprocessgroup {/execcommand DefaultCommand send pause} loop } fork store pause } if } def /KillDefComProcess{ DefComProcess null ne { pause DefComProcess killprocessgroup pause /DefComProcess null store pause} if } def (Command Window\n) printdbg From don@brillig.umd.edu Sat Jan 28 23:47:30 1989 Date: Sat, 28 Jan 89 23:47:30 EST To: NeWS-makers@brillig.umd.edu Subject: NeWSillustrator (part 5 of 5) From: mcvax!prlb2!bernard@uunet.uu.net (Bernard Yves) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) %-------------------------------------------------------------------------------- /ConfirmText? {%message => bool get_textstring append ( ??) append Confirm? } def /CommandWinMenu [ (Redisplay) {/PaintClient CommandWindow send pause /PaintClient win send pause KillDefComProcess} (Zoom In) {/ZoomIn win send} (Zoom Out) {/ZoomOut win send} (----) {} (Font => ) fontmenu (FontSize => ) pointsizemenu (Files => ) filemenu (----) {} (Make Tool) {MakeNewCommand} ] /new DefaultMenu send def /MakeCommandWindow { /CommandWindow framebuffer /new MyWindowClass send def { /PaintClient { ClientCanvas setcanvas 1 fillcanvas CommandTable 0 Ncommand getinterval {/display exch send} forall pause pause DefaultCommand null ne {/hilite DefaultCommand send} if } def /ClientMenu CommandWinMenu def /FrameLabel (NeWSillustrator - Tools Palette) def /IconLabel (Tools) def } CommandWindow send ToolPalettePosition null eq {/reshapefromuser CommandWindow send} {ToolPalettePosition aload pop /reshape CommandWindow send} ifelse /map CommandWindow send {ClientCanvas} CommandWindow send setcanvas % Create event manager to select command. /selectmgr [ LeftMouseButton %a new command is selected { KillDefComProcess select_command %exec the selected com /hilite DefaultCommand send MakeDefComProcess} DownTransition {ClientCanvas} CommandWindow send eventmgrinterest % interest MiddleMouseButton %a new command is selected as default { KillDefComProcess select_command LastCommand null ne LastCommand? and {LastCommand /CanBeDefault? get {/DefaultCommand LastCommand store} if } if /hilite DefaultCommand send MakeDefComProcess } DownTransition {ClientCanvas} CommandWindow send eventmgrinterest % interest ] forkeventmgr def pause MakeDefComProcess pause } def /select_command{ %the event is in CurrentEvent CurrentEvent begin XLocation YLocation end %x y of click find_command dup null ne %command {/deshilite DefaultCommand send /execcommand exch send } {pop} ifelse } def /foundcommand null def /find_command{% x y => command | null; %if found, the command is highlited /foundcommand null store CommandTable 0 Ncommand getinterval {%x y com 3 copy %x y com x y com /is_in_obj exch send {/foundcommand exch store exit} {pop} ifelse } forall pop pop foundcommand null ne { LastCommand null ne LastCommand? and {/deshilite LastCommand send} if /hilite foundcommand send} if foundcommand } def %------------------------------------------------------------------------ % alphanumeric input of tool arguments %high-level event ; the value - coord, angle or scale factors %will be in /ClientData %the followint event types (Name) are recorded in macro % /Command, /AlphaEvent (action /Point /Move /Rotate /Scale /String /Stop) % /Param, /Dparam % these events are stored as 3 dict begin /Name /Action /ClientData end (alphanum input\n) printdbg /MakeEventToRecord{% data action name => myevent 3 dict dup begin %data action name ev 4 1 roll /Name exch def /Action exch def /ClientData exch def end } def /MakeEventToSend{% data action name => NeWS event createevent dup begin %data action name ev 4 1 roll /Name exch def /Action exch def /ClientData exch def end } def /PointEvent null /Point /AlphaEvent MakeEventToSend def /MoveEvent null /Move /AlphaEvent MakeEventToSend def % /RotateEvent null /Rotate /AlphaEvent MakeEventToSend def /ScaleEvent null /Scale /AlphaEvent MakeEventToSend def /WaitForEvent PointEvent def /ParseDataDict dictbegin /argarray 10 array def /argtop 0 def /iarg 0 def /GoodType {% /type1 /type2 exch dup /num eq {%/type2 /num pop dup /integertype eq exch /realtype eq or} {eq} ifelse } def dictend def /DataFormat null def /ParseData{ % string => argument bool % true if the string contains an argument compatible % with the DataFormat ParseDataDict begin /argtop 0 store {token {% post token dup type %post token t dup /integertype eq exch %post token ib t /realtype eq or %post token b {argarray exch argtop exch put /argtop argtop 1 add store %post } {exit} ifelse %post } {exit} ifelse } loop /iarg 0 store DataFormat {% type argarray iarg get type GoodType {/iarg iarg 1 add store} {/iarg -1 store exit} ifelse } forall iarg -1 eq {false} { iarg 1 eq {argarray 0 get} {[ argarray 0 iarg getinterval aload pop ]} ifelse true} ifelse end } def /SendAlphaEvent {% reads the string in the CP data item % and sends as an AlphaEvent it if matches the awaited event items begin alphadata /ItemValue get end WaitForEvent /Action get /Rotate eq {/DataFormat [/num] store} {/DataFormat [/num /num] store} ifelse ParseData {% data WaitForEvent begin Action Name end MakeEventToSend sendevent pause } {(data do not match awaited event) prerror} ifelse } def /RecordEvents? false def %------------------------------------------------------------------------- %Tool definition %----------------------------------------------------------------------- (Tool Definition\n) printdbg /topcom {CommandTable Ncommand 1 sub get} def %Select /new CommandObj send dup AddCommand mark 11 537.88 1 1 0 [ 11 537.88 44 571.376 ] -1 0 0 0 0 0 [ %group geometry /new Polyline send mark 0 32.928 1 1 0 [ 0 0 31.4561 32.928 ] -1 5 0 0 0 0 [ %polyg. geom [ 31.4561 -32.928 ] ] %end of polyg. geom true 1 false 0 false false loadobj /new Polyline send mark 0 21.006 1 1 0 [ 0 21.006 10.847 33.496 ] -1 5 0 0 0 0 [ %polyg. geom [ 0 12.49 ] [ 10.847 12.49 ] ] %end of polyg. geom true 2 false 0 false false loadobj ] %end of group geometry false 2 /Select loadobj { /CanBeDefault? true def /execproc { select_object } def } topcom send /DefaultCommand topcom def %Rect /new CommandObj send dup AddCommand mark 11 480.54 1 1 0 [ 11 480.54 45.168 512.9002 ] -1 0 0 0 0 0 [ %group geometry /new DrawObject send mark 0 32.3602 1 1 0 [ 0 0 34.168 32.3602 ] -1 0 0 0 0 0 [ 34.168 -32.3602 ] true loadobj ] %end of group geometry false 1 /Rectangle loadobj { /execproc { DrawObject create_object } def /CanBeDefault? true def } topcom send %Line /new CommandObj send dup AddCommand mark 11 420.929 1 1 0 [ 11 420.929 45.168 460.102 ] -1 0 0 0 0 0 [ %group geometry /new Polyline send mark 0 39.173 1 1 0 [ 0 0 34.168 39.173 ] -1 0 0 0 0 0 [ %polyg. geom [ 7.051 -33.496 ] [ 16.813 -10.219 ] [ 34.168 -39.173 ] ] %end of polyg. geom true 3 false 0 false false loadobj ] %end of group geometry false 1 /Polyline loadobj { /CanBeDefault? true def /execproc { Polyline create_object } def} topcom send %Polygon /new CommandObj send dup AddCommand mark 11 364.724 1 1 0 [ 11 364.724 45.7102 403.3291 ] -1 0 0 0 0 0 [ %group geometry /new Polyline send mark 0 38.6051 1 1 0 [ 0 0 34.7102 38.6051 ] -1 0 0 0 0 0 [ %polyg. geom [ 9.22 -38.6051 ] [ 34.7102 -28.3861 ] [ 20.6091 -13.058 ] [ 34.168 -1.703 ] ] %end of polyg. geom true 4 true 0 false false loadobj ] %end of group geometry false 1 /Polygon loadobj { /CanBeDefault? true def /execproc {Polyline create_object current_selection null ne {current_selection begin /Closed true store end /display current_selection send} if } def} topcom send %Curve /new CommandObj send dup AddCommand mark 11 301.139 1 1 0 [ 11 301.139 47.337 348.26 ] -1 0 0 0 0 0 [ %group geometry /new Curve send mark 0 47.121 1 1 0 [ 0 0 36.337 47.121 ] -1 0 0 0 0 0 [ %polyg. geom [ 2.216 -19.8403 ] [ 11.5213 -29.761 ] [ 19.498 -20.4603 ] [ 25.259 -11.1601 ] [ 32.792 -17.3602 ] [ 36.337 -47.121 ] ] %end of polyg. geom true 6 false 0 false false loadobj ] %end of group geometry false 1 /Curve loadobj {/CanBeDefault? true def /execproc { Curve create_object } def} topcom send %RoundedRect /new CommandObj send dup AddCommand mark 11 252.3141 1 1 0 [ 11 252.3141 45.7102 290.3521 ] -1 0 0 0 0 0 [ %group geometry /new RoundedRect send mark 0 38.038 1 1 0 [ 0 0 34.7102 38.038 ] -1 0 0 0 0 0 [ 34.7102 -38.038 ] true 14 loadobj ] %end of group geometry false 1 /RoundRect loadobj {/CanBeDefault? true def /execproc {RoundedRect create_object} def } topcom send %Oval /new CommandObj send dup AddCommand mark 11 191 1 1 0 [ 11 191 45.7102 232.444 ] -1 0 0 0 0 0 [ %group geometry /new Oval send mark 0 41.444 1 1 0 [ 0 0 34.7102 41.444 ] -1 0 0 0 0 0 [ 34.7102 -41.444 ] true loadobj ] %end of group geometry false 1 /Oval loadobj {/CanBeDefault? true def /execproc {Oval create_object} def} topcom send %Text /new CommandObj send dup AddCommand mark 11 129 1 1 0 [ 11 129 58 174 ] -1 0 0 0 0 0 [ %group geometry /new TextObject send mark 7 13 0.578 0.585 0 [ 7 13 39.3673 25.287 ] 0 0 0 0 0 0 (Text) true /Times-Roman 30 21 56 loadobj /new DrawObject send mark 0 45 1 1 0 [ 0 0 47 45 ] -1 0 0 0 0 0 [ 47 -45 ] true loadobj ] %end of group geometry false 2 /Text loadobj {/CanBeDefault? true def /execproc {TextObject create_object } def} topcom send %Group /new CommandObj send dup AddCommand mark 11 71.488 1 1 0 [ 11 71.488 48.572 115.3771 ] -1 0 0 0 0 0 [ %group geometry /new Group send mark 0 0 1 1 0 [ 0 0 37.572 43.8891 ] -1 0 0 0 0 0 [ %group geometry /new DrawObject send mark 0.578 43.8891 1 1 0 [ 0.578 32.1853 10.983 43.8891 ] -1 0 0 0 0 0 [ 10.405 -11.704 ] true loadobj /new Polyline send mark 13.295 17.556 1 1 0 [ 13.295 17.556 29.48 31.015 ] -1 0 0 0 0 0 [ %polyg. geom [ 16.185 0 ] [ 5.7802 13.4592 ] ] %end of polyg. geom true 2 true 0 false false loadobj /new Oval send mark 24.8553 11.704 1 1 0 [ 24.8553 0 37.572 11.704 ] -1 0 0 0 0 0 [ 12.717 -11.704 ] true loadobj /new DrawObject send mark 0 43.8891 1 1 0 [ 0 0 37.572 43.8891 ] -1 0 0 1 0 0 [ 37.572 -43.8891 ] true loadobj ] %end of group geometry true 4 loadobj ] %end of group geometry false 1 /Group loadobj {/CanBeDefault? true def /execproc {Group create_object} def } topcom send %ImportPS /new CommandObj send dup AddCommand mark 11 13 1 1 0 [ 11 13 59 56 ] -1 0 0 0 0 0 [ %group geometry /new TextObject send mark 12 14 0.578 0.585 0 [ 12 14 31.074 26.8721 ] 0 0 0 0 0 0 (PS) true /Times-Roman 30 22 33 loadobj /new DrawObject send mark 0 43 1 1 0 [ 0 0 48 43 ] -1 0 0 0 0 0 [ 48 -43 ] true loadobj ] %end of group geometry false 2 /ImportPS loadobj { /execproc {PostScript create_object} def} topcom send %Move /new CommandObj send dup AddCommand mark 83 531.265 1 1 0 [ 83 531.265 127.694 571.861 ] -1 0 0 0 0 0 [ %group geometry /new DrawObject send mark 23 18.735 1 1 0 [ 23 0 44.694 18.735 ] -1 0 0 0 0 0 [ 21.694 -18.735 ] true loadobj /new DrawObject send mark 0 40.596 1 1 0 [ 0 21.861 21.694 40.596 ] -1 3 0 0 0 0 [ 21.694 -18.735 ] true loadobj ] %end of group geometry false 2 /Move loadobj { /execproc {/crosshair? true def /drag_and_trans fapply_on_sel /crosshair? false def /commandswitch [/ClickToMove? ClickToMove?] store } def } topcom send %Rotate /new CommandObj send dup AddCommand mark 83 477.051 1 1 0 [ 83 477.051 111.647 510.517 ] -1 0 0 0 0 0 [ %group geometry /new DrawObject send mark 0 18.735 1 1 0 [ 0 0 21.694 18.735 ] -1 3 0 0 0 0 [ 21.694 -18.735 ] true loadobj /new DrawObject send mark 0 18.735 1 1 42.7681 [ 0 4.982 28.647 33.466 ] -1 0 0 0 0 0 [ 21.694 -18.735 ] true loadobj ] %end of group geometry false 2 /Rotate loadobj { /execproc {/drag_and_rotate fapply_on_sel} def } topcom send %Scale /new CommandObj send dup AddCommand mark 83 418.0071 1 1 0 [ 83 418.0071 122.592 456.6123 ] -1 0 0 0 0 0 [ %group geometry /new DrawObject send mark 0 38.6051 1 1 0 [ 0 19.8702 21.694 38.6051 ] -1 3 0 0 0 0 [ 21.694 -18.735 ] true loadobj /new DrawObject send mark 0 38.038 1 1 0 [ 0 0 39.592 38.038 ] -1 0 0 0 0 0 [ 39.592 -38.038 ] true loadobj ] %end of group geometry false 2 /Scale loadobj { /execproc {/drag_and_scale fapply_on_sel} def } topcom send %Copy /new CommandObj send dup AddCommand mark 83 359.265 1 1 0 [ 83 359.265 129.694 402.111 ] -1 0 0 0 0 0 [ %group geometry /new DrawObject send mark 0 42.846 1 1 0 [ 0 24.111 21.694 42.846 ] -1 3 0 0 0 0 [ 21.694 -18.735 ] true loadobj /new DrawObject send mark 25 18.735 1 1 0 [ 25 0 46.694 18.735 ] -1 3 0 0 0 0 [ 21.694 -18.735 ] true loadobj ] %end of group geometry false 2 /Copy loadobj { /param dictbegin /xr 0 def /yr 0 def dictend store /execproc {{ /old_selection current_selection store /current_selection /clone current_selection send store /erase_flag false store /crosshair? true store /drag_and_trans current_selection send /crosshair? false store /erase_flag true store Abort? {/current_selection old_selection store} {current_selection AddObject current_selection push_selection param begin /xr current_selection /X get old_selection /X get sub store /yr current_selection /Y get old_selection /Y get sub store end} ifelse } apply_on_sel} def /repeatproc {{ /old_selection current_selection store /current_selection /clone current_selection send store current_selection begin /X X param /xr get add store /Y Y param /yr get add store end /make_bbox current_selection send /display current_selection send Cancel? { /erase current_selection send /current_selection old_selection store } {current_selection AddObject current_selection push_selection } ifelse } apply_on_sel} def } topcom send %Move Up /new CommandObj send dup AddCommand mark 82 295.2652 1 1 0 [ 82 295.2652 127 346.0002 ] -1 0 0 0 0 0 [ %group geometry /new DrawObject send mark 12 32.735 1 1 0 [ 12 0 45 32.735 ] 0.5 0 0 0 0 0 [ 33 -32.735 ] true loadobj /new DrawObject send mark 0 50.735 1 1 0 [ 0 18 33 50.735 ] -1 3 0 0 0 0 [ 33 -32.735 ] true loadobj ] %end of group geometry false 2 /MoveUp loadobj { /execproc {{ current_selection move_up dup null ne {/display exch send /display current_selection send} {(no overlapping object over selection) prmessage} ifelse } apply_on_sel } def } topcom send %Move Down /new CommandObj send dup AddCommand mark 79 241.2652 1 1 0 [ 79 241.2652 126 290.0002 ] -1 0 0 0 0 0 [ %group geometry /new DrawObject send mark 0 48.735 1 1 0 [ 0 16 33 48.735 ] -1 3 0 0 0 0 [ 33 -32.735 ] true loadobj /new DrawObject send mark 14 32.735 1 1 0 [ 14 0 47 32.735 ] 0.5 0 0 0 0 0 [ 33 -32.735 ] true loadobj ] %end of group geometry false 2 /MoveDown loadobj { /execproc {{ current_selection move_down dup null ne {/display current_selection send /display exch send} {(no overlapping object behind selection) prmessage} ifelse } apply_on_sel } def } topcom send %Delete /new CommandObj send dup AddCommand mark 83 190.974 1 1 0 [ 83 190.974 119.3373 228.444 ] -1 0 0 0 0 0 [ %group geometry /new DrawObject send mark 8 29.026 1 1 0 [ 8 10.291 29.694 29.026 ] -1 3 0 0 0 0 [ 21.694 -18.735 ] true loadobj /new Polyline send mark 0 37.47 1 1 0 [ 0 1.703 36.3373 37.47 ] -1 0 0 0 0 0 [ %polyg. geom [ 36.3373 -35.767 ] ] %end of polyg. geom true 1 false 0 false false loadobj /new Polyline send mark 0 0 1 1 0 [ 0 0 33.0832 37.47 ] -1 0 0 0 0 0 [ %polyg. geom [ 33.0832 37.47 ] ] %end of polyg. geom true 1 false 0 false false loadobj ] %end of group geometry false 3 /Delete loadobj { /param 10 dict def /execproc { param begin /deleted null def end { /delete current_selection send param begin /deleted current_selection def end pop_selection} apply_on_sel} def /undoproc { {ClientCanvas} win send setcanvas param begin deleted null ne { /getclassname deleted send /Group eq /getclassname deleted send /ClippingGroup eq or { gsave deleted begin /X 0 store /Y 0 store /Angle 0 store /Sx 1 store /Sx 1 store geom end /set_geom deleted send grestore} if gsave /display deleted send /current_selection deleted store DeleteFreeEntries current_selection /tableindex get ObjTable exch current_selection put current_selection push_selection grestore } if end } def } topcom send %Destroy /new CommandObj send dup AddCommand mark 83 122.086 1 1 0 [ 83 122.086 129.243 172.998 ] -1 0 0 0 0 0 [ %group geometry /new Polyline send mark 0 28.914 1 1 0 [ 0 17.914 14 28.914 ] -1 0 0 0 0 0 [ %polyg. geom [ 14 -11 ] ] %end of polyg. geom true 1 false 0 false false loadobj /new DrawObject send mark 0 46.815 1 1 0 [ 0 35.111 10.405 46.815 ] -1 3 0 0 0 0 [ 10.405 -11.704 ] true loadobj /new Polyline send mark 0 20.482 1 1 0 [ 0 20.482 16.185 33.9412 ] -1 3 0 0 0 0 [ %polyg. geom [ 16.185 0 ] [ 5.7802 13.4592 ] ] %end of polyg. geom true 2 true 0 false false loadobj /new Oval send mark 0 14.63 1 1 0 [ 0 2.926 12.717 14.63 ] -1 3 0 0 0 0 [ 12.717 -11.704 ] true loadobj /new DrawObject send mark 0 46.815 1 1 0 [ 0 2.926 37.5721 46.815 ] -1 3 0 1 0 0 [ 37.572 -43.8891 ] true loadobj /new Polyline send mark 0 50.912 1 1 0 [ 0 0 46.243 50.912 ] -1 0 0 0 0 0 [ %polyg. geom [ 46.243 -50.912 ] ] %end of polyg. geom true 1 false 0 false false loadobj /new Polyline send mark 0 0 1 1 0 [ 0 0 46.243 49.741 ] -1 0 0 0 0 0 [ %polyg. geom [ 46.243 49.741 ] ] %end of polyg. geom true 1 false 0 false false loadobj /new Polyline send mark 16.185 48.805 1 1 0 [ 0 32.42 16.185 48.805 ] -1 0 0 0 0 0 [ %polyg. geom [ -16.185 -16.3852 ] ] %end of polyg. geom true 1 false 0 false false loadobj /new Polyline send mark 0 15.449 1 1 0 [ 0 1.404 13.873 15.449 ] -1 0 0 0 0 0 [ %polyg. geom [ 13.873 -14.045 ] ] %end of polyg. geom true 1 false 0 false false loadobj /new Polyline send mark 0 0.8191 1 1 0 [ 0 0.8191 15.029 14.8641 ] -1 0 0 0 0 0 [ %polyg. geom [ 15.029 14.045 ] ] %end of polyg. geom true 1 false 0 false false loadobj /new Polyline send mark 0 16.914 1 1 0 [ 0 16.914 15 31.914 ] -1 0 0 0 0 0 [ %polyg. geom [ 15 15 ] ] %end of polyg. geom true 1 false 0 false false loadobj ] %end of group geometry false 11 /Destroy loadobj { /param 10 dict def /undoproc { {ClientCanvas} win send setcanvas param begin deleted null ne { %the table entry may not be the same /getclassname deleted send /Group eq /getclassname deleted send /ClippingGroup eq or { /undestroy deleted send /display deleted send /current_selection deleted store DeleteFreeEntries current_selection /tableindex get ObjTable exch current_selection put current_selection push_selection } if } if end } def /execproc { param begin /deleted null def end { param begin /deleted current_selection def end /destroy current_selection send pop_selection} apply_on_sel } def } topcom send %Edit /new CommandObj send dup AddCommand mark 83 66.552 1 1 0 [ 83 66.552 121.1501 104.589 ] -1 0 0 0 0 0 [ %group geometry /new Polyline send mark 0 38.037 1 1 0 [ 0 0.585 28.902 38.037 ] -1 3 0 0 0 0 [ %polyg. geom [ 7.677 -37.452 ] [ 28.902 -27.538 ] [ 17.1602 -12.6673 ] [ 28.45 -1.6521 ] ] %end of polyg. geom true 4 true 0 false false loadobj /new Polyline send mark 0 37.452 1 1 0 [ 0 0 38.1501 37.452 ] -1 0 0 0 0 0 [ %polyg. geom [ 7.677 -37.452 ] [ 38.1501 -12.874 ] [ 17.1602 -12.6673 ] [ 28.45 -1.6521 ] ] %end of polyg. geom true 4 true 0 false false loadobj ] %end of group geometry false 2 /Edit loadobj { /execproc {/edit_geom fapply_on_sel} def } topcom send %Clip /new CommandObj send dup AddCommand mark 83 3 1 1 0 [ 83 3 121.728 51.571 ] -1 0 0 0 0 0 [ %group geometry /new Curve send mark 0 48.571 1 1 0 [ 0 0 38.728 48.571 ] -1 5 0 0 0 0 [ %polyg. geom [ 2.3613 -20.451 ] [ 12.28 -30.676 ] [ 20.781 -21.09 ] [ 26.9203 -11.504 ] [ 34.9493 -17.8943 ] [ 38.728 -48.571 ] ] %end of polyg. geom true 6 false 0 false false loadobj /new ClippingGroup send mark 0 5.267 1 1 0 [ 0 5.267 36.994 47.986 ] -1 0 0 0 0 0 [ %group geometry /new Oval send mark 0 42.719 1 1 0 [ 0 0 36.994 42.719 ] 1 0 0 0 0 0 [ 36.994 -42.719 ] true loadobj /new Curve send mark -2.312 43.304 1 1 0 [ -2.312 -5.267 36.416 43.304 ] -1 0 0 0 0 0 [ %polyg. geom [ 2.3613 -20.451 ] [ 12.28 -30.676 ] [ 20.781 -21.09 ] [ 26.9203 -11.504 ] [ 34.9493 -17.8943 ] [ 38.728 -48.571 ] ] %end of polyg. geom true 6 false 0 false false loadobj ] %end of group geometry true 2 loadobj ] %end of group geometry false 2 /Clip loadobj { /execproc {{make_clip current_selection send} fapply_on_sel} def } topcom send %Align Left /new CommandObj send dup AddCommand mark 155 530.2944 1 1 0 [ 155 530.2944 190.253 572.8742 ] -1 0 0 0 0 0 [ %group geometry /new Group send mark 0 0 1 1 0 [ 0 0 35.253 42.58 ] -1 0 0 0 0 0 [ %group geometry /new DrawObject send mark 0 42.58 1 1 0 [ 0 31.225 9.7622 42.58 ] -1 0 0 0 0 0 [ 9.7621 -11.355 ] true loadobj /new Polyline send mark 0 17.033 1 1 0 [ 0 17.033 15.186 30.091 ] -1 0 0 0 0 0 [ %polyg. geom [ 15.186 0 ] [ 5.4233 13.058 ] ] %end of polyg. geom true 2 true 0 false false loadobj /new Oval send mark 0 11.355 1 1 0 [ 0 0 11.932 11.355 ] -1 0 0 0 0 0 [ 11.932 -11.355 ] true loadobj /new DrawObject send mark 0 42.58 1 1 0 [ 0 0.001 35.253 42.58 ] -1 0 0 1 0 0 [ 35.253 -42.5792 ] true loadobj ] %end of group geometry true 4 loadobj ] %end of group geometry false 1 /AlignLeft loadobj { /execproc {{/align_left self send} align_op} def } topcom send %A Bottom /new CommandObj send dup AddCommand mark 155.0002 473.9692 1 1 0 [ 155.0002 473.9692 197.679 509.343 ] -1 0 0 0 0 0 [ %group geometry /new Group send mark 42.679 0.121 1 1 90.163 [ 0 0 42.679 35.3732 ] -1 0 0 0 0 0 [ %group geometry /new DrawObject send mark 0 42.5792 1 1 0 [ 0 31.225 9.7621 42.5792 ] -1 0 0 0 0 0 [ 9.7621 -11.355 ] true loadobj /new Polyline send mark 0 17.032 1 1 0 [ 0 17.032 15.186 30.0893 ] -1 0 0 0 0 0 [ %polyg. geom [ 15.186 0 ] [ 5.4233 13.058 ] ] %end of polyg. geom true 2 true 0 false false loadobj /new Oval send mark 0 11.3543 1 1 0 [ 0 0 11.932 11.355 ] -1 0 0 0 0 0 [ 11.932 -11.355 ] true loadobj /new DrawObject send mark 0 42.5792 1 1 0 [ 0 0 35.253 42.5792 ] -1 0 0 1 0 0 [ 35.253 -42.5792 ] true loadobj ] %end of group geometry true 4 loadobj ] %end of group geometry false 1 /AlignBottom loadobj { /execproc {{/align_bottom self send} align_op} def } topcom send %A Right /new CommandObj send dup AddCommand mark 155 414.479 1 1 0 [ 155 414.479 190.253 457.0582 ] -1 0 0 0 0 0 [ %group geometry /new Group send mark 0 0 1 1 0 [ 0 0 35.253 42.5792 ] -1 0 0 0 0 0 [ %group geometry /new DrawObject send mark 25.4903 42.5792 1 1 0 [ 25.4903 31.225 35.253 42.5792 ] -1 0 0 0 0 0 [ 9.7621 -11.355 ] true loadobj /new Polyline send mark 20.067 17.032 1 1 0 [ 20.067 17.032 35.253 30.0893 ] -1 0 0 0 0 0 [ %polyg. geom [ 15.186 0 ] [ 5.4233 13.058 ] ] %end of polyg. geom true 2 true 0 false false loadobj /new Oval send mark 23.321 11.3543 1 1 0 [ 23.321 0 35.253 11.355 ] -1 0 0 0 0 0 [ 11.932 -11.355 ] true loadobj /new DrawObject send mark 0 42.5792 1 1 0 [ 0 0 35.253 42.5792 ] -1 0 0 1 0 0 [ 35.253 -42.5792 ] true loadobj ] %end of group geometry true 4 loadobj ] %end of group geometry false 1 /AlignRight loadobj { /execproc {{/align_right self send} align_op} def } topcom send %A Top /new CommandObj send dup AddCommand mark 155 359.289 1 1 0 [ 155 359.289 197.679 395.855 ] -1 0 0 0 0 0 [ %group geometry /new Group send mark 0 0 1 1 0 [ 0 0 42.679 36.566 ] -1 0 0 0 0 0 [ %group geometry /new DrawObject send mark 0.1 0 1 1 90.163 [ 0 0 42.679 35.373 ] -1 0 0 1 0 0 [ 35.253 -42.5792 ] true loadobj /new Oval send mark 29.929 24.5002 1 1 90.163 [ 29.895 24.5003 41.283 36.464 ] -1 0 0 0 0 0 [ 11.932 -11.355 ] true loadobj /new Polyline send mark 24.5053 21.1262 1 1 90.163 [ 11.433 21.1262 24.5053 36.312 ] -1 0 0 0 0 0 [ %polyg. geom [ 15.186 0 ] [ 5.4233 13.058 ] ] %end of polyg. geom true 2 true 0 false false loadobj /new DrawObject send mark 0.1 26.7711 1 1 90.163 [ 0.0722 26.7711 11.4542 36.566 ] -1 0 0 0 0 0 [ 9.7621 -11.355 ] true loadobj ] %end of group geometry true 4 loadobj ] %end of group geometry false 1 /AlignTop loadobj { /execproc {{/align_top self send} align_op} def } topcom send %C vert /new CommandObj send dup AddCommand mark 155 299.7983 1 1 0 [ 155 299.7983 190.253 342.378 ] -1 0 0 0 0 0 [ %group geometry /new Group send mark 0 0 1 1 0 [ 0 0 35.253 42.5792 ] -1 0 0 0 0 0 [ %group geometry /new DrawObject send mark 12.7451 42.5792 1 1 0 [ 12.7451 31.225 22.5073 42.5792 ] -1 0 0 0 0 0 [ 9.7621 -11.355 ] true loadobj /new Polyline send mark 10.0333 17.032 1 1 0 [ 10.0333 17.032 25.2191 30.0893 ] -1 0 0 0 0 0 [ %polyg. geom [ 15.186 0 ] [ 5.4233 13.058 ] ] %end of polyg. geom true 2 true 0 false false loadobj /new Oval send mark 11.661 11.3543 1 1 0 [ 11.6603 0 23.592 11.355 ] -1 0 0 0 0 0 [ 11.932 -11.355 ] true loadobj /new DrawObject send mark 0 42.5792 1 1 0 [ 0 0 35.253 42.5792 ] -1 0 0 1 0 0 [ 35.253 -42.5792 ] true loadobj ] %end of group geometry true 4 loadobj ] %end of group geometry false 1 /CenterV loadobj { /execproc {{/center_vertical self send} align_op} def } topcom send %C hor /new CommandObj send dup AddCommand mark 155 247 1 1 0 [ 155 247 197.679 282.373 ] -1 0 0 0 0 0 [ %group geometry /new Group send mark 0 0 1 1 0 [ 0 0 42.679 35.373 ] -1 0 0 0 0 0 [ %group geometry /new DrawObject send mark 0.1 0 1 1 90.163 [ 0 0 42.679 35.373 ] -1 0 0 1 0 0 [ 35.253 -42.5792 ] true loadobj /new Oval send mark 29.929 12.25 1 1 90.163 [ 29.895 12.2501 41.283 24.214 ] -1 0 0 0 0 0 [ 11.932 -11.355 ] true loadobj /new Polyline send mark 24.5053 10.563 1 1 90.163 [ 11.433 10.563 24.5053 25.749 ] -1 0 0 0 0 0 [ %polyg. geom [ 15.186 0 ] [ 5.4233 13.058 ] ] %end of polyg. geom true 2 true 0 false false loadobj /new DrawObject send mark 0.1 13.386 1 1 90.163 [ 0.0722 13.386 11.4542 23.18 ] -1 0 0 0 0 0 [ 9.7621 -11.355 ] true loadobj ] %end of group geometry true 4 loadobj ] %end of group geometry false 1 /CenterH loadobj { /execproc {{/center_horizontal self send} align_op} def } topcom send %repeat /new CommandObj send dup AddCommand mark 152 187 1 1 0 [ 152 187 205 234 ] -1 0 0 0 0 0 [ %group geometry /new TextObject send mark 2 20 0.6 1.0024 0 [ 2 20 52.3723 41.051 ] 0 0 0 0 0 0 (Repeat) true /Times-Roman 30 21 84 loadobj /new DrawObject send mark 0 47 1 1 0 [ 0 0 53 47 ] -1 0 0 0 0 0 [ 53 -47 ] true loadobj ] %end of group geometry false 2 /Repeat loadobj { /execproc{ LastCommand null ne {LastCommand? %a command {/repeatproc LastCommand send} {/execmacro LastCommand send} ifelse } if } def} topcom send /RepeatCommand topcom def %Undo /new CommandObj send dup AddCommand mark 152 126 1 1 0 [ 152 126 205 173 ] -1 0 0 0 0 0 [ %group geometry /new TextObject send mark 2 16.7373 0.732 0.9184 0 [ 2 16.7373 51.777 36.944 ] 0 0 0 0 0 0 (Undo) true /Times-Roman 30 22 68 loadobj /new DrawObject send mark 0 47 1 1 0 [ 0 0 53 47 ] -1 0 0 0 0 0 [ 53 -47 ] true loadobj ] %end of group geometry false 2 /Undo loadobj { /execproc { LastCommand null ne { {undoproc} LastCommand send } if } def } topcom send %redefines that in your .NeWSillustrator to [x y w h] /ControlPanelPosition null def /DrawingAreaPosition null def /ToolPalettePosition null def /WindowPositions{%print in the message panel the 3 windows position (CP: % % % %, DA: % % % %, TP: % % % %) [{FrameX FrameY FrameWidth FrameHeight} controlpanel send {FrameX FrameY FrameWidth FrameHeight} win send {FrameX FrameY FrameWidth FrameHeight} CommandWindow send ] sprintf prmessage } def (Window definition \n) printdbg /WinMenu [ (Redisplay) {/PaintClient ThisWindow send} (Zoom In) {/ZoomIn ThisWindow send} (Zoom Out) {/ZoomOut ThisWindow send} (Font => ) fontmenu (FontSize => ) pointsizemenu (Files IO => ) filemenu (-------) { } ] /new DefaultMenu send def /win framebuffer /new ScrollAndZoomWindow send def { /PaintClient { ClientCanvas setcanvas 1 fillcanvas /display a4rect send RepaintAll } def /FrameLabel (NeWSillustrator - Drawing Area) def /IconLabel (Drawing Area) def /ClientMenu WinMenu def } win send %user file (.NeWSillustrator\n) printdbg (HOME) getenv (/.NeWSillustrator) append LoadFile pop MakeControlPanel DrawingAreaPosition null eq {/reshapefromuser win send} { DrawingAreaPosition aload pop /reshape win send} ifelse /map win send 1000 1000 /Resize win send {/Scroll win send} {/Scroll win send} /SetNotifiers win send win /ClientCanvas get setcanvas win begin /overlaycan ClientCanvas createoverlay store end MakeCommandWindow /Started 1 def /FirstUserCommand Ncommand def %end %end NeWSillustratorDict From don@brillig.umd.edu Mon Jan 30 12:05:30 1989 Date: Mon, 30 Jan 89 12:05:30 EST To: NeWS-makers@brillig.umd.edu Subject: A whimsical memorial From: spectral!sjs@bellcore.com (Stan Switzer) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) In memory of Salvador Dali I submit a modification of the standard "roundclock" tool. The enclosed shar file contains only the differences between the standard "roundclock" and the Daliesque version. The Makefile already knows how to edit in the changes so you don't have to bother with it but you'll have to change the CLSRC macro if your client source is installed in an unususl place. NOTE: Since the shar file creates a file named "Makefile", you'll probably want to run it in a new directory. This turned out to be a bit more tedious than I expected because it's difficult to create a path which is the union of the intersections of paths. Stan Switzer sjs@ctt.bellcore.com "I do not use drugs. I _am_ drugs." -- Salvador Dali ------- cut here ------- #!/bin/sh CLSRC=/usr/NeWS/clientsrc/client if test -f Makefile; then echo File Makefile exists!; exit 1; fi sed -e 's/^X//' <<'EOF' >Makefile XCLSRC=/usr/NeWS/clientsrc/client X X.SUFFIXES: .h .cps .diff X X.cps.h: X cps $*.cps X XCFLAGS = -O -I/usr/NeWS/include X XALL: daliclock X Xdaliclock: daliclock.o X cc -o $@ daliclock.o /usr/NeWS/lib/libcps.a X Xdaliclock.o: daliclock.c daliclock.h X Xdaliclock.cps: X cat $(CLSRC)/roundclock.cps >daliclock.cps X ed daliclock.cps daliclock.c X ed daliclock.c cps.diff X { { diff -e $(CLSRC)/roundclock.c daliclock.c||true;};echo w;} >c.diff X { echo "#!/bin/sh"; \ X echo CLSRC="$(CLSRC)"; \ X for F in Makefile c.diff cps.diff; do \ X echo "if test -f $$F; then echo "File $$F exists!"; exit 1; fi"; \ X echo "sed -e 's/^X//' <<'EOF' >$$F"; \ X sed -e 's/^/X/' <$$F; \ X echo "EOF"; \ X done; \ X } > shar X EOF if test -f c.diff; then echo File c.diff exists!; exit 1; fi sed -e 's/^X//' <<'EOF' >c.diff X48c X#include "daliclock.h" X. Xw EOF if test -f cps.diff; then echo File cps.diff exists!; exit 1; fi sed -e 's/^X//' <<'EOF' >cps.diff X99c X fill } dopaint X. X97c X { rot rotate newpath -5 0 moveto 0 0 5 180 360 arc X. X88,89c X { rot rotate 0 0 moveto 0 rad rlineto stroke } dopaint X. X72c X calctransform X { drawclockframe } dopaint X clipcanvas X. X66c X { FrameWidth 100 div FrameHeight 100 div } window send scale X. X55,56c X KeyFocus? {KeyFocusColor} {backgroundcolor} ifelse setcolor X calctransform X { 0 0 40 0 360 arc stroke } dopaint X. X46,47c X FrameWidth 100 div FrameHeight 100 div scale X 50 50 translate X 0 0 50 A1 A2 arc X xform X 0 0 50 A2 A1 arc X FrameCanvas setcanvasshape X. X44a X /FrameHeight FrameHeight X 50 rY sub H mul 50 rY add add 100 div div cvi def X. X40c X /IconLabel (DaliClock) def X /IconImage /iconedit def X /ClientMinWidth 4 def /ClientMinHeight 4 def X. X37a X % /rX 50 def /rY -20 def /Ang -30 def /A1 141 def /A2 338 def /Sk .7 def /H 1 def X % /rX 50 def /rY 15 def /Ang 0 def /A2 17.5 def /A1 180 A2 sub def /Sk 1.2 def /H .5 def X % /rX 50 def /rY 15 def /Ang 0 def /A2 17.5 def /A1 180 A2 sub def /Sk 1.5 def /H .4 def X /rX 50 def /rY 15 def /Ang 0 def /A2 17.5 def /A1 180 A2 sub def /Sk 1.7 def /H .3 def X /xform { X rX rY translate X Ang rotate X [ 1 0 Sk H 0 0 ] concat X Ang neg rotate X rX neg rY neg translate X } def X /lowclip { X matrix currentmatrix X -50 -50 moveto 100 0 rlineto 0 50 rY add rlineto X Ang rotate -200 0 rlineto closepath clip X setmatrix X } def X /hiclip { X matrix currentmatrix X -50 50 moveto 100 0 rlineto 0 -50 rY add rlineto X Ang rotate -200 0 rlineto closepath clip X setmatrix X } def X /dopaint { % proc => X dup gsave lowclip exec grestore X gsave xform hiclip exec grestore X } def X. X36a X% Daliesque modifications by Stan Switzer sjs@ctt.bellcore.com 1/28/89 X% Explaination of parameters: X% Assuming circle inscribes a square in [-50,50]X[-50,50] square X% (rX,rY) intersection of bend line with right edge of boundin square X% Ang angle of intersection X% A1 angle from (0,0) to left intersection of bend with circle X% A2 angle from (0,0) to right intersection of bend with circle X% Sk skew factor above bend X% H height factor above bend X% Each set of parameters below gives interesting results. X% The first is the most complex, but the last (in my opinion) gives the X% most realistinc 3D effect as it can be "draped" over the edge of another X% window for comic/artictic effect. X X. Xw EOF From don@brillig.umd.edu Mon Jan 30 12:05:51 1989 Date: Mon, 30 Jan 89 12:05:51 EST To: NeWS-makers@brillig.umd.edu Subject: Re: A whimsical memorial From: spectral!sjs@bellcore.com (Stan Switzer) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) One more thing: The effect is most (sur)realistic when the clock is draped over the edge of some other window. Stan Switzer sjs@ctt.bellcore.com "The Exterminator does a good job," said the Sailor. "Almost too good sometimes." From don@brillig.umd.edu Tue Jan 31 08:32:04 1989 Date: Tue, 31 Jan 89 08:32:04 EST To: NeWS-makers@brillig.umd.edu Subject: More questions (icon in front), print NeWS fonts, vfonts in psterm From: steinmetz!vdsvax!steinmetz!barnett@uunet.uu.net (Bruce Barnett) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) I have a few more questions about NeWS stuff.. 1) Has anyone modified their user.ps to cause icons, when opened, to be in front of the other windows? 2) Does anyone know how to get the NeWS fonts printed in a document? -- Bruce G. Barnett barnett@ge-crd.ARPA, barnett@steinmetz.ge.com uunet!steinmetz!barnett From don@brillig.umd.edu Tue Jan 31 08:32:09 1989 Date: Tue, 31 Jan 89 08:32:09 EST To: NeWS-makers@brillig.umd.edu Subject: Changing FrameFillColor From: steinmetz!vdsvax!steinmetz!barnett@uunet.uu.net (Bruce Barnett) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) I would like to change the default behavior for all windows to set the FrameFillColor from the results of a procedure I have defined. I have tried several different ways of doing this. In fact, I can think of at least 6 ways to do this, and so far, either nothing happens, or else all of my windows dissappear. Can anyone else get this working? I will summarize all responses. -- Bruce G. Barnett barnett@ge-crd.ARPA, barnett@steinmetz.ge.com uunet!steinmetz!barnett From don@brillig.umd.edu Tue Jan 31 08:33:09 1989 Date: Tue, 31 Jan 89 08:33:09 EST To: NeWS-makers@brillig.umd.edu Subject: Re: Is "transform" in NeWS 1.1 OK ? From: sgi!msc%ramoth.SGI.COM@ucbvax.Berkeley.EDU (Mark Callow) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) In article <4495@natmlab.dms.oz>, ronb@natmlab.dms.oz (Ron Baxter) writes: > > The following session with psh puzzles me and I wonder > what I am missing. > > executive > Welcome to NeWS Version 1.1 > matrix currentmatrix pstack > [1 0 0 1 0 0] The preceding line does nothing since the next thing you do is clear the stack > clear 100 200 transform pstack > 100 700 > clear -20 -40 transform pstack > -20 940 > clear 50 70 itransform pstack > 50 830 > > Since the CTM is an identity matrix I would have expected > transform, itransform, etc to make no change to x and y. > The LaserWriter behaves as I expected, so is this a NeWS 1.1 > funny? The default CTM isn't the identity matrix. It is the default matrix that gives the user a coordinate system with a lower left origin and 72 units to the inch on the output device. Sun ignores the 72/inch requirement but they do use the matrix to invert to get an upper left origin hence the result you see. N.B., If you had used the 3 operand transform 100 200 [1 0 0 1 0 0] transform on your Sun you would have got a typecheck error. The 3 operand form isn't implemented. I recently implemented it on the Iris and it will be in our next release. -- -Mark From don@brillig.umd.edu Mon Feb 6 01:40:26 1989 Date: Mon, 6 Feb 89 01:40:26 EST To: NeWS-makers@brillig.umd.edu Subject: More questions (icon in front), print NeWS fonts, vfonts in psterm From: steinmetz!vdsvax!steinmetz!barnett@uunet.uu.net (Bruce Barnett) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) I have a few more questions about NeWS stuff.. 1) Has anyone modified their user.ps to cause icons, when opened, to be in front of the other windows? 2) Does anyone know how to get the NeWS fonts printed in a document? -- Bruce G. Barnett barnett@ge-crd.ARPA, barnett@steinmetz.ge.com uunet!steinmetz!barnett From don@brillig.umd.edu Mon Feb 6 01:40:53 1989 Date: Mon, 6 Feb 89 01:40:53 EST To: NeWS-makers@brillig.umd.edu Subject: Changing FrameFillColor From: steinmetz!vdsvax!steinmetz!barnett@uunet.uu.net (Bruce Barnett) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) I would like to change the default behavior for all windows to set the FrameFillColor from the results of a procedure I have defined. I have tried several different ways of doing this. In fact, I can think of at least 6 ways to do this, and so far, either nothing happens, or else all of my windows dissappear. Can anyone else get this working? I will summarize all responses. -- Bruce G. Barnett barnett@ge-crd.ARPA, barnett@steinmetz.ge.com uunet!steinmetz!barnett From don@brillig.umd.edu Mon Feb 6 01:41:53 1989 Date: Mon, 6 Feb 89 01:41:53 EST To: NeWS-makers@brillig.umd.edu Subject: Re: Is "transform" in NeWS 1.1 OK ? From: sgi!msc%ramoth.SGI.COM@ucbvax.Berkeley.EDU (Mark Callow) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) In article <4495@natmlab.dms.oz>, ronb@natmlab.dms.oz (Ron Baxter) writes: > > The following session with psh puzzles me and I wonder > what I am missing. > > executive > Welcome to NeWS Version 1.1 > matrix currentmatrix pstack > [1 0 0 1 0 0] The preceding line does nothing since the next thing you do is clear the stack > clear 100 200 transform pstack > 100 700 > clear -20 -40 transform pstack > -20 940 > clear 50 70 itransform pstack > 50 830 > > Since the CTM is an identity matrix I would have expected > transform, itransform, etc to make no change to x and y. > The LaserWriter behaves as I expected, so is this a NeWS 1.1 > funny? The default CTM isn't the identity matrix. It is the default matrix that gives the user a coordinate system with a lower left origin and 72 units to the inch on the output device. Sun ignores the 72/inch requirement but they do use the matrix to invert to get an upper left origin hence the result you see. N.B., If you had used the 3 operand transform 100 200 [1 0 0 1 0 0] transform on your Sun you would have got a typecheck error. The 3 operand form isn't implemented. I recently implemented it on the Iris and it will be in our next release. -- -Mark From don@brillig.umd.edu Mon Feb 6 01:43:00 1989 Date: Mon, 6 Feb 89 01:43:00 EST To: NeWS-makers@brillig.umd.edu Subject: UI.ps consult needed From: agate!saturn!jupiter.ucsc.edu!conrad@ucbvax.Berkeley.EDU (Al Conrad) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Well, my NeWS1.1 port is very close to complete. All the mouse interaction works, all of the server/client socket stuff works, but only half of the keyboard stuff works (specifically: upper and lower case A through Z, the digits 0 through 9, back space, and carriage return). I started with lk201keys.ps and, since I've only got access to the ASCII values generated by the keyboard in my KbEventsHaveSelected() service routine, I just used those values for the postion field of each keyboard character. For example, (A) toChar [65 /keystation unshifted] def My KbEventsHaveSelected() code just does an up and down transition for most characters with a faked shift key for upper case alpha (see attached C code). So, for some reason punctation and most control characters don't work, despite all of my experiments with /anydown, /controlled, etc. Admittedly, I am hacking here and not taking the time to thoroughly understand UI.ps. Possibly there is some documentation I am missing? Help me, oh UI.ps guru(s). Only two weeks to connectathon! Al Conrad conrad@saturn.ucsc.edu ------------------------------------------------------------------------------ void make_events_for_ascii( eventp, ascii, _nevents ) struct inputevent *eventp; unsigned char ascii; int *_nevents; { if ( isalpha( ascii ) ) if ( islower( ascii ) ) { mkevent( eventp, toupper( ascii ), 0, 0, (int) x, (int) y, (*_nevents) ); eventp->ie_shiftmask = 0; mkevent( eventp, toupper( ascii ), IE_NEGEVENT, 0, (int) x, (int) y, (*_nevents) ); } else { mkevent( eventp, SHIFTCHAR, 0, 0, (int) x, (int) y, (*_nevents) ); eventp->ie_shiftmask = 0; mkevent( eventp, ascii & 0x7F, 0, 0, (int) x, (int) y, (*_nevents) ); eventp->ie_shiftmask = 0; mkevent( eventp, ascii & 0x7F, IE_NEGEVENT, 0, (int) x, (int) y, (*_nevents) ); eventp->ie_shiftmask = 0; mkevent( eventp, SHIFTCHAR, IE_NEGEVENT, 0, (int) x, (int) y, (*_nevents) ); } else { mkevent( eventp, ascii & 0x7F, 0, 0, (int) x, (int) y, (*_nevents) ); eventp->ie_shiftmask = 0; mkevent( eventp, ascii & 0x7F, IE_NEGEVENT, 0, (int) x, (int) y, (*_nevents) ); } } From don@brillig.umd.edu Mon Feb 6 02:47:18 1989 Date: Mon, 6 Feb 89 02:47:18 EST To: NeWS-makers@brillig.umd.edu Subject: Re: Is "transform" in NeWS 1.1 OK ? From: spectral!sjs@bellcore.com (Stan Switzer) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Never make any assumptions about the device coordinates. You might feel justified in expecting the default matrix to have the form "[ n 0 0 -n 0 0 ]" because that is the way most framebuffers (printers and screens alike) are laid out, but you'd be wrong. I got a rude awakening one day when I discovered that a certain printer's default matrix had the form "[ 0 n -n 0 0 0 ]". This seemed pretty wierd to me until I realized that the paper fed through the printer sideways, right edge first. In fact, if you were driving a wide aspect-ratio screen you might want to turn the thing sideways and change the default matrix rather than the modifying the beam scan pattern or framebuffer layout (but expect people to scream when they try to hook up a projector). Stan Switzer sjs@ctt.belllcore.com "NeWS -- the windowing system for the other half of your brain." -- Don Hopkins From don@brillig.umd.edu Mon Feb 6 02:47:29 1989 Date: Mon, 6 Feb 89 02:47:29 EST To: NeWS-makers@brillig.umd.edu Subject: Re: Is "transform" in NeWS 1.1 OK ? From: mcvax!ukc!harrier.ukc.ac.uk!eagle.ukc.ac.uk!icdoc!qmc-cs!liam@uunet.uu.net (William Roberts) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) The problem stems from a mistaken belief that the default CTM should have 0 0 at bottom left and y increasing up the page. Sun turned themselves inside out to make this true for pixrects, which have 0 0 as top left and y increasing down the page. If they hadn't done that then an awful lot of current faults (e.g. movecanvas) would not be there... -- William Roberts ARPA: liam@cs.qmc.ac.uk (gw: cs.ucl.edu) Queen Mary College UUCP: liam@qmc-cs.UUCP LONDON, UK Tel: 01-975 5250 From don@brillig.umd.edu Mon Feb 6 02:47:36 1989 Date: Mon, 6 Feb 89 02:47:36 EST To: NeWS-makers@brillig.umd.edu Subject: Re: NeWS on VMS... From: mcvax!enea!naggum!isncr!m2cs!frode@uunet.uu.net (Frode Odegard) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) In article <14431@hc.DSPO.GOV>, siegel@hc.DSPO.GOV (josh Siegel) writes: > Has anybody ported NeWS to VMS yet? How about to a Microvax 2000 > running VMS? > Taking into consideration the fact that DEC just launched a new workstation which gives pretty good performance for the price (we're all awaiting a HUGE price cut from Sun :-)), I would think that someone must be working on it..... The new DEC workstation runs UNIX, though... ;-) - Frode -- | Frode L. Odegard |"The world is coming to an end! Repent and| | Modula-2 CASE Systems |rm /bin/cc" | | NORWAY (EUROPE) | | | Email: frode@m2cs.uu.no | | From don@brillig.umd.edu Mon Feb 6 02:56:43 1989 Date: Mon, 6 Feb 89 02:56:43 EST To: NeWS-makers@brillig.umd.edu Subject: Latest NeWS RTF, Nov. 8, '88 From: amdahl!pyramid!prls!philabs!ppgbms!paul@ames.arc.nasa.gov (Paul Matz) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) I've heard that there is a more recent version of the NeWS 1.1 RTF available (RTF rev. A, Nov. 8, '88, 800-1737-17), which has some interesting information on performance in 4Mbyte machines. Does anyone have a copy they would be willing to send (or email from someone at Sun)? Also, has anyone had any luck communicating with the news-archive or getting a response from news-interest? I've sent numerous requests to both, as described in the release notes, without any response. I suppose that it could be a problem with my return path, but I've had no problem with email, and have gotten responses from other source archives, like uunet!netlib or mit-eddie!expo.lcs.mit.edu!xstuff. What am I doing wrong? Thanks (wishful thinking), Paul Matz PPG Biomedical Systems Pleasantville, NY. 914-741-4685 ppgbms!paul or ppgbms!paul@philabs.Philips.COM rformed as if going to an icon when you are going FROM an icon, and vice versa.) I am using NeatWindow as my base, but the changes are the same for DefaultWindow. >2) Does anyone know how to get the NeWS fonts printed in a document? I havn't any idea. -- Ed Weiss "I thought it was generally accepted, sir, that att!ihlpf!spock vulcans are an advanced and most honorable race." "They are, they are. And damn annoying at times." From don@brillig.umd.edu Mon Feb 6 02:56:50 1989 Date: Mon, 6 Feb 89 02:56:50 EST To: NeWS-makers@brillig.umd.edu Subject: dstack From: apctrc!figaro!zcch0a@uunet.uu.net (Chris Humphrey) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Walter Quay (zwdq01) and I are beginners in NeWS here at the Amoco Research Center, and could use some help in learning it. Is there some command that functions like dstack? This is a command similar to pstack, mentioned in the beginning of the Red Book (though not in the body). We have found pstack immensely useful in learning NeWS, and thought dstack would help as well. Did Sun just not implement this command in NeWs? Or is there some equivalent? Anyone out there willing to help a couple of struggling novices? snail: 4502 E. 41st St Rm 325,Tulsa, OK 74135 Dr. Humphrey voice: (918) 660-4045 Corporate Philosopher uucp: ...!uunet!apctrc!zcch0a Amoco Research Center From don@brillig.umd.edu Mon Feb 6 06:50:13 1989 Date: Mon, 6 Feb 89 06:50:13 EST To: NeWS-makers@brillig.umd.edu Subject: fast display of wave-forms? From: uhccux!richard@humu.nosc.mil (Richard Foulk) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Is there a really fast way of displaying something like wave-forms with NeWS? We need to display records that are about 1k points each. The various tests I've run seem to show NeWS as quite a bit slower at the task than various approaches within Sunview. Basically I coded some traces up in Postscript and sent them along with a simple window wrapper to psh. It was mostly a bunch of lineto's. Is there a faster way? Is there a way to send binary data? I need to be able to display and perhaps move and scale these traces quickly. I'd much rather use NeWS if possible ... Thanks. Richard Foulk richard@uhccux.uhcc.hawaii.edu From don@brillig.umd.edu Mon Feb 6 06:50:27 1989 Date: Mon, 6 Feb 89 06:50:27 EST To: NeWS-makers@brillig.umd.edu Subject: Need NeWSIllustrator 4 and 5 From: mailrus!jarvis.csri.toronto.edu!utgpu!utzoo!yunexus!hydroesm!rob@tut.cis.ohio-state.edu (Rob Cairns) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Could someone please repost parts 4 and 5 of NeWSIllustrator (that was posted last weekend)? Thanks... -- Rob Cairns (416)-592-4919 Ontario Hydro Instrumentation and Control Dept. 700 University Ave., H13F21 ,Toronto, Ontario , Canada , M5G 1X6 -- Rob Cairns (416)-592-4919 Ontario Hydro Instrumentation and Control Dept. 700 University Ave., H13F21 ,Toronto, Ontario , Canada , M5G 1X6 From don@brillig.umd.edu Mon Feb 6 06:50:34 1989 Date: Mon, 6 Feb 89 06:50:34 EST To: NeWS-makers@brillig.umd.edu Subject: Re: fast display of wave-forms? From: steinmetz!vdsvax!montnaro@uunet.uu.net (Skip Montanaro) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) In article <3202@uhccux.uhcc.hawaii.edu> richard@uhccux.uhcc.hawaii.edu (Richard Foulk) writes: Is there a really fast way of displaying something like wave-forms with NeWS? We need to display records that are about 1k points each. The various tests I've run seem to show NeWS as quite a bit slower at the task than various approaches within Sunview. I've done a little plotting in NeWS and discovered a couple things. Others here at GE CRD (and elsewhere I imagine) have discovered them as well, so I doubt they'll be earth-shattering to many readers of this group. 1. As you mentioned, NeWS is slow relative to SunView. Using C & cps yields some compression using NeWS' binary encoding, but you're compressing each number individually. Unfortunately, cps does not provide a way to send arrays of data. If it did, some more opportunities for compression might turn up. 3. If you can use a PostScript function to generate some of the data, it may help. For instance, in the simple case of X-Y plots, if X runs from 0 to 1000 by 1's, you would be better off sending a short PostScript function to generate the X's. If you can send a function to compute Y as well, you've saved even more of the precious bandwidth. 4. Data decimation helps. If you are plotting 1000 pairs of points but only have a 100 pixel wide window to display it in, ten pairs of points will be plotted in each column of pixels in the X direction. Compute minY and maxY for each group of ten points, then send (minX, minY) and (maxX, maxY) to NeWS as the next two points to plot. You get a short little vertical line, but when looking at a lot of data in a smallish window it looks about like what you'd see anyway. As you zoom in on the data and cross the point where there are two points per pixel along the X axis, switch back to normal plotting to preserve accuracy. Data decimation wins big in both data transfer (fewer bits on the wire) and cpu time (fewer redundant dots on the screen). -- Skip Montanaro (montanaro@sprite.steinmetz.ge.com, montanaro@ge-crd.arpa) From don@brillig.umd.edu Mon Feb 6 06:50:46 1989 Date: Mon, 6 Feb 89 06:50:46 EST To: NeWS-makers@brillig.umd.edu Subject: pspp/ptags version 0.05 From: siegel@hc.dspo.gov (josh Siegel) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) There is a new version of pspp on hc.dspo.gov in the ~ftp/pub directory. The diff between the 0.04 version and the 0.05 version is larger then the source. CHANGES: Removed some code that wasn't needed. Fixed a "cdef" indentation problem Added manual pages Added ptags function the ptags program is the postscript equiv of ctags. One of the Sun people at usenix mentioned I should add it and since I have been back for 6 hours, I did. The code still looks REAL bad and doesn't go as fast as it could but it is beginning to settle down. If you can't access it via ftp, send me mail and I will mail it to you personally. -- Josh Siegel (siegel@hc.dspo.gov) I like using a C-47A "puff dragon" to go shooting beer cans with. From don@brillig.umd.edu Mon Feb 6 18:28:32 1989 Date: Mon, 6 Feb 89 18:28:32 EST To: NeWS-makers@brillig.umd.edu Subject: Bug fix in pspp... From: siegel@hc.dspo.gov (josh Siegel) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Apply the following to version 0.05 otherwise the comment lines in your postscript files might get messed up... --Josh Siegel --- diff -c -r pspp.n/Makefile pspp/Makefile *** pspp.n/Makefile Mon Feb 6 15:02:19 1989 --- pspp/Makefile Mon Feb 6 15:01:48 1989 *************** *** 27,32 **** --- 27,35 ---- DOCS = pspp.1 ptags.1 all: $(PROGRAM) + @/bin/rm -f ptags + @echo linking ptags to pspp + @ln pspp ptags ${PROGRAM}.shar: $(SRCS) ${MAKEFILE} ${DOCS} README patchlevel.h shar -a README $(SRCS) ${MAKEFILE} ${DOCS} patchlevel.h> ${PROGRAM}.shar diff -c -r pspp.n/README pspp/README *** pspp.n/README Mon Feb 6 15:02:19 1989 --- pspp/README Mon Feb 6 15:00:16 1989 *************** *** 39,44 **** --- 39,48 ---- % pspp -lba foo.cps +lba foobar.ps + Note: + pspp is the same program as ptags. Use "make install" to install + them. + Special NeWS related features... lines beginning with cdef are assumed to be cdef calls under NeWS. diff -c -r pspp.n/patchlevel.h pspp/patchlevel.h *** pspp.n/patchlevel.h Mon Feb 6 15:02:20 1989 --- pspp/patchlevel.h Mon Feb 6 14:59:42 1989 *************** *** 1 **** ! #define PATCHLEVEL 4 --- 1 ---- ! #define PATCHLEVEL 5 diff -c -r pspp.n/pspp.l pspp/pspp.l *** pspp.n/pspp.l Mon Feb 6 15:02:18 1989 --- pspp/pspp.l Mon Feb 6 14:56:23 1989 *************** *** 8,13 **** --- 8,16 ---- You may copy the pspp kit in whole or in part as long as you don't try to make money off it, or pretend that you wrote it. + Version 0.06 + Fixed comment lines getting stuck together (bug by Dave Yost). + Version 0.05 Removed some code that wasn't needed. Fixed a "cdef" indentation problem *************** *** 288,294 **** parseflag(&yytext[3]); neednew=1; } ! [^^]\%.*\n { /* 11 */ yytext[yyleng-1]='\0'; fprintf(yyout,"%s",yytext); neednew=1; --- 291,297 ---- parseflag(&yytext[3]); neednew=1; } ! [^^]\%.* { /* 11 */ yytext[yyleng-1]='\0'; fprintf(yyout,"%s",yytext); neednew=1; -- Josh Siegel (siegel@hc.dspo.gov) I like using a C-47A "puff dragon" to go shooting beer cans with. From don@brillig.umd.edu Tue Feb 7 19:56:23 1989 Date: Tue, 7 Feb 89 19:56:23 EST To: NeWS-makers@brillig.umd.edu Subject: Job Announcement From: beta!sxe@lanl.gov (Stephen Eubank) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Hacker wanted in scenic New Mexico for work with a diverse group of dynamical and complex systems researchers implementing a unique approach to data analysis and noise reduction based on nonlinear, chaotic modelling. Applications of this approach include weather, economic, and geological forecasting, remastering early musical recordings, and similar peaceful purposes. A rough kernel is already in place, written in C++, and is rapidly evolving. Current areas of development include: window-based user interface and menuing system (NeWS/X), interactive graphical output diagnostics, efficient numerical algorithms, multi-threading/tasking, and distributed processing, to name a few. Work is currently conducted on Suns with access to the computing facilities at Los Alamos National Labs (including Crays and our brand new Connection machine). The talents required should be clear from the description above. To name a few: C++ experience / C wizardry + object-oriented experience NeWS/X development experience mathematical literacy (comfortable with calculus, vector spaces, statistics, etc.) The most qualified applicants will also have: high school diploma iron intestines (for massive green chili consumption) bass or drum playing ability Contact eubank@flamingo.lanl.gov (I'm not pink) with a brief resume. If you must, mail to Stephen Eubank, CNLS MS-B258 Los Alamos National Laboratory Los Alamos, NM 87545 From don@brillig.umd.edu Wed Feb 8 12:05:10 1989 Date: Wed, 8 Feb 89 12:05:10 EST To: NeWS-makers@brillig.umd.edu Subject: Open Look From: Mark Richer Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Can someone report on the status of OPEN LOOK? I read some nasty reports in ComputerWorld that Open Look was more or less dead in the water or would be soon --- that is not to say that Sun or AT&T are abandoning, but that it had little chance of becoming a widespread standard. ComputerWorld -- feb. 6, 1989 AT&T's Open Look support vanishing, page 6 "Many analysts concurred last week that Open Look's days are numbered." "Open Look will become a great trivia question." "Tow or three years from now, Open Look will have disappeared." I've been waiting to see it and now people are already pronouncing and perhaps celebrating its death. Is there any substance to these rumors? mark From don@brillig.umd.edu Wed Feb 8 12:05:16 1989 Date: Wed, 8 Feb 89 12:05:16 EST To: NeWS-makers@brillig.umd.edu Subject: High-res bitmap from News From: ajb@retina.mitre.org (Alan J. Broder) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) I have an application which requires me to produce a full-page equivalent of the 300-dpi bitmap which would be produced by a PostScript printer. The people at Adobe told me that in fact, the Display PostScript on the NeXT machine does this; the NeXT laser printer is not a PostScript printer, rather it expects a pre-rasterized 300dpi raw bitmap which is produced using Display PostScript on the NeXT CPU (with output to a bitmap file rather than to a screen window). My question is this: Is there any way for me to achieve the same result using NeWS on a Sun ? That is, will NeWS allow me to render my postscript to a buffer or a file (instead of the screen) at the equivalent of 300dpi resolution ? If this is not possible, does anyone know of a postscript printer simulator which will produce such an output ? (There are already products on the market for PC's which will, in effect, convert your "dumb" laser printer into a postscript printer by rasterizing on the P.C.). Please send replies direct to me as I am new on this list. I will summarize if there is any interest. Thanks Alan J Broder ajb@cornea.mitre.org <------------ use this address The MITRE Corporation Image Processing Technology Center From don@brillig.umd.edu Thu Feb 9 14:33:28 1989 Date: Thu, 9 Feb 89 14:33:28 EST To: NeWS-makers@brillig.umd.edu Subject: Another dumb bug in pspp From: siegel@hc.dspo.gov (josh Siegel) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) This fixes a few more silly bugs on my part... There were some comment line trucations and I blew away existing comment indentations. Also, if a string larger then BUFSIZ (for example, 23,000 characters long) came in, pspp dumped. These are now fixed. --Josh Siegel diff -r -c pspp.n/pspp.l pspp/pspp.l *** pspp.n/pspp.l Thu Feb 9 09:37:02 1989 --- pspp/pspp.l Thu Feb 9 09:36:41 1989 *************** *** 8,13 **** --- 8,17 ---- You may copy the pspp kit in whole or in part as long as you don't try to make money off it, or pretend that you wrote it. + Version 0.07 + Fixed two more comment bugs. + Fixed a core dump when I get a string over BUFSIZ (stdio.h) long. + Version 0.06 Fixed comment lines getting stuck together (bug by Dave Yost). *************** *** 118,123 **** --- 122,133 ---- default: break; } i++; + if(i >= BUFSIZ-1) { + yytext[i]= '\0'; + newline(); + fprintf(yyout,"%s",yytext); + i = 0; + } } yytext[i]= '\0'; newline(); *************** *** 124,130 **** fprintf(yyout,"%s",yytext); } ! \{[ \t]*\} { /* Yet another special case */ newline(); fprintf(yyout,yytext); } "def" { /* Rule 3 */ if(check_flag(FLAG_DB)) --- 134,143 ---- fprintf(yyout,"%s",yytext); } ! \{[ \t]*\} { /* Yet another special case */ ! newline(); ! fprintf(yyout,yytext); ! } "def" { /* Rule 3 */ if(check_flag(FLAG_DB)) *************** *** 291,298 **** parseflag(&yytext[3]); neednew=1; } ! [^^]\%.* { /* 11 */ ! yytext[yyleng-1]='\0'; fprintf(yyout,"%s",yytext); neednew=1; } --- 304,311 ---- parseflag(&yytext[3]); neednew=1; } ! [^^][ \t]*\%.* { /* 11 */ ! /* yytext[yyleng-1]='\0'; */ fprintf(yyout,"%s",yytext); neednew=1; } -- Josh Siegel (siegel@hc.dspo.gov) I like using a C-47A "puff dragon" to go shooting beer cans with. From don@brillig.umd.edu Thu Feb 9 16:33:20 1989 Date: Thu, 9 Feb 89 16:33:20 EST To: NeWS-makers@brillig.umd.edu Subject: Re: input extensions? From: voder!wlbr!mh@ucbvax.Berkeley.EDU (Mike Hoegeman) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) In article <2651@daisy.UUCP> klee@daisy.UUCP (Ken Lee) writes: >I've been hearing about a number of X output extensions, such as PEX, >but am wondering if anyone is working on input extensions. The NeWS >concept of lightweight, server-resident, event handlers seems to be a >major performance gain for highly interactive clients. > >Some simple examples: > return a string, instead of every typed character > return region enter/exit, instead of motion events or creating > (not so free) windows > various forms of grid snapping > >Although NeWS allows each client to define (at run time) its own >server extensions, a small set of hard coded extensions would still >be valuable. We do a fair amount of output/input extending w/ NeWS and it works great!! I think it is a real mistake to "hard code" extensions Our NeWS machines have to "share" a keyboard and a mouse with a second (radar display) machine. the keyboard and mouse are hooked up to NeWS machine and when the user hits the 'switch' key we redirect all the keyboard and mouse events through a serial line, translating the keys into what the other machine wants for key/mouse codes. It works great!! and it's more than fast enough for the job. Here's another example. We also have a NeWS machine hooked up to a large screen display. There are a whole bunch of NeWS machines in one room which are facing the large screen machine. With NeWS we wrote a little i/o extension that let's any user use their keyboard and mouse on the large screen display simply by moving their mouse past the top of their screen, their cursor then warps to the large screen display and they can log in , run programs, use menus, whatever, on the large screen display. To move back to their local machine they simply move their mouse cursor down past the bottom of the large screen and they are warped back to their local machine. It's really neat! and best of all WE DID IT WITHOUT HACKING ANY OF THE SERVER!. These two i/o extenders took a grand total of two or three days to code and have been running great ever since. It even runs using different styles of keyboards. just specify which postscript dictionary it should use for the keycode mapping and it's all set. Anyway, what I'm getting at is it's worth considering doing extensions at run time and NOT hardcoding them into the server. It works and it's a helluva lot more flexible then wiring it into the server. I wish X would gravitate more toward being extensible. -mike (mike@etn.wlv.eaton.com) From don@brillig.umd.edu Thu Feb 9 22:38:20 1989 Date: Thu, 9 Feb 89 22:38:20 EST To: NeWS-makers@brillig.umd.edu Subject: NeWS uses Display Postscript? From: tigger!adamb@boulder.colorado.edu (Adam 'Velvis' Beguelin) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) I just read an article in 1/89 issue of Byte about X windows. The last section says that NeWS uses Display Postscript. This isn't true is it? Please respond via email. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Adam Beguelin Computer Science Department Box 430 adamb@boulder.Colorado.Edu University of Colorado 303/492-7906 Boulder, CO 80309-430 From don@brillig.umd.edu Thu Feb 9 22:39:01 1989 Date: Thu, 9 Feb 89 22:39:01 EST To: NeWS-makers@brillig.umd.edu Subject: NeWS and Display PostScript From: mailrus!rioja.ifs.umich.edu!ric@g.ms.uky.edu (Richard Campbell) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) What's the beef between Adobe and Sun?? I've just started reading Adobe's Display PostScript System Reference manual and it sounds like Adobe doesn't like Sun's NeWS system at all. In the manual's Question and Answers section, Adobe proudly reports that several OEMs are supporting DPS including NeXT, DEC, and IBM. Then, on the *last* page, the question pops up, What about NeWS? Adobe says that NeWS is an imaging model and window system instead of DPS which is just an imaging model; that NeWS's imaging model is not compatible with PostScript; that NeWS's extensions are not the same thing as DPS; and that NeWS can't use the Adobe Type Library. It was my understanding that Sun had committed to full Postscript and DPS compatibility. Given this, and the fact that DPS and NeWS are practically the same thing (DPS has .psw files; NeWS .cps files, et alia, ad nauseum...), what happened between the two companies to cause such low esteem and bad feelings? Why the attempt by Adobe to effectivly scuttle NeWS??? From don@brillig.umd.edu Thu Feb 9 22:39:38 1989 Date: Thu, 9 Feb 89 22:39:38 EST To: NeWS-makers@brillig.umd.edu Subject: Re: High-res bitmap from News From: sgi!msc%ramoth.SGI.COM@ucbvax.Berkeley.EDU (Mark Callow) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) In article <8902081448.AA01383@retina.mitre.org>, ajb@RETINA.MITRE.ORG (Alan J. Broder) writes: > > I have an application which requires me to produce a full-page equivalent > of the 300-dpi bitmap which would be produced by a PostScript printer. > > My question is this: Is there any way for me to achieve the same result using > NeWS on a Sun ? That is, will NeWS allow me to render my postscript to a > buffer or a file (instead of the screen) at the equivalent of 300dpi > resolution ? It occurs to me that using a retained canvas and setting the transformation matrix to an appropriate matrix for 300dpi might work. I haven't tried it but it seems worth a shot. -- -Mark From don@brillig.umd.edu Fri Feb 10 14:25:03 1989 Date: Fri, 10 Feb 89 14:25:03 EST To: NeWS-makers@brillig.umd.edu Subject: Re: NeWS and Display PostScript From: jcricket!sjs@bellcore.com (Stan Switzer) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) > What's the beef between Adobe and Sun?? I've just started reading > Adobe's Display PostScript System Reference manual and it sounds > like Adobe doesn't like Sun's NeWS system at all. Indeed, Adobe and Sun should rally to what is certainly their common cause. Notwithstanding the IBM NeXTStep deal, Microsoft has been making noises along the lines of "What's so great about PostScript? The presentation manager does the same stuff." Now, we all know that this is only true to a very rough approximation, but PC types run leminglike whichever way Gates & Co. point. But is it all hype? Decide for yourself: they are already talking about developing their own page description language. We risk seeing all of the benefits of this wonderful technology swept away because of least-common-denominatorism of the very worst kind. Let's face it, X and PM application developers will be very hesitant to use DPS extensions because it will limit their products to those users who run extended servers. ONLY with NeWS can you say with certainty "It's in there." Only in NeWS can a programmer confidently take advantage of the power of PostScript. Now the problem is this: What's in it for Adobe? Let's examine some possibilities: 1) Sun goes fully DPS compatable in NeWS and licenses some documentation, technology, or something from Adobe. 2) Sun licenses Adobe font format technology and consequently can use Adobe fonts. This makes NeWS better (much better), and creates a whole new (very big) market for Adobe fonts. Adobe fonts are very fine indeed. 3) NeWS/DPS creates new markets for Adobe software products such as Illustrator. 4) DPS display technology sells PostScript printers. There ARE ways for both parties to benefit from ending this stupid war. If Adobe and Sun cannot come to some kind truce about PostScript and don't start working together, both NeWS and eventually PostScript will go down the drain. This would be a damn shame. Stan Switzer sjs@ctt.bellcore.com "Why, sometimes I've believed as many as six impossible things before breakfast." [Now, where DID I put that bagel?] From don@brillig.umd.edu Sat Feb 11 15:36:16 1989 Date: Sat, 11 Feb 89 15:36:16 EST To: NeWS-makers@brillig.umd.edu Subject: Garbage collection From: munnari!murtoa.cs.mu.oz.au!cs.mu.oz.au!mwp@uunet.uu.net (Michael Paddon) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Can anybody give a complete definition of how garbage collection works in NeWS 1.1? The manual indicates that whenever any process dies (I presume either killed or terminated), all its stacks are garbage collected. Each composite object has a ref count which tells NeWS when it is safe to throw something away. All quite straightforward, but... Is it possible to garbage collect objects while a process is running? Does "undef" cause immediate collection? What happens to objects that have no references? ie. if I have a process {(hello world) show} fork is the space used by the string ever reclaimed? If so, when? Any thing else that I need to know about garbage collection? ======================================================== | Michael Paddon (mwp@munnari.oz.au) | | Department of Computer Science, Melbourne University | ======================================================== From don@brillig.umd.edu Sat Feb 11 15:36:27 1989 Date: Sat, 11 Feb 89 15:36:27 EST To: NeWS-makers@brillig.umd.edu Subject: Re: NeWS and Display PostScript From: cs.utexas.edu!sm.unisys.com!csun!polyslo!lchirica@tut.cis.ohio-state.edu (Laurian Chirica) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) > I've just started reading > Adobe's Display PostScript System Reference manual Could anyone please tell me how I can get a copy? -- Laurian M. Chirica (lchirica@polyslo.calpoly.edu) Computer Science Department ..!ucbvax!voder\ California Polytechnic State University ..!sdcrdcf!csun |!polyslo!lchirica San Luis Obispo, CA 93407-(805)756-1332 ..!lll-crg!csustan/ From don@brillig.umd.edu Sat Feb 11 15:37:34 1989 Date: Sat, 11 Feb 89 15:37:34 EST To: NeWS-makers@brillig.umd.edu Subject: How to get the DPS manual From: phri!roy@nyu.edu (Roy Smith) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) lchirica@polyslo.CalPoly.EDU (Laurian Chirica) writes: > Could anyone please tell me how I can get a copy [of Adobe's Display > PostScript System Reference manual]? What I did is send off $30 to: DPS Reference Manual Offer Adobe Systems Incorporated 1585 Charleston Road P.O. Box 7900 Mountain View, CA 94039-7900 Whether this will work for you or not, is a good question. A few weeks after our order went out, a copy of The Red Book showed up in the mail. I called Adobe and told them that they mis-shipped and they said to send the book back and the would send the DPS docs when they were ready (they were being printed at the time). Some time (well over a month) later, I still hadn't gotten the DPS stuff so I called and was told that you had to be approved to order the DPS reference manual! This didn't make sense, so I asked them what they meant and was told that not just anybody could order the DPS manual, that you had to be on the approved list. When I protested that I had already paid for it and nobody had said anything about approvals, they said that if it turns out that I wasn't approved, I would get a refund of my $30! Now, friends, this is about the most absurd thing I have ever heard of; not being allowed to buy a book unless you're "approved". Anyway, I yelled and screamed a bit and a day or so later somebody called me back to say that I would be getting the manual. It just showed up the other day; I havn't had a chance to do anything more than take the pages out of the shrink-wrap and put them in the binder. There was also a cover letter telling me that this was my "free complementary copy" of the reference manual. Maybe you only get it for free if you're approved and otherwise you have to pay for it? I could understand that, but that's not what I was told on the phone. -- Roy Smith, System Administrator Public Health Research Institute {allegra,philabs,cmcl2,rutgers}!phri!roy -or- phri!roy@uunet.uu.net "The connector is the network" From don@brillig.umd.edu Sun Feb 12 16:52:14 1989 Date: Sun, 12 Feb 89 16:52:14 EST To: NeWS-makers@brillig.umd.edu Subject: Multiple desktops under NeWS From: oliveb!pyramid!prls!philabs!linus!gomez.mitre.org!sheffler@ames.arc.nasa.gov (Thomas J. Sheffler) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) I started wondering how a collection of desktops could be managed under NeWS. A desktop would be simply a set of windows. Switching from one desk to the other should be easy and should allow an arbitrary grouping of windows. My first attempt at this is presented below. The application window has a number of buttons. The "ToDeskX" buttons bring up one of three desktops. The "All" button brings up ALL windows. Sorting windows into the desktops is done by pressing "NextWindow". This selects a window and hilites the one selected by flashing it (you'll be able to tell). Put it in one or more desks with the "InDeskX" buttons, or in all three with "InAll". Because the creation of new windows is not caught and the exit of other windows is not noticed, there is a "RESET" button. This releases all windows from the desks and allows you to start over. The main reason this is needed is to release zombie canvases. When a window application exits but is in a desktop, a reference to that canvas is still in the desktop structure. The canvas will not disappear until the reference is released: "reset" does this. No guarantees come with this software. As a hint, if something goes wrong, use the "AllWindows" rootmenu menu to send "Open" or "Close" to all windows to get them back. This package achieves its effect by selectively mapping and unmapping windows -- maybe there's a better way. Any comments/improvements would be appreciated. Send them to sheffler@gateway.mitre.org -Tom ===================== C U T H E R E ====================================== #! /usr/NeWS/bin/psh % Provide a multi-desktop capability for NeWS % Upon startup, all existing windows are located and placed in a list. % Pressing the "NextWindow" button causes the selection of the next % window in the list - it is hilited by flashing it on the screen and % bringing it to the top. The window may be placed in one of the % three desktops with the "InDesk" buttons, or in all three desktops % with the "In All" button. After windows have been placed in desks, % a desktop may be selected with the "ToDesk" buttons, or the "All" % button to re-map all windows. % Because the desktop manager doesn't know about windows dying or starting % up, the "Reset" button must be used to relocate windows. This % destroys desktop lists. % Tom Sheffler % MITRE % February 1989 systemdict /DeskWin known not { % only load the class if not known systemdict begin /DeskWin DefaultWindow dictbegin % instance variables dictend classbegin % class variables first /MaxWin 50 def % max number of windows? /Desk1 MaxWin dict def % dictionaries for desk-tops /Desk2 MaxWin dict def /Desk3 MaxWin dict def /Every MaxWin dict def % list EVERY window found (w/ AllWin) /UniqueCycle 0 def % for cycling through windows /currentWin null def % used with function /NextWindow /controlWin null def % keep track of the ONE main window % Clear one entry of a dict in a /forall loop /clearone { % key value => - pop null store } def % Clear all entries in the dicts (to return to VM mgr) /clearall { /currentWin null def % release this one /Desk1 null def % release all storage /Desk2 null def /Desk3 null def /Desk1 MaxWin dict def % and create new /Desk2 MaxWin dict def /Desk3 MaxWin dict def } def % Go thru the dicts clearing out DEAD windows. % Treat the buttons as frame controls. /CreateFrameControls { /CreateFrameControls super send /b1 (ToDesk1) {/ToDesk1 DeskWin send} FrameCanvas /new ButtonItem send 20 -60 /move 3 index send def /b2 (ToDesk2) {/ToDesk2 DeskWin send} FrameCanvas /new ButtonItem send 90 -60 /move 3 index send def /b3 (ToDesk3) {/ToDesk3 DeskWin send} FrameCanvas /new ButtonItem send 160 -60 /move 3 index send def /b4 (All ) {/ToAll DeskWin send} FrameCanvas /new ButtonItem send 230 -60 /move 3 index send def /b5 (Next Window) {/HiliteNext DeskWin send} FrameCanvas /new ButtonItem send 70 -110 /move 3 index send def % /b6 (Find) {/Find DeskWin send} FrameCanvas /new ButtonItem send % 110 -110 /move 3 index send def /b7 (Reset) {/Reset DeskWin send} FrameCanvas /new ButtonItem send 180 -110 /move 3 index send def /b8 (InDesk1) {/PutDesk1 DeskWin send} FrameCanvas /new ButtonItem send 20 -160 /move 3 index send def /b9 (InDesk2) {/PutDesk2 DeskWin send} FrameCanvas /new ButtonItem send 90 -160 /move 3 index send def /b10 (InDesk3) {/PutDesk3 DeskWin send} FrameCanvas /new ButtonItem send 160 -160 /move 3 index send def /b11 (In All) {/PutAll DeskWin send} FrameCanvas /new ButtonItem send 230 -160 /move 3 index send def % Resize them all for the first time [b1 b2 b3 b4 b5 b7 b8 b9 b10 b11] { { location ObjectWidth ObjectHeight reshape paint } exch send } forall % Start processes for listening to buttone [b1 b2 b3 b4 b5 b7 b8 b9 b10 b11] forkitems } def % Repaint the buttons whenever frame controls repainted /PaintFrameControls { /PaintFrameControls super send [b1 b2 b3 b4 b5 b7 b8 b9 b10 b11] { { paint } exch send } forall } def % The /new method for this class only allows one /contolWin to Exist /new { % only allow one to exist! controlWin null eq { /new super send % get the window dup /controlWin exch def % keep track of this one begin % open the new dict end 500 500 310 200 /reshape controlWin send /map controlWin send % make visible } if DeskWin /currentWin controlWin put % an initial value } def % Try to release all VM (so no zombie canvases) /DestroyClient { % reset /controlWin DeskWin /Every null put clearall % clear the rest of them DeskWin /currentWin null put DeskWin /controlWin null put % before "super send" ?? % else get ZOMBIE canvas /DestroyClient super send } def % Reset: clear everything and start over /Reset { {/map self send} AllWin % just in case! /Every null def clearall % clear the rest of them /currentWin controlWin def FindWindows } def % Add a window to /Every. Each window is a key in a dict, the % value assoc w/ the key is an index. These indices are incremented % when the win is accessed thru /NextWindow. When no more values in the % dict match /UniqueCycle, a new cycle begins. /AddWin { % window => - % dup % => win win % [ exch ] (Add Window:%\n) exch dbgprintf % => win Every exch UniqueCycle put % put window in /Every dict } def % Find every window and place in every /FindWindows { % - => - % (IN FindWindows!\n) [ ] dbgprintf /Every null def % free VM /Every MaxWin dict def % a new dict % save each window {self /AddWin DeskWin send} AllWin } def % For debugging only, print all windows in dict /Every /PrintWindows { Every { [ exch ] (Value:%) exch dbgprintf [ exch ] (Key:%\n) exch dbgprintf } forall } def % Check if a window (kept in a list) is a ZOMBIE, return null if it is /CheckZombie { % win => win/null dup % win win /FrameEventMgr get % win val/null? % (In ZOMBIE:) [] dbgprintf % dup [exch] (%\n) exch dbgprintf null eq {pop null} if % replace w/ null if eq null } def % This function finds a window in the current cycle, or null if % there are none. A result is returned AND /currentWin is left % the value too. /NextInWindowCycle { /currentWin null def % set to null Every { % => win value UniqueCycle eq { dup % => win win Every exch UniqueCycle % => win dict win unique 1 add put % => win /currentWin exch def exit % exit the loop } { pop % suck up the win } ifelse } forall currentWin % the return value } def % Move on to the next cycle if cycling thru windows and none % found with NextWindow /NextCycle { /UniqueCycle UniqueCycle 1 add def } def % This function continually returns a new window each time called. /NextWindow { % => win NextInWindowCycle dup null eq { pop % throw away null?? NextCycle NextInWindowCycle% begin next cycle } if % otherwise, return the win } def % Hilite Window by bringing to top, hiliting /HiliteWindow { % win => - dup /totop exch send % bring to top dup /unmap exch send % unmap it /map exch send % map it } def % Hilite next window and select it /HiliteNext { % - => win NextWindow HiliteWindow } def % Given a dict of windows, map only those /MapDesk { % dict => - % Can't use 'AllWin' because it blocks Every { pop % get rid of value CheckZombie % see if win is a zombie dup null eq % => win/null f/t {pop} {/unmap exch send} ifelse } forall /map controlWin send % map the control window % DEBUG % dup % dup the dict % {[exch] (Value:%) exch dbgprintf % [exch] (Key:%\n) exch dbgprintf % } forall % (dict is still on the stack) { pop % get rid of value CheckZombie dup null eq {pop} {/map exch send} ifelse } forall } def /MapAll { % this one's easy {/map self send} AllWin } def % Put the current window, currentWin, in a desk /PutDesk { % dict => - currentWin % => dict currentWin UniqueCycle put } def % The methods called from the button's notify procs /ToDesk1 {Desk1 MapDesk} def /ToDesk2 {Desk2 MapDesk} def /ToDesk3 {Desk3 MapDesk} def /ToAll { {/map self send} AllWin } def /PutDesk1 {Desk1 PutDesk} def /PutDesk2 {Desk2 PutDesk} def /PutDesk3 {Desk3 PutDesk} def /PutAll {Desk1 PutDesk Desk2 PutDesk Desk3 PutDesk} def classend def end % of systemdict! } if % matches "known not" at beginning framebuffer /new DeskWin send pop % throw away? /FindWindows DeskWin send From don@brillig.umd.edu Sun Feb 12 21:12:08 1989 Date: Sun, 12 Feb 89 21:12:08 EST To: NeWS-makers@brillig.umd.edu Subject: Re: input extensions? From: mcvax!kth!enea!naggum!isncr!m2cs!frode@uunet.uu.net (Frode Odegard) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Before switching to NeWS (oh, hill thee...), I used to run SunView on my 3/60 with a color montor and a monochrome monitor. Having to monitors was wonderful, and I'm sure it made me more productive. I tried the same think with NeWS, but what happened was that the keyboard went wild. This wasn't surprising, after all the two display servers were sharing it. Can I make NeWS work this way without having to buy the source code for the display server? [Of course, I would also like to be able to move windows and icons back and forth, but I expect that's too much to hope for...] - Frode -- | Frode L. Odegard |"The world is coming to an end! Repent and| | Modula-2 CASE Systems |rm /bin/cc" | | NORWAY (EUROPE) | | | Email: frode@m2cs.uu.no | | From don@brillig.umd.edu Mon Feb 13 15:44:19 1989 Date: Mon, 13 Feb 89 15:44:19 EST To: NeWS-makers@brillig.umd.edu Subject: Sun Terminal & Executive Prompt. From: mcvax!reading.ac.uk!Anthony.D.Worrall@uunet.UU.NET Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Dear NeWS Makers Two Quick Questions. Has anybody got a terminal in NeWS that is fully compatible with the Sun Terminal, or a vt100 with its own identification sequence, or is it possible to make psterm respond to an identification request? Is it possible to set a prompt in the psh executive mode? Laser writers use a prompt and it makes things so much more user friendly. Anthony.Worrall@Reading.Ac.Uk From don@brillig.umd.edu Mon Feb 13 21:25:56 1989 Date: Mon, 13 Feb 89 21:25:56 EST To: NeWS-makers@brillig.umd.edu Subject: Re: NeWS and Display PostScript From: "Michael_Powers.Henr801M"@Xerox.COM Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) >If Adobe and Sun cannot come to some kind truce about PostScript and >don't start working together, both NeWS and eventually PostScript will >go down the drain. This would be a damn shame. I don't think that Sun and Adobe will be able to "work together" outright. The reason why Adobe has done so well with Postscript in the first place is because of it's low profile. (What I mean by low profile is that: 1) it is not a major hardware vendor 2) it is not allied directly with one particular vendor and 3) it's a relatively small company). If Adobe were to push NeWS or even appear to be pushing NeWS then I do believe that the OSF members (who also happen to be OEMS of DPS) would be quite upset. Adobe cannot afford that. They cannot alienate DEC, IBM, HP, and the whole PC world just to gain the advantage of NeWS customers. Personally I agree that it would be nice to have Adobe and Sun working together rather than playing these political olympics. But it just is not going to happen with the current client of OSFism and the workstation war that is heating up. Mike Powers Xerox Corp. powers.henr801m@xerox.com "What's InterPress?" :) From don@brillig.umd.edu Mon Feb 13 21:26:05 1989 Date: Mon, 13 Feb 89 21:26:05 EST To: NeWS-makers@brillig.umd.edu Subject: X/SunView/View2 forms package avail? From: voder!wlbr!etn-rad.eaton.com!markus@ucbvax.Berkeley.EDU (Markus Richardson) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) I am looking for a window-based forms package which enables field data typing/ validation operating in a GUI like SunView or X. I have talked to many of the major database vendors (such as Oracle, Informix, and Ingres) and standalone forms vendors (such as C-Scape and Windows for Data) but have been surprised to find that they only support character oriented displays like the vt100 terminal. The SunView environment supports primitives for text field validation (via text panels) so why isn't there such a package available? Alternatively, the X environment would be even better (for us) but no such primitives for building forms exist (that I know of) and it appears that no company is willing to develop something like this for anything but the PC. Any leads to such a forms package/generator would be much appreciated! The only stipulation is that it operate in the X or SunView/View2 environment but not through xterm or a tty subwindow! Rumors, pending rumors and other such info are welcome as well as the cold hard facts :-) Please email to me and I will summarize if enough interest is shown. If it helps, here is some 'thanks in advance'. { voder,hacgate,jplgodo }!wlbr!etn-rad!markus markus%etn-rad@etn-wlv.eaton.com From don@brillig.umd.edu Thu Feb 16 02:18:47 1989 Date: Thu, 16 Feb 89 02:18:47 EST To: NeWS-makers@brillig.umd.edu Subject: Re: NeWS and Display PostScript From: unicads!stefan@boulder.colorado.edu (Stefan) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) In article <890213-155306-7860@Xerox>, "Michael_Powers.Henr801M"@XEROX.COM writes: > >If Adobe and Sun cannot come to some kind truce about PostScript and > >don't start working together, both NeWS and eventually PostScript will > >go down the drain. This would be a damn shame. > > I don't think that Sun and Adobe will be able to "work together" outright. > > [some reasons why not...] > > Personally I agree that it would be nice to have Adobe and Sun working > together rather than playing these political olympics. But it just is not > going to happen with the current client of OSFism and the workstation war > that is heating up. > > Mike Powers Well, I don't happen to agree with Mike's perspective on this issue. I'll generalize here and say that the rank-and-file at Adobe Systems seem to bear no ill will towards Sun (indeed, you have only to look at their hardware :->). However, I don't think the same may be said about the views of "those in charge". Sun has made a number of attempts to get Adobe to pull the NeWS wagon together with them. All seem to have been met with disdain (if not legal threats). [disclaimer here - I have no knowledge of any overtures made in the last 7-8 months]. The problem lies not with Sun, but with Adobe. I think there is a general perception at Sun that Adobe sees (saw?) NeWS as a threat to the future of PostScript (their lifeblood). When NeWS came along it represented a significant advance over "printer" PostScript. The extensions to PostScript that made it interactive seemed to set a whole new direction. That's the threat that Adobe perceives - the loss of the chance to guide the future direction of PostScript. I think it has little to do with OSF or their relationship to other companies (re Powers' comments). As long as NeWS is perceived by Adobe to threaten Adobe's control of the future direction of PostScript they will continue to put it down (as non-conforming, etc.). I know it's bullshit but what can you do with small minds? Stefan -- Stefan Fielding-Isaacs Unicad, Boulder, Co. (303) 443-6961 CAD/UIMS software sun!unicads!stefan or boulder!unicads!stefan From don@brillig.umd.edu Thu Feb 16 02:18:58 1989 Date: Thu, 16 Feb 89 02:18:58 EST To: NeWS-makers@brillig.umd.edu Subject: Destroying windows under NeWS 1.1 From: toth@tut.cis.ohio-state.edu (Susan Korda Toth) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) We had a pre-beta NeWS 1.1 before and we have NeWS 1.1 now. In the older version, when I gave an 'exit' in the program, all windows started by the program disappeared. Under our new NeWS version it doesn't happen, my window called up in the program remains on the screen, so I used a /destroy win send in the program before leaving (win is the identifyer of my window). But it didn't help either. I don't know how to get a window disappeared. Thanks in advance for any help -- Susan Toth Systems programmer CIS, The Ohio State University From don@brillig.umd.edu Thu Feb 16 02:20:44 1989 Date: Thu, 16 Feb 89 02:20:44 EST To: NeWS-makers@brillig.umd.edu Subject: Re: NeWS and Display PostScript From: lts!amanda@uunet.uu.net (Amanda Walker) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) stefan@unicads.UUCP (Stefan) writes: [ ... ] That's the threat that Adobe perceives - the loss of the chance to guide the future direction of PostScript. I think it has little to do with OSF or their relationship to other companies (re Powers' comments). I think that given the relatively small size of Adobe, that they are not entirely unjustified in this, but there also seems to be another issue at work as well, and it's one that many other companies in this industry, large and small, seem to have problems with. It can be best summed up in the phrase, "but that's not how we planned to use it!" You can see it in the Display PostScript vs. NeWS debate. Adobe's position seems to be that PostScript *should not* be used to implement a window system, even if it can be. Apple has held a similar view with regards to AppleTalk--for several years they hotly claimed that AppleTalk *should not* be used for big networks, or for cheap TCP/IP transport, or whatever, even though it works quite well for these things. They are finally reacting to market demand, but it's still painfully slow going... In a sense, the cleanliness of PostScript's design works against Adobe. Its very extensibility and flexibility means that it can be used for things besides imaging, whether or not Adobe designed it that way... -- Amanda Walker ...!uunet!lts!amanda / lts!amanda@uunet.uu.net InterCon, 11732 Bowman Green Drive, Reston, VA 22090 -- Calm down; it's only ones and zeros... From don@brillig.umd.edu Thu Feb 16 02:44:06 1989 Date: Thu, 16 Feb 89 02:44:06 EST To: NeWS-makers@brillig.umd.edu Subject: results of informal NeWS usage survey From: Eric Marshall Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Here are the results to my informal NeWS usage survey: > I would like to conduct an informal survey to find out > how many people are using NeWS on a regular basis, and on what > platforms. I am interested in how many people are using NeWS > in your organization, and the manufacturer, model number and > operating system of the platform which you run it on. If you > would like to respond for your entire organization, please indicate > this, so that I can watch for other members of your organization > responding also. I will summarize and post the results to the > net in a few weeks. I received a total of 39 responses, representing ~194 users. Most of those who responded reported 3-5 NeWS users at their site, with a maximum concentration of 20 NeWS users at one site (a university). Of the 39 responses, 20 were from commercial organizations, 12 were from universities, and 7 were from government agencies. Most of the respondents (34) use NeWS on Suns, 5 use MacNeWS on Machintoshs, 5 use 4Sight on Silicon Graphics IRISs, 2 use NeWS/2 on PS/2s, 1 uses a Raster Technologies machine, and 1 uses a HP machine. It is evident that a number of the respondents (25%) regularly use NeWS on multiple platforms. Thanks to all those who responded. Eric Marshall Software Productivity Consortium SPC Building 2214 Rock Hill Road Herndon, VA 22070 (703) 742-7153 CSNET: marshall@software.org ARPANET: marshall%software.org@relay.cs.net ---------------------------------------------------------------------- I'm just an X programmer gone straight. From don@brillig.umd.edu Thu Feb 16 02:44:12 1989 Date: Thu, 16 Feb 89 02:44:12 EST To: NeWS-makers@brillig.umd.edu Subject: Re: NeWS and Display PostScript From: adobe!greid@decwrl.dec.com (Glenn Reid) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Sigh. I guess I have to jump into this a little bit.... In article <335@unicads.UUCP> stefan@unicads.UUCP (Stefan) writes: >In article <890213-155306-7860@Xerox>, "Michael_Powers.Henr801M"@XEROX.COM writes: >> >If Adobe and Sun cannot come to some kind truce about PostScript and >> >don't start working together, both NeWS and eventually PostScript will >> >go down the drain. This would be a damn shame. >> >> I don't think that Sun and Adobe will be able to "work together" outright. >> >> [some reasons why not...] >> >> Personally I agree that it would be nice to have Adobe and Sun working >> together rather than playing these political olympics. But it just is not >> going to happen with the current client of OSFism and the workstation war >> that is heating up. >> >> Mike Powers I basically liked this message. Our business is to make our customers happy, whoever they may be. We don't have the luxury of being able to develop technology on the off chance that somebody within the user community might use it, because (as it was pointed out) we are not a hardware company. We depend on people licensing the technology from us. > Sun has made a number of attempts to get Adobe to pull the NeWS wagon > together with them. All seem to have been met with disdain (if not > legal threats). [disclaimer here - I have no knowledge of any overtures > made in the last 7-8 months]. Adobe has also made a number of attempts to get Sun to license Display PsotScript from us, all of which have met with, well, non-action. I certainly wouldn't use a word like "disdain" without having been at the meeting myself :-) The disagreements hinge at least in part on the controversy over source code. Adobe is a system software technology company, and Sun is a hardware and software company. It would not make sense for us to license something from them just to sell back to DEC :-) > The problem lies not with Sun, but with Adobe. I think there is a > general perception at Sun that Adobe sees (saw?) NeWS as a threat to > the future of PostScript (their lifeblood). When NeWS came along it > represented a significant advance over "printer" PostScript. The > extensions to PostScript that made it interactive seemed to set a > whole new direction. Adobe is realistically not in a position to license NeWS, are they? We have a proprietary implementation of a PostScript interpreter dating from 1985, and are well known as its inventor. What would you have us do differently? Adobe has already licensed Display PostScript to IBM, DEC, NeXT, and Sytex, and probably will license it to many more. It is our own technology and it is not positioned directly against NeWS. NeWS is different, and although we perhaps could have copied it, licensed it from Sun, or been compatible with it in other ways, it would not have met our customers' needs. If it would have, our customers could have used NeWS to begin with. The incompatibilities are due to different ideas as to how it should be done, and are not "deliberately" different to force incompatibility. That approach doesn't lend itself to good technology, which is what we try to develop. > That's the threat that Adobe perceives - the loss of the chance to > guide the future direction of PostScript. I think it has little to > do with OSF or their relationship to other companies (re Powers' > comments). Adobe defined the PostScript language, and we will continue to do so. So-called "clones" which implement additional verbs will always exist. [And I'd rather not take a position on whether or not NeWS is a clone; the statement is still generically true]. And new PostScript language procedures can be defined at any moment, even by user-level programs. Realistically, I don't think there is a threat to the future direction of PostScript. We are, naturally, worrying about the future direction of our products. PostScript is our product. It is not like FORTRAN, which is just a programming language that has many implementations. [No flames about this, please]. > As long as NeWS is perceived by Adobe to threaten Adobe's control > of the future direction of PostScript they will continue to put > it down (as non-conforming, etc.). I know it's bullshit but what > can you do with small minds? We don't put NeWS down, we have just implemented a different strategy. We do try to be careful about the terminology, and we don't like people to call it "PostScript", because that is our registered trademark. If you call it NeWS and it works for you, then we are very happy with that, because it indeed supports the spirit of the PostScript language. Display PostScript is now a product. NeWS is a product, I think. They are perhaps different solutions to the same problem, but they are not compatible at the moment. Of the two paths to compatibility, we would simply like to see Sun license Display PostScript from us. Of course, I hate to participate directly in these controversies, but I do want our position to reasonably well understood. Glenn Reid Adobe Systems From don@brillig.umd.edu Thu Feb 16 19:22:40 1989 Date: Thu, 16 Feb 89 19:22:40 EST To: NeWS-makers@brillig.umd.edu Subject: Re: NeWS available for HP workstations ? From: messino@Sun.COM (Steven Messino) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Please contact Chris Maio 212 584 2736 for HP port. Steven Messino Window Technology Marketing Sun Micro Systems 415 336 2017 From don@brillig.umd.edu Thu Feb 16 19:27:56 1989 Date: Thu, 16 Feb 89 19:27:56 EST To: NeWS-makers@brillig.umd.edu Subject: Re: width and height of canvases? From: voder!pyramid!prls!philabs!nori!jcm@ucbvax.Berkeley.EDU (John Martin) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) In article <44718@philabs.Philips.Com> I write: >I would like to find out the width and height of an SRF image that has been >read with readcanvas. Does anyone know how to do this? >For example, after the line: > > (/c3/jcm/images/car.im8) readcanvas > >the new canvas is on the stack, and I would like to know what aspect ratio >to use in displaying it before I pass it to imagecanvas. In case anyone is interested, one possible way is: (/c3/jcm/images/car.im8) readcanvas dup setcanvas initclip clippath pathbbox /height exch def /width exch def pop pop imagecanvas Thanks to Laura Appleton, who (ironically) sits 50 feet away. John Martin Philips Labs jcm@philabs.philips.com hilips Labs jcm@philabs.philips.com From don@brillig.umd.edu Thu Feb 16 19:33:39 1989 Date: Thu, 16 Feb 89 19:33:39 EST To: NeWS-makers@brillig.umd.edu Subject: Postscript Patent? From: toto.cis.ohio-state.edu!pollack@tut.cis.ohio-state.edu (Jordan B. Pollack) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Glen Reid, writes: > We have a proprietary implementation of a PostScript interpreter dating > from 1985, and are well known as its inventor. Not to pick nits, but this is sorta like Apple or Microsoft claiming to have invented window systems. I thought that Postscript was just Xerox's INTERPRESS with a symbol table... Who holds the patents? From don@brillig.umd.edu Fri Feb 17 19:46:32 1989 Date: Fri, 17 Feb 89 19:46:32 EST To: NeWS-makers@brillig.umd.edu Subject: Re: NeWS and Display PostScript From: hpfcdc!hpfcmr!chan@hplabs.hp.com (Chan Benson) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) > Display PostScript is now a product. More info please. It is available as a porting base from Adobe? From particular manufacturers for their machines? The impression I got from the DEC/Adobe presentation at the recent X Conference was that it was not yet a product. -- Chan Benson HP Fort Collins chan@hpfcmi.HP.COM From don@brillig.umd.edu Fri Feb 17 20:53:17 1989 Date: Fri, 17 Feb 89 20:53:17 EST To: NeWS-makers@brillig.umd.edu Subject: NeWS archive and marble desktop From: "Michael_Powers.Henr801M"@Xerox.COM Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Hi folks, First I would like to ask what the address of the ftp site that has archived the NeWS public domain code is. I forgot to save the original mail note. Second, I would appreciate it if someone could mail me the marble (granite?) desktop that was mentioned a while ago? I'm assuming that what this consists of is a marble-like background pattern. Mike Powers powers.henr801m@xerox.com P.S. If there is anyone internal to Xerox who has retrieved the archived NeWS code I'd appreciate it if you would let me know. From don@brillig.umd.edu Mon Feb 20 15:30:35 1989 Date: Mon, 20 Feb 89 15:30:35 EST To: NeWS-makers@brillig.umd.edu Subject: news terminal etc... From: rohlicek%bbn.com@bbn.com (Robin Rohlicek) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Having just moved from SunView to NeWS 1.1 I could use pointers to a few things: 1) a reasonable terminal emulator. Preferably one in which tcsh works. 2) GNU Emacs support with a meta- key and mouse 3) A TeX previewer. Thanks, Robin Rohlicek BBN Labs Cambridge, MA From don@brillig.umd.edu Mon Feb 20 15:33:54 1989 Date: Mon, 20 Feb 89 15:33:54 EST To: NeWS-makers@brillig.umd.edu Subject: Re: news terminal etc... From: tinman.cis.ohio-state.edu!bob@tut.cis.ohio-state.edu (Bob Sutterfield) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) In article <36194@bbn.COM> rohlicek@bbn.com (Robin Rohlicek) writes: 1) a reasonable terminal emulator. Preferably one in which tcsh works. Try the Grasshopper Group's new psterm, available on the SUG SEX NeWS tape from ?.umd.edu or tut.cis.ohio-state.edu:pub/news-tape/*. 2) GNU Emacs support with a meta- key and mouse See columbia.edu:pub/ps-emacs.tar.Z. It works with 18.51 or 18.52. From don@brillig.umd.edu Tue Feb 21 17:21:27 1989 Date: Tue, 21 Feb 89 17:21:27 EST To: NeWS-makers@brillig.umd.edu Subject: Re: Sun Terminal & Executive Prompt. From: leah!rpi!pawl.rpi.edu!deven@csd4.milw.wisc.edu (Deven Corzine) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) In article <21145.8902131122@isgcl.cs.reading.ac.uk> Anthony.D.Worrall@reading.ac.UK writes: > Is it possible to set a prompt in the psh executive mode? Laser writers >use a prompt and it makes things so much more user friendly. Yes, indeed. This is one of the many changes I have in my user.ps. There is a slight bug in the input handling that will cause problems if you try to type a literal string with a newline in it. In other words: PS> (this is PS> a string) will not work correctly. (it will put (this is) on the stack and try to execute "a", "string", and ")"...) Aside from that, there is no limit to input line length. Here is the relevant code from my user.ps: -------------------------------------------------------------------------- systemdict /prompt {(PS> ) print flush} put systemdict /executive { % - => - (Execute current file) countdictstack 1 eq {100 dict begin} if % make sure there is a userdict (Welcome to NeWS Version ) print version print (\n) print /execfile currentfile dup null eq {pop (%stdin) (r) file} if def { { execfile status not { quit } if { { prompt () { execfile 256 string readline pop dup length 256 eq not {append exit} if append } loop % get a line of input, without size restrictions cvx exec } loop } stopped pop execfile status not { quit } if ExecutiveErrorHandler } loop } stopped { quit } if } put -------------------------------------------------------------------------- As in the Adobe implementation, you can change the prompt globally with: systemdict /prompt {(NeWS> ) print flush} put to change the default prompt to "NeWS> " or you could use: /prompt {(NeWS> ) print flush} def to change it locally, for a single psh. The whole setup works rather nicely. I gave this change along with some others to gregm@sun.com a while back; maybe it will make it into a later release. I have yet to get around to fixing the string problem, but aside from that, it seems ok. Try it, you'll like it. :-) Deven -- ------- shadow@pawl.rpi.edu ------- Deven Thomas Corzine --------------------- Cogito shadow@acm.rpi.edu 2346 15th Street Pi-Rho America ergo userfxb6@rpitsmts.bitnet Troy, NY 12180-2306 (518) 272-5847 sum... In the immortal words of Socrates: "I drank what?" ...I think. From don@brillig.umd.edu Tue Feb 21 19:15:22 1989 Date: Tue, 21 Feb 89 19:15:22 EST To: NeWS-makers@brillig.umd.edu Subject: Re: width and height of canvases? From: sgi!msc%ramoth.SGI.COM@ucbvax.Berkeley.EDU (Mark Callow) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Here's how to I do it /Cover BeautyDir (back.im8) append readcanvas def % Calculate the aspect ratio of the image /Ratio Cover setcanvas clippath pathbbox div 3 1 roll pop pop def -- -Mark From don@brillig.umd.edu Tue Feb 21 21:47:11 1989 Date: Tue, 21 Feb 89 21:47:11 EST To: NeWS-makers@brillig.umd.edu Subject: Toolplaces for NeWS From: nyser!cmx!goedel!chris@cunyvm.cuny.edu (Chris White) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Has anyone thought about how to implement a facility for capturing the state of windows in NeWS? Having a command like "toolplaces" in SunView is convenient because you don't have to reshape your windows each time you start up. The other half of this problem is not having a ".suntools" type file for NeWS -- this has been discussed before, but the problem is that there is no uniform way of telling a program that you want the main window to have a particular size and location. One solution might be to have each Unix process which has a NeWS window respond to a set of queries from outside the process. There must be a way to cycle though each of your running NeWS programs to make this work though. It would probably be inefficient for each process to listen for these relatively uncommon events -- perhaps we could use signals. But then what do we do about pure NeWS programs (no C code). These are completely inside of the NeWS server, so how could they respond to outside process queries? A more sophisticated functionality would be to have state saved has on the Macintosh. Much more information is preserved acrossed sessions than in Sunview. Could this be implemented by rewriting or subclassing LiteWindow? An even more sophisticated system would allow the copying of windows (and their program state if application-supported). Imagine being able to copy a terminal emulator and have the CShell state also duplicated...In fact, the entire desktop could be thought of as a MacDraw-type program, allowing duplication and grouping of anything on the screen. Okay, I'm rambling on. I guess what I'm saying is I'd like to see some discussion of these window system design ideas. Chris White Software Engineer Applied Logic Systems From don@brillig.umd.edu Tue Feb 21 21:54:17 1989 Date: Tue, 21 Feb 89 21:54:17 EST To: NeWS-makers@brillig.umd.edu Subject: terminal emulator From: toms@ncifcrf.gov Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) rohlicek%bbn.com@bbn.com (Robin Rohlicek) wrote: > could use pointers to a few things ... > a reasonable terminal emulator ... Is there a NeWS terminal emulator that simulates shelltool windows? I'm not looking for more than running vi, but I want a quality window! The VT102 `scrolling prototype' is slow, ugly and hard on the eyes, so I only use it to run graphics out of. I keep a bunch of Suntool windows (shelltool) around on my screen for normal work. The shelltool gives reasonably clear characters (read: could be better, but they work), a distinct background and is FAST. All my text work (like this letter) I do in a shelltool, but I run on top of NeWS to get the graphics (for which I'm forced to use the prototype). Also, what about a NeWS based debugger like dbxtool and a mail icon like mailtool? Tom Schneider National Cancer Institute Laboratory of Mathematical Biology Frederick, Maryland toms@ncifcrf.gov From don@brillig.umd.edu Thu Feb 23 01:21:28 1989 Date: Thu, 23 Feb 89 01:21:28 EST To: NeWS-makers@brillig.umd.edu Subject: TeX previewer From: ramani@na-net.stanford.edu (Ramani Pichumani) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) In response to the question regarding the availability of a TeX previewer for NeWS (rohlicek%bbn.com@bbn.com (Robin Rohlicek) ), I currently use dvitool which was written by Jeff McCarrell (jwm@renoir.berkeley.edu). I works fine but it is written for suntools (which of course means it runs on NeWS but rather presumptuously). If anyone knows of a TeX previewer written specifically for NeWS and/or is better than dvitool, I too would be interested in hearing about it. dvitool works fine except when you try to display fonts that aren't in your TeX fonts directory (i.e., there is no default font), you just get a bunch of dots on the screen in that case. Ramani Pichumani Dept. of Computer Science Stanford University ramani@na-net.stanford.edu From don@brillig.umd.edu Thu Feb 23 01:27:27 1989 Date: Thu, 23 Feb 89 01:27:27 EST To: NeWS-makers@brillig.umd.edu Subject: Re: How to get the DPS manual From: adobe!greid@decwrl.dec.com (Glenn Reid) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) In article <3678@phri.UUCP> roy@phri.UUCP (Roy Smith) writes: >lchirica@polyslo.CalPoly.EDU (Laurian Chirica) writes: >> Could anyone please tell me how I can get a copy [of Adobe's Display >> PostScript System Reference manual]? > >What I did is send off $30 to: > > DPS Reference Manual Offer > Adobe Systems Incorporated > 1585 Charleston Road > P.O. Box 7900 > Mountain View, CA 94039-7900 > >Whether this will work for you or not, is a good question. A few weeks after >our order went out, a copy of The Red Book showed up in the mail. I called >Adobe and told them that they mis-shipped and they said to send the book back >and the would send the DPS docs when they were ready (they were being printed >at the time). Some time (well over a month) later, I still hadn't gotten the >DPS stuff so I called and was told that you had to be approved to order the >DPS reference manual! This didn't make sense, so I asked them what they >meant and was told that not just anybody could order the DPS manual, that you >had to be on the approved list. When I protested that I had already paid for >it and nobody had said anything about approvals, they said that if it turns >out that I wasn't approved, I would get a refund of my $30! This is, of course, highly embarrassing. It stems from too many different people knowing too little. We really do have a consistent policy :-) Yes, you can order it if you just pay money for it, and there isn't any approval policy, other than cashing your check. The best thing to do is to address inquiries directly to Marci Eversole, the adminstrative assistant for Developer Support, rather than the more general address of "DPS Reference Manual Offer" (although she may not agree with me). The heck with generality and indirection, it works better if you send it to a person. The problem was that "DPS Reference Manual" and "PS Reference Manual" (usually thought of as the red book) are just too similar.... Thanks for your patience. -- Glenn Reid Adobe Systems Developer Tools & Strategies