========================================================================

The CyberSpace Deck Manual

  Don Hopkins		     Grasshopper Group		Last update
  don@brillig.umd.edu	     grass@toad.com		22 July 89

========================================================================

Introduction

The CyberSpace deck lets you graphically display and manipulate the many
PostScript data strutures, programs, and processes living in the virtual
memory space of NeWS.

The Network extensible Window System (NeWS) is a multitasking object
oriented PostScript programming environment.  NeWS programs and data
structures make up the window system kernel, the user interface
toolkit, and even entire applications.

The CyberSpace deck is one such application, written entirely in
PostScript, the result of an experiment in using a graphical programming
environment to construct a interactive visual user interface to itself.

It displays views of structured data objects in overlapping windows that
can be moved around on the screen, and manipulated with the mouse:  you
can copy and paste data structures from place to place, execute them,
edit them, open their substructures up to any depth, adjust the scale to
shrink and magnify parts of the display, and pop up menus of other useful
commands.  Deep or complex data structures can be more easily grasped by
applying various views to them.

There is a window onto a NeWS process, a PostScript interpreter with
which you can interact (as with an "executive").  PostScript is a stack
based language, so the window has a spike sticking up out of it,
representing the process's operand stack.  Objects on the process's stack
are displayed in windows with their tabs pinned on the spike.  (Figure
xxx) You can feed PostScript expressions to the interpreter by typing
them with the keyboard, or pointing and clicking at them with the mouse,
and the stack display will be dynamically updated to show the results.

Not only can you examine and manipulate the objects on the stack, but you
can also manipulate the stack directly with the mouse.  You can drag the
objects up and down the spike to change their order on the stack, and
drag them on and off the spike to push and pop them; you can take objects
off the spike and set them aside to refer to later, and close them into
icons so they don't take up as much screen space.

NeWS processes running in the same window server can be debugged using
the existing NeWS debug commands in harmony with the graphical stack
and object display.

The CyberSpace deck can be used as a "hands on" way to learn about
programming in PostScript and NeWS.  You can try out examples from
cookbooks and manuals, and explore and enrich your understanding of
the environment with the help of the interactive data structure 
display.

========================================================================
========================================================================

Concepts

This section describes some concepts that you should be familiar with
when using the CyberSpace Deck.  It describes the most important types of
PostScript data structures, and tells you how they look displayed on the
screen.

It also gives references to sections of other manuals that explain the
concepts in more detail (Delimited by ~tildes~.)

  Referenced Manuals

      ~Blue: Adobe PostScript Language Tutorial and Cookbook~
      ~Red: Adobe PostScript Language Reference Manual~
      ~Green: Adobe PostScript Language Design~
      ~NeWS: NeWS 1.1 Manual~

  Object

      ~Blue 2: Stack and Arithmetic~
      ~Blue 2.1: The PostScript Stack~
      ~Red 3.2: Interpreter~
      ~Green 2.3: The Operand Stack; Objects in the PostScript Language~

      An object is any NeWS data structure that you can push onto the
      stack or refer to in other objects.  Each object has a type, some
      attributes, and a value.
      ~Red 3.4: Data Types and Objects~

      (The word "object" is used here in a more general sense than in
      "object oriented programming."  The more specific words "class"
      and "instance" are used instead.)
      ~NeWS 6: Classes~

      When an object is displayed in a window, its type is displayed
      in the window tab.  An object's type precedes its value when 
      its displayed inside another object.  Examples:  "array [6]",
      "integer 100" (Figure xxx)

      Composite objects, such as arrays, strings, and dictionaries, which
      can be pushed on the stack or referenced by other objects, are
      represented internally as pointers to their bodies.  So there can be
      multiple references to any composite object, and its body doesn't
      get moved around in memory whenever the references are moved or
      copied.
      ~Blue 8.1:  PostScript Arrays~ 
      ~Red 3.4:  Data Types and Objects; Simple and Composite Objects~

      A reference count is maintained in the body of each composite
      object.  Once there are no longer any remaining references to an
      object, its body is automatically garbage collected and its storage
      is reclaimed.
      ~NeWS 11.8:  Object Cleanup~

  Executable/Literal

      ~Blue 4.2: Defining Procedures and Variables~
      ~Red 3.4: Data Types and Objects; Attributes of Objects~
      ~Green 2.3: The Operand Stack; Objects in the PostScript Language~
      ~Green 2.7: Procedures~

      Each object has an attribute that makes it either executable or
      literal.  This affects how the PostScript interpreter deals with it
      (whether it's used as code or data).  Each reference to an object
      has its own executable/literal bit, so you can have an executable
      and a literal reference to the same object at once.

      Executable objects are displayed in an italic font, and literal
      objects are displayed in a non-italic font.  (Figure xxx)

  String

      ~Blue 5.0: Printing Text; Introduction~
      ~Red 3.3: Syntax; Strings~
      ~Red 3.4: Data Types and Objects; String~
      ~Green 2.6: The Interpreter and the Scanner~

      Strings are delimited by parenthesis:  "string (foobar)" The
      parenthesis inside the string do not have to be quoted if they
      balance:  "string (Copyright (C) 1989)" If a string is longer
      than 80 characters, then only the first 80 are displayed,
      followed by an elipse:  "string (blablabla...bla)..."

  Name

      ~Blue 4: Procedures and Variables~
      ~Red 3.3: Syntax; Names"
      ~Red 3.4: Data Types and Objects; Name~
      ~Green 2.5: Operators and Name Lookup~

      Names are used as keys in dictionaries, to refer to the values 
      of variables and procedures.

      Executable names are displayed in italics, without a leading 
      slash: "name foo"
      Literal names are displayed with a slash before them: "name /foo"

  Array

      ~Blue 7: Loops and Conditionals~
      ~Blue 8: Arrays~
      ~Red 3.3: Syntax; Arrays, Procedures~
      ~Red 3.4: Data Types and Objects; Array~
      ~Red 3.6: Execution: Execution of Specific Types~
      ~Green 2.7: Procedures~

      PostScript arrays are polymorphic:  Each array element can be an
      object of any type.  A PostScript procedure is just an executable
      array of other objects, to be interpreted one after the other.

      Executable arrays (i.e.  procedures) are displayed in italics, with
      their length enclosed in braces:  "array {37}" Literal arrays are
      displayed with their length enclosed in square brackets:  
      "array [6]"

      When you open up an array, lines are drawn fanning out to the
      right, leading from the array to its elements, which are
      displayed as "index: type value", in a smaller point size.

  Dictionary

      ~Blue 4: Procedures and Variables~
      ~Red 3.4: Data Types and Objects; Dictionary~
      ~Green 2.4: The Dictionary Stack~
      ~Green 2.5: Operators and Name Lookup~

      Dictionaries associate keys with values.  The key (an index into a
      dictionary) can be an object of any type (except null), but is
      usually a name.  The value can be anything at all.  Dictionaries
      are used to hold the values of variables, functions and
      arguments, as records, lookup tables, classes, instances, and
      other things -- they're very useful! 

      The dictionary stack defines the context of a PostScript process.
      Whenever the value of a name is needed, it is looked up in the
      dictionaries on the dictionary stack, in top to bottom order.

      A dictionary is displayed by showing the number of keys it
      contains, a slash, and the maximum size of the dictionary,
      enclosed in angled brackets:  "dict <31/200>"

      When you open up a dictionary, lines are drawn fanning out to
      the right, leading from the dictionary to its elements,
      which are displayed as "key : type value" in a smaller point
      size: "/FirstName : string (don)"

  Class

      ~NeWS 6: Classes~

      NeWS uses an object oriented programming package, which
      uses dictionaries to represent classes and instances.

      When a class dictionary is displayed, its class name is 
      displayed, instead of its actual type "dict":  
      "MessageItem <10/200>"

  Instance

      ~NeWS 6: Classes~

      When an instance dictionary is displayed, its type is displayed
      as a period followed by its class name:  ".MessageItem <31/200>"

  Magic Dictionary

      ~NeWS 11: NeWS Type Extensions~
      ~NeWS 11.2: NeWS Type Extensions; Objects as Dictionaries~

      Magic dictionaries are certain types of NeWS objects, such as
      processes, canvases, and events, that appear to be dictionaries,
      but are really special data types.  They have a fixed set of keys
      with special meanings (such as a process's /OperandStack, or a
      canvas's /TopChild), but otherwise, you can treat them just
      like regular dictionaries.  Special things may happen when you
      read or change the values of the keys (for example, setting the
      /Mapped key of a canvas to false makes it immediately disappear
      from the screen). 

  Selection

      ~Red 3.4: Data Types and Objects~
      ~NeWS 5: The Extended Input System~
      ~NeWS 5.4: The Extended Input System; 
		   Selection Overview and Data Structures~

      A selection is a piece of data, such as text from a terminal
      window, that can be copied and pasted from window to window.
      Selections are used to move data between separate window system
      applications.  There are several different ranks of selections
      that you can make, but the most frequently used one is called the
      "primary selection".  The CyberSpace deck displays the current
      primary selection in the field at the top of the scrolling text
      window.  (figure xxx)  Selections also come in different types,
      and the following types are currently recognized:

      text

	  A string of ASCII text, selected from something like a
	  terminal emulator, text canvas, text editor.

      object

	  A single PostScript object, of any type.

      pointer

	  PostScript does not have an explicit notion of a "pointer",
	  but if we consider the meaning, "a way to reference or
	  replace an object in memory," the term "pointer" means a
	  *pair* of PostScript objects:  a container and an index, that
	  specify the location of another PostScript object.  The
	  container (usually an array or dictionary) holds the object,
	  and the index into the container (usually an integer or name)
	  tells which element of the container the object is.

	  The PostScript operators "get" and "put" take pointers as
	  arguments.
	  ~Red 6.3: get, put~

	  The advantage of selecting a pointer to an object, rather
	  than the object itself, is that whoever uses the selection is
	  able to tell where the object came from, and/or can replace
	  the selection with a new value.

      interval

	  A subsequence of an array or string, a contiguous subset of
	  the original elements, sharing the same storage.  
	  ~Red 6.3: getinterval, putinterval~

  Process

      ~Red 3.5: Stacks~
      ~NeWS 2.1: NeWS Extensions Overview; The Lightweight Process Mechanism~
      ~NeWS 11.6: NeWS Type Extensions; Processes as Dictionaries~

  Canvas

      ~NeWS 1.3: Introduction; Canvases~
      ~NeWS 2.2: NeWS Extensions Overview; Canvases and Shapes~
      ~NeWS 11.3: NeWS Type Extensions; Canvases as Dictionaries~

  Event

      ~NeWS 1.4: Introduction; User Interaction -- Input~
      ~NeWS 3: Input~
      ~NeWS 11.4: NeWS Type Extensions; Events as Dictionaries~

========================================================================
========================================================================

How to Get Started

First, you have to be running NeWS.  If you don't have a NeWS handy,
you can skip to the next section.

The CyberSpace deck currently runs under NeWS 1.1, and walks under
X11/NeWS Beta 2.  (One day it will fly!)

Take a look at the file "README" which should be supplied with the
CyberSpace deck.  It should contain the latest instructions for loading
all the files you need to run it.

In a directory containing the files the CyberSpace Deck was distributed
with, just type "cyber".

Or put the .ps files into your NeWS directory (under the directory where
you run NeWS), and "psh cyber.ps" to load them all automatically.

Or load them in the following order:

echo "(debug.ps) LoadFile pop" | psh
psh textcan.ps
psh piemenu.ps
psh pullout.ps
psh quickwin.ps
psh overlay.ps
psh pointer.ps
psh distill.ps
psh mics.ps
psh cyber.ps

========================================================================
========================================================================

Navigating in CyberSpace

There are several ways of giving commands to the CyberSpace Deck.  The
number of "*"'s to the right of the title of a section tell how important
something is if you are learning to use the CyberSpace deck.  (The more
splats, the more interesting.)

  Clicking with the Mouse						*****

      The most commonly used functions can be performed directly by
      clicking on things with the mouse buttons.  What a mouse button
      does depends exactly on what was underneath the cursor when you
      clicked the button.  For example, the exact word you are on when
      you bring up a menu is often what the menu will affect.  (This
      differs from most applications where all that matters is what
      window you are in.)

  Selecting from Menus							****

      There are a lot of commands available via pop-up menus, that you
      can get by clicking the "Menu" button (usually the right button).
      The menu that pops up applies to whatever was underneath the
      cursor when you first pressed down on the menu button.

  Typing PostScript Expressions						***

      You can type into the scrolling text window (or anywhere else in
      the CyberSpace Deck window).  What you type is interpreted as a
      PostScript expression, and you can interact with the PostScript
      interpreter "executive", as you normally can with an "psh" (or
      "tip" to a laser printer).

  Pressing Function Keys and Control Characters				**

      Certain function keys and control characters invoke functions 
      immediately when you type them. 

  There are several different regions on the screen to interact with...

  The Scrolling Text Window						*****

      The scrolling text window presents a view of a NeWS process.
      There is a spike sticking out of the top of the window which
      represents the process's stack.  Text that the process prints
      to its standard output is put into the text window, and text
      that you type anywhere in the CyberSpace Deck window is fed
      into the standard input of the process.

      At the top of the text window is a banner displaying the current
      primary selection.  Text that you select from a text window,
      terminal emulator, or other applications goes into the primary
      selection, along with the objects you select from the deck.

      Text Window Tab							**

	  You can move the text window around by pressing the Point
	  button (left) down over the tab sticking out of the edge, 
	  dragging it to where you want, and releasing.

	  Clicking the Menu button in the text window tab pops up a pie
	  menu of commands affecting the process and text window, as well
	  as a few commands for internal debugging and introspection.

      Text Display							****

	  You can type commands into the text window, to be interpreted
	  by NeWS.  You can edit the text as you type it in, using the
	  Delete or Backspace key to erase characters, and Control-X or
	  Control-U to erase the whole line.  There are a lot of other
	  functions bound to control characters and function keys, which
	  you can get a list of by pressing Help, Alternate, or Meta-?.
	  (Todo:  define a function called "help" in the initial
	  userdict.)  (To type in a "Meta" character on a Sun keyboard,
	  hold down the "Left" key.)  One of the most useful keyboard
	  commands is Meta-Esc (or L9), which displays all the keys on
	  the dictionary stack that match the partially typed name in the
	  text window.

	  The scroll bar on the left edge of the text window can be
	  used to scroll through the lines of text that have been typed
	  out in the window.  (You'll need to use it to look at the
	  list of key bindings.)

	  Clicking and dragging the Point and Adjust buttons (left
	  and middle) over the characters in the text window selects
	  the text as the primary selection.

	  Clicking the Menu button (right) inside of the text window
	  pops up a menu of commands that operate on the Primary
	  selection.

  The Background Menu							****

      If you click the Menu button (right) on the white background of
      the CyberSpace Deck window, the background menu will pop up.
      This is a menu of functions that push interesting things onto the
      stack for you to look at and play with.

      Pallets...							***

	  A pallet is a dictionary or array of useful functions, that
	  you can open up and execute with the mouse (below).
	  Selecting the name of a pallet from the "Pallets..."  submenu
	  pushes a pallet of related functions onto the stack.  You can
	  open up a pallet and make its click action click-exec, from
	  the tab menu.  (todo:  make automatic) The "Debug" pallet is
	  a handy interface to the NeWS debugger (debug.ps).

      Processes								***

	  This pushes an array of arrays of NeWS processes onto the
	  stack.  Each subarray contains all the processes in one
	  process group.  (This only works in X11/NeWS.)

      Framebuffer							***

	  This pushes the framebuffer, the root of the canvas hierarchy,
	  onto the stack.  You can open up a canvas editor on the
	  framebuffer to see an array of its children (from the
	  structure "type...canvas editor" submenu) and open up a
	  scroller editor on the array (also from the structure
	  "type...scroller editor" submenu).  (todo:  make automatic)

      Windows								****

	  This pushes on the stack a dictionary of every LiteWindow that
	  has an active event manager listening for /DoIt events.  The
	  keys of the dictionary are the event managers, and the values
	  are the windows they are managing.

      Canvases								****

	  This lets you click at a place on the screen, and pushes on
	  the stack an array of the canvases underneath the cursor where
	  you clicked.  It draws an "X" shape at the cursor to prompt
	  you to click somewhere.

      Object								****

	  This pushes the class Object, the root of all other classes,
	  onto the stack.  You can open up an class editor on class
	  Object (from the structure "type...class editor" submenu).
	  (todo:  make automatic) You can open up Object's arrays of
	  SubClasses and ClassDicts, and open class editors on classes
	  in them, too.  You can enter the context of the class or
	  instance (from the structure "type...enter" submenu), and open
	  up scroller editors (from the "type...scroller editor"
	  submenu) on the class editor's arrays of InstanceVars,
	  ClassVars, and Methods, and open up name editors on the names
	  contained therein.  (todo:  make it open up collections of
	  actual pointers to the objects, so you don't need to enter the
	  object's context, and you can open them up and edit them.)

  The Data Structure Views						*****

      Views of PostScript data structures are displayed in windows with
      tabs sticking out of them.  The tabs display the type of data
      structure being viewed in the window.

      View Window Tab							*****

	Moving the View Window						*****

	  You can press the Point button (left) down on a tab, and drag
	  the window around on the screen.  When you release the button,
	  the window will stay where it is (usually).  If you place it
	  so the tab overlaps the pin sticking out of the top of the
	  scrolling text window, it will be pushed onto the stack.  You
	  can move objects around on the stack by dragging them up and
	  down the spike by the tabs.

	Iconifying the View Window					**

	  If you press the middle button over a structure window tab, it
	  will iconify the window, so it displays only the first level
	  of the data structure, with a rounded line drawn around the
	  inside border.  This isn't particularly useful for windows
	  that are only displaying one level of data structure in the
	  first place, but it sure is handy for big deep ones.

	View Window Tab Menu						*****

	    Pressing the menu button over the tab of a structure window
	    pops up a menu of operations on that whole window.

	    Layout							*

		Recompute the layout of the structure.  Updates the
		display if the structure has changed.

	    Paint							**

		Redraw the structure.

	    Zap								*****

		Destroy the view of the data structure.  If the window
		is on the stack, then the object is popped.  Zapping a
		view window does not destroy the displayed data
		structure itself, unless there are no other references
		to it, in which case it gets garbage collected
		automatically.

	    Print							*

		Write out a PostScript program to print out the
		structure display. This is presently broken, but at
		least it doesn't seem to crash.

	    Tab...							**

		Submenu to move the tab to different places around the
		window.  Ignore the names, just select the direction in
		which you want the tab moved.

	    View...							*****

	        Menu of functions that affect the view of the 
		structure in the window. The attributes you set
		with this menu can be overridden locally in the
		individual pieces of structure, with the structure
		view menu.

		point size						*****

		    Change the point size at which the top level piece
		    of structure is displayed.  Pull out further to get
		    a bigger point size.  The size you have selected is
		    displayed in the menu center.

		shrink							***

		    Change the factor by which the point size
		    diminishes with depth.  Pull out further to get a
		    bigger shrink factor.  (If it's more than one then
		    it's a grow factor!)  The factor you have selected
		    is displayed in the menu center.

	        open							***

		    Open the structure to a certain depth.  Pull out
		    further to open it deeper.  The depth to which
		    the structure will be opened is displayed in the
		    menu center.  Be careful about opening big
		    structures deeper than one or two levels at once,
		    unless you have a lot of time to wait!

	        click proc...						*

		    Sets the function to call when you click the Adjust
		    (middle) button on a piece of structure in that
		    window.  These are described later, but the most
		    useful one for pallets of functions is "click-exec".
		    An object whose click action is click-exec will be
		    executed when you click the Adjust button on it. 

      Structure View							*****

	  A mouse sensative structural view of PostScript data is
	  displayed inside the view window.  You can use the mouse to
	  point at a piece of structure in the display, inspect and
	  manipulate it.  No matter how small something is displayed
	  (even in unreadable 1-point text), it is still mouse sensative!
	  (It won't shrink any smaller than a pixel, so you can always
	  point to it.)

	  Selecting Data Structures					*****

	      Clicking once on an object with the Point button (left)
	      will select the object.  This actually selects a "pointer"
	      to the object (see above), and you will see it as the
	      current primary selection, displayed in the line labeled
	      "Selected:"  at the top of the scrolling text window.

	      You can hold the Point button down and drag the cursor up
	      and down to select other pieces of structure in the same
	      container.  The currently selected structure will be
	      displayed in the banner at the top of the scrolling text
	      window.

		    If you hold the shift key down while making a data
		    structure selection, the results you get will depend
		    on the type of the container from which you're
		    selecting.  If it's a dictionary, you can select one
		    of its keys.  If it's an array, you can drag the
		    cursor up and down to select an array subinterval.

	  Executing Data Structures					****

	      Double clicking the Point button on an object selects it,
	      makes it executable, and executes it.  This is useful for
	      calling functions that are displayed on the screen, and
	      for using strings of text, such as previously typed
	      commands selected from a text window, as command buttons.

	  Doing Other Stuff to Data Structures				*****

	      Clicking the Adjust button (middle) on a structure calls
	      the structure's click action, or the default click action
	      of the structure window if the particular piece of
	      substructure does not have its own.  There are several
	      different click actions, such as click-exec, click-push,
	      and click-select, but click-transfer is the default.

	      The Default Click Action					*****

		  Here are the three ways to use "click-transfer":

		  Open/Close Structure					*****

		      Press and release the Adjust (middle) button over
		      a composite object like a dictionary, an array,
		      canvas, or process.  The structure will open up
		      one level deep (or close if it was already
		      opened).

		  Transfer to Background				*****

		      Press the Adjust button over an object, and
		      holding it down, drag the object out over the
		      background.  When you release the button, a new
		      view window will appear on the background.  It
		      will contain a copy of the object you just dragged
		      out.

		  Transfer to Structure					*****

		      If you drag an object over to another structure
		      window (or to the same one, but over a different
		      piece of substructure), and release the button,
		      the object will be pasted into the structure
		      underneath the cursor when you released the
		      button.  Now you are actually editing PostScript
		      data structures!  Be careful!  You can severly
		      hose your NeWS server if you start pasting things
		      into system data structures or functions.  Make a
		      few of your own dictionaries and arrays to play
		      around with!

	  Structure Menu						*****

	      If you click the Menu button (right) over a piece of
	      structure, you will pop up a structure menu with lots of
	      functions which operate on the object under the cursor at
	      the time you pressed the Menu button.

	      push							*****

		  Push the object onto the stack.

	      exec							*****

		  Make the object executable, and execute it.

	      paste							*****

		  Paste the primary selection into the place of the
		  object under the cursor.  This actually edits
		  PostScript data structures!  See the above warning in
		  the description of click-transfer!

              open...							****

		  Submenu of functions to open up an object in different
		  ways.  Pull out further to open it deeper.  The depth
		  to which the structure will be opened is displayed in
		  the menu center.

	      change...							***

		  Submenu of functions that perform type conversions on
		  the object (or at least they try).

	      view...							****

		  Submenu of functions that affect the local view of
		  the piece of structure.  Similar to the view submenu
		  on the structure window tab, except that these
		  functions apply just to the piece of structure under
		  the cursor and its children, not all pieces of
		  structure in the window.

	      etc...							**

		  Submenu of random but useful functions that wouldn't
		  fit anywhere else. The "Molecule" function pops up
		  a pseudo-scientific visualizer view of the
		  PostScript data structure under the cursor. 

	      type...							*****

		  Pops up a type-specific submenu of functions that
		  apply to the object under the cursor at the time you
		  popped up the structure menu.  Which menu you get
		  depends on the type of the object.

========================================================================

========================================================================

Type Specific Functions

========================================================================

Editors

    boolean

    canvas

    class

    definitions

    digit

    element

    filter

    scroller

    shift

    step

    user

========================================================================

Pallets

    Window

    Debug

========================================================================

Debugging

    break-cont

    break-copy&cont

    break-enter

    break-exit

    break-kill

    break-list

    clear

    enter-it

    exit

    fix-typo

    push-dictstack

    push-execstack

    push-process

    show-dictstack

    show-execstack

========================================================================