[comp.windows.news] cyber.shar.splitad

don@TUMTUM.CS.UMD.EDU (Don Hopkins) (11/23/89)

======== START OF cyber.shar.splitad ========
X
X  } LiteMenu send
X
X  { % send to Item:
X
X% Beta 2 bug, liteitem.ps, class Item
X    /ThingSize { % thing textfont => width height
X    gsave
X	setfont
X%	dup type { % X11/NeWS font type = dicttype, so use 'truetype'
X	dup truetype {
X	    /stringtype {stringwidth pop currentfont fontheight}
X	    /nametype {
X		dup { load } stopped pop xcheck {
X		    false exch cvx exec
X		} {
X		    iconfont setfont iconstring stringbbox 4 2 roll pop pop
X		} ifelse
X	    }
X	    /nulltype {0 0}
X	    /Default {0 0}
X	} case
X    grestore
X    } def
X
X% Beta 2 bug, liteitem.ps, class Item
X    /ShowThing { % thing color x y textfont => -
X    gsave
X	setfont translate setcolor
X	0 0 moveto % moveto establishs current pt.
X%	dup type { % X11/NeWS font type = dicttype, so use 'truetype'
X	dup truetype {
X	    /stringtype {0 currentfont fontdescent rmoveto show}
X	    /nametype {
X		dup { load } stopped pop xcheck {
X		    true exch cvx exec
X		} {
X		    iconfont setfont iconstring show
X		} ifelse
X	    }
X	    /nulltype {pop}
X	    /Default {pop}
X	} case
X    grestore
X    } def
X
X% Beta 2 bug, liteitem.ps, class Item
X    /EraseThing { % thing color x y textfont => -
X    gsave
X% X11/NeWS: {load} stopped => ... `load` true, but {load} errored => ... true
X%	4 index dup type /nametype eq exch { load } stopped pop xcheck and {
X	4 index dup type /nametype eq exch { load } errored pop xcheck and {
X	    5 -1 roll exch ThingSize rectpath setcolor fill
X	} {
X	    ShowThing
X	} ifelse
X    grestore
X    } def
X
X  } Item send
X
X  { % send to SimpleScrollbar:
X
X% Beta 2 bug, liteitem.ps, class SimpleScrollbar
X%     /ScrollDownArrow 16 16 1 { } { < % X11/NeWS: matrix arg isn't ignored!
X%	> } buildimage def
X      /ScrollDownArrow 16 16 1 [16 0 0 -16 0 16] { <
X	  07F8 0FF8 0818 0818 0818 0818 781F F81F
X	  8002 4004 2008 1010 0820 0440 0280 0100
X	> } buildimage def
X
X% Arrgh, it's still hosing me! I'm mad now!
X      /PaintArrow {
X	gsave
X	  translate scale setshade
X	  .5 .1 moveto
X	  .1 .9 lineto
X	  .5 .6 lineto
X	  .9 .9 lineto
X	  closepath
X	  fill
X	grestore
X      } def
X
X    } SimpleScrollbar send
X
X} if % version 1.0 (beta 2 bugs)
X
Xend % systemdict
X
X% end of X11/NeWS compatibility crud
X
X} { % else if not X11/NeWS (install NeWS 1.1 compatibility stuff)
X  systemdict begin
X
X    /truetype { type } ?def
X    /RootUserDict 10 dict def
X
X  end % systemdict
X} ifelse
X
X% End of compatibility crud. You can empty your barf bag now.
X
X%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
X% Icky system globals and merciless kludges
X
Xsystemdict begin
X
X/array? { % obj => bool
X  type dup /arraytype eq exch /packedarraytype eq or
X} def
X
X/comment { pop } def
X
X% Reap dead debuggers
X/rd {
X  systemdict /DbgDicts known {
X    [ DbgDicts {pop} forall ] {
X      dup /State get /zombie eq {
X	dup killprocess
X	DbgDicts exch undef
X      } { pop } ifelse
X    } forall
X  } if
X} def
X
Xrd
X
X/_ViewCanvas null def
X
X/_SendUpdateStack {
X  count array astore aload
X  null /UpdateStack _SendViewEvent
X%  { flush } errored {
X%    { dbgstop } errored quit
X%  } if
X} def
X
X/_SendViewEvent { % ClientData Action Name => -
X  createevent begin
X    /Name exch def
X    /Action exch def
X    /ClientData exch def
X    /Canvas
X      currentprocess /Interests get 0 get % event
X      /ClientData get /ViewCanvas get % can
X    def
X  currentdict end sendevent
X} def
X
X/_ReadyProcess {
X  {
X    currentprocess
X    XNeWS? {
X      dup /ProcessName (Spike) put
X    } if
X    createevent begin
X      /Canvas _ViewCanvas def
X      /Name /ProcessReady def
X      /Action currentprocess def
X      count array astore aload
X      /ClientData exch def
X    currentdict end sendevent
X    createevent begin
X      /Name 20 dict def
X      Name begin
X	/ExecIt {
X	  /ClientData get
X	  exec
X	  _SendUpdateStack
X	} def
X	/ReplaceStack {
X	  dup /Action get dup type /stringtype ne { pop } {
X	    { print flush } errored { 
X	      { dbgstop } errored 
X	      clear currentprocess killprocessgroup
X	    } if
X	  } ifelse
X	  /ClientData get
X	  count 1 roll
X	  count 1 sub {pop} repeat
X	  aload pop
X	} def
X	/DropDead {
X	  { dbgstop } errored
X	  { (Ayyyeee!\n) print flush } errored
X	  clear currentprocess killprocessgroup
X	} def
X      end % Name
X      /ClientData 20 dict def
X      ClientData begin
X	/ViewCanvas _ViewCanvas def % Stash!
X      end % ClientData
X    currentdict end expressinterest
X
X% The /execfile kludge is to get around the fact that /execfile is a 
X% function defined in systemdict in X11/NeWS pre fcs, instead of being
X% a file defined in userdict by executive, as in earlier versions. 
X% The problem is that "dbgstart" checks for /execfile in userdict to 
X% tell if an executive has already been started, and if it's not (or
X% even if it is, in our case), it starts one. (and executive doesn't 
X% return, so we've lost control!) (Supposedly a call to "executive" 
X% occurs right before "_ReadyProcess" on the input stream.) So until 
X% such a time as "dbgstart" knows how to tell an executive has already
X% been started, we must fool it... 
X    /execfile dup load def 
X
X    dbgstart
X
X    256 {
X      rd % reap dead rebuggers
X      dstack { eventloop } stopped { 
X	(\nI'm confused...\n) print
X	pause pause
X        ExecutiveErrorHandler
X	pause pause
X      } if
X      (\nTry again...\n) print
X      pause pause
X    } repeat
X    (\nGame over, man!\n) print
X  } fork
X  createevent begin
X    /Name /ExecIt def
X    /Process exch def
X    currentdict
X  end
X  { currentfile dup null eq { clear exit } if
X    token {
X      1 index createevent copy % ev1 ob ev2
X      dup /ClientData 4 -1 roll % ev1 ev2 /CD obj
X      [ exch ] cvx
X      put % ev1 ev2
X      sendevent
X    } {
X      clear exit
X    } ifelse
X  } loop
X} def
X
X/eventloop {
X  { awaitevent } loop 
X} def
X
X/dstack {
X  currentprocess /DictionaryStack get 
X  dup length (dstack[%]: ) printf
X  {
X    smart-name print (  ) print
X  } forall
X  (\n) print
X} def
X
X/enter-eventloop {
X  dstack eventloop
X} def
X
X% This does not exit when you type "exit"...(invalidexit error)
X/enter-executive {
X  { dstack executive exit } loop
X} def
X
X/enter {
X  currentprocess /Interests get length 0 eq
X  /enter-executive /enter-eventloop ifelse
X  exch send
X  dstack
X} def
X
X% Debugger Aliases
X/dbe	{dbgbreakenter} def
X/dbx	{dbgbreakexit} def
X/dc	{dbgcontinue} def
X/dcb	{dbgcontinuebreak} def
X/dcc	{dbgcopystack dbgcontinue} def
X/dcs	{dbgcopystack} def
X/de	{dbgenter} def
X/deb	{dbgenterbreak} def
X/dgb	{dbggetbreak} def
X/dk	{dbgkill} def
X/dkb	{dbgkillbreak} def
X/dlb	{dbglistbreaks} def
X/dmp	{dbgmodifyproc} def
X/dp	{dbgpatch} def
X/dpe	{dbgprintfenter} def
X/dpx	{dbgprintfexit} def
X/dw	{dbgwhere} def
X/dwb	{dbgwherebreak} def
X/dx	{dbgexit} def
X
X% Useful aliases
X/fb	{framebuffer} def
X/ls	{[currentdict {pop} forall] ==} def
X
XXNeWS? not { % XXX?
X  /revokekbdinterests {	%  [ int1 int2 ... intn ]  can =>  -
X      removefocusinterest
X  %    aload pop revokeinterest revokeinterest revokeinterest
X      {{revokeinterest} errored {pop} if} forall
X  } store
X} if
X
X{
X  /getmenuaction { % index => action
X    dup null ne {
X      MenuActions 1 index MenuActions length 1 sub min get
X  % Execute actions that are names! (This is so we can have the executable 
X  % name of a submenu, or a functions to compute the menu action!)
X      dup type /nametype eq { exec } if
X    } {nullproc} ifelse
X    exch pop
X  } def
X} LiteMenu send
X
XXNeWS? {
X  % ick!
X  /Primary dup framebuffer /new ClassSelection send
X  exch setselection
X} if
X
Xsystemdict /old-setselection known not {
X  /old-setselection /setselection load def
X  /setselection { % dict rank
X    2 copy old-setselection
X    createevent begin
X      /Name /SelectionChanged def
X      /Action exch def
X      /ClientData exch def
X    currentdict end sendevent
X  } def
X} if
X
X/select-object { % obj => -
X  20 dict begin
X    /SelectionType /object def
X    /ContentsPostScript 1 index def
X    /ContentsAscii exch (%) sprintf def
X    /SelectionObjSize 1 def
X    /SelectionResponder null def
X    /Canvas currentcanvas def % XXX?
X    /SelectionHolder currentprocess def % XXX?
X    currentdict
X  end
X  /PrimarySelection setselection
X} def
X
X/select-pointer { % obj index => -
X  20 dict begin
X    /SelectionType /pointer def
X    /SelectionStartIndex exch def
X    /ContentsPostScript exch def
X    /ContentsAscii
X      /ContentsPostScript load
X      /SelectionStartIndex load get
X      (%) sprintf
X    def
X    /SelectionObjSize 1 def
X    /SelectionResponder null def
X    /Canvas currentcanvas def % XXX?
X    /SelectionHolder currentprocess def % XXX?
X    currentdict
X  end
X  /PrimarySelection setselection
X} def
X
X/select-interval { % obj start len => -
X  20 dict begin
X    /SelectionType /interval def
X    /SelectionObjSize exch def
X    /SelectionStartIndex exch def
X    /SelectionLastIndex
X      SelectionStartIndex SelectionObjSize add 1 sub
X    def
X    /ContentsPostScript exch def
X    /ContentsAscii
X      /ContentsPostScript load
X      SelectionStartIndex  SelectionObjSize getinterval
X      (%) sprintf
X    def
X    /SelectionResponder null def
X    /Canvas currentcanvas def % XXX?
X    /SelectionHolder currentprocess def % XXX?
X    currentdict
X  end
X  /PrimarySelection setselection
X} def
X
X/dissect-selection { % seldict => obj
X  dup selection-type {
X    /empty {
X      pop null % null
X    }
X    /unknown {
X      % seldict
X    }
X    /text {
X      /ContentsAscii get % string
X    }
X    /object {
X      /ContentsPostScript get % obj
X    }
X    /pointer {
X      dup /ContentsPostScript get % seldict container
X      exch /SelectionStartIndex get % container index
X      1 index type /dicttype eq {
X        2 copy known
X      } true ifelse {
X	get % obj
X      } {
X	pop pop null % null
X      } ifelse
X    }
X    /interval {
X      dup /ContentsPostScript get % seldict container
X      exch dup /SelectionStartIndex get % container seldict start
X      exch /SelectionLastIndex get % container start last
X      1 index sub 1 add % container start len
X      getinterval % obj
X    }
X    /Default {
X      % seldict
X    }
X  } case
X} def
X
X/selection-type { % seldict => name
X  dup null ne { 
X    dup /SelectionType known { 
X      dup /SelectionType get dup null ne exch /UnknownRequest ne and
X    } false ifelse {
X      /SelectionType get
X    } {
X      dup /ContentsAscii known {
X	pop /text
X      } {
X	pop /unknown
X      } ifelse
X    } ifelse
X  } {
X    pop /empty
X  } ifelse
X} def
X
X/interesting-keys [
X  /SelectionType
X  /ContentsAscii /ContentsPostScript
X  /SelectionStartIndex /SelectionLastIndex
X] def
X
XXNeWS? {
X  /request-selection { % rank => seldict
X    10 dict begin
X      interesting-keys { null def } forall
X      currentdict
X    end
X    exch selectionrequest
X  } def
X} {
X  /request-selection { % rank => seldict
X    dup getselection dup null ne {
X      exch pop
X    } {
X      pop
X      10 dict begin
X	interesting-keys { null def } forall
X	currentdict
X      end
X      exch selectionrequest
X    } ifelse
X  } def
X} ifelse
X/selected-object { % - => obj
X  /PrimarySelection request-selection
X  dissect-selection
X} def
X
X/selected-pointer? { % - => false / collection index true
X  /PrimarySelection request-selection
X  dup selection-type /pointer eq {
X    dup /ContentsPostScript get exch /SelectionStartIndex get 
X    true
X    2 index type /dicttype eq {
X      3 copy pop known not { % invalid pointer
X	pop pop pop false
X      } if
X    } if
X  } {
X    pop false
X  } ifelse
X} def
X
X/selected-interval? { % - => false / collection start last true
X  /PrimarySelection request-selection
X  dup selection-type /interval eq {
X    dup /ContentsPostScript get 
X    exch dup /SelectionStartIndex get 
X    exch /SelectionLastIndex get true
X  } {
X    pop false
X  } ifelse
X} def
X
X/selected-pointer-or-interval? { % - => false / collection first last true
X  /PrimarySelection request-selection dup selection-type {
X    /interval {
X      dup /ContentsPostScript get exch
X      dup /SelectionStartIndex get exch
X      /SelectionLastIndex get
X      true
X    }
X    /pointer {
X      dup /ContentsPostScript get exch
X      /SelectionStartIndex get dup
X      true
X      2 index type /dicttype eq {
X	3 copy pop known not { % invalid pointer
X	  pop pop pop false
X	} if
X      } if
X    }
X    /Default {
X      pop false
X    }
X  } case
X} def
X
X% NeWS-print 0.996
X% Written by Josh Siegel
X% Munged by Don Hopkins
X
X/Externals 512 dict def
X/ExternalsBack 512 dict def
XExternals /Count 0 put
X
X/string-magic 
X        dictbegin
X            (\b) 0 get (\\b) def
X            (\f) 0 get (\\f) def
X            (\n) 0 get (\\n) def
X            (\r) 0 get (\\r) def
X            (\t) 0 get (\\t) def
X            (\() 0 get (\\\() def
X            (\)) 0 get (\\\)) def
X            (\\) 0 get (\\\\) def
X        dictend
Xdef
X
X/fixstring { 
X    10 dict
X    begin
X	/len 0 def
X        /out 1 index length 3 mul string def
X        {
X            dup string-magic exch known {
X                string-magic exch get
X	    } {
X	        cvis
X            } ifelse
X	    out len 2 index putinterval
X	    /len exch length len add def
X        } forall
X        out 0 len getinterval dup length string copy
X    end
X} def
X
X/stringer { % proc => string
X    dup type cvlit
X    {
X        /arraytype {
X	  pause
X	  /arraylvl arraylvl 1 add store
X	  dup xcheck {
X            /the_string the_string ( {\n) append store
X            {
X                stringer
X            } forall
X            /the_string the_string ( }\n) append store
X	  } {
X            /the_string the_string ( [\n) append store
X            {
X                stringer
X            } forall
X            /the_string the_string ( ]\n) append store
X	  } ifelse
X	  /arraylvl arraylvl 1 sub store
X        }
X        /nametype {
X            dup xcheck {
X                the_string
X	        arraylvl 0 eq (% /% cvx ) (% %) ifelse
X		sprintf
X                /the_string exch store
X            } {
X                the_string (% /%) sprintf
X		/the_string exch store
X            } ifelse
X        }
X        /operatortype {
X            255 string cvs dup length 2 sub 1 exch getinterval
X	    the_string
X	    arraylvl 0 eq (% /% cvx ) (% %) ifelse
X	    sprintf
X            /the_string exch store
X        }
X        /stringtype {
X            fixstring
X            the_string (% \(%\)) sprintf
X            /the_string exch store
X        }
X	/marktype {
X	    (mark ) % [ DANGER! ]
X	}
X        /booleantype /integertype /realtype /nulltype {
X            the_string (% %) sprintf
X            /the_string exch store
X        }
X	/Default {
X	  dup type /dicttype ne dictlvl 0 ne or arraylvl 0 ne or {
X	    ExternalsBack 1 index known {
X	      ExternalsBack exch get % name
X	    } {
X	      Externals begin Count /Count Count 1 add def end % obj count
X	      1 index type (&%_%) sprintf % obj name
X	      Externals 1 index 3 index put % obj name
X	      ExternalsBack 3 -1 roll 2 index put % name
X	    } ifelse
X	    the_string ( //) append exch append /the_string exch store
X	  } {
X	    /dictlvl dictlvl 1 add store
X            /the_string the_string ( dictbegin\n) append store
X            {   pause
X		/the_string the_string (\t) append store
X		exch stringer stringer
X		/the_string the_string ( def\n) append store
X            } forall
X            /the_string the_string ( dictend \n) append store
X	    /dictlvl dictlvl 1 sub store
X	  } ifelse
X	} def
X    } case
X} def
X
X/tokeout { % obj => string
X    10 dict
X    begin
X        /cnt Externals /Count get def
X	/dictlvl 0 def
X	/arraylvl 0 def
X	/the_string () def
X        stringer the_string
X	cnt Externals /Count get ne {
X	  (Externals begin\n%\nend\n) sprintf
X	} def
X    end
X} def
X
X% Short readable names
X
X  /ShortNameDict 40 dict def
X
X  ShortNameDict begin
X    /nametype {
X      dup xcheck (%) (/%) ifelse
X      sprintf
X    } def
X    /dicttype {
X      dup maxlength exch length (<%/%>)
X      sprintf
X    } def
X    /arraytype {
X      dup length exch xcheck ({%}) ([%]) ifelse
X      sprintf
X    } def
X    /packedarraytype /arraytype load def
X    /stringtype {
X      dup length 80 gt { 0 80 getinterval ((%)...) } ((%)) ifelse
X      sprintf
X    } def
X    /marktype {
X      pop (mark)
X    } def
X    /eventtype {
X      dup /Name get short-name
X      exch /IsInterest get
X      (interest(%)) (event(%)) ifelse
X      sprintf
X    } def
X    /canvastype {
X      gsave
X	dup setcanvas
X	clippath pathbbox points2rect 4 2 roll pop pop exch % h w
X	framebuffer setcanvas
X	3 -1 roll 
X	dup /Parent get null eq { 
X	  pop (can(%,%)) sprintf
X	} {
X	  getcanvaslocation exch
X	  (can(%,%,%,%)) sprintf
X	} ifelse
X      grestore
X    } def
XXNeWS? {
X    /processtype {
X       dup /Execee get exch
X       dup /State get exch
X       dup /ProcessName known { /ProcessName get } (anonymous) ifelse
X       (proc('%',%,%)) sprintf
X    } def
X} { % not XNeWS?
X    /processtype {
X% One or more of these is causing a core dump some of the time... (NeWS 1.1)
X%       dup /Interests get length exch
X%       dup /ExecutionStack get length exch % CORE DUMP
X%       dup /DictionaryStack get length exch
X%       dup /OperandStack get length exch
X%       dup /Execee get exch
X%       /State get
X%       (proc(%,%,o%,d%,e%,i%)) sprintf
X       dup /Execee get exch
X       /State get
X       (proc(%,%)) sprintf
X    } def
X} ifelse % XNeWS?
X  end %  ShortNameDict
X
X  /short-name {
X    dup type ShortNameDict 1 index known {
X      ShortNameDict exch get exec
X    } {
X      pop 80 string cvs
X    } ifelse
X  } def
X
X  /smart-name {
X    dup smart-type ( ) append exch short-name append
X  } def
X
X  /SmartTypeDict 40 dict def
X
X  SmartTypeDict begin
X
X      /dicttype {
X	dup systemdict eq {
X	  pop (systemdict)
X	} {
X	  % TODO: Detect the process's userdict ...
X	  magic-type
X	} ifelse
X      } def
X
X      /canvastype {
X% 	dup framebuffer eq {
X% 	  pop (framebuffer)
X% 	} {
X% 	  magic-type
X% 	} ifelse
X	magic-type
X      } def
X
X      /eventtype {
X        magic-type
X      } def
X
X      /processtype {
X	magic-type
X      } def
X
X      /fonttype {
X        magic-type
X      } def
X
X      /integertype {
X        dup floor sub 0 eq
X        (integer) (real) ifelse
X      } def
X    
X    end % SmartTypeDict
X
X  /smart-type { % obj => str
X    dup truetype % obj type
X    SmartTypeDict 1 index known {
X      SmartTypeDict exch get exec % str
X    } { % obj type
X      pop short-type % str
X    } ifelse
X  } def
X
X  /magic-type {
X    dup /ParentDictArray known 
X    { dup /ParentDictArray get type /nametype ne } % Detect bogus classes!
X    false ifelse {
X      dup /ClassName known { % class
X	/ClassName get 64 string cvs
X      } { % instance
X	% ugly ugly!
X	/ClassName exch send
X	64 string cvs (.) exch append
X      } ifelse
X    } {
X      short-type
X    } ifelse
X  } def
X
X  /short-type { % obj => str
X    truetype 20 string cvs
X    0 1 index length 4 sub getinterval
X  } def
X
Xsystemdict /quicksort known not {
X
X%
X% quicksort by Don Woods at Sun Microsystems, Inc.
X%
X/quicksort { % array proc => array (sorted, reuses same storage)
X10 dict begin
X    /Bigger? exch cvx def               % a b bigger? => t if a<b
X    dup quickrecur                      % start recursion
Xend
X} def % quicksort
X
X/quickrecur { % array => --  sorts array in place, using Bigger? for comparisons
X    dup length dup 2 gt {               % A N
X	% the next lines (until but not incl /Key...) subsort three elements
X	% so we can use the median as the partitioning element; this improves
X	% performance for the case where the array is initially nearly sorted,
X	% but is not strictly necessary for the algorithm to work (it does
X	% seem to improve average runtime by about 10%)
X	2 copy 1 sub 2 copy 2 idiv 1 index 0    % A N A N-1 A (N-1)/2 A 0
X	6 copy get 5 1 roll get 3 1 roll get    % above & A[N-1] A[(N-1)/2] A[0]
X	2 copy Bigger? {exch} if                % subsort for three elements
X	3 1 roll 2 copy Bigger? {exch} if       %   ... (call them min mid max)
X	3 -1 roll 2 copy Bigger? {exch} if      %   ... subsort finished
X	9 index % A N A N-1 A (N-1)/2 A 0 min mid max N
X	3 eq {
X	    5 2 roll put 4 1 roll put put       % store min/mid/max back
X	    pop pop                             % pop A & N
X	} { % else store mid at 0, max at N-1, min at (N-1)/2, then partition
X	    3 -1 roll 5 2 roll put exch 4 1 roll put put        % A N
X	    /Key 2 index 0 get def              % partitioning value
X	    0                                   % A N 0, also known as A j i
X	    {   % main partitioning loop
X		% incr i until i=j or A[i]>=A[0]; note A[j] is rangecheck
X		{   1 add 2 copy gt {           % i++; A j i j>i?
X			dup 3 index exch get    % A j i A[i]
X			Key exch Bigger? not {exit} if
X		    } {exit} ifelse
X		} loop
X		% decr j until A[j]<=A[0]; happens at j=i-1 if not sooner
X		exch {                          % A i j
X		    1 sub dup 3 index exch get  % A i j A[j]
X		    Key Bigger? not {exit} if
X		} loop
X		2 copy gt {exit} if             % if i>=j, finished partition
X		% swap A[j] & A[i]; stack has: A i j
X		2 index 4 copy exch get         % A i j A A i A[j]
X		4 1 roll get                    % A i j A[j] A A[i]
X		3 index exch put                % A i j A[j]
X		4 copy exch pop put pop exch    % A j i
X	    } loop
X	    % finish partition by exchanging A[j] with A[0]; stack has: A i j
X	    exch pop 2 copy 4 copy get          % A j A j A j A[j]
X	    exch pop 0 exch put Key put         % A j
X	    % now recur on A[0..j-1] and A[j+1..N-1]
X	    2 copy 1 add 1 index length 1 index sub     % A j A j+1 N-1
X	    getinterval 3 1 roll 0 exch getinterval     % A[j+1..N-1] A[0..j-1]
X	    2 copy length exch length gt {exch} if      % put smaller on top
X	    quickrecur quickrecur       % tail recursion avoids deep stack
X	} ifelse % =3 or >3 elements
X    } { % handle 1- and 2-element cases specially for efficiency
X	2 eq {
X	    dup aload pop Bigger? {aload 3 1 roll exch 3 -1 roll astore} if
X	    } if
X	pop     % pop the array
X    } ifelse
X} def % quickrecur
X
X% end of quicksort
X
X} if % quicksort not known
X
X% This function in systemdict makes sure ClassName is always in a
X% dictionary on the dict stack.  Objects all have their own class
X% name.  This function provides names for /systemdict and /userdict.
X% It returns the dictionary itself for other dictionaries.
X%
X% The use of this is a little bad and hacky because /ClassName is used
X% as a method for any object (including classes themselves), even though
X% it is not an advertised method in class Object.
X%
X/ClassName { % - => name | dict
X    currentdict
X    dup userdict   eq {pop /userdict} if
X    dup systemdict eq {pop /systemdict} if
X} ?def
X
Xend % systemdict
X
X%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
X% Userdict Utilities
X
X/shift-names 10 dict def
Xshift-names begin
X  /Meta false def
X  /Shift false def
X  /Control false def
Xend % shift-names
X
X/update-shifts {
X  shift-names {store} forall
X  /KeyState get {
X    shift-names 1 index known { true store } { pop } ifelse
X  } forall
X} def
X
X/key-names 40 dict def
Xkey-names begin
X  8 (Backspace) def
X  9 (Tab) def
X  10 (Newline) def
X  13 (Return) def
X  27 (Escape) def
X  32 (Space) def
X  127 (Delete) def
Xend % key-names
X
X/key-name { % key => string
X  dup type /integertype eq {
X    dup 127 and
X    key-names 1 index known {
X      key-names exch get
X    } {
X      dup 32 lt {
X        64 add cvis (^%) sprintf
X      } {
X        cvis
X      } ifelse
X    } ifelse
X    exch 128 ge {
X      (Meta-%) sprintf
X    } if
X  } {
X    (%) sprintf
X  } ifelse
X} def
X
X/comment-string { % obj => string
X  dup array? {
X    dup length 2 ge {
X      dup 1 get /comment eq {
X	0 get
X      } if
X    } if
X  } if
X  (%) sprintf
X} def
X
X/destroy { % dummy destroy method for items
X} def
X
X% Forward messages on to stack 
X/prompt {
X  {} execute-it
X} def
X
X/execute-it {
X  /execute-it dialog-item send
X} def
X
X/exec-it {
X  /exec-it dialog-item send
X} def
X
X/push-it {
X  /push-it dialog-item send
X} def
X
X/kbd-select-object {
X  gsave
X    can setcanvas
X    select-object
X  grestore
X} def
X
X/kbd-select-pointer {
X  gsave
X    can setcanvas
X    select-pointer
X  grestore
X} def
X
X/kbd-select-interval {
X  gsave
X    can setcanvas
X    select-interval
X  grestore
X} def
X
X% This is here because the scanner doesn't believe that \r's end comments!
X/remove-returns { % str => str'
X  dup (\r) search not { pop } { % str rest \r pre
X    length 1 add exch pop % str rest len
X    3 -1 roll dup length string copy % rest len str'
X    3 1 roll { % str' rest len
X      2 index 1 index 1 sub 10 put
X      exch (\r) search { % str' len rest \r pre
X	length 1 add exch pop % str' len rest len
X	3 -1 roll add % str' rest len
X      } { % str' len rest
X	pop pop exit
X      } ifelse
X    } loop
X  } ifelse
X} def
X
X% Quantize the font size to a multiple of .5 so we don't blow up the
X% font cache. (This is mainly for X11/NeWS.)
X/scalefontquant { % font size => font
X  2 mul round 2 div scalefont
X} def
X
X% Stolen from:
X% stickem version 1.0
X% Written by Josh Siegel (Wed Jun 29 1988)
X
XXNeWS? {
X
X  /find_canvas { % x y => [canvases]
X    canvasesunderpoint
X  } def
X
X} { % NeWS 1.1
X
X  % getxyloc returns the position of the next left-button
X  % mouse up event.  It passes all other events.
X
X  /getxyloc { %  => x y
X    gsave % ???
X      framebuffer setcanvas % ???
X      10 dict 
X      begin
X	  createevent
X	  dup /Priority 20 put
X	  dup /Name /LeftMouseButton put
X	  dup /Action /UpTransition put
X	  /foobar exch def
X	  foobar expressinterest
X	  {
X	      awaitevent
X	      dup /Name get /LeftMouseButton eq { 
X		  exit 
X	      } if
X	      redistributeevent
X	  } loop
X	  foobar revokeinterest
X	  dup /XLocation get
X	  exch /YLocation get
X      end
X    grestore % ???
X  } def
X
X  % find_tree traverses the canvas tree passed to it and calls
X  % check_canvas to check to see if the point is in the
X  % canvas.   It is also a example of a recursive NeWS routine.
X
X  /find_tree { % canvas => found?
X      dup null eq {
X	  pop false
X      } {
X	  dup /Mapped get {
X	      dup check_canvas {
X	          dup [ exch ] answer exch append /answer exch def
X		  /TopChild get
X		  {   dup null eq {
X			  pop true exit
X		      } if
X		      dup find_tree { pop true exit } if
X		      /CanvasBelow get
X		  } loop
X	      } {
X		pop false
X	      } ifelse
X	  } {
X	    pop false
X	  } ifelse
X      } ifelse
X  } def
X
X  % Check canvas checks to see if the point is inside of the
X  % clipping path of the canvas.  This is VERY important for things
X  % like the clock where the clipping path is round.
X  %
X
X  /check_canvas { % canvas => boolean
X      framebuffer setcanvas % ???
X      dup getcanvaslocation % can xwin ywin
X      ypnt exch sub % can xwin ypnt-ywin
X      exch xpnt exch sub exch % can xpnt-xwin ypnt-ywin
X      3 -1 roll setcanvas clipcanvaspath pointinpath % boolean
X      framebuffer setcanvas
X  } def
X
X  % find_canvas is a convient front end to the whole system.
X  % I use a local dictionary to help in garbage collected in case
X  % this routine is later used as part of a larger piece of code.
X
X  /find_canvas { % x y => [canvas]
X    gsave % ???
X      framebuffer setcanvas % ???
X      10 dict
X      begin
X	  /answer [ ] def
X	  /ypnt exch def
X	  /xpnt exch def
X	  framebuffer find_tree
X	  answer
X      end
X    grestore % ???
X  } def
X
X} ifelse
X
X%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
X% CyberMenu class definition
X
X/CyberMenu
X  systemdict /SoftMenu known { SoftMenu } { PieMenu } ifelse
Xdef
X
X/PulloutCyberMenu
X  PulloutPieMenu
Xdef
X
X%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
X% NeWSScrollBar item definition
X
Xsystemdict begin % this is for textcan.ps
X
X/NeWSScrollbar SimpleScrollbar []
Xclassbegin
X   /setbgcolor { % color - => -
X     /BoxFillColor exch def 
X     /ButtonFillColor BoxFillColor def
X   } def
Xclassend def
X
Xend % systemdict
X
X%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
X% StructItem class definition
X
X% This huge blob implements the data doo-dads.
X% It just kept getting bigger and bigger, before I realized what 
X% was happening. This class should be factored out into several 
X% classes... (I'll probably just reimplement it in NDE from 
X% scratch.)
X
X/StructItem LabeledItem
Xdictbegin
X
X%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
X% Instance variables
X
X  /Shrink .9 def
X  /Pad 3 def
X  /Point null def
X  /x 0 def
X  /y 0 def
X  /Levels 0 def
X  /DL null def
X  /ItemFrame 2 def
X  /ItemRadius 5 def
X  /ItemBorder 6 def
X  /ItemButton [PointButton AdjustButton MenuButton] def
X  /StackI null def
X  /LayoutLock null def
X  /LastX 0 def
X  /LastY 0 def
X  /LastTime 0 def
X  /Clicks 1 def
X  /TrackProc null def
X  /DX 0 def /DY 0 def
X  /TabX 0 def
X  /TabY 0 def
X  /TabWidth 0 def
X  /TabHeight 0 def
X  /PinX 0 def
X  /StartIndex 0 def
X  /LastIndex 0 def
X  /OldIndex 0 def
X  /MySiblings null def
X  /layout-proc /layout-struct def
X  /click-proc /click-transfer def
X  /transfer-proc /paste-obj def
X  /display-proc /display-tree-struct def
X  /erase-proc /erase-label def
X  /label-proc /object-label def
X  /lw null def
X  /lh null def
X  /lx null def
X  /ly null def
X  /BigWidth 64 def
X  /BigHeight 64 def
X  /Filter? false def
X  /OpenToRight? false def
X  /ShowFan? true def
Xdictend
Xclassbegin
X
X%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
X% Class variables
X
X  /StartPoint 18 def
X  /DoubleClickTime 2 60 div def
X  /DoubleClickDistanceSquared 8 dup mul def
X  /CanvasYFudge 2 store
X  /Sort? true def
X  /SubStructureIndent 10 def
X  /LineGap 30 def
X  /Icon? false def
X  /SortBy /by-name def
X  /ItemLabelFont /Helvetica-Bold findfont 14 scalefontquant def
XXNeWS? { % How about something sexy...
X%   /ItemFont /AvantGarde-Book findfont def % Normal font
X%   /ItemXFont /AvantGarde-BookOblique findfont def % Executable font
X%   /ItemSFont /AvantGarde-Book findfont def % Small font
X%   /ItemFont /GillSans findfont def % Normal font
X%   /ItemXFont /GillSans-Italic findfont def % Executable font
X%   /ItemSFont /GillSans findfont def % Small font
X  /ItemFont /LucidaSans findfont def % Normal font
X  /ItemXFont /LucidaSans-Italic findfont def % Executable font
X  /ItemSFont /LucidaSans findfont def % Small font
X  /SmallPointSize 7 def % Use small font when smaller than this.
X} { % NeWS 1.1
X  /ItemFont /Courier-Bold findfont def % Normal font
X  /ItemXFont /Courier-BoldOblique findfont def % Executable font
X  /ItemSFont /Courier findfont def % Small font
X  /SmallPointSize 10 def % Use small font when smaller than this.
X} ifelse
X
X%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
X% Initialization stuff
X
X  /new { % Collection Index notifyproc parentcanvas => instance
X    4 2 roll 2 copy get type (% \267) sprintf % notify parent cont ind label
X    5 1 roll 2 array astore % label notify parent object
X    3 1 roll /Right % label object notify parent loc
X    3 1 roll % label object loc notify parent
X    /new super send begin
X       ItemCanvas /Transparent false put
X%       ItemCanvas /Transparent true put
X       ItemCanvas /Retained true put
X       /LayoutLock createmonitor def
X       /xhair /xhair_m ItemCanvas setstandardcursor
X    currentdict end
X  } def
X
X  /ensure-DL {
X    DL null eq {
X      Collection Index Levels grow-struct
X      /DL exch store
X      /ObjectWidth 0 store
X    } if
X    ObjectWidth 0 eq ObjectHeight 0 eq or { 
X        perform-layout
X    } if
X  } def
X
X  /makestartinterests {
X    /makestartinterests super send
X    [ exch aload pop
X      /DoTransfer {/DoTransfer /Self GetFromCurrentEvent send}
X      null ItemCanvas eventmgrinterest
X      dup /Exclusivity true put
X      dup /Self self PutInEventMgrInterest
X    ]
X  } def
X
X%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
X% Event handlers
X
X  /DoTransfer { % event => -
X    ItemBegin
X      /it self store
X      CurrentEvent update-shifts
X      do-search
X      ob null eq {
X	% pththth
X      } {
X	% Are we transfering something to where it already is?
X	CurrentEvent /ClientData get ob eq {
X	  % Transfering an object into itsself toggles its opened/closed state
X	  click-open
X	} {
X	  % Beam me up, Scotty!
X	  ob begin /transfer-proc load end
X	  cvx { exec } fork pop pop
X	} ifelse
X      } ifelse
X    ItemEnd
X    pop % XXX? 
X  } def
X
X  /ClientDown {
X    ItemBegin
X      /it self store
X      currenttime LastTime sub DoubleClickTime lt 
X      CurrentEvent begin
X	LastX XLocation sub dup mul LastY YLocation sub dup mul add
X	/LastX XLocation store  /LastY YLocation store
X      end
X      DoubleClickDistanceSquared lt
X      and {
X	/Clicks Clicks 1 add store
X      } {
X	/Clicks 1 store
X      } ifelse
X      /LastTime currenttime store
X      CurrentEvent update-shifts
X      CurrentEvent /Name get MenuButton eq {
X	event-in-tab? {
X	  show-tab-menu
X	} {
X	  show-struct-menu
X	} ifelse
X      } {
X	CurrentEvent /Name get PointButton eq {
X%	  CurrentEvent recallevent
X	  event-in-tab? {
X	    items FillColor self slideitem
X	  } {
X	    do-search
X	    ob null eq {
X	      items FillColor self slideitem
X	    } {
X	      Clicks 1 eq {
X		make-selection
X	      } {
X		TrackProc null ne { TrackProc killprocess } if
X		click-exec
X	      } ifelse
X	    } ifelse
X	  } ifelse
X	} {
X	  CurrentEvent /Name get AdjustButton eq {
X	    event-in-tab? {
X	      toggle-icon
X	    } {
X	      do-search
X	      ob null eq {
X	      } {
X		NotifyUser
X	      } ifelse
X	     } ifelse
X	  } if
X	} ifelse
X      } ifelse
X    ItemEnd
X  } def
X
X  /make-selection {
X    TrackProc null ne { TrackProc killprocess } if
X    2 60 div blockinputqueue
X    /TrackProc {
X      unblockinputqueue
X      /OldIndex null store
X      obs length 1 le {
X        /MySiblings [ob] store
X	/TipX null def /TipY null def
X	/Multiple? false def
X      } {
X        obs dup length 2 sub get
X        /MySiblings 
X	  1 index /Branches get dup null eq { pop nullarray } if
X	  2 index /Controls get dup null eq { pop } { append } ifelse
X	store
X	/Pointers? false def
X        /TipX 1 index /TipX get def
X        /TipY exch /TipY get def
X	/Multiple?
X	  ob /C get array-or-string?
X	  Shift and
X	def
X      } ifelse
X      /StartIndex 
X        0 MySiblings {
X	  /I get ob /I get eq { exit } if
X	  1 add
X        } forall
X      store
X      /LastIndex StartIndex store
X      ItemCanvas createoverlay setcanvas
X      ObjectX ObjectY ObjectHeight add translate
X      currentcursorlocation
X      { newpath pop pop
X	/LastIndex
X	  0 MySiblings {
X	    /Y get y le {
X	      exit
X	    } if
X	    1 add
X	  } forall
X	  MySiblings length 1 sub min
X	store
X	Multiple? not {
X	  /StartIndex LastIndex store
X	} if
X	TipX null ne {
X%	  TipX TipY moveto
X	  TipX 1 add TipY moveto
X	  MySiblings StartIndex LastIndex min get begin
X%	    X Y H add lineto
X	    X Y H add 1 sub lineto
X	  end
X	  MySiblings StartIndex LastIndex max get begin
X%	    X Y lineto
X	    X Y 1 add lineto
X	  end
X	  closepath
X	  fill
X	} if
X	MySiblings StartIndex LastIndex min get begin
X	  X 1 sub Y H add moveto
X	end
X        StartIndex LastIndex min  1  StartIndex LastIndex max {
X	  MySiblings exch get begin
X	    X W add dup Y H add lineto
X	    Y lineto
X	  end
X	} for
X	MySiblings StartIndex LastIndex max get begin
X	  X 1 sub Y lineto
X	end
X	closepath
X	Shift { stroke } { fill } ifelse
X
X	OldIndex LastIndex ne {
X	  /OldIndex LastIndex store
X	  Multiple? {
X	    % Don't select part of control panel
X	    MySiblings StartIndex get /C get 
X	    MySiblings LastIndex get /C get eq {
X	      MySiblings StartIndex get /C get
X	      StartIndex LastIndex 2 copy gt {exch} if
X	      MySiblings exch get /I get exch
X	      MySiblings exch get /I get exch
X	      1 index sub 1 add
X	      kbd-select-interval
X	    } if
X	  } {
X	    MySiblings LastIndex get
X	    Shift { % Shift to select array index
X	       /I get kbd-select-object
X	    } {
X	       dup /C get exch /I get kbd-select-pointer
X	    } ifelse
X	  } ifelse
X	} if
X
X      } getanimated waitprocess
X      /MySiblings null store
X      /TrackProc null store
X    } fork store
X  } def
X
X  /show-tab-menu {
X    userdict /it self put
X    CurrentEvent /showat TabMenu send
X  } def
X
X  /show-struct-menu {
X    ItemBegin
X      do-search
X      ob null eq { /ob DL store } if
X      ob null ne {
X	CurrentEvent /showat StructMenu send
X      } if
X    ItemEnd
X  } def
X
X  /ClientUp {
X    StopItem
X  } def
X
X  /click-exec {
X    Shift { click-step } {
X      ob /Obj get exec-it
X    } ifelse
X  } def
X
X  /click-transfer {
X    2 60 div blockinputqueue
X    {
X      unblockinputqueue
X      % (Aaah, that feels much better -- thanks Stan!)
X      gsave 10 dict begin
X	Shift { % Shift to select the index
X	 ob /I get
X	} {
X	 ob /Obj get
X	} ifelse
X	/thing exch def
X	/thing load kbd-select-object
X	/str /thing load smart-name def
X	ItemLabelFont setfont
X	fboverlay setcanvas
X	currentcursorlocation
X	{ lineto str show } getanimated waitprocess aload pop % x y
X	createevent begin
X	  /Name /DoTransfer def
X	  /YLocation exch def /XLocation exch def
X	  /Action 1 dict def
X	  Action begin
X	    /Source /thing load def
X	  end
X	  % We're sneaking this in so DoTransfer can tell if we're transfering
X	  % something to where it already is, in which case we just do a
X	  % click-open, to open or close the object's internal structure.
X	  /ClientData ob def
X	  currentdict sendevent
X	end
X      grestore
X    } fork pop
X  } def
X
X  /click-magic {
X    % Invoke magic editing function...
X    obs length 1 gt {
X      { ob /C get dup array-or-string? { pop currentdict } if
X        begin
X          ob /Obj get 
X	  use-parent-obj 
X	  cvx exec
X	end
X      } fork pop pause
X    } if
X  } def
X
X  /click-edit {
X    % Invoke magic editing function...
X    obs length 1 gt {
X      { ob /C get dup array-or-string? { pop currentdict } if
X        begin
X          ob /Obj get cvx change-parent-obj
X	end
X      } fork pop pause
X    } if
X  } def
X
X  /click-push {
X    push-obj
X  } def
X
X  /old-click-step {
X    [ ob /Obj get ] cvx exec-it
X  } def
X
X  /click-step {
X    gsave
X      ItemCanvas createoverlay setcanvas
X      ObjectX ObjectY ObjectHeight add translate
X      ob dup begin
X        X Y W H rectpath 
X      end
X      [ exch /Obj get
X	/gsave load %  Whip me beat me make me check bad writes!
X	  currentstate /setstate load /erasepage load
X	/grestore load 
X      ] cvx fill exec-it
X
X      obs length 1 le {
X        /MySiblings [ob] store
X      }{
X        obs dup length 2 sub get
X        /MySiblings
X	  1 index /Branches get dup null eq { pop nullarray } if
X	store
X      } ifelse
X      /StartIndex
X        0 MySiblings {
X	  /I get ob /I get eq { exit } if
X	  1 add
X        } forall
X      store
X      /LastIndex StartIndex store
X      currentcursorlocation
X      { newpath pop pop
X	/LastIndex
X	  0 MySiblings {
X	    /Y get y le {
X	      exit
X	    } if
X	    1 add
X	  } forall
X	  MySiblings length 1 sub min
X	store
X	{ StartIndex LastIndex ge { exit } if
X	  /StartIndex StartIndex 1 add store
X
X          MySiblings StartIndex get dup begin
X            newpath X Y W H rectpath 
X          end
X          [ exch /Obj get
X            /gsave load %  Whip me beat me make me check bad writes!
X	      currentstate /setstate load /erasepage load
X	    /grestore load
X          ] cvx fill exec-it
X	} loop
X      } getanimated waitprocess
X      /MySiblings null store
X    grestore
X  } def
X
X  /click-type-dict 100 dict def
X  click-type-dict begin
X    /integertype {
X      Shift 1 -1 ifelse add
X    } def
X    /realtype {
X      Shift -1 1 ifelse add
X    } def
X    /booleantype {
X      not
X    } def
X  end % click-type-dict
X
X  /click-type {
X    ob /Obj get dup type
X    click-type-dict 1 index known {
X      click-type-dict exch get
X      cvx exec
X      replace-obj
X    } {
X      pop pop %%% /click-proc load cvx exec
X    } ifelse
X  } def
X
X  /click-dragcanvas {
X    { ob /C get ob /I get get 
X      dup /Parent get null eq { pop } {
X        gsave
X	  setcanvas false dragcanvas
X	grestore
X	obs { begin } forall
X	ItemTextColor setcolor
X	ObjectX ObjectY ObjectHeight add translate
X	currentdict end draw-struct
X	obs length 1 sub { end } repeat
X      } ifelse
X    } fork pop
X  } def
X
X  /click-dragimage {
X    { ob /C get ob /I get get % % can
X      gsave
X        dup createoverlay setcanvas
X	ob /C get % EditorDict
X	begin % EditorDict
X	    currentcursorlocation
X	    { 2 copy
X	      y0 sub ViewY exch sub /ViewY exch store
X	      x0 sub ViewX exch sub /ViewX exch store
X	      /y0 exch store /x0 x store
X	      ViewX ViewY ViewWidth ViewHeight rectpath
X	    } getanimated waitprocess pop
X	end % EditorDict
X	obs { begin } forall
X	  ItemCanvas setcanvas
X	  ItemTextColor setcolor
X	  ObjectX ObjectY ObjectHeight add translate
X	  currentdict end draw-struct
X	obs length 1 sub { end } repeat
X      grestore
X    } fork pop
X  } def
X    
X  /handle-click { % - => -
X    ob null ne {
X%      obs /begin load forall
X      ob begin
X        /click-proc load 
X      end % ob
X%      obs length /end load repeat
X      cvx exec
X    } if
X%    pop % ??? the notifyproc should not pop the event
X  } def
X
X  /open-icon {
X    Icon? {
X      /ObjectWidth OW store
X      /ObjectHeight OH store
X      currentdict /Icon? undef
X      redo-shape
X    } if
X  } def
X
X  /close-icon {
X    Icon? not {
X      gsave
X        /OW ObjectWidth def
X        /OH ObjectHeight def
X        Font setfont Str stringbbox points2rect
X        /IconH exch def /IconW exch def
X	pop pop
X        /ObjectWidth IconW store
X        /ObjectHeight IconH store
X      grestore
X      /Icon? true def
X      redo-shape
X    } if
X  } def
X
X  /toggle-icon {
X    DL begin
X      Icon? { open-icon } { close-icon } ifelse
X    end
X    /LastTime 0 store
X  } def
X
X  /click-select {
X    Clicks 1 eq {
X      % first click
X      ob null ne {
X	Shift { % Shift to select the index
X	  ob /I get
X	} {
X	  ob /Obj get
X	} ifelse
X	Control {
X	  exec-it
X	  /LastTime 0 store
X	} {
X	  kbd-select-object
X	} ifelse
X      } if
X    } {
X      click-open
X    } ifelse
X  } def
X
X  /click-open {
X      ob null ne {
X	DL begin Icon? end {
X	  toggle-icon
X	} {
X	  Shift {
X	    ob /L get 1 add open-struct
X	  } {
X	    ob /L get 0 eq {
X	      1 open-struct
X	    } {
X	      close-struct
X	    } ifelse
X	  } ifelse
X	} ifelse
X      } if
X  } def
X
X  /event-in-tab? {
X    ItemBegin
X      newpath label-bbox rectpath
X      CurrentEvent begin XLocation YLocation end pointinpath
X    ItemEnd
X  } def
X
X  /ClientExit {
X    StopItem
X  } def
X
X  /Silent? { % - => bool
X    Meta Control Shift or and
X  } def
X
X%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
X% Menu callbacks
X
X  /push-array-obj {
X    ob /Obj get % [stack] 
X    selected-object % [stack] top
X    1 index type /stringtype eq 1 index type /integertype ne and {
X      pop pop
X    } {
X      1 index type /stringtype eq {
X	cvis
X      } {
X        [ exch ]
X      } ifelse % [stack] [top]
X      1 index exch append % [stack] [stack top]
X      exch xcheck { cvx } if
X      replace-obj
X    } ifelse
X  } def
X
X  /pop-array-obj {
X    ob /Obj get
X    dup length 0 eq { pop } {
X      dup dup length 1 sub get kbd-select-object
X      0 1 index length 1 sub getinterval
X      replace-obj
X    } ifelse
X  } def
X
X  /prepend-to-array-obj {
X    selected-object dup array-or-string? not { pop } { % [sel]
X      ob /Obj get % [sel] {obj}
X      dup type /stringtype eq % [sel] {obj} objstring?
X      1 index type /stringtype eq xor { % [sel] {obj}
X	% incompatible types
X        pop pop %
X      } { % [sel] {obj}
X	exch 1 index % {obj} [sel] {obj}
X	append % {obj} [sel obj]
X	exch xcheck { cvx } if % {sel obj}
X	replace-obj %
X      } ifelse
X    } ifelse
X  } def
X
X  /append-to-array-obj {
X    selected-object dup array-or-string? not { pop } { % [sel]
X      ob /Obj get % [sel] {obj}
X      dup type /stringtype eq % [sel] {obj} objstring?
X      1 index type /stringtype eq xor { % [sel] {obj}
X	% incompatible types
X        pop pop %
X      } { % [sel] {obj}
X	dup 3 -1 roll % {obj} {obj} [sel]
X	append % {obj} [obj sel]
X	exch xcheck { cvx } if % {obj sel}
X	replace-obj %
X      } ifelse
X    } ifelse
X  } def
X
X  /top-array-obj {
X    selected-pointer-or-interval? { %  collection start last
X      2 index ob /Obj get ne {
X	pop pop pop
X	% error: first select part of this array
X      } {
X	10 dict begin
X	  /Last exch def /Start exch def /Len exch length def
X          [ ob /Obj get {} forall
X	    Len Start neg roll
X	    Start Len Last sub 1 sub add Start roll
X	  ] ob /Obj get
X	  dup type /stringtype eq { % [65 66 67] (abc)
X	    exch 0 exch { % (abc) 0 65
X	      3 copy put pop 1 add
X	    } forall
X	    pop pop
X	  } {
X	    copy pop
X	  } ifelse
X        end
X	ob /Obj get replace-obj
X      } ifelse
X    } if
X  } def
X
X  /bottom-array-obj {
X    selected-pointer-or-interval? { %  collection start last
X      2 index ob /Obj get ne {
X	pop pop pop
X	% error: first select a part of this array
X      } {
X	10 dict begin
X	  /Last exch def /Start exch def /Len exch length def
X          [ ob /Obj get {} forall
X	    Len Start sub
X	    Len Last sub 1 sub roll
X	  ] ob /Obj get
X	  dup type /stringtype eq { % [65 66 67] (abc)
X	    exch 0 exch { % (abc) 0 65
X	      3 copy put pop 1 add
X	    } forall
X	    pop pop
X	  } {
X	    copy pop
X	  } ifelse
X        end
X	ob /Obj get replace-obj
X      } ifelse
X    } if
X  } def
X
X  /delete-array-obj {
X    selected-pointer-or-interval? { % collection start last
X      2 index ob /Obj get ne {
X	pop pop pop
X	% error: first select a part of this array
X      } {
X	10 dict begin
X	  /Last exch def /Start exch def /Cont exch cvlit def
X	  /Len Cont length def
X	  Cont 0 Start getinterval cvlit
X	  Cont Last 1 add Len Last 1 add sub getinterval cvlit
X	  append
X%           [ ob /Obj get aload pop
X% 	    Len Start sub
X% 	    Len Last sub 1 sub roll
X% 	    Last Start sub 1 add {pop} repeat
X% 	  ]
X        end
X	ob /Obj get xcheck {cvx} if
X	replace-obj
X      } ifelse
X    } if
X  } def
X
X  /splice-array-obj {
X    selected-interval? { % collection start last
X      2 copy get dup array? {
X	2 index ob /Obj get eq {
X	  10 dict begin
X	    /Last exch def /Start exch def /Len exch length def
X	    [ ob /Obj get  0  Start  getinterval  aload pop
X	      ob /Obj get  Start  Last Start sub 1 add getinterval
X	      ob /Obj get  xcheck {cvx} if
X	      ob /Obj get  Last 1 add  Len Last sub 1 sub  getinterval aload pop
X	    ]
X	  end
X	  ob /Obj get xcheck {cvx} if
X	  replace-obj
X	} {
X	  pop pop pop
X	  % error: select an array or an interval of this array
X	} ifelse
X      } {
X        pop pop pop
X	% error: can't do that to strings!
X      } ifelse
X    } {
X      selected-pointer? { % collection index
X        2 copy get dup array? { % collection index array
X	  2 index ob /Obj get eq {
X	    10 dict begin
X	      /Arr exch cvlit def /Start exch def /Len exch length def
X	      [ ob /Obj get  0  Start  getinterval  aload pop
X		Arr aload pop
X		ob /Obj get  Start 1 add  Len Start sub 1 sub
X		getinterval aload pop
X	      ]
X	    end
X	    ob /Obj get xcheck {cvx} if
X	    replace-obj
X	  } {
X	    pop pop pop
X	    % error: select an array or an interval of this array
X	  } ifelse
X	} {
X	  pop pop pop
X	  % error: select an array or an interval of this array
X	} ifelse
X      } if
X    } ifelse
X  } def
X 
X  /def-in-dict-obj {
X    selected-pointer? { % collection index
X      exch 1 index get % index obj
X      true
X    } {
X      selected-object dup null eq { pop false } { % index
X        dup type /stringtype eq { cvn } if
X        null % index object
X	true
X      } ifelse
X    } ifelse
X    { % index obj
X      ob /Obj get 3 copy pop put % index obj
X      pop ob /Obj get exch % dict index
X      ob /Branches get null eq { pop pop } { % dict index
X	0 grow-struct % DL
X	ob begin
X	  /Branches [ % DL mark
X	    Branches { % DL mark branch
X	      dup /I get
X	      counttomark 2 add index /I get
X	      eq {pop} if
X	    } forall
X	    counttomark 3 add -1 roll % mark branches... DL
X	  ] Sort? {SortBy quicksort} if def %
X	end
X      } ifelse % 
X      redo-layout
X    } if
X  } def
X
X  /undef-in-dict-obj {
X    selected-pointer? { % collection index
X      exch pop ob /Obj get exch % dict index
X      true
X    } {
X      selected-object null eq { pop false } {
X	ob /Obj get exch % dict index
X        dup type /stringtype eq { cvn } if % XXX: NeWS BUG in undef!! (Marja)
X	true
X      } ifelse
X    } ifelse
X    { % dict index
X      ob /Obj get 1 index known not { pop } { % index
X	ob /Obj get exch % dict index
X	2 copy get kbd-select-object
X	undef % 
X	ob begin
X	  Branches null ne {
X	    /Branches [
X	      Branches {
X		begin /C load /I load known { currentdict } if end
X	      } forall
X	    ] def
X	  } if
X	end
X	redo-layout
X      } ifelse % 
X    } if
X  } def
X
X  /break-obj {
X    { clear
X      ob /Obj get dup type /dicttype eq {
X	dup /ParentDict known {
X	  { { ClassName dbgbreak } exch send }
X	} {
X	  { countdictstack 1 sub { end } repeat
X	    dup begin currentdict 30 string cvs cvn dbgbreak }
X	} ifelse
X      } {
X	{ dup type dbgbreak }
X      } ifelse
X      { exec } fork pop pop
X    } fork pop
X  } def
X
X  /begin-obj {
X    ob /Obj get begin-it
X  } def
X
X  /enter-obj {
X    ob /Obj get enter-it
X  } def
X
X  /change-obj { % func => -
X    { { count 1 roll
X        count 1 sub { pop } repeat
X        ob /Obj get exch exec } errored pop 
X    } fork
X    exch pop waitprocess
X    modify-obj
X  } def
X
X  % Execute token with Externals on the dict stack, so externalized
X  % //&type_123 object references are resolved.
X  /tokein-obj {
X    ob /Obj get type /stringtype eq {
X      { clear Externals begin
X	  ob /Obj get remove-returns
X	  { { token { exch } { exit } ifelse
X	    } loop
X	  } errored {
X	    clear ob /Obj get
X	  } {
X	    count array astore cvx
X	  } ifelse
X	end
X      } fork waitprocess
X      kbd-select-object
X    } if
X  } def
X
X  /cvx-obj {
X    { ob /Obj get cvx } errored {pop} {
X%      replace-obj
X      kbd-select-object
X    } ifelse
X  } def
X
X  /cvn-obj {
X    { ob /Obj get cvn } errored {pop} {
X%      replace-obj
X      kbd-select-object
X    } ifelse
X  } def
X
X  /cvs-obj {
X    { ob /Obj get 256 string cvs } errored {pop} {
X%      replace-obj
X      kbd-select-object
X    } ifelse
X  } def
X
X  /tokeout-obj {
X    ob /Obj get tokeout 
X    kbd-select-object
X  } def
X
X  /cvlit-obj {
X    { ob /Obj get cvlit } errored {pop} {
X%      replace-obj
X      kbd-select-object
X    } ifelse
X  } def
X
X  /cvi-obj {
X    { ob /Obj get cvi } errored {pop} {
X%      replace-obj
X      kbd-select-object
X    } ifelse
X  } def
X
X  /cvr-obj {
X    { ob /Obj get cvr } errored {pop} {
X%      replace-obj
X      kbd-select-object
X    } ifelse
X  } def
X
X  /load&push-obj {
X    ob /Obj get load&push-it
X  } def
X
X  /load&push-it { %
X    [ exch cvlit {dup load} /errored cvx
X      { pop smart-name (%% ) (%Load: % is not defined!\n) printf }
X      { exch smart-name 1 index smart-name exch
X	(%% ) (%Load: % Push: %\n) printf }
X      /ifelse cvx ] cvx
X    execute-it
X  } def
X
X  /load-obj {
X    ob Shift /I /Obj ifelse get load-it
X  } def
X
X  /load-it { %
X    [ exch cvlit {dup load} /errored cvx
X      { pop smart-name (%% ) (%Load: % is not defined!\n) printf }
X      { exch smart-name 1 index smart-name exch
X        (%% ) (%Load: % Select: %\n) printf
X        select-object } /ifelse cvx ] cvx
X    execute-it
X  } def
X
X  /pointsize-obj { % point => -
X    dup /Default eq {
X      pop ob /Point undef
X    } {
X      ob exch /Point exch put
X    } ifelse
X    redo-layout
X  } def
X
X  /shrink-obj { % shrink => -
X    dup /Default eq {
X      pop ob /Shrink undef
X    } {
X      ob exch /Shrink exch put
X    } ifelse
X    redo-layout
X  } def
X
X  /update-obj {
X    % ...
X  } def
X
X  /open-obj { % levels => -
X    dup 0 eq { pop close-struct } { open-struct } ifelse
X  } def
X
X  /set-open-direction { % bool => -
X    { /Right {
X	ob /OpenToRight? true put
X      }
X      /Below {
X	ob /OpenToRight? false put
X      }
X      /Default {
X	ob /OpenToRight? undef
X      }
X    } case
X  } def
X
X  /open-right-obj { % levels => -
X    /Right set-open-direction open-obj
X  } def
X
X  /open-below-obj { % levels => -
X    /Below set-open-direction open-obj
X  } def
X
X  /set-show-fan { % bool => -
X    dup { 
X      true false { ob exch /ShowFan? exch put }
X      /Default { pop ob /ShowFan? undef }
X    } case
X  } def
X
X  /push-obj {
X    ob Shift /I /Obj ifelse get push-it
X  } def
X
X  /push-it {
X    [ exch [ exch ] 0 /get cvx
X      /dup cvx /smart-name cvx (%% ) (%Push: %\n) /printf cvx ] cvx
X    execute-it
X  } def
X
X  /begin-it {
X    [ exch [ exch ] 0 /get cvx
X      /dup cvx /smart-name cvx (%% ) (%Begin: %\n) /printf cvx 
X      /begin cvx /dstack cvx
X    ] cvx
X    execute-it
X  } def
X
X  /enter-it {
X    [ exch [ exch ] 0 /get cvx
X      /dup cvx /smart-name cvx (%% ) (%Enter: %\n) /printf cvx 
X      /enter cvx
X    ] cvx
X    execute-it
X  } def
X
X  /insert-before-obj {
X  } def
X
X  /insert-after-obj {
X  } def
X
X  /molecule-obj {
X    ob /Obj get start_visualizer
X  } def
X
X  % construct a reference to a piece of substructure relative to the 
X  % top level object
X  /reference-obj {
X    obs length 2 lt { {} } {
X      [ obs dup 1 exch length 1 sub getinterval {
X          /I get cvlit /get cvx
X        } forall
X      ] cvx kbd-select-object
X    } ifelse
X  } def
X
X  /exec-obj {
X    ob /Obj get Shift {[exch]cvx} if exec-it
X  } def
X
X  /exec-it { % obj => -
X    { [ exch cvlit /cvx cvx 
X        /dup cvx /smart-name cvx (%% ) (%Exec: %\n) /printf cvx
X        cvx /exec cvx ] cvx
X      execute-it
X    } fork pop pop pause
X  } def
X
X  /paste-obj {
X    selected-object
X    replace-obj
X  } def
X
X  /replace-obj { % obj => -
X    ob begin
X      replace-struct
X    end
X    Silent? not { redo-layout } if
X    ob DL eq StackI null ne and { % Tell processes if we changed its stack.
X      /ReplaceStack items StackI get send
X    } if
X  } def
X
X  /modify-obj { % obj => -
X    LayoutLock {
X      ob begin
X	gsave
X	  ItemCanvas setcanvas
X	  ObjectX ObjectY ObjectHeight add translate
X	  /erase-proc load cvx exec
X          C I 3 -1 roll put
X	  make-label change-label
X	grestore
X      end
X    } monitor
X    ob DL eq StackI null ne and { % Tell processes if we changed its stack.
X      /ReplaceStack items StackI get send
X    } if
X  } def
X
X  /make-label { % - => str
X    /Obj /C load /I load get def
X    % get default if not defined (don't use parent's)
X    currentdict /label-proc known {
X      /label-proc load 
X    } {
X      self /label-proc get
X    } ifelse
X    cvx exec
X  } def
X
X
X  % func is passed the object, and the object is replaced by 
X  % whatever's left on the top of stack.
X  /transform-obj { % func => -
X    LayoutLock {
X      ob begin
X	gsave
X	  ItemCanvas setcanvas
X	  ObjectX ObjectY ObjectHeight add translate
X	  /erase-proc load cvx exec
X          C I 2 copy get 4 -1 roll {errored pop} fork waitprocess
X	  exch pop exch pop put
X	  pop pop
X	  make-label change-label
X	grestore
X      end
X    } monitor
X    ob DL eq StackI null ne and { % Tell processes if we changed its stack.
X      /ReplaceStack items StackI get send
X    } if
X  } def
X
X%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
X% Moving and shaping
X
X  /just-reshape {
X% Core dumps X11/NeWS beta 1:
X    ItemCanvas null ne { ItemCanvas /Mapped false put } if
X
X    /ItemHeight exch store /ItemWidth exch store
X
X    ItemWidth 0 eq ItemHeight 0 eq or {
X      /DL null store
X    } if
X    ensure-DL
X
X    adjust-geometry
X
X    ItemWidth ItemHeight /reshape super send
X    gsave ItemCanvas setcanvas ItemFillColor fillcanvas grestore
X
X    ItemCanvas /Mapped true put
X  } def
X
X  /reshape { % x y w h => -
X    just-reshape
X    location move
X  } def
X
X  /just-move { % x y => -
X    /move super send
X  } def
X
X  /move { % x y => -
X    label-bbox /lh exch store /lw exch store % x y lx ly
X    2 index add /ly exch store % x y lx
X    2 index add /lx exch store % x y
X    ly 0 max /ClientHeight win send lh sub min ly sub add exch
X    lx 0 max /ClientWidth win send lw sub min lx sub add exch
X    cvi exch cvi exch /move super send
X    snaps-here? pop
X    Index ThisI eq {
X      /paint-hilite win send
X    } if
X    StackI null ne StackI Index ne and {
X      /MoveMe TellStack
X    } if
X  } def
X
X  /redo-layout {
X    gsave
X      ItemCanvas setcanvas
X      ObjectX ObjectY ObjectHeight add translate
X      perform-layout
X      redo-shape
X    grestore
X  } def
X
X  /redo-shape {
X    %location 10 10 just-reshape
X    location 10 10 reshape
X    damage-view
X  } def
X
X  /label-bbox { % x y w h
X    TabX TabY TabWidth TabHeight
X  } def
X
X  /tab-top { % - => y
X    location TabY add TabHeight add exch pop
X  } def
X
X  /tab-bottom { % - => y
X    location TabY add exch pop
X  } def
X
X  /label-rect { %  X Y w h
X    location TabY add exch TabX add exch TabWidth TabHeight
X  } def
X
X  /object-bbox { % x y w h
X    ObjectX ItemBorder sub  ObjectY ItemBorder sub % x y
X    ObjectWidth ItemBorder dup add add % w
X    ObjectHeight ItemBorder dup add add % h
X  } def
X
X  /ItemPath {
X    ItemRadius label-bbox rrectpath
X    ItemRadius object-bbox rrectpath
X  } def
X
X  /AdjustItemSize { % - => - [uses item context]
X      ObjectLoc {
X      /Right /Left /RightBelow /RightAbove /LeftBelow /LeftAbove {
X	  /ItemWidth ItemBorder 3 mul ItemGap add
X	      LabelWidth add ObjectWidth add store
X	  /ItemHeight ItemBorder 2 mul LabelHeight
X	      ObjectHeight max add store
X      }
X      /Top /Bottom /AboveLeft /AboveRight /BelowLeft /BelowRight {
X	  /ItemWidth ItemBorder 2 mul LabelWidth ObjectWidth max add store
X	  /ItemHeight ItemBorder 3 mul ItemGap add
X	      LabelHeight add ObjectHeight add store
X      }
X      } case
X  } def
X
X  /CalcObj&LabelXY { % - => - [uses item context]
X    ObjectLoc {
X      /RightAbove {
X	  /LabelX ItemBorder def /LabelY ItemBorder store
X	  /ObjectX ItemBorder dup add LabelWidth add ItemGap add store
X	  /ObjectY ItemHeight ObjectHeight sub 2 div store
X	  /TabX LabelX ItemBorder sub def /TabY LabelY ItemBorder sub store
X	  /TabWidth
X	    ItemBorder LabelWidth add ItemGap add ItemRadius dup add add store
X	  /TabHeight LabelHeight ItemBorder dup add add def }
X      /RightBelow /Right {
X	  /LabelX ItemBorder store
X	  /LabelY ItemHeight ItemBorder sub LabelHeight sub store
X	  /ObjectX ItemBorder dup add LabelWidth add ItemGap add store
X	  /ObjectY ItemHeight ObjectHeight sub 2 div store
X	  /TabX LabelX ItemBorder sub def /TabY LabelY ItemBorder sub store
X	  /TabWidth
X	    ItemBorder LabelWidth add ItemGap add ItemRadius dup add add store
X	  /TabHeight LabelHeight ItemBorder dup add add def }
X      /LeftAbove {
X	  /LabelX ItemBorder dup add  ItemGap add ObjectWidth add store
X	  /LabelY ItemBorder store
X	  /ObjectX ItemBorder store
X	  /ObjectY ItemHeight ObjectHeight sub 2 div store
X	  /TabX LabelX ItemGap sub ItemRadius dup add sub store
X	  /TabY LabelY ItemBorder sub store
X	  /TabWidth
X	    ItemRadius dup add ItemGap add LabelWidth add ItemBorder add store
X	  /TabHeight LabelHeight ItemBorder dup add add def }
X      /LeftBelow /Left {
X	  /LabelX ItemBorder dup add ItemGap add ObjectWidth add store
X	  /LabelY ItemHeight ItemBorder sub LabelHeight sub store
X	  /ObjectX ItemBorder store
X	  /ObjectY ItemHeight ObjectHeight sub 2 div store
X	  /TabX LabelX ItemGap sub ItemRadius dup add sub store
X	  /TabY LabelY ItemBorder sub store
X	  /TabWidth
X	    ItemRadius dup add ItemGap add LabelWidth add ItemBorder add store
X	  /TabHeight LabelHeight ItemBorder dup add add def }
X      /AboveRight /Top {
X	  /LabelX ItemBorder def /LabelY ItemBorder store
X	  /ObjectX ItemWidth ObjectWidth sub 2 div store
X	  /ObjectY ItemBorder dup add LabelHeight add ItemGap add store
X	  /TabX LabelX ItemBorder sub def /TabY LabelY ItemBorder sub store
X	  /TabWidth LabelWidth ItemBorder dup add add store
X	  /TabHeight
X	    ItemBorder LabelHeight add ItemGap add ItemRadius dup add add
X	  def }
X      /AboveLeft {
X	  /LabelX ItemWidth ItemBorder sub LabelWidth sub store
X	  /LabelY ItemBorder store
X	  /ObjectX ItemWidth ObjectWidth sub 2 div store
X	  /ObjectY ItemBorder dup add LabelHeight add ItemGap add store
X	  /TabX LabelX ItemBorder sub def /TabY LabelY ItemBorder sub store
X	  /TabWidth LabelWidth ItemBorder dup add add store
X	  /TabHeight
X	    ItemBorder LabelHeight add ItemGap add ItemRadius dup add add
X	  def }
X      /BelowRight /Bottom {
X	  /LabelX ItemBorder store
X	  /LabelY ItemBorder dup add ObjectHeight add ItemGap add store
X	  /ObjectX ItemWidth ObjectWidth sub 2 div store
X	  /ObjectY ItemBorder store
X	  /TabX LabelX ItemBorder sub store
X	  /TabY LabelY ItemGap sub ItemRadius dup add sub store
X	  /TabWidth LabelWidth ItemBorder dup add add store
X	  /TabHeight
X	    ItemRadius dup add ItemGap add LabelHeight add ItemBorder add
X	  def }
X      /BelowLeft {
X	  /LabelX ItemWidth ItemBorder sub LabelWidth sub store
X	  /LabelY ItemBorder dup add ObjectHeight add ItemGap add store
X	  /ObjectX ItemWidth ObjectWidth sub 2 div store
======== END OF cyber.shar.splitad ========