From don@brillig.umd.edu Thu Feb 23 01:55:07 1989 Date: Thu, 23 Feb 89 01:55:07 EST To: NeWS-makers@brillig.umd.edu Subject: Interactive connection server From: thaeler@hc.dspo.gov (Bret K. Thaeler) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) % % Feel free to use this code as you like. Any questions, bugs, ideas, % problems, whatever would be greatly appreciated. % % Bret K. Thaeler % Los Alamos National Labs (MEE-10) % thaeler@hc.dspo.gov % % If you are like me you are probably at little bit worried about % strange people and programs connecting into your NeWS server. % So you probably run with NetSecurityWanted set to true so that % only machines in the RemoteHostRegistry dict (this is what the % 'newshost' commands adds and remove things from) can connect % to your machine. Unfortunitly sometimes you forget to add % a host before you try sending something from that host. Well, % this program solves all of that. % % This program will replace the connection server for your NeWS % server. This program will work exactly like its predicessor % execpt that if a machine is not registered it will popup a % little window asking you if you want to accept this connection % refuse this connections or accept and register this host for % all future connection attemps. The window appears such that % the YES or accept button is dirrectly under the mouse. You % can press the left mouse button or hit a return on the keyboard % so simple accept the connection. To refuse the connection or % register the new host you will have to move the mouse to the % appropriate button and press the left mouse key. This window % will also wake up and raise itself to the top of all the other % windows every couple of seconds just to make sure you didn't % forget a connection request. % % Note: all the options to 'newshost' still work exactly as % before. % % This file contains two parts: % The first part contains the new server code itself. This % code can be inserted directly into the 'init.ps' file in place % of the existing server or added to a 'user.ps' to superceed % the default server. % % The second part of this file contains code which can be used % to kill the running connection server thus allowing you to % start the new server up. This allows you to add this new % server without having to modify any files or having to reboot % your news server. % % WARNING!!!! % 1) The code which kills the running server relies on the % fact that the definition for the server '/server' has % not yet changed. Therefor you will need to kill the % running server BEFORE you define the code for the new % server. SEE THE COMMENTS FOR '/start_new_server'. % % 2) When modifing this code you should use great care. If % you happen to crash your connections server you will % not be able to start up any more jobs or connections. % Your only option will be to reboot your NeWS server. % % This is the code to define the new connection server into % the systemdict. % % New variables added into system dict: % /SecurityCanvas --- dict containing all the information about the % popup window. % /SecurityPopup --- The routine which popus up the window and waits % for a responce. % /LastConnectingHost --- The name of the last host to have connected % into the server. % /define_new_server { systemdict begin gsave /SecurityCans 7 dict dup begin /Times-Roman findfont 20 scalefont setfont /root framebuffer 200 75 createcanvas def /xcurs /xcurs_m root setstandardcursor root begin /Transparent false def /EventsConsumed /AllEvents def /Retained true def end root setcanvas 1 1 1 rgbcolor fillcanvas 0 0 0 rgbcolor strokecanvas /no root 66 37 createcanvas dup begin /Transparent false def /EventsConsumed /AllEvents def /Mapped true def /Retained true def end def no setcanvas 0 0 0 rgbcolor dup setcolor strokecanvas 10 10 moveto (NO) show /yes root 66 35 createcanvas dup begin /Transparent false def /EventsConsumed /AllEvents def /Mapped true def /Retained true def end def yes setcanvas 65 0 movecanvas 0 0 0 rgbcolor dup setcolor strokecanvas 10 10 moveto (YES) show /reg root 66 35 createcanvas dup begin /Transparent false def /EventsConsumed /AllEvents def /Mapped true def /Retained true def end def reg setcanvas 132 0 movecanvas 0 0 0 rgbcolor dup setcolor strokecanvas 10 10 moveto (REG) show /SecBoldFont /Times-Bold findfont 14 scalefont def /SecFont /Times-Roman findfont 12 scalefont def /SecurityAddInterests { createevent dup begin /Name LeftMouseButton def /Action UpTransition def /Canvas yes def end expressinterest createevent dup begin /Name ascii_keymap def /Action DownTransition def /Canvas yes def end expressinterest createevent dup begin /Name /AddFocusClient def /Action [ currentprocess yes] def end sendevent createevent dup begin /Name LeftMouseButton def /Action UpTransition def /Canvas no def end expressinterest createevent dup begin /Name LeftMouseButton def /Action UpTransition def /Canvas reg def end expressinterest createevent dup begin /Name /SecurityLift def end expressinterest } def end def grestore /SecurityPopup { % (host hame) => true/false(should we allow connection) SecurityCans begin gsave currentcursorlocation 18 sub exch 99 sub exch root setcanvas movecanvas 1 1 1 rgbcolor fillcanvas 0 0 0 rgbcolor dup setcolor strokecanvas 10 46 moveto SecBoldFont setfont (Connecting Host: ) show SecFont setfont dup show root /Mapped true put createevent dup begin /Name /SecurityLift def /TimeStamp currenttime .03 add def end sendevent { root canvastotop awaitevent /Canvas get [ yes { pop true exit } no { pop false exit } reg { % reg canvas systemdict /RemoteHostRegistry get exch cvn 1 put % systemdict /NetSecurityWanted false put true exit } /Default { createevent dup begin /Name /SecurityLift def /TimeStamp currenttime .03 add def end sendevent } ] case } loop root /Mapped false put grestore end } def /NetSecurityWanted true def /server { { { currentdict systemdict eq { exit } { end } ifelse } loop clear newprocessgroup SecurityCans begin SecurityAddInterests end { NeWS_socket (r) file } stopped { clear (%socketl2000) (r) file } if dup getsocketlocaladdress (NEWSSERVER) exch putenv (TERM) (PostScript) putenv { dup mark exch acceptconnection dup getsocketpeername /LastConnectingHost exch def RemoteHostRegistry LastConnectingHost known NetSecurityWanted not or { true } { LastConnectingHost SecurityPopup } ifelse { LastConnectingHost { 200 dict begin initmatrix newprocessgroup /OriginatingHost exch def exch pop exch pop cvx exec currentprocess killprocessgroup } fork } { closefile } ifelse cleartomark } loop } fork pop } def end } def % % End of new server code... % % This routine can be called to kill a running connection server and % start up the new server. % % The {/old,/new} option to this function specifies weather you % are tring to kill and old style or a new style server. This % code is VERY specific. If you have changed your server code % from the default released by Sun this code will PROBABLY NOT % work. % % NOTE: % This code relies on the definition for '/server' in systemdict % being the actual code that the running connections server is % executing. Therefor the loading of the new server code MUST % take place in the routine AFTER the running server has been killed. % /start_new_server { % /old,/new => - % this is the code we will insert into the runnign server. { closefile pop closefile currentprocess killprocessgroup } % depending weather we are old or new insert the above code % into different places. (we are inserting this code after % the 'acceptconnections' instructions). exch /old eq { /server load 0 get 13 get dup 3 2 roll 4 exch put 5 /exec cvx put } { /server load 0 get 20 get dup 3 2 roll 4 exch put 5 /exec cvx put } ifelse % Now that the server has been booby traped to die when it % recieves a new connection request, try to connect into it. (NEWSSERVER) getenv (.) search pop pop pop (;) search pop exch pop exch pop (%socketcXXXX) dup 3 -1 roll 8 exch putinterval (r) file pause pause pause pause pause closefile % This is UGLY UGLY UGLY. But we must wait for the socket to % clear its self up before we try to reuse it. % We have a NASTY NASTY race condition sometimes...... 1 1 1000 { pause } for % This following two line can be removed from here and called % anytime after this command. But until these are called % no connections to the NeWS server will succeed. define_new_server server } def % go ahead and start the new server. /old start_new_server From don@brillig.umd.edu Thu Feb 23 06:34:06 1989 Date: Thu, 23 Feb 89 06:34:06 EST To: NeWS-makers@brillig.umd.edu Subject: Inverse video From: neptune!rudolf@cs.orst.edu (Jim Rudolf) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) My eyes fatigue extra-fast when looking at black-on-white windows in NeWS. Is there an equivalent to 'suntools -i' in NeWS that will bring up inverse video windows? Thanks, Jim Rudolf ---------------------------------------------------------------------------- Internet: rudolf@oce.orst.edu "All opinions herein are mine" UUCP: {tektronix,hp-pcd}!orstcs!oce.orst.edu!rudolf ---------------------------------------------------------------------------- From don@brillig.umd.edu Thu Feb 23 15:07:06 1989 Date: Thu, 23 Feb 89 15:07:06 EST To: NeWS-makers@brillig.umd.edu Subject: Some fixes to the Interactive connection server From: "Stephen C. Pope" Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) After finding a few problems with Bret's Interactive Connection Server, I thought I'd make the fixes available. One bug was was the server not recognizing connections from the local host on machines which return an unqualified host name from localhostname, but a fully qualified hostname from getsocketpeername. The fix is copied directly from the original server in init.ps. The Times-Roman font scaled up to 20 looked a little funny to me (no flames please, to each his own...), so the fonts were altered, and the canvas made a little longer so it doesn't chop off any but the longest host names. Also, "reg" was changed to "always". Finally, since failing to respond locks up the server to other connection requests, the connection request will time out, returning a "no", after 30 seconds. As the original init.ps loads user.ps before starting up the server, the following code can be placed entirely within user.ps, and the server rebooted (exit and restart) without having to shut down the old server. I've not checked to see if "/new start_new_server" is compatible with these mods. Stephen C. Pope Santa Fe Institute scp@santafe.edu % This is the code to define the new connection server into % the systemdict. % % New variables added into system dict: % /SecurityCanvas --- dict containing all the information about the % popup window. % /SecurityPopup --- The routine which popus up the window and waits % for a responce. % /LastConnectingHost --- The name of the last host to have connected % into the server. % /define_new_server { systemdict begin gsave /SecurityCans 7 dict dup begin /Times-Bold findfont 16 scalefont setfont /root framebuffer 230 75 createcanvas def /ptr /ptr_m root setstandardcursor root begin /Transparent false def /EventsConsumed /AllEvents def /Retained true def end root setcanvas 1 1 1 rgbcolor fillcanvas 0 0 0 rgbcolor strokecanvas /no root 66 37 createcanvas dup begin /Transparent false def /EventsConsumed /AllEvents def /Mapped true def /Retained true def end def no setcanvas 0 0 0 rgbcolor dup setcolor strokecanvas 20 14 moveto (NO) show /yes root 66 35 createcanvas dup begin /Transparent false def /EventsConsumed /AllEvents def /Mapped true def /Retained true def end def yes setcanvas 65 0 movecanvas 0 0 0 rgbcolor dup setcolor strokecanvas 18 12 moveto (YES) show /always root 96 35 createcanvas dup begin /Transparent false def /EventsConsumed /AllEvents def /Mapped true def /Retained true def end def always setcanvas 132 0 movecanvas 0 0 0 rgbcolor dup setcolor strokecanvas 13 12 moveto (ALWAYS) show /SecBoldFont /Times-Bold findfont 14 scalefont def /SecFont /Times-Roman findfont 12 scalefont def /SecurityAddInterests { createevent dup begin /Name LeftMouseButton def /Action UpTransition def /Canvas yes def end expressinterest createevent dup begin /Name ascii_keymap def /Action DownTransition def /Canvas yes def end expressinterest createevent dup begin /Name /AddFocusClient def /Action [ currentprocess yes] def end sendevent createevent dup begin /Name LeftMouseButton def /Action UpTransition def /Canvas no def end expressinterest createevent dup begin /Name LeftMouseButton def /Action UpTransition def /Canvas always def end expressinterest createevent dup begin /Name /SecurityLift def end expressinterest createevent dup begin /Name /Timeout def /Canvas no def end expressinterest } def end def grestore /SecurityPopup { % (host hame) => true/false(should we allow connection) SecurityCans begin gsave currentcursorlocation 18 sub exch 99 sub exch root setcanvas movecanvas 1 1 1 rgbcolor fillcanvas 0 0 0 rgbcolor dup setcolor strokecanvas 10 46 moveto SecBoldFont setfont (Connecting Host: ) show SecFont setfont dup show root /Mapped true put createevent dup begin /Name /SecurityLift def /TimeStamp currenttime .03 add def end sendevent createevent dup begin /Name /Timeout def /TimeStamp currenttime .5 add def /Canvas no def end sendevent { root canvastotop awaitevent /Canvas get [ yes { pop true exit } no { pop false exit } always { % always canvas systemdict /RemoteHostRegistry get exch cvn 1 put % systemdict /NetSecurityWanted false put true exit } /Default { createevent dup begin /Name /SecurityLift def /TimeStamp currenttime .03 add def end sendevent } ] case } loop root /Mapped false put grestore end } def /NetSecurityWanted true def /server { { { currentdict systemdict eq { exit } { end } ifelse } loop clear newprocessgroup SecurityCans begin SecurityAddInterests end { NeWS_socket (r) file } stopped { clear (%socketl2000) (r) file } if dup getsocketlocaladdress (NEWSSERVER) exch putenv (TERM) (PostScript) putenv { dup mark exch acceptconnection dup getsocketpeername /LastConnectingHost exch def RemoteHostRegistry LastConnectingHost known LastConnectingHost localhostname anchorsearch { pop (.) anchorsearch { pop pop RemoteHostRegistry localhostname known } { pop false } ifelse } { pop false } ifelse or NetSecurityWanted not or { true } { LastConnectingHost SecurityPopup } ifelse { LastConnectingHost { 200 dict begin initmatrix newprocessgroup /OriginatingHost exch def exch pop exch pop cvx exec currentprocess killprocessgroup } fork } { closefile } ifelse cleartomark } loop } fork pop } def end } def % % End of new server code... % define_new_server From don@brillig.umd.edu Thu Feb 23 15:16:41 1989 Date: Thu, 23 Feb 89 15:16:41 EST To: NeWS-makers@brillig.umd.edu Subject: Re: Inverse video From: Katy Kislitzin Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) > My eyes fatigue extra-fast when looking at black-on-white windows in > NeWS. Is there an equivalent to 'suntools -i' in NeWS that will bring > up inverse video windows? > Thanks, > Jim Rudolf > ---------------------------------------------------------------------------- > Internet: rudolf@oce.orst.edu "All opinions herein are mine" > UUCP: {tektronix,hp-pcd}!orstcs!oce.orst.edu!rudolf > ---------------------------------------------------------------------------- i stole these lines from hugh daniel's colortool program (see the SUG tape) and put them in my user.ps: systemdict /Item known not { (NeWS/liteitem.ps) run } if systemdict begin % Turn the screen to White on Black for many things /thetextiswhite { /textcolor 1 1 1 rgbcolor store /backgroundcolor 0 0 0 rgbcolor store /bordercolor 1 1 1 rgbcolor store { /MenuTextColor 1 1 1 rgbcolor store /MenuFillColor 0 0 0 rgbcolor store /MenuBorderColor 1 1 1 rgbcolor store } LiteMenu send { /ShadowColor .5 .5 .5 rgbcolor def } LitePullRightMenu send { /ItemTextColor 1 1 1 rgbcolor store /ItemFillColor 0 0 0 rgbcolor store /ItemBorderColor 1 1 1 rgbcolor store } Item send { /FrameTextColor 1 1 1 rgbcolor store /FrameFillColor 0 0 0 rgbcolor store /FrameBorderColor 1 1 1 rgbcolor store /KeyFocusColor 1 1 1 rgbcolor store /ClientFillColor 0 0 0 rgbcolor store /IconTextColor 1 1 1 rgbcolor store /IconFillColor 0 0 0 rgbcolor store /IconBorderColor 1 1 1 rgbcolor store } LiteWindow send } def end thetextiswhite this puts all my windows in reverse video. with colortool, you can also experiment with variuos shades of grey, etc. unfortunately, this makes for illegible text :-) --kt From don@brillig.umd.edu Fri Feb 24 13:50:16 1989 Date: Fri, 24 Feb 89 13:50:16 EST To: NeWS-makers@brillig.umd.edu Subject: Help requested in understanding < self send > From: egg-id!beaver!llh@ucdavis.ucdavis.edu (L. Linn Hower) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) I am a novice NeWS programmer and am having trouble understanding the programming concepts I see used in Sun's liteitem.ps. My question concerns the use of `self send' in a method of a subclass. Sometimes this construct is used and sometimes the method is just executed directly. What are the differences? Specifically, I cannot see the difference between: /method0 { ... } def /method1 { /method0 self send } def or /method0 { ... } def /method1 { method0 } def What happens different when a /method1 subclass send is executed? Don't they both start looking for method0 with the dictstack in the same state? I can't cause any differences in the test cases I have generated. What am I missing? Thanks... Linn -- Linn Hower lh1@INEL.GOV Phone: 208-526-9353 at the Idaho National Engineering Laboratory, Idaho Falls, ID From don@brillig.umd.edu Fri Feb 24 13:52:29 1989 Date: Fri, 24 Feb 89 13:52:29 EST To: NeWS-makers@brillig.umd.edu Subject: Re: Inverse video From: arg@trzdor1.ico.olivetti.com (arg) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Use `user.ps' files From don@brillig.umd.edu Sun Feb 26 16:59:06 1989 Date: Sun, 26 Feb 89 16:59:06 EST To: NeWS-makers@brillig.umd.edu Subject: Re: Toolplaces for NeWS From: David Rosenthal 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. > The mechanism for doing what you want is defined in the X Inter-Client Communication Manual. NeWS clients under X/NeWS can use this mechanism. I don't know about back-porting to NeWS1.1, but I would advise doing this rather than indulging NIH. David. From don@brillig.umd.edu Tue Feb 28 16:55:37 1989 Date: Tue, 28 Feb 89 16:55:37 EST To: NeWS-makers@brillig.umd.edu Subject: C Client arrays From: munnari!mimir!hugin!augean!sirius!gtravan@uunet.uu.net (George Travan) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) could someone provide some demo code which demonstrates a mechanism whereby a C Client could pass arrays of data (particularly floating point) to a Server? I seem to have quite a few problems trying to do this successfully. --george travan ACSNET: gtravan@sirius.ua.oz or george@frodo.ua.oz From don@brillig.umd.edu Tue Feb 28 17:20:42 1989 Date: Tue, 28 Feb 89 17:20:42 EST To: NeWS-makers@brillig.umd.edu Subject: Re: Toolplaces for NeWS From: mcvax!kth!enea!naggum!isncr!m2cs!frode@uunet.uu.net (Frode Odegard) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) This should be possible. In fact, provided one has a decent library used by the applications on the client side, one should be able to save and restore THE WHOLE DESKTOP like in Smalltalk. GNU Emacs has some nice code that it uses for loading faster. It will load the ELISP code into its data segment and then produce a core dump of itself. Then this core dump is converted into a new executable which has all the ELISP stuff preloaded (minus user ELISP files, of course, I'm only talking about the basic editor code here). If one could also save info about the call chain, a RESUME would be in reach. We have the problem with limbo descriptors of course, but that's what the "decent library" is all about.... I expect the library would also have to talk to NeWS to save/restore what ever the client had going over there. If the client only goes trough The Nice Library for doing graphics (farewell, extensibility ;->), the graphics wouldn't be a problem either. Comments from Real Unix Hackers? [I'm just a Modulean, I write my own operating systems ;-)] - 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 Wed Mar 1 17:16:35 1989 Date: Wed, 1 Mar 89 17:16:35 EST To: NeWS-makers@brillig.umd.edu Subject: Re: C Client arrays From: capmkt!tim@uunet.UU.NET Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) >>> could someone provide some demo code which demonstrates a mechanism whereby a >>> C Client could pass arrays of data (particularly floating point) to a Server? assuming you already have the connection to the server you could do it like this: /*** the c function ***/ send_valarray() double vals[]; { int i; arraystart(); for(i=0;i frode@m2cs.uu.no (Frode Odegard) > GNU Emacs has some nice code that it uses for loading faster. It > will load the ELISP code into its data segment and then produce a core > dump of itself. Then this core dump is converted into a new executable > which has all the ELISP stuff preloaded [...] > Comments from Real Unix Hackers? [I'm just a Modulean, I write my > own operating systems ;-)] Well, clearly Frode is using some meaning of "nice" with which I am totally unfamiliar. This one little hack contributes somewhere between two-thirds and three-quarters of the difficulty in porting GNU Emacs. If instead of producing a core dump, it write exactly the data elements needed in the form of a C module to compile and link in with a "generation II" editor executable, the code would be more portable, more maintainable, and in all ways better than it is now. IMHO. Hmpf. -- The LISP programmer knows the value of everything but the cost of nothing. --- Alan J. Perlis Wayne Throop !mcnc!rti!xyzzy!throopw From don@brillig.umd.edu Thu Mar 2 16:49:18 1989 Date: Thu, 2 Mar 89 16:49:18 EST To: NeWS-makers@brillig.umd.edu Subject: Using PSH to produce output in a window From: leah!kds545@csd4.milw.wisc.edu (Kevin Samborn) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) I am interested in using psh with psterm to produce postscript output interactively. The only problem is that the output appears in framebuffer, and sometimes behind the other windows, is illegible, etc. What I want to do is when I call psh, I would like there to also be a concurrent window I would call the 'graphics window', where the psh output would appear. This way, I could run my psterm, my editor, and psh all in windows, and also have my output in a window. The reason I need to do this is for a teaching mechanism. I hope someone out there knows this. Thanks. -- | Kevin Samborn | kds545@leah.albany.edu | 529 Washington Ave. | | Albany, NY 12206 | (voice) 518-465-9526 From don@brillig.umd.edu Thu Mar 2 17:29:20 1989 Date: Thu, 2 Mar 89 17:29:20 EST To: NeWS-makers@brillig.umd.edu Subject: Disabled menu items From: neptune!rudolf@cs.orst.edu (Jim Rudolf) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Has anyone hacked together something in NeWS that will allow disabled menu items similar to what is common in Sunview? What I mean is, have a particular menu item or items in gray, as well as ignoring the event if a disabled menu item is selected. I would be most appreciative if someone has already figured this out so I don't have to :-). Thanks for any help you can give me. -- Jim Rudolf BTW, I called Springer-Verlag on 2/28 to find out about The NeWS Book. I've been waiting anxiously for a supplement to the NeWS Manual. They told me it's publication date had been delayed again, and that I should call back in about 2 weeks...rats. ---------------------------------------------------------------------------- Internet: rudolf@oce.orst.edu "All opinions herein are mine" UUCP: {tektronix,hp-pcd}!orstcs!oce.orst.edu!rudolf ---------------------------------------------------------------------------- From don@brillig.umd.edu Thu Mar 2 23:57:18 1989 Date: Thu, 2 Mar 89 23:57:18 EST To: NeWS-makers@brillig.umd.edu Subject: Re: Using PSH to produce output in a window From: swagman@Sun.COM (Patrick J. McEvoy (Sun Entry Systems ISV Liaison)) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) > I am interested in using psh with psterm to produce postscript > output interactively. The only problem is that the output > appears in framebuffer...I would like there to also be a > concurrent window I would call the 'graphics window', where the > psh output would appear. I usually start off my psh sessions with: /mywin framebuffer /new DefaultWindow send def /reshapefromuser mywin send /map mywin send /mycanvas /GetCanvas mywin send def mycanvas setcanvas I suppose you could make the canvas retained as well. From don@brillig.umd.edu Fri Mar 3 17:22:38 1989 Date: Fri, 3 Mar 89 17:22:38 EST To: NeWS-makers@brillig.umd.edu Subject: Re: Using PSH to produce output in a window From: des%orenda%amara.uucp@mailgw.cc.umich.edu (Dave Steinhoff) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) I'm not exactly sure what would suit you best, but it is straight- forward to run psh and open a window into which subsequent graphics operations are directed. For example, % psh executive /win framebuffer /new DefaultWindow send def /reshapefromuser win send {/FrameLabel (* PSH Output Window *) def /PaintClient {1 fillcanvas} def /IconImage /door def } win send /map win send {ClientCanvas} win send setcanvas .5 fillcanvas ...would create a window with a white background and then fill the background with a .5 grayscale pattern (on a b/w box). All but the last line could be saved in a file to shorten the preamble: % psh executive (.../psh-win) run .5 fillcanvas ...to produce the same effect. I apologize if you were looking for a different sort of solution. Let me know how it goes. Dave. Dave Steinhoff (313)973-1300 ...uunet!amara!des Applied Dynamics International des@amara.UUCP 3800 Stone School Rd, Ann Arbor, Mi 48108 From don@brillig.umd.edu Fri Mar 3 18:36:21 1989 Date: Fri, 3 Mar 89 18:36:21 EST To: NeWS-makers@brillig.umd.edu Subject: Disabled menu items From: suncan!steve%jtsv16.jts.com@Sun.COM (steve rosenberg) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) >Has anyone hacked together something in NeWS that will allow disabled menu >items similar to what is common in Sunview? What I mean is, have a particular >menu item or items in gray, as well as ignoring the event if a disabled menu >item is selected. I would be most appreciative if someone has already figured >this out so I don't have to :-). I think that the following file implements the feature that you are looking for. It has only been tested in mono on NeWS 1.1. It does the gray-out by "spraying" white pixels over the menu choice (bitmap fonts can't be set to an intermediate shade of gray). You will note that the MenuFont has been set to 18 point Helvetica. That seemed to work best with the gray-out pattern used. Change the font and you may have to change the gray-out pattern. You can disable/enable menu choices by sending the following messages to your menu object: index -or- key /disable index -or- key /enable This menu sub-class also does another interesting thing. It provides a click-or-drag feature so that if the user "clicks" the menu button (i.e. press and release without moving) the menu will pop-up and stay up until a choice is made by clicking again. The press-drag technique can still be used. The damping factor (amount of movement before drag is assumed) can be adjusted by changing the class variable Damping. Nervous hands need more. Either place the following file in your user.ps or run it from there, and redefine the default menu: /DefaultMenu LitePRMenu+ store %%% - cut here - % litemenu enhancements for enable/disable and click-or-drag % /LitePRMenu+ LitePullRightMenu dictbegin % enable/disable feature /Mf false def % flag (for mask proc) /Mw 0 def /Mh 0 def % mask width and height /Ms1 nullstring def % strings for gray-out image source /Ms2 nullstring def % click or drag /DownX 0 def /DownY 0 def /MenuClicked? false def % true if this menu has been clicked dictend classbegin /Damping 4 def /MenuFont /Helvetica findfont 18 scalefont def % dimmed choice stuff /MaskStr1 20 string def /MaskStr2 20 string def 0 1 19 {MaskStr1 exch 16#55 put} for 0 1 19 {MaskStr2 exch 16#AA put} for /disable { % index -or- key => - dup type /integertype eq not { /searchkey self send pop } if % stack now => index MenuItems exch get % => menuitems(dict) begin /ok? false def end } def /enable { % index -or- key => - dup type /integertype eq not { /searchkey self send pop } if % stack now => index MenuItems exch get % => menuitems(dict) begin /ok? true def end } def /domenu { % menu => - MenuValue null eq { pop } { /domenu super send } ifelse } def /layout { /layout super send MenuItems { begin currentdict /ok? known not { /ok? true def } if end } forall } def /PaintMenuItems { MenuTextColor setcolor MenuItems { begin X Y X Y W H ok? /Key load x y end % get the interesting stuff from the % MenuItems dict ShowThing % => X Y X Y W H ok? (show this menu choice "thing") { pop pop pop pop } % this choice is enabled { % gray out this choice gsave % => X Y X Y W H 2 copy % => X Y X Y W H W H /Mh exch def /Mw exch def newpath rectpath clip % clip area to be grayed translate 0 0 moveto Mw Mh scale MaskStr1 0 Mw 8 div ceiling 1 sub getinterval /Ms1 exch def MaskStr2 0 Mw 8 div ceiling 1 sub getinterval /Ms2 exch def /Mf false def 1 setgray % use white to do the gray-out Mw Mh true [ Mw 0 0 Mh 0 0 ] { Mf { /Mf false def Ms1 } { /Mf true def Ms2 } ifelse } imagemask % spatter white over the thing grestore } ifelse } forall } def /PaintMenuValue { % - => - (Highlights current item, un-hilighting prev.) MenuGSave PaintedValue PaintBox MenuValue dup null ne { MenuItems exch get begin ok? end { MenuValue PaintBox } { /MenuValue null store } ifelse } { pop } ifelse /PaintedValue MenuValue store grestore } def /showat { % x y -or- event => - MenuClicked? not { % only save loc if not yet clicked dup type /eventtype eq { dup begin framebuffer setcanvas XLocation YLocation end % ... xloc yloc } { 2 copy % ... xloc yloc } ifelse /DownY exch def /DownX exch def /showat super send % only send to super if not clicked } if } def /DownProc { % dummy proc to swallow down stroke % of click } def /UpProc { MenuClicked? not { % only test for click/drag % if not yet done framebuffer setcanvas CurrentEvent begin XLocation YLocation end % see if mouse moved more % than damping factor (dragged), % or stayed relatively still (clicked) dup % => x y y DownY Damping add le exch % => x bool y DownY Damping sub ge and exch % => bool x dup DownX Damping add le exch % => bool bool x DownX Damping sub ge and % => bool bool and { /MenuClicked? true def % menu was clicked } { /UpProc super send % send up event if dragged } ifelse } { /UpProc super send } ifelse } def /makeinterests { % - => - /MenuInterests [ ParentMenu null eq { MenuButton /UpProc UpTransition null eventmgrinterest } if MouseDragged /DragProc null MenuCanvas eventmgrinterest MenuButton /DownProc DownTransition null eventmgrinterest /EnterEvent /EnterProc null MenuCanvas eventmgrinterest /ExitEvent /ExitProc null MenuCanvas eventmgrinterest /Damaged /DamageProc null MenuCanvas eventmgrinterest ] def } def /popdown { /MenuClicked? false def /popdown super send } def classend def %% end of file _________________________________________________________________________ Steve Rosenberg | steve@jtsv16.jts.com JTS Computer Systems Ltd. | uunet!jtsv16!steve Toronto +1 416 665 8910 | ...![sun|...]!suncan!jtsv16!steve __________________________|______________________________________________ From don@brillig.umd.edu Sun Mar 5 00:23:11 1989 Date: Sun, 5 Mar 89 00:23:11 EST To: NeWS-makers@brillig.umd.edu Subject: visual debugger under NeWS From: mcvax!enea!naggum!isncr!m2cs!frode@uunet.uu.net (Frode Odegard) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Have anyone done a dbxtool-like program which runs under NeWS, or will we have to wait for Sun Microsystems to do something? I have obtained a Sun technical paper which explains how dbxtool communicate with dbx, but before I start hacking it would nice to know if I'm duplicating other people's work.. - Frode PS: Dear Sun Microsystems, we need: * better/more NeWS documentation * more NeWS tools * faster news_server (compile with GNU C) * news_server source code -- free (this helped X a *lot*) * classes (in Europe, too!) -- | 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 Sun Mar 5 14:27:11 1989 Date: Sun, 5 Mar 89 14:27:11 EST To: NeWS-makers@brillig.umd.edu Subject: 3-D plotting From: IO70706%MAINE.BITNET@mitvma.mit.edu (Jon Everett) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) I am looking for code to generate a wire-mesh contour plot from a matrix of x,y,z coordinates. If anyone has such a thing, I'd like to see it. Or, if you think this is a trivial problem, please direct me to the appropriate reference(s) on the subject. Thanks. Please reply to me directly since I am not subscribed to this discussion. Jon Everett io70706%maine.bitnet@mitvma.mit.edu From don@brillig.umd.edu Sun Mar 5 15:34:22 1989 Date: Sun, 5 Mar 89 15:34:22 EST To: NeWS-makers@brillig.umd.edu Cc: dmichel@sun.com (Doug Michel [Unreliable Salesman]) Subject: Visual NeWS process debugger ("real soon now") From: Don Hopkins Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) To: NeWS-makers@brillig.umd.edu From: mcvax!enea!naggum!isncr!m2cs!frode@uunet.uu.net (Frode Odegard) Have anyone done a dbxtool-like program which runs under NeWS, or will we have to wait for Sun Microsystems to do something? I have obtained a Sun technical paper which explains how dbxtool communicate with dbx, but before I start hacking it would nice to know if I'm duplicating other people's work.. - Frode *Don't* wait for Sun! Go ahead on your NeWS dbx tool! I'm working on a visual NeWS debugger/browser, for NeWS processes and data structures. (As opposed to Unix processes, like dbx.) I haven't posted it yet, because I know it has problems running in color, and I need to fix them first. To fix them, I need to run NeWS in color, and the 3/50 I use just doesn't cut it. Sun donated a color Sun to the University of Maryland Human Computer Interation Lab, almost a year ago, but it still hasn't been delivered yet. They have promised its delivery at least 5 times since before Christmas, and every time it was not delivered when they said, so I cannot say when I will be able to post the debugger. What I have learned from this experience: If you want a Sun delivered before it is obsolete, you have to pay for it. Unless the salesman is making a commission, don't believe him when he gives you a delivery date. If Sun donates a machine to you, and you don't have a year to wait around for its delivery, you should take the money you saved by not buying a Sun, and buy a machine from some other company. (You might consider a Mac II running A/UX, the Silicon Graphics Personal Iris, or [if you have NeWS sources] the new MIPS machine from DEC, if you can stand the keyboard.) Potential Sun employees take note: I have heard from a reliable source (as opposed to the salesman handling the fiasco), that Sun ships machines to employees at an even lower priority than they ship donations. Our research has really been held back by this "donation". A year is a very long time in our field of work. We were going to buy a 3/60, before they said they'd donate a machine to us. Had they not donated anything, we would have had the 3/60 a long time ago. (The salesman reassured me that none of these delays would have happened if we'd paid for it.) NeWS is almost impossible to use on a 3/50, but we've been trying to do the best we can. (Sun's idiotic policy on third party 3/50 memory upgrades sure hasn't given us any hope.) If you've had problems with Sun donations, please get in contact with me, so I can consider your experiences in my summary to Sun-Spots. -Don Hopkins From don@brillig.umd.edu Mon Mar 6 16:00:14 1989 Date: Mon, 6 Mar 89 16:00:14 EST To: NeWS-makers@brillig.umd.edu Subject: Re: C Client arrays From: oliveb!pyramid!prls!philabs!ppgbms!paul@apple.com (Paul Evan Matz) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) In article <8903010054.AA06125@bill.capmkt.com> tim@capmkt.UUCP writes: > >/*** the cps defs ***/ > >cdef arraystart() > [ > >cdef arrayend() > ] > >cdef emit_double(double val) > val > You might want to build into the cdef functions the array identifier assignment part too, like: cdef arraystart() ArrayDataName [ cdef arrayend() ] def One *VERY* big problem with this method is that the array data is being put on the stack of the server side liteweight process, so if you're trying to pass an array bigger than 1000 words, look out for a stack overflow! (I've heard there is a way to increase the stack size, but have never found out how). Another problem with this method is that the data being passed is translated into ascii by the client, sent on the byte stream connection to the server, who then translates it back to binary whatever. Kinda slow. Depending on what you are doing with the data, it is sometimes better to use some of the cdef intrinsics like ps_moveto, ps_lineto; I think the passed parameters are tokenized in an XDR-like way (I can't remember where I read this. I could be completely off base on this, but I don't think so). Maybe Sun will provide a decent binary array transmission mechanism in the X11/NeWS merge. Anybody care to comment? Paul Matz PPG Biomedical Systems One Campus Drive Pleasantville, NY. 10570 914-741-4685 path ppgbms!moe!paul@philabs.philips.com From don@brillig.umd.edu Mon Mar 6 19:33:22 1989 Date: Mon, 6 Mar 89 19:33:22 EST To: NeWS-makers@brillig.umd.edu Subject: converting SunView icons to NeWS icons? From: xanth!nic.MR.NET!eta!rscott@ames.arc.nasa.gov (Rich Scott) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Gentle comp.windows.news readers, tell me, how can I convert my (large) library to SunView-style icons to NeWS-usable icons? The NeWS manual describes in intimate detail how to convert fonts of other formats to NeWS format, but no good words about doing icons. And of course, all the software I've seen posted on the net all have *blank* icons! Even Don Hopkins, NeWSer-at-large, when asked this question at SUG-Miami, by me, got nervous and said he had a previous engagement to attend! :-) Anyway, if you all have a reasonably easy method of importing SunView (or heck, even X11) icons to NeWs, I'd like to know. I'll post a summary of responses, if warranted. Thanks. ---------- rich scott (612) 642-8404 internet: rscott@unix.eta.com eta systems, st. paul, mn uucp: {amdahl,rutgers}!bungia!eta!rscott "I've been on a calendar, but never on time" - Marilyn Monroe From don@brillig.umd.edu Mon Mar 6 19:43:53 1989 Date: Mon, 6 Mar 89 19:43:53 EST To: NeWS-makers@brillig.umd.edu Subject: Re: converting SunView icons to NeWS icons From: siegel@hc.dspo.gov (josh Siegel) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) NeWSer converts suntools icons to a "NeWS" icon. Then, there is "example.cps" which includes a "foobar" icon and displays it. Is this good enough or do you want to convert it to a NeWS font?!? --------- NeWSer #! /bin/sh ed - $1.icon< /g 2,\$s/^\(.*\)$/<\1> append/g w $1.news q EOF ------- example.cps /win framebuffer /new DefaultWindow send def /showicon { dup type /stringtype eq { % use string as an icon image gsave currentpoint translate 64 64 scale 0 setgray 64 64 true [1 0 0 1 0 0] 5 -1 roll imagemask grestore } { % assume literal and use as standard icon lookup % this comes straight out of 'icons.ps' currentfont ( ) dup 0 icondict 5 index get put iconfont setfont show setfont pop } ifelse } def { /IconImage #include "foobar2.news" def % Give it an icon 200 200 700 350 reshape % Give it a size } win send /map win send -- 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 Mar 6 20:40:30 1989 Date: Mon, 6 Mar 89 20:40:30 EST To: NeWS-makers@brillig.umd.edu Subject: Re: C Client arrays From: owen@Sun.COM (Owen Densmore) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) One *VERY* big problem with this method is that the array data is being put on the stack of the server side liteweight process, so if you're trying to pass an array bigger than 1000 words, look out for a stack overflow! (I've heard there is a way to increase the stack size, but have never found out how). The stack can be avoided by using an executable array: cdef arraystart() ArrayDataName { cdef arrayend() } cvlit def The cvlit converts this back to a vanilla array. The stack does not get used to create the array; the scanner takes care of it for you. Owen From don@brillig.umd.edu Mon Mar 6 20:41:51 1989 Date: Mon, 6 Mar 89 20:41:51 EST To: NeWS-makers@brillig.umd.edu Subject: Re: C Client arrays From: capmkt!tim@uunet.UU.NET Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) ppgbms!moe!paul@philabs.philips.com writes: >>One *VERY* big problem with this method is that the array data is being >>put on the stack of the server side liteweight process, so if you're >>trying to pass an array bigger than 1000 words, look out for a stack >>overflow! (I've heard there is a way to increase the stack size, but >>have never found out how). there is apparently a workaround for this. after i had posted the original method, a fellow from sun (i believe it was but i have lost the original message) sent me tip saying that if you use executable arrays, then the stack is not used at all. so changing the code to read cdef arraystart() { %%% instead of [ cdef arrayend() } %%% instead of ] should solve the stack-overflow problem. if anyone understands the magic behind this, i would be interested in knowing how/why this works. tim edwards capital market technology, inc. 1995 university, #390 berkeley, ca (415)540-6400 tim@capmkt.com or capmkt!tim@uunet.uu.net From don@brillig.umd.edu Mon Mar 6 21:06:55 1989 Date: Mon, 6 Mar 89 21:06:55 EST To: NeWS-makers@brillig.umd.edu Subject: soft menus From: Don Hopkins Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) %! %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Copyright (C) 1989 by Don Hopkins. 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. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Menus that can be changed while they're popped up. % Don Hopkins % % Instructions: % % This file defines a subclass of DefaultMenu called SoftMenu, which % it then installs as DefaultMenu. % It allows you to cut & paste menu keys around dynamically from menu % to menu, using the PointButton. (The left mouse button on a Sun.) % This should work with most menu classes. (hopefully...) Just don't % load it in on top of itsself. % % While making a selection from a menu: % PointButton % Copy the highlighted menu item to PrimarySelection. % (i.e. like "copy" on the Mac) % Shift PointButton % "Insert" the menu item from PrimarySelection before the % highlighted item. If no items are highlighted, it's appended % to the end of the menu. % Control PointButton % "Delete" the highlighted menu item. % Meta PointButton % "Edit" the highlighted menu item. (Coming soon. Suggestions?) % % To make a new menu item, you can select a string or array % subinterval which will push a menu key and an action on the stack % when executed, and insert it into a menu. Note that everything is % executed in the context of the menu you're inserting into. % % It's your responsibility to avoid circularities! % % If you select a (dict,key) pointer in cyberspace, and insert it % into a menu, the key name will be the menu key and the value % "dict key get" will be the action. % % Examples: (just select the following and paste them:) { (--------) {} % separator (Frame...) /FrameMenu ThisWindow send (Hello, Sailor!) { gsave framebuffer setcanvas currentcursorlocation [(Nothing) (happens) (here.)] popmsg pop grestore } (Be Gone!) { /flipiconic ThisWindow send /tobottom ThisWindow send } (rootmenu) rootmenu (psload) { (NEWSHOME) getenv (/bin/psload) forkunix } } pop systemdict begin /SoftMenu DefaultMenu dictbegin /Changed? true def /MenuLock null def /ChangedEvent null def /ChangeDelay .25 60 div def /Control false def /Shift false def /Meta false def dictend classbegin /new { /new super send begin /MenuLock createmonitor def currentdict end } def /layout { MenuLock { /layout super send /Changed false def } monitor } def /paint { MenuLock { /paint super send } monitor } def /insertitem { MenuLock { /insertitem super send change } monitor } def /deleteitem { MenuLock { /deleteitem super send change } monitor } def /showat { MenuLock { /showat super send } monitor } def /change { /Changed true def /MenuValue null def MenuCanvas null ne { ChangedEvent null eq { /ChangedEvent createevent def ChangedEvent /Name /MenuChanged put } { ChangedEvent recallevent } ifelse ChangedEvent /Canvas MenuCanvas put ChangedEvent /TimeStamp currenttime ChangeDelay add put ChangedEvent sendevent } if } def /makeinterests { /makeinterests super send /MenuInterests [ MenuInterests { dup /Name get PointButton eq { pop } if } forall /MenuChanged /ChangeProc null MenuCanvas eventmgrinterest PointButton /PointProc /DownTransition MenuCanvas eventmgrinterest ] def } def /ChangeProc { ChangedEvent recallevent Changed MenuCanvas null ne MenuEventMgr null ne and and { gsave framebuffer setcanvas MenuCanvas getcanvaslocation /MenuValue null def layout reshape MenuCanvas setcanvas movecanvas clippath extenddamage % /MenuEventMgr null def % { clear MenuX MenuY MenuHeight add showat } fork pop % currentprocess killprocess grestore } if } def /UpdateShifts { /Shift false def /Control false def /Meta false def CurrentEvent /KeyState get { { /Shift /Control /Meta } { 1 index eq { dup true def exit } if } forall pop } forall } def /PointProc { UpdateShifts Control { PointDelete } { Shift { PointInsert } { Meta { PointEdit } { PointSelect } ifelse } ifelse } ifelse } def /PointDelete { % Menus break with 0 items... MenuValue null ne MenuItems length 1 gt and { MenuValue deleteitem } if } def /PointInsert { MenuValue dup null eq { pop MenuItems length } if % index /PrimarySelection getselection % sel dup null eq { pop pop } { dup /ContentsPostScript known { dup /ContentsPostScript get exch % obj sel dup /SelectionStartIndex known not { pop } { dup /SelectionLastIndex known { dup /SelectionStartIndex get % obj sel start exch /SelectionLastIndex get % obj start last 1 index sub 1 add % obj start len getinterval % interval } { % obj sel /SelectionStartIndex get % obj index exch 1 index get % index val exch (%) sprintf exch % key val 2 array astore % [ key action ] } ifelse } ifelse } { /ContentsAscii get } ifelse { count 1 roll count 1 sub {pop} repeat { cvx exec } errored pop count 2 ne { (Bad MenuKey) {} } if 2 array astore } fork waitprocess exch pop aload pop % index key proc insertitem % } ifelse } def /PointEdit { % Pop up dialog box? } def /PointSelect { MenuValue null ne { MenuItems MenuValue get begin 20 dict begin /ContentsPostScript [ [ /Key load Menu dup null eq { pop /Action load } if ] /aload cvx /pop cvx ] def /ContentsAscii ContentsPostScript 0 get aload pop exch (MenuItem[% %]) sprintf def /SelectionObjSize 1 def /SelectionResponder null def /Canvas MenuCanvas def /SelectionHolder MenuEventMgr def currentdict end % SelectionDict /PrimarySelection setselection end % ItemDict } if } def classend def /setdefaultmenu { % class => - /DefaultMenu exch store systemdict /rootmenu known { /rootmenu /flipstyle rootmenu send store } if } def SoftMenu setdefaultmenu end % systemdict From don@brillig.umd.edu Tue Mar 7 00:08:46 1989 Date: Tue, 7 Mar 89 00:08:46 EST To: NeWS-makers@brillig.umd.edu Subject: Class vars or Instance vars From: Knut Skog Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) After a close inspection of the elegant implementation of classes and message-pasing by the rutines in class.ps I am unable to see the reason for the distinction made between instance- and class-vars in the definition of the LiteWindow class . I would have put several of the class vars (f.i. FrameLabel, PaintClient, etc) as instance vars. In effect that is what happens when a { /FrameLabel () def} is sent to some window instance. The definition is added to the instance and since the instance is currentdict when the message is executed, this definition overrules definitions in its parent class as long as the keys are the same. (Using store insted of def would be rather bad style of programming) Installing attributes of this type as class-vars reduces generality. Despite the "lite/play" nature of this class I wonder if someone close to its design will comment on this issue. Have I missed out some esential part of the nature of instance and class properties? Much obliged. Knut From don@brillig.umd.edu Tue Mar 7 15:32:46 1989 Date: Tue, 7 Mar 89 15:32:46 EST To: NeWS-makers@brillig.umd.edu Subject: NeWS and NeXT From: conrad@cgl.ucsf.edu (Conrad Huang) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Has anyone ported NeWS to the NeXT? Does anyone plan to? We are very interested in getting NeWS on our NeXT machines since we have several NeWS applications that run on all our Suns and SGI machines. Having a object-oriented PostScript window system that handles both input and output makes implementing and porting applications much less painful (almost easy, even). So, has anyone in the know done this port yet? Please e-mail and I will summarize. Conrad conrad@cgl.ucsf.edu PS Lest anyone get the idea that I don't like the NeXT machine, I have one at home. The hardware is great. Mach is pretty good. The window system, however, ... :-) From don@brillig.umd.edu Tue Mar 7 16:57:45 1989 Date: Tue, 7 Mar 89 16:57:45 EST To: NeWS-makers@brillig.umd.edu Subject: NeWS, OpenView and PostScript From: orion.cf.uci.edu!uci-ics!zardoz!infotec!mel@elroy.jpl.nasa.gov (Michael Mel) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Does anyone know what role, if any, PostScript will play in the upcoming OpenView (or View2, or Sunview 2.0, or ???). I'd like to feel that learning PostScript and NeWS programming hasn't been a waste of time. Michael Mel ...!sun!sunkist!infotec!mel From don@brillig.umd.edu Tue Mar 7 17:25:16 1989 Date: Tue, 7 Mar 89 17:25:16 EST To: NeWS-makers@brillig.umd.edu Subject: InterViews -> NeWS port From: "Stephen C. Pope" Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Hi! As I'm new to the mailing list, I hope I'm not asking the *dumbest* question possible, but has anyone yet "ported" InterViews to run under NeWS instead of X? We're involved in developing a rather large application utilizing window-based interactive menus and graphical output. Some rough NeWS code is already in place. However, we would like to move our code to a wide variety of machines, many of which do not run NeWS. In order to keep the development work to a minimum, we'd like to hide the window system behind an interface such as InterViews providing the usual windows/Scenes, Items/Interactors. We are not looking for an exact duplication of X-styled InterViews under NeWS, but rather a "functional equivalent" - one way of getting stuff on the screen regardless of the underlying window system, so we can stop worrying about the window system we're running under. Although I'm little familiar with InterViews/X, I do recognize that the event handling is quite different than in NeWS. It does appear that with a thin layer between InterViews and the client code, one can completely hide events from the client, and replace it with a psuedo-stream communications interface. Thanks, Stephen C. Pope The Santa Fe Institute scp@santafe.edu From don@brillig.umd.edu Tue Mar 7 20:30:56 1989 Date: Tue, 7 Mar 89 20:30:56 EST To: NeWS-makers@brillig.umd.edu Subject: Re: InterViews -> NeWS port From: Ramani Pichumani Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) > Hi! As I'm new to the mailing list, I hope I'm not asking > the *dumbest* question possible, but has anyone yet > "ported" InterViews to run under NeWS instead of X? I went to a demonstration of InterViews given last year by Mark Linton (its creator) and he mentioned that someone had ported InterViews to NeWS but didn't say who. What I would suggest you do is send him e-mail (linton@lurch.stanford.edu) and ask him for the latest details. Ramani From don@brillig.umd.edu Wed Mar 8 01:59:07 1989 Date: Wed, 8 Mar 89 01:59:07 EST To: NeWS-makers@brillig.umd.edu Subject: Re: InterViews -> NeWS port From: cs.utexas.edu!milano!titan!janssen%titan.sw.mcc.com@tut.cis.ohio-state.edu (Bill Janssen) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) InterViews is a very nice system, but it is still just getting started. I would suggest porting the Andrew Toolkit to NeWS, and using that. Andrew is a system from the Information Technology Center at CMU, distributed free by IBM and CMU, on the X11R3 tape. It is an extensive object-oriented system with hundreds of useful classes (including major applications such as a mail system, a multi-media extensible editor, a typescript, a graphical workstation monitor-console, a help tool) that is based on a good model of a virtual window system, along with two ports to real window systems, WM and X11. All applications talk in terms of the virtual window system, so that different window systems can be used by the same application. Code can be dynamically loaded, so that the appropriate window system class can be selected at run-time. You would have to provide the port to NeWS, but it would be a minor job compared to the wealth of ready tools you would receive. The sources for Andrew are distributed on the X11R3 tape under contrib/toolkits/andrew. You might want to join the mailing list "info-andrew@andrew.cmu.edu" for more information (requests to "info-andrew-request@andrew.cmu.edu"), or try sending mail to ???? (perhaps postmaster@andrew.cmu.edu?). Bill From don@brillig.umd.edu Wed Mar 8 04:40:49 1989 Date: Wed, 8 Mar 89 04:40:49 EST To: NeWS-makers@brillig.umd.edu Subject: C-- Digital Clock From: thaeler@hc.dspo.gov (Bret K. Thaeler) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) % % Digital Clock. % % Author: Bret K. Thaeler % Mini author: Josh Siegel % Los Alamos National Labs (MEE-10) % {thaeler,siegel}@hc.dspo.gov % % % Yet another thing that you can't do with X.... % % This program brings up a digital clock (looking like your wrist % watch or a clock) that is COMPLETELY written in NeWS. This clock % doesn't have ANY C side... % % The later it gets the worse this code becomes. It is now late and % this code is REALLY UGLY.... % % Have Fun... % % % Create Window % % % Set attributes for window % /lasteve null def /do2412 0 def % 0 => 24, 1 => 12 /toggel2412 { % togger between 24 and 12 hour clock. do2412 0 eq { /do2412 1 store 0 (24 Hour Clock) /toggel2412 /changeitem /ClientMenu win send send resize_window } { /do2412 0 store 0 (12 Hour Clock) /toggel2412 /changeitem /ClientMenu win send send resize_window } ifelse } def /dohms 0 def % 0 => hms, 1 => hm /timetnu 1 60 div def % minutes to next update /toggelhms { % toggel between HH:MM:SS and HH:MM dohms 0 eq { /dohms 1 store /timetnu 1 store 1 (H:M:S) /toggelhms /changeitem /ClientMenu win send send resize_window } { /dohms 0 store /timetnu 1 60 div store 1 (H:M) /toggelhms /changeitem /ClientMenu win send send resize_window lasteve begin /TimeStamp currenttime def end } ifelse } def /win framebuffer /new DefaultWindow send dup { /FrameLabel () def % Give it a label /BorderLeft 5 def /BorderRight 5 def /BorderTop 5 def /BorderBottom 5 def /PaintFocus {} def /IconHeight 30 def /IconWidth 80 def 200 200 270 70 reshape % Give it a size /ClientMenu [ (12 Hour Clock) /toggel2412 (H:M) /toggelhms () {} (ZAP!) {lasteve /Canvas null put currentprocess killprocessgroup} ] /new DefaultMenu send def /IconMenu ClientMenu def /num_dig 9 def /flipiconic load { lasteve begin /TimeStamp currenttime def end } exch append cvx /flipiconic exch def } exch send def /resize_window { do2412 0 eq { 8 } { 8.5 } ifelse dohms 0 eq { 0 } { -3 } ifelse add 1 add { /num_dig exch def } win send do_app_update } def % % Define the canvas for this beast % /can win /ClientCanvas get def /cani win /IconCanvas get def % can /Retained false put % cani /Retained true put % % If we didn't give window a size above use this. Else not. % % /reshapefromuser win send % % Now display the window % % win begin % FrameInterests /FrameDamageEvent undef % end /map win send can setcanvas pause pause pause pause 0 0 0 rgbcolor fillcanvas % % clock digits % /Digital_Font_Dict 10 dict def Digital_Font_Dict begin /FontMatrix [0.05 0 0 0.025 0 0 ] def /FontBBox [-1 -1 20 40] def /Encoding StandardEncoding def /CharProces dictbegin Encoding { {} def } forall /Gap 2 def /Width 20 def /HorizSeg % { Width Gap 2 mul sub } def 16 def /HalfHeight 20 def /VerSeg % { HalfHeight Gap 2 mul sub } def 16 def /DigitSpacing 10 def /LineWidth 2 def /colon { 0 0 HalfHeight 2 div add exch Width 2 div 5 add add exch 2 copy 2 copy moveto exch 5 sub exch 5 0 360 arc fill HalfHeight add 2 copy moveto exch 5 sub exch 5 0 360 arc fill stroke } def /period { Width 2 div 5 add 5 moveto Width 2 div 5 5 0 360 arc fill } def /hyphen { 0 0 moveto Gap HalfHeight rmoveto HorizSeg 0 rlineto stroke } def /zero { 0 0 moveto 0 Gap rmoveto 0 VerSeg rlineto 0 Gap 2 mul rmoveto 0 VerSeg rlineto Gap Gap rmoveto HorizSeg 0 rlineto Gap Gap neg rmoveto 0 VerSeg neg rlineto 0 Gap 2 mul neg rmoveto 0 VerSeg neg rlineto Gap neg Gap neg rmoveto HorizSeg neg 0 rlineto stroke } def /one { 0 0 moveto Width Gap rmoveto 0 VerSeg rlineto 0 Gap 2 mul rmoveto 0 VerSeg rlineto stroke } def /two { 0 0 moveto Width Gap sub 0 rmoveto HorizSeg neg 0 rlineto Gap neg Gap rmoveto 0 VerSeg rlineto Gap Gap rmoveto HorizSeg 0 rlineto Gap Gap rmoveto 0 VerSeg rlineto Gap neg Gap rmoveto HorizSeg neg 0 rlineto stroke } def /three { 0 0 moveto Gap 0 rmoveto HorizSeg 0 rlineto Gap Gap rmoveto 0 VerSeg rlineto 0 Gap 2 mul rmoveto 0 VerSeg rlineto Gap neg Gap rmoveto HorizSeg neg 0 rlineto 0 HalfHeight neg rmoveto HorizSeg 0 rlineto stroke } def /four { 0 0 moveto Width Gap rmoveto 0 VerSeg rlineto 0 Gap 2 mul rmoveto 0 VerSeg rlineto Gap neg HalfHeight Gap sub neg rmoveto HorizSeg neg 0 rlineto Gap neg Gap rmoveto 0 VerSeg rlineto stroke } def /five { 0 0 moveto Gap 0 rmoveto HorizSeg 0 rlineto Gap Gap rmoveto 0 VerSeg rlineto Gap neg Gap rmoveto HorizSeg neg 0 rlineto Gap neg Gap rmoveto 0 VerSeg rlineto Gap Gap rmoveto HorizSeg 0 rlineto stroke } def /six { 0 0 moveto 0 Gap rmoveto 0 VerSeg rlineto 0 Gap 2 mul rmoveto 0 VerSeg rlineto Gap Gap rmoveto HorizSeg 0 rlineto Gap HalfHeight Gap add neg rmoveto 0 VerSeg neg rlineto Gap neg Gap neg rmoveto HorizSeg neg 0 rlineto 0 HalfHeight rmoveto HorizSeg 0 rlineto stroke } def /seven { 0 0 moveto Width Gap rmoveto 0 VerSeg rlineto 0 Gap 2 mul rmoveto 0 VerSeg rlineto Gap neg Gap rmoveto HorizSeg neg 0 rlineto stroke } def /eight { 0 0 moveto 0 Gap rmoveto 0 VerSeg rlineto 0 Gap 2 mul rmoveto 0 VerSeg rlineto Gap Gap rmoveto HorizSeg 0 rlineto Gap Gap neg rmoveto 0 VerSeg neg rlineto 0 Gap 2 mul neg rmoveto 0 VerSeg neg rlineto Gap neg Gap neg rmoveto HorizSeg neg 0 rlineto 0 HalfHeight rmoveto HorizSeg 0 rlineto stroke } def /nine { 0 0 moveto 0 HalfHeight Gap add rmoveto 0 VerSeg rlineto Gap Gap rmoveto HorizSeg 0 rlineto Gap Gap neg rmoveto 0 VerSeg neg rlineto 0 Gap 2 mul neg rmoveto 0 VerSeg neg rlineto Gap neg Gap neg rmoveto HorizSeg neg 0 rlineto 0 HalfHeight rmoveto HorizSeg 0 rlineto stroke } def dictend def /BuildChar { % font char exch begin Encoding exch get CharProces begin Width DigitSpacing add 0 -1 -1 20 40 setcachedevice LineWidth setlinewidth cvx exec end end } def end /Digital_Font Digital_Font_Dict definefont pop /the_delta 0 def /the_oldtime [0 0 0 0 0 0 0] def /redo_time { 10 dict begin /the_ball (%socketc13) (r) file dup 60 string readstring pop exch closefile def /the_delta currenttime store /the_oldtime [ the_ball 0 3 getinterval the_ball 4 3 getinterval the_ball 8 2 getinterval cvi the_ball 11 2 getinterval cvi the_ball 14 2 getinterval cvi the_ball 17 2 getinterval cvi the_ball 20 4 getinterval cvi ] store end } def redo_time /the_newtime { 10 dict begin /foo [ the_oldtime aload pop ] def currenttime the_delta sub /h 1 index 60 div cvi def /m 1 index h 60 mul sub cvi def /s exch dup cvi sub 60 mul def foo 5 foo 5 get s add cvi put foo 5 get 60 ge { /m m 1 add store foo 5 foo 5 get 60 sub cvi put } if foo 4 foo 4 get m add put foo 4 get 60 ge { /h h 1 add store foo 4 foo 4 get 60 sub put } if foo 3 foo 3 get h add put foo 3 get 24 ge { redo_time /foo [ the_oldtime aload pop ] def } if foo end } def /do_window_update { gsave initmatrix clippath pathbbox 60 div exch /num_dig win send 30 mul 10 sub div exch scale pop pop /Digital_Font findfont 20 scalefont setfont 0 0 0 rgbcolor fillcanvas 1 1 0 rgbcolor setcolor do2412 1 eq { 30 10 moveto } { 15 10 moveto } ifelse the_newtime dup 5 get 2 string cvs dup length 2 exch sub 2 string dup 0 32 put dup 1 32 put dup 4 -2 roll exch putinterval exch dup 4 get 2 string cvs dup length 2 exch sub 2 string dup 0 32 put dup 1 32 put dup 4 -2 roll exch putinterval exch 3 get dup 12 gt do2412 1 eq and { 12 sub /_day_half (PM) def } { /_day_half (AM) def } ifelse 2 string cvs dup length 2 exch sub 2 string dup 0 32 put dup 1 32 put dup 4 -2 roll exch putinterval dohms 0 eq { (%:%:%) sprintf show } { 3 -1 roll pop (%:%) sprintf show } ifelse do2412 1 eq { 5 35 moveto /Iconic? win send { /Times-Roman findfont 2 scalefont setfont } { /Times-Bold findfont 10 scalefont setfont } ifelse _day_half show } if grestore } def { /PaintClient { ClientCanvas setcanvas do_window_update } def /PaintIcon { IconCanvas setcanvas do_window_update } def } win send /do_app_update { /Iconic? win send { cani setcanvas } { can setcanvas } ifelse do_window_update } def { createevent dup begin /Name /FoobarTimeUpdate def /Canvas can def end expressinterest { /Iconic? win send { cani setcanvas } { can setcanvas } ifelse do_window_update createevent dup dup /lasteve exch def begin /Name /FoobarTimeUpdate def % /TimeStamp currenttime 0.25 add def /Canvas can def % /TimeStamp currenttime 0.01666 add def /TimeStamp currenttime timetnu add def end sendevent { awaitevent dup /Name get /FoobarTimeUpdate eq { pop exit } { redistributeevent } ifelse } loop } loop } fork From don@brillig.umd.edu Wed Mar 8 15:02:33 1989 Date: Wed, 8 Mar 89 15:02:33 EST To: NeWS-makers@brillig.umd.edu Subject: OpenFonts From: David Rosenthal Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) This is the announcement of the Folio font technology that is in X/NeWS. It means that you'll be able to buy intelligent scaling fonts for X/NeWS from the type vendors, rather than from your PostScript language vendor. David. The following announcements were made on 3/6/89: SUN LICENSES OPENFONTS TO LEADING TYPE VENDORS AND DESIGN STUDIOS SUN INTRODUCES OPENFONTS, INTELLIGENT, NON-PROPRIETARY FONT TECHNOLOGY *** SUN LICENSES OPENFONTS TO LEADING TYPE VENDORS AND DESIGN STUDIOS MOUNTAIN VIEW, Calif.-- March 6, 1989-- Sun Microsystems today reported it has signed licensing agreements with five of the leading type vendors in graphic arts and publishing: Linotype AG, The Monotype Corporation Plc., H. Berthold AG, ITC and the design studio of Bigelow & Holmes. The five vendors will license Sun's just-introduced OpenFonts(TM) technology, thereby making a wide selection of brand-name fonts available to developers and end-users in a non-proprietary intelligent outline description called the F3(TM) format. OpenFonts is a new solution that allows use of the same font on any type of output device, from low to high resolution. It is comprised of TypeMaker(TM) software, which automatically creates intelligent outlines, and TypeScaler(TM) software, for generating bitmaps at any point size, at any resolution. Linotype AG is a leading company in the newspaper, magazine, book publishing and desktop publishing industries. "Their library is synonymous with high quality," said Scott McNealy, president and CEO of Sun. The entire Linotype library will be converted to F3, using Sun's TypeMaker, beginning with several hundred fonts within the year. It includes well-known typefaces like Times Roman(R) and Helvetica(R). Linotype AG has also obtained the right to sublicense Sun's TypeScaler software to OEMs for inclusion in printer controllers and window servers. The Monotype Corporation will convert the entire Monotype Typeface Library into F3 with TypeMaker. Developed over a period of 90 years, the Monotype library is one of the finest original typeface libraries in the world. It includes such classic and popular faces as Rockwell(R) and Bembo(R). Monotype also acquires the right to sublicense Sun's TypeScaler. Sun Microsystems and H. Berthold AG of Berlin have announced that substantial parts of Berthold's library of typefonts will be available for use on Sun workstations. As part of this cooperation, the firms have reported that the Berthold font format is now one of those accepted by TypeMaker, Sun's automated font processing software. Berthold will license TypeMaker to produce fonts in Sun's F3 format and will make those fonts available to Sun customers. "We are excited by the prospect of being able to offer the Berthold library to our electronic publishing users and applications," said Darryl Barbe, vice president and general manager, Sun Europe. Berhold and Sun expect to finalize agreements that will make the typefonts available in 1989. H. Berthold AG supplies the publishing market with software and hardware for professional typesetting and integrated processing of texts, graphics and images. Berthold's library of typefonts contains both new creations and revivals of classic designs for today's publishing market. ITC (International Typeface Corporation) has licensed its trademarks to Sun to facilitate the conversion of ITC fonts to F3 format. ITC has been a leader in bringing a wide variety of typefaces to publishing and printing markets. Bigelow & Holmes will be converting its library of fonts to the F3 format using Sun's TypeMaker software. Bigelow & Holmes is the designer of the Lucida typeface family the first faces designed specifically for output on laser printers. Lucida also broke new ground as the first set of serif, sans serif and monospaced faces designed to work harmoniously on a page. Sun Microsystems, Inc., is one of the world's leading suppliers of network-based distributed computing systems, including professional workstations, servers, and UNIX operating system and productivity software. ### *** SUN INTRODUCES OPENFONTS, INTELLIGENT, NON-PROPRIETARY FONT TECHNOLOGY Will Make Scalable Fonts Widely Available MOUNTAIN VIEW, Calif. --March 6, 1989-- Sun Microsystems today introduced OpenFonts(TM) technology, which creates fonts that can be used on any raster device, from screens to typesetters. Before now, those who needed scalable fonts were tied to the proprietary technology of specific vendors. However, OpenFonts will be supported by multiple type suppliers, making scalable fonts widely available. To this end, Sun also announced today that it has licensed OpenFonts to a number of leading type vendors and design studios, including Linotype, Monotype, Berthold and Bigelow & Holmes. Sun expects that within a year, more than 700 brand-name typefaces will be available to end-users and developers, among them Palatino(R), Helvetica(R) and Times Roman(R) from Linotype and Monotype's Bembo(R), Gill Sans(R) and Rockwell(R). OpenFonts is based on technology Sun acquired in September 1988. At the heart of this technology is an open, intelligent outline font description called the F3(TM) format. OpenFonts is comprised of two software tools that reduce or eliminate the need for manual labor in the production of intelligent outlines. TypeMaker(TM) software automatically creates F3 fonts, while TypeScaler(TM) software generates bitmaps for screen, printer and imagesetter at any point size or resolution and in any orientation. With OpenFonts, type vendors now have an inexpensive, unrestricted tool to rapidly bring new fonts to market. This technology will therefore enable end-users to pick freely from a vastly expanded range of font choices, while developers can easily incorporate intelligent font technology into their systems, applications and devices. Standard Type Format Needed Leading type vendors are reporting that OpenFonts should have a great impact on the industry. "This is an important development in printing technology," said Rene Kerfante, director of typography for Monotype. OpenFonts solves several of today's problems: a limited choice of fonts in many incompatible formats and substantial barriers to entry for type suppliers. Intelligent outline fonts contain not only information about the character shapes but also "hints" that describe how the character should be rendered at small sizes and low resolutions. While character shape information exists in the libraries of many font suppliers, hints must be individually created from scratch for each typeface. The usual method of generating this information involves from two to six man-weeks of highly trained labor. Additional specialized labor is needed beyond the generation of the hints before intelligent outline fonts can be marketed. The reason is that, in spite of the hints, the characters produced from intelligent outlines at screen resolutions are seldom acceptable. Bitmap fonts that match the outlines must therefore be produced -- in a largely manual process -- and distributed with the intelligent outline fonts for screen use. As a result, of the tens of thousands of commercially available typefaces, only a few hundred are available in any one intelligent outline format. OpenFonts licensees expect their costs of producing fonts to dramatically decrease. This will enable them to create hundreds of typefaces in the F3 format within a year, they report. Linotype and Monotype intend to offer their entire font libraries in F3 format in the future. "We believe that our alliance with Sun will strengthen our position to market the Linotype Library for new emerging publishing technologies," said Dr. Wolfgang Kummer, chairman of Linotype. As part of its licensing agreements, Sun will provide a limited number of fonts with its workstations. This includes all 35 of the typefaces in Apple's LaserWriter printer, most of which are trademarked typefaces >from Linotype and International Typeface Corp. (ITC). In addition, Sun will add a selection of typefaces from Monotype and Bigelow & Holmes. According to Roger Black, president of Roger Black Inc. and a world-famous publication designer, "The availability of a much larger variety of type on off-the-shelf platforms should also have a major impact on the number of designers using computers. Lack of type has been the number one excuse." Sun Microsystems, Inc., headquartered in Mountain View, Calif., is a leading worldwide supplier of network-based distributed computing systems, including professional workstations, servers and UNIX operating system and productivity software. ### Press contact: Cindee Mock 336-3563 From don@brillig.umd.edu Wed Mar 8 15:08:33 1989 Date: Wed, 8 Mar 89 15:08:33 EST To: NeWS-makers@brillig.umd.edu Subject: Re: converting SunView icons to NeWS icons From: thaeler@hc.dspo.gov (Bret K. Thaeler) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) This is another program that was written when the code that Josh previously posted was created. This program converts each character of a vfont into a seperate file in suntools iconedit format. This allows you to take the existing NeWS Icon font and convert it into a vfont, you can then dump that into files sutable for use with the iconedit tool. You can then take this and with the code previously posted and put the new modified icon back into your NeWS applications... Here is how to do it: 1) First compile the inclosed program. a) extract the end of this article into the file 'extract_font.c'. b) % cc -o extract_font extract_font.c 2) Now copy the NeWS Icon font and make it into a vfont. a) % mkdir play b) % cd play c) % cp /usr/NeWS/fonts/Icon12.fb . d) % dumpfont -d . -v Icon12.fb 3) Now run the extract font program. a) % extract_font Icon12.vft The extract font program will produce a file for each character in the font. Each file will be named 'Icon12.vft.??' where ?? is the 'character number' of the icon. You can now type '% iconedit' and load the file '*' to lookat and select to modify any of the icons... If you have any questions or comments let me know. Have fun..... -Bret Thaeler Los Alamos Nations Labs (MEE-10) thaeler@hc.dspo.gov --------------- extract_font.c -------------- /* * Written by Bret K. Thaeler * Los Alamos National Labs (MEE-10) * thaeler@hc.dspo.gov * * extract_font: * This program converts a vfont (a possibly produced by the * NeWS program 'dumpfont') into a series of ascii files * sutable for use with the suntools utility 'iconedit'. * You can use this code to modify NeWS icons... */ #include #include #include main(argc, argv) int argc; char *argv[]; { FILE *font_file, *output_file; int i, j, k, bits_to_read, row_rounded; long pos; struct header header; struct dispatch characters[NUM_DISPATCH]; char buff[256]; unsigned char *char_buff, *data_pointer, data, sub_data; char_buff = 0; if (!(argc >= 2)) { printf("Usage: %s font_list\n", argv[0]); exit(-1); } for(argc--, argv++; argc > 0; argc--, argv++) { if ((font_file = fopen(argv[0], "r")) == NULL) { printf("Can't open file '%s'.\n", argv[0]); continue; } if (fread(&header, sizeof(struct header), 1, font_file) != 1) goto error; if (header.magic != VFONT_MAGIC) { printf("Bad MAGIC number in file '%s'.\n", argv[0]); fclose(font_file); continue; } if (char_buff) { free(char_buff); char_buff = 0; } char_buff = (unsigned char *) malloc(header.maxx/8 * header.maxy); if (fread(characters, sizeof(struct dispatch), NUM_DISPATCH, font_file) != NUM_DISPATCH) goto error; pos = ftell(font_file); for(i = 0; i < NUM_DISPATCH; i++) { if (characters[i].nbytes == 0) continue; fseek(font_file, (long)(pos + characters[i].addr), 0); sprintf(buff, "%s.%d", argv[0], i); if ((output_file = fopen(buff, "w")) == NULL) { printf("Can't open outputfile '%s'.\n", buff); continue; } if (fread(char_buff, characters[i].nbytes, 1, font_file) != 1) { printf("Can't read from input file '%s' character '%d'.\n", argv[0], i); fclose(output_file); continue; } if (((characters[i].left + characters[i].right) % 8) != 0) { bits_to_read = ((8 - ((characters[i].left + characters[i].right) % 8)) + (characters[i].left + characters[i].right)) * (characters[i].up + characters[i].down); row_rounded = (8 - ((characters[i].left + characters[i].right) % 8)) + (characters[i].left + characters[i].right); } else { bits_to_read = (characters[i].left + characters[i].right) * (characters[i].up + characters[i].down); row_rounded = (characters[i].left + characters[i].right); } data_pointer = char_buff; fprintf(output_file, "/* Format_version=1, Width=%d, Height=%d, Depth=1, Valid_bits_per_item=16\n */\n", /* (characters[i].left + characters[i].right), */ row_rounded, (characters[i].up + characters[i].down)); while(1) { fprintf(output_file, "\t"); for(k = 0; k < 8; k++) { fprintf(output_file, "0x%02X", *(data_pointer++)); fprintf(output_file, "%02X", *(data_pointer++)); if ((bits_to_read -= 16) < 0) bits_to_read = 0; if (bits_to_read != 0) fprintf(output_file, ","); else { fprintf(output_file, "\n"); goto done; } } fprintf(output_file, "\n"); } done: fclose(output_file); } continue; error: printf("Error while reading file '%s'.\n", argv[0]); if (char_buff) { free(char_buff); char_buff = 0; } fclose(font_file); } } From don@brillig.umd.edu Thu Mar 9 06:56:12 1989 Date: Thu, 9 Mar 89 06:56:12 EST To: NeWS-makers@brillig.umd.edu Subject: simple trick for finding unbalanced parens From: Don Hopkins Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Every once in a while I'll accidentally munge a PS file that I'm editing, and delete a closing brace or paren or something. The symptom is that I psh a file, NeWS crunches on it, and then nothing happens. Inserting the following two lines into the beginning of the file helps to find out where it is the scanner's getting bonked out: /old-def /def load def /def { 1 index = flush old-def } def -Don From don@brillig.umd.edu Thu Mar 9 06:56:21 1989 Date: Thu, 9 Mar 89 06:56:21 EST To: NeWS-makers@brillig.umd.edu Subject: Updated version of softmenu.ps From: don@amanda.cs.umd.edu (Don Hopkins) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) There were some bugs in softmenu.ps that I have hopefully fixed. Here we go again! -Don %! %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Copyright (C) 1989 by Don Hopkins. 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. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Menus that can be changed while they're popped up. % Don Hopkins % % Instructions: % % This file defines a subclass of DefaultMenu called SoftMenu, which % it then installs as DefaultMenu. % It allows you to cut & paste menu keys around dynamically from menu % to menu, using the PointButton. (The left mouse button on a Sun.) % This should work with most menu classes. (hopefully...) Just don't % load it in on top of itsself. % % While making a selection from a menu: % PointButton % Copy the highlighted menu item to PrimarySelection. % (i.e. like "copy" on the Mac) % Shift PointButton % "Insert" the menu item from PrimarySelection before the % highlighted item. If no items are highlighted, it's appended % to the end of the menu. % Control PointButton % "Delete" the highlighted menu item. % Meta PointButton % "Edit" the highlighted menu item. (Coming soon. Suggestions?) % % To make a new menu item, you can select a string or array % subinterval which will push a menu key and an action on the stack % when executed, and insert it into a menu. Note that everything is % executed in the context of the menu you're inserting into. % % It's your responsibility to avoid circularities! % % If you select a (dict,key) pointer in cyberspace, and insert it % into a menu, the key name will be the menu key and the value % "dict key get" will be the action. % % Examples: (just select the following and paste them:) { (--------) {} % separator (Frame...) /FrameMenu ThisWindow send (Hello, Sailor!) { gsave framebuffer setcanvas currentcursorlocation [(Nothing) (happens) (here.)] popmsg pop grestore } (Be Gone!) { /flipiconic ThisWindow send /tobottom ThisWindow send } (rootmenu) rootmenu (psload) { (NEWSHOME) getenv (/bin/psload) forkunix } } pop systemdict begin /SoftMenu DefaultMenu dictbegin /Changed? true def /MenuLock null def /ChangedEvent null def /ChangeDelay .25 60 div def /Control false def /Shift false def /Meta false def dictend classbegin /new { /new super send begin /MenuLock createmonitor def currentdict end } def /layout { MenuLock { /layout super send /Changed? false def } monitor } def /paint { MenuLock { /paint super send } monitor } def /insertitem { MenuLock { /insertitem super send change } monitor } def /deleteitem { MenuLock { /deleteitem super send change } monitor } def /showat { MenuLock { /showat super send } monitor } def /change { /Changed? true def /MenuValue null def /PaintedValue null def MenuCanvas null ne { ChangedEvent null eq { /ChangedEvent createevent def ChangedEvent /Name /MenuChanged put } { ChangedEvent recallevent } ifelse ChangedEvent /Canvas MenuCanvas put ChangedEvent /TimeStamp currenttime ChangeDelay add put ChangedEvent sendevent } if } def /makeinterests { /makeinterests super send /MenuInterests [ MenuInterests { dup /Name get PointButton eq { pop } if } forall /MenuChanged /ChangeProc null MenuCanvas eventmgrinterest PointButton /PointProc /DownTransition MenuCanvas eventmgrinterest ] def } def /DragProc { Changed? { ChangeProc } if /DragProc super send } def /PaintMenuValue { Changed? { ChangeProc } if /PaintMenuValue super send } def /ChangeProc { ChangedEvent recallevent Changed? MenuCanvas null ne MenuEventMgr null ne and and { gsave framebuffer setcanvas MenuCanvas getcanvaslocation /MenuValue null def /PaintedValue null def layout reshape MenuCanvas setcanvas movecanvas % clippath extenddamage % /MenuEventMgr null def % { clear MenuX MenuY MenuHeight add showat } fork pop % currentprocess killprocess grestore } if } def /UpdateShifts { /Shift false def /Control false def /Meta false def CurrentEvent /KeyState get { { /Shift /Control /Meta } { 1 index eq { dup true def exit } if } forall pop } forall } def /PointProc { UpdateShifts Control { PointDelete } { Shift { PointInsert } { Meta { PointEdit } { PointSelect } ifelse } ifelse } ifelse } def /PointDelete { PointSelect % Select it so we can insert it again % Menus break with 0 items... MenuValue null ne MenuItems length 1 gt and { MenuValue deleteitem } if } def /PointInsert { MenuValue dup null eq { pop MenuItems length } if % index /PrimarySelection getselection % sel dup null eq { pop pop } { dup /ContentsPostScript known { dup /ContentsPostScript get exch % obj sel dup /SelectionStartIndex known not { pop } { dup /SelectionLastIndex known { dup /SelectionStartIndex get % obj sel start exch /SelectionLastIndex get % obj start last 1 index sub 1 add % obj start len getinterval % interval } { % obj sel /SelectionStartIndex get % obj index exch 1 index get % index val exch (%) sprintf exch % key val 2 array astore % [ key action ] } ifelse } ifelse } { /ContentsAscii get } ifelse { count 1 roll count 1 sub {pop} repeat { cvx exec } errored pop count 2 ne { (Bad MenuKey) {} } if 2 array astore } fork waitprocess exch pop aload pop % index key proc insertitem % } ifelse } def /PointEdit { % Pop up dialog box? } def /PointSelect { MenuValue null ne { MenuItems MenuValue get begin 20 dict begin /ContentsPostScript [ [ /Key load Menu dup null eq { pop /Action load } if ] /aload cvx /pop cvx ] def /ContentsAscii ContentsPostScript 0 get aload pop exch (MenuItem[% %]) sprintf def /SelectionObjSize 1 def /SelectionResponder null def /Canvas MenuCanvas def /SelectionHolder MenuEventMgr def currentdict end % SelectionDict /PrimarySelection setselection end % ItemDict } if } def classend def /setdefaultmenu { % class => - /DefaultMenu exch store systemdict /rootmenu known { /rootmenu /flipstyle rootmenu send store } if } def SoftMenu setdefaultmenu end % systemdict From don@brillig.umd.edu Thu Mar 9 06:57:15 1989 Date: Thu, 9 Mar 89 06:57:15 EST To: NeWS-makers@brillig.umd.edu Subject: wtf.ps From: don@amanda.cs.umd.edu (Don Hopkins) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Here's a fun way to look at strings of text! You have to try this out to see what it does. (No it's not the shoelace window! Josh?) -Don %! %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % String Shaped Window % Copyright (C) 1988. % By Don Hopkins. % All rights reserved. % % This program is provided for UNRESTRICTED use provided that this % copyright message is preserved on all copies and derivative works. % This is provided without any warranty. No author or distributor % accepts any responsibility whatsoever to any person or any entity % with respect to any loss or damage caused or alleged to be caused % directly or indirectly by this program. This includes, but is not % limited to, any interruption of service, loss of business, loss of % information, loss of anticipated profits, core dumps, abuses of the % virtual memory system, or any consequential or incidental damages % resulting from the use of this program. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Instructions: % % psh wtf.ps % % If is not given, a studly default is used. % Stroke out a window. % Text that you type in it is inserted at the end of the string. % You can paste text onto the end by typing Get (L8). % Type EditBackChar (Delete) to erase a character. % Type EditBackLine (^U) to erase the line. % Hit return or click the PointButton (left) to copy the string to the % /PrimarySelection. % Type escape to toggle between graph and paper tape shape. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Based on "input-example" by Dave Lavellee, % and "ptape" by Don Hopkins. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /main { { newprocessgroup framebuffer setcanvas /win framebuffer /new DefaultWindow send def % Create a window { /Background .125 .125 .125 rgbcolor def /Foreground 1 1 1 rgbcolor def /BorderLeft 2 def /BorderRight 2 def /BorderTop 2 def /BorderBottom 2 def /hole-radius 4 def /hole-spacing 12 def /tape-margin 3 def /inputtext ($1) dup () eq { pop ( NeWS! NeWS! NeWS! NeWS! NeWS! ) } if def /old-matrix matrix def /ptape-string () def /ptape { % width height string => /ptape-string exch def /image-height exch def /image-width exch def old-matrix currentmatrix pop /tape-length ptape-string length hole-spacing mul tape-margin dup add add def /tape-width hole-spacing 9 mul tape-margin dup add add def image-width tape-length div image-height tape-width div scale newpath 0 0 moveto tape-length 0 rlineto 0 tape-width rlineto tape-length neg 0 rlineto closepath hole-spacing 2 div tape-margin add dup translate ptape-string { /char exch def /power 1 def 8 { power 16 eq { 0 0 hole-radius 2 div 0 360 arc closepath 0 hole-spacing translate } if pause char power and 0 ne { 0 0 hole-radius 0 360 arc closepath } if 0 hole-spacing translate /power power dup add def } repeat hole-spacing dup -9 mul translate } forall old-matrix setmatrix } def /graph { % width height string => /ptape-string exch def /image-height exch def /image-width exch def old-matrix currentmatrix pop /tape-length ptape-string length hole-spacing mul tape-margin dup add add def /tape-width 256 tape-margin dup add add def image-width tape-length div image-height tape-width div scale newpath tape-length tape-width moveto tape-length 0 lineto 0 0 lineto 0 tape-width rlineto hole-spacing 2 div tape-margin add dup translate ptape-string { /char exch def 0 char lineto % 0 char .5 controlpoint hole-spacing 0 translate } forall closepath old-matrix setmatrix } def /shape-state true def /toggle-shape { /shape-state shape-state not def FrameX FrameY FrameWidth FrameHeight reshape } def /make-shape { shape-state { graph } { ptape } ifelse } def % The client canvas will be rectangular inside an % elliptical frame with 0 borders. /ShapeFrameCanvas { % Form into a circle gsave ParentCanvas setcanvas FrameX FrameY translate matrix currentmatrix 0 0 moveto 0 FrameHeight translate -90 rotate FrameHeight FrameWidth inputtext make-shape setmatrix FrameCanvas eoreshapecanvas FrameCanvas /Mapped true put MoveFrameControls grestore } def /ShapeClientCanvas { % Form into a circle % Don't do anything. Doesn't get mapped? } def /ShapeIconCanvas { gsave ParentCanvas setcanvas % Try to align the bits of the icon with the round shape 0 0 translate ParentCanvas setcanvas matrix currentmatrix 0 0 moveto 0 IconHeight translate -90 rotate IconWidth IconHeight inputtext make-shape setmatrix IconCanvas eoreshapecanvas grestore } def /PaintFrame { clippath Background setshade fill Foreground setshade repair } def % Supposedly can't see frame /PaintIcon { clippath Background setshade fill Foreground setshade } def /ClientCanvas null def /IconImage /scroll def /PaintFocus { } def % Don't show input focus--ruins images /ForkPaintClient? true def % avoid forking PaintClient. } win send /reshapefromuser win send % Shape window. /can win /FrameCanvas get def can setcanvas /map win send % Map the window. (Damage causes PaintClient to be called) { % Stolen from Scout's keyboard input example: /textx 8 def /initx 8 def /texty 8 def /inity 8 def /textfont /Courier-Bold findfont 16 scalefont def /labelx gsave textfont setfont (X) stringwidth pop 1.5 mul grestore def /cleartext { gsave can setcanvas Background setshade initx inity moveto inputtext show () setinputtext Foreground setshade /textx initx store /texty inity store grestore } def /setinputtext { % str => - /inputtext exch def shapewindow } def /shapewindow { gsave textfont setfont FrameX FrameY FrameWidth FrameHeight reshape grestore } def %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% KEY HANDLING PROCEEDURES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /addchar { cvis addstring } def /addstring { gsave inputtext exch append dup setinputtext grestore } def /deletechar { gsave inputtext () ne { inputtext dup length 1 sub 0 exch getinterval setinputtext } if grestore } def /deleteline { cleartext } def /returnkey { selectstring } def /selectstring { 20 dict begin /ContentsAscii inputtext def /SelectionResponder null def /Canvas can def /SelectionHolder currentprocess def currentdict end /PrimarySelection setselection } def /extendstring { selectstring % for now } def /deselectstring { } def /handlers 200 dict dup begin 0 1 127 { dup [ exch /addchar cvx ] cvx def } for 13 {returnkey} def 27 {toggle-shape} def /EditBackChar {deletechar} def /EditBackLine {deleteline} def /InsertValue {dup /Action get addstring} def /DeSelect {deselectstring} def % /SetSelectionAt {selectstring} def % /ExtendSelectionTo {extendstring} def end def %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% INITIALIZE A WINDOW %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /repair { gsave can setcanvas textfont setfont FrameHeight inity sub % y inputtext { % y cvis exch % s y textfont fontheight sub dup inity lt { pop FrameHeight inity sub textfont fontheight sub labelx 0 translate 0 0 transform pop FrameWidth gt { exit } if } if initx 1 index moveto exch show } forall pop grestore } def /MouseClickEventMgr [ PointButton { selectstring } /DownTransition can eventmgrinterest ] forkeventmgr def %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% KEYBOARD INPUT LOOP %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% { can setcanvas currentcanvas addkbdinterests pop currentcanvas addselectioninterests pop currentcanvas addeditkeysinterest pop { awaitevent dup /Name get dup handlers exch known { handlers exch get exec } if clear } loop } fork } win send } fork pop } def main From don@brillig.umd.edu Thu Mar 9 17:20:14 1989 Date: Thu, 9 Mar 89 17:20:14 EST To: NeWS-makers@brillig.umd.edu Subject: SGI TextItem From: baker@ncsa.uiuc.edu (Polly Baker 2nd signon) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) I'm having trouble getting a TextItem to work on the SGI running 4Sight. The item activates correctly (the vertical bar appears and blinks when the item is clicked) but keyboard input is not echoed in the item itself. What am I missing? Polly Baker Natl. Center for Supercomputing Applications, 605 E. Springfield, Champaign, IL 61801 ARPA: baker@ncsa.uiuc.edu From don@brillig.umd.edu Thu Mar 9 18:22:04 1989 Date: Thu, 9 Mar 89 18:22:04 EST To: NeWS-makers@brillig.umd.edu Subject: Pie menus with "Direct Pac-Manipulation" feedback From: don@amanda.cs.umd.edu (Don Hopkins) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) This is a new version of pie menus for NeWS, with several bugs fixed, some defaults changed, and some new features added. They don't use retained canvas by default, and they don't use savebehind on a monochrome display, since it seems to occasionaly tickle some server bug and leave turds on the screen. Now pie menus support mouse ahead display supression based on mouse motion (instead of a timeout like before), and "Direct Pac-Manipulation" feedback. If you press the menu button down, without moving the mouse, the menu should pop up almost immediatly. If you're moving the mouse around, the menu display is supressed until you stop moving or make a selection. If you "mouse ahead", and make a selection quickly before the menu is displayed, then you will see a pac-man blink onto the screen where the menu would have been and chomp the slice you selected. You can tell you're getting the hang of it and really racking up them points when you can make the pac-man blink all the way through several levels of nested menus! But other people can look at the screen and see what menu selections you're making, so if you'd rather that your menu selections be invisible and mysterious, you can set the class variable /Wocka to false. If you can tolerate it, you can increate /WockaTime to get a slower pac-man. (PS: Lawyers, please note, this uses a non-profit, non-denominational, generic pac-man, whose green card is on file. All disclaimers in the universe apply, but are not listed here due to space limitations. "moveto", "arc", and "closepath" are trademarks of Adobe. ;-) -Don %! %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % @(#)piemenu.ps % % Pie menu class implementation. % Copyright (C) 1987. % By Don Hopkins. % All rights reserved. % % Simple Simon popped a Pie Men- % u upon the screen; % With directional selection, % all is peachy keen! % % Pie Menus are provided for UNRESTRICTED use provided that this % copyright message is preserved on all copies and derivative works. % This is provided without any warranty. No author or distributor % accepts any responsibility whatsoever to any person or any entity % with respect to any loss or damage caused or alleged to be caused % directly or indirectly by this program. This includes, but is not % limited to, any interruption of service, loss of business, loss of % information, loss of anticipated profits, core dumps, abuses of the % virtual memory system, or any consequential or incidental damages % resulting from the use of this program. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % May 28 1987 Don Hopkins % First cut, based on LitePullRightMenu. % % May 30 1987 Don Hopkins % Uses "Thing"s from liteitem.ps for key labels. A thing can be a % string, or a keyword. The string is shown in MenuFont. The % keyword can be either the name of an icon in icondict, or bound % on the dict stack to an executable function. The function takes % a boolean as input; if true, it draws itsself; if false, it % returns its width and height. % NOTE: in NeWS 1.1, a Thing is either: a string, a keyword (icon % name only), an executable array (taking /draw or /size as % input), or an Object dict (sent a /draw and /size messages). % See the colornames demo! % Better label positioning scheme: top or bottom justify labels at % at the very bottom or top of the menu, and left or right justify % labels on the right or left sides of the menu. The points % relative to which the labels are justified are positioned at % evenly spaced angles in a circle around the menu center. The % instance variable PieInitialAngle is the angle of the first % point. LabelRadius is the distance from the menu center to each % point, calculated as: % LabelMinRadius + LabelRadiusPerKey * % NOTE: LabelRadiusPerKey is obsolete now. LabelRadius is automatically % pushed out until no labels overlap. % If the menu can't be centered on the location of the button % event that invoked it, then warp the cursor to the menu center % plus how much it has moved since the button down event, so that % pop up menus near the screen edge and static menus work % correctly. But ARRRGH FOO: setcursorlocation is broken!!! It % moves the cursor, but next time you move the mouse, the cursor % pops back to where it used to be! The Sun X server used to have % the same problem with XWarpMouse. Makes you wonder. Well, % anyway, I commented it out, because it's more confusing with % setcursorlocation broken than it is not warping at all. % NOTE: It's fixed now, so it works right! % % July 13 1987 Don Hopkins % Fixed up handling of retained canvases. Changed SliceLines to % SliceWedges, and made it draw wedges inside of LabelRadius. % Put in MoveMenu, which moves the menu, making sure that it's % completely on the screen, and the mouse is in the menu center. % (The latter part should be uncommented when setcursorlocation % is fixed.) Changed slice highlighting. % Implemented an oops function. Pressing the adjust button moves % the top menu so the cursor's back in its center. (Well, % setcursorlocation is still broken ...) If the mouse is already % in the menu center, then the menu is popped down and the % one below it is moved so its center is at the cursor. % NOTE: Oops works much better now that setcursorlocation is fixed! % On AdjustButton Down (Ker), the cursor moves to the menu center. % On AdjustButtonUp (Chunk), if the cursor is still in the menu % center, the menu is popped down, leaving you in the previous % menu (if any), at the location you invoked this menu from. % % July 24 1987 Don Hopkins % Changed to work with NeWS 1.1 litemenu.ps ... (just in time for SIGGRAPH!) % % August 20, 1987 Don Hopkins % Uncommented out and fixed the mouse warping code. Added display % interruption, so that if the events that would make the menu % selection are already in the event queue, then the menu is not % displayed. I'm not sure if the way I'm doing it is the best way, % but it seems to work. I'm still not sure that the way mouse warping % near the screen edge and display interruption are interacting is % really correct. It should not warp the mouse if the events are % already in the queue, so maybe warping should be defered, as well. % There was also a problem with /Damaged events generated when the % canvas is reshaped, being put into the queue before the /MapMenu % event is. This was causing the menu to be painted before the % defered mapping took place, which is not the way I think it should % work. So I kludged around it. There's got to be a safer way to % make it work right. % NOTE: This kludge has been flushed in favor of drawing the menu % before it's mapped. % A delay has been added to the map event, to facilitate mouse-ahead % display suppression. If you click down and up, without moving out % of the menu center, you will get the menu as soon you let up, but % if you click down and move, without letting up, there will be a % delay before it is mapped, during which time if you let up in an % active slice region, the mapping of the menu will be suppressed % (unless there is a submenu), and the selection you have chosen % acted upon immediatly. The submenu delay is shorter than the delay % of a menu with no parent, so that when you mouse-ahead quickly % into a submenu, you will see the submenu mapped first. (Because % the parent menu is less important than the active submenu, now % that you've already made the selection.) This may sound quite % bizarre, but it seems to work pretty nicely for me. % % March 29, 1988 Don Hopkins % Lots of changes have been made, too many to go into excruciating % detail, but I've put notes in the above comments to bring them % somewhat up to date. Please destroy any evil old copies of % piemenu.ps and replace them with this!!! % % August 28, 1988 Don Hopkins % Fixed "go!" so the framebuffer's event manager would not end up % with the currentcanvas of the process from which it was invoked. % (This was causing damage on the framebuffer not to be repainted % if piemenu.ps was run from a menu.) % Added the DontSetDefaultMenu flag. % % February 17 1989 Don Hopkins % Changed MapMenuEvent handler so that mapping is defered until % the mouse stops moving around. % % March 7 1989 Don Hopkins % Finally figure out some sort of light-weight feedback to use with % mouse-ahead display suppression, short of mapping the menu. When % popping down a menu whose display was supressed, draw a circle % where the menu would have been, with the selected slice cut out. % (Direct Pac-Manipulation feedback.) % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Things to do: % % Teach it to use items as menu keys. Create PieItems like buttons, % cycles, sliders and pull-out menus based on the distance, % etc... (Use Things that are Objects!) % % Make each slice a canvas, and map just the choosen slices. Leave % a trail of wedges to the current active submenu. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% systemdict begin systemdict /Item known not { (NeWS/liteitem.ps) run } if systemdict /LiteMenu known not { (NeWS/litemenu.ps) run } if %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Utilities % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Replace the go! function with one that starts a root event manager % that listens for (and ignores) menu button up events. This is so they % don't get dropped on the floor before a pie menu can express interest % in them. (Crucial for effective mouse-ahead!) /go! { verbose? { (Starting root eventmgr\n) print } if /rooteventmgr where { pop rooteventmgr type /processtype eq { rooteventmgr killprocess } if } if { countdictstack 1 sub {end} repeat framebuffer setcanvas /rooteventmgr [ /rootmenu where { pop MenuButton { {newprocessgroup /showat rootmenu send} fork pop } /DownTransition framebuffer eventmgrinterest MenuButton { CurrentEvent redistributeevent } null null eventmgrinterest dup /Priority -5 put AdjustButton { CurrentEvent redistributeevent } null null eventmgrinterest dup /Priority -5 put } if /Damaged {newprocessgroup damagepath clipcanvas PaintRoot newpath clipcanvas} null framebuffer eventmgrinterest ] forkeventmgr def } fork pop } def /rooteventmgr where { pop rooteventmgr type /processtype eq { go! } if } if % Coerce an angle to be >=0 and <360. % Note: mod returns integers, so's no good. /NormalAngle { % angle => angle dup 0 lt { dup 360 sub 360 idiv 360 mul sub } if dup 360 ge { dup 360 idiv 360 mul sub } if } def % From demomenu.ps % Fake method to send to a menu that returns a copy of the menu in the % new menu style. Recursivly changes all sub-menus. One thing to look % out for is that it does not change variables bound to the sub-menus % that were changed, so setting /rootmenu to the result of sending % /flipstyle to rootmenu will give you a new root menu, with a new % terminal sub-menu, but /terminalmenu will still be bound to the old % one, so sending messages to terminalmenu will not change the % terminal menu you get under the new rootmenu. But sending /flipstyle % to terminalwindow would not update the terminal menu under rootmenu. % So get your changes in before you flip styles! Or use /searchkey to % find the new menu, and re-def it in systemdict. /flipstyle { % - => newmenu 0 1 MenuActions length 1 sub { dup getmenuaction % fixed to use getmenuaction! dup type /dicttype eq { /flipstyle exch send % i menu' MenuActions 3 1 roll put % - } {pop pop} ifelse } for MenuKeys MenuActions /new DefaultMenu send } def % Override flipdefaultmenustyle, a function invoked from the user % interface menu. /flipdefaultmenustyle { % - => - (Flips default menu style) /DefaultMenu DefaultMenu SunViewMenu eq {PieMenu} {SunViewMenu} ifelse store } def %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % SimplePieMenu class % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /SimplePieMenu LiteMenu %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Instance variables % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% dictbegin % The slice currently painted. /PaintedValue null def % Inner radius around which labels are positioned. Based LabelMinRadius, % LabelRadiusPerKey, and the length of MenuKeys. /LabelRadius null def % Pie menu outer radius. Based on LabelRadius and the bounding boxes of % the Key Things. /PieRadius null def % The number of degrees a slice takes up. Based on length of MenuKeys. /PieSliceWidth null def % The current direction in degrees from the menu center to the cursor. /PieDirection null def % The current distance from the menu center to the cursor. /PieDistance null def % Angle used in loops. /ThisAngle null def % Amount to move the menu so that it fits entirely on the screen. /DeltaX null def /DeltaY null def % Flag to remember if we've gotten a menu button down event before. /GotDown false def % Interruptable display event /MapMenuEvent null def /CurX 0 def /CurY 0 def dictend %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Class variables % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% classbegin % Highlight: true strokes, false fills. /StrokeSelection false def % Width of border just inside PieRadius perimiter. /Border 3 def % Gap between outermost label edge and border. /Gap 9 def % Radius of numb hole in menu center that makes no menu selection. /NumbRadius 14 def % Fudge factors for menu positioning. /MouseXDelta 0 def /MouseYDelta -3 def % Draw lines delimiting slices. /SliceWedges true def % Draw arrows in the directions of slices. /SliceArrows false def % Drill a hole through the menu center, as big as NumbRadius. /NumbHole false def % Save the bits so pop-up is fast. % /RetainCanvas? true def /RetainCanvas? false def % Nice menu font... /MenuFont /Helvetica-Bold findfont 12 scalefont def % Draw arrow pointing to current selection? /HiLiteWithArrow? true def % Menu line attributes /MenuLineWidth 0 def /MenuLineCap 1 def /MenuArrowWidth 1 def /MenuArrowCap 1 def % Minimum radius for label positioning. /LabelMinRadius 25 def % Radius to step by when sizing menu /LabelRadiusStep 5 def % Extra radius to add when sizing menu /LabelRadiusExtra 10 def % Direction in which the keys are laid out around the circle. /Clockwise true def % The angle at which the first key is placed. /PieInitialAngle 90 def % up % Don't ask. /SplatFactor 0 def % Delays to use before mapping, if a button up has not happened yet. /MapLongDelay .6 60 div def % root menu popup delay /MapShortDelay .25 60 div def % submenu popup delay /NoMapDist 10 def % Direct Pac-Manupulation Feedback /Wocka true def /WockaTime .05 60 div def %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Class methods % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Calculate and set the menu % LabelRadius, PieRadius, MenuWidth, and MenuHeight. Shape the canvas % and set the cursor. /layout { gsave MenuFont setfont initmatrix /PieSliceWidth 360 MenuKeys length 1 max div store % Get the size of all the keys, and point them in the right direction /ThisAngle PieInitialAngle store MenuItems { begin w null eq {/Key load ThingSize /h exch def /w exch def} if /ang ThisAngle def /dx ang cos def /dy ang sin def dx abs .05 lt { % top or bottom /xoffset w -.5 mul def /yoffset ang 180 gt {h neg} {0} ifelse def } { % left or right /xoffset ang 90 gt ang 270 lt and {w neg} {0} ifelse def /yoffset h -.5 mul def } ifelse /ThisAngle ThisAngle PieSliceWidth Clockwise {sub} {add} ifelse NormalAngle store end } forall % Push the keys out so none of them overlap /LabelRadius LabelMinRadius def MenuItems length 1 gt { 0 1 MenuItems length 1 sub { /i exch def /nexti i 1 add MenuItems length mod def { i calcrect nexti calcrect rectsoverlap not {exit} if /LabelRadius LabelRadius LabelRadiusStep add def } loop } for } if /LabelRadius LabelRadius LabelRadiusExtra add def /PieRadius LabelRadius dup mul def MenuItems { begin /x dx LabelRadius cvr mul def % XXX: cvr is for NeWS math bug /y dy LabelRadius cvr mul def /X x xoffset add def /Y y yoffset add def dx abs .05 lt { % top or bottom x abs w 2 div add dup mul y abs h add dup mul add } { % left or right x abs w add dup mul y abs h 2 div add dup mul add } ifelse PieRadius max /PieRadius exch store end } forall /PieRadius PieRadius sqrt Gap add Border add round store /MenuWidth PieRadius dup add store /MenuHeight MenuWidth store grestore } def /calcrect { % item_number => x y w h MenuItems exch get begin LabelRadius dx mul xoffset add LabelRadius dy mul yoffset add w h end } def /reshape { MenuGSave framebuffer setcanvas newpath PieRadius dup dup 0 360 arc closepath NumbHole { PieRadius dup NumbRadius 1 sub 360 0 arcn closepath } if SplatFactor { 6 { PieRadius dup add random mul } repeat curveto } repeat MenuCanvas eoreshapecanvas /beye /beye_m MenuCanvas setstandardcursor % So retained canvases don't have their old image upon popup: RetainCanvas? { MenuCanvas setcanvas MenuFillColor fillcanvas } if grestore } def % Make sure nothing's highlighted if there's a retained canvas. % Layout the menu, make the canvas, and reshape it, as needed. Try to % center the menu on (XLocation, YLocation) (the location of the event % or the (X, Y) arguments), but if needed, move it so that it's % completely on the screen, remembering the distance moved in (DeltaX, % DeltaY), for repositioning the mouse later. Set up the canvas. Send % out a MapMenuEvent with a delay, so that we can supress the mapping % if we receive the events that complete the selection right away. % (This is mouse-ahead display suppression.) (Submenus have a shorter % delay than parentless menus, because if you mouse quickly into a % submenu, then wait, you're more immediatly interested in seeing the % submenu than the parent.) Finally, reset the menu value, and % activate the menu event manager. /showat { % event => - PaintedValue null ne MenuCanvas null ne and MenuWidth null ne and { MenuGSave PaintedValue PaintSlice grestore } if /PaintedValue null store MenuEventMgr null ne {MenuEventMgr waitprocess pop} if MenuWidth null eq { /layout self send MenuCanvas null ne {/reshape self send} if } if MenuCanvas null eq { /MenuCanvas ParentCanvas newcanvas def MenuCanvas /Retained RetainCanvas? put MenuCanvas /SaveBehind ColorDisplay? put % MenuCanvas /SaveBehind true put /reshape self send } if MapMenuEvent null eq { /MapMenuEvent createevent def MapMenuEvent begin /Name /MapMenu def end % MapMenuEvent } if MapMenuEvent /Canvas MenuCanvas put gsave framebuffer setcanvas dup type /eventtype eq { begin XLocation YLocation end } if PieRadius sub MouseYDelta add /MenuY exch def PieRadius sub MouseXDelta add /MenuX exch def currentcursorlocation /CurY exch def /CurX exch def clippath pathbbox /DeltaY exch def /DeltaX exch def pop pop /DeltaY MenuY MenuHeight add dup DeltaY ge { DeltaY exch sub } { dup MenuHeight lt { MenuHeight exch sub } { pop 0 } ifelse } ifelse def /DeltaX MenuX MenuWidth add dup DeltaX ge { DeltaX exch sub } { dup MenuWidth lt { MenuWidth exch sub } { pop 0 } ifelse } ifelse def /MenuX MenuX DeltaX add store /MenuY MenuY DeltaY add store % MenuCanvas savebehindcanvas MenuCanvas setcanvas MenuX MenuY movecanvas MenuCanvas canvastotop grestore % Defer the mapping till events already in the input queue % have been processed. MapMenuEvent recallevent % So active submenu pops up before already choosen parent! MapMenuEvent /TimeStamp currenttime MapShortDelay add put MapMenuEvent sendevent /MenuValue null def /GotDown false def /activate self send } def /paint { MenuGSave PaintMenuFrame PaintMenuItems grestore } def /PaintMenuFrame { MenuGSave MenuFillColor fillcanvas PieRadius dup translate newpath 0 0 PieRadius 0 360 arc closepath 0 0 PieRadius Border sub 0 360 arc closepath % 0 0 NumbRadius 0 360 arc closepath MenuBorderColor setcolor eofill grestore } def /PaintMenuItems { MenuGSave false setprintermatch PieRadius dup translate MenuItems { % item begin MenuTextColor setcolor /Key load X Y ShowThing % There seems to be a NeWS line clipping bug with lines with one % endpoint the right of the hole in the center of the menu ... 2 setlinequality % Solves SOME of the line glitches ... MenuLineWidth setlinewidth MenuLineCap setlinecap SliceWedges { gsave newpath ang PieSliceWidth 2 div sub rotate NumbRadius 0 moveto LabelRadius Gap sub 0 lineto MenuBorderColor setcolor stroke grestore } if SliceArrows { gsave MenuArrowWidth setlinewidth MenuArrowCap setlinecap newpath ang rotate NumbRadius 0 moveto LabelRadius .5 mul 0 lineto currentpoint LabelRadius .4 mul LabelRadius .04 mul lineto moveto LabelRadius .4 mul LabelRadius -.04 mul lineto MenuBorderColor setcolor stroke grestore } if end } forall grestore } def % Handle drag events. If there's not a child menu up, then track the % mouse movement, updating the menu value according the the event % location; if it has changed, then update the highlighting. /DragProc { ChildMenu null eq { MenuGSave PieRadius dup translate CurrentEvent begin XLocation DeltaX add YLocation DeltaY add end SetMenuValue MenuValue PaintedValue ne { PaintMenuValue } if grestore } if } def % Handle enter canvas events. Just call DragProc to keep the menu % value updated. /EnterProc { DragProc } def % Handle exit canvas events. Same as above. Here we keep tracking even % when you're off the menu edge (due to expressing interest in events % on the null canvas). But if it really turns you on, going off the % edge could mean no selection (like when you're within the numb % radius - look at SetMenuValue), or select the slice, or pop up a % submenu, or drag the menu around, or give more info about the slice, % or whatever. /ExitProc { DragProc } def % Pop back to the center of the menu. /KerProc { MenuGSave DragProc framebuffer setcanvas MenuX PieRadius add MouseXDelta sub MenuY PieRadius add MouseYDelta sub setcursorlocation grestore } def % Pop back to the previous menu, if we're in this menu's center. /ChunkProc { MenuGSave DragProc MenuValue null eq { popdown } if grestore } def % Map the menu on the screen. This is invoked when we get a /MapMenu % event, so that we can interrupt the display of the menu (by % recalling the event) if the events that would complete the selection % are already in the input queue. /MapMenu { gsave DeltaX 0 ne DeltaY 0 ne or { framebuffer setcanvas currentcursorlocation exch DeltaX add exch DeltaY add setcursorlocation /DeltaX 0 def /DeltaY 0 def } if % MenuCanvas /SaveBehind ChildMenu null eq put MenuCanvas /Mapped true put grestore } def /MaybeMapMenu { gsave framebuffer setcanvas CurX CurY currentcursorlocation /CurY exch def /CurX exch def CurY sub dup mul exch CurX sub dup mul add NoMapDist gt { MapMenuEvent /TimeStamp currenttime ChildMenu null eq MapShortDelay MapLongDelay ifelse add put MapMenuEvent sendevent } { MapMenu } ifelse grestore } def /popdown { % Direct Pac-Manipulation Feedback Wocka MenuCanvas /Mapped get not and { MenuValue null ne { gsave MenuItems MenuValue get begin fboverlay setcanvas overlayerase erasepage 0 setgray MenuX PieRadius add MenuY PieRadius add translate ang rotate 0 0 moveto 0 0 PieRadius % x y r PieSliceWidth 2 div dup neg arc closepath fill CurrentEvent /TimeStamp get WockaTime add { pause dup currenttime lt { exit } if } loop pop overlayerase erasepage end % Item grestore } if } if MapMenuEvent recallevent MenuCanvas null ne {MenuCanvas unmapcanvas} if % spin needs this?? RetainCanvas? not { /MenuCanvas null store /MenuInterests null store % /MenuWidth null store } if % framebuffer setcanvas? ChildMenu null ne { /popdown ChildMenu send } if ParentMenu null ne { ParentMenu /ChildMenu null put /ParentMenu null store } if MenuEventMgr null ne { MenuEventMgr /MenuEventMgr null store killprocess } if } def % Calculate and set the menu value from the cursor x y location. % Updates /PieDistance and /PieDirection instance variables. /SetMenuValue { % x y => - (Sets /MenuValue) /PieDistance 2 index cvr dup mul 2 index cvr dup mul add sqrt def exch atan /PieDirection exch def /MenuValue PieDistance NumbRadius le % It could be that when the cursor is out past the menu radius, % nothing is selected. But I don't do it that way, because it wins % to be able to get arbitrarily more precision by moving out further. % PieDistance PieRadius gt or { null } { PieSliceWidth 2 div PieInitialAngle Clockwise { add PieDirection sub } { sub PieDirection add } ifelse NormalAngle PieSliceWidth idiv } ifelse def } def % Update the highlighted slice to show the current menu value. /PaintMenuValue { % - => - (Hilite current item, un-hilite prev one.) PaintedValue PaintSlice MenuValue PaintSlice /PaintedValue MenuValue store } def % Paint highlighting on a menu slice. If it's null, then do nothing. % Draw an arrow, and a box around the key. /PaintSlice { % key => - dup null ne { % key MenuGSave PieRadius dup translate % Draw an arrow pointing out in the direction of the slice. MenuItems exch get begin % overlayerase MenuBorderColor setcolor 5 setrasteropcode HiLiteWithArrow? { gsave ang rotate newpath NumbRadius 0 moveto LabelRadius Gap sub % r dup .6 mul dup PieSliceWidth 3 div sin mul lineto dup .9 mul 0 lineto .6 mul dup PieSliceWidth -3 div sin mul lineto % closepath StrokeSelection {stroke} {fill} ifelse grestore } if % Highlight the key Thing. -4 2 X Y w h insetrrect rrectpath StrokeSelection {stroke} {fill} ifelse end grestore } {pop} ifelse % } def % Handle button up events. If we have children, then let the leaf % child menu handle the button up event. Otherwise, we handle it: If % it's a menu dictionary, then make it the child menu and show it. % Otherwise, execute the associated menu action, and send a /popdown % message to the root parent menu. /UpProc { DragProc MenuValue getmenuaction dup type /dicttype eq { /DeltaX 0 def /DeltaY 0 def % selection already made -- don't warp! /ChildMenu exch def ChildMenu /ParentMenu self put CurrentEvent /showat ChildMenu send } { pop % Ignore first mouse up if we're still in center of first menu ParentMenu null ne MenuValue null ne GotDown or or { /DeltaX 0 def /DeltaY 0 def % don't warp! { % Find the parent menu self { dup /ParentMenu get dup null eq { pop exit } { exch pop } ifelse } loop % ^?^? (toodles [tm]!) /popdown exch send domenu } fork waitprocess % doesn't return } { % If we are still in menu center then map immediatly! MapMenuEvent recallevent MapMenu } ifelse } ifelse } def % Handle menu button down events. /DownProc { /GotDown true store DragProc } def % Handle damage events. Gotta make sure the highlighted slice is % re-highlighted. /DamageProc { MenuGSave damagepath clipcanvas /paint self send PaintedValue PaintSlice newpath clipcanvas grestore } def % Construct menu event interests. Use exclusivity so only the % top-most menu sees the events. /makeinterests { /MenuInterests [ MenuButton /UpProc UpTransition null eventmgrinterest dup /Exclusivity true put dup /Priority 5 put MenuButton /DownProc DownTransition null eventmgrinterest dup /Exclusivity true put MouseDragged /DragProc null null eventmgrinterest dup /Exclusivity true put /EnterEvent /EnterProc null MenuCanvas eventmgrinterest dup /Exclusivity true put /ExitEvent /ExitProc null MenuCanvas eventmgrinterest dup /Exclusivity true put /Damaged /DamageProc null MenuCanvas eventmgrinterest dup /Exclusivity true put dup /Priority -5 put AdjustButton /KerProc DownTransition null eventmgrinterest dup /Exclusivity true put AdjustButton /ChunkProc UpTransition null eventmgrinterest dup /Exclusivity true put % Kludge to refresh messed up retained menu canvases. Ssssh! Don't tell anyone. PointButton {} DownTransition null eventmgrinterest PointButton /DamageProc UpTransition MenuCanvas eventmgrinterest /MapMenu /MaybeMapMenu null MenuCanvas eventmgrinterest dup /Priority -5 put ] def } def /getmenuaction { % index => action dup null ne { MenuActions 1 index MenuActions length 1 sub min get % Execute actions that are names! (This is so we can have references % to submenus (executable names) as actions, as opposed to having the % submenu object dict itsself!) dup type /nametype eq { exec } if } {nullproc} ifelse exch pop } def classend def /PieMenu SimplePieMenu def %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /LayeredPieMenu SimplePieMenu dictbegin /MenuArgs [] def /MenuArg null def /PaintedArg null def dictend classbegin % Need to make flipstyle a no-op because /new takes a different number % of args, and actions might depend on MenuArg! Scratch that. % Instead, let's just make a new instance of ourselves, of % the same class. /flipstyle { 0 1 MenuActions length 1 sub { dup getmenuaction % fixed to use getmenuaction! dup type /dicttype eq { /flipstyle exch send % i menu' MenuActions 3 1 roll put % - } {pop pop} ifelse } for MenuArgs MenuKeys MenuActions /new ClassName load send dup /LabelMinRadius LabelMinRadius put % hack } def /new { % args keys actions => menu % -or- args keys/actions (one array) => menu /new super send begin /MenuArgs exch def currentdict end } def /showat { /MenuArg null def PaintedArg null ne MenuCanvas null ne and MenuWidth null ne and { MenuGSave PaintedArg PaintMenuArg grestore } if /PaintedArg null store /showat super send } def /DragProc { ChildMenu null eq { MenuGSave PieRadius dup translate CurrentEvent begin XLocation DeltaX add YLocation DeltaY add end SetMenuValue MenuValue PaintedValue ne { PaintMenuValue } if MenuArg PaintedArg ne { PaintMenuArg } if grestore } if } def /DamageProc { MenuGSave damagepath clipcanvas /paint self send PaintedValue PaintSlice PaintedArg PaintArg newpath clipcanvas grestore } def /PaintMenuArg { PaintedArg PaintArg MenuArg PaintArg /PaintedArg MenuArg store } def /PaintArg { dup null ne { MenuGSave PieRadius dup translate MenuBorderColor setcolor 5 setrasteropcode 100 string cvs dup stringbbox points2rect -.5 mul exch -.5 mul exch moveto pop pop show grestore } if } def /SetMenuValue { % x y => - /SetMenuValue super send /MenuArg MenuValue null eq MenuArgs length 0 eq or { null } { PieDistance PieRadius 1 sub min NumbRadius sub PieRadius NumbRadius sub div MenuArgs length mul floor MenuArgs exch get } ifelse def } def /getmenuarg { MenuArg } def classend def %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /setdefaultmenu { % class => - /DefaultMenu exch store systemdict /rootmenu known { /rootmenu /flipstyle rootmenu send store } if } def systemdict /DontSetDefaultMenu known not { % Death to pulldown menus! PieMenu setdefaultmenu } if end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% From don@brillig.umd.edu Thu Mar 9 18:26:41 1989 Date: Thu, 9 Mar 89 18:26:41 EST To: NeWS-makers@brillig.umd.edu Subject: quickwin.ps: pie menu window manager From: don@amanda.cs.umd.edu (Don Hopkins) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) This is subclass of LiteWindow, which implements a window manager designed for pie menus. It's an improved version of neatwin.ps, which, among other things, shares the menus between all window instances, and makes the FrameCanvas and IconCanvases non-retained when they are unmapped. IconMenu and FrameMenu are one and the same. And the shared FrameMenu won't let Spin or Backgammon molest it (it gives them their own copy of itsself). -Don %! %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % @(#)quickwin.ps % % QuickWindow Class pie menu based window manager % Copyright (C) 1988. % By Don Hopkins. % All rights reserved. % % This program is provided for UNRESTRICTED use provided that this % copyright message is preserved on all copies and derivative works. % This is provided without any warranty. No author or distributor % accepts any responsibility whatsoever to any person or any entity % with respect to any loss or damage caused or alleged to be caused % directly or indirectly by this program. This includes, but is not % limited to, any interruption of service, loss of business, loss of % information, loss of anticipated profits, core dumps, abuses of the % virtual memory system, or any consequential or incidental damages % resulting from the use of this program. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % August 28, 1988 Don Hopkins % Made the menus shared by all instances of the class. % Put in a kludge to keep "spin" from trashing everybody's frame menu. % (If you want to learn how to write good NeWS code, don't look at spin.) % Added the DontSetDefaultWindow flag. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% systemdict begin systemdict /PieMenu known not { (NeWS/piemenu.ps) LoadFile pop } if /QuickWindow LiteWindow dictbegin /Retained? framebuffer newcanvas /Retained get def dictend classbegin /stretchtopright { non-iconic FrameX FrameY BBoxFromUser reshape } def /stretchtopleft { non-iconic FrameX FrameWidth add FrameY BBoxFromUser reshape } def /stretchbottomright { non-iconic FrameX FrameY FrameHeight add BBoxFromUser reshape } def /stretchbottomleft { non-iconic FrameX FrameWidth add FrameY FrameHeight add BBoxFromUser reshape } def /stretchtop { non-iconic /GA_value FrameX def /GA_constraint 0 def FrameX FrameWidth add FrameY BBoxFromUser reshape } def /stretchbottom { non-iconic /GA_value FrameX def /GA_constraint 0 def FrameX FrameWidth add FrameY FrameHeight add BBoxFromUser reshape } def /stretchleft { non-iconic /GA_value FrameY def /GA_constraint 1 def FrameX FrameWidth add FrameY FrameHeight add BBoxFromUser reshape } def /stretchright { non-iconic /GA_value FrameY def /GA_constraint 1 def FrameX FrameY FrameHeight add BBoxFromUser reshape } def /movevertical { /GA_constraint 0 def slide } def /movehorizontal { /GA_constraint 1 def slide } def /flipmove { gsave framebuffer setcanvas CurrentEvent begin XLocation YLocation end unmap Iconic? { exch FrameWidth 2 div sub exch FrameHeight 2 div sub /FrameX 2 index def /FrameY 1 index def FrameCanvas } { exch IconWidth 2 div sub exch IconHeight 2 div sub /IconX 2 index def /IconY 1 index def IconCanvas } ifelse setcanvas matrix defaultmatrix setmatrix 2 copy movecanvas flipiconic move slide grestore } def /non-iconic { Iconic? { flipiconic } if } def /reshapefromuser-open { non-iconic reshapefromuser } def /flipiconic { Retained? { % Don't retain the frame canvas when iconic! IconCanvas /Retained Iconic? not put FrameCanvas /Retained Iconic? put } if /flipiconic super send } def /CreateFrameCanvas { /CreateFrameCanvas super send /Retained? FrameCanvas /Retained get def } def /CreateFrameMenu { % - => - (Create frame menu) % Note: Store menu in class to share menus, especially if retained. /FrameMenu ClassFrameMenu def } def /CreateIconMenu { % - => - (Create icon menu) % Note: Store menu in class to share menus, especially if retained. /IconMenu {FrameMenu} def } def %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % The menus shared by all instances of the class: /MenuFont /Courier findfont 12 scalefont def /select-object { % obj => - 20 dict begin /ContentsPostScript 1 index def /ContentsAscii exch (%) sprintf def /SelectionObjSize 1 def /SelectionResponder null def /Canvas currentcanvas def % XXX? /SelectionHolder currentprocess def % XXX? currentdict end /PrimarySelection setselection } def /FrameSelectMenu [ (userdict) (ThisWindow) ] [ { currentkey cvx { exec } errored pop select-object } ] /new PieMenu send def FrameSelectMenu /MenuFont MenuFont put FrameSelectMenu /flipstyle {currentdict} put FrameSelectMenu /LabelMinRadius 5 put /FrameEtcMenu [ (zap) {/destroy ThisWindow send} (select) FrameSelectMenu ] /new PieMenu send def FrameEtcMenu /MenuFont MenuFont put FrameEtcMenu /flipstyle {currentdict} put FrameEtcMenu /LabelMinRadius 5 put /FrameMoveMenu [ /move_v {/movevertical ThisWindow send} /move {/slide ThisWindow send} /eye {/flipmove ThisWindow send} /move_h {/movehorizontal ThisWindow send} ] /new PieMenu send def FrameMoveMenu /flipstyle {currentdict} put FrameMoveMenu /LabelMinRadius 15 put FrameMoveMenu /LabelRadiusExtra 0 put FrameMoveMenu /SliceWedges false put FrameMoveMenu /HiLiteWithArrow? false put /FrameStretchMenu [ /stretch_h {/stretchtop ThisWindow send} /stretchNE {/stretchtopright ThisWindow send} [/stretch_v 4 0] {/stretchright ThisWindow send} /stretchSE {/stretchbottomright ThisWindow send} /stretch_h {/stretchbottom ThisWindow send} /stretchSW {/stretchbottomleft ThisWindow send} [/stretch_v 4 0] {/stretchleft ThisWindow send} /stretchNW {/stretchtopleft ThisWindow send} ] /new PieMenu send def FrameStretchMenu /flipstyle {currentdict} put FrameStretchMenu /LabelMinRadius 5 put FrameStretchMenu /LabelRadiusExtra 0 put FrameStretchMenu /SliceWedges false put FrameStretchMenu /HiLiteWithArrow? false put /ClassFrameMenu [ [(\255) /Symbol findfont 12 scalefont] {/totop ThisWindow send} (Paint!) {/paint ThisWindow send} (Move\274) FrameMoveMenu (Etc\274) FrameEtcMenu [(\257) /Symbol findfont 12 scalefont] {/tobottom ThisWindow send} (Shape!) {/reshapefromuser-open ThisWindow send} (Grab\274) FrameStretchMenu /eye {/flipiconic ThisWindow send} ] /new PieMenu send def ClassFrameMenu /MenuFont MenuFont put ClassFrameMenu /LabelMinRadius 10 put ClassFrameMenu /LabelRadiusExtra 10 put % Make a copy of ourselves if somebody tries to change us! % (Yes this is a hack, but otherwise "spin" messes up everybody % else's frame menu, and if you mess with the frame menu you're % asking for trouble anyway.) { /clone&forward { % /msg => - /flipstyle self send ThisWindow dup null eq { pop /win where {pop win} { % Foo on spin... /window where {pop window} { % Foo on othello... /dont-mess-with-the-frame-menu dbgbreak } ifelse } ifelse } if /FrameMenu 2 index put send } def /insertitem { /insertitem clone&forward } def /deleteitem { /deleteitem clone&forward } def /changeitem { /changeitem clone&forward } def } ClassFrameMenu send classend def systemdict /DontSetDefaultWindow known not { /DefaultWindow QuickWindow def % Hack to make ScrollWindow a subclass of QuickWindow. (gross) /ScrollWindow load type /arraytype eq { 10 dict begin /LiteWindow DefaultWindow def ScrollWindow pop end } if } if end % systemdict From don@brillig.umd.edu Fri Mar 10 20:43:39 1989 Date: Fri, 10 Mar 89 20:43:39 EST To: NeWS-makers@brillig.umd.edu Subject: HDTV--High Definition Television (a plea) From: vector!poynton@sun.com (Charles Poynton) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) This posting is followed by two separately-posted documents, TN21 and TN28 (both of whose Subject: lines begin 'HDTV--'). This is a plea for contributions which could convince the HDTV standards community to adopt square pixels for 1125-line HDTV. The current proposal calls for pixels that are 4% narrower than they are high. This fact is of little significance for traditional television but I believe it would severely limit the appeal of the standard to commercial, industrial, scientific, and medical applications, and in particular to computer graphics. Attached to this note is a letter which outlines the state of the 1125-line standards discussions, and presents names and addresses of committee chairmen and such. There is precious little participation in this effort from the computer community, and the television industry recognizes no particular advantage to square pixels. This document recommends a course of action for those of you who would like to contribute. The second posting (TN21) is my current view of HDTV in general. The Europeans have scuttled the adoption of a single international standard and have proposed their own 1250-line standard, and the U.S. television networks are muddying the waters with their 1050-line proposal (for which no hardware exists). Consumer and especially terrestrial broadcast HDTV is a long way off in America. However, the parameters of an 1125-line system for Production HDTV were adopted in the U.S. as ANSI/SMPTE 240M a few weeks ago, commercial 1125-line hardware is abundant (albeit expensive), and industrial and commercial application of this system is imminent. Colour pre-press equipment exploiting 1125-line HDTV display technology is already in the field. Discussions are currently underway to establish the standard "digital representation" of the 1125-line system. The parameters currently favoured are based on a picture with 1035 lines of 1920 pixels, and a picture aspect ratio of 16:9, giving pixels which are 4% narrower than they are high. The third posting (TN28) is a detailed description of the pixel aspect ratio issue, and the choices available for the adoption of square pixels. A 4% reduction of the proposed sampling frequency, or any of a number of other parameter changes, would make the pixels square. Warning: this one is tough slogging for anyone not intimate with television standards. Technical contributions would be most effective; for example, issues of fonts, image processing, anti-aliased rendering, filter and transform algorithms, raster file exchange, input devices (scanners, CCDs), output devices (hard copy, plasma, LCD), window system issues, etc. I'm especially looking for technical contributions from some of the large organizations who have recently announced various HDTV initiatives, for example, IBM, H-P, DEC, Apple, AT&T, MIT, and Tektronix. Organizations such as these have much to gain from the convergence of HDTV and computer graphics, but have been surprisingly absent from the standards discussions. This is a rather liberal use of net bandwidth, but if you wade through this set of documents you will be very well informed regarding HDTV. If you make a short contribution describing why square pixels are desirable, we stand a chance of adopting an HDTV standard which promises to unify the heretofore disparate fields of television and computer graphics. Thanks. Charles A. Poynton Sun Microsystems, Inc. ----- Charles A. Poynton Sun Microsystems, Inc. 2550 Garcia Avenue, MS 8-04 Mountain View, CA 94043 415-336-7846 89.03.10 The basic analog parameters of the 1125-line HDTV system have been accepted internationally (as Annex II of CCIR Report 801-2), and in the U.S. as the recently-adopted ANSI/SMPTE 240M. Standardization of the digital representation of this system is proceeding rapidly. Although it seems that European obstructionism has prevented the 1125-line system from being adopted as a single worldwide standard for HDTV, it is clear that all users of 1125-line HDTV will conform to a common standard. There is a once-in-a-lifetime opportunity to base this standard on a sampling structure which has exactly equal horizontal and vertical sample spacing, which I believe will greatly benefit both the television industry and other industries (in particular, computer graphics), by facilitating the design of hardware and software, and the exchange of images. The parameters contained in CCIR Report 801-1 and ANSI/SMPTE 240M do not specify a sampling frequency. The Japanese manufacturers' Broadcast Television Association (BTA) have recommended a sampling frequency (74.25 MHz) which produces a sample aspect ratio of 120:115, only 4% off- square. There are great benefits in having exactly square pixels, and an alternate proposed sample rate which is just 4% lower (70.875 MHz) achieves precisely square pixels. The Society of Motion Picture and Television Engineers (SMPTE) is accredited by the American National Standards Institute (ANSI) to develop national standards for studio television, and also to recommend to the U.S. State Department the position to be taken by the U.S. in international standards development. The U.S. Advanced Television Systems Committee, ATSC, also contributes to this process. The SMPTE Working Group on High Definition Electronic Production (WGHDEP), has formed the Ad-Hoc Group on Digital Representation of 1125- line HDTV (AHG-DR1125). There has been some discussion within the WGHDEP and the AHG-DR1125 regarding the square-pixel issue, but the various SMPTE groups have representation that is essentially only from the broadcast industry, which does not view square pixels as being important for their particular application. In the absence of any contribution from other industries, the current proposals will almost certainly be adopted. The feeling at the various SMPTE standards committees is that if industries other than television do not contribute to the standardization process, then the work will be done without them, and they can take or leave the result. The international standardization for HDTV is proceeding through Study Group 11 of the CCIR (International Radio Consultative Committee). The chairman of the U.S. National Study Group to the CCIR is Bernie L. Dickens. The chairman of Canadian National Study Group 11 is Ken P. Davies. These groups are fundamental to the international standards process, and the individuals have influence within SMPTE, but the international process lags the national work and this particular issue is likely to be a fait accompli before the CCIR study groups have had a chance to consider it. If you would like to make your views known, then I would suggest a short letter to Hugo Gaggioni, the chairman of the AHG-DR1125. A copy should be sent to Dick Stumpf, the chairman of the Working Group on High Definition Electronic Production (WGHDEP), and copies could optionally be sent to the other individuals listed below. The next meeting of the WGHDEP is on April 5 in Los Angeles, and the AHG-DR1125 meets on April 29 in Las Vegas, immediately prior to the National Association of Broadcasting (NAB) convention. It is likely that the square pixel issue will be finally decided at one of these meetings. I am a member of both committees, and I will convey to the committees any e-mail replies which I receive regarding this issue. A large volume of replies from the net might make the committee sit up and take notice, but e-mail contributions will carry less weight than a written submission to the committee. Please review these documents, distribute them to anyone that you think may have comments, suggestions, or influence, and let your views be known! Charles A. Poynton ----- HDTV STANDARDIZATION -- NAMES AND ADDRESSES SMPTE COMMITTEES Richard J. Stumpf, Chairman SMPTE WHGDEP Vice-President R&D, Universal Studios 100 Universal Plaza Universal City, CA 91608 818-777-3198 Hugo Gaggioni, Chairman SMPTE AHG-DR1125, Sony Advanced Systems 1600 Queen Anne Road Teaneck, NJ 07666 201-833-5715, fax 201-833-9321 Keith Field, Chairman SMPTE AHG-HDSS C.B.C. Engineering Headquarters 7925 Cote St. Luc Road Montreal, Quebec H4W 1R5 Canada 514-485-5570 SMPTE HEADQUARTERS Stanley N. Baron, SMPTE Engineering Vice-President NBC 30 Rockefeller Plaza (1600W) New York, NY 10112 212-664-7557 Barry C. Detwiler, Television Engineer SMPTE 595 West Hartsdale Avenue White Plains, NY 10607 914-761-1100, fax 914-761-3115 Sherwin H. Becker, Director of Engineering SMPTE, 595 West Hartsdale Avenue White Plains, NY 10607 914-761-1100, fax 914-761-3115 CCIR STUDY GROUPS Bernard L. Dickens, Chairman USNSG-11 C.B.S 555 West 57th Street New York, NY 10019 212-975-2003 Ken P. Davies, Chairman CNSG-11 C.B.C. Engineering Headquarters 7925 Cote St. Luc Road Montreal Quebec H4W 1R5 Canada 514-485-5474 ATSC Dr. Robert Hopkins, Executive Director A.T.S.C 1771 N Street N.W. Washington, DC 20036 202-429-5345 ----- From don@brillig.umd.edu Fri Mar 10 20:56:49 1989 Date: Fri, 10 Mar 89 20:56:49 EST To: NeWS-makers@brillig.umd.edu Subject: HDTV--Notes on Square Pixels for 1125-Line HDTV (TN28, long) From: vector!poynton@sun.com (Charles Poynton) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) HDTV--Notes on Square Pixels for 1125-Line HDTV (TN28) Charles A. Poynton Sun Microsystems, Inc. 89/03/09 11:40 SCOPE This document outlines possible choices for detailed parameters (in particular, sampling frequency) for the proposed 1125-line HDTV system which, in addition to a picture aspect ratio of 16:9, achieve a sample aspect ratio of exactly unity (i.e. "square pixels", in computer graphics terminology). The property of samples having equal horizontal and vertical spacing will be important in HDTV applications related to computer graphics, and could contribute greatly to the acceptance of the detailed HDTV parameters in systems for printing and publishing, medical applications, simulator applications, and other non-broadcast industries. This document is an update of Poynton Vector Corporation Technical Note 28 dated June 27, 1987, which was submitted to the SMPTE AHG-HDSS committee as document N15.4/6 REF 34 REV 7. General information about HDTV is available in an associated document "Current State of High Definition Television". GENERAL The basic parameters of the 1125-line HDTV system are now established in the U.S. by ANSI/SMPTE 240M, and are contained in Annex II of the international document CCIR Report 801-2: Number of scanning lines: 1125 Number of active lines: 1035 Field rate: 60.00 Hz Interlace: 2:1 Aspect ratio: 16:9 Samples per active line: 1920 for luminance (Y), 960 for colour difference (U, V) With agreement on these basic analog interface parameters, the digital representation of the 1125-line system is in the process of being standardized. "ACTIVE" SAMPLES Note that although a line rate of 33.75 kHz is implied by these parameters (1125x60 Hz), and the count of "active" samples per line is directly specified, neither the total sample count per line or the sampling frequency are specified or implied, and discussion of values for these parameters is currently taking place. The figure of 1920 "active" digital samples is suggested in an appendix of ANSI/SMPTE 240M, and has agreement of the Japanese manufacturers' group BTA. This number is derived from the number of "active" samples in CCIR Rec. 601-1 (720), times the nominal doubling of horizontal resolution (2), times the increase in aspect ratio (4/3). The word "active" is in quotes because there is not agreement on whether this number refers to the number of samples per picture width (i.e. between the 50% points of a white flatfield), or the number of digital samples per line which are permitted to be above blanking level. In a system with finite bandwidth (and risetime), some number of non-blanking digital words are required to represent the tails of the blanking transitions. If the tails of blanking are truncated, then the picture width will be narrowed as the signal passes through successive pieces of equipment. CCIR Rec. 601-1 specifies the number of "active" samples per line as 720, for both 525-line and 625-line television systems. The definition of "active" is not made explicit in this document, but it is stated that the number 720 was chosen as being sufficient to accommodate all non-blanking samples at the widest picture width tolerance of both 525- and 625-line systems. The reference number of samples per picture width (i.e. the number of samples between the 50% points of a reference white flatfield) is somewhat less than 720, nominally 702 in 625-line systems (for blanking of 12 us), and between 702 and 712 in 525-line systems (for blanking between 11.6 us and 10.8 us). CHOICE OF 1920 "ACTIVE" SAMPLES The BTA group has indicated the desire to maximize the count of samples per picture width. The choice of 1920 samples per picture width has a particular advantage when combined with a sample rate of 74.25 MHz: this sample count represents an increase in picture width over existing (5:3 aspect ratio) HDTV hardware and software which is almost exactly equal to the increase in aspect ratio from 5:3 to 16:9. With this choice of analog picture width, existing 5:3 hardware and recorded material can be used in a 16:9 system, providing a slight cropping of picture width (about 6%) and a slight alteration of aspect ratio (less than 1%) is allowed. The blanking width resulting from this choice is about 3.77 us. It is not clear how the BTA proposal would deal with transition samples. Either the number of "active" digital samples should be somewhat greater than 1920, or the number of samples per picture width should be somewhat less than this. PICTURE ASPECT RATIO OF 1.85:1 A choice of picture aspect ratio of 1.85:1 would achieve precisely square pixels with the currently-proposed sampling parameters (74.25 MHz, 1920 samples per picture width, picture time 48/55 of total line time). 1.85:1 is the most widespread aspect ratio standard for 35 mm motion picture production and distribution. This choice would require changing the 16:9 picture aspect ratio parameter of CCIR Report 801 and ANSI/SMPTE 240M. CHOICE OF 1840 SAMPLES PER PICTURE WIDTH For a total picture aspect ratio of 16:9, the aspect ratio of each sample (for a choice of 1920 samples per picture width) is 120:115, only 4% off-square. That is, the horizontal spacing of samples is 4% less than the vertical spacing between samples. This ratio must decrease slightly in order to accommodate transition samples within 1920 "active" digital samples; this will make the samples even closer to being square. With a choice of 1840 samples per picture width, the sample aspect ratio can be made exactly unity. (The value 1840 is simply the number of lines per picture height of 1035, times the picture aspect ratio of 16/9.) This choice of active samples can be made for a number of choices of total samples per line (i.e. a number of choices of sampling rate). CHOICE OF 2200 TOTAL SAMPLES The current BTA proposed sampling rate is 74.25 MHz, which is 11/2 times 13.5 MHz. This corresponds to 2200 samples per total line. Square samples are easily achieved with this sample rate, resulting in 1840 samples per picture width and a blanking time of 4.85 us almost identical the blanking time of current 5:3 equipment. However, with square samples at this sample rate a 4% picture aspect ratio error would result for existing 5:3 material displayed on new equipment. (1840 samples per picture width at 16:9 picture aspect ratio corresponds to 1725 samples at 5:3 aspect ratio.) CHOICE OF 2070 TOTAL SAMPLES A total sample count of 2070 simultaneously achieves square samples and exact preservation of the aspect ratio of existing recorded material. This sample count corresponds to a sampling rate of 69.8625 MHz, exactly 5.175 times the CCIR 601 sampling rate of 13.5 MHz. This is a somewhat inconvenient multiple [23x3x3/(5x2x2x2)]. The corresponding analog blanking value is about 3.29 us, which is somewhat short for current CRT technology. CHOICE OF 1053 LINES PER PICTURE HEIGHT If the narrower of the 525-line and 625-line values for samples per picture width is taken (625-line, at 702), then using the 2:1 horizontal sample relationship outlined above, the number of samples per picture width appropriate for the 1125-line system is 1872. With this count of samples per picture width, a count of 1053 lines per picture width obtains samples of exactly unity aspect ratio. This option is unappealing in that it would require a change to the SMPTE 240M analog interface standard. CHOICE OF 2100 TOTAL SAMPLES A choice of 2100 total samples per line results in a sample rate of 70.875 MHz, 5.25 (21/4) times 13.5 MHz. This rate has the following properties: 1. downconversion to 525-or 625-lines can use a horizontal subsampling ratio of exactly 1/2; 2. blanking time (3.67 us) is almost identical to the BTA proposal; 3. existing recorded material is reproduced with less than 1.4% aspect ratio error, an error generally agreed to be imperceptible; 4. the sample rate is related to 13.5 MHz by the simple integer ratio 21/4; 5. the 240M sync waveform can be generated exactly, using a pulse width basis of 21 clocks (the sync pulses can be generated exactly using 23.625, 13.5, or 10.125 MHz clocks); and 6. samples have exactly unity aspect ratio. This choice seems to be the best compromise between exactly square samples, preservation of existing material, and blanking time. RECOMMENDATION Sun recommends: 1. that the term "samples per total line" (S/TL) be defined as the number of sample periods per line period, and that this parameter be assigned the value 2100; 2. that the term "luminance samples per active line" (S/AL) be defined to be the maximum number of samples which may be assigned a value different from blanking level, and that this parameter be assigned the value 1920; 3. that the term "luminance samples per picture width" (S/PW) be defined to refer to the number of digital samples between the 50% points of the picture width, as referenced to a white flatfield, and that this parameter be assigned the value 1840; 4. that a note indicate that these sampling parameters result in a reference sampling frequency of 70.875 MHz, and a sample aspect ratio of exactly unity. ----- From don@brillig.umd.edu Fri Mar 10 21:49:41 1989 Date: Fri, 10 Mar 89 21:49:41 EST To: NeWS-makers@brillig.umd.edu Subject: HDTV--The Current State of High Definition Television (TN21, long) From: vector!poynton@sun.com (Charles Poynton) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) HDTV--The Current State of High Definition Television (TN21) Charles A. Poynton Sun Microsystems, Inc. 89/03/09 11:33 SCOPE Equipment for High Definition television (HDTV) is now commercially available, and HDTV is expected to be of great importance in industrial, scientific, and medical applications as well as in entertainment. This document outlines the background of HDTV, describes the basic parameters of the 1125-line system and their derivations, lists available commercial equipment, outlines potential application areas, reviews the standardization of HDTV to this point, and briefly describes standardization issues currently under discussion. INTRODUCTION Nomenclature A video system is usually denoted by its total line count and its frame rate (in hertz) separated by a solidus. For example, 525/59.94 represents the scanning parameters of the U.S. broadcast television system, and 625/50 scanning is used in Europe. Television system nomenclature refers to the total number of lines in a raster. Computer graphics nomenclature is generally concerned with the number of picture lines (lines per picture height, L/PH), which is about 8% less than the total lines in the raster in order to accommodate vertical blanking interval overhead. For example, a 1280 by 1024 system may have 1066 total lines. HDTV is defined as having approximately double the number of lines of current broadcast television at approximately the same frame rate. Hence the line rate is approximately doubled (from about 15 kHz to about 34 kHz). Luminance bandwidth is increased such that horizontal resolution is also approximately doubled. Resolution HDTV has about double the (linear) resolution of 525-line television, or about 5.5 times its luminance spatial resolution. Computer graphics is not generally concerned with the resolution of the picture on the display screen, but refers to "resolution" as the number of visible pixels stored in the frame buffer. The number of line pairs (cycles) actually resolved on the face of the display screen may be substantially less than the number of pixel pairs stored for each scan line, due to electrical and electro-optical filtering effects. Psychophysics The fundamental development work for HDTV was done at at the NHK (Japan Broadcasting Corporation), after extensive psychophysical and perceptual research led by Dr. Takashi Fujio. HDTV is capable of generating pictures substantially brighter, sharper, and of better colourimetry than 35 mm motion picture film. Many psycho-physical studies have shown that human viewers to position themselves relative to a scene such that the smallest detail of interest in the scene subtends an angle of about one minute (1/60 degrees) of arc, which is the limit of angular discrimination for normal vision. For the 481 visible lines of 525-line television the corresponding viewing distance is about 7 times picture height, and the horizontal viewing angle is about 11 degrees. For the 1035 visible lines of 1125-line HDTV, the corresponding viewing distance is 3.3 times screen height and the viewing angle is about 28 degrees. Psychophysical research has shown that a viewer's involvement in a motion picture is increased when the picture is presented with a wide aspect ratio. The aspect ratio 16:9 has been chosen for HDTV. This value, about 1.78:1, is nearly as wide as the most common theatrical film format of 1.85:1. The viewer of HDTV thus does not normally perceive increased "definition" (resolution) for the same size picture, but rather moves closer to the screen. Thus HDTV should more properly be called "wide screen television", and some argue that this designation would also be more appropriate to consumer marketing and product differentiation than "HDTV". Recent NHK research has revealed that high-quality stereo sound impacts the psychophysical response of the viewer to the picture (in particular, the viewer's eye-tracking response). Quality The picture quality of HDTV is superior to that of 35 mm film. The limit to resolution of motion picture film is not the static resolution of the film, but judder and weave in the projector. [35 mm motion picture film is conveyed vertically through the projector, and has an aspect ratio of 1.85:1, so the projected film area is only about 21 mm by 11 mm, compared to 36 mm by 24 mm for slide or print film.] Also, the colourimetry obtainable with the colour separation filters and CRT phosphors of a video system is greatly superior to that possible with the photochemical processes of a colour film system. The quality of various proposed transmission systems varies widely, and in some cases has yet to be demonstrated. The 1125/60 System This section outines the basic parameters of the 1125/60 system. More detailed information about the detailed parameters are available in an associated document. Broadcasters have proposed 1250/50 and 1050/59.94 systems in Europe and the U.S. respectively, based on "compatibility" with local broadcast standards. No commercial equipment, and very little experimental equipment, exists for these standards. Such systems will be outlined in a later section of this document. Basic Parameters of 1125/60 HDTV The scanning parameters of 1125/60 are chosen to be closely related to 525-line and 625-line systems: The total line counts 1125, 625, and 525 are odd multiples (45, 25, and 21 respectively) of 25. Vertical blanking for each system is chosen to be exactly 8% (2/25) of the total line count, thus the active line counts 1035, 575, and 483 are the odd multiples (45, 25, and 21 respectively) of 23. The target luminance bandwidth of HDTV is generally agreed to be 30 MHz, about five or six times the bandwidth of current broadcast television, although not all currently-available HDTV equipment can meet this bandwidth, and most of the proposed transmission systems cannot meet this bandwidth. SMPTE 240M Parameters The basic parameters of the 1125-line HDTV system are contained in the ANSI/SMPTE 240M standard recently-adopted in the U.S., and are contained in Annex II to the international CCIR Report 801-2. The basic parameters are as follows: Number of scanning lines: 1125 Number of active lines: 1035 Field rate: 60.00 Hz Interlace: 2:1 Aspect ratio: 16:9 Samples per active line: 1920 for luminance (Y), 960 for colour difference (U, V) ANSI/SMPTE 240M specifies RGB or YUV components, with well- characterized colourimetry and transfer functions. Luminance bandwidth is specified as 30 MHz. The signal has zero setup (pedestal), and includes a tri-level sync signal. 1125/60 Equipment Commercial hardware operating with the 1125-line system is widely available from Japanese manufacturers. Equipment which is commercially available includes: - video monitors (Sony, Hitachi, Ikegami, Barco); - video projectors (Sony, Hitachi, Ikegami); - cameras (Sony, Ikegami, Hitachi, BTS); - videotape recorder (Sony); - telecine [film-to-video] (Rank-Cintel); - framestores (Sony, Asaca/Shiba-Soku, Toko); - paintbox (Quantel); - down-converter (Sony, Ikegami) - switchers (Grass Valley Group, Sony); - test equipment (Tektronix, Magni); and - blue-screen matte (Ultimatte). 1125-line equipment which has been demonstrated, but is not necessarily commercially-available, includes: - MUSE broadcast encoder, decoder (NHK); - MUSE optical videodisc player (Sanyo, JVC); - MUSE videocassette recorder (Hitachi); - YUV videocassette recorder (Sony); - YUV videodisc player (Sony); - digital HDTV videotape recorders (Hitachi [648 Mb/s] and Sony [1.188 Gb/s]); - laser telecine (Sony, NHK) - laser film recorder (NHK); and - large-screen video projector (General Electric, Eidophor, Barco). Although current-generation 1125-line equipment is universally 2:1 interlaced, there is general agreement that the industry will tend towards progressive (non-interlaced) systems for production and display. Interlace may or may not be retained for transmission. HDTV APPLICATIONS Commercial/Industrial/Scientific It is generally thought that the initial application of HDTV will be in industrial, medical, and scientific applications where pickup, recording, and distribution of moving images is important, but where 525-line resolution is insufficient. It is also likely that HDTV technology will contribute to printing and publishing applications, even though the images in that application are stills. For example, Quantel sells their HDTV "Graphics Paintbox" to the printing and publishing industry. It is also quite likely that the 1125-line HDTV format will become an output format for computer graphics equipment. There is a strong trend in computer graphics towards higher resolution, but no preferred format. The HDTV format (about 1 k by 2 k picture samples) satisfies the need for higher resolution and high colour accuracy, and offers the opportunity to exchange, record, and distribute images among various application areas. Also, 1125- line video monitors and projectors will rapidly benefit from the economies of scale of manufacture of monitors in large quantities for other applications, and this format is therefore a good choice. Film Production HDTV is currently viable for production of material to be released on film. HDTV is equivalent (and in many respects superior) to 35 mm motion picture film. Its acceptance as a production medium awaits the wider availability of HDTV production facilities, and more knowledge of HDTV production techniques on the part of the film production community. There are advantages in producing entertainment material in HDTV, even if the end product is to be down-converted to 525-line or 625-line television. For example, it has been demonstrated that image compositing using Ultimatte can be done very effectively in HDTV. There are currently four commercial HDTV production studio facilities: Rebo Associates, Zbig Video, and 1125 Productions in New York, and Captain Video in Paris, France. A facility in Los Angeles is being planned. Consumer Broadcasting of HDTV is probably five to ten years distant, except in Japan. Broadcasting requires spectrum allocation, which is subject to domestic and international political concerns. IDTV ("improved definition") describes receiver techniques to improve the quality of standard NTSC or PAL broadcast signals. A receiver is considered IDTV if it employs frame-rate doubling to eliminate inter-line twitter, although additional techniques such as noise reduction may also be employed. IDTV receivers are currently on the market. EDTV ("enhanced definition") describes a 525-line or 625-line broadcast television signal with altered or augmented signal content which makes possible higher quality at consumer receivers. A number of proposals for EDTV broadcast systems have ben made, but equipment will not be available until a decision of EDTV brooadcast standards is made. Consumer HDTV equipment also awaits standards. It is certain that any consumer HDTV receiver equipment will include up-conversion capability, to display 525-line or 625-line signals with improved quality. Distribution of high-quality material for consumers could take place using HDTV either through cable systems (in the manner of Home Box Office), or on consumer HDTV videocassette (for sale or rental), prior to use of HDTV for broadcast in either North America or Europe. This approach to consumer HDTV may arise due to both the technical difficulty of HDTV broadcast (because of its large spectrum/bandwidth requirement), and the difficulties that the traditional broadcasting networks are likely to face in adopting HDTV. Japan seems to be absolutely committed to HDTV broadcast in the near future. It is certain that the primary origination medium for consumer HDTV in any form will initially be 35 mm motion picture film, due to the vast amount of existing material in that medium. Standards Since it is now evident that there will be no single worldwide standard, discussions in the standards communities have now concentrated on three different areas: production, distribution, and transmission. Production is the shooting and assembling of program material, distribution is the exchange among program producers, and transmission is to the consumer. History Various Japanese manufacturers exhibited HDTV equipment at the World's Fair at Tsukuba in 1985. That equipment, and some of the equipment currently in experimental use around the world, has a picture aspect ratio of 5:3 and the same 59.94 Hz field rate as 525-line NTSC television. Picture aspect ratio was changed 16:9, and field rate was changed to exactly 60.00 Hz in order to facilitate international agreement on standards, resulting in unanimous agreement to present a set of basic parameters to the CCIR Plenary session in June of 1986. Adoption of these changes by the Japanese represented a major concession to the Europeans: tooling for the manufacture of CRT display tubes with 5:3 aspect ratio was already complete at a number of companies, and the field rate change required re-engineering of equipment. The proposal was not accepted by the CCIR at that time, due to lack of agreement from the European members. The Europeans stated at the time that "serious" technical problems existed in the down-conversion of 60 Hz 1125-line HDTV to 50 Hz 625-line PAL, but both Sony and NHK developed and demonstrated extremely sophisticated down-converters prior to the 1986 CCIR Plenary Session. Experts viewing the 50 Hz output from these converters perceived no motion artifacts. Many knowledgeable individuals believe that the European governments impeded the adoption of 1125-line HDTV in an attempt to protect their domestic studio and consumer equipment manufacturers. Certainly no serious technical proposals for an alternative HDTV system have been presented by the Europeans, and only a very small quantity of experimental equipment has been built in Europe. The Europeans (and the Australians) have a political interest in not adopting HDTV at this time, due to their recent adoption of multiplexed analog component (MAC) encoding for direct broadcast from satellite (DBS) systems in these countries. Receiver manufacturers now include MAC decoders in their new receivers, but consumers must install set-top converters for old receivers in order to receive MAC. The European broadcasting community would find it embarrassing to require consumers to purchase a new converter for another new standard, just a few years after the introduction (with much fanfare) of MAC. MAC is therefore currently being promoted in Europe as being capable of upgrade to HDTV (ED-MAC, for extended definition), but there are few serious technical proposals indicating how ths can be achieved, and no converters currently being delivered that can accommodate the signal formats being proposed. Production Standards The ANSI/SMPTE 240M standard for an 1125-line Production system was adopted in the U.S. in February 1989. Disclaimers on this document carefully delineate its applicability to production use only. The standard essentially represents agreement on the detailed analog parameters of the 1125/60 system. Discussions on the digital representation of 1125-line HDTV are currently underway. Distribution Standards The de facto international television program distribution standard is, surprisingly, 35 mm film. In North America, film is transferred to video using a "3-2 pulldown" scheme which scans alternately three then two video fields from successive film frames. The film is run 0.1% slow to result in the 59.94 Hz field rate. In Europe, film is run 4% fast with 2-2 pulldown to result in 50 Hz frame rate. Discussions of distribution standards are in an early stage, but there is general agreement that film "friendliness" will be important. Transmission Standards A transmission standard is likely to mandate some form of framestore in the receiver to minimize transmission bandwidth, and to provide for standard-television backward compatibility. All proposed transmission standards involve the reduction of transmission bandwidth by exploiting the spatio-temporal properties of the human visual system, as first characterized by Drs William and Karen Glenn. Fundamentally, spatial detail is transmitted at low frame rate, and the information transmitted at the high frame rate necessary to portray motion has low spatial detail. Japan The Japan Broadcasting Corporation (NHK) in Japan is expected to commence HDTV broadcasting in 1992, using direct broadcasting from satellite (DBS) with the MUSE (MUltiple Sub-Nyquist Encoded) system. MUSE is not compatible with any current broadcast system, and has a bandwidth of about 8.4 MHz. North America VHF and UHF spectrum is controlled in the U.S. by the FCC. Many "proponents" of HDTV in the U.S. have asked the FCC to consider their systems for adoption as a U.S. standard. U.S. networks have proposed systems based on 1050-line, 59.94 Hz rasters, with a line rate of exactly twice that of the NTSC system, and about 966 L/PH. The claim is made that such systems are "compatible" with NTSC. Cable and satellite operators are unrestricted in their choice of transmission standards. It is quite conceivable that Japanese manufacturers could introduce consumer hardware prior to and quite independently of the choice of a broadcast standard. In any case, the vast majority of initial program material for consumer HDTV will be existing theatrical films from Hollywood. Europe The standardization process in Europe is substantially different from the standardization process in North America. Most broadcasting organizations are state-owned. Standards are agreed by the European Broadcasting Union, which is a union of the broadcasters. These meetings are closed; manufacturers (and other interested parties) attend only when invited. Systems based on 1250-lines and 50 Hz, with about 1152 L/PH, have been proposed by the Eureka-95 project in Europe. 1125/60 Parameters Under Discussion Although the combination of 1125 total lines, 60 Hz field rate, and 2:1 interlace produces a line rate of exactly 33.75 kHz, and therefore a line time of about 29.63 us, neither the total number of samples per line nor the sampling frequency is specified in ANSI/SMPTE 240M or CCIR Rep. 801-2. Appendix II of CCIR Rep. 801 specifies 1920 luminance samples per "active" line, following the terminology of CCIR Recommendation 601-1, but the term "active" is not defined in either document. In CCIR 601-1, it is implicit that some number of leading and trailing "active" samples are at blanking (or black) level, and some additional "active" samples are taken up by transition samples from blanking to video and video to blanking. Although the field rate of HDTV is exactly 60 Hz (emphasized by the "60.00" in the document), there is a movement in North America to accommodate operation at the NTSC field rate of 59.94 Hz, to maximize compatibility with existing NTSC equipment. Some current HDTV equipment is configurable for operation at either rate. The Square Pixel Issue Detailed parameters which have not yet been agreed upon are the sampling rate for digital HDTV systems, the number of "active" (non-blanking) digital samples per line, and the number of samples per picture width. These parameters are mutually interrelated, and should be related by simple integer ratios to the internationally-standardized digital sampling parameters for 525-line and 625-line television systems (in particular, the 13.5 MHz sampling rate and the count of 720 "active" samples per line), as documented in CCIR Recommendation 601-1. Poynton Vector has made a proposal for a sampling frequency of 70.875 MHz (2100 samples per total line) which achieves a sample aspect ratio which is exactly unity. One difficulty in the current discussion of possible parameter values for standardization is that nearly all manufacturers of HDTV equipment (and all manufacturers of cameras and VTRs) are Japanese. Thus, North American and European contributions are made from a position lacking in experience. Also, Japanese manufacturers tend to design products which are highly optimized for particular application areas, rather than being of general use. For example, three independent efforts to build an HDTV CCD imaging chip have been described, and each has non-square pixels etched into the silicon. It seems that the manufacturers expect these chips to be used only for entertainment television production applications, and are not interested in potential use of the same device in scientific and medical imaging applications for which square pixels are a necessity. Efforts to develop flat panel displays using LCD, gas plasma, and light-valve technology are underway. These devices are also fabricated with a particular pixel aspect ratio, and would also have limited appeal in other application areas. Another problem is that all discussion is taking place within the traditional television constituency of broadcasters and broadcast studio equipment manufacturers. Users in non-broadcast areas, potentially the largest users of HDTV in the two- to six-year time frame, are not represented at all. Thus the SMPTE is likely to recommend parameter values for standardization which are appropriate for broadcast applications, and not necessarily appropriate for other applications. For example, the television constituency can maximize compatibility with existing NTSC equipment by choosing the NTSC frame rate of 59.94 Hz, but this rate would place a burden on non-broadcast users and European users, who would both prefer exactly 60 Hz. However, unless the concerns of non-broadcasters are expressed within the SMPTE, the broadcast-orientation will prevail, and by the time the impact of these issues is felt by the non-broadcast users it will be too late to change. From don@brillig.umd.edu Sat Mar 11 05:17:58 1989 Date: Sat, 11 Mar 89 05:17:58 EST To: NeWS-makers@brillig.umd.edu Subject: NeWS Molecules From: Don Hopkins Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) This is a new version of the Pseudo-Scientific Visualizer. It projects hallucinations of a NeWS molecules onto the screen. (These things don't really exist, so they're not prohibited by law.) Once it's done virtualizing the hallucination, there is a shudder, a puff of smoke comes out of the back of the CPU, and then all the little bits and pieces are made synesthetically mouse sensative! Composite objects (arrays and dictionaries) highlight when you point at them, and their printed name is show in the text item at the bottom of the window. When you click the point (left) button on a highlighted object, it is selected (in PrimarySelection). When you click the point button on the background, it highlights *all* mouse sensative objects. When you click with the adjust button on a highlighted object, it zoom into that object. Select the menu item "Thing... Top" to get back to the original object.) When you change something with the menu, it takes effect immediatly while it's drawing. If you make changes after it's finished painting, you should redraw (menu "paint") the window to see them. If there is an argument to psh, it executes it and grows a molecule with the resulting object. Otherwise it just installs its class in systemdict, for later use. Use it like this: psh molecule.ps rootmenu psh molecule.ps '[ [1 2 3 4] [1 2 3] [1 2] [1] ]' psh molecule.ps '10 dictbegin /foo LiteMenu def /bar LiteItem def dictend' -Don %! %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % The NeWS Pseudo-Scientific Visualizer % -- the class browser for the other half of your brain. % Copyright (C) 1988 by Don Hopkins (don@brillig.umd.edu) % % You are free to redistribute this program. Please leave the comments % intact, add your own views and hallucinations, and pass it on to % friends! The author is not responsible for any time or brain cells % wasted with this software. (Has anybody ever actually gotten sued for % that?) % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % We've got to have the classes PieMenu and PulloutPieMenu are defined. systemdict /PieMenu known not { (NeWS/piemenu.ps) LoadFile not { currentcursorlocation [(Need) (piemenu.ps)] popmsg pop currentprocess killprocess } if } if systemdict /PulloutPieMenu known not { (NeWS/pullout.ps) LoadFile not { currentcursorlocation [(Need) (pullout.ps)] popmsg pop currentprocess killprocess } if } if systemdict begin /PSVisualizerWindow DefaultWindow dictbegin /hfrob .3 def /sfrob .5 def /bfrob .3 def /procs 1 def /maxprocs 10 def /maxdrawdepth 0 def /maxtargetdepth 0 def /thing null def /highmark 10 def /pp null def /FrameLabel (The NeWS Pseudo-Scientific Visualizer!) def /IconLabel (PS Visualizer) def /IconImage /eye def /Canvases null def /Items null def /BorderBottom 32 def /Top null def dictend classbegin /new { /new super send begin /Top 1 index def /thing exch def /maxdrawdepth countdictstack 3 add def /maxtargetdepth countdictstack 999 add def currentdict end } def /destroy { % clean up drain pp type /processtype eq { pp killprocessgroup /pp null def /thing null def } if Canvases null ne { Canvases {pop /Interests get dup length 0 eq {(zip ) [] dbgprintf} if % XXX {revokeinterest} forall} forall } if /destroy super send } def /drain { maxdrawdepth /maxdrawdepth 0 def 50 { pause procs 0 eq {exit} if } repeat /maxdrawdepth exch def } def /PaintClient { gsave ClientCanvas setcanvas { clear newprocessgroup drain pp null ne { pp killprocessgroup % why doesn't this kill all of 'em??? } if /pp currentprocess def Canvases dup type /dicttype eq { Canvases { pop dup /Interests get dup length 0 eq {(zip ) [] dbgprintf} if % XXX {revokeinterest} forall /Mapped false put } forall } if /Canvases 2048 dict def erasepage random random random sethsbcolor /highmark countdictstack def /procs 1 def clippath pathbbox scale pop pop .5 .5 translate .05 .05 scale {/thing load visualize} fork waitprocess pop 300 { procs 1 le {exit} if .1 sleep } repeat ClientCanvas setcanvas [ Canvases { pop [ PointButton AdjustButton MenuButton /EnterEvent /ExitEvent ] /target-event null 4 -1 roll eventmgrinterest } forall PointButton /point-background null ClientCanvas eventmgrinterest ] forkeventmgr /pp exch def } fork pop grestore } def /PaintFrame { /PaintFrame super send Items paintitems } def /activate { /Items 10 dict dup begin /message_item () () /Right nullproc FrameCanvas /new MessageItem send BorderLeft 4 330 0 /reshape 5 index send def end def Items forkitems pop map ClientCanvas /Retained true put } def /reshape { /reshape super send Items null ne { BorderLeft 4 /move Items /message_item get send } if } def /toggle-can { setcanvas 0 setgray 5 setrasteropcode clippath fill } def /point-background { gsave Canvases { pop toggle-can } forall grestore } def /target-event-names 10 dict def target-event-names begin PointButton { CurrentEvent /Action get /DownTransition eq { Canvases CurrentEvent /Canvas get get /obj get select-object } { } ifelse } def AdjustButton { CurrentEvent /Action get /DownTransition eq { Canvases CurrentEvent /Canvas get get /obj get /thing exch store PaintClient } { } ifelse } def MenuButton { CurrentEvent /Action get /UpTransition eq { } { } ifelse } def /EnterEvent { Canvases CurrentEvent /Canvas get dup toggle-can get /obj get (%) sprintf /printstring Items /message_item get send } def /ExitEvent { CurrentEvent /Canvas get toggle-can } def end /target-event { gsave target-event-names CurrentEvent /Name get get exec grestore } def /ignorekeys 20 dict def ignorekeys begin /TopCanvas dup def /BottomCanvas dup def /CanvasAbove dup def /Parent dup def /FrameMenu dup def /IconMenu dup def /ParentDict dup def /ParentDictArray dup def end /cvfixed { 16384 mul floor cvi -14 bitshift } def /wrap { dup floor sub cvfixed } def % This is useful for finding core leaks ... (Really!) /context-string { % => (string) () currentprocess /DictionaryStack get dup length 2 sub 2 exch getinterval { dup /obj known { begin i obj 3 -1 roll (%/%:%) sprintf end } {pop} ifelse } forall 1 index exch (% = %) sprintf } def /make-target { countdictstack maxtargetdepth lt { /can ClientCanvas newcanvas def 0 0 1 0 360 arc can reshapecanvas can /Transparent true put can /Mapped true put Canvases can currentdict put } if } def /visualize { % obj => - % count 5 gt {/foo dbgbreak} if pause countdictstack maxdrawdepth ge { countdictstack highmark gt { % Uncomment this to hunt for core leaks. % context-string (High water: %\n) [3 -1 roll] dbgprintf /highmark countdictstack store } if pop } { { gsave currenthsbcolor 3 -1 roll random hfrob mul add wrap 3 -1 roll random sfrob mul add wrap sqrt % Crank up the saturation! 3 -1 roll random bfrob mul add wrap sqrt % Crank up the brightness! sethsbcolor dup type { % /canvastype /dicttype { newpath 0 0 1 0 360 arc closepath 0 0 .9 0 360 arc closepath 0 0 .2 0 360 arc closepath eofill 10 dict begin make-target /obj exch cvlit def /pieces obj length def pieces 0 ne { /step 360 pieces div def obj { pause countdictstack maxdrawdepth ge {pop pop exit} if /thing exch cvlit def /i exch cvlit def gsave 2.5 0 translate .6 .6 scale i visualize 2.5 0 translate ignorekeys i known not { thing } { /triangle } ifelse visualize grestore step rotate } forall } if end } /arraytype { newpath 0 0 1 0 360 arc closepath 0 0 .9 0 360 arc closepath eofill 10 dict begin make-target /obj exch cvlit def /pieces obj length def pieces 0 ne { /step 360 pieces div def /i -1 def obj { pause countdictstack maxdrawdepth ge {pop exit} if /thing exch cvlit def /i i 1 add def gsave 2.5 0 translate .6 .6 scale thing visualize grestore step rotate } forall } if end } /stringtype { length 1 add newpath -.5 -.1 % x y 3 -1 roll 5 div .5 add .2 % x y w h rectpath fill } /realtype /integertype { dup 100 div wrap 1 index 10 div wrap 3 -1 roll wrap setrgbcolor -.4 -.4 .8 .8 rectpath fill } /eventtype { pop -.8 -.8 1.6 1.6 rectpath -.8 .8 moveto 0 0 lineto -.8 -.8 lineto stroke } /nulltype { pop gsave -90 rotate -1 -.3 translate 2 2 scale newpath % Nick Turner's finger .2 0 moveto 0 .3 lineto .1 .5 lineto .2 .5 lineto .2 .55 lineto .3 .6 lineto .4 .55 lineto .4 .95 lineto .5 1 lineto .6 .95 lineto .6 .55 lineto .7 .6 lineto .8 .55 lineto .8 .5 lineto .9 .55 lineto 1 .5 lineto 1 .3 lineto .8 0 lineto closepath fill grestore } /operatortype { pop -.2 -.2 .4 .4 rectpath 0 0 .5 0 360 arc eofill } /processtype { pop newpath -.5 -.5 moveto 1 -.4 lineto 1 -.2 lineto .8 -.2 lineto 1 .4 lineto 1 1 lineto .5 .3 lineto -.5 .5 lineto closepath eofill } % /canvastype { % -.5 -.5 translate % imagecanvas % } /Default { pop newpath % -.5 -.5 1 1 rectpath 0 -.5 moveto 1 0 lineto 0 .5 lineto closepath % stroke % -.4 -.4 .8 .8 rectpath eofill } } case grestore } % A verb, Senator Kennedy, we need a verb! random .6 lt procs maxprocs lt and { /procs procs 1 add store { exec /procs procs 1 sub store } fork pop pop pop } { exec } ifelse % mumble frotz ... } ifelse } def % Menu definitions /ColorFrobMenu [ [(0.0) (0.02) (0.05) (0.1) (0.2) (0.3) (0.4) (0.5) (0.6) (0.7) (0.8) (0.9) (1.0) (99)] ] [ (HueFrob) { ThisWindow /hfrob getmenuarg cvr put } (BrightnessFrob) { ThisWindow /bfrob getmenuarg cvr put } (SaturationFrob) { ThisWindow /sfrob getmenuarg cvr put } ] /new PulloutPieMenu send def /ThingMenu [ (SendContexts) { ThisWindow /thing currentprocess /SendContexts get put } (UI_private) { ThisWindow /thing UI_private put } (Top) { {/thing /Top load def } ThisWindow send } (rootmenu) { ThisWindow /thing rootmenu put } (DefaultMenu) { ThisWindow /thing DefaultMenu put } (userdict) { ThisWindow /thing userdict put } (bar) { ThisWindow /thing /bar load put } (Item) { ThisWindow /thing Item put } ] /new PieMenu send def /ClientMenu [ [] [(1) (2) (3) (4) (5) (6) (7) (8) (9) (10) (9999)] [(1) (2) (3) (4) (5) (6) (7) (8) (9) (10) (9999)] [] [(1) (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13) (14) (15) (16) (17) (18) (19) (20)] [] ] [ (Thing...) ThingMenu (DrawDepth) { getmenuarg cvi { countdictstack add /maxdrawdepth exch def } ThisWindow send } (TargetDepth) { getmenuarg cvi { countdictstack add /maxtargetdepth exch def } ThisWindow send } (ColorFrob...) ColorFrobMenu (MaxProcs) { ThisWindow /maxprocs getmenuarg cvi put } (paint) { /paint ThisWindow send } ] /new PulloutPieMenu send def % Hurray for you -- you're reading the source code! % You can run a psh, and change foo and bar in systemdict to whatever % you want to look at! (warning: systemdict gets "unregistered" errors!) % To find core leaks, visualize objects in your application's userdict, % and look for the infinite regression of circular references. systemdict /foo ClientMenu put systemdict /bar UserProfile put classend def /select-object { % obj => - 20 dict begin /ContentsPostScript 1 index def /ContentsAscii exch (%) sprintf def /SelectionObjSize 1 def /SelectionResponder null def /Canvas currentcanvas def % XXX? /SelectionHolder currentprocess def % XXX? currentdict end /PrimarySelection setselection } ?def /start_visualizer { % thing => { framebuffer setcanvas newprocessgroup framebuffer /new PSVisualizerWindow send /reshapefromuser 1 index send /activate exch send } fork pop pop } def end % systemdict % visualize command line args, if any. { clear { ($1 $2 $3 $4 $5 $6 $7 $8 $9) cvx exec } errored not { count 0 ne { start_visualizer } if } if } fork pop From don@brillig.umd.edu Sat Mar 11 05:18:26 1989 Date: Sat, 11 Mar 89 05:18:26 EST To: NeWS-makers@brillig.umd.edu Subject: NeWS CyberSpace Deck (without instruction) From: Don Hopkins Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) I will post instructions to this soon (I have to catch a flight!), but as an experiment, try it out and see what you can figure out on your own, and then when I send instructions, you can tell me what features were hopelessly obscure. ;-) Hints: FunctionF10 (Alternate) is "help". Double click the left button on things to open them. Shift, Control, and Meta do special stuff. Press L9 (Find) for completion! -Don %! %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % PostScript Structure CyberSpace % Copyright (C) 1989 % By Don Hopkins % All rights reserved. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % This program is provided for UNRESTRICTED use provided that this % copyright message is preserved on all copies and derivative works. % This is provided without any warranty. No author or distributor % accepts any responsibility whatsoever to any person or any entity % with respect to any loss or damage caused or alleged to be caused % directly or indirectly by this program. This includes, but is not % limited to, any interruption of service, loss of business, loss of % information, loss of anticipated profits, core dumps, abuses of the % virtual memory system, or any consequential or incidental damages % resulting from the use of this program. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % WARNING WARNING! DANGER! DANGER WILL ROBINSON! DANGER! % This is *gross* code. I mean UUUUUGLY! (And it used to be % even more contorted, if you can believe that.) % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% systemdict begin statusdict begin 0 setjobtimeout end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Load necessary stuff systemdict /NeWSScrollbar known not { (NEWSHOME) getenv (/clientsrc/client/nterm/NeWSSbar.ps) append LoadFile pop } if systemdict /TextCanvas known not { (NEWSHOME) getenv (/clientsrc/client/nterm/textcan.ps) append LoadFile pop } if %systemdict /PieMenu known not { % (NeWS/piemenu.ps) LoadFile pop %} if systemdict /PieMenu known systemdict /PulloutPieMenu known not and { (NeWS/pullout.ps) LoadFile pop } if %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % StructItem class definition /StructItem LabeledItem dictbegin %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Instance variables /Shrink .8 def /Pad 3 def /StartPoint 14 def /Point StartPoint def /x 0 def /y 0 def /Levels 0 def /DL null def /ItemFrame 2 def /ItemRadius 5 def /ItemBorder 6 def % /ItemButton [PointButton MenuButton] def /ItemButton [PointButton AdjustButton MenuButton] def /StackI null def /LayoutLock null def /LastX 0 def /LastY 0 def /LastTime 0 def /DX 0 def /DY 0 def /TabX 0 def /TabY 0 def /TabWidth 0 def /TabHeight 0 def /PinX 0 def /StartIndex 0 def /LastIndex 0 def /MySiblings null def /View /layout-struct def /Click /click-struct def /lw null def /lh null def /lx null def /ly null def dictend classbegin %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Class variables /DoubleClickTime 1 60 div def /CanvasYFudge 2 store /Sort? true def /LineGap 30 def /ItemLabelFont /Helvetica-Bold findfont 14 scalefont def /ItemFont /Courier findfont def /ItemXFont /Courier-Oblique findfont def /Icon? false def /SortBy /by-name def %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Initialization stuff /new { % Collection Index notifyproc parentcanvas => instance 4 2 roll 2 copy get type (% \267) sprintf % notify parent cont ind label 5 1 roll 2 array astore % label notify parent object 3 1 roll /Right % label object notify parent loc 3 1 roll % label object loc notify parent /new super send begin ItemCanvas /Transparent false put ItemCanvas /Retained true put /LayoutLock createmonitor def /xhair /xhair_m ItemCanvas setstandardcursor currentdict end } def /ensure-DL { DL null eq { Collection Index Levels grow-struct /DL exch store /ObjectWidth 0 store } if ObjectWidth 0 eq ObjectHeight 0 eq or { perform-layout } if } def %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Event handlers /ClientDown { CurrentEvent update-shifts CurrentEvent /Name get MenuButton eq { event-in-tab? { show-tab-menu } { show-struct-menu } ifelse } { CurrentEvent /Name get AdjustButton eq { CurrentEvent recallevent event-in-tab? { items FillColor self slideitem } { do-search ob null eq { items FillColor self slideitem } { make-selection } ifelse } ifelse } { CurrentEvent /Name get PointButton eq { event-in-tab? { toggle-icon } { do-search ob null eq { } { NotifyUser } ifelse } ifelse } if } ifelse } ifelse } def /make-selection { obs length 1 le { /MySiblings [ob] store /TipY null def /Multiple? false def }{ obs dup length 2 sub get /MySiblings 1 index /Branches get store /TipY exch dup /Y get exch /H get 2 div add def /Multiple? ob /C get type /arraytype eq Shift and def } ifelse /StartIndex 0 MySiblings { /I get ob /I get eq { exit } if 1 add } forall store /LastIndex StartIndex store ItemCanvas createoverlay setcanvas ObjectX ObjectY ObjectHeight add translate currentcursorlocation { newpath pop pop /LastIndex 0 MySiblings { /Y get y le { exit } if 1 add } forall MySiblings length 1 sub min store Multiple? not { /StartIndex LastIndex store } if TipY null ne { ob /X get LineGap sub TipY moveto MySiblings StartIndex LastIndex min get begin X Pad sub Y H add lineto end MySiblings StartIndex LastIndex max get begin X Pad sub Y lineto end closepath fill } if MySiblings StartIndex LastIndex min get begin X 1 sub Y H add moveto end StartIndex LastIndex min 1 StartIndex LastIndex max { MySiblings exch get begin X W add LineGap sub 1 add dup Y H add lineto Y lineto end } for MySiblings StartIndex LastIndex max get begin X 1 sub Y lineto end closepath Shift { stroke } { fill } ifelse } getanimated waitprocess ob /C get Multiple? { StartIndex LastIndex 2 copy gt {exch} if 1 index sub 1 add kbd-select-interval } { MySiblings LastIndex get /I get Shift { kbd-select-object pop } { kbd-select-pointer } ifelse } ifelse /MySiblings null store } store /show-tab-menu { userdict /it self put CurrentEvent /showat TabMenu send } def /show-struct-menu { ItemBegin do-search ob null ne { CurrentEvent /showat StructMenu send } if ItemEnd } store /ClientUp { StopItem } def /click-exec { ItemBegin ItemCanvas setcanvas CurrentEvent begin LastX XLocation sub dup mul LastY YLocation sub dup mul add end do-search ob null ne { ob /Obj get exec-it } if ItemEnd } def /click-point { /Click load cvx exec } def /open-icon { Icon? { /ObjectWidth OW store /ObjectHeight OH store currentdict /Icon? undef redo-shape } if } def /close-icon { Icon? not { gsave /OW ObjectWidth def /OH ObjectHeight def Font setfont Str stringbbox points2rect /IconH exch def /IconW exch def /ObjectWidth IconW store /ObjectHeight IconH store grestore /Icon? true def redo-shape } if } def /toggle-icon { DL begin Icon? { open-icon } { close-icon } ifelse end /LastTime 0 store } def /click-struct { ItemCanvas setcanvas CurrentEvent begin LastX XLocation sub dup mul LastY YLocation sub dup mul add end 4 lt currenttime LastTime sub DoubleClickTime lt and not { % first click ob null ne { Shift { % Shift to select the index ob /I get } { ob /Obj get } ifelse /LastTime currenttime store Control { exec-it /LastTime 0 store } { kbd-select-object } ifelse } if ItemCanvas setcanvas CurrentEvent begin /LastX XLocation store /LastY YLocation store end } { % double clicks ob null ne { DL begin Icon? end { toggle-icon } { Shift { ob /L get 1 add open-struct } { ob /L get 0 eq { 1 open-struct } { close-struct } ifelse } ifelse } ifelse } if /LastTime 0 store } ifelse } store /event-in-tab? { ItemBegin newpath label-bbox rectpath CurrentEvent begin XLocation YLocation end pointinpath ItemEnd } def /ClientExit { StopItem } def %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Menu definitions /PointMenu [ (2) (4) (6) (8) (10) (12) (14) (16) (18) (20) (22) (24) (28) (32) ] [ {currentkey cvi {/StartPoint exch def redo-layout} it send} ] /new DefaultMenu send def /LocationMenu [ (LeftBelow) (LeftAbove) (AboveLeft) (AboveRight) (RightAbove) (RightBelow) (BelowRight) (BelowLeft) ] [ { currentkey cvn {/ObjectLoc exch def location 10 10 reshape damage-view} it send} ] /new DefaultMenu send store LocationMenu /PieInitialAngle 360 16 div put /ShrinkMenu [ (.1) (.2) (.3) (.4) (.5) (.6) (.7) (.8) (.9) (1) ] [ {currentkey cvr {/Shrink exch def redo-layout} it send} ] /new DefaultMenu send def /ClickMenu [ (click-struct) (click-exec) ] [ {currentkey cvn {/Click exch def} it send} ] /new DefaultMenu send def /TabMenu [ (Point...) PointMenu (Paint) {/paint it send} (Click..) ClickMenu (Zap) {/Free it send} (Shrink...) ShrinkMenu (Layout) {/redo-layout it send} (Location...) LocationMenu (Print) {/write-DL it send} ] /new DefaultMenu send store /ChangeMenu [ (toke in) { /token-obj it send } (executable){ /cvx-obj it send } (name) { /cvn-obj it send } (string) { /cvs-obj it send } (toke out) { /tokout-obj it send } (literal) { /cvlit-obj it send } (integer) { /cvi-obj it send } (real) { /cvr-obj it send } ] /new DefaultMenu send def /UtilMenu [ (undef) { /undef-obj it send } (molecule) { /molecule-obj it send } (select) { ob /Obj get kbd-select-object } (--) {} (nulldef) { /nulldef-obj it send } (--) {} (reference) { /reference-obj it send } (--) {} ] /new DefaultMenu send def UtilMenu /PieInitialAngle 45 put /StructMenu [ % Note: depends on fixed getmenuarg (push) {/push-obj it send} (type...) /FigureTypeAction cvx (load) {/load-obj it send} (util...) UtilMenu (exec) {/exec-obj it send} (change...) ChangeMenu (paste) {/paste-obj it send} (open) {getmenuarg cvi /open-obj it send} ] /PulloutPieMenu where { pop [ nullarray [ [ { gsave /Screen findfont 12 scalefont setfont ob /Obj get type 30 string cvs 0 1 index length 4 sub getinterval % drop "type" exch /paint eq { 0 currentfont fontdescent rmoveto show } { stringbbox points2rect 4 2 roll pop pop } ifelse grestore } ] ] nullarray nullarray nullarray nullarray nullarray [(0) (1) (2) (3) (4) (5) (6) (7)] ] exch /new PulloutPieMenu send def } { /new DefaultMenu send def StructMenu /getmenuarg {ob /L get 0 eq 1 0 ifelse} put } ifelse { /LabelMinRadius 25 def /FigureTypeAction { ob /Obj get type { /arraytype { /ArrayMenu it send } /stringtype { /StringMenu it send } /dicttype { /DictMenu it send } /processtype { /ProcessMenu it send } /canvastype { /CanvasMenu it send } /eventtype { /EventMenu it send } /Default { { gsave framebuffer setcanvas currentcursorlocation [ (Nothing)(Happens)(Here!) ] popmsg pop grestore } } } case } def } StructMenu send /ArrayMenu [ (prepend) { /prepend-to-array-obj it send } % selected array (push) { /push-array-obj it send } % selected object (append) { /append-to-array-obj it send } % selected array (pop) { /pop-array-obj it send } % to selection ] /new DefaultMenu send def /StringMenu [ (prepend) {} % selected string (forall) {} % selected function (append) {} % selected string ] /new DefaultMenu send def /DictMenu [ (def) { /def-in-dict-obj it send } % selected function (merge) {} % selected dict ] /new DefaultMenu send def /ProcessMenu [ (kill) {} (kill group) {} (suspend) {} (resume) {} (wait) {} % select return value (userdict) {} % select userdict ] /new DefaultMenu send def /CanvasMenu [ (manager) {} % select /Interests 0 /Process (bbox) {} % select [x y w h] (setcanvas) {} % changes proc's gstate (zap) {} % unretain & unmap whole tree ] /new DefaultMenu send def /EventMenu [ (express) {} % Does this make any sense in this context? (revoke) {} (sendevent) {} ] /new DefaultMenu send def % integer real file path color ... %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Menu callbacks /push-array-obj { ob /Obj get dup [ selected-object ] append exch xcheck { cvx } if replace-obj } def /pop-array-obj { ob /Obj get dup length 0 eq { pop } { dup dup length 1 sub get kbd-select-object 0 1 index length 1 sub getinterval replace-obj } ifelse } def /prepend-to-array-obj { selected-object dup type /arraytype ne { pop } { % [sel] ob /Obj get % [sel] {obj} exch 1 index % {obj} [sel] {obj} append % {obj} [sel obj] exch xcheck { cvx } if % {sel obj} replace-obj } ifelse } def /append-to-array-obj { selected-object dup type /arraytype ne { pop } { % [sel] ob /Obj get % [sel] {obj} dup 3 -1 roll % {obj} {obj} [sel] append % {obj} [obj sel] exch xcheck { cvx } if % {obj sel} replace-obj % } ifelse } def /def-in-dict-obj { selected-pointer? { % collection index ob /Obj get % collection index dict 2 copy exch known 1 index type /dicttype eq or not { pop pop } { 1 index % collection index dict index 4 -2 roll get % dict index obj 3 copy put pop % dict index ob /Branches get null eq { pop pop } { 0 grow-struct % DL ob begin /Branches [ % DL mark Branches { % DL mark branch dup /I get counttomark 2 add index /I get eq {pop} if } forall counttomark 3 add -1 roll % mark branches... DL ] Sort? {SortBy quicksort} if def % end } ifelse redo-layout } ifelse } if } store % Execute token with Externals on the dict stack, so externalized % //&type_123 object references are resolved. /token-obj { { clear Externals begin ob /Obj get remove-returns { { token { exch } { exit } ifelse } loop } errored { clear ob /Obj get } { count array astore cvx } ifelse end } fork waitprocess replace-obj } def /cvx-obj { { ob /Obj get cvx } errored {pop} { replace-obj } ifelse } def /cvn-obj { { ob /Obj get cvn } errored {pop} { replace-obj } ifelse } def /cvs-obj { { ob /Obj get 256 string cvs } errored {pop} { replace-obj } ifelse } def /tokout-obj { ob /Obj get tokout replace-obj } def /cvlit-obj { { ob /Obj get cvlit } errored {pop} { replace-obj } ifelse } def /cvi-obj { { ob /Obj get cvi } errored {pop} { replace-obj } ifelse } def /cvr-obj { { ob /Obj get cvr } errored {pop} { replace-obj } ifelse } def /load&push-obj { ob /Obj get load&push-it } def /load&push-it { % [ exch cvlit {dup load} /errored cvx { pop (%% ) (%Load: % is not defined!\n) printf } { exch 1 index exch (%% ) (%Load: % Push: %\n) printf } /ifelse cvx ] cvx execute-it } def /load-obj { ob /Obj get load-it } def /load-it { % [ exch cvlit {dup load} /errored cvx { pop (%% ) (%Load: % is not defined!\n) printf } { exch 1 index exch (%% ) (%Load: % Select: %\n) printf select-object } /ifelse cvx ] cvx execute-it } def /open-obj { % levels => - dup 0 eq { pop close-struct } { open-struct } ifelse } def /push-obj { ob /Obj get push-it } def /push-it { [ exch [ exch ] 0 /get cvx /dup cvx (%% ) (%Push: %\n) /printf cvx ] cvx execute-it } def /nulldef-obj { ob /Obj get % dict dup type /dicttype ne { pop } { selected-object dup null eq { pop } { % dict key 2 copy null put ob /Branches get null eq { pop pop } { ob /L get grow-struct % DL ob begin /Branches [ % DL /B mark Branches { dup /I get counttomark 2 add index /I get eq {pop} if } forall % DL /B mark branches... counttomark 3 add -1 roll % /B mark branches... DL ] Sort? {SortBy quicksort} if def % end } ifelse redo-layout } ifelse } ifelse } store /undef-obj { ob /Obj get dup type /dicttype ne { pop } { selected-object dup null eq { pop } { 2 copy known { 2 copy undef ob begin Branches null ne { /Branches [ Branches { begin /C load /I load known { currentdict } if end } forall ] def } if end redo-layout } if } ifelse } ifelse } store /molecule-obj { systemdict /start_visualizer known not { (NeWS/molecule.ps) LoadFile pop } if ob /Obj get start_visualizer } def % construct a reference to a piece of substructure relative to the % top level object /reference-obj { obs length 2 lt { {} } { [ objs dup 1 exch length 1 sub getinterval { /I get cvlit /get cvx } forall ] cvx kbd-select-object } ifelse } def /exec-obj { ob /Obj get exec-it } def /exec-it { % obj => - { [ exch cvlit /cvx cvx /dup cvx (%% ) (%Exec: %\n) /printf cvx cvx /exec cvx ] cvx execute-it } fork pop pause } def /paste-obj { selected-object replace-obj } def /replace-obj { % obj => - ob begin replace-struct end Meta not { redo-layout } if ob DL eq StackI null ne and { % Tell processes if we changed its stack. /ReplaceStack items StackI get send } if } def %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Moving and shaping /just-reshape { ItemCanvas null ne { ItemCanvas /Mapped false put } if /ItemHeight exch def /ItemWidth exch def ItemWidth 0 eq ItemHeight 0 eq and { /DL null store } if ensure-DL adjust-geometry ItemWidth ItemHeight /reshape super send gsave ItemCanvas setcanvas ItemFillColor fillcanvas grestore ItemCanvas /Mapped true put } def /reshape { % x y w h just-reshape location move } def /just-move { /move super send } def /move { % x y label-bbox /lh exch store /lw exch store % x y lx ly 2 index add /ly exch store % x y lx 2 index add /lx exch store % x y ly 0 max /ClientHeight win send lh sub min ly sub add exch lx 0 max /ClientWidth win send lw sub min lx sub add exch /move super send snaps-here? pop Index ThisI eq {/paint-hilite win send} if StackI null ne StackI Index ne and { /MoveMe TellStack } if } store /redo-layout { perform-layout redo-shape } def /redo-shape { %location 10 10 just-reshape location 10 10 reshape damage-view } def /label-bbox { % x y w h TabX TabY TabWidth TabHeight } def /tab-top { % - => y location TabY add TabHeight add exch pop } def /tab-bottom { % - => y location TabY add exch pop } store /label-rect { % X Y w h location TabY add exch TabX add exch TabWidth TabHeight } def /object-bbox { % x y w h ObjectX ItemBorder sub ObjectY ItemBorder sub % x y ObjectWidth ItemBorder dup add add % w ObjectHeight ItemBorder dup add add % h } def /ItemPath { ItemRadius label-bbox rrectpath ItemRadius object-bbox rrectpath } def /AdjustItemSize { % - => - [uses item context] ObjectLoc [ /Right /Left /RightBelow /RightAbove /LeftBelow /LeftAbove { /ItemWidth ItemBorder 3 mul ItemGap add LabelWidth add ObjectWidth add def /ItemHeight ItemBorder 2 mul LabelHeight ObjectHeight max add def } /Top /Bottom /AboveLeft /AboveRight /BelowLeft /BelowRight { /ItemWidth ItemBorder 2 mul LabelWidth ObjectWidth max add def /ItemHeight ItemBorder 3 mul ItemGap add LabelHeight add ObjectHeight add def } ] case } store /CalcObj&LabelXY { % - => - [uses item context] ObjectLoc { /RightAbove { /LabelX ItemBorder def /LabelY ItemBorder store /ObjectX ItemBorder dup add LabelWidth add ItemGap add store /ObjectY ItemHeight ObjectHeight sub 2 div store /TabX LabelX ItemBorder sub def /TabY LabelY ItemBorder sub store /TabWidth ItemBorder LabelWidth add ItemGap add ItemRadius dup add add store /TabHeight LabelHeight ItemBorder dup add add def } /RightBelow /Right { /LabelX ItemBorder store /LabelY ItemHeight ItemBorder sub LabelHeight sub store /ObjectX ItemBorder dup add LabelWidth add ItemGap add store /ObjectY ItemHeight ObjectHeight sub 2 div store /TabX LabelX ItemBorder sub def /TabY LabelY ItemBorder sub store /TabWidth ItemBorder LabelWidth add ItemGap add ItemRadius dup add add store /TabHeight LabelHeight ItemBorder dup add add def } /LeftAbove { /LabelX ItemBorder dup add ItemGap add ObjectWidth add store /LabelY ItemBorder store /ObjectX ItemBorder store /ObjectY ItemHeight ObjectHeight sub 2 div store /TabX LabelX ItemGap sub ItemRadius dup add sub store /TabY LabelY ItemBorder sub store /TabWidth ItemRadius dup add ItemGap add LabelWidth add ItemBorder add store /TabHeight LabelHeight ItemBorder dup add add def } /LeftBelow /Left { /LabelX ItemBorder dup add ItemGap add ObjectWidth add store /LabelY ItemHeight ItemBorder sub LabelHeight sub store /ObjectX ItemBorder store /ObjectY ItemHeight ObjectHeight sub 2 div store /TabX LabelX ItemGap sub ItemRadius dup add sub store /TabY LabelY ItemBorder sub store /TabWidth ItemRadius dup add ItemGap add LabelWidth add ItemBorder add store /TabHeight LabelHeight ItemBorder dup add add def } /AboveRight /Top { /LabelX ItemBorder def /LabelY ItemBorder store /ObjectX ItemWidth ObjectWidth sub 2 div store /ObjectY ItemBorder dup add LabelHeight add ItemGap add store /TabX LabelX ItemBorder sub def /TabY LabelY ItemBorder sub store /TabWidth LabelWidth ItemBorder dup add add store /TabHeight ItemBorder LabelHeight add ItemGap add ItemRadius dup add add def } /AboveLeft { /LabelX ItemWidth ItemBorder sub LabelWidth sub store /LabelY ItemBorder store /ObjectX ItemWidth ObjectWidth sub 2 div store /ObjectY ItemBorder dup add LabelHeight add ItemGap add store /TabX LabelX ItemBorder sub def /TabY LabelY ItemBorder sub store /TabWidth LabelWidth ItemBorder dup add add store /TabHeight ItemBorder LabelHeight add ItemGap add ItemRadius dup add add def } /BelowRight /Bottom { /LabelX ItemBorder store /LabelY ItemBorder dup add ObjectHeight add ItemGap add store /ObjectX ItemWidth ObjectWidth sub 2 div store /ObjectY ItemBorder store /TabX LabelX ItemBorder sub store /TabY LabelY ItemGap sub ItemRadius dup add sub store /TabWidth LabelWidth ItemBorder dup add add store /TabHeight ItemRadius dup add ItemGap add LabelHeight add ItemBorder add def } /BelowLeft { /LabelX ItemWidth ItemBorder sub LabelWidth sub store /LabelY ItemBorder dup add ObjectHeight add ItemGap add store /ObjectX ItemWidth ObjectWidth sub 2 div store /ObjectY ItemBorder store /TabX LabelX ItemBorder sub store /TabY LabelY ItemGap sub ItemRadius dup add sub store /TabWidth LabelWidth ItemBorder dup add add store /TabHeight ItemRadius dup add ItemGap add LabelHeight add ItemBorder add def } } case /PinX LabelX LabelWidth add 2 sub store } def /adjust-geometry { /ItemLabel Collection Index get type (% \267) sprintf store LabelSize /LabelHeight exch def /LabelWidth exch def AdjustItemSize CalcObj&LabelXY } def %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Display /PaintItem { LayoutLock { ItemRadius label-bbox rrectpath ItemFillColor setcolor fill ItemFrame 0 gt { ItemFrame ItemRadius label-bbox rrectframe ItemBorderColor setcolor eofill } if ItemRadius object-bbox rrectpath ItemFillColor setcolor fill ItemFrame 0 gt { ItemFrame ItemRadius object-bbox rrectframe ItemBorderColor setcolor eofill } if ShowLabel paint-struct } monitor } store /paint-struct { gsave ensure-DL ItemTextColor setcolor ObjectX ObjectY ObjectHeight add translate DL draw-struct grestore } def /damage-view { gsave %ItemParent setcanvas bbox rectpath extenddamage paint grestore } def %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Accessers /Collection { ItemObject 0 get cvlit } def /Index { ItemObject 1 get cvlit } def %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Structure stuff /old-search-struct { % proc x y dict => proc x y begin dup Y ge { dup Y H add lt { % Path setpath newpath X Y W H rectpath %(x % y % X % Y % W % H % \n)[3 index 3 index X Y W H ]dbgprintf 2 copy pointinpath { 2 index exec } { Branches null ne { Branches { search-struct } forall } if } ifelse } if } if end } def /do-search { /it self store DL begin Icon? end { /obs [ DL ] store /ob DL store } { gsave ItemCanvas setcanvas ObjectX ObjectY ObjectHeight add translate DL CurrentEvent begin XLocation YLocation end search-struct /obs exch store obs length 0 eq { null } { obs dup length 1 sub get } ifelse /ob exch store grestore } ifelse } def % Return the path down the display list to the substructure enclosing (x,y). /search-struct { % dict x y => [ dl1 dl2 ... dln ] 10 dict begin /ssy exch def /ssx exch def [ exch { do-search-struct % unsucessful search exit } loop % catch possible exit ] end } def /do-search-struct { % dl => dl dl' dl'' dl''' ... begin ssx X ge { ssy Y ge { ssx X W add le { ssy Y H add le { currentdict Branches end dup null eq { pop } { { do-search-struct } forall } ifelse exit % skip past all the ends on the execution stack } if } if } if } if end } store /close-struct { gsave DL /Icon? undef ItemCanvas setcanvas ObjectX ObjectY ObjectHeight add translate ob /L 0 put ob /Branches null put Meta not { redo-layout } if grestore } def /open-struct { % levels => - gsave DL /Icon? undef ItemCanvas setcanvas ObjectX ObjectY ObjectHeight add translate ob begin grow-substruct end Meta not { redo-layout } if grestore } def % (dl on dictstack) /replace-struct { % obj => - C I 3 -1 roll put C I L grow-struct begin /Branches Branches /C dup load /I dup load % /L L /Obj dup load /Str Str /X X /Y Y /W W /H H /Font Font end def def def def def def def def def def def } def /grow-substruct { % l => - /L exch def % /forbidden? {pop false} def /Branches C I L grow-struct 1 index get def % currentdict /forbidden? undef } def /composite? { % obj => bool type { /arraytype /dicttype /canvastype /processtype /eventtype /fonttype {true} /Default {false} } case } def /forbidden-dict 50 dict def forbidden-dict begin /Interests null def /Process null def /BuildChar null def /Encoding null def /WidthArray null def /ParentDictArray null def /ParentDict null def /TopCanvas null def /BottomCanvas null def /TopChild null def /CanvasAbove null def /CanvasBelow null def /Parent null def end % forbidden-dict /forbidden? { forbidden-dict exch known currentdict ob ne and % forbidden things must be be explicitly opened. } def % Collection Index Levels => dict /grow-struct { /xcurs /xcurs_m ItemCanvas setstandardcursor LayoutLock { /hourg /hourg_m ItemCanvas setstandardcursor do-grow-struct } monitor /xhair /xhair_m ItemCanvas setstandardcursor } def /do-grow-struct { pause 32 dict begin /L exch def cvlit /I exch def cvlit /C exch def /Obj C I get def /Str /Obj load I (% = %) sprintf def /X 0 def /Y 0 def /W 0 def /H 0 def /StrY 0 def /LineX 0 def /Obj load composite? I forbidden? not and L 0 gt and { /Obj load dup type /arraytype eq { /Branches exch [ exch { pop /Obj load counttomark 1 sub L 1 sub do-grow-struct } forall ] def } { /Branches exch [ exch { pop /Obj load exch L 1 sub do-grow-struct } forall ] Sort? {SortBy quicksort} if def } ifelse } { /Branches null def } ifelse currentdict end } def % /SortBy default: /by-name { /Str get exch /Str get lt } def %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Layout /perform-layout { /xcurs /xcurs_m ItemCanvas setstandardcursor LayoutLock { /hourg /hourg_m ItemCanvas setstandardcursor /ItemLabel Collection Index get type (% \267) sprintf store init-format DL do-layout /ObjectHeight DL /H get store adjust-geometry } monitor /xhair /xhair_m ItemCanvas setstandardcursor } def /init-format { /Point StartPoint def /x 0 def /y 0 def /ObjectWidth 0 def /ObjectHeight 0 def } def /LineHeight { Font fontheight 1 add } def /do-layout { % dict => - begin /View load cvx exec end pause } def /layout-struct { % - => - /Str /Obj load I (% = %) sprintf def /Obj load xcheck Point 10 ge and { /Font ItemXFont Point scalefont def } { /Font ItemFont Point scalefont def } ifelse Font setfont /X x def /Y y def /W Str stringwidth pop LineGap add def Branches null eq { % Icon? or /H LineHeight def } { /x x W add store /Point Point Shrink mul store Branches { do-layout } forall /Point Point Shrink div store /x x W sub store 0 0 % w h Branches { begin exch W max exch H add end } forall % W H LineHeight max 1 max /H exch def /LineX X W add LineGap sub def W add /W exch def } ifelse /Y Y H sub def /StrY Y Font fontdescent add H LineHeight sub 2 div add def /y Y store /ObjectWidth ObjectWidth x W add LineGap sub max store } store % dict => - /draw-struct { pause begin Icon? { gsave Font setfont 0 Font fontdescent IconH sub 2 copy moveto Str show translate -2 ItemRadius Str stringbbox points2rect insetrrect rrectpath 0 setlinewidth 0 setgray stroke grestore } { show-obj Branches null ne Icon? not and { LineX Y H 2 div add Branches length 0 ne { Branches 0 get begin 2 copy moveto X Pad sub Y H add lineto Pad 5 mul 0 rlineto stroke end Branches { begin 2 copy moveto X Pad sub Y lineto Pad 2 mul 0 rlineto stroke currentdict end draw-struct } forall Branches dup length 1 sub get begin 2 copy moveto X Pad sub Y lineto Pad 5 mul 0 rlineto stroke end } if pop pop } if } ifelse end } store /show-obj { Font setfont X StrY moveto Str show } def %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Printing % This needs to be brought up to date... /write-DL { % { /f (DL.ps) (w) file def f (%!\n) writestring f (gsave 0 setgray 0 setlinewidth 20 20 translate\n) writestring DL begin f H W (%%) (%BoundingBox: 0 0 % %\n) sprintf writestring end /cur-font-name null def /cur-font-size 0 def DL print-struct f (grestore showpage\n) writestring f closefile } stopped pop } def /print-struct { % dict => - pause begin Font /FontMatrix get 0 get /Obj load xcheck ItemXFont ItemFont ifelse /FontName get 1 index cur-font-size eq 1 index cur-font-name eq and { pop pop } { 2 copy /cur-font-name exch store /cur-font-size exch store (/% findfont % scalefont setfont\n) sprintf f exch writestring } ifelse Font setfont Font fontdescent StrY ObjectHeight add X (% % moveto ) sprintf f exch writestring Str ( (%) show\n) sprintf f exch writestring Branches null ne Icon? not and { X W add LineGap sub Y H 2 div add ObjectHeight add Branches { begin 2 copy exch (% % moveto ) sprintf f exch writestring X Pad sub Y ObjectHeight add exch (% % lineto ) sprintf f exch writestring Pad 2 mul 0 exch (% % rlineto ) sprintf f exch writestring f (stroke\n) writestring currentdict end print-struct } forall Branches length 0 ne { Branches dup length 1 sub get begin 2 copy exch (% % moveto ) sprintf f exch writestring X Pad sub Y H add ObjectHeight add exch (% % lineto ) sprintf f exch writestring Pad 2 mul 0 exch (% % rlineto ) sprintf f exch writestring f ( stroke\n) writestring end } if pop pop } if end } def %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Stack stuff /execute-it { % obj => - /exec-and-update dialog-item send } def /TellStack { % message => - createevent begin /Name exch def /ClientData Index def /Action StackI def /Canvas ItemParent def currentdict end sendevent } def /pack { StackI null ne { /PackStack items StackI get send } if } def %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Snap dragging /pinned? { % y h => bool location pop PinX add 3 1 roll % x y h 6 exch % x y w h pin-rect rectsoverlap } store % items backgroundcolor => - (interactively move item) /moveinteractive { ItemBegin 10 dict begin /GA_constraint 0 def /GA_value /calc_GA_value load def currentcursorlocation /DY exch def /DX exch def currentcanvas mapcanvas false dragcanvas end ItemEnd } store /SnapIn { ThisI StackI ne { StackI null ne { /PopMe TellStack } if /StackI ThisI store /PushMe TellStack } if } def /SnapOut { StackI null ne StackI Index ne and { /PopMe TellStack /StackI null store } if } def /snaps-here? { % - => bool ThisI null eq ThisI Index eq or {false} { /pin-rect items ThisI get send label-rect rectsoverlap dup { SnapIn } { SnapOut } ifelse } ifelse } def /calc_GA_value { StackI Index eq { currentcursorlocation pop % cx } { StackI null eq { snaps-here? { location pop DX add % ix } { currentcursorlocation pop % cx } ifelse } { location TabY add TabHeight /pinned? items StackI get send not { SnapOut pop currentcursorlocation pop % cx } { % ix { location pop PinX add } items StackI get send % ItemX PinX PinX sub % ItemX ItemGoal exch 1 index exch sub % ItemGoal ItemDelta currentcursorlocation pop % ItemGoal ItemDelta CurX' 2 index exch sub % ItemGoal ItemDelta CurDelta DX add dup abs TabWidth gt { SnapOut pop pop pop currentcursorlocation pop DX sub } { 1 index abs 1 index abs gt {exch} if % ItemGoal Close Far pop % ItemGoal Close % .2 mul sub sub } ifelse DX add } ifelse } ifelse } ifelse } store /NextPos { % - => x y location % x y label-bbox % X Y x y w h exch pop add % X Y x y+h 3 -1 roll add % X x Y+y+h exch 3 -1 roll add exch % X+x Y+y+h exch PinX add exch } def %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Storage managment /Free { SnapOut ItemCanvas /Retained false put unmap ItemLock { /free-items [ free-items aload pop Index ] store } monitor } def /init-attributes { {/ObjectWidth /DL /Shrink /StartPoint /View /Click} { InstanceVarDict 1 index get store } forall /ObjectLoc /Right store adjust-geometry } store % obj => - /Reuse { Collection Index 3 -1 roll put ItemCanvas /Retained true put ItemCanvas canvastotop init-attributes %ensure-DL %redo-layout } store /destroy { ItemEventMgr null ne { ItemEventMgr killprocess } if ItemCanvas /Retained false put unmap } def classend def %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % TextStructItem class definition /TextStructItem StructItem dictbegin %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Instance variables /I null def /MyStack null def /MyProcess null def /Scroller null def /ScrollerWidth 16 def /Notifier null def /NotifierHeight 16 def /SubItemGap 2 def /SubItemMgr null def /DeferedUpdateEvent null def /UpdateDelay .5 60 div def /PinHeight 0 def /DropShadow 6 def dictend classbegin %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Class Variables /TextWidth 700 def /TextHeight 200 def %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % /new { /new super send begin /MyStack [] def /ItemLabel (processtype) def currentdict end } def /kbd-reset { /dialog-buf () store /dialog-string () store { psh-socket bytesavailable string readstring pop } errored {(\n%% Reset!\n) print} execute-it } def /shut-down { { psh-socket (\ndbgstop\nquit\n) writestring psh-socket flushfile } errored pop null null /DropDead TellMyProcess 1 60 div sleep } def /kbd-reboot { { /dialog-buf () store /dialog-string () store [ () (%% Reboot!) () ] true /writeatcaret dialog-text send shut-down psh-socket closefile /psh-socket null store ensure-DL % { EventMgr null ne { EventMgr killprocess } if % /EventMgr Interests forkeventmgr store % KeyboardEventMgr null ne { KeyboardEventMgr killprocess } if % /KeyboardEventMgr { KeyboardHandler } fork store % } dialog-text send start-event-mgrs } fork waitprocess pop } def /use-selected-process { selected-object dup type /processtype eq { set-process } if } def /adjust-geometry { LabelSize /LabelHeight exch def /LabelWidth exch def AdjustItemSize CalcObj&LabelXY } def /DialogMenu [ (process) {/use-selected-process it send} (reset) {/kbd-reset it send} (pack) {/PackStack it send} (reboot) {/kbd-reboot it send} ] /new DefaultMenu send def /SelectionMenu [ (push) {{Collection Index get push-it} it send} (load) {{Collection Index get load-it} it send} (exec) {{Collection Index get exec-it} it send} (change...) /ChangeMenu StructItem send ] /new DefaultMenu send def /replace-obj { % obj => - Collection Index 2 index put kbd-select-object } def /show-tab-menu { /it self store CurrentEvent /showat DialogMenu send } def /show-struct-menu { /it self store /ob 20 dict store ob begin /C Collection def /I Index def /Obj Collection Index get def end CurrentEvent /showat SelectionMenu send } def /make-selection { % We ARE the selection. } def /pin-rect { % X Y w h location exch PinX add 3 sub exch % x y PinHeight 0 lt { PinHeight add } if ItemHeight PinHeight abs add 6 exch } def /exec-and-update { % func => - null /ExecIt TellMyProcess } def /TellMyProcess { % ClientData Action Name 8 { % wait up to 4 seconds if no process MyProcess null eq { .5 60 div sleep } { exit } ifelse } repeat MyProcess null eq { pop pop pop gsave framebuffer setcanvas currentcursorlocation [(No process!)] popmsg pop grestore } { createevent begin /Name exch def /Action exch def /ClientData exch def /Process MyProcess def currentdict end sendevent } ifelse } def /UpdateStack { % DeferedUpdateEvent null ne { DeferedUpdateEvent recallevent } if /DeferedUpdateEvent CurrentEvent store DeferedUpdateEvent begin /Name /DeferedUpdate def /TimeStamp currenttime UpdateDelay add def end % event DeferedUpdateEvent sendevent } def /DeferedUpdate { % /DeferedUpdateEvent null store [ /getcaretpos dialog-text send pop 1 gt { () } if dialog-string dialog-buf CurrentEvent /ClientData get length (NeWS[%]> %%) sprintf { (\n) search { % chop string up at newlines exch pop exch } { exit } ifelse } loop ] true /writeatcaret dialog-text send pause CurrentEvent /ClientData get SetStack } def /ProcessReady { CurrentEvent dup /ClientData get exch /Action get set-process } def /set-process { % stack process => - /MyProcess exch def SetStack { currentprocess (%% ) (%Hello, my name is %!\n) printf } execute-it } def /SelectionChanged { CurrentEvent /Action get /PrimarySelection eq { CurrentEvent /ClientData get dissect-selection Collection Index 2 index put (%: %) [ 3 -1 roll dup type exch ] /printf Notifier send } if } def /makestartinterests { /makestartinterests super send [ exch aload pop /ProcessReady {/ProcessReady /Self GetFromCurrentEvent send} null ItemCanvas eventmgrinterest dup /Self self PutInEventMgrInterest /UpdateStack {/UpdateStack /Self GetFromCurrentEvent send} null ItemCanvas eventmgrinterest dup /Self self PutInEventMgrInterest /DeferedUpdate {/DeferedUpdate /Self GetFromCurrentEvent send} null ItemCanvas eventmgrinterest dup /Self self PutInEventMgrInterest /SelectionChanged {/SelectionChanged /Self GetFromCurrentEvent send} null null eventmgrinterest dup /Self self PutInEventMgrInterest /PushMe {/DoPushMe /Self GetFromCurrentEvent send} Index ItemParent eventmgrinterest dup /Self self PutInEventMgrInterest /PopMe {/DoPopMe /Self GetFromCurrentEvent send} Index ItemParent eventmgrinterest dup /Self self PutInEventMgrInterest /MoveMe {/DoMoveMe /Self GetFromCurrentEvent send} Index ItemParent eventmgrinterest dup /Self self PutInEventMgrInterest ] } def /DoPushMe { CurrentEvent /ClientData get PushMe } def /DoPopMe { CurrentEvent /ClientData get PopMe } def /DoMoveMe { ItemLock { SortStack ReplaceStack } monitor } def /PushMe { % index => - ItemLock { /I exch def /MyStack [ MyStack { dup I eq {pop} if } forall I ] store SortStack GetStack {Collection Index get} items I get send 80 string cvs (%% Push: ) exch append (\n) append /ReplaceStack TellMyProcess } monitor } def /PopMe { % index => - ItemLock { /I exch def /MyStack [ MyStack { dup I eq {pop} if } forall ] store GetStack {Collection Index get} items I get send 80 string cvs (%% Pop: ) exch append (\n) append /ReplaceStack TellMyProcess } monitor } def /ReplaceStack { ItemLock { GetStack null /ReplaceStack TellMyProcess } monitor } def /SortStack { ItemLock { MyStack { /tab-top exch items exch get send exch /tab-top exch items exch get send lt } quicksort pop } monitor } store % To do: % Make this premptable: Each pass it does one thing to make the % display look more like MyStack. (bottom to top priority) /SetStack { % stack => - ItemLock { ItemBegin 10 dict begin /NewStack exch def /OldStack 200 dict def MyStack { items 1 index get {Collection Index get} exch send OldStack 3 1 roll put } forall /MyStack [] store NewStack { % new pause /I null def OldStack { % new ind old dup 3 index eq { % new ind old xcheck 2 index xcheck eq { % new ind /I exch def exit % new } { pop } ifelse % new } { pop pop } ifelse % new } forall % new pause /I load null ne { pop % OldStack /I load undef /MyStack [ MyStack aload pop /I load ] store } { % new /MyStack [ MyStack aload length 3 add -1 roll % /MyStack [ ... new create-struct % /MyStack [ ... newind ] store % } ifelse } forall pause OldStack { % ind old pop % ind items exch get % item dup /StackI null put % XXX /Free exch send % pause } forall pause /Y tab-top def MyStack { % ind items exch get % item Y { % PrevTop dup tab-bottom exch sub % PrevTop below dup 0 lt { location 2 index sub just-move pause } if pop pop tab-top } 3 -1 roll send % NextTop /Y exch def % } forall % pin-rect % x y w h exch pop add exch pop % PinTop Y lt { % if we ran off the top of the stack, then pack it down. PackStack } if pause ItemEnd end } monitor } store /create-struct { % obj => i ItemLock { 20 dict begin /Obj exch def NextStackPos /NextY exch def /NextX exch def free-items length 0 eq { Stack SP /Obj load put Stack SP {click-point} can /new StructItem send /It exch def /items [ items aload pop It ] store /I SP def /SP SP 1 add store It /StackI Index put createevent begin /Name /UpdateInterests def /Canvas ItemParent def /ClientData I def currentdict end sendevent } { /I free-items dup length 1 sub get def /It items I get def /free-items [ free-items aload pop pop ] store It /StackI Index put /Obj load /Reuse It send } ifelse NextX NextY { 2 copy 20 20 just-reshape exch PinX sub exch just-move map damage-view } It send I pause pause end } monitor } store /GetStack { % Don't use [ ... ] in case there are marks on the stack!! MyStack { {Collection Index get} exch items exch get send } forall MyStack length array astore } def /PackStack { 10 dict begin /Y tab-top def MyStack { items exch get Y { % PrevTop dup tab-bottom exch sub % PrevTop below location 2 index sub just-move pause pause pop pop tab-top } 3 -1 roll send /Y exch def pause pause } forall end pause } def /NextStackPos { % - => x y MyStack length 0 eq { NextPos } { MyStack dup length 1 sub get items exch get /NextPos exch send } ifelse } store /ClientExit { CurrentEvent /KeyState get { dup PointButton eq { { ItemBegin /StackI Index store /ThisI Index store ItemCanvas setcanvas location TabY add TabHeight 2 div add exch PinX add exch ItemParent createoverlay setcanvas { 2 setlinewidth exch pop x0 exch lineto } getanimated waitprocess aload pop % x y exch pop location exch pop sub dup 0 gt {ItemHeight sub 0 max} if /PinHeight exch store /paint-hilite win send ItemEnd } fork pop exit } if } forall StopItem } def /paint-struct { gsave ensure-DL /paint Scroller send /paint Notifier send dialog-can setcanvas /fixdamage dialog-text send grestore } def /DrawHilite { gsave can setcanvas location CanvasYFudge add translate ItemRadius object-bbox 4 -1 roll DropShadow add 4 -1 roll DropShadow sub 4 2 roll rrectpath .5 setgray fill % -3 ItemRadius label-bbox insetrrect rrectpath 2 setlinewidth 0 setgray stroke PinHeight 0 ne { 1 setlinecap 2 setlinewidth 0 setgray PinX 0 dup PinHeight add min 6 sub moveto 0 ItemHeight PinHeight abs add 12 add rlineto stroke 1 setlinecap 6 setlinewidth 0 setgray PinX 0 dup PinHeight add min moveto 0 ItemHeight PinHeight abs add rlineto gsave stroke grestore 2 setlinewidth 1 setgray stroke } if grestore } store /reshape { /reshape super send gsave ensure-DL ItemCanvas setcanvas ObjectX ScrollerWidth add SubItemGap add ObjectY translate 0 0 ObjectWidth ScrollerWidth sub SubItemGap sub ObjectHeight NotifierHeight sub SubItemGap sub rectpath dialog-can reshapecanvas dialog-can /Mapped true put /reshape dialog-text send ItemCanvas setcanvas { [ 1 0 1 TextHeight div dup CanHeight floor 1 sub mul null ] } dialog-text send /setrange Scroller send ObjectX ObjectY ScrollerWidth ObjectHeight NotifierHeight sub SubItemGap sub /reshape Scroller send /paint Scroller send ObjectX ObjectY ObjectHeight add NotifierHeight sub ObjectWidth NotifierHeight /reshape Notifier send /paint Notifier send /SubItemMgr dictbegin /Scroller Scroller def /Notifier Notifier def dictend forkitems store grestore } def /ensure-DL { /ObjectWidth TextWidth def %XXX /ObjectHeight TextHeight def %XXX dialog-text null eq { /dialog-can ItemCanvas newcanvas store /dialog-text 200 dialog-can /new TextCanvas send store { /KeyDict 200 dict def KeyDict begin 127 { (erase character) comment % Rubout dialog-string length 0 ne { getcaretpos exch dup 1 gt { 1 sub exch movecaret getcaretpos 1 3 1 roll deletestring /dialog-string dialog-string dup length 1 sub 0 max 0 exch getinterval store } if } if } def 8 127 load def % Backspace 23 { (erase word) comment % ^W 0 { dialog-string length 1 index sub % i dup 0 le { pop exit } if 1 sub dialog-string exch get DelimDict exch known 1 index 0 ne and { exit } if 1 add } loop dup 0 eq { pop } { dup getcaretpos exch 2 index sub exch 2 copy movecaret deletestring /dialog-string dialog-string dup length 4 -1 roll sub 0 max 0 exch getinterval store } ifelse } def 24 { (erase line) comment % ^X getcaretpos exch dialog-string length sub 1 max exch 2 copy movecaret dialog-string length 3 1 roll deletestring /dialog-string () store } def 21 24 load def % ^U 13 { (exec line) comment % Return [ () () ] true writeatcaret dialog-string /dialog-enter dialog-item send /dialog-string () store } def 10 { (select line) comment % Newline [ () () ] true writeatcaret dialog-string kbd-select-object /dialog-string () store prompt } def 10 128 add { (input line) comment % Meta-Newline [ () () ] true writeatcaret dialog-string /dialog-newline dialog-item send /dialog-string () store prompt } def 19 { (insert selection) comment % ^S selected-object (%) sprintf [ 1 index ] true writeatcaret /dialog-string exch dialog-string exch append store } def 20 { (exchange) comment % ^T { (%% exch\n) print exch } execute-it } def 11 { (stack to selection) comment % ^K { (%% Stack to selection\n) print count 0 ne { select-object } if } /execute-it dialog-item send } def 25 { (selection to stack) comment % ^Y { (%% Selection to stack\n) print selected-object } /execute-it dialog-item send } def 27 { (execute selection) comment % Escape selected-object % Since 'token' doesn't recognize \r's as ending comments, % if the selection has \r's in it, make a copy with \r's % mapped to \n's. dup type /stringtype eq { dup remove-returns exch 1 index ne { kbd-select-object } if } if { selected-object cvx dup 64 string cvs (\n) search { exch pop exch pop } if (%% ) (%Execute selection %\n) printf exec } /execute-it dialog-item send } def 3 { (reset input) comment % ^C /kbd-reset dialog-item send } def 4 { (reboot process) comment % ^D /kbd-reboot dialog-item send } def /FunctionR9 { (page up) comment /ScrollPageForward /FakeScroll dialog-scroll send } def /FunctionR15 { (page down) comment /ScrollPageBackward /FakeScroll dialog-scroll send } def /FunctionR7 { (scroll down) comment /ScrollLineForward /FakeScroll dialog-scroll send } def /FunctionR13 { (scroll up) comment /ScrollLineBackward /FakeScroll dialog-scroll send } def /FunctionR11 { (scroll to bottom) comment 1 /ScrollTo dialog-scroll send } def /FunctionF10 { (help) comment % Alternate [ () (Key Bindings:) ()] true writeatcaret [ KeyDict { comment-string exch key-name (%: %) sprintf pause pause } forall ] /gt quicksort { [ exch () ] true writeatcaret pause } forall prompt } def /FunctionR1 { (describe key) comment [ () (Describe key: ) ] true writeatcaret /DescribingKey? true store } def /FunctionR2 { (bind selection to key) comment [ () selected-object (Bind selection %) sprintf (to key: ) ] true writeatcaret /BindingKey? true store } def /FunctionL9 { (find completions) comment [ dialog-string { DelimDict 1 index known { cleartomark mark } if } forall ] cvas dup length 0 eq { pop } { kbd-select-object { selected-object currentprocess /DictionaryStack get 20 dict begin /DS exch def /pat exch def /found null def /complete null def /str pat length string def DS length 1 sub -1 0 { /i exch def DS i get { /val exch def dup str cvs pat ne { pop } { found null eq { /found 1 index 250 string cvs def /complete found def } { /found 1 index 250 string cvs def found length complete length lt { /complete found def } { 0 complete { found 2 index get ne { /complete complete 0 3 index getinterval store exit } if 1 add } forall pop } ifelse } ifelse /val load exch i (%: % = %\n) printf } ifelse } forall pause pause } for pause pause pause complete null eq { () } { complete pat length 1 index length 1 index sub getinterval } ifelse createevent begin /Name /InsertValue def /Action exch def /Canvas currentprocess /Interests get 0 get % event /ClientData get /ViewCanvas get % can /Parent get % clientcanvas has keyboard interests! def currentdict end sendevent complete null ne { complete select-object } if end } execute-it } ifelse } def end % KeyDict /DelimDict 50 dict def DelimDict begin 0 1 32 { dup def } for (%/()<>[]{}) { dup def } forall end /typein { [1 index] true writeatcaret /dialog-string exch dialog-string exch append store } def /DescribingKey? false def /BindingKey? false def /key 0 def /KeyHitCallback { % event => dup update-shifts /Name get dup type /integertype eq { Meta {128 add} if } { Meta { (Meta%) sprintf } if Shift { (Shift%) sprintf } if Control { (Control%) sprintf } if cvn } ifelse /key exch def BindingKey? DescribingKey? or { BindingKey? { selected-object KeyDict key known { KeyDict key get } { null } ifelse kbd-select-object dup null eq { pop KeyDict key undef } { KeyDict exch key exch put } ifelse } if [ () KeyDict key known { KeyDict key get comment-string } { key type /integertype eq (self insert) (unbound) ifelse } ifelse key key-name (%: %) sprintf () ] true writeatcaret /BindingKey? false store /DescribingKey? false store prompt } { KeyDict key known { { KeyDict key get cvx exec } fork pop pause } { key type /integertype eq { key cvis typein } { % beep } ifelse } ifelse } ifelse } def /s null def /newlines 0 def /i 0 def /a null def /pre null def /lastnl 0 def /InsertValueCallback { % string => - /s exch dialog-string exch append store /newlines 0 store /lastnl null store 0 1 s length 1 sub { /i exch store s i get 13 eq { s i 10 put } if s i get 10 eq { /newlines newlines 1 add store /lastnl i store pause } if } for lastnl null ne { s 0 lastnl 1 add getinterval /dialog-enter dialog-item send pause pause pause /dialog-string s lastnl 1 add 1 index length 1 index sub getinterval store pause } if /s s dialog-string length 1 index length 1 index sub getinterval store /a newlines 1 add array store 0 1 newlines 1 sub { pause /i exch store s (\n) search pop /pre exch store pop /s exch store a i pre put } for /dialog-string dialog-string s append store a newlines s put a true writeatcaret } store /KeyboardHandler { % - => - % --- Handler for keyboard, InsertValue, and Deselect events /KeyboardInterest [ % Can addkbdinterests aload pop % Can addselectioninterests aload pop % % Get rid of LiteUI's mouse interests % revokeinterest % Can addfunctionnamesinterest % dup /Action /DownTransition put can addkbdinterests aload pop % XXX can=ClientCanvas can addselectioninterests aload pop % Get rid of LiteUI's mouse interests revokeinterest can addfunctionnamesinterest dup /Action /DownTransition put ] def /dialog-proc currentprocess store { awaitevent dup /Name get { /DeSelect { dup /Action get /PrimarySelection eq { false DrawSelection /SelectionPath null store } if /Action get /InputFocus eq { InactivateCaret } if } /RestoreFocus { pop ReactivateCaret } /InsertValue { /Action get InsertValueCallback } /Ignore { pop } /Default { KeyHitCallback } if } case } loop } def /destroy { % - => - KeyboardInterest null ne { KeyboardInterest can revokekbdinterests % XXX can=ClientCanvas } if KeyboardEventMgr null ne { % added! -deh KeyboardEventMgr killprocess } if EventMgr null ne { EventMgr killprocess } if DelayedMoveProc null ne { % added! -deh DelayedMoveProc killprocess } if MouseDragEventMgr null ne { MouseDragEventMgr killprocess } if } def /CaretBlinkTime 3 def /CaretDutyCycle 0.95 def % Percentage on % This doesn't work: /FontHeight 12 def /FontName FontName def [ () (%% Ready!) () ] true writeatcaret oncaret } dialog-text send /Scroller [1 0 .005 .05 null] 1 {} ItemCanvas /new NeWSScrollbar send def /dialog-scroll Scroller store { /NotifyUser { null ItemValue /moveviewport dialog-text send } def /ClientDrag { DoScroll null ItemValue /moveviewport dialog-text send } def /FakeScroll { % motion => - ItemBegin /ScrollMotion exch def DoScroll EraseBox PaintBox NotifyUser ItemEnd } def /ScrollTo { % val => - ItemBegin /ItemValue exch def EraseBox PaintBox NotifyUser ItemEnd } def } Scroller send /Notifier (Selection:) () /Right {} ItemCanvas /new MessageItem send def { /ItemFont /Screen-Bold findfont 13 scalefont def /ItemFrame 1 def } Notifier send } if psh-socket null eq { MyProcess null ne { MyProcess killprocess } if /MyProcess null store incoming null ne { incoming killprocess } if /incoming null store systemdict /_ViewCanvas ItemCanvas put /psh-socket { socket-file (r) file } errored { { newprocessgroup framebuffer setcanvas 500 500 [(Could not establish connection)] popmsg pop } fork pause pause pop currentprocess killprocessgroup } if store /incoming { { { psh-socket 255 string readline false eq { [() (Lost it!) ()] true writeatcaret % 1 60 div sleep % /kbd-reboot dialog-item send /incoming null store currentprocess killprocess } if [ exch getcaretpos pop 1 ne { () exch } if () ] true writeatcaret psh-socket bytesavailable 0 eq { prompt } if } loop } dialog-text send } fork store psh-socket (systemdict/dbgstart known not{(NeWS/debug.ps)run}if dbgstart\n_ReadyProcess\n) writestring psh-socket flushfile } if } def /dialog-newline { % str => - psh-socket exch writestring psh-socket 10 write psh-socket flushfile } def /dialog-enter { % str => - /dialog-buf exch dialog-buf (%%\n) sprintf remove-returns store { dialog-buf { token } errored { [(%% Syntax error!)] true /writeatcaret dialog-text send kbd-reset exit } { { exch /dialog-buf exch store [ exch ] cvx execute-it } { dialog-buf ( _FOO_) append token { % Ignore white space exch pop /_FOO_ eq { /dialog-buf () store } if } if exit } ifelse } ifelse pause } loop } def /destroy { shut-down SubItemMgr null ne { SubItemMgr killprocess /SubItemMgr null store } if dialog-text null ne { % {{destroy} errored pop} dialog-text send dialog-can /Retained false put /destroy dialog-text send /dialog-text null store /dialog-can null store } if /destroy super send } def classend def %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Icky system globals and merciless kludges /comment { pop } def % Reap dead debuggers /rd { [ DbgDicts {pop} forall ] { dup /State get /zombie eq { DbgDicts 1 index undef killprocess } { pop } ifelse } forall } def systemdict /DbgDicts known { rd } if /dirname { ob begin uniquecid dup 3 -1 roll (dir2dict % % | psh) sprintf forkunix [exch cidinterest1only] forkeventmgr waitprocess replace-struct end redo-layout } store /filename { (file2dict % | psh) sprintf forkunix } def /_ViewCanvas null def /_SendUpdateStack { count array astore aload null /UpdateStack _SendViewEvent { currentfile flushfile } errored { { dbgstop } errored quit } if } def /_SendViewEvent { % ClientData Action Name => - createevent begin /Name exch def /Action exch def /ClientData exch def /Canvas currentprocess /Interests get 0 get % event /ClientData get /ViewCanvas get % can def currentdict end sendevent } def /_ReadyProcess { createevent begin /Canvas _ViewCanvas def /Name /ProcessReady def /Action currentprocess def count array astore aload /ClientData exch def currentdict end sendevent createevent begin /Name 20 dict def Name begin /ExecIt { /ClientData get exec _SendUpdateStack } def /ReplaceStack { dup /Action get dup type /stringtype ne { pop } { { print currentfile flushfile } errored { { dbgstop } errored quit } if } ifelse /ClientData get count 1 roll count 1 sub {pop} repeat aload pop } def /DropDead { { dbgstop } errored { (Ayyyeee!\n) print currentfile flushfile } errored quit } def end % Name /ClientData 20 dict def ClientData begin /ViewCanvas _ViewCanvas def % Stash! end % ClientData currentdict end expressinterest { awaitevent } loop quit } def /revokekbdinterests { % [ int1 int2 ... intn ] can => - removefocusinterest % aload pop revokeinterest revokeinterest revokeinterest {revokeinterest} forall } store /getmenuaction { % index => action dup null ne { MenuActions 1 index MenuActions length 1 sub min get % Execute actions that are names! (This is so we can have the executable % name of a submenu, or a functions to compute the menu action!) dup type /nametype eq { exec } if } {nullproc} ifelse exch pop } def systemdict /old-setselection known not { /old-setselection /setselection load def /setselection { % dict rank 2 copy old-setselection createevent begin /Name /SelectionChanged def /Action exch def /ClientData exch def currentdict end sendevent } def } if /select-object { % obj => - 20 dict begin /ContentsPostScript 1 index def /ContentsAscii exch (%) sprintf def /SelectionObjSize 1 def /SelectionResponder null def /Canvas currentcanvas def % XXX? /SelectionHolder currentprocess def % XXX? currentdict end /PrimarySelection setselection } def /select-pointer { % obj index => - 20 dict begin /SelectionStartIndex exch def /ContentsPostScript exch def /ContentsAscii /ContentsPostScript load /SelectionStartIndex load get (%) sprintf def /SelectionObjSize 1 def /SelectionResponder null def /Canvas currentcanvas def % XXX? /SelectionHolder currentprocess def % XXX? currentdict end /PrimarySelection setselection } def /select-interval { % obj start len => - 20 dict begin /SelectionObjSize exch def /SelectionStartIndex exch def /SelectionLastIndex SelectionStartIndex SelectionObjSize add 1 sub def /ContentsPostScript exch def /ContentsAscii /ContentsPostScript load SelectionStartIndex SelectionObjSize getinterval (%) sprintf def /SelectionResponder null def /Canvas currentcanvas def % XXX? /SelectionHolder currentprocess def % XXX? currentdict end /PrimarySelection setselection } def /dissect-selection { % seldict => obj dup null ne { dup /ContentsPostScript known { dup /ContentsPostScript get % seldict obj 1 index /SelectionStartIndex known { 1 index /SelectionLastIndex known { exch dup /SelectionStartIndex get % obj seldict start exch /SelectionLastIndex get % obj start last 1 index sub 1 add % obj start len getinterval % subobj } { exch /SelectionStartIndex get get % subobj } ifelse } { exch pop } ifelse % obj } { dup /ContentsAscii known { /ContentsAscii get } if } ifelse } if } def /selected-object { % - => obj /PrimarySelection getselection dissect-selection } def /selected-pointer? { % - => false / collection index true /PrimarySelection getselection dup null eq { false } { dup /ContentsPostScript known not { false } { dup /SelectionStartIndex known not { false } { dup /ContentsPostScript get exch /SelectionStartIndex get true } ifelse } ifelse } ifelse } def % NeWS-print 0.996 % Written by Josh Siegel % Munged by Don Hopkins /Externals 512 dict def /ExternalsBack 512 dict def Externals /Count 0 put /string-magic dictbegin (\b) 0 get (\\b) def (\f) 0 get (\\f) def (\n) 0 get (\\n) def (\r) 0 get (\\r) def (\t) 0 get (\\t) def (\() 0 get (\\\() def (\)) 0 get (\\\)) def (\\) 0 get (\\\\) def dictend def /fixstring { 10 dict begin /len 0 def /out 1 index length 3 mul string def { dup string-magic exch known { string-magic exch get } { cvis } ifelse out len 2 index putinterval /len exch length len add def } forall out 0 len getinterval dup length string copy end } def /stringer { % proc => string dup type cvlit { /arraytype { pause /arraylvl arraylvl 1 add store dup xcheck { /the_string the_string ( {\n) append store { stringer } forall /the_string the_string ( }\n) append store } { /the_string the_string ( [\n) append store { stringer } forall /the_string the_string ( ]\n) append store } ifelse /arraylvl arraylvl 1 sub store } /nametype { dup xcheck { the_string arraylvl 0 eq (% /% cvx ) (% %) ifelse sprintf /the_string exch store } { the_string (% /%) sprintf /the_string exch store } ifelse } /operatortype { 255 string cvs dup length 2 sub 1 exch getinterval the_string arraylvl 0 eq (% /% cvx ) (% %) ifelse sprintf /the_string exch store } /stringtype { fixstring the_string (% \(%\)) sprintf /the_string exch store } /marktype { (mark ) % [ DANGER! ] } /booleantype /integertype /realtype /nulltype { the_string (% %) sprintf /the_string exch store } /Default { dup type /dicttype ne dictlvl 0 ne or arraylvl 0 ne or { ExternalsBack 1 index known { ExternalsBack exch get % name } { Externals begin Count /Count Count 1 add def end % obj count 1 index type (&%_%) sprintf % obj name Externals 1 index 3 index put % obj name ExternalsBack 3 -1 roll 2 index put % name } ifelse the_string ( //) append exch append /the_string exch store } { /dictlvl dictlvl 1 add store /the_string the_string ( dictbegin\n) append store { pause /the_string the_string (\t) append store exch stringer stringer /the_string the_string ( def\n) append store } forall /the_string the_string ( dictend \n) append store /dictlvl dictlvl 1 sub store } ifelse } def } case } def /tokout { % obj => string 10 dict begin /cnt Externals /Count get def /dictlvl 0 def /arraylvl 0 def /the_string () def stringer the_string cnt Externals /Count get ne { (Externals begin\n%\nend\n) sprintf } def end } def end % systemdict %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Nasty userdict variables /dialog-text null def /dialog-can null def /dialog-proc null def /dialog-string () def /dialog-buf () def /dialog-item null def /dialog-scroll null def (NEWSSERVER) getenv (;) search pop (.) search pop pop pop /socket-port exch def pop /socket-host exch def /socket-file (%socketc) socket-port append socket-host append def /psh-socket null def /SP 0 def /Stack 256 array def /Pallets 100 dict def Stack 0 Pallets put Stack 1 (Nothing!) put /ThisI null def /it null def /ob null def /obs null def /FillColor 1 1 1 rgbcolor def /ItemLock createmonitor def /items [] def /free-items [] def /Meta false def /Control false def /Shift false def /win null def /can null def /slidemgr null def /itemmgr null def /incoming null def %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % User Utilities % % quicksort by Don Woods at Sun Microsystems, Inc. % /quicksort { % array proc => array (sorted, reuses same storage) 10 dict begin /Bigger? exch cvx def % a b bigger? => t if a -- sorts array in place, using Bigger? for comparisons dup length dup 2 gt { % A N % the next lines (until but not incl /Key...) subsort three elements % so we can use the median as the partitioning element; this improves % performance for the case where the array is initially nearly sorted, % but is not strictly necessary for the algorithm to work (it does % seem to improve average runtime by about 10%) 2 copy 1 sub 2 copy 2 idiv 1 index 0 % A N A N-1 A (N-1)/2 A 0 6 copy get 5 1 roll get 3 1 roll get % above & A[N-1] A[(N-1)/2] A[0] 2 copy Bigger? {exch} if % subsort for three elements 3 1 roll 2 copy Bigger? {exch} if % ... (call them min mid max) 3 -1 roll 2 copy Bigger? {exch} if % ... subsort finished 9 index % A N A N-1 A (N-1)/2 A 0 min mid max N 3 eq { 5 2 roll put 4 1 roll put put % store min/mid/max back pop pop % pop A & N } { % else store mid at 0, max at N-1, min at (N-1)/2, then partition 3 -1 roll 5 2 roll put exch 4 1 roll put put % A N /Key 2 index 0 get def % partitioning value 0 % A N 0, also known as A j i { % main partitioning loop % incr i until i=j or A[i]>=A[0]; note A[j] is rangecheck { 1 add 2 copy gt { % i++; A j i j>i? dup 3 index exch get % A j i A[i] Key exch Bigger? not {exit} if } {exit} ifelse } loop % decr j until A[j]<=A[0]; happens at j=i-1 if not sooner exch { % A i j 1 sub dup 3 index exch get % A i j A[j] Key Bigger? not {exit} if } loop 2 copy gt {exit} if % if i>=j, finished partition % swap A[j] & A[i]; stack has: A i j 2 index 4 copy exch get % A i j A A i A[j] 4 1 roll get % A i j A[j] A A[i] 3 index exch put % A i j A[j] 4 copy exch pop put pop exch % A j i } loop % finish partition by exchanging A[j] with A[0]; stack has: A i j exch pop 2 copy 4 copy get % A j A j A j A[j] exch pop 0 exch put Key put % A j % now recur on A[0..j-1] and A[j+1..N-1] 2 copy 1 add 1 index length 1 index sub % A j A j+1 N-1 getinterval 3 1 roll 0 exch getinterval % A[j+1..N-1] A[0..j-1] 2 copy length exch length gt {exch} if % put smaller on top quickrecur quickrecur % tail recursion avoids deep stack } ifelse % =3 or >3 elements } { % handle 1- and 2-element cases specially for efficiency 2 eq { dup aload pop Bigger? {aload 3 1 roll exch 3 -1 roll astore} if } if pop % pop the array } ifelse } def % quickrecur % end of quicksort /shift-names 10 dict def shift-names begin /Meta false def /Shift false def /Control false def end % shift-names /update-shifts { shift-names {store} forall /KeyState get { shift-names 1 index known { true store } { pop } ifelse } forall } store /key-names 40 dict def key-names begin 8 (Backspace) def 9 (Tab) def 10 (Newline) def 13 (Return) def 27 (Escape) def 32 (Space) def 127 (Delete) def end % key-names /key-name { % key => string dup type /integertype eq { dup 127 and key-names 1 index known { key-names exch get } { dup 32 lt { 64 add cvis (^%) sprintf } { cvis } ifelse } ifelse exch 128 ge { (Meta-%) sprintf } if } { (%) sprintf } ifelse } store /comment-string { % obj => string dup type /arraytype eq { dup length 2 ge { dup 1 get /comment eq { 0 get } if } if } if (%) sprintf } def /destroy { % dummy destroy method } def % Forward messages on to stack /prompt { {} execute-it } def /execute-it { /execute-it dialog-item send } def /exec-it { /exec-it dialog-item send } def /push-it { /push-it dialog-item send } def /kbd-select-object { gsave can setcanvas select-object grestore } def /kbd-select-pointer { gsave can setcanvas select-pointer grestore } def /kbd-select-interval { gsave can setcanvas select-interval grestore } def /remove-returns { % str => str' dup (\r) search not { pop } { % str rest \r pre length 1 add exch pop % str rest len 3 -1 roll dup length string copy % rest len str' 3 1 roll { % str' rest len 2 index 1 index 1 sub 10 put exch (\r) search { % str' len rest \r pre length 1 add exch pop % str' len rest len 3 -1 roll add % str' rest len } { % str' len rest pop pop exit } ifelse } loop } ifelse } def %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Pallets of useful functions Pallets begin /Debug dictbegin /dlb /dbglistbreaks cvx def /de /dbgenter cvx def /dx /dbgexit cvx def /dk /dbgkill cvx def /dc /dbgcontinue cvx def /dcc {dbgcopystack dbgcontinue} def /dw /dbgwhere cvx def /execstack {DbgImplicitBreak DbgGetExecStack} def /exec /exec cvx def /stack /stack cvx def /clear /clear cvx def /typo { % undefined (select correct spelling) => - userdict begin dup cvlit [ selected-object (%) sprintf cvn cvx ] cvx def end exec } def dictend def /Number dictbegin 0 {10 mul} def 1 {10 mul 1 add} def 2 {10 mul 2 add} def 3 {10 mul 3 add} def 4 {10 mul 4 add} def 5 {10 mul 5 add} def 6 {10 mul 6 add} def 7 {10 mul 7 add} def 8 {10 mul 8 add} def 9 {10 mul 9 add} def /Back {10 div floor} def /Reset {0 mul} def /Enter {0} def dictend def currentautobind false setautobind /Math { {add sub mul div idiv mod} {neg abs min max} {ceiling floor round truncate} {cos sin tan arcsin arccos arctan atan exp ln log sqrt} {random rand} {etc, etc, etc...} {(Add your own!)} } cvlit def /Stack { dup pop exch clear load def store get put aload forall [ ] } cvlit def /Window 20 dict begin /new { framebuffer /new DefaultWindow send { newprocessgroup /reshapefromuser 1 index send /map exch send } fork waitprocess pop dup /ClientCanvas get setcanvas (%% Now on ) print currentcanvas == } def dictend def setautobind end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Item managment /createitems { ItemLock { /items [ Stack 0 {click-point} can /new StructItem send 20 10 0 0 /reshape 5 index send Stack 1 {} can /new TextStructItem send 20 50 0 0 /reshape 5 index send ] def /SP items length store /dialog-item items 1 get store {/PinHeight 600 def /StackI 1 def} dialog-item send /ThisI 1 store } monitor } def /slideitem { % items fillcolor item => - ItemLock { gsave dup 4 1 roll % item items fillcolor item {ItemCanvas canvastotop moveinteractive location move} exch send % item grestore } monitor } def /update-slide-interests { CurrentEvent /ClientData get % Index items exch get % item 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 expressinterest } def /update-start-interests { CurrentEvent /ClientData get % Index items exch get % item mark [/makestartinterests 3 index send aload pop] {dup xcheck {exec} {expressinterest} ifelse} forall cleartomark pop } def /start-event-mgrs { % 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 null ne {slidemgr killprocess} if { %XXX /slidemgr [ items { % key item dup /ItemCanvas get % item can MiddleMouseButton [items FillColor % item can name mark dict color 6 -1 roll /slideitem cvx] cvx % can name proc DownTransition % can name proc action 4 -1 roll eventmgrinterest % interest } forall /UpdateInterests /update-slide-interests null can eventmgrinterest ] forkeventmgr store } pop %XXX itemmgr null ne {itemmgr killprocess} if /itemmgr [ items iteminterests aload pop /UpdateInterests /update-start-interests null can eventmgrinterest ] forkeventmgr store } def %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Window class definition /CyberWindow DefaultWindow dictbegin /FrameLabel (PostScript Structure CyberSpace) def /IconLabel (PS CyberSpace) def /IconImage /galaxy def dictend classbegin /PaintClient { paint-hilite items paintitems } def /paint-hilite { ClientCanvas setcanvas erasepage /DrawHilite dialog-item send } def /ClientMenu [ (Break Stack) { clear /BrokenStack /dbgbreak dialog-item send } (Credits) { /display-credits win send } (Break Window) { clear /BrokenWindow /dbgbreak win send } (Break Struct) { clear /BrokenStruct /dbgbreak items 0 get send } ] /new DefaultMenu send def /display-credits { gsave framebuffer setcanvas currentcursorlocation [ (NeWS CyberSpace:) ( by Don Hopkins) (----------------) (Code stolen from:) ( Josh Siegel) ( Don Woods) ] popmsg pop grestore } def /DestroyClient { { newprocessgroup itemmgr type /processtype eq { itemmgr killprocess } if slidemgr type /processtype eq { slidemgr killprocess } if items { /destroy exch send } forall /items null store /_ViewCanvas null store /PrimarySelection clearselection % XXX? ClientCanvas /Retained false put FrameCanvas /Retained false put FrameCanvas /Mapped false put /DestroyClient super send } fork pop } def classend def %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Create objects /win framebuffer /new CyberWindow send store % Create a window 0 0 900 900 /reshape win send /can win /ClientCanvas get def % BOO HISS can /Parent get /Retained true put createitems % /reshapefromuser win send /map win send start-event-mgrs From don@brillig.umd.edu Sun Mar 12 16:33:50 1989 Date: Sun, 12 Mar 89 16:33:50 EST To: NeWS-makers@brillig.umd.edu Subject: pullout.ps From: Don Hopkins Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) You'll need the following class definition to run the Pseudo-Scientific Visualizer. The CyberSpace deck uses pullout pie menus if they're defined. You can select the "util... molecule" menu item over an object in CyberSpace, to view it with the visualizer. (I'll integrate them better later!) (PS: softmenu.ps doesn't wort work with pullout menus yet...) -Don %! %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Class PulloutPieMenu % Copyright (C) 1988 by Don Hopkins (don@brillig.umd.edu) % % This program is provided free for unrestricted use and redistribution, % provided that the headers remain intact. No author or distributor % accepts any responsibility for any problems with this software. % % PulloutPieMenu is a subclass of PieMenu that uses cursor distance % from the menu center to specify an argument to the menu selection. % Each menu key has an array of possible arguments, from which the % cursor distance selects the argument value. The values in the % arrays are "Things" (cf. litemenu.ps & colordemo) that are painted % in the menu center as feedback. The /new method of class % PulloutPieMenu takes the same arguments that regular menus do, plus % an additional array of argument arrays. Each argument array % corresponds to a menu key. If you give just one argument array, it % is used for all the keys, the same as with the array of actions. % You can use getmenuarg and getmenuargindex in your menu actions to % retrieve the argument displayed when the key was selected. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% systemdict begin % ------------------------------------ % % PulloutPieMenu /PulloutPieMenu PieMenu dictbegin /SliceWedges false def /HiLiteWithArrow? false def /PrinterMatch? false def /ArgBorder 2 def /EraseArgs? true def /MenuArgs null def /MenuArg null def /MenuArgIndex null def /PaintedArg null def dictend classbegin % [[args...]...] [keys...] [actions...] => menu /new { /new super send begin dup length MenuKeys length lt { [ exch aload pop % pad out args w/ last arg counttomark MenuKeys length exch sub {dup} repeat ] } if /MenuArgs exch def currentdict end } def % Need to make flipstyle a no-op because /new takes a different number % of args, and actions might depend on MenuArg! Scratch that. % Instead, let's just make a new instance of ourselves, of % the same class. /flipstyle { 0 1 MenuActions length 1 sub { dup getmenuaction % fixed to use getmenuaction! dup type /dicttype eq { /flipstyle exch send % i menu' MenuActions 3 1 roll put % - } {pop pop} ifelse } for MenuArgs MenuKeys MenuActions /new ClassName load send dup /LabelMinRadius LabelMinRadius put % hack } def /MenuGSave { /MenuGSave super send PrinterMatch? setprintermatch } def /DragProc { ChildMenu null eq { MenuGSave PieRadius dup translate CurrentEvent begin XLocation DeltaX add YLocation DeltaY add end SetMenuValue MenuValue PaintedValue ne { PaintMenuValue } if getmenuarg /PaintedArg load ne { PaintMenuArg } if grestore } if } def framebuffer /GLCanvas known { % SGI 4Sight? % Paint menus on the overlay plane /paint { /paint super send /PaintedArg load /PaintArg self send } def } { /DamageProc { MenuGSave damagepath clipcanvas /paint self send PaintedValue PaintSlice /PaintedArg load PaintArg newpath clipcanvas grestore } def } ifelse /PaintMenuArg { getmenuarg dup null eq /PaintedArg load null eq EraseArgs? or or { % The null...pop is to get around the fact that 4Sight's ThingSize % recognizes [(string) /name] as a special case, and eats both, % which hoses us if we call it with just a /name, but with a % (string) on the stack before that. null /PaintedArg load EraseArg pop } if dup PaintArg /PaintedArg exch store } def /EraseArg { % thing => - MenuGSave dup null eq { pop PieRadius dup translate MenuFillColor setcolor 0 0 LabelRadius Gap sub 3 sub 0 360 arc fill } { PieRadius dup translate MenuFillColor setcolor % dup /toggle3 eq {/foo dbgbreak} if ThingSize 2 copy -.5 mul exch -.5 mul exch 4 -2 roll ArgBorder neg 5 1 roll insetrect % Some extra padding... rectpath fill } ifelse grestore } def /PaintArg { % thing => - MenuGSave dup null eq { pop PieRadius dup translate MenuBorderColor setcolor MenuLineWidth setlinewidth MenuLineCap setlinecap MenuItems { begin gsave newpath ang PieSliceWidth 2 div sub rotate NumbRadius 0 moveto LabelRadius Gap sub 4 sub 0 lineto MenuBorderColor setcolor stroke grestore end } forall } { PieRadius dup translate MenuTextColor setcolor dup ThingSize -.5 mul exch -.5 mul exch ShowThing } ifelse grestore } def /showat { PaintedArg null ne PaintedValue null ne and MenuCanvas null ne and MenuWidth null ne and { MenuGSave /PaintedArg load EraseArg /PaintedArg null store null PaintArg grestore } if /MenuArg null def /MenuArgIndex null def /showat super send } def /SetMenuValue { % x y => - /SetMenuValue super send /MenuArg MenuValue null eq {null true} {MenuArgs MenuValue get dup length 0 eq} ifelse { pop null /MenuArgIndex null def } { PieDistance PieRadius 1 sub min NumbRadius sub PieRadius NumbRadius sub div 1 index length mul floor /MenuArgIndex 1 index def get } ifelse def } def /getmenuargindex { % - => index MenuArgIndex } def /getmenuarg { % - => Thing /MenuArg load } def classend def end % systemdict From don@brillig.umd.edu Tue Mar 14 03:04:44 1989 Date: Tue, 14 Mar 89 03:04:44 EST To: NeWS-makers@brillig.umd.edu Subject: Class vars or Instance vars From: Knut Skog Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Thanks to Cris (cws) and Greg @Sun for instructive comments. Gregs comment: > Now, LiteWindow has not made all the right > choices (by a long mark), so some of them can not be explained. removes my first source of confusion. Yes, I too thought that instance-vars was non-shared and class-vars was shared by all instances, however Chris' comment on composit objects as instance vars gave me a new understanding of the term non-shared. Is it right to state that class vars are shared and so is instance vars that are composite (string, array, dict, proc). Only the instance-vars that are simple objects are non-shared. To me this looks like a small problem. In object oriented system design a class should be constructed based on the true nature of the attributes of the objects under consideration. Class variations should be taken care of by subclassing and truly private data of a class instance should be defined as instance vars. The fact that class-vars is 'turned into instance vars' (placed in Instance dict) as soon as their attributs are assigned dynamicaly and therby makes it preferable to write 'natural instance attributes' as class-vars, is a pecullarity of this system that class-writers must be aware of. Right? In my 25-years as computer professional I have never had a more enjoyable and interesting experiance than NeWS. krg, Knut Skog Comp SC. Dep Univ. of Tromsoe, Norway From don@brillig.umd.edu Tue Mar 14 03:06:52 1989 Date: Tue, 14 Mar 89 03:06:52 EST To: NeWS-makers@brillig.umd.edu Subject: Class vars or Instance vars, conclusion From: Knut Skog Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) My comments on this issue may have propagated some of my own confution. My current understanding is that the values of composite instance variables are shared dispite being an "instance". This is demonstrated by the following example; % The test should be executed incrementaly in three steps as indicated. % Step1: Make your own subclass /MyClass DefaultWindow dictbegin /InstComposite (Instance string) def dictend classbegin /ClassComposite (Class string) def /PaintClient { /Helvetica-Bold findfont 18 scalefont setfont 100 100 moveto InstComposite show 100 50 moveto ClassComposite show } def classend def /MyCInst1 framebuffer /new MyClass send def { /FrameLabel (Inst 1) def } MyCInst1 send /reshapefromuser MyCInst1 send /map MyCInst1 send % end Step1 % Step2: Change Instance value. { /InstComposite ClassComposite def % Some dict or an array assignment is % more likely in real } MyCInst1 send % end Step 2. % Resize window to see the to strings being equal. % Now we believe that our instance , its values inclusive, % is non shared (traditional interpretation). % We modify the composite value of our class object: % Step3: { ClassComposite 0 188 put } MyClass send % end Step3. % We have not done anything explicitly to MyCInst. However, % having instructed a change in our class definition, when it % is repainted, we see that the instance variable (InstComposite) % of our first instance has been changed indirectly! % Hence composite values of instance vars are shared because composite % def-ing in PostScript is by reference (not by value). Knut From don@brillig.umd.edu Sat Mar 18 02:46:57 1989 Date: Sat, 18 Mar 89 02:46:57 EST To: NeWS-makers@brillig.umd.edu Subject: Re: Class vars or Instance vars, conclusion From: aramis.rutgers.edu!athos.rutgers.edu!gaynor@rutgers.edu (Silver) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) > My comments on this issue may have propagated some of my own confution. My > current understanding is that the values of composite instance variables are > shared dispite being an "instance". Indeed, I refer you to page 27 of The Red Book. This property is clearly demonstrated by the following example: 69 dup % ... 69 69 1 add % ... 69 70 [69] dup % ... [69] [69] dup 0 70 put % ... [70] [70] Regards, [Ag] gaynor@rutgers.edu [BTW, confution --> confusion, dispite --> despite; yes, English sucks.] From don@brillig.umd.edu Sat Mar 18 02:52:28 1989 Date: Sat, 18 Mar 89 02:52:28 EST To: NeWS-makers@brillig.umd.edu Subject: Re: Class vars or Instance vars From: spectral!sjs@bellcore.com (Stan Switzer) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) In article <101*knut-skog@rglab.uit.uninett> knut-skog%rglab.uit.uninett@NORUNIX.BITNET (Knut Skog) writes: > .... In object oriented system design > a class should be constructed based on the true nature of the attributes > of the objects under consideration. Class variations should be taken care > of by subclassing and truly private data of a class instance should be > defined as instance vars. The fact that class-vars is 'turned into > instance vars' (placed in Instance dict) as soon as their attributs are > assigned dynamicaly and therby makes it preferable to write 'natural > instance attributes' as class-vars, is a pecullarity of this system that > class-writers must be aware of. Right? This is indeed true (so long as you use "def" and not "store" to change the values). It is an interesting and useful feature of NeWS's class system that default values for instance variables can simply be declared as class variables. Generally, with variables that reflect user preferences, etc., and which don't change too much (i.e. aren't *really* part of the object's dynamic state) I make them class variables with the understanding that they can be overridden by assigning to the instance. Additionally, such variables can be overridden in subclasses. Although this feature is somewhat unusual it is not unique to NeWS. The language "Self" described in the '87 (I think) OOPSLA has the same property. In a "true" object-oriented system, ALL data would be objects. In this case, the distinction between shared and non-shared object usually remains. Generally, composite objects are shared and simple objects (in SmallTalk, just the small ints) are not. (The point is somewhat moot since there are no operations that *change* atomic objects, only operations that create new immutable objects, so you really wouldn't know if they were shared or not.) In any system with class variables (or other means of namespace sharing) one must distinguish between shared objects and shared references to objects. > > In my 25-years as computer professional I have never had a more > enjoyable and interesting experiance than NeWS. Likewise. I haven't had as much enjoyment programming since I first got my hands on LISP 1.5. In the elegance of its conception and the virtuosity of its execution NeWS is nearly unparalleled. Stan Switzer sjs@ctt.bellcore.com "NeWS -- The windowing system for the other half of your brain." -- Don Hopkins From don@brillig.umd.edu Sun Mar 19 21:35:01 1989 Date: Sun, 19 Mar 89 21:35:01 EST To: NeWS-makers@brillig.umd.edu Subject: Re: Class vars or Instance vars, conclusion From: aramis.rutgers.edu!athos.rutgers.edu!gaynor@rutgers.edu (Silver) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) > My comments on this issue may have propagated some of my own confution. My > current understanding is that the values of composite instance variables are > shared dispite being an "instance". Indeed, I refer you to page 27 of The Red Book. This property is clearly demonstrated by the following example: 69 dup % ... 69 69 1 add % ... 69 70 [69] dup % ... [69] [69] dup 0 70 put % ... [70] [70] Regards, [Ag] gaynor@rutgers.edu [BTW, confution --> confusion, dispite --> despite; yes, English sucks.] From don@brillig.umd.edu Sun Mar 19 21:45:32 1989 Date: Sun, 19 Mar 89 21:45:32 EST To: NeWS-makers@brillig.umd.edu Subject: Did anyone get my program "treeedit" to work? From: gondor.cs.psu.edu!callahan@psuvax1.cs.psu.edu (Paul B. Callahan) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) I posted a program called treeedit last October or so (maybe Nov.). It consisted of two files: treeedit.c and treeedit.cps. The program was an interactive graphical binary tree "editor," which allowed the user to perform insertions, deletions, and rotations on a binary search tree. Needless to say, it runs under NeWS. The only response I have had to date is from a person who was unable to get the source to compile for some unknown reason. We have been trying to determine why the program works for me and not for him, but have so far been unsuccessful. I would appreciate a response from anyone who tried out the program, whether successful or not. I would especially appreciate some explanation as to why it may not be portable to other systems running NeWS. I will mail the source to anyone who would like to troubleshoot. From don@brillig.umd.edu Mon Mar 20 22:04:03 1989 Date: Mon, 20 Mar 89 22:04:03 EST To: NeWS-makers@brillig.umd.edu Subject: Time to create comp.sources.news? From: mcvax!enea!maxim!prc@uunet.uu.net (Robert Claeson) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Given the high frequency of sources in this newsgroup, isn't it time to create comp.sources.news soon? I'm N_O_T_ taking votes. -- Robert Claeson, ERBE DATA AB, P.O. Box 77, S-175 22 Jarfalla, Sweden Tel: +46 (0)758-202 50 Fax: +46 (0)758-197 20 EUnet: rclaeson@ERBE.SE uucp: {uunet,enea}!erbe.se!rclaeson ARPAnet: rclaeson%ERBE.SE@uunet.UU.NET BITNET: rclaeson@ERBE.SE From don@brillig.umd.edu Mon Mar 20 22:12:07 1989 Date: Mon, 20 Mar 89 22:12:07 EST To: NeWS-makers@brillig.umd.edu Subject: tbl with transcript/psview From: agate!saturn!jupiter.ucsc.edu!conrad@ucbvax.Berkeley.EDU (Al Conrad, x2370) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) When I psview documents prepared with ditroff/transcript2.1, the vertical lines in tables come out as a ladder of horizontal lines. The same postscript produces the right picture on the laser printer. Has anyone else experienced this problem? Thanks in advance, Al Conrad conrad@saturn.ucsc.edu From don@brillig.umd.edu Mon Mar 20 23:20:08 1989 Date: Mon, 20 Mar 89 23:20:08 EST To: NeWS-makers@brillig.umd.edu Subject: Re: Did anyone get my program "treeedit" to work? From: steinmetz!vdsvax!montnaro@itsgw.rpi.edu (Skip Montanaro) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) The only response I have had to date is from a person who was unable to get the source to compile for some unknown reason. We have been trying to determine why the program works for me and not for him, but have so far been unsuccessful. There are three places in the code where you neglected to place space around either "=*" or "=&". This results in an ambiguity detected by Sun's C compiler. It can't tell if you are using an assignment operator followed by * or &, or the old-fashioned versions of *= and &=. I suspect you weren't using a Sun for treeedit development. My diffs follow. I have not tested them yet. diff -rc2 treeedit.c~ treeedit.c *** treeedit.c~ Mon Mar 13 22:11:03 1989 --- treeedit.c Thu Mar 16 22:35:32 1989 *************** *** 76,80 **** if (depth>*maxdepth) *maxdepth=depth; findxy(root->left,rank,depth+1,maxdepth); ! root->rank=*rank; root->depth=depth; (*rank)++; --- 76,80 ---- if (depth>*maxdepth) *maxdepth=depth; findxy(root->left,rank,depth+1,maxdepth); ! root->rank = *rank; root->depth=depth; (*rank)++; *************** *** 169,177 **** } else if (cps_rightbutton(&id,&geomx)) { ! insplace=&root; while ((*insplace)!=NULL) { if ((float) ((*insplace)->rank) > geomx) ! insplace=&((*insplace)->left); ! else insplace=&((*insplace)->right); } *insplace=(struct bst *) malloc(sizeof(struct bst)); --- 169,177 ---- } else if (cps_rightbutton(&id,&geomx)) { ! insplace = &root; while ((*insplace)!=NULL) { if ((float) ((*insplace)->rank) > geomx) ! insplace = &((*insplace)->left); ! else insplace = &((*insplace)->right); } *insplace=(struct bst *) malloc(sizeof(struct bst)); -- Skip Montanaro (montanaro@sprite.crd.ge.com) From don@brillig.umd.edu Mon Mar 20 23:23:00 1989 Date: Mon, 20 Mar 89 23:23:00 EST To: NeWS-makers@brillig.umd.edu Subject: Thanks to all who responded (Was: Re: Did anyone get my program "treeedit" to work?) From: gondor.cs.psu.edu!callahan@psuvax1.cs.psu.edu (Paul B. Callahan) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) In article (Skip Montanaro) writes: >There are three places in the code where you neglected to place space around >either "=*" or "=&". This results in an ambiguity detected by Sun's C >compiler. It can't tell if you are using an assignment operator followed by >* or &, or the old-fashioned versions of *= and &=. I suspect you weren't >using a Sun for treeedit development. Yes. This would produce the problems that occurred with compilation. Thanks for pointing it out. I could not find these strings in my program because I did a grep for "*=" and "&=" instead of "=*" and "=&" when I looked at the error file that was sent to me. (Line numbers didn't seem to correspond for some reason). I'll have to make a permanent mental note of this problem. Oddly enough, I did do the development on a Sun. And I received many replies from people who got it to work on a Sun. It was probably just a different revision of the Sun compiler. Finally, thanks to everyone who responded to my posting. --Paul From don@brillig.umd.edu Tue Mar 21 01:26:47 1989 Date: Tue, 21 Mar 89 01:26:47 EST To: NeWS-makers@brillig.umd.edu Subject: Re: Need NeWSIllustrator 4 and 5 From: mcvax!unido!nixctc!sun360.Online.Nixdorf.De!pete@uunet.uu.net (pete delany) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) How about a complete re-posting of NeWSIllustrator. Pete Delaney - Nixdorf UCC | pete@NIXCTC.DE Prefered Addr Loffel Strasse 3 | pyramid!nixctc!pete UUCP from Calf 7000 Stuttgart 70 | pete@RELAY.HUJI.AC.IL Backup Address West Germany | Phone: +49 (711) 7685-128 From don@brillig.umd.edu Thu Mar 23 19:11:03 1989 Date: Thu, 23 Mar 89 19:11:03 EST To: NeWS-makers@brillig.umd.edu Subject: Active Items From: David Walker Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) I need some of the items (buttons) in an interface to perform some function (e.g. highlight) when the cursor enters them. I think i need to fork a process which looks to see if the cursor has entered an object and perform some action. Is this the correct way to go about it? If anyone has done a similar hack can you tell me what you did and why? Thanks, david walker. davidw@prl.philips.co.uk From don@brillig.umd.edu Fri Mar 24 12:24:43 1989 Date: Fri, 24 Mar 89 12:24:43 EST To: NeWS-makers@brillig.umd.edu Subject: have a cigar shaped window! From: Don Hopkins Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Hurray! Our much awaited Sun 4/110 was safely delivered, and now it's all set up and compiling its own NeWS servers! I feel like passing out cigar-shaped windows! Many thanks to the people at Sun whose made the donation possible, including Jean Griffin-Holst, Michael LoBue, Doug Michel, and others. We really appreciate all the support and enthusiasm for our work, and now that we have the equipment that makes it possible, we're looking forward to doing a lot of things that we could only dream of before. The long wait was hard on my nerves, but it gave me a lot of time to think. Now on to realizing those ideas as PostScript code! -Don From don@brillig.umd.edu Mon Mar 27 18:16:06 1989 Date: Mon, 27 Mar 89 18:16:06 EST To: NeWS-makers@brillig.umd.edu Subject: Re: Class vars or Instance vars, conclusion From: voder!wlbr!mh@ucbvax.Berkeley.EDU (Mike Hoegeman) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) In article <102*knut-skog@rglab.uit.uninett> knut-skog%rglab.uit.uninett@NORUNIX.BITNET (Knut Skog) writes: > >My comments on this issue may have propagated some of >my own confution. My current understanding is >that the values of composite instance variables are >shared dispite being an "instance". > Just as an added note to this discussion, to make a non shared composite instance variable for an object class just create it in the objects "/new" method like this /MyClass ParentObject dictbegin % instance vars... % normally you would put MyNonSharedArrayInstanceVariable here dictend classbegin /new { /new super send begin % we are the instance at this point... /MyNonSharedArrayInstanceVariable [ 1 2 3 4 (five) (six) currenttime /whatever ] def currentdict end } def classend def -mike From don@brillig.umd.edu Mon Mar 27 18:17:07 1989 Date: Mon, 27 Mar 89 18:17:07 EST To: NeWS-makers@brillig.umd.edu Subject: nclock: Yet another NeWS clock program From: spectral!sjs@bellcore.com (Stan Switzer) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Ok, so the last thing anyone needs is yet another NeWS clock, right? Like Bret Thaeler's clock, this one has no client-side code. It uses a different trick to figure out a base reference time, though. Basically, I "forkunix" a shell command which executes "date" and stuffs it back into NeWS using "sendevent" in "psh." Deviant, eh? Of course, this technique can be used to capture the results of any UNIX command for further NeWS processing Try it, maybe you'll like it. Stan Switzer sjs@ctt.bellcore.com ------------ #!/usr/NeWS/bin/psh % % nclock: a clock in NeWS alone % % 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. % systemdict /Midnight known not { /GetDate { % - -> (str) true -or- false { 25 dict begin % fork (to keep events from being confused) /Interest createevent dup begin /Name [ /TimeOut /Date ] def end dup expressinterest def /Timer Interest createevent copy dup begin /Name /TimeOut def /TimeStamp currenttime .25 add def end dup sendevent def (echo "createevent dup begin) ( /Name /Date def /Action (`date`)) append ( def end sendevent" | psh) append forkunix awaitevent dup /Name get /TimeOut eq { pop [ false ] } { Timer recallevent /Action get [ exch true ] } ifelse end } fork waitprocess aload pop } def /GetHHMMSS { % - -> hh mm ss true -or- false GetDate { 3 { ( ) search pop pop pop } repeat ( ) search 4 2 roll pop pop pop 2 { (:) search pop exch pop cvi exch } repeat cvi true } { false } ifelse } def systemdict /Midnight currenttime GetHHMMSS pop 3 -1 roll 60 mul 3 -1 roll add exch 60 div add sub put } if /ClockWin DefaultWindow dictbegin /TickProc null def dictend classbegin ColorDisplay? { /FrameFillColor ColorDict /Firebrick get def } { /FrameFillColor 0 def /KeyFocusColor 1 def } ifelse /ClockShape { % X Y W H -> - 4 2 roll translate scale newpath DrawClock DrawHands } def /ShapeFrameCanvas { gsave ParentCanvas setcanvas FrameX FrameY FrameWidth FrameHeight ClockShape FrameCanvas reshapecanvas grestore } def /PaintFrame { FrameFillColor fillcanvas } def /ShapeIconCanvas { gsave ParentCanvas setcanvas 0 0 IconWidth IconHeight ClockShape IconCanvas reshapecanvas grestore } def /PaintIcon { IconBorderColor fillcanvas } def /PaintFocus { gsave FrameCanvas setcanvas .5 .5 translate KeyFocus? { KeyFocusColor } { FrameFillColor } ifelse setshade 0 0 .5 0 360 arc 0 0 .49 360 0 arcn fill grestore } def /CreateClientCanvas nullproc def /DrawHand { % deg lng wid -> - matrix currentmatrix 4 1 roll .5 .5 translate 3 -1 roll rotate 2 div dup neg dup moveto 0 1 index -.5 mul lineto dup neg lineto 0 exch lineto closepath setmatrix } def /DrawClock { matrix currentmatrix .5 .5 translate 12 { -30 rotate 0 0 .45 117 93 arcn 0 .40 lineto } repeat closepath 0 0 .5 0 360 arc setmatrix } def /DrawHands { currenttime Midnight sub cvi dup 3600 mod 60 div -30 mul .28 .10 DrawHand 60 mod -6 mul .40 .08 DrawHand } def /TimerLoop { createevent dup begin /Name /Timer def /Action /Tick def end dup expressinterest createevent copy dup begin /TimeStamp currenttime dup Midnight sub dup cvi sub 1 exch sub add def end sendevent { awaitevent dup begin /TimeStamp TimeStamp 1 add def end sendevent ShapeFrameCanvas } loop } def /on-off { % bool -> - { TickProc null eq { /TickProc { TimerLoop } fork def } if } { TickProc null ne { TickProc killprocess /TickProc null def } if } ifelse } def classend def { reshapefromuser map true on-off } framebuffer /new ClockWin send send From don@brillig.umd.edu Mon Mar 27 18:30:12 1989 Date: Mon, 27 Mar 89 18:30:12 EST To: NeWS-makers@brillig.umd.edu Subject: blankscreen.ps: NeWS screensaver and lock program. From: spectral!sjs@bellcore.com (Stan Switzer) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) "Blankscreen" is a substitute for the SunView "screenblank" and "lockscreen" programs. Rather than repeat a description here, I refer interested parties to the documentation at the beginning of the program. Be sure to read up to and including the "Warnings" section. Now, if only I had a NeWS "mailtool" clone I'd be one happy camper. Enjoy! Stan Switzer sjs@ctt.bellcore.com ------------ % % BlankScreen: Lights out! % % 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. % % DESCRIPTION: % % BlankScreen quietly monitors your keyboard and mouse for activity, % invoking a screen-saver when there has been no activity in a user- % selectable time period. If, after another user-selectable time period, % there has been no keyboard or mouse activity, BlankScreen quietly enters % a "lock" mode which demands your login password before releasing your % workstation. % % At invocation, the variables /BlankTime and /LockTime control the amount % of idle time that causes blanking and amount of blanked time that leads % to locking. Changing these values later has no effect (to protect against % accidents). The default times for these values are three minutes % and two minutes respectively. If you find locking objectionable, you % can disable it by setting /LockTime to 0. % % When blankscreen is restarted, it kills any other running (but % unlocked) blankscreen processes. This allows you to change the % timer parameters without compromising the security of the % locking function. % % If /BlankFKey is defined, it is the name of a function key to use to % blank the screen on demand. Similarly for /LockFKey. I use the following: % /BlankFKey /FunctionF6 def /LockFKey /FunctionF7 def % % The poem can be changed by assigning a different array of strings % to /Poetry before invoking blankscreen. A value of "null" disables % the poetry entirely. % % The colors used in the blanking display can be changed by assigning values to % the appropriate variables before invocation. Interested parties should % look at the first few lines of source. % % WARNINGS: % % This program checks passwords by trying to connect to your FTP % server (yes, this is a hack). You would do well to see if you can % "ftp localhost" before you begin using this program. % % Additionally, either (USER) or (LOGNAME) must be in the environment % for the locking mode to know who you are. % % If either of these two assumptions fails to hold, setting "LockTime" % to 0 disables automatic locking, thus avoiding the problem. % % Because this program goes to great lengths to defeat the keyboard focus % manager, it depends on things perhaps that might easily change from one % release on NeWS to another. I only know for sure that it works in % NeWS 1.1 with a Sun-3 keyboard. % % Finally, "forkunix" must work (I don't know about non-UNIX NeWS % implementations) and there must be a reasonably standard "date" % command. % % NeWS Notes: % % Apparently, mouse transitions caught by a non-canvas specific and % non-exclusive interests do not require redistribution, but key transitions % do. Since this seems much too arbitrary, I use an exclusive % interest and redistribute everything. Probably, I should be registering % interests relative to a framebuffer overlay instead of a null canvas. % % Interests having dictionaries of procs for both their Name and Action % do not execute either procedure but instead return both an event and array % from awaitevent. The array contains the two procedures that should have % been executed. Maybe I should have been using "forkeventmgr" anyway to % avoid all of this hassle (then again, for security reasons, maybe not). % % There are certain interesting techniques in here that you may feel free % to borrow. My favorite is the "condition" handler. A close runner-up % is the FTP password hack (thanks Don) and the date query. Please % do not use the keyboard handling as a model for input handling since % this code intentionally subverts the very mechanisms you should % generally be using. % % ------------ % Stan Switzer sjs@ctt.bellcore.com % % 3/27/89 - SJS % Release 1.0 % Start a new dictionary here to prevent patching the locking code, prevent % unauthorized access to the /Password entry, and to avoid systemdict % namespace polution. 100 dict begin { end } pop % { end } pop is to fool formatters! /default { % key val -> - def into current dictionary, val is default 1 index where { 2 index get exch pop } if def } def /BlankTime 180 default /LockTime 120 default /Testing? false def % /Testing? true def /conprint { pop pop } def /Conprint { sprintf console exch writestring console flushfile } def % /conprint /Conprint load def /SC { % key grayshade pastelhue-or-color -> - set color dup type /colortype ne { .35 1 hsbcolor } if % pastel hue ColorDisplay? not 3 1 roll ifelse dup type /colortype ne { dup dup rgbcolor } if % gray value default } def /BlankColor 0 0 0 0 rgbcolor SC /HourColor 1 .5 SC /MinColor 1 .5 SC /ClockColor 1 .5 SC /TextColor 1 .5 SC /QuoteColor 1 .5 SC % Generally, I prefer that users wishing to change the displayed verses do % so by defining the new verses before "running" this file. This way, we % can avoid unnecesary speciation of this program. /Poetry [ (`The time has come', the Walrus said,) ( `To talk of many things:) % (Of shoes\320and ships\320and sealing wax\320) (Of shoes\0\320and ships\320and sealing wax\320) % "\0"? see below! ( Of cabbages\320and kings\320) (And why the sea is boiling hot\320) ( And whether pigs have wings.') ( \320 Lewis Carroll) ] default % It is a complete mystery to me why, but sometimes (not always) % the dash after "shoes" does not display! Somehow, the \0 seems to avoid % the problem, but I'm stumped why it would. It appears to be a scanner % bug because "Poetry 2 get ==" shows a \0 instead of a \320. All attempts % to isolate the problem in a simpler program fail to manifest the bug. % Now here's the wierd thing: If I comment out the line with the "\0", % uncomment the one without it, and reverse them (putting the now % commented-out line first), the dash shows! Then, if I delete the % comment, the dash doesn't show! In fact, virtually any change % immediately before the line in question makes the bug go away. % Update: prior to posting, I modified the prefatory comments, and now % the bug does not appear. Present theory is that scanner breaks % when \nnn crosses a psio buffer boundary. % We are going to be paranoid and hoist certain non-operator procs to % this private dictionary to prevent insertion of trojan horses in the % password collection and checking logic. I know of a few holes here, but % I don't see the point of documenting them, if you get my drift. Still, % considering how "append," for instance, is used in here, it is only % prudent to protect ourselves. /CopyProc { % proc -> proc' dup type /arraytype eq { % array? dup xcheck exch 0 exch { % forall -- exec? n item CopyProc exch 1 add } forall array astore exch { cvx } if } if } def [ /append ] { % hoist these global procs ... dup load CopyProc def } forall /GetDate { % - -> (str) true -or- false { 25 dict begin % fork (to keep events from being confused) /Interest createevent dup begin /Name [ /TimeOut /Date ] def end dup expressinterest def /Timer Interest createevent copy dup begin /Name /TimeOut def /TimeStamp currenttime .25 add def end dup sendevent def (echo "createevent dup begin) ( /Name /Date def /Action (`date`)) append ( def end sendevent" | psh) append forkunix awaitevent dup /Name get /TimeOut eq { pop [ false ] } { Timer recallevent /Action get [ exch true ] } ifelse end } fork waitprocess aload pop } def % GetDate stack /GetHHMMSS { % - -> hh mm ss true -or- false GetDate { 3 { ( ) search pop pop pop } repeat ( ) search 4 2 roll pop pop pop 2 { (:) search pop exch pop cvi exch } repeat cvi true } { false } ifelse } def % GetHHMMSS /Midnight { Midnightproc waitprocess pop /Midnightproc null store Midnight } def /Midnightproc { /Midnight currenttime GetHHMMSS % try again if it didn't work (maybe server wasn't started yet) true { GetHHMMSS } ifelse { % worked? 3 -1 roll 60 mul 3 -1 roll add exch 60 div add sub store true } { % not worked? pop pop false } ifelse } fork def /NeWSLogoThing Object dictbegin dictend classbegin /Font /Times-Roman findfont 92 scalefont def /String (NeWS) def /Verses Poetry def /NVerses Verses null eq { 0 } { Verses length } ifelse def /Poetry? NVerses 0 gt def /ClockRad Poetry? 46 36 ifelse def /MinHand ClockRad 7 sub def /HourHand ClockRad 20 sub def /Vfont /Times-Roman findfont 14 scalefont def /LogoUp Poetry? 19 0 ifelse def /VerseNo 0 def /Verse { Verses VerseNo dup 0 lt 1 index NVerses ge or { pop /VerseNo 0 store 0 } if get } def /InitVerse { /VerseNo -1 store } def /NextVerse { /VerseNo VerseNo 1 add store } def /PaintHand { % deg r -> - exch gsave rotate -4 -4 moveto 4 -4 lineto 0 exch lineto closepath fill grestore } def /PaintClock { % x y -> - gsave translate ClockColor setcolor gsave 12 { 30 rotate -2 ClockRad moveto 4 0 rlineto -2 -6 rlineto closepath fill } repeat grestore currenttime Midnight sub cvi dup 3600 mod 60 div HourColor setcolor -30 mul HourHand PaintHand MinColor setcolor 60 mod -6 mul MinHand PaintHand grestore } def /GSave { gsave Font setfont TextColor setcolor } def /size { GSave String stringwidth pop ClockRad 2 mul add Font fontascent LogoUp add grestore } def /paint { GSave currentpoint ClockRad add exch ClockRad add exch PaintClock ClockRad 2 mul 0 rmoveto gsave 0 LogoUp rmoveto String show grestore Poetry? { Vfont setfont QuoteColor setcolor Verse show } if grestore } def classend def /TheThing /new NeWSLogoThing send def /ThingX null def /ThingY null def % Thing stuff from the menu package ... /ShowThingDict dictbegin LiteMenu /&ShowThingDict get /def load forall dictend def /ThingSizeDict dictbegin LiteMenu /&ThingSizeDict get /def load forall dictend def /IconString { icondict exch get cvis } def /ThingSize { ThingSizeDict begin gsave dup type exec end grestore .5 add cvi exch .5 add cvi exch } def /ShowThing { gsave currentpoint translate ShowThingDict begin dup type exec end grestore } def % GetUserid: -> % false -- didn't work % (userid) true -- got user id /GetUserid { (USER) { getenv } stopped { pop (LOGNAME) { getenv } stopped { pop false } true ifelse } true ifelse } def % Check password using ftp server (Don Hopkins thought of using FTP). % % CheckPW: (userid) (password) -> % false -- check didn't work % ok? true -- OK? is true iff PW is correct % % NOTE: we wish to distinguish failure of the checking procedure from % failure of the check itself. /CheckPW { { 25 dict begin /Password exch def /User exch def /S (%socketc21) (rw) file def % socket /R { S exch readline } def % str -> str -- read from socket /W { S exch writestring S flushfile } def % str -> - -- write socket /SR { % (good) (bad) timeoutsec -> good? true -or- false -- srch /Time exch 60 div def /Interest createevent dup begin /Name /DoneEvent def end dup expressinterest def /Bad exch def /Good exch def /Match1 { anchorsearch { pop pop true } { pop false } ifelse } def /Match { dup type /arraytype eq { { Match1 { true exit } if } forall } { Match1 } ifelse } def /Str 200 string def /Proc { % fork { % loop Str R not { /Ugly exit } if dup Good Match { /Good exit } if dup Bad Match { /Bad exit } if pop } loop exch pop Interest createevent copy dup /Action 4 -1 roll put sendevent } fork def /Timer Interest createevent copy dup begin /Action /TimeOut def /TimeStamp currenttime Time add def end dup sendevent def awaitevent /Action get dup /TimeOut eq { Proc killprocess pop /Ugly } if dup /Ugly eq { Timer recallevent pop false } { /Good eq true } ifelse Interest revokeinterest } def { % only once through: (220 ) (xxx ) 15 SR not { false exit } if not { false exit } if (user ) User append (\n) append W (331 ) [ (530 ) (500 ) ] 15 SR not { false exit } if not { false exit } if (pass ) Password append (\n) append W (230 ) [ (530 ) (500 ) ] 20 SR not { false exit } if true exit } loop dup 2 1 ifelse array astore (quit\n) W S closefile end } fork exch pop exch pop waitprocess aload pop } def /UserID GetUserid not (Unknown User) if def Testing? { /win framebuffer /new DefaultWindow send def /reshapefromuser win send /map win send /CanvasToBlank /ClientCanvas win send def } { /CanvasToBlank framebuffer def } ifelse /CoverCanvas { % canvas => canvas' gsave dup setcanvas newcanvas dup begin /Transparent false def /Retained false def /Mapped false def end clippath dup reshapecanvas /nouse /nouse_m 2 index setstandardcursor grestore } def /Blanket CanvasToBlank CoverCanvas def /QueryW 350 def /QueryH 85 def /QueryR 10 def /QueryMessage () def /QueryFont /Times-Roman findfont 18 scalefont def /QueryCanvas gsave Blanket dup setcanvas newcanvas dup begin /Transparent false def /Retained false def /Mapped false def end clippath pathbbox 4 2 roll pop pop exch QueryW sub 2 div exch QueryH sub 2 idiv translate QueryR 0 0 QueryW QueryH rrectpath dup reshapecanvas grestore def /PWstring 100 string def /PWpos 0 def /Password () def /AddPW { PWpos PWstring length lt { PWstring PWpos 3 -1 roll put /PWpos PWpos 1 add store /Password PWstring 0 PWpos getinterval store } { pop } ifelse % Thanks Don } def /DelPW { /PWpos PWpos 1 sub 0 max store /Password PWstring 0 PWpos getinterval store } def /ClearPW { /PWpos 0 store /Password PWstring 0 PWpos getinterval store 0 1 Password length 1 sub { Password exch 0 put } for % zero PW string } def /State null def /seconds { 60 div } def /Member? { % item array -> bool false 3 1 roll { % forall 1 index eq { exch pop true exch } if } forall pop } def /Secure? { State { /Lock /Query /Check } Member? } def % Timer while in state: /StateTimes 10 dict dup begin /Sleep 15 BlankTime 2 div min seconds def /Monitor BlankTime seconds def /Blank 3 seconds def /Lock Blank def /Query Blank def /Check Blank def end def /Conditions [ dictbegin % Keyboard and mouse monitoring: /Condition { State { /Monitor /Blank /Lock } Member? } def /Enter { MonitorInterests /expressinterest load forall } def /Leave { MonitorInterests /revokeinterest load forall } def dictend dictbegin % Screen is blanked: /Condition { State { /Blank /Lock /Query /Check } Member? } def /Enter { /InitVerse TheThing send MoveThing Blanket canvastotop Blanket /Mapped true put /BlankCount 0 store } def /Leave { Blanket /Mapped false put } def /Remain { Blanket canvastotop MoveThing } def dictend dictbegin % Querying: /Condition { State /Query eq } def /Enter { ClearPW /QueryMessage (Enter Password.) store QueryInterests /expressinterest load forall /QueryCount 0 store } def /Leave { QueryInterests /revokeinterest load forall } def dictend dictbegin % Checking: /Condition { State /Check eq } def /Enter { /QueryMessage (Checking Password.) store RepaintQuery CheckInterest expressinterest } def /Leave { CheckInterest revokeinterest } store dictend dictbegin % Querying or checking: /Condition { State { /Query /Check } Member? } def /Enter { QueryCanvas /Mapped true put } def /Leave { QueryCanvas /Mapped false put ClearPW } def dictend ] def % General-purpose condition handler: monitors changes to boolean conditions % and invokes associated handling routines. /HandleConditions { 0 begin Conditions { % forall begin /Value Condition def % eveluate condition Prev Value { { True Same Remain Was } % Is and was { True Different Enter WasNot } % Is and was not } { { False Different Leave Was } % Is not and was { False Same Desists WasNot } % Is not and was not } ifelse ifelse /Prev Value def end } forall end } dup 0 dictbegin /Prev false def % initial value of the condition /Condition {false} def % Condition check proc { /True /False /Enter /Leave /Same /Different /Remain /Desists /Was /WasNot } { nullproc def } forall dictend put def % time to lock: /LockSteps LockTime seconds StateTimes /Lock get idiv def /BlankCount 0 def % time to query: /QueryTime 30 seconds def /QuerySteps QueryTime StateTimes /Query get idiv def /QueryCount 0 def % Change to a new state: /newState { % state -> - (>> % -> %\n) [ State 3 index ] conprint /State exch store HandleConditions TimerEvent dup /IsQueued get { dup recallevent } if dup /TimeStamp StateTimes State get pause currenttime add put sendevent } def /MoveThing { gsave Blanket setcanvas clippath pathbbox 4 2 roll pop pop /size TheThing send 3 -1 roll exch sub random mul cvi 3 1 roll sub random mul cvi exch /ThingY exch store /ThingX exch store /NextVerse TheThing send PaintBlanket grestore } def /PaintBlanket { BlankColor fillcanvas ThingX ThingY moveto /paint TheThing send } def /RepaintBlanket { gsave Blanket setcanvas PaintBlanket grestore } def /RepairBlanket { gsave Blanket setcanvas damagepath clipcanvas PaintBlanket newpath clipcanvas grestore } def /PaintQuery { 1 fillcanvas QueryFont setfont 0 setshade 12 60 moveto (Userid: ) show UserID show 12 40 moveto (Password: ) show % Password show (#%*&@!%&@#X?#No!*NeWS!*%$#@$@!) % cryptic missive dup length 0 exch PWpos min getinterval show 2 0 rmoveto 5 -5 rlineto -11 0 rlineto closepath fill 30 15 moveto QueryMessage show } def /RepaintQuery { gsave QueryCanvas setcanvas PaintQuery grestore } def /RepairQuery { gsave QueryCanvas setcanvas damagepath clipcanvas PaintQuery newpath clipcanvas grestore } def /ScreenBlank { % What to do when the timer expires: /TimerInterest createevent dup begin /Name 2 dict dup begin /Timer { State { % case /Sleep { /Monitor newState } /Monitor { /Blank newState } /Blank { /BlankCount BlankCount 1 add store BlankCount LockSteps gt LockTime 0 ne and /Lock /Blank ifelse newState (>> Count % %\n) [ BlankCount LockSteps ] conprint } /Lock { /Lock newState } /Query { /QueryCount dup load 1 add store QueryCount QuerySteps gt /Lock /Query ifelse newState (>> QCount % %\n) [ QueryCount QuerySteps ] conprint } } case } def end def end dup expressinterest def % External control: /ControlInterest createevent dup begin /Name /BlankScreen def /Action 5 dict dup begin /Destroy { Secure? not { currentprocess killprocessgroup } if } def /BlankOrLock { State { % case /Sleep { /Blank newState } /Default { /Lock newState } } case } def /Blank { Secure? not { /Blank newState } if } def /Lock { /InitVerse TheThing send /Lock newState } def /Query { /Query newState } def end def end dup expressinterest def % We clone this event from the interest to get the /Process value: /TimerEvent TimerInterest createevent copy dup begin /Name /Timer def end def /MonitorInterests [ createevent dup begin /Priority 20 def /Exclusivity true def /Action 1 dict dup begin /DownTransition { Secure? { /Query newState } { dup redistributeevent pause /Sleep newState } ifelse } def end def end createevent dup begin /Priority 5 def /Name 1 dict dup begin /MouseDragged { Secure? { /Query newState } { /Sleep newState } ifelse } def end def end ] def /DamageInterest createevent dup begin /Name 1 dict dup begin /Damaged { RepairBlanket } def end def /Canvas Blanket def end dup expressinterest def % It is important to understand that this is THE HARD WAY to get keyboard % input and it is done this way solely to subvert the focus manager. % Normally, you would want to cooperate with the focus manager and use % addkbdinterests (which is MUCH simpler). /QueryInterests [ createevent dup begin /Name 1 dict dup begin /Damaged { RepairQuery } def end def /Canvas QueryCanvas def end createevent dup begin /Priority 20 def /Name ascii_keymap def /Action 2 dict dup begin /DownTransition { /QueryCount 0 store dup /Name get dup 32 ge 1 index 127 lt and { dup AddPW RepaintQuery } if dup 8 eq 1 index 127 eq or { DelPW RepaintQuery } if dup 10 eq 1 index 13 eq or { /Check newState { UserID Password ClearPW CheckPW not false if CheckInterest createevent copy begin /Name /PWresult def /Action exch def currentdict end sendevent } fork pop } if pop } def end def /Exclusivity true def end createevent dup begin % Handle shifts here % priority below key processing /Priority 19 def /Name 20 dict dup begin keyboard_positions { % forall dup 0 get type /arraytype ne { [ exch ] } if % Name [ [key class] [key class] ... ] { % forall aload pop /shift_key ne { pop } { % Name key [ /dup cvx UI_private /begin cvx 5 index /do_shift_key cvx /end cvx ] cvx % Name key { dup D begin Name do_shift_key end } def % in /Name entry of this this interest } ifelse } forall pop } forall end def /Exclusivity true def end createevent dup begin % absorb all other KB input % priority below shift processing /Priority 18 def /Exclusivity true def /Action /DownTransition def end ] def /CheckInterest createevent dup begin /Name 1 dict dup begin /PWresult { dup /Action get /Sleep /Lock ifelse newState } def end def /Canvas QueryCanvas def % avoid fraud! end def /Sleep newState { % Event processing loop: awaitevent dup type /arraytype eq { /exec load forall } if (>> Event % % % -> %\n) exch [ exch begin Name Action Canvas end State ] conprint } loop } def % kill our illustrious predecessors createevent dup begin /Name /BlankScreen def /Action /Destroy def end sendevent /BlankFKey where { pop BlankFKey { createevent dup begin /Name /BlankScreen def /Action /Blank def end sendevent } bindkey } if /LockFKey where { pop LockFKey { createevent dup begin /Name /BlankScreen def /Action /Lock def end sendevent } bindkey } if % let the dust settle before we enter the fray! pause pause BlankTime 0 ne { { newprocessgroup ScreenBlank } fork pop } if { begin } pop end % do it this way to fool formatters! From don@brillig.umd.edu Mon Mar 27 19:27:22 1989 Date: Mon, 27 Mar 89 19:27:22 EST To: NeWS-makers@brillig.umd.edu Subject: Wallpaper for The Mind From: pterodactyl.cis.ohio-state.edu!zwicky@tut.cis.ohio-state.edu (Elizabeth D Zwicky) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) This version *really* makes all its windows disappear when you Zap it. Or at least I sincerely believe so, and it works for me. The attached NeWS program colors in a window that you give it, basing the color of each dot on the result of an equation in x and y for that dots x and y coordinates. On a monochrome screen, it makes the dot black if the equation's result is odd, and white if it is even; on a color screen it mods the result by six, and uses that to pick a color. You can change the portion of the plane you are looking at, zoom in or zoom out, add and remove detail on the portion you are looking at, and change the dot size, not to mention being able to specify the equation it uses. You can't yet get some idea of what you've set any parameter but the equation to. Yes, if you're sufficiently clever you can do the Mandelbrot set, but it will take you a ***VERY*** long time. Elizabeth D. Zwicky (zwicky@cis.ohio-state.edu) -----------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 .2 rgbcolor def /Yellow 1 1 0 rgbcolor def /Purple .7 0 1 rgbcolor def /Orange 1 .5 0 rgbcolor def /colors [Red Orange Yellow Green Blue Purple] def /startx{1} def /starty{1} def /div*{ dup 0 eq {pop pop 0}{div}ifelse}def /magnify 1 def /scalefactor 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 /called false 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 gsave colorcanvas {colors function cvi 6 mod abs get setcolor dot} {function cvi 2 mod abs 1 eq {dot} if} ifelse grestore }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 2 setlinecap 1 setlinewidth scalefactor scalefactor scale clipcanvaspath pathbbox /height exch store /width exch store /width width scalefactor div truncate 1 add scalefactor mul store /height height scalefactor div truncate 1 add scalefactor mul store 0 setgray 0 0 moveto /realx startx def /realy starty def square } def /FrameLabel (Wallpaper) def /destroy{ % Kill subwindows /called true store /destroy formulawindow send first not {/destroy helpwindow send} if % Will die even during redraw PaintProcess null ne { PaintProcess killprocessgroup} if FrameEventMgr null ne { FrameCanvas /Mapped false put FrameEventMgr killprocessgroup} if currentprocess killprocessgroup } def /ClientMenu [ (Zoom In) {/magnify magnify 2 mul store /paint paperwindow send} (Zoom Out) {/magnify magnify 2 div store /paint paperwindow send} (Scale Up) {/scalefactor scalefactor 2 mul store /paint paperwindow send } (Scale Down) {/scalefactor scalefactor 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 { /destroy{ /unmap formulawindow send called not {/destroy paperwindow send} if } def } 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 } 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 Mon Mar 27 19:29:28 1989 Date: Mon, 27 Mar 89 19:29:28 EST To: NeWS-makers@brillig.umd.edu Subject: extension of tee? ("wy?") From: Don Hopkins Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) I'd like a version of tee ("wy?") that instead of writing to an output file, writes to a process. Its arguments would be the name of a process to run and its args. It should run a shell to parse the args, if necessary. The stuff wy reads from its stdin should be written to its stdout, and to a pipe connected to the stdin of the process. The process's stdout should be the same file as wy's stdout, unless the command redirects the process's output with the shell. Show an rwho, then the word count, all piped through more: rwho | wy wc | more Cat smut auditing: alias cat "\cat \!:* | wy grep -i sex \> .dirt" Lots of other uses. I'll leave it to your imagination. Has anybody written something like this of general utility? Is there a simple way to do it with the shell? I want to use this in conjunction with a simple program called "pshexec", which loads a PostScript program into the NeWS server through a socket, connects stdin and stdout up to the same NeWS server socket, then exec's a Unix program. The program can be a command line driven program, or a shell script. The Unix process's stdout is connected to NeWS process's stdin, whose stdout is connected back to the Unix process's stdin. (Too bad tftp already has that port number!) Given a pre-existing command line driven program, you can program NeWS to interpret the Unix process's output (which could be piped through other Unix processes, i.e. awk), and to send command lines to the Unix process's input when you press buttons, select from menus, fill out forms, drag things around, etc... NeWS can process all the low level user input, and write strings of high level commands to the Unix process's input. Or you can write a shell script on the Unix side that reads and interprets NeWS's output, echos PostScript commands back to NeWS, and invokes programs that output PS code. The protocol is totally arbitrary and application specific. NeWS could be talking to a shell script, awk, a Lisp interpreter, a C program, a fortran program, an nntp server, a bunch of processes piped together, image processing filters, kermit, pearl, another NeWS server, whatever... With the right tools, on the NeWS side and the Unix side, it would very easy to build graphical NeWS interfaces to Unix programs, using your favorite filters and pipes in the grand tradition of Unix, and good old command line driven programs that work on dumb terminals, without any stinking event dispatch loops! Also, has anybody done anything with a remote "process server" or "pumping station" or "socket manager"? You could run one under your uid on every machine on the network you wanted to use, and it would serve as your "liaison" on that machine. You'd be able to connect to it over the network, and tell it to open files, make network connections, listen for connections on ports, set environment variables, fork off (and popen) unix processes, and send signals to them, and then have it make connections between the resulting file descriptors, and pump bytes back and forth. You should be able to change the connections dynamically, and tell it to start and stop pumping bytes on various channels. You should be able to ask it for status information about the channels, like how many bytes have been pumped, how much input is available for reading, the buffer size, etc... You could connect to it over a control port to give commands, but when you wanted to pump data back and forth, you just connect to it yourself or tell it to connect to you, over another socket. One feature I'd really like is the ability to tell it to pump bytes, until it sees a particular regular expression in the stream, at which point it (optionally) turns off the pump, and sends an event (i.e. writes some string on some other socket). The event strings should undergo re-replacement. i.e.: When you see /^"\([^"]\), line \([0-9]+\): \(.*\)$/ on file 4, write /(\1) \2 (\3) signal-error\n/ on file 5, and stop pumping. Where you might be running a compile on the other end of file 4, whose error messages look like: "foo.c", line 47: syntax error ...And you might have a NeWS source debugger server on the other end of file 5, whose commands look like: (foo.c) 47 (syntax error) signal-error ...Any ideas or references or pointers to anonymous ftp directories? -Don From don@brillig.umd.edu Tue Mar 28 05:27:20 1989 Date: Tue, 28 Mar 89 05:27:20 EST To: NeWS-makers@brillig.umd.edu Subject: wy.c and pshexec.c From: siegel@hc.dspo.gov (josh Siegel) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) The remote server will be built into the mini-NeWS... I will post the pieces you need in the next day or two. --Josh Siegel To compile: % cc -o wy wy.c % cc -o pshexec pshexec.c to run: % cat /etc/termcap | wy wc > o (the bottom of 0 will have the word count) % pshexec popup.ps ls #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh 'popup.ps' <<'END_OF_FILE' X% Example by Don Hopkins X X{ currentcursorlocation X [ ($@ $0 $1 $2 $3 $4 $5 $6 $7 $8 $9) X { currentfile 80 string readline not { exit } if } loop X ] popmsg pop } Xexec END_OF_FILE if test 171 -ne `wc -c <'popup.ps'`; then echo shar: \"'popup.ps'\" unpacked with wrong size! fi # end of 'popup.ps' fi if test -f 'pshexec.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'pshexec.c'\" else echo shar: Extracting \"'pshexec.c'\" \(2437 characters\) sed "s/^X//" >'pshexec.c' <<'END_OF_FILE' X X/* X * Written by Josh Siegel X * siegel@hc.dspo.gov X * X * Mon Mar 27, 1989 X * X * Does ${0-9} substitution as well as $@ X * X */ X X X#include X#include X#include X#include X#include X#include X#include X#include X#include X Xchar cwd[MAXPATHLEN]; X Xmain(argc, argv) X int argc; X char *argv[]; X{ X int ns; X X X ns = open_news(); X if (ns < 0) { X perror("phone"); X exit(0); X } X X X dump_out(ns, argv[1],argv,argc); X X dup2(ns, 1); X dup2(ns, 0); X execvp(argv[2], &argv[2]); X} Xdump_out(news, file,argv,argc) X int news,argc; X char *file; X char *argv[]; X{ X struct stat fbuf; X int n, fd; X register char *buf,*p,*p2; X X getwd(cwd); X X n = stat(file, &fbuf); /* st_size */ X X if (n != 0) { X perror("stat"); X exit(0); X } X buf = (char *) malloc(fbuf.st_size); X X fd = open(file, O_RDONLY); X if (fd < 0) { X perror(file); X exit(0); X } X n=read(fd, buf, fbuf.st_size); X buf[n] = '\0'; X close(fd); X X p2 = p = buf; X while(1) { X while(*p2!='$' && *p2!='\0') X p2++; X write(news, p, p2-p); X if(*p2=='\0') X break; X p2++; X if(*p2>='0' && *p2 <= '9') { X if(*p2-'0'+2 < argc) X write(news,argv[*p2-'0'+2],strlen(argv[*p2-'0'+2])); X } X else X switch(*p2) { X case '@': X write(news,cwd,strlen(cwd)); X break; X default: X write(news,p2-1,2); X break; X } X p2++; X p = p2; X } X X free(buf); X} X/* X Phone: Connects to a established port setup by accept(). X*/ Xopen_news() X{ X char *p, *p2, *p3; X int news; X X p = (char *) getenv("NEWSSERVER"); X X if (p) { X p2 = (char *) index(p, '.') + 1; X p3 = (char *) index(p2, ';'); X *p3++ = '\0'; X news = phone(atoi(p2), p3); X } else X news = phone(2000, "localhost"); X X if (news < 0) { X perror("phone"); X exit(0); X } X return (news); X} Xphone(port, host) X int port; X char host[]; X{ X X struct sockaddr_in sin; X struct servent *sp; X struct hostent *hp; X int s, *p; X char buff[255]; X X bzero((char *) &sin, sizeof(sin)); X X sin.sin_port = port; X X hp = gethostbyname(host); X X if (hp == NULL) X return (-1); X X bcopy(hp->h_addr, (char *) &sin.sin_addr, hp->h_length); X sin.sin_family = hp->h_addrtype; X s = socket(AF_INET, SOCK_STREAM, 0); X if (s < 0) X return (-1); X X if (connect(s, &sin, sizeof(sin)) < 0) { X close(s); X return (-1); X } X return (s); X} END_OF_FILE if test 2437 -ne `wc -c <'pshexec.c'`; then echo shar: \"'pshexec.c'\" unpacked with wrong size! fi # end of 'pshexec.c' fi if test -f 'wy.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'wy.c'\" else echo shar: Extracting \"'wy.c'\" \(384 characters\) sed "s/^X//" >'wy.c' <<'END_OF_FILE' X/* X * Written by Josh Siegel X * siegel@hc.dspo.gov X * X * Mon Mar 27, 1989 X */ X Xmain(argc,argv) Xint argc; Xchar *argv[]; X{ X int fildes[2],n; X char buff[4096]; X X pipe(fildes); X X if(fork()) { X close(fildes[0]); X while(n=read(0,buff,sizeof(buff))) { X write(1,buff,n); X write(fildes[1],buff,n); X } X } else { X close(fildes[1]); X dup2(fildes[0],0); X execvp(argv[1],&argv[1]); X } X} END_OF_FILE if test 384 -ne `wc -c <'wy.c'`; then echo shar: \"'wy.c'\" unpacked with wrong size! fi # end of 'wy.c' fi echo shar: 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 Wed Mar 29 13:13:37 1989 Date: Wed, 29 Mar 89 13:13:37 EST To: NeWS-makers@brillig.umd.edu Subject: pan/zoom utility From: aramis.rutgers.edu!kish@rutgers.edu (Bill Kish) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Is there a utility written for NeWS which will take a PostScript file and perform pan and zoom operations on it ? Thanks, Bill Kish email: kish@jove.rutgers.edu From don@brillig.umd.edu Thu Mar 30 11:38:55 1989 Date: Thu, 30 Mar 89 11:38:55 EST To: NeWS-makers@brillig.umd.edu Subject: Improved PlaneWindow From: dennis!dennis@boulder.colorado.edu Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Some time ago I posted the code for PlaneWindow, which provides the illusion of a window over a larger window. It provided the ability to pan/scroll/zoom over that larger window. That code had some errors in it, most notably that it had a cyclic reference so that when the window was killed, the window didn't disappear from the screen. The following version corrects that problem. ================================================== systemdict /LiteWindow known not { (NeWS/litewin.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 canvas over 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 origin 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. /PlaneWindow ScrollWindow dictbegin % 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] } def /Yrange { [minY maxY PlaneHeight .01 mul round PlaneHeight .1 mul round null] } 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 => - % 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 % deltax/2 deltax/2 maxX add % deltax/2 maxX+deltax/2 /maxX exch store % deltax/2 minX exch sub /minX exch store } { pop } ifelse ClientHeight PlaneHeight sub dup 0 gt { % deltay 2 div 0.5 add truncate dup maxY add /maxY exch store minY exch sub /minY exch store }{ pop } ifelse rerange } def /SetPlaneScale { % scalex scaley => - /ScaleY exch store /ScaleX exch store /ClientFont ClientFont ScaleX ScaleY min 16 mul 0.5 add truncate scalefont store redisplay } def /reshape { % x y w h => - /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 origin 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 { /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 % Remove the cycle induced by the MyPlane % variable added to the Scrollbars. % Thanks to Tom Sheffler of Mitre for pointing this out. /destroy { {/MyPlane null store} HScrollbar send {/MyPlane null store} VScrollbar send /destroy super send } def classend def pause % 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 } def /PaintClient { /PaintClient super send PaintBackGround } def /PaintBackGround { % - => - gsave ClientCanvas setcanvas minX neg minY neg translate PlaneWidth PlaneHeight scale BackGround null ne { BackGround imagecanvas pause } if 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 % (note, this is same as framebuffer size, so no dithering occurs, % 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 (./picture) /SetBackGround testwin send /map testwin send From don@brillig.umd.edu Thu Mar 30 11:44:54 1989 Date: Thu, 30 Mar 89 11:44:54 EST To: NeWS-makers@brillig.umd.edu Subject: controlwindow without circularities From: dennis!dennis@boulder.colorado.edu Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) This is newer version of the ControlWindow that I posted some months ago. The main difference is that it has all of the circular references removed (I hope). It requires the PlaneWindow that I also (re-)posted very recently (i.e., today). ================================================== systemdict /PlaneWindow known not { (planewindow.ps) run } if systemdict /Item known not { (NeWS/liteitem.ps) run } if %-------------------------------------------------- % 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 /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 { % - => - (destroy frame control canvases/items) % break all outstanding cycles {removefocus /ReaderClient null store} Reader send /ReaderAction null store /Display null store /Reader null store MsgWinEventMgr dup null ne {killprocess} if /MsgWinEventMgr null store /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 /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 /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 /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 /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 { /ItemLabel exch store paint location ItemWidth ItemHeight reshape paint } 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 { 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. /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 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % 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 ClientFont setfont 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 /destroy { /ClientMenu null store /destroy super send } def 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 Fri Mar 31 19:51:38 1989 Date: Fri, 31 Mar 89 19:51:38 EST To: NeWS-makers@brillig.umd.edu Subject: Re: OPEN LOOK Availability From: mcvax!unido!nixctc!pete%relay.nixctc.de@uunet.uu.net (Pete Delaney at Nixdorf Cim Technology Center) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) In article <8903291906.AA10842@ATHENA.MIT.EDU>, ruthlk@attunix.att.COM writes: > Path: nixctc!unido!mcvax!uunet!lll-winken!ames!mailrus!tut.cis.ohio-state.edu!bloom-beacon!attunix.att.COM!ruthlk > > I'd just like to provide the correct information about OPEN LOOK availability: > 1) An OPEN LOOK Beta distribution has been available since Jan. > Information about the OPEN LOOK beta program was posted to this > net several months ago. All companies, not just UNIX International > companies, have been able to participate in the beta program. Is that just the ATT OPEN LOOK toolkit or also the X11/NeWS Merge that has been available since Jan? I have been having difficulty getting a clear picture of the X11/NeWS merge project. > 2) General Availability of the OPEN LOOK source is > 3/31/89. (This Friday!!) I've talked to Christina Hahn at AT&T Unix Europe this week and she provided Licensing Terms for the AT&T OPEN LOOK GUI source product, with a Source Fee of $1,000. Is it safe to assume this is all that is being made available on 3/31/89? What about the NeWS/X11 merge? Also, the AT&T product sheet quotes a XWIN product that appears to be the MIT/DEC X11R3 with support for VGA and CGA on the 386 port, for just :-) $17,000. From don@brillig.umd.edu Sun Apr 2 17:29:52 1989 Date: Sun, 2 Apr 89 17:29:52 EDT To: NeWS-makers@brillig.umd.edu Subject: Re: OPEN LOOK Availability From: mcvax!unido!nixctc!pete@uunet.uu.net (Pete Delaney) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) In article <1627@iesd.dk> fischer@iesd.dk (Lars P. Fischer) writes: > >I seem to remember from a Sun briefing that this has been renamed >"Xview" (to emphasize that it is not tied to Sun), and that it will be >donated to MIT, for free distribution on the X tape. It should be >ready for distribution "sometime this spring..". > >Anyone care to comment? That sounds like what the a Sun technical support guru told me the-week-before-last while at the Hannover Fair. Unfortunately however I was unable to confirm it with Michael Arden (the Product Manager for NeWS). Her secetrary was able to send out a NeWS license form for $25,000 however I was hopeing the technical support guru at Hanover was correct. With this stupid OSF vs. UNIX Incorporated nonsense going on, I doubt I could get my management to sign off on a $25,000 license; and with X windows being accepted so well by the market I doubt the guys at Sun expect to sell many more of these $25k licenses any longer. I like programming NeWS more than X, perhaps because I started with it first, perhaps because it's easier. Clearly Po Cheung's xdbx and Don Hopkins CyberSpace make programing both of these windowing systems more enjoyable. I find Don's code (as well as that from Josh Siegel and Don Woods) particularly interesting. Having to switch back a forth between the X and NeWS server's is rather uncomfortable. I have asked the guys at Sun to be a beta for the X11/NeWS merge but haven't heard anything. I was hoping to try integrating it into one of the System V Release 3 (yek!) X servers but .... --pete -- Pete Delaney - Nixdorf UCC | pete@NIXCTC.DE Prefered Addr Loffel Strasse 3 | pyramid!nixctc!pete UUCP from Calf 7000 Stuttgart 70 | pete@RELAY.HUJI.AC.IL Backup Address West Germany | Phone: +49 (711) 7685-128 From don@brillig.umd.edu Sun Apr 2 22:31:37 1989 Date: Sun, 2 Apr 89 22:31:37 EDT To: NeWS-makers@brillig.umd.edu Subject: Needed: help with input mechanism (function keys) From: xanth!nic.MR.NET!shamash!eta!skappel@g.ms.uky.edu (Steve kappel) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Has anyone figured out a way to customize NeWS so that each function key can behave like 3? I'm looking for a way to get many functions! I'm thinking this could be done by using the state of the shift and control keys. Something like: unshifted /FunctionF1 shifted /FunctionF1s controlled /FunctionF1c I've looked through UI.ps, liteUI.ps, sun3_keys.ps, etc. I've also read the NeWS 1.1 manuals. The input mechanism is still beyond me :-(. Or maybe somebody from Sun can tell me that this functionality will be available in the released product (please say yes!). _______________________________________________________________________________ Steve Kappel, Software Engineer internet: skappel@engsw.eta.com ETA Systems, Inc. uucp : {rutgers,amdahl}!bungia!eta!skappel 1450 Energy Park Drive St. Paul, MN 55108 The New Force In Supercomputing From don@brillig.umd.edu Tue Apr 4 05:45:43 1989 Date: Tue, 4 Apr 89 05:45:43 EDT To: NeWS-makers@brillig.umd.edu Subject: Re: OPEN LOOK Availability 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 <1028@nixctc.DE> pete@nixctc.DE (Pete Delaney) writes: In article <1627@iesd.dk> fischer@iesd.dk (Lars P. Fischer) writes: I seem to remember from a Sun briefing that this has been renamed "Xview" (to emphasize that it is not tied to Sun), and that it will be donated to MIT, for free distribution on the X tape. It should be ready for distribution "sometime this spring..". Anyone care to comment? That sounds like what the a Sun technical support guru told me the-week-before-last while at the Hannover Fair. If you're concerned about something for the X world, you should be reading comp.windows.x, not comp.windows.news. Here's a fairly authoritative-sounding article that appeared there recently: |From: tomj@snowking.Sun.COM (Tom Jacobs) |Newsgroups: comp.windows.x |Subject: Re: SunView to X Windows 11? |Message-ID: <94886@sun.Eng.Sun.COM> |Date: 20 Mar 89 17:54:52 GMT |Reply-To: tomj@sun.UUCP (Tom Jacobs) |Organization: Sun Microsystems, Mountain View | |In article <571@ubbpc.UUCP> wgh@ubbpc.UUCP (William G. Hutchison) writes: |> How hard is it to port from SunView to X Windows 11? | |With XView, the port to X11 is relatively simple. Sun has migrated |SunView onto X11 and retained retained most of the Application |Programming Interface (API). What this means is if you can program |to SunView, you can program to XView pretty easily. Existing |applications (of which there are >2100) can be converted in a few |days to a few weeks (if heavy graphics) . Our early ISVs tell us |that conversion is very straight forward. In addition, XView source |will be donated to the X Consortium for inclusion with X11 release 4. |XView is also portable. We did a "proof-of-concept" port to Ultrix |2.0 (just for fun :-) and demoed it at the OpenWindows press |conference at Uniforum. | |XView is implemented to Xlib and the X Consortium's ICCC |(Inter-Client Communications-Conventions). XView, unlike its |predecessor, is object-oriented (ie. all objects are opaque objects |where clients get() and set() values on objects). It is also has a |static class-based (single-inheritance) system model. The system is |extensible (ie. create new classes, or subclass existing ones), but |it is not a collection of "widgets" and is not based upon Xt. | |Tom Jacobs |Sun Microsystems. Mountain View, CA |Internet and Smail: tomj@sun.UUCP | uucp: uunet!sun!tomj Unfortunately however I was unable to confirm it with Michael Arden (the Product Manager for NeWS). Michelle oversees the product stuff for the X11/NeWS merge, but XView is coming from a different group. I have asked the guys at Sun to be a beta for the X11/NeWS merge but haven't heard anything. I think you're about 18 months too late to be a beta site, and they aren't adding any more to the list these days. I groveled before Ms Arden at SUG in Miami to be one of their early-ship (gamma?) sites, but there seems to be no action on that front either. Bummer... From don@brillig.umd.edu Tue Apr 4 05:48:15 1989 Date: Tue, 4 Apr 89 05:48:15 EDT To: NeWS-makers@brillig.umd.edu Subject: Sun Paint/Write/Draw From: emory!km@gatech.edu (Ken Mandelberg) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Do the new Sun Paint/Write/Draw programs run under NeWS (or X for that matter), or do they write directly to the framebuffer? -- 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 Apr 4 06:01:44 1989 Date: Tue, 4 Apr 89 06:01:44 EDT To: NeWS-makers@brillig.umd.edu Subject: Bug fixes to blankscreen and nclock From: spectral!sjs@bellcore.com (Stan Switzer) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) I have unwittingly perpetrated an April Fool's joke on many of you because of a stupid bug in my two recent postings "blankscreen" and "nclock." Each routine contains an identical, incorrect, subroutine "GetHHMMSS." A (more) correct version of this routine can be found below. Replacing this routine will fix the problem. Also, a new "blankscreen," with hooks to support different blanking animations, is under development. It should be presentable in a couple of weeks. Anyone wanting a copy can mail me at the address below. If volume warrants, I'll post; otherwise, I'll reply via mail. Suggestions, of course, are always welcome. Stan Switzer sjs@ctt.bellcore.com %------- fixed GetHHMMSS for blankscreen and nclock: /GetHHMMSS { % - -> hh mm ss true -or- false GetDate { 3 { ( ) search { % (true) post match pre { exch pop () ne { exit } if ( ) search not { exit } if } loop } if } repeat ( ) search 4 2 roll pop pop pop 2 { (:) search pop exch pop cvi exch } repeat cvi true } { false } ifelse } def %------- From don@brillig.umd.edu Tue Apr 4 06:14:52 1989 Date: Tue, 4 Apr 89 06:14:52 EDT To: NeWS-makers@brillig.umd.edu Subject: Things That Won't Go Away From: pterodactyl.cis.ohio-state.edu!zwicky@tut.cis.ohio-state.edu (Elizabeth D Zwicky) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Recently I've been having a horrible time making things go away in NeWS. First it was a window, created from another window, with a TextItem in it; it went away happily, unless the TextItem had been activated. As soon as that cursor started blinking, the window became immortal. After beating my head against that for a while, I simply cheated and unmapped the sucker in its /destroy. It still doesn't die, but it's at least invisible. Now, however, I have items that I am trying to make appear and disappear. I used to do this by adding a canvas to the item that was a child of the ItemCanvas, opaque, on top, and the same size, and mapping and unmapping this canvas. This works but is inelegant at best. It finally dawned upon me that I could just map and unmap the ItemCanvas. Wrong. I can map and paint it, and it appears, but after I unmap it it doesn't disappear until I repaint the parent window. The parent window has 20-odd items in it, and repainting it is unpleasant at best. The manual says a lot of things about the conditions necessary for a canvas to appear, but nothing about the conditions necessary for it to *dis*appear. I can just make do with the various hacks I've evolved, but it pains my aesthetic sense. Does anyone have any suggestions about less horrible ways to get around these problems? Elizabeth (zwicky@cis.ohio-state.edu) From don@brillig.umd.edu Tue Apr 4 06:17:03 1989 Date: Tue, 4 Apr 89 06:17:03 EDT To: NeWS-makers@brillig.umd.edu Subject: PostScript/NeWS lint? From: dasys1!treed@rice.edu (Timothy Reed) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Is there a lint library for postscript or NeWS? Is it uucp'able from an archive? Thanks Timothy Reed -- NAME : Timothy Reed FONE : 718-797-4634 UUCP : ..!cmcl2!phri!dasys1!treed || ..!uunet!dasys1!treed MAIL : 300 Union St^MBkyn, NY^M11231 From don@brillig.umd.edu Wed Apr 5 00:50:37 1989 Date: Wed, 5 Apr 89 00:50:37 EDT To: NeWS-makers@brillig.umd.edu Subject: SunView redraw events From: mcvax!ukc!axion!ist!riches@uunet.uu.net (Mark Riches) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Does anyone have any idea how NeWS redraws all the windows when a SunView redraw event happens. I've got a canvas that I want redrawn that isn't in a window, and it's not being redrawn. I've tried listening for Damage and DoIt events, but it's not that I've even checked with the event logging, and it doesn't seen to be done by sending events at all. Any hints (or guesses) much appreciated. Just telling the users not to use SunView doesn't seem to be going down too well. Mark Riches riches@uk.co.ist From don@brillig.umd.edu Wed Apr 5 18:21:37 1989 Date: Wed, 5 Apr 89 18:21:37 EDT To: NeWS-makers@brillig.umd.edu Subject: stringtype => dicttype From: David Walker Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) In a cps application it does not see, possible to pass a dicttype from the c code to postscript. You can only pass strings or ints and there is no postscript command to convert a string into a dict name. Does anyone know how to do this, if it is possible. david walker davidw@prl.philips.co.uk From don@brillig.umd.edu Wed Apr 5 18:21:44 1989 Date: Wed, 5 Apr 89 18:21:44 EDT To: NeWS-makers@brillig.umd.edu Subject: stringtype => dicttype From: mcvax!ukc!stc!idec!prlhp1!walker@uunet.uu.net (walker) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Hi, i'm writing a cps apllication and i need to pass a dicttype from c into ps. Cps allows me to pass strings, but i can find no way of converting this string into a dicttype. Does anyone have a solution or workaround? david walker walker@prl.philips.co.uk From don@brillig.umd.edu Wed Apr 5 21:22:16 1989 Date: Wed, 5 Apr 89 21:22:16 EDT To: NeWS-makers@brillig.umd.edu Subject: invertmatrix code supplied From: gregc@cgl.ucsf.edu (Greg Couch) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) The following is PostScript source for the invertmatrix operator that NeWS left out for some stupid reason. It even fails in the same ways as the real PostScript version. Enjoy... %! % The following is an implementation of the PostScript invertmatrix for NeWS. % No copyright allowed. Greg Couch, UCSF Computer Graphic Lab, April 1989 % % [ a b c d x y ] -> % [ d -b -c a (cy - dx) -(ay - bx) ] / (ad - bc) systemdict /invertmatrix known not { systemdict /invertmatrix { % matrix1 matrix2 invertmatrix matrix2 7 dict begin exch aload pop % m2 a b c d x y /y exch def /x exch def % m2 a b c d /d exch def /c exch def % m2 a b /b exch def /a exch def % m2 /t a d mul b c mul sub def % t = ad - bc d t div % m2 a2 b neg t div % m2 a2 b2 c neg t div % m2 a2 b2 c2 a t div % m2 a2 b2 c2 d2 c y mul d x mul sub t div % m2 a2 b2 c2 d2 x2 b x mul a y mul sub t div % m2 a2 b2 c2 d2 x2 y2 7 -1 roll % a2 b2 c2 d2 x2 y2 m2 astore % m2 end } put } if From don@brillig.umd.edu Thu Apr 6 09:45:49 1989 Date: Thu, 6 Apr 89 09:45:49 EDT To: NeWS-makers@brillig.umd.edu Subject: Grasshopper psterm From: att!ihlpf!spock@ucbvax.Berkeley.EDU (Weiss) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) I had to give up on playing with NeWS for a while, and so I was just saving sources off the net. Now I discover that I don't have all of the Grasshopper psterm. Can someone send it to me? Can I have all the patches also? -- 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 Thu Apr 6 09:47:10 1989 Date: Thu, 6 Apr 89 09:47:10 EDT To: NeWS-makers@brillig.umd.edu Subject: Re: Application development using Microsoft Windows From: !cmx!goedel!chris@cunyvm.cuny.edu (Chris White) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) In article <3884@ucdavis.ucdavis.edu> chow@iris.ucdavis.edu (John L. Chow) writes: >I am in the process of making the decision of using Microsoft >Windows as a standard user interface platform for all application >development under MSDOS. [stuff deleted] > >Could some of you please give me your suggestion/advise based on your >experience with MS Windows? In addition, I would also like to know: > >1. What is the future of MS Windows as a standard for DOS? >5. What are other alternatives (i.e., NewWave) if MS Windows is not > recommended? Well, the answer is simple -- you should make NeWS/OpenLook the standard user interface platform for all your applications. Soon all PCs will be just NeWS servers, so why not get a head start? :-) Really John, asking this newsgroup for advice on MS Windows is like going into a Porshe dealership and asking them whether you should buy a Yugo. -- Chris White #! rnews 1 From don@brillig.umd.edu Thu Apr 6 09:59:07 1989 Date: Thu, 6 Apr 89 09:59:07 EDT To: NeWS-makers@brillig.umd.edu Subject: Wanted: graphical user interface applicaton From: attcan!utzoo!sq!dave@uunet.uu.net (David Seaman) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) We have written a large application for the Macintosh using Object Pascal and MacApp. We are now rewritting the application using C++ and we are looking for C++-tools that are similar to MacApp. We would like these tools to support multiple windowing environments if possible: The ideal would be one package which supported X, MS-Windows, Presentation Manager, DecWindows, SunView and the Macintosh. We are looking for a *commercial* product not unsupported public domain software. The public domain software we have investigated -- e.g. interviews -- has not been appropriate for us. We would be very interested to hear from anyone who knows of such tools and even more interested to hear from any who has used them. Peter Sharpe {utai,utzoo}!sq!peter peter@sq.com SoftQuad West Suite 321 9801 King George Highway Surrey, British Columbia, Canada V3T 5H5 (604) 585-1999 From don@brillig.umd.edu Thu Apr 6 10:24:46 1989 Date: Thu, 6 Apr 89 10:24:46 EDT To: NeWS-makers@brillig.umd.edu Subject: NeWS for 386's From: bunny!abh0@husc6.harvard.edu (Andrew Hudson) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) I read in some hi-tech trade-journal tabloid that Sun will be licensing NeWS source to third party vendors. Does anyone else have details? Is there any central organization which coordinates who does what to NeWS? I would be interested in seeing a comprehensive list of vendors who supply NeWS, for what hardware platforms, and with what requirements. Even better would be a consumer's advocate kind of comparison, benchmarks and bugs report. Comments? Criticisms? - Andrew Hudson GTE Laboratories abh0@gte.com From don@brillig.umd.edu Thu Apr 6 10:34:34 1989 Date: Thu, 6 Apr 89 10:34:34 EDT To: NeWS-makers@brillig.umd.edu Subject: Help required with damaged events From: mcvax!ukc!strath-cs!glasgow!cathy@uunet.uu.net (Catherine Anne Wood) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) This time I think I am really going crazy .... After discovering to my cost that depending on retained canvas for fixing damage to items in a window is a BAD idea, I have been trying to catch Damaged events to do my own damage repair. However, it seems that Damaged events are not being generated ... or if they are they are too elusive for me to catch ! The test program I am using is simply displaying two ButtonItems which are overlapped, and then unmapping one. It remains visible until I repaint the whole window and its contents. Using eventlog, it appears that Damaged events are not generated for the ButtonItems, (but are being generated for the window's canvas when it is damaged). I am expressing interest in damaged events for the ItemCanvas of ButtonItems (I think!) and the ItemCanvases are opaque. I inserted the interest in the TrackInterests dictionary (the same place as the interests EnterEvent ExitEvent etc are set up in liteitem.ps) ... see code below. /TrackInterests 10 dict begin % Code for Enter interests etc ..... /ClientDamaged /Damaged {ItemBegin RepairDamage ItemEnd} null ItemCanvas eventmgrinterest def end def } def TrackInterests is then passed to forkeventmgr i.e. /ItemEventMgr TrackInterests forkeventmgr def RepairDamage (at the moment) just prints out a message on the console to say it has been called .. this never happens. I guess I am doing something wrong somewhere .. can anyone help me please ? Thanks, Cathy. ARPANet: cathy%cs.glasgow.ac.uk@nss.cs.ucl.ac.uk JANET : cathy@uk.ac.glasgow.cs UseNet: mcvax!ukc!cs.glasgow.ac.uk!cathy Mail : Cathy Wood, Computer Science, 17 Lilybank Gardens, GB-GLASGOW G12 8QQ : 041 339-8855 ext 6040 From don@brillig.umd.edu Fri Apr 7 10:00:46 1989 Date: Fri, 7 Apr 89 10:00:46 EDT To: NeWS-makers@brillig.umd.edu Subject: NeWS licensing From: shelby!Portia!hanauma!rick@decwrl.dec.com (Richard Ottolini) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Sun has been licensing NeWS for several years. Originally they charged $25K for source, but may have adjusted their policy with regards to X-Windows popularity. Silicon Graphics uses NeWS as its standard window system. A company, I beileve called Grasshopper, sells a Mac version. The strong similarity of Display Postscript to NeWS has slowed down NeWS ports too. From don@brillig.umd.edu Fri Apr 7 13:20:13 1989 Date: Fri, 7 Apr 89 13:20:13 EDT To: NeWS-makers@brillig.umd.edu Subject: Re: stringtype => dicttype From: !cmx!goedel!chris@cunyvm.cuny.edu (Chris White) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) In article <3230.8904051131@prsun5f.prl.philips.co.uk> davidw@prlhp1.UUCP (David Walker) writes: > > In a cps application it does not see, possible to pass a dicttype >from the c code to postscript. You can only pass strings or ints and >there is no postscript command to convert a string into a dict name. >Does anyone know how to do this, if it is possible. > > david walker >davidw@prl.philips.co.uk Assuming you have passed the following into NeWS from C: (10 dict begin /somekey (Value) def end) you can run it by using the: (stringval) cvx exec operator combination. I'm pretty sure this works, but I can't test it now -- I'm at home on a Mac without any PostScript references. If that's not the exact command, it's something similiar though. -- Chris White ps. I tried to send mail, but the address didn't work. Always the way when I try to reply. Hey, anyone feel like using that wy program to make a good NeWS interface for rn -- that'd be really cool. It could have a scrollable list of topics (a la '=') and bring up an article window when the topic is selected. You could have multiple article windows so that you could compare and contrast. Okay, maybe I'm getting carried away...but I'd try it if I didn't have other pet projects to do. From don@brillig.umd.edu Fri Apr 7 13:38:21 1989 Date: Fri, 7 Apr 89 13:38:21 EDT To: NeWS-makers@brillig.umd.edu Subject: CFP: IFIP Conference on Workstations for Experimentation From: ulowell!hawk!grinstei@bbn.com (Georges Grinstein) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) subject: 1989 IFIP WG 5.10 INTERNATIONAL WORKING CONFERENCE ======================================================================= Please pass this annnoucement along to additional interested people. To obtain more information and a registration form, just reply to this message, or to one of the other addresses in the announcement. ======================================================================== IFIP CONFERENCE ANNOUNCEMENT 1989 IFIP WG 5.10 INTERNATIONAL WORKING CONFERENCE ON WORKSTATIONS FOR EXPERIMENTATION JULY 27 to 29, 1989 Organized by IFIP WG 5.10 Hosted by The University of Lowell PROGRAM: The purpose of the conference is to provide an international forum for the exchange of technical information on workstations used for experimentation. The conference format will consist of conference paper presentations and workshops. Workshops can be classified as tutorial, informational or for the purposes of producing output documents. Papers from all nations are being solicited on the following topics, but are not limited to these: Models of Workstation Environments Experimental Visualization Workstations or Environments Auditory Workstations Multi-media Workstations Integrated Scientific Workstations Integrated Graphics and Imaging Environments Supermini Workstations Application Workstations Interactive Super-Computing International Standards and Profiles Interconnection and Networking User Interface Models and Designs Information Object Standards for Interchange Distributed Environments Graphical Issues Systems Issues Issues in Perception Human Factors Deadlines to either program chairs: Submissions - June 1, 1989 Camera Ready - July 15, 1989 Attendees will receive a PREPRINT of the Conference Papers and copies of Workshop Position Papers. After the conference, all contributions will be published as Conference Proceedings with an international publisher. PROGRAM COMMITTEE: Bergeron, Encarnacao, ten Hagen, Hopgood, Kochan, Kromker, Kuijk, Magalhaes, Mantyla, Mehl, Moltedo, Pickett, Reinfelds, Scheifler, Woodworth. PROGRAM CHAIRS: Jose Encarnacao (FRG) Georges Grinstein (USA) ORGANIZING COMMITTEE: Georges Grinstein (USA) - General Chair John Hurtado (USA) - U Lowell Conference Coordinator CONFERENCE REGISTRATION : For information on submittals and registration forms, please contact chairs via one of the netmail or postal addresses below, or by phone. Registration will be available at the Conference. The registration fee is set at $250. A processing fee of $50 will be charged on written cancellations received before 25 June 1989. After that date, the full fee will be retained. No refund will be made for people who have paid but do not attend. However, the workshop postion papers and a preprint of the conference papers will be mailed to them. HOTEL INFORMATION: Lowell Hilton 50 Warren Street Lowell, MA 01852 Telephone: (508) 452-1200 Fax : (508) 453-4674 rates: $82/nite single; $97/nite double 75 Rooms are reserved for attendees. This block of rooms will be held until July 5, 1989. Be sure to say you are attending the "IFIP 5.10 CONFERENCE" to get the Conference Rate and to credit our conference. A guarantee (usually credit card) is required for arrival after 6PM. Because of the National Folk Festival occurring during that weekend, please register early: **************************************************************** * Major other event in Lowell during that weekend: * * * * The National Folk Festival 7/28-7/30 (Fri-Sun) * **************************************************************** Alternate hotel information is available From U Lowell. AIRPORT/AIRLINE INFORMATION: Logan International Airport in Boston is the closest major airport served by all domestic and international airlines. It is managed by the Massachusetts Port Authority (617) 567-2233. For further conference information -- Send requests to: University of Lowell Continuing Education Attention - IFIP Conference One University Avenue Lowell, MA 01854 Phone: 1 - 508 - 454 - 4664 Internet: ifip@ulowell.edu Bitnet: Boole3005009 Please send submissions to one of the co-chairs: Dr. Georges Grinstein internet: grinstein@ulowell.edu Graphics Research Laboratory phone: 1 - 508 - 452 - 5000 ext 2389 University of Lowell fax: 1 - 508 - 453 - 6586 Lowell, Massachussetts 01854 telex: 710 343 6461 ULCAR LOWE USA Dr. Jose Encarnacao internet: unido!zgdva!jle@uunet.uu.net Graphische Datenverarbeitung uucp: ...mcvax!unido!zgdva!jle Wilhelminenstrasse 7 phone: +49 - (0)6151 - 1000 - 29 6100 Darmstadt fax: +49 - (0)6151 - 1000 - 99 FRG telex: 4 197 367 agd d Dr. Georges Grinstein Director - Graphics Research Laboratory grinstein@ulowell.edu University of Lowell (508)-452-5000 x2681 Lowell, MA 01854 From don@brillig.umd.edu Fri Apr 7 16:46:00 1989 Date: Fri, 7 Apr 89 16:46:00 EDT To: NeWS-makers@brillig.umd.edu Subject: Re: NeWS for 386's From: jato!mahendo!wlbr!mh@elroy.jpl.nasa.gov (Mike Hoegeman) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) In article <6759@bunny.UUCP> abh0@bunny.UUCP (Andrew Hudson) writes: >I read in some hi-tech trade-journal tabloid that Sun will be >licensing NeWS source to third party vendors. Does anyone else >have details? Is there any central organization which coordinates >who does what to NeWS? I would be interested in seeing a comprehensive >list of vendors who supply NeWS, for what hardware platforms, and with >what requirements. Even better would be a consumer's advocate kind >of comparison, benchmarks and bugs report. > >Comments? Criticisms? > >- Andrew Hudson >GTE Laboratories >abh0@gte.com sun already licenses NeWS. they always have as far back as i can remember. i'm sure the merged X/NeWS will be too. For more detailed info sun is the best source, but i will will try to answer any questions if you need a specific answer. BTW, NeWS is already on a whole bunch of machines (Mac's, Silicon graphics, HP's, 386's, etc..). The list is really quite extensive. There are NeWS' out there for third party boards for suns too. We use Parallax's graphics boards in our 3/160's with "PNeWS" which has a set of LIVE (and still)video sampling extensions which are AWESOME. Parallax did a really good job and it did'nt take them long at all to do the port, I don't remember exactly how long it took them but it was something on the order of 2-3 months. Right now I'm watching "Top Gun" in one NeWS window and typing this article in another. OH !! Wait a minute!! here comes Kelly McGillis.. Yow! :-) -mike. From don@brillig.umd.edu Sat Apr 8 18:03:41 1989 Date: Sat, 8 Apr 89 18:03:41 EDT To: NeWS-makers@brillig.umd.edu Subject: Re: NeWS for 386's From: messino@Sun.COM (Steven Messino) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Hello all, I am the Licensing Manager for Sun's Window and Graphics products. If you would like to know more about source licensing NeWS or X11/NeWS you can reach my office at 415 336 2017. I will look forward to hearing from you. SM From don@brillig.umd.edu Sat Apr 8 18:22:52 1989 Date: Sat, 8 Apr 89 18:22:52 EDT To: NeWS-makers@brillig.umd.edu Subject: Re: Application development using Microsoft Windows From: iris!chow@ucdavis.ucdavis.edu (John L. Chow) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) [Moderator's note to NeWS-makers readers: I didn't distribute the original question that chow posted to comp.windows.news about MS-windows, since it didn't have anything to do with NeWS, and wasn't very amusing; but now that it's gotten amusing ... ;-) I hope nobody objects to my low key message filtering. I don't distribute the "add me to the mailing list" messages either. Please, keep the MS-windows flames in the appropriate newsgroups! Here's to higher education! -Don] In your response to my questions posted in comp.windows.news: > From: chris@goedel.uucp (Chris White) > Newsgroups: comp.windows.news > Subject: Re: Application development using Microsoft Windows > Date: 5 Apr 89 11:39:22 GMT > Organization: Logic Lab, CIS Dept., Syracuse University > > Really John, asking this newsgroup for advice on MS Windows > is like going into a Porshe dealership and asking them whether you should > buy a Yugo. > Not only did I find your answer inappropriate, it was not humorous either! I posted the questions simply trying to find out if relevant readers would have answers to them. If you didn't think you had the answer to my questions, I would assume you not answer them. People who read and use the NET are generally engaging in higher education. I think that they should have the maturity not to insult others when there is disagreement. Frankly Chris, I do think your response very amusing! -- John From don@brillig.umd.edu Sat Apr 8 18:23:22 1989 Date: Sat, 8 Apr 89 18:23:22 EDT To: NeWS-makers@brillig.umd.edu Subject: liteitem bug From: agate!saturn!jupiter.ucsc.edu!conrad@ucbvax.Berkeley.EDU (Al Conrad, x2370) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) The following code demonstrates some kind of race condition that comes up when you use getanimated after typing text into a text item. Just psh the following, type some text into the text box, click OK, and then get a rubber band line. You'll notice that after the first rubber band line click the line disappears every time you stop moving the cursor. Somewhere, somebody is doing an erasepage in the overlay canvas, but commenting out the erasepage in litetext.ps doesn't help?! ---------------------------------------------------------------- systemdict /Item known not { (NeWS/liteitem.ps) run } if /overlay framebuffer createoverlay def /PromptBox { /CANCELResponce { can /Mapped false put %get rid of canvas p killprocess %kill dialog process } def /OKResponce { /getvalue items /responce get send can /Mapped false put %get rid of canvas p killprocess %kill dialog process } def %create canvass for the dialog box /itembackground .75 def /can framebuffer 240 150 createcanvas def can setcanvas 400 100 movecanvas currentcanvas mapcanvas itembackground fillcanvas 0 strokecanvas /items 10 dict dup begin %items is the dictionary of liteitems that make up the dialog /CancelButton (CANCEL) /CANCELResponce can 100 0 /new ButtonItem send def 130 30 /move CancelButton send /OKButton (OK) /OKResponce can 100 0 /new ButtonItem send def 10 30 /move OKButton send /responce (>) () /Right {} can 220 0 /new TextItem send 10 100 /move 3 index send def end def items paintitems /p items forkitems def p } def PromptBox waitprocess overlay setcanvas 0 0 {} getanimated waitprocess aload pop % wait for first click { lineto } getanimated waitprocess aload pop % wait for second click From don@brillig.umd.edu Sat Apr 8 18:39:43 1989 Date: Sat, 8 Apr 89 18:39:43 EDT To: NeWS-makers@brillig.umd.edu Subject: Re: NeWS for 386's From: nyit!michael@sbcs.sunysb.edu (Michael Gwilliam) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) In article <28981@wlbr.EATON.COM>, mh@wlbr.EATON.COM (Mike Hoegeman) writes: > BTW, NeWS is already on a whole bunch of machines (Mac's, Silicon > graphics, HP's, 386's, etc..). The list is really quite extensive. I'm interested in NeWS, and have written applications in it. However, the attitude around here is that it's not available on very many machines where X windows is. If someone could provide a list of machines or other practical information on NeWS. I'd be grateful. michael From don@brillig.umd.edu Sat Apr 8 18:52:26 1989 Date: Sat, 8 Apr 89 18:52:26 EDT To: NeWS-makers@brillig.umd.edu Subject: Re: Application development using Microsoft Windows From: bucsb!jbw@bu-cs.bu.edu (jbw) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) chow@iris.ucdavis.edu (John L. Chow) writes: >In your response to my questions posted in comp.windows.news: > > From: chris@goedel.uucp (Chris White) > > Really John, asking this newsgroup for advice on MS Windows > > is like going into a Porshe dealership and asking them whether you should > > buy a Yugo. > >Not only did I find your answer inappropriate, it was not humorous >either! However, it was humorous, and many of us enjoyed it. >I posted the questions simply trying to find out if relevant readers >would have answers to them. If you didn't think you had the answer >to my questions, I would assume you not answer them. So then, Chris may only post if it is of direct benefit to you? The enjoyment he brought to the rest of us doesn't count? -- Joe Wells INTERNET: jbw%bucsf.bu.edu@bu-it.bu.edu IP: [128.197.10.201] UUCP: ...!harvard!bu-cs!bucsf!jbw From don@brillig.umd.edu Sat Apr 8 23:49:57 1989 Date: Sat, 8 Apr 89 23:49:57 EDT To: NeWS-makers@brillig.umd.edu Subject: Re: Application development using Microsoft Windows From: prism!capone!ken@gatech.edu (Ken Seefried iii) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) In article <3903@ucdavis.ucdavis.edu> chow@iris.ucdavis.edu (John L. Chow) writes: > >In your response to my questions posted in comp.windows.news: > > > > > Really John, asking this newsgroup for advice on MS Windows > > is like going into a Porshe dealership and asking them whether you should > > buy a Yugo. > > > >Not only did I find your answer inappropriate, it was not humorous either! >I posted the questions simply trying to find out if relevant readers would have >answers to them. If you didn't think you had the answer to my questions, >I would assume you not answer them. People who read and use the NET are >generally engaging in higher education. I think that they should have the >maturity not to insult others when there is disagreement. > >Frankly Chris, I do think your response very amusing! > >-- John Frankly, I would imagine most people who read the NeWS newsgroup DID find it funny. What ISN'T funny is someone like YOU indiscriminately cross-posting to a bunch of newsgroups that in NO WAY relate to your question. Just to make it VERY clear, asking MS Windows questions in the Sun NeWS newsgroup does not meet you criteria of reaching "relevant readers", even tho there will certainly be knowledgeable people here. Chris was very nicely making the point that your note was not appropriate, and I think you should have the "maturity not to insult..." when you are wrong. As far as "higher education" (what WAS the relevance of that, by the way), please read news.announce.newusers so that you will be educated as to what is proper net behaviour concerning cross-posting. Oh, and having been exposed to both NeWS and Windows...the Porsche/Yugo analogy was appropriate... ...ken ken seefried iii ...!{akgua, allegra, amd, harpo, hplabs, ken@gatech.edu masscomp, rlgvax, sb1, uf-cgrl, unmvax, ccastks@gitvm1.bitnet ut-ngp, ut-sally}!gatech!ken From don@brillig.umd.edu Wed Apr 12 17:59:49 1989 Date: Wed, 12 Apr 89 17:59:49 EDT To: NeWS-makers@brillig.umd.edu Subject: Re: NeWS for 386's From: crdgw1!crdgw1.ge.com!barnett@uunet.uu.net (Bruce Barnett) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) In article <352@nyit.UUCP>, michael@nyit (Michael Gwilliam) writes: >I'm interested in NeWS, and have written applications in it. However, >the attitude around here is that it's not available on very many >machines where X windows is. If someone could provide a list of >machines or other practical information on NeWS. I'd be grateful. Another issue is the number of machines the client libraries have been ported to. For instance, I ported the client code to a vax, so I can use psterm and NeWS/emacs on a vax. Has anyone done this with a convex? I started this and when I had to research the format of the floating point code, I postposted the effort. Another topics: Sorry, but I forgot where I saw this, but.... Some company is selling a NeWS *clone* to run on a MS-DOS machine. I want a window environment at home that lets me develop and debug tools that can be used standalone or thru a modem to my machine at work. NeWS is the obvious solution, but I don't know of anyone with practical experience. Do you have to use SLIP? Does anyone have any tools? I am aware of Bruce Schwartz's NeWSline program. Does anyone have any experience using NeWS as a remote window system over a 2400 baud modem? -- Bruce G. Barnett a.k.a. uunet!steinmetz!barnett, From don@brillig.umd.edu Wed Apr 12 18:21:05 1989 Date: Wed, 12 Apr 89 18:21:05 EDT To: NeWS-makers@brillig.umd.edu Subject: NeWS Early Adopters Survey From: dkmann@Sun.COM (Darlene Mann) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Hello NeWS-Makers! I am the "new" NeWS Product Manager at Sun. I have been here about 2 months, and am trying to get a handle on the NeWS user community. A number of folks at Sun are in the process of doing some research on the NeWS 1.1 customer base for the purposes of product planning and future product marketing. We want to know who uses NeWS, what they use it for, what they like and don't like about the NeWS environment, what they would like to see Sun do in the future with NeWS, etc. We are trying to collect the information in a way that can be useful to both our engineering and marketing teams in both short and long-term planning cycles. This is an opportunity for you to provide feedback on NeWS!! Any of you out there who would like to participate, please fill out the questionnaire below. If possible, please respond by Friday, April 14th. If you would prefer to respond in real-time or have any questions, please call us: Darlene Mann Tony Barbagallo NeWS Product Manager Product Marketing Engineer Sun Microsystems Sun Microsystems dkmann@scarlett tonyb@ripples 415-336-3428 415-336-3701 (If we aren't available, please leave your name, number and mention the survey as your reason for calling - you will get a priority call back!) Thank-you for your participation. We look forward to your responses! -------------------NeWS Early Adopters Survey---------------------- Your Name:___________________________ Your Title & Function:_________________ Company Name:__________________________________________________________________ Mailing Address:_______________________________________________________________ E-Mail Address:________________________________________________________________ Type of business: _____Academic _____Commercial ______Government Type of NeWS licensee: ______Binary _______Source Nature of work being done in NeWS: Type and number of workstation(s) running NeWS: Why did you choose the NeWS environment? What are the 3 primary advantages of using NeWS? What are the 3 greatest disadvantages of using NeWS? Number of NeWS projects underway: Number of NeWS programmers at your site: Describe the type of NeWS applications being developed at your site (Please include a description of the end-user, what the design objective of the application is, what NeWS is specifically user for, etc.): Do you intend to expand your NeWS development efforts in 1989? If yes, what kind of projects are you considering? Have you attempted to design/write NeWS applications, or portions of NeWS applications, which failed? If so, what were the reasons? Are you using the Lite Toolkit as part of your development efforts? Please list the user interface tools that you would most like to see made available to NeWS developers: (such as menus, scrollbars, text objects, etc.) 1. 2. 3. 4. 5. Please list the developer tools that you would most like to see made available to NeWS developers: (such as debuggers, porting aids, editors, etc.) 1. 2. 3. 4. 5. Please rank in order of importance, the following projects being considered: ___ Extended client-side interface ___ Porting aids ___ PostScript debugger ___ Class browser/Object browser/Data inspector ___ Terminal emulator Please rate the following client-side interfaces that you are interested in using with NeWS: (1 = most interested) ___ C ___ C++ ___ Objective C ___ Pascal ___ FORTRAN ___ PostScript ___ Other: ___________________________ Do you believe CPS is a sufficient client-side interface to NeWS? If not, what enhancements are needed? In your opinion, what is the single, most valuable action which Sun can take regarding NeWS? (You can list more than one.) Please answer the following questions according to the choices which follow: 1 Excellent 2 Above Average 3 Average 4 Below Average 5 Unsatisfactory How would you rate PostScript as a programming language for your applications? Please elaborate: How would you rate Sun's extensions to the PostScript Language? Please elaborate: Are your NeWS applications structured in an object-oriented way using classes, subclasses, etc.)? If so, please rate NeWS as an object-oriented programming language: Please elaborate: THANK-YOU FOR YOUR TIME - WE APPRECIATE IT!! From don@brillig.umd.edu Wed Apr 12 19:16:24 1989 Date: Wed, 12 Apr 89 19:16:24 EDT To: NeWS-makers@brillig.umd.edu Subject: Re: Application development using Microsoft Windows From: iris!chow@ucdavis.ucdavis.edu (John L. Chow) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) To all, Please let me clarify one thing that would help us all to settle down our misunderstanding on the recent article postings. When I was getting ready to post my MS Windows questions initially, I was suggested by someone to include comp.windows.news (along with comp.windows.ms and comp.windows.misc). At the time, it appeared to us (and somewhat misinterpreted) that comp.windows.news was a 'news' group for windows and not the SUN's 'NeWS' group. ^^^^ ^^^^ I had no intention to generate all the confusion to the readers in that group and most certainly did not try to cross-posting. My apology for the misunderstanding. -- John P.S. I like SUN's NeWS too! :-) From don@brillig.umd.edu Thu Apr 13 13:25:27 1989 Date: Thu, 13 Apr 89 13:25:27 EDT To: NeWS-makers@brillig.umd.edu Subject: Re: Application development using Microsoft Windows From: "Charles_Nail.WBST129"@Xerox.COM Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Chris, I am not aware of NeWS being available for 386's in general; my understanding the Sun 386i is the 386 system licensed to use the package. If I am wrong, will you please set me straight? Charlie From don@brillig.umd.edu Fri Apr 14 13:33:20 1989 Date: Fri, 14 Apr 89 13:33:20 EDT To: NeWS-makers@brillig.umd.edu Subject: Re: NeWS for 386's From: "Charles_Nail.WBST129"@Xerox.COM Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) I read similar info: ISC and Sun announced an agreement in February that ISC will be licensed to sell NeWS and SunView to parties running on the SPARC chip. Are you aware of any other sources? Any for 386's? Charlie Nail Xerox Corporation (716)-422-4588 From don@brillig.umd.edu Sun Apr 16 04:48:14 1989 Date: Sun, 16 Apr 89 04:48:14 EDT To: NeWS-makers@brillig.umd.edu Subject: Re: NeWS for 386's From: mcvax!unido!nixctc!pete%relay.NixCtc.de@uunet.uu.net (Pete Delaney) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) In article <93@crdgw1.crd.ge.com>, barnett@crdgw1.crd.ge.com (Bruce Barnett) writes: > Do you have to use SLIP? Unless your working for the Government and required to migrate to OSI in the near future, I think NeWS/TCP/IP/SLIP is a reasonable approach. For the Government/OSI folks it would likeley be non-conformant to run NeWS/TP0/CONS/X25, I suppose they are suppose to use ODA over the OSI stack for this kind of stuff. > Does anyone have any tools? I am aware of Bruce Schwartz's NeWSline > program. What protocol stack does that use? > > Does anyone have any experience using NeWS as a remote window system > over a 2400 baud modem? I tried but couldn't get support from Neighboring System Administrators who are sold on X11. Any one want to connect up over TCP/IP/XNI/X25? I've noticed that xterm uses about twice as many packets as a rlogin session, and that rlogin uses about twice as many packets as a nterm session. So over 2400 baud modems NeWS might perform as well as X11 over a 9600 baude modem. Pete Delaney - Nixdorf UCC | pete@NIXCTC.DE Prefered Addr Loffel Strasse 3 | pyramid!nixctc!pete UUCP from Calf 7000 Stuttgart 70 | pete@RELAY.HUJI.AC.IL Backup Address West Germany | Phone: +49 (711) 7685-128 From don@brillig.umd.edu Sun Apr 16 04:48:31 1989 Date: Sun, 16 Apr 89 04:48:31 EDT To: NeWS-makers@brillig.umd.edu Subject: Re: Things that won't go away From: "Michael_Powers.Henr801M"@Xerox.COM Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Elizabeth writes >Now, however, I have items that I am trying to make appear and >disappear. I used to do this by adding a canvas to the item that >was a child of the ItemCanvas, opaque, on top, and the same size, >and mapping and unmapping this canvas. This works but is inelegant >at best. It finally dawned upon me that I could just map and unmap >the ItemCanvas. Wrong. I can map and paint it, and it appears, but >after I unmap it it doesn't disappear until I repaint the parent >window. The parent window has 20-odd items in it, and repainting >it is unpleasant at best. The manual says a lot of things about >the conditions necessary for a canvas to appear, but nothing about >the conditions necessary for it to *dis*appear. I didn't hear a response (unless someone answered directly) so, here's my two cents. To solve the problem I simply changed the /Tranparent entry in the ItemCanvas dictionary to "false". This makes the canvas opaque and will fix what's underneath when the item is moved. (especially nice when things are retained) Mike powers.henr801m@xerox.com From don@brillig.umd.edu Sun Apr 16 04:49:41 1989 Date: Sun, 16 Apr 89 04:49:41 EDT To: NeWS-makers@brillig.umd.edu Subject: Re: NeWS for 386's From: Andrew Hudson Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) From tomlin@hc.dspo.gov Thu Apr 6 11:41:37 1989 Date: Thu, 6 Apr 89 08:25:49 MST From: Bob Tomlinson To: abh0@bunny Subject: Re: NeWS for 386's abh0@bunny.UUCP (Andrew Hudson): > > I read in some hi-tech trade-journal tabloid that Sun will be > licensing NeWS source to third party vendors. Does anyone else > have details? I believe they've always been doing this. There are several vendors who sell NeWS in one form or another. > Is there any central organization which coordinates > who does what to NeWS? The person who is the one to talk to if you want to license NeWS is: Messino, Steve Window Technology Markting Sun NeWS src licensing (415) 336-2017 > I would be interested in seeing a comprehensive > list of vendors who supply NeWS, for what hardware platforms, and with > what requirements. Silicon Graphics: Their window system (I forget what it's called) has their old window system merged with NeWS. Macintosh NeWS: Grasshopper Group (Bay area - San Francisco) OS/2 NeWS: Someone has this. I don't remember their name since we don't have OS/2 machines. (I thought these people were on the East Coast) Parallax: These people have NeWS on their board which is a board which incorporates live video in a window on a high res monitor. Raster Tech (now part of Alliant): The GX4000 (their fast graphics board) has NeWS on it. There may be others. Steve Messino would know the complete list. Numerous people (including us) have ported the client side of NeWS to various machines (MIPS, Alliant, Encore, VAX/VMS). We've also got running a port of the server side to a VAX 2000 running Ultrix, although it's not a commercial product. > Even better would be a consumer's advocate kind > of comparison, benchmarks and bugs report. I don't understand the question. Doesn't it depend on what platform you're trying to run this on? -- bob From @uunet.uu.net:ppgbms!moe!paul@philabs.philips.com Mon Apr 10 22:37:16 1989 Date: Mon, 10 Apr 89 19:35:09 EDT From: Paul Evan Matz To: philabs!gte.com!abh0@uunet.uu.net Subject: Re: NeWS for 386's Andrew, Here's some oldish info that I got from my Sun TSE. I'm sure you could get an updated version from Sun if you ask your sales rep. Good Luck! Regards, Paul Matz PPG Biomedical Systems One Campus Drive Pleasantville, NY. 10570 914-741-4685 path ppgbms!moe!paul@philabs.philips.com ----------------- Current Status of NeWS 6/1/88 NeWS has been generally available since early 1987. We have received numerous requests for a "status report" on "what people are doing with NeWS". This report is to give you a brief overview of the status of NeWS in the industry. Sun is not aware of ALL the activity that is progressing on NeWS as there is no requirement for applications developers, manufacturers or NeWS licensees to inform Sun of their activities. However, Sun is aware of some activities that may be of general interest and we would like to make as much of that information as generally available as possible. Most of the available information Sun has is given below. If you have further questions, don't hesitate to ask; however, please don't be disappointed if we simply do not have more information. Table of Contents: 1.0 Number and list of "public" licensees 2.0 Announced and supported NeWS products 3.0 Known porting activities 4.0 Availablilty of these ports 5.0 Contents/changes in NeWS 1.1 6.0 Source Upgrade policy (NeWS 1.1 and X11/NeWS) 1.0 Number and list of "public" licensees As of June 1, 1988, we have a total of over 60 licensees of NeWS. Note: These are NeWS "licensees", they have not necessarily announced any product support of NeWS or NeWS applications. Reminder, a source license is not required for application development. Many software houses and major corporations are developing products based on NeWS and are not on this list. Over 3000 NeWS binaries have shipped to date, and that is where most of the application development is taking place. Also, several multi-user computer companies have announced support for NeWS as a client over a network. Again, this does not require a source license, so these companies are not included on this list. NeWS licensees: Acorn Computers Ltd. Ameristar Technologies AT&T-IS AT&T Bell Labs AT&T Technologies Eastman Kodak Company ESL Evans & Sutherland Franz Inc. Grasshopper Group ICL Jet Propulsion Laboratories Los Alamos National Laboratories LSI Logic Measurex Automation Systems Microsoft Corporation National Research Counsel of Canada Olivetti Palladio Group Parallax Graphics ParcPlace Systems Raster Technologies Rand Corporation Santa Cruz Operation SAE (Solutions Are Everything) Silicon Graphics Inc. Stratus Computer Tektronix Inc. Unicad, Inc. Wedge Whitechapel Workstations Brown University Cambridge University Carneige-Mellon University Columbia University Duke University Hull University Institute of Systems Science INESC Nanzan University New York University Princeton University Purdue University Queen Mary College Rutgers University State University of New York at Stony Brook Turing Institute University College of London Universitat Kaiserland University of Calgary University of Colorado University of Maryland University of Manchester University of Michigan University of Milan University of Pittsburgh University of Wisconsin University of Southern California University of Singapore UC Santa Barbara UC Santa Cruz 2.0 Announced and supported NeWS products Several companies have announced products based on NeWS. More detailed product information is available from these companies directly. Silicon Graphics: NeWS (4Sight) SGI workstations Mountain View, CA Parallax Graphics: Video Windows via NeWS Santa Clara, CA Palladeo Group: NeWS on OS/2 Brooklyn, NY Grasshopper Group: NeWS on a MacII, A/UX San Francisco, CA Wedge Software: NeWS on a MacII, Mac OS Cambridge, MA Whitechapel Workstations: NeWS for Whitechapel Workstations London, England Acorn Computer: NeWS for Acorn Computers Cambridge, England Raster Technologies: NeWS for the GX4000 Westford, MA Ameristar Technologies: NeWS for the Amiga 2000 Long Island, NY Celerity: NeWS client-side for Celerity San Diego, CA Alliant: NeWS client-side for Alliant Littleton, MA AT&T: X11/NeWS for Unix System V Summitt, NJ Santa Cruz Operation: X11/NeWS for Xenix Santa Cruz, CA 3.0 Known porting activities As well as commercially announced products, several ports are being worked on among the educational NeWS licensees. Please let me know if you are aware of any others!! Porting activities we know about: Apollo DN3000 University of Michigan, HP 9000 Columbia University Transputers Queen Mary College Amiga State University of New York, Stoneybrook Mac II (unix) Los Alamos National Laboratories Cray, client-side Los Alamos National Laboratories 4.0 Availablilty of these ports All NeWS educational licensees may freely exchange source and binary work in NeWS with other educational licensees as part of the standard NeWS educational license agreement. If someone in interested in getting one of these ports but is not eligible for an educational license, then they must get a commercial NeWS license and obtain the "diffs" of the port done by the educational licensee directly from that licensee. These ports are not available directly from Sun because all ports and derivative works completed by educational licensees are owned by the licensees, not by Sun. 5.0 Sources of information on NeWS Applications Development Net news: news-makers news-interest@sun.COM comp.windows.news Sun's NeWS & X11/NeWS Product Manager: Michelle Arden 415-691-2810 or marden@sun.COM For Licensing information: Amy Christen 415-691-2815 or achristen@sun.COM 6.0 Source Upgrade Policy All holders of NeWS source licenses may upgrade to X11/NeWS without having to execute another license agreement. Upgrades are available at $5,000 per release, or are included free with a Portable Windows Support Agreement available for $8000 per year. We are currently shipping NeWS Source Release 1.1. This includes Source used to build Sun Native binaries Source ported to reference platforms - Operating Systems System V, Release 3.0 4.2 BSD Ultrix 1.2 - Platforms Intel 80386 Motorola 680xx Digital VAX Troff formated documentation (to allow reproduction of manuals) Subject: NeWS & OS2 This may be of interest to some of you: NeWS is apparently now available for OS/2 from a company called ImageSoft. It is advertised on page 120 of Computer Language Magazine. Among many nice features it claims it will support OPEN LOOK once it is released. Requires: IBM-AT or compatible, OS/2, 3 button mouse and 3Mb of memory recommended. List price $495. ImageSoft (800) 245-8840 From don@brillig.umd.edu Sun Apr 16 04:49:56 1989 Date: Sun, 16 Apr 89 04:49:56 EDT To: NeWS-makers@brillig.umd.edu Subject: Re: Things that won't go away From: Elizabeth D Zwicky Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Actually, several people answered directly; later today I will post the set of solutions. One person had actually fixed my code (from a copy I had posted)! Making the ItemCanvas opaque did solve my problem beautifully. EDZ From don@brillig.umd.edu Sun Apr 16 04:50:37 1989 Date: Sun, 16 Apr 89 04:50:37 EDT To: NeWS-makers@brillig.umd.edu Subject: Re: NeWS for 386's From: fajita!jalapeno!doc%suntan.West@Sun.COM (Tom Dockery) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) In <93@crdgw1.crd.ge.com>, Bruce Barnett writes: > Another topics: Sorry, but I forgot where I saw this, but.... > Some company is selling a NeWS *clone* to run on a MS-DOS machine. The company is Technology Application Group in Los Alamitos CA. The product is call NeWScript, and the contact I have is Robert McGill, (213) 430-9792. They demoed it at Uniforum in San Francisco, and while it lacked some communications capabilities, it was quite impressive. They do plan to extend the communications by late summer. Tom Dockery ...sun!suntan!fajita!doc Market Focus Technologies From don@brillig.umd.edu Sun Apr 16 04:50:56 1989 Date: Sun, 16 Apr 89 04:50:56 EDT To: NeWS-makers@brillig.umd.edu Subject: Re: Things That Won't Go Away From: pterodactyl.cis.ohio-state.edu!zwicky@tut.cis.ohio-state.edu (Elizabeth D Zwicky) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Here are the proven fixes for my problems (by popular request): The immortal window with the item in it (which is, indeed, the one from wallpaper), can be made mortal by putting *anything* on the stack before the "itemdict forkitems" (I am using "(Food for Randomness)"). Neither I nor Phillip Nicholson, who sent me this answer, has any idea why. Although the immortality surely must be due to a remaining reference (as many, many people suggested), I had no luck in finding one, and cannot conjecture why this fix would cause one not to be created. The visible but unmapped items are a result of items being transparent. Mapping and unmapping transparent items does not propagate damage to the parent canvas. Making /Transparent false in /ItemCanvas makes it work beautifully. This was also suggested by several people. Send me mail if you would like the fixed version of wallpaper; it should function identically to the unaided eye, but it doesn't leave things around using memory when it goes away. Elizabeth Zwicky (zwicky@cis.ohio-state.edu) From don@brillig.umd.edu Sun Apr 16 04:53:22 1989 Date: Sun, 16 Apr 89 04:53:22 EDT To: NeWS-makers@brillig.umd.edu Subject: Re: Application development using Microsoft Windows From: rlgvax!benson@uunet.uu.net (Paul Benson) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) >>generally engaging in higher education. I think that they should have the I feel as though this discussion has been educational. Bob. From don@brillig.umd.edu Sun Apr 16 04:53:43 1989 Date: Sun, 16 Apr 89 04:53:43 EDT To: NeWS-makers@brillig.umd.edu Subject: Re: NeWS for 386's From: voder!wlbr!mh@ucbvax.Berkeley.EDU (Mike Hoegeman) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) In article <890410-132543-4946@Xerox> "Charles_Nail.WBST129"@XEROX.COM writes: >Chris, > >I am not aware of NeWS being available for 386's in general; my >understanding the Sun 386i is the 386 system licensed to use the package. >If I am wrong, will you please set me straight? > >Charlie I know for sure there is NeWS for 386's under OS/2 , it will also run with 80286'es . I think you need and EGA and a multisync type monitor , I would think 4 meg of memory is needed too. the company who makes OS/2 NeWS is imagesoft. here's there phone # 800-245-8840 -mike From don@brillig.umd.edu Sun Apr 16 05:31:37 1989 Date: Sun, 16 Apr 89 04:54:12 EDT To: NeWS-makers@brillig.umd.edu Subject: Re: NeWS for 386's From: voder!wlbr!mh@ucbvax.Berkeley.EDU (Mike Hoegeman) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) In article <890410-132543-4946@Xerox> "Charles_Nail.WBST129"@XEROX.COM writes: >Chris, > >I am not aware of NeWS being available for 386's in general; my >understanding the Sun 386i is the 386 system licensed to use the package. >If I am wrong, will you please set me straight? > >Charlie I know for sure there is NeWS for 386's under OS/2 , it will also run with 80286'es . I think you need and EGA and a multisync type monitor , I would think 4 meg of memory is needed too. the company who makes OS/2 NeWS is imagesoft. here's there phone # 800-245-8840 -mike From don@brillig.umd.edu Sun Apr 16 16:11:18 1989 Date: Sun, 16 Apr 89 16:11:18 EDT To: NeWS-makers@brillig.umd.edu Subject: NextStap and NeWS what's this difference other than DP From: mcvax!unido!nixctc!pete%nixctc.de@uunet.uu.net (Pete Delaney) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Would someone be so kind as to explane the difference between Sun MicroSystems NeWS package and NeXt's NextStep. I know NeXtStep is written in Display Postscript and I have ordered Adobe's DP book. I just scan thru the NeXt news group and expected a bit more postscript programs being exchanged as in the comp.windows.news news-group. Perhaps I should have checked out the postscript news-group. Anyway, any bits of wisdom about NeXtStep as compared to NeWS would be interesting. For example does NeXt step provide a postscript level debugger like the gem Don Hopkins posted last week. Are NeWS and NextStep programs interchangable with a library of defines to map from one world to the other? Grasshopper et al seem to think that display postscript is about the same as NeWS with just some names changed. So, NeXT Landers, why is NextStep our next step in human interfaces? What new ideas does NextStep offer? Is IBM makeing NextStep it's user interface as implied by Jina Lytton in UNIX World? What about the other UNIX developers? Unix Interntional? OSF? Where is NextStep going to fit it? Is it going to be licensed like NeWS is? Or will it be a propriority interface used by NeXt and IBM? Is NeWS so similar that it won't matter? Just currious :) Pete Delaney - Nixdorf UCC | pete@relay.NIXCTC.DE Prefered Addr Loffel Strasse 3 | pyramid!nixctc!pete UUCP from Calf 7000 Stuttgart 70 West Germany | Phone: +49 (711) 7685-128 From don@brillig.umd.edu Mon Apr 17 15:44:49 1989 Date: Mon, 17 Apr 89 15:44:49 EDT To: NeWS-makers@brillig.umd.edu Subject: Re: NextStap and NeWS what's this difference other than DP From: elbereth.rutgers.edu!hardees.rutgers.edu!patterso@rutgers.edu (Ross Patterson) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) > I just scan thru the NeXt news >group and expected a bit more postscript programs being exchanged >as in the comp.windows.news news-group. Perhaps NeXT has a slight problem getting their machines out into the field? Several people here at Rutgers have been trying for some time to purchase one, unsuccessfully. These folks are the ones that end-users call with questions like "I just got $25,000 in my grant for a computer, what should I get? I hear these Sun's are neat, and I've been reading all about those NeXT's in the ." It seems the local marketroids are too busy giving mass demonstrations ("... and here, if you could see the screen from the back of the lecture hall, you'd see this neat little icon we drew ..."), and can't find time to send price lists to purchasing agents. Perhaps now that BusinessLand is selling them (albeit at a higher price) they'll start selling a few. But not likely very many here. Too bad for Jobs, who said he was counting on the traditional University-developed software pool to make his machines worthwhile. Ross Patterson Rutgers University Center for Computer and Information Services From don@brillig.umd.edu Mon Apr 17 15:57:43 1989 Date: Mon, 17 Apr 89 15:57:43 EDT To: NeWS-makers@brillig.umd.edu Subject: Re: Help required with damaged events From: watmath!cantuar!greg@iuvax.cs.indiana.edu (G. Ewing) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Catherine Anne Wood (cathy@cs.glasgow.ac.uk) writes: >RepairDamage (at the moment) just prints out a message on the console to >say it has been called .. this never happens. I had a similar problem once. If the repair routine never calls damagepath, then the after the first damage event, NeWS won't give you any more, since it thinks you haven't got the first one yet. damagepath clears the accumulated damage path, allowing further damage events to occur. The repairing code should look something like: damagepath clipcanvas % draw your stuff newpath clipcanvas Greg Ewing Internet: greg@cantuar.uucp Spearnet: greg@nz.ac.cantuar Telecom: +64 3 667 001 x8357 UUCP: ...!{watmath,munnari,mcvax,vuwcomp}!cantuar!greg Post: Computer Science Dept, Univ. of Canterbury, Christchurch, New Zealand Disclaimer: The presence of this disclaimer in no way implies any disclaimer. From don@brillig.umd.edu Tue Apr 18 19:19:37 1989 Date: Tue, 18 Apr 89 19:19:37 EDT To: NeWS-makers@brillig.umd.edu Subject: Wrappingpaper From: pterodactyl.cis.ohio-state.edu!zwicky@tut.cis.ohio-state.edu (Elizabeth D Zwicky) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Well, now that wallpaper is working, I'd thought I'd give you all another way to waste time. This one lets you waste paper, too, if you have a PostScript printer. It also has a lot of small and not-so-small useful tricks coded into it, and is possibly the most egregious example of overuse of items and windows I've ever seen, much less perpetrated. I realize that the user interface leaves something to be desired, but my theory about a better one involves several new item types, so I thought I'd save it for a later release. ----------------Cut Here------------------------------------------- #! /usr/NeWS/bin/psh % wrappingpaper: Written and conceived by Elizabeth D. Zwicky % Send comments to zwicky@cis.ohio-state.edu false setautobind %Install LiteItem if nothing else has systemdict /Item known not { (NeWS/liteitem.ps) run } if % Start a new dictionary; we've outgrown the default one /partsdict dictbegin /name (PostScript) def % default printer name /tilewin null def /startup{ %defines all the drawing variables; it is wrapped like this % so that it is simple to make sure that everything will be % initialized both in the window and in the printer. /times 3 def /times2 4 def /hoffset 0 def /voffset 0 def /hoffset2 0 def /voffset2 0 def /slant 0 def /slant2 0 def /prerotate 0 def /prerotate2 0 def /prescale 1 def /prescale2 1 def /alternate null def /alterdo {-1 1 scale} def /alternate2 null def /alterdo2 {-1 1 scale} def /alterrotate 180 def /alterrotate2 180 def /on false def /arow false def /offrow false store /on2 false def /arow2 false def /offrow2 false store /drawone{}def /drawtwo{}def /dimen 25 store /dimen2 25 store /dimen2 25 store /dimen22 25 store /firsttile true def /firstdraw true def /shape null def /starty null def /drawitems null def /over null def /startx null def /tmpx 0 def /tmpy 0 def /tox null def /toy null def /canvas null def /lastx 0 def /lasty 0 def /execshape {shape cvx exec} def /tofile false def /n 3 def /n2 3 def /nn 3 def /nstarn 5 def /nstarn2 5 def /nstarnn 5 def /nstarangle {180 360 nstarnn div sub 3 div} def /second false def /second2 false def /unit2 false def /ontop false def }def startup /MySliderItem SliderItem dictbegin dictend classbegin /XToValue { % x -> value ObjectX sub 0 max ObjectWidth SliderWidth sub min Scale div SliderMin add Round {round} {round .1 mul}ifelse } def /ValueToX{ Round {SliderMin sub Scale mul ObjectX add} {SliderMin sub Scale mul 10 mul ObjectX add} ifelse } def classend def /disappear {% Takes an item and makes it invisible dup /ItemCanvas get /Transparent false put dup /unmap exch send /ItemCanvas get /Transparent true put } def /reappear { % makes a disappeared item reappear dup /map exch send /paint exch send } def % These are the possible smallest units /paisle{ 30 0 30 40 0 40 rcurveto -40 0 -50 -10 -50 -40 rcurveto 5 20 30 30 30 20 rcurveto 5 -10 10 -20 20 -20 rcurveto closepath } def /ngon{ % polygon of n sides, n determined by nslider nn {150 nn div 0 rlineto 360 360 nn div sub rotate } repeat closepath } def /nstar{ % star of n points, n determined by nstarslider nstarnn { 150 nstarnn div 0 rlineto 180 180 nstarangle 2 mul sub sub rotate 150 nstarnn div 0 rlineto 180 180 360 nstarnn div sub nstarangle 2 mul sub sub neg rotate } repeat closepath } def /crescent { 40 20 40 50 0 70 rcurveto 20 -20 20 -50 0 -70 rcurveto closepath } def /tri{ 70 0 rlineto -35 30 rlineto -35 -30 rlineto closepath }def % Rotation or reflection chooses how the larger pieces are made % out of the smaller ones. /rotation{ /drawone{ alternate prerotate rotate prescale prescale scale times{ hoffset voffset rmoveto gsave slant rotate part stroke pause grestore hoffset neg voffset neg rmoveto 360 times div rotate }repeat }store /rot true store }def /rotation2{ /drawtwo { alternate2 prerotate2 rotate prescale2 prescale2 scale times2{ hoffset2 voffset2 rmoveto gsave slant2 rotate part2 stroke pause grestore hoffset2 neg voffset2 neg rmoveto 360 times2 div rotate }repeat }store /rot2 true store }def /reflection{ /drawone{ alternate prerotate rotate prescale prescale scale times{ gsave hoffset voffset rmoveto slant rotate part stroke pause grestore gsave -1 1 scale hoffset voffset rmoveto slant rotate part stroke pause grestore 360 times div rotate }repeat }store /rot false store }def /reflection2{ /drawtwo{ alternate2 prerotate2 rotate prescale2 prescale2 scale times2{ gsave hoffset2 voffset2 rmoveto slant2 rotate part2 stroke pause grestore gsave -1 1 scale hoffset2 voffset2 rmoveto slant2 rotate part2 stroke pause grestore 360 times2 div rotate }repeat }store /rot2 false store }def /loopstart{% precalculates values used in the tiling loops /hexdimen dimen def /hexdimen2 hexdimen hexdimen mul hexdimen 2 div hexdimen 2 div mul sub sqrt def /outloop height hexdimen 3 mul div ceiling cvi 1 add def /inloop width hexdimen2 2 mul div ceiling cvi 1 add def /yincr hexdimen 1.5 mul def /xincr hexdimen2 2 mul def /firstcorrect inloop xincr mul neg hexdimen2 add def /lastcorrect inloop xincr mul neg hexdimen2 neg add def /correct inloop xincr mul neg def /sqoutloop height dimen div ceiling cvi 1 add def /sqinloop width dimen div ceiling cvi 1 add def /hincr dimen def /vincr dimen2 def /hinloop width dimen div ceiling cvi 1 add def /1correct hinloop hincr mul hincr 2 div sub neg def /2correct hinloop hincr mul hincr 2 div add neg def /houtloop height dimen2 div ceiling cvi 1 add def }def % These procedures actually do the tiling /hextile{ /on false store /prev on store outloop{ inloop{ 0 0 moveto gsave drawone stroke grestore newpath ontop {0 0 moveto gsave drawtwo stroke grestore} if xincr 0 translate } repeat arow {/on true store} {/on false store} ifelse second {/on prev store} if firstcorrect yincr translate inloop{ 0 0 moveto gsave drawone stroke grestore newpath ontop {0 0 moveto gsave drawtwo stroke grestore} if xincr 0 translate } repeat /on false store second {/on prev not store /prev on store} if lastcorrect yincr translate }repeat 0 0 moveto gsave drawone grestore } store /halftile{ /on false store /prev on store houtloop{ hinloop{ 0 0 moveto gsave drawone stroke grestore newpath ontop {0 0 moveto gsave drawtwo stroke grestore} if hincr 0 translate } repeat arow {/on true store} {/on false store} ifelse second {/on prev store} if 1correct vincr translate hinloop{ 0 0 moveto gsave drawone stroke grestore newpath ontop {0 0 moveto gsave drawtwo stroke grestore} if hincr 0 translate } repeat /on false store second {/on prev not store /prev on store} if 2correct vincr translate }repeat 0 0 moveto gsave drawone grestore } store /squaretile{ /on false store /prev on store sqoutloop{ sqinloop{ 0 0 moveto gsave drawone stroke grestore newpath ontop { 0 0 moveto gsave drawtwo stroke grestore} if dimen 0 translate } repeat arow {offrow {/on false store /offrow false store} {/on true store /offrow true store} ifelse } {second {offrow {/on prev store /offrow false store} {/on prev not store /prev on store /offrow true store} ifelse} {/on false store} ifelse } ifelse dimen sqinloop mul neg 0 translate 0 dimen translate }repeat 0 0 moveto gsave drawone stroke grestore /offrow false store } store % This sets what smallest unit is the default /part {ngon} def /part2 {crescent} def % Sets the default for both parts to reflection reflection reflection2 % Sets the default tiling to hexagonal /tile{hextile}store /tmpstring 30 string def /recurse{% Given an array, write a representation of it to a file whose % filehandle is "tmp" tmp ({ ) writestring {dup type (arraytype) eq {recurse} {dup type (nametype) eq exch dup xcheck not exch 3 1 roll and {tmp (/) writestring} if tmp exch tmpstring cvs writestring tmp ( ) writestring } ifelse } forall tmp (} ) writestring } def /dump{ % given the name of something currently defined, dump its % definition to a file whose filehandle is tmp using recurse dup tmp (/) writestring tmp exch tmpstring cvs writestring tmp ( ) writestring load dup type (arraytype) eq {recurse} {dup type (nametype) eq exch dup xcheck not exch 3 1 roll and {tmp (/) writestring} if tmp exch tmpstring cvs writestring tmp ( ) writestring } ifelse tmp (def \n) writestring } def /printdump{% Use dump to print the current filing to a printer or % to a file /tmp (tmp) (w) file def tmp (%! \n /height 700 def /width 500 def /pause {} def \n) writestring /startup dump tmp (startup \n) writestring /hoffset dump /hoffset2 dump /voffset dump /voffset2 dump /slant dump /slant2 dump /times dump /times2 dump /prerotate dump /prerotate2 dump /prescale dump /prescale2 dump /alterrotate dump /alterrotate2 dump /dimen dump /dimen2 dump /shape dump /ontop dump /loopstart dump /second dump /n dump /n2 dump /nn dump /part load {} forall dump /part2 load {} forall dump tmp (/on false def /offrow false def /execshape {shape} def \n) writestring /alternate dump /alterdo dump /part dump /part2 dump /arow dump /drawone dump /drawtwo dump /tile load {} forall dump /tile dump tmp (loopstart 0 0 moveto tile showpage \n) writestring tmp closefile tofile {(cp tmp ) name append forkunix} {(lpr -P) name append ( tmp) append forkunix} ifelse } def % Printer dialog box /printwin framebuffer /new DefaultWindow send def 100 100 200 200 /reshape printwin send /printcan printwin /ClientCanvas get def /printitems 10 dict def printitems begin /nametext (Name of File or Printer) (PostScript) /Bottom {} printcan 100 20 /new TextItem send 10 100 /move 3 index send def /printit (Print) {/name printitems /nametext get /ItemValue get store printdump /unmap printwin send} printcan 20 20 /new ButtonItem send 70 10 /move 3 index send def /cancel (Cancel) {/unmap printwin send} printcan 20 20 /new ButtonItem send 10 10 /move 3 index send def /filecycle (Print to File:) [/panel_check_off /panel_check_on] /Right {tofile {/tofile false store} {/tofile true store} ifelse } printcan 20 20 /new CycleItem send 10 65 /move 3 index send def end printitems forkitems {/PaintClient{erasepage printitems paintitems} def /destroy {/unmap printwin send} def } printwin send % Window for the tiling /tilemain{ /firsttile false store /tilewin framebuffer /new DefaultWindow send store { /PaintClient{ erasepage clippath pathbbox /height exch store /width exch store loopstart 0 0 moveto tile }def /destroy{ %Gentle destroy /firsttile true store /unmap tilewin send tilewin /FrameEventMgr get killprocess }def } tilewin send /reshapefromuser tilewin send /map tilewin send }def % Window for the controls /itemwin framebuffer /new DefaultWindow send def {/PaintClient{erasepage items paintitems} def } itemwin send 100 100 500 310 /reshape itemwin send /can itemwin /ClientCanvas get def % Window for Unit One /win framebuffer /new DefaultWindow send def /reshapefromuser win send { /PaintClient{ erasepage clippath pathbbox /y exch def /x exch def x 2 div y 2 div moveto drawone }def /FrameLabel (Unit One) def /ClientMenu [ (Show me a tiling) {first {tilemain} {/paint tilewin send} ifelse} ]/new DefaultMenu send def } win send /first true def /helpwindow null def /help {% Put up help file in window % Make help window /helpwindow framebuffer /new ScrollWindow send store 0 0 390 460 /reshape helpwindow send framebuffer setcanvas itemwin /FrameCanvas get getcanvaslocation exch 200 add exch 460 sub /move helpwindow send { /NotifyUser { /PaintClient helpwindow send} def } dup helpwindow /VScrollbar get send helpwindow /HScrollbar get send helpwindow /ClientCanvas get setcanvas { /PaintClient{ ClientCanvas setcanvas erasepage clippath pathbbox /place exch def /urx exch def /lly exch def /llx exch def /width urx llx sub def /height place lly sub def HScrollbar /ItemValue get width mul neg VScrollbar /ItemValue get height mul translate 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 /helptext [ (This program allows you to create interesting repeating) (patterns and print them. It is called "wrappingpaper") (partly because of an earlier program named "wallpaper") (by the same author, and partly because it has often been) (suggested that the printouts would make good wrapping) (paper for small gifts.) ( ) (The repeating patterns are built up from "units" made) (by repeating, by rotation or rotation and reflection,) ("parts". The parts can be moved around the axis of) (rotation horizontally and vertically, and scaled and tilted) (before the repetitions are made. The units can also be) (rotated as wholes. The first unit is always visible; to) (see the tiling, hit the tile button, and it will give you) (yet another window.) ( ) (Three possible tilings are available, with various sorts) (of alternation. The best way to get an idea of what the) (different tiling options do is to tile a single paisle.) (Since the paisle is neither vertically nor horizontally) (symmetrical, all rotations and reflections are visible) (when applied to it.) ( ) (If you choose to draw your own part, you will get a) (very primitive drawing window. Click to place the) (endpoint of the line; doubleclick to end the shape.) ( ) (You can add a second unit, which is currently treated just) (like the first one \(you can't alternate between the two ) (units\). More features for the second unit will be added) (later, as will a more intuitive interface.) ( ) (This program will only print to a PostScript printer.) (It is addictive and you may waste a lot of paper!) (Written and conceived by Elizabeth D. Zwicky.) (Send comments to zwicky@cis.ohio-state.edu) ] def % Window for the second part /win2 null def /made2win false def /make2win{made2win not {/win2 framebuffer /new DefaultWindow send store /reshapefromuser win2 send { /PaintClient{ erasepage clippath pathbbox /y exch def /x exch def x 2 div y 2 div moveto drawtwo }def /FrameLabel (Unit Two) def /ClientMenu [ (Show me a tiling) {first {tilemain} {/paint tilewin send} ifelse} ]/new DefaultMenu send def } win2 send /map win2 send /made2win true store} {/map win2 send} ifelse }def % Long notify procedures /alternotify{ ItemValue [ 0 {/arow false store /alternate {} store /second false store itemwin items /alterdocycle get disappear items /alterrotateslider get disappear} 1 {/on false store /arow false store /second false store /alternate{ on {alterdo /on false store} {/on true store} ifelse } store itemwin items /alterdocycle get reappear} 2 {/on false store /arow true store /second false store /alternate{ on {alterdo} if} store} 3 {/on false store /arow true store /second false store /alternate{ on { alterdo /on false store} {/on true store} ifelse } store} 4 {/on false store /second true store /arow false store /alternate{ on {alterdo /on false store} {/on true store} ifelse } store} ] case } def /oneify{%set controls to match Unit One items begin {hoffset setvalue} hoffsetslider send {voffset setvalue} voffsetslider send {slant setvalue} slantslider send {times setvalue} timesslider send {n setvalue} nslider send /part load {} forall dup [ (ngon) {{0 setvalue} partcycle send} (tri) {{1 setvalue} partcycle send} (paisle) {{2 setvalue} partcycle send} (crescent) {{3 setvalue} partcycle send} (nstar) {{4 setvalue} partcycle send} (execshape) {{5 setvalue} partcycle send} ] case dup (ngon) eq {nslider reappear} {nslider disappear} ifelse (nstar) eq {nstarslider reappear} {nstarslider disappear} ifelse {prerotate setvalue} rotateslider send {prescale setvalue} scaleslider send rot {{1 setvalue} reflectcycle send} {{0 setvalue} reflectcycle send} ifelse end } def /twoify{% Set controls to match Unit Two items begin {hoffset2 setvalue} hoffsetslider send {voffset2 setvalue} voffsetslider send {slant2 setvalue} slantslider send {times2 setvalue} timesslider send {n2 setvalue} nslider send /part2 load {} forall dup [ /ngon {{0 setvalue} partcycle send} /tri {{1 setvalue} partcycle send} /paisle {{2 setvalue} partcycle send} /crescent {{3 setvalue} partcycle send} /nstar {{4 setvalue} partcycle send} /execshape {{5 setvalue} partcycle send} ] case dup (ngon) eq {nslider reappear} {nslider disappear} ifelse (nstar) eq {nstarslider reappear} {nstarslider disappear} ifelse {prerotate2 setvalue} rotateslider send {prescale2 setvalue} scaleslider send rot2 {{1 setvalue} reflectcycle send} {{0 setvalue} reflectcycle send} ifelse end }def /drawnotify { /firstdraw false store items /partcycle get begin /Cycle [(N-gon)(Triangle)(Paisle)(Crescent)(N-star)(NewPart)] def end /drawwin framebuffer /new DefaultWindow send def /reshapefromuser drawwin send /canvas drawwin /ClientCanvas get store { /destroy { % Gentle destroy; does not take other things with it drawwin /IconCanvas get /Mapped false put drawwin /FrameCanvas get /Mapped false put drawwin /ClientCanvas get /Mapped false put drawwin /FrameEventMgr get killprocess /firstdraw true store }def } drawwin send /startx 0 store /starty 0 store /tox 100 store /toy 100 store /shape null store /gstate null def canvas setcanvas /over currentcanvas createoverlay store /drawitems dictbegin /shapebutton (Make a Shape) {/gstate null store shape null ne { canvas setcanvas 100 75 translate 1 setgray 0 0 moveto shape cvx exec stroke 0 setgray /shape null store /lastx 0 store /lasty 0 store } if { over setcanvas 100 75 translate startx starty {x y lineto} getanimated waitprocess aload pop /toy exch def /tox exch def canvas setcanvas gstate null ne {gstate setstate} {100 75 translate} ifelse startx starty moveto tox toy lineto /gstate currentstate store gsave stroke grestore /shape mark /lastx 0 store /lasty 0 store {/tmpy exch store /tmpx exch store tmpx lastx sub tmpy lasty sub /lastx tmpx store /lasty tmpy store /rmoveto cvx } {/tmpy exch store /tmpx exch store tmpx lastx sub tmpy lasty sub /lastx tmpx store /lasty tmpy store /rlineto cvx} {/curveto cvx} {/closepath cvx} pathforall counttomark array astore exch pop store startx tox eq starty toy eq and {exit} if /startx tox def /starty toy def } loop /startx 0 def /starty 0 def } canvas 100 20 /new ButtonItem send 10 10 /move 3 index send def dictend store drawitems forkitems drawitems paintitems { /PaintClient{ erasepage drawitems paintitems shape null ne {100 75 translate 0 0 moveto shape cvx exec stroke} if } def } drawwin send /map drawwin send } def % Define a *lot* of items /items dictbegin /altercycle (Alternation:) [(No Alternation) (Alternate Items) (Alternate Rows) (Checkerboard) (Stretched Checkerboard) ] /Right /alternotify can 100 20 /new CycleItem send 200 70 /move 3 index send def /alterdocycle (Do Alternate:) [(Reflect Vertical) (Rotate) (Reflect Horizontal)] /Right {unit2 {ItemValue{ 0 {/alterdo2 {-1 1 scale} store} 1 {/alterdo2 {alterrotate2 rotate} store itemwin items /alterrotateslider get reappear} 2 {/alterdo2 {1 -1 scale} store itemwin items /alterrotateslider get disappear} } case } {ItemValue{ 0 {/alterdo {-1 1 scale} store} 1 {/alterdo {alterrotate rotate} store itemwin items /alterrotateslider get reappear} 2 {/alterdo {1 -1 scale} store itemwin items /alterrotateslider get disappear} } case } ifelse } can 100 20 /new CycleItem send 200 40 /move 3 index send def /hoffsetslider (Horizontal Offset:) [-50 50 0] /Right {unit2 {/hoffset2 ItemValue store /paintclient win2 send} {/hoffset ItemValue store /paintclient win send} ifelse} can 120 10 /new SliderItem send 10 190 /move 3 index send def /voffsetslider (Vertical Offset:) [-50 50 0] /Right {unit2 {/voffset2 ItemValue store /paintclient win2 send} {/voffset ItemValue store /paintclient win send} ifelse} can 120 10 /new SliderItem send 230 190 /move 3 index send def /slantslider (Slant:) [-180 180 0] /Right {unit2 {/slant2 ItemValue store /paintclient win2 send} {/slant ItemValue store /paintclient win send} ifelse} can 120 10 /new SliderItem send 48 160 /move 3 index send def /timesslider (Number:) [1 20 3] /Right {unit2 {/times2 ItemValue store /paintclient win2 send} {/times ItemValue store /paintclient win send} ifelse} can 120 10 /new SliderItem send 110 250 /move 3 index send def /nslider (N:) [3 20 3] /Right {unit2 {/n2 ItemValue store /nn n2 store /paintclient win2 send} {/n ItemValue store /nn n store /paintclient win send} ifelse} can 120 10 /new SliderItem send 10 230 /move 3 index send def /nstarslider (N:) [3 20 5] /Right {unit2 {/nstarn2 ItemValue store /nstarnn nstarn2 store /paintclient win2 send} {/nstarn ItemValue store /nstarnn nstarn store /paintclient win send} ifelse} can 120 10 /new SliderItem send 10 230 /move 3 index send def /partcycle (Unit:) [(N-gon)(Triangle)(Paisle)(Crescent)(N-star)] /Right {unit2 {ItemValue{ 0 {/part2 {ngon} store itemwin items /nstarslider get disappear items /nslider get reappear} 1 {/part2 {tri} store itemwin items /nslider get disappear} 2 {/part2 {paisle} store} 3 {/part2 {crescent} store} 4 {/part2 {nstar} store items /nstarslider get reappear} 5 {/part2 {execshape} store items /nstarslider get disappear} } case /paintclient win2 send} {ItemValue{ 0 {/part {ngon} store itemwin items /nstarslider get disappear items /nslider get reappear} 1 {/part {tri} store itemwin items /nslider get disappear} 2 {/part {paisle} store} 3 {/part {crescent} store} 4 {/part {nstar} store items /nstarslider get reappear} 5 {/part {execshape} store items /nstarslider get disappear} } case /paintclient win send} ifelse } can 100 20 /new CycleItem send 10 250 /move 3 index send def /reflectcycle (Symmetry Type:) [(Reflection)(Rotation)] /Right {unit2 {ItemValue { 0 {reflection2} 1 {rotation2} } case /paintclient win2 send} {ItemValue { 0 {reflection} 1 {rotation} } case /paintclient win send} ifelse } can 100 20 /new CycleItem send 10 215 /move 3 index send def /tilecycle (Tiling Type:) [(Hexagonal)(Half Drop)(Square)] /Right { ItemValue{ 0 {/tile {hextile} store } 1 {/tile {halftile} store itemwin items /dimen2slider get reappear} 2 {/tile {squaretile} store itemwin items /dimen2slider get disappear} } case } can 120 10 /new CycleItem send 10 70 /move 3 index send def /tilebutton (Tile) {firsttile {tilemain} {/paintclient tilewin send} ifelse} can 50 10 /new ButtonItem send 130 95 /move 3 index send def /unitswitch (Settings:) [(First Unit) (Second Unit)] /Right {ItemValue [ 0 {/unit2 false store oneify} 1 {/unit2 true store twoify} ] case } can 60 10 /new CycleItem send 300 215 /move 3 index send def /foo{ /unitcycle (Second Unit Placed:) [(On Top) (At Corners) (Interleaved)] } def /secondcycle (Second Unit) [(Off) (On)] /Right {ItemValue 0 eq { /ontop false store /unmap win2 send itemwin items /unitswitch get disappear /unit2 false store oneify % items /unitcycle get disappear } {/ontop true store make2win itemwin items /unitswitch get reappear % items /unitcycle get reappear } ifelse} can 120 10 /new CycleItem send 185 215 /move 3 index send def /printbutton (Print) {printwin /FrameCanvas get /Mapped get true eq {/totop printwin send} {/totop printwin send /map printwin send} ifelse } can 50 10 /new ButtonItem send 195 95 /move 3 index send def /helpbutton (Help) {first {help} if} can 50 10 /new ButtonItem send 250 95 /move 3 index send def /newpartbutton (Draw New Part) {firstdraw {drawnotify} if} can 100 10 /new ButtonItem send 10 95 /move 3 index send def /dimenslider (Dimension 1:) [1 100 25] /Right {/dimen ItemValue store} can 120 10 /new SliderItem send 10 45 /move 3 index send def /dimen2slider (Dimension 2:) [1 100 25] /Right {/dimen2 ItemValue store} can 120 10 /new SliderItem send 10 20 /move 3 index send def /rotateslider (Rotate Unit:) [-180 180 0] /Right {unit2 { /prerotate2 ItemValue store /paintclient win2 send} { /prerotate ItemValue store /paintclient win send} ifelse} can 120 10 /new SliderItem send 10 130 /move 3 index send def /alterrotateslider (Alternate Rotation:) [-180 180 180] /Right {unit2 { /alterrotate2 ItemValue store /paintclient win2 send} { /alterrotate ItemValue store /paintclient win send} ifelse} can 120 10 /new SliderItem send 10 0 /move 3 index send def /scaleslider (Scale Unit:) [0 100 1] /Right {unit2 {/prescale2 ItemValue store /paintclient win2 send} {/prescale ItemValue store /paintclient win send} ifelse} can 120 10 /new MySliderItem send 250 250 /move 3 index send def scaleslider /Round false put dictend def items /foo undef items forkitems /map win send win /FrameCanvas get getcanvaslocation 310 sub /move itemwin send /map itemwin send itemwin /ClientCanvas get /Retained false put itemwin /FrameCanvas get getcanvaslocation 200 sub /move printwin send items begin dimen2slider disappear alterdocycle disappear unitswitch disappear alterrotateslider disappear end dictend def From don@brillig.umd.edu Wed Apr 19 21:42:28 1989 Date: Wed, 19 Apr 89 21:42:28 EDT To: NeWS-makers@brillig.umd.edu Subject: List of NeWS servers and NeWS applications From: mimsy!uunet!hoptoad!gnu (John Gilmore) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) We at Grasshopper have been building such a list. It is not complete (in particular, NEmacs from Unipress is not yet listed) but it should give you some idea of what is available. If you have any updates to this info, please send them to "tech@toad.com" and we'll fold them in. # # catalog -- Other NeWS server products and NeWS related products # NeWS Servers --------------------------------------------- NeWS/2 for OS/2 by Architec +1 718 622 8577 FAX +1 718 622 9205 850 Carroll St., Brooklyn, New York 11215 USA NeWS is up and running on OS/2! Networking to other machines on your LAN Manager net is just like using your own machine now! Unfortunately OS/2 doesn't support TCP/IP yet, so it doesn't yet network to your Suns, Macs, etc. PNeWS for Sun VMEbus machines by Parallax +1 408 727 2228 PNeWS is a NeWS port extended to deal with live video! Using display systems from Parallax, any NTSC signal can be fed into a window on your Sun system, for display or digitizing. MacNews for A/UX on Apple Macintosh by Grasshopper Group <...!{uunet, sun, apple}!hoptoad!tech> Orders: +1 408 266 4783 Tech: +1 415 668 5998 1996 Hayes St., San Francisco CA 94117 USA MacNews is a full NeWS port, running on Apple's Unix port with full Berkeley TCP/IP networking. MacNews Version 1.1.10 supports standard (reasonable) Macintosh color displays. Runs in 4 megs of RAM, works best with more RAM, of course! Version 1.1.10 runs only on A/UX version 1.1, MacNews 1.1.01 runs only on A/UX 1.0. Shipped on floppies. Price: MacNews 1.1.10, $300 US. MacNews 1.1.01, $225 USA NeWS for SunOS by Sun Microsystems +1 415 960 1300 Inquiries: 2550 Garcia Avenue, Mt. View, CA 94043 USA Orders: call your local Sun sales office The original NeWS port is for Sun Workstations. It is available from Sun for $100, including the binaries on tape (cartridge or reel-to-reel), NeWS manual and installation instructions, and the Adobe PostScript reference manual and tutorial. An outstanding value for $100! NewScript, a NeWS interaction clone for MS/DOS by TAG inc. Technology Application Group inc. +1 213 430 9792 FAX +1 714 995 7980 10621 Bloomfield Street, Suite 33 Los Alamitos, California 90720 USA NewScript(tm) is a compact, high performance emulation of the NeWS window system, for 286 and 386 machines running DOS or OS/2(tm). NewScript offers an interactive user interface design environment for the development and prototyping of NeWS compatible graphical interfaces. Perfect for PostScript and NeWS class teaching! NewScript is based on the PostScript(R) language as defined by Adobe Systems Inc. with Events, Canvases, Monitors, Processes, and Object PostScript extensions specified by NeWS. NewScript emulates a subset of NeWS and PostScript. CPS, network communications, and stroke fonts are not supported in version 1.0. NeWS related Products for MacNews -------------------------------------------- softquad Publishing Software -- Product Summary +1 800 387 2777, +1 416 963 8337 SoftQuad Inc., 720 Spadina Avenue,Toronto, Ontario, Canada M5S 2T9 Device-independent text and graphic processing for laserprinters, typesetters, and impact printers. Powerful and flexible, SoftQuad Publishing Software is a high performance derivation of AT&T's Documenter's Workbench, complete with troff, eqn, tbl, pic and grap processors for text, equations, tables, graphics and graphs. SoftQuad Publishing Software is a cost-effective solution for most publishing and in-house publishing tasks: manuals, reports, books, proposals, price lists, newsletters, and memos. The software provides the tools to simply and methodically create macro formatting packages to produce typeset quality output, taking full advantage of the capabilities of all popular printing devices for those users who have neither the time nor the expertise to painstakingly design each page. Because of its heritage as a true building-block program within UNIX, SoftQuad Publishing Software can format and print text files from any source, including word processor, database and spreadsheet applications. It can run alone or invisibly, behind other applications, to create fine quality, reproducible laserprinter output or inexpensive proofs which emulate the line and page breaks of high-cost typeset galleys. Features include typeface and point size changes, justification, centering, hyphenation, page and section numbering, multiple columns, proper character fit (kerning) and user definable hyphenation exception dictionary. Newly added features include bitmap inclusion, white lettering on dark background, and landscape printing. Detailed, readable manuals are included. Screen previewers for NeWS and X-windows are also available for a variety of machines. SoftQuad Publishing Software is available for virtually all UNIX and MS-DOS computers, including, of course, the Apple Macintosh II and IIX running A/UX. PostScript Clip Art Images from 3G Graphics +1 800 456 0234 +1 206 823 8198 11410 N.E. 124th St., Suite 6155 Kirkland, Washinton 98034 USA 3G sells a growing line of over 200 pieces of PostScript Clip Art Images. These images come on MacOS floppies that can be read with the A/UX 'hfx' toolbox utility into AppleDouble format files. The data fork of the AppleDouble file (you can throw away the half that starts with a %) can be previewed with 'paper'. 3G has graciously provided some sample images; they are viewable under the Demos => Previewer => Paper menu in MacNews 1.1.10. -- John Gilmore {sun,pacbell,uunet,pyramid,amdahl}!hoptoad!gnu gnu@toad.com "Use the Source, Luke...." Copyright 1989 John Gilmore; you may redistribute only if your recipients may. From don@brillig.umd.edu Thu Apr 20 04:48:20 1989 Date: Thu, 20 Apr 89 04:48:20 EDT To: NeWS-makers@brillig.umd.edu Subject: Beyond PostScript From: brillig.umd.edu!don@mimsy.umd.edu (Don Hopkins) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) What if there was another bit in every PostScript array reference (like the executable bit), that when set, makes it an "inline executable array", i.e. when the interpreter hits an inline executable array, it would execute it (push it directly onto the execution stack) instead of pushing it onto the operand stack. Then autobind could replace names that were bound to inline executable arrays, as well as built-in operators like it does now... So you could define your own autobound inline PostScript functions, which didn't have to be looked up on the dict stack at run time! (You could accomplish the same thing manually by pushing the array and then doing an exec, ala {//myfunc exec}, but that's twice as many runs through the interpreter loop.) Inline executable arrays could save a lot of dictionary searches, especially when used for the non-primative functions in systemdict (the last dict in the search list, and quite a whopper), and commonly called functions in userdict. That's the funny thing about PostScript ... The interpreter treats arrays differently than everything else: When it comes across an executable array in a function, it pushes the array onto the operand stack, same as with literal arrays. I think it could speed things up a bit if you could have a kind of super-executable array that was automatically executed, that the scanner automatically autobinds into your functions. Something Forth has that PostScript doesn't is the notion of "immediacy". (This is something different than "inline executable arrays" described above.) Each Forth word has a bit that tells if it's immediate or not (most aren't). The compiler (i.e. scanner, in the case of a hypothetically extended PostScript) *executes* an immediate word (function) instead of compiling it (i.e. putting it into an executable array). It would be like an extended mode of autobind. Immediate functions take care of compiling (or scanning) themselves. They can even read things off the input stream following the token that invoked them. This mechanism is used in Forth for implementing control structures, macros, inline string literals, and other types of magic compiler constructs. The way the NeWS scanner works would have to be changed to accomodate immediate PostScript function, because the scanner uses its own special stack for building executable arrays. You'd want the PostScript scanner to put a mark on the operand stack, and push each array element as it's scanned. When it scans an executable token that's bound to an immediate function on the dict stack, it would execute that function, then go on scanning the rest of the array. Immediate PostScript functions would be able to look at the operand stack to see what of the array has been scanned so far, and anything they left on the stack would end up in the array. User definable magic variables and tuple-space operations (ala PIX) could be a great deal of fun, too! [Check out Wm Leler's "PIX, the latest NeWS" in the Proceedings of COMPCON Spring '89, IEEE, and N. Carriero and D. Gelernter's "Linda In Context", in the April 1989 CACM.] But then it wouldn't be PostScript TM, would it? (Ah, yes, the eternal tension between featurization and standardization. Phooey. Onward!) -Don From don@brillig.umd.edu Thu Apr 20 04:49:11 1989 Date: Thu, 20 Apr 89 04:49:11 EDT To: NeWS-makers@brillig.umd.edu Subject: Help, I have a bar-problem. From: Knut Skog Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Somewhere along the mail-route to my corner of the NeWS community, someone grabs the bar encoding (octal 174) of ordinary shell-pipe and c-programs (logical or ) and converts it to a right bracket (octal 135). I assume that some part of the mail system is causing this problem. Locally I'm using EAN. Can anyone give me a hint to whom a modest request for improvement should be issued in order to have this problem fixed. I can not possibly ask the NeWS-world to say away from the bar? Knut From don@brillig.umd.edu Thu Apr 20 04:51:58 1989 Date: Thu, 20 Apr 89 04:51:58 EDT To: NeWS-makers@brillig.umd.edu Subject: Re: Wrappingpaper From: pterodactyl.cis.ohio-state.edu!zwicky@tut.cis.ohio-state.edu (Elizabeth D Zwicky) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) I *really* ought to know better than to post things just before I go home at night. Here are diffs to make the nslider appear, disappear and function correctly for both ngon and nstar. Sigh. ------------Cut Here------------------------------------------------ 9c9 < /tilewin null def --- > /tilewin null def /star false def 92c92 < /nstar{ % star of n points, n determined by nstarslider --- > /nstar{ % star of n points, n determined by nslider 634d633 < {n setvalue} nslider send 645,646c644,649 < {nslider reappear} < {nslider disappear} --- > {/star false store {n setvalue} nslider send nslider reappear} > {(nstar) eq > {/star true store {nstar setvalue} nslider send > nslider reappear} > {nslider disappear} > ifelse} 648,651d650 < (nstar) eq < {nstarslider reappear} < {nstarslider disappear} < ifelse 666,667c665 < {n2 setvalue} nslider send < /part2 load {} forall dup --- > /part2 load {} forall dup 677,678c675,680 < {nslider reappear} < {nslider disappear} --- > {/star false store {n2 setvalue} nslider send nslider reappear} > {(nstar) eq > {/star true store {nstarn2 setvalue} nslider send > nslider reappear} > {nslider disappear} > ifelse} 680,683d681 < (nstar) eq < {nstarslider reappear} < {nstarslider disappear} < ifelse 866,867c864,878 < {unit2 {/n2 ItemValue store /nn n2 store /paintclient win2 send} < {/n ItemValue store /nn n store /paintclient win send} ifelse} --- > {star > {unit2 > {/nstarn2 ItemValue store > /nstarnn nstarn2 store > /paintclient win2 send} > {/nstarn ItemValue store > /nstarnn nstarn store > /paintclient win send} > ifelse} > {unit2 > {/n2 ItemValue store /nn n2 store /paintclient win2 send} > {/n ItemValue store /nn n store /paintclient win send} > ifelse} > ifelse > } 873,883d883 < /nstarslider < (N:) < [3 20 5] < /Right < {unit2 {/nstarn2 ItemValue store /nstarnn nstarn2 store /paintclient win2 send} < {/nstarn ItemValue store /nstarnn nstarn store /paintclient win send} ifelse} < can 120 10 < /new SliderItem send < 10 230 /move 3 index send < def < 890,892c890,893 < 0 {/part2 {ngon} store itemwin items /nstarslider get disappear < items /nslider get reappear} < 1 {/part2 {tri} store itemwin items /nslider get disappear} --- > 0 {/part2 {ngon} store > /star false store > items /nslider get dup {n2 setvalue} exch send reappear} > 1 {/part2 {tri} store items /nslider get disappear} 895,896c896,900 < 4 {/part2 {nstar} store items /nstarslider get reappear} < 5 {/part2 {execshape} store items /nstarslider get disappear} --- > 4 {/part2 {nstar} store > /star true store > items /nslider get dup > {nstarn2 setvalue} exch send reappear} > 5 {/part2 {execshape} store items /nslider get disappear} 901,902c905,906 < 0 {/part {ngon} store itemwin items /nstarslider get disappear < items /nslider get reappear} --- > 0 {/part {ngon} store /star false store > items /nslider get dup {n setvalue} exch send reappear} 906,907c910,913 < 4 {/part {nstar} store items /nstarslider get reappear} < 5 {/part {execshape} store items /nstarslider get disappear} --- > 4 {/part {nstar} store /star true store > items /nslider get dup {nstarn setvalue} exch send > reappear} > 5 {/part {execshape} store items /nslider get disappear} From don@brillig.umd.edu Thu Apr 20 04:52:10 1989 Date: Thu, 20 Apr 89 04:52:10 EDT To: NeWS-makers@brillig.umd.edu Subject: Distribution of GoodNeWS 1.2 From: mcvax!ukc!strath-cs!turing!dug@uunet.uu.net (Dug Scoular) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Hi there, We are looking for people who would be interested in distributing our NeWS window environment called GoodNeWS. GoodNeWS is a NeWS environment with the following features: - Improved terminal emulator - Object-oriented, color drawing tool - TeX previewer which allows inclusion of drawings created with the drawing tool. - HyperNeWS with multiple stacks, color and prolog interface. - and many other useful tools and features Here is our request: We would like to put this system onto any ftp/uucp server for world-wide distribution (if possible). The system is about 5Mb uncompressed. Please contact us if you are willing to distribute this for us or if you have any hints on how we can distribute this into the public domain efficiently. -- Doug Scoular (System Administrator) E-mail: dug@uk.ac.turing Tel: 041 552 6400 Postal: The Turing Institue George House 36 N. Hanover Street Glasgow G1 2AD Scotland UK. From don@brillig.umd.edu Thu Apr 20 20:21:02 1989 Date: Thu, 20 Apr 89 20:21:02 EDT To: NeWS-makers@brillig.umd.edu Subject: Re: NextStep and NeWS... From: allosaur.cis.ohio-state.edu!bob@tut.cis.ohio-state.edu (Bob Sutterfield) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) In article bob@allosaur.cis.ohio-state.edu (Bob Sutterfield) writes: What interpretive language would you like to use to interact with your windows? PostScript and X11 are already done. How about Common Lisp? Smalltalk? Forth? Prolog? APL? I forgot Display PostScript :-) From don@brillig.umd.edu Sat Apr 22 14:08:50 1989 Date: Sat, 22 Apr 89 14:08:50 EDT To: NeWS-makers@brillig.umd.edu Subject: Open Vista Association From: dreamon!scott%gotham.East@Sun.COM (Scott Manville) Sender: NeWS-makers-request@brillig.umd.edu (Don Hopkins) Open Vistas Association, dedicated to the open systems philosophy and to the promotion of window systems having intelligence, held its first meeting at Uniforum in February. Our next meeting will be at the Baltimore Usenix. (Anyone who would like to participate, or exhibit in our--subsidized--booth, should contact me at the address below, or speak with the Grasshopper Group.) OVA is an organization for all users of the forthcoming Unix System V window system, X-11/NeWS; and all current users of NeWS and PostScript technology. OVA will offer a newsletter and bulletin board, an office to contact for information and referrals, a technology distribution service for products in the public domain--but most importantly, it will raise the profile, both academic and commercial, of X-11/NeWS. This PostScript-based technology is truly open, with at least seven active vendors, over a dozen platforms, and over fifty licensees--even before the release of X-11/NeWS. (And there are certainly NeWS products I am not aware of yet. Please tell me what you have, and I will mention it in our publications and discussions with the press.) It is open to you, too. Membership is extremely reasonable, with individual and non-profit rates of $30, and a corporate rate of only $100. For more information, contact me, Scott Manville, at Open Vistas Association, 80 East 11th St., Suite 222, New York, New York 10003. 212 979 5337.