DOC PWM                                      Ben Rubinstein, 1987

         CONTENTS - (Use <ENTER> g to access required sections)

 -- 1   INTRODUCTION
 -- 1.1   The Poplog Window Manager: design aims and constraints
 -- 1.2   Purposes of this document
 -- 1.3   Types of windows
 -- 1.4   Specification of arguments to functions
 -- 1.5   Format of following function specifications

 -- 2   PWM MANAGEMENT FUNCTIONS
 -- 2.1   Identifying the nature and facilities of the PWM
 -- 2.2   Keeping PWM and POPLOG in synchronisation
 -- 2.3   Creation and destruction of windows
 -- 2.4   Multiplexing user input on windows

 -- 3   WINDOW MANAGEMENT
 -- 3.1   Size
 -- 3.2   Position
 -- 3.3   Cosmetics
 -- 3.4   Other window management functions

 -- 4   TERMINAL EMULATION FUNCTIONS
 -- 4.1   Simple terminal emulation
 -- 4.2   Special functions for VED windows
 -- 4.3   Maintaining a text 'selection'

 -- 5   GRAPHICS FUNCTIONS
 -- 5.1   Selecting graphics window, raster op, and paint
 -- 5.2   Page creation and destruction
 -- 5.3   Point, line and area fill
 -- 5.4   Raster functions
 -- 5.5   Fonts
 -- 5.6   Colour

 -- 6   FUNCTIONS FOR TRACKING THE MOUSE
 -- 6.1   Mouse reports and recording mouse positions
 -- 6.2   Feedback modes

 -- 7   USER INTERFACE FUNCTIONS
 -- 7.1   Menus
 -- 7.2   Scroll bars
 -- 7.3   Prompt boxes
 -- 7.4   Customising the cursor image
 -- 7.5   Marking ranges of text

 -- 8   FUTURE OF THE POPLOW WINDOW MANAGER
 -- 8.1   Possible extensions to the PWM
 -- 8.2   The PWM, RAL-CSI, Sun-NeWS and X-WINDOWS

 -- 9   APPENDICES

-- 1   INTRODUCTION ---------------------------------------------

-- 1.1   The Poplog Window Manager: design aims and constraints -

The Poplog Window Manager (PWM) is a means by  which  the  multi-
language  Artificial  Intelligence development environment POPLOG
can be interfaced to graphics workstations to make  use  of  user
interface  facilities such as windows, pop-up menus and mice, and
to allow POPLOG programs to use high-resolution graphics.

POPLOG is a very portable environment running on a  wide  variety
of machines and most POPLOG programs will run under POPLOG on any
of the supported machines without modification.    Thus  a  major
design  aim  for  the  PWM  was to retain as far as possible this
degree of portability.

To achieve this, a high level description of a window system  has
been  abstracted  which  should  be  consistent  with most of the
window systems on which the PWM is to be implemented.   A  simple
control  language  has  been designed by which POPLOG can control
and interface to this notional window manager.  POPLOG  has  been
extended  so  that  it  both  uses  this  language  to  provide a
sophisticated high-level interface for programmers working in the
environment,  and  provides  a suite of functions by which POPLOG
programs can use these facilities.

The language is then interpreted by a  program  which  interfaces
directly  to a host workstation's window system, and communicates
with POPLOG through a terminal or pseudo-terminal  device.   This
program  has to be constructed anew for each workstation.  It has
the job of translating  the  concepts  of  the  notional  "Poplog
Window  Manager"  to a sensible equivalent in the concepts of the
host machine's window manager, and  hides  the  details  of  this
window  manager  from  POPLOG.  Henceforth in this document "PWM"
will refer to such a program.

This design has several major advantages:

   o  from  POPLOG's  point  of  view,  and  from  that  of   the
       programmer, there is just one, conceptually simple, window
       manager to deal with

   o from the user's point of view  POPLOG  and  POPLOG  programs
       maintain the style of their workstation's interface

   o porting to a new workstation is relatively fast -  only  the
       small  'translation'  program  needs  to  be  written, and
       POPLOG and POPLOG programs can immediately make use of the
       facilities

   o POPLOG and the PWM need not be running on the same  machine.
       It  is  quite  feasible  for  the  PWM  to be running on a
       (perhaps  relatively  slow)  workstation,  being  used  as
       sophisticated   terminal  to  POPLOG  running  on  another

       machine  which  might  not   have   graphics   facilities,
       communicating over something as simple as a serial line.

The design also settles painlessly  the  problem  of  POPLOG  not
being  an event-driven system.  On many window systems the client
is responsible for accepting requests from the user  for  actions
like   opening,  closing  and  resizing  windows.   It  would  be
unacceptable if such requests were ignored for very long  periods
of time - for example if the user could not close a POPLOG window
while POPLOG was compiling a large program.  One  of  the  design
aims  of  the PWM has been to shift the burden of processing from
POPLOG to the PWM, where this is appropriate: for example chapter
6  describes  the numerous ways that the PWM can be instructed to
follow a mouse cursor, to  relieve  POPLOG  from  this  intensive
task.

The major disadvantage of this design  is  performance.   Because
the  channel  by  which POPLOG communicates to the PWM has such a
narrow bandwith, actions which require a lot of information (such
as dumping a bit-image, or refreshing a large text window) take a
long time to complete.  Such delays would be unavoidable  in  any
case when POPLOG is running on a remote machine; it is hoped that
before too long a version of the PWM will be produced which  uses
pipes  to establish a fast communication link with POPLOG running
on the same machine: however, it has been found that this is  not
as trivial a task as might have been expected.

It is worth mentioning here some constraints  which  have  guided
the  evolution  of the PWM design, and the selection of functions
to implement.  One such constraint has been a desire to  restrict
the  overall  size of command set for three main reasons: to keep
the  language  concise,  in  order  to  reduce  the   amount   of
communication  traffic;  to assist the speedy porting of PWM's to
new machines; and to reduce the actual size of the  PWM  program.
(In the case of a PWM and POPLOG running on the same machine, the
size of the PWM is very important to avoid the two being  swapped
in   and  out  as  one  writes  and  the  other  reads  from  the
communications channel.)

The second major constraint has been the desire to keep  the  set
of  facilities  consistent  across  all  implementations (to date
there has been only one deliberate breach of this principle - see
the  section  on  colour  graphics).  An assumption has been made
that, given that there are a small set of functions and that  the
portability of the system is proclaimed, it is better not to have
a function than to have it work in one environment and fall  over
in  another.   This  does  not, however, apply to functions where
there is an easily defineable and  acceptable  degradation  path:
the syntax for defining menus (given in an appendix) for example,
has been expanded beyond the capabilities of some of the  systems
on which the PWM has been implemented.

In summary, the Poplog Window Manager aims to provide:

   o a multi-window access to  VED  (the  POPLOG  screen  editor,
       within  which  programs  can  not only be written but also
       compiled, debugged, and run) with user-customisable use of
       mice and menus.

   o a small and easy to use device-independent graphics language
       for   POPLOG  programmers  (who  have  previously  had  to
       externally link special graphics  code  written  in  other
       languages,  or be content with a character-graphics turtle
       package).

   o the facilities to build a sophisticated,  device-independent
       user interface to applications written in POPLOG

   o both remote and local use, enabling cheap graphics terminals
       to be used with powerful computers.

It is not an aim of the  Poplog  Window  Manager  to  provide  an
exhaustive interface between POPLOG and some workstation (but see
the note about "software expansion slots" in section 8.1).  It is
quite likely that such an interface may be produced in the future
for some workstations: but this will be quite orthoganal  to  the
PWM.

Nor is it an aim to provide a toolbox out of which  any  possible
user  interface  can  be built; more a self-assembly kit of parts
which can be combined in different ways to  build  a  variety  of
different  interfaces.   Thus  many  functions may provide two or
three variations: but not all possible variations on a  facility.
There  is  a  limit to what can be provided given the constraints
noted above, and so this principle has been explicitly adopted to
guide the design.

Finally it should be noted that the PWM is  not  intended  to  be
used except through the medium of POPLOG (apart from the simplest
terminal emulation in the 'base window' (qv) to  allow  users  to
talk  to  shells,  exchanges  etc. in order to log on to a remote
computer) and some aspects of the design reflect this assumption.

-- 1.2   Purposes of this document ------------------------------

This document has several distinct but overlapping purposes.

It is the first draft of a functional specification to be used by
those  writing  new implementations of the Poplog Window Manager.
Additionally,   because   there   are   already    two    partial
implementations  (for  Sun  Microsystem  and HP 9000/300 (Bobcat)
workstations)  it  serves  to  describe  the  functional  changes
between those first versions and this new specification.

It is also intended to be a discussion document, to  allow  those
with views or interests on the subject a chance to comment on the
proposed  set  of  functions,  and   raise   any   omissions   or
malformations.   Finally,   it  discusses  the impact of emerging
standards such as the RAL-CSI, Sun NeWS,  and  X-Windows  on  the
future direction of the PWM.

Because of the large amount of overlap between the material  that
should be included in documents for any of the purposes described
above, it has seemed most sensible  to  create  one  document  to
answer  all  these  needs.   Chapters 2 to 7 describe each of the
functions in detail; chapter 8 discusses  possible  additions  to
the specifications, and how the future of the PWM may be affected
by emergent "standards" for window systems.

This document does not specify (except implicitly) any details of
the  interface  POPLOG  imposes  between programmers and the PWM.
That  interface   is   described   separately   in   the   online
documentation of the POPLOG system.

-- 1.3   Types of windows ---------------------------------------

A window, in PWM terms, is a two-dimensional surface which can be
drawn  upon  and  which  can  be  made visible on the workstation
screen.  The major subdivision of  windows  is  into  "text"  and
"graphics" windows.  At present the effective distinction is that
text windows support certain terminal emulation facilities  which
graphics  windows  do  not:  all  facilites supported by graphics
windows are  supported  by  text  windows.   The  latter  feature
however  may  be  impossible,  or  may impose too great a loss of
efficiency, on some window systems: therefore it is not  required
that   all  PWMs  allow  graphics  operations  on  text  windows,
althought it would be desirable to preserve this feature.

Two specialisations of text windows can be distinguished from the
standard  form.  The  "base  window" is a text window that always
exists  during  an  invocation  of  a  PWM  (and  by   assumption
throughoutt  the  life  of a POPLOG process that is communicating
with a PWM).  It cannot be created or destroyed by the user. "Ved
windows"  similarly  cannot  be created or destroyed by the user:
they may have slightly different  terminal  characteristics  from
the  ordinary  text window; and they may support a few additional
functions.

Another kind of two-dimensional surface must  be  noted  here  to
avoid confusion: a "page", sometimes called a memory window, is a
two dimensional surface which is created and destroyed, and  upon
which  certain  graphics  operations  can be performed, using the
same syntax as for the other kinds of window.  However, it cannot
be  made  visible, cannot recieve input, and does not support the
window manipulation functions that all other windows support.

-- 1.4   Specification of arguments to functions ----------------

Throughout the PWM functions there are a number of areas in which
varying numbers of the same kind of object need to be defined and
referenced (for example windows or cursor images) and in many  of
these  cases the methods of definition may have to differ between
PWM's.

For example, a PWM on the Sun can load a cursor image from a file
in  a  standard  format,  whose  filespec could be transmitted by
POPLOG; or could in theory accept a definition for such an  image
from  POPLOG;  while  another  machine  might be unable to create
cursors at run-time but could load them from files; and  a  third
might have a fixed set of cursors.

A standard approach has been adopted to all  these  areas,  which
should overcome problems of differences between workstations such
as that of cursors mentioned above.   In all these cases, however
an  object is defined, its definition creates an identifier which
distinguishes it from all other currently extant objects  of  the
same  type (although the identifier for an object of one type may
overlap with that for an object of another type).  The identifier
is  then  the  only way in which the object is referenced for any
purposes including destroying the object.  The  identifier  is  a
small  integer,  generally in the range 0 to 32, although this is
not explicitly guaranteed and should never be made  use  of  (and
need never be known) by the user.

In this way, one can provide standard functions to, for  example,
set  the  cursor  image, using an identifier.  Only the code in a
user's program which sets  up  the  cursor  images  need  be  PWM
specific:  the  body  of the program which manipulates the cursor
will be entirely portable.

Throughout  the  remainder  of  this  document,  identifiers  are
referred  to  as,  for example, <window-id> or <cursor-id>.  If a
function is described as taking an argument  it indicates that an
identifier  for  any  of the surfaces described in the preceeding
section is acceptable.

Implementors should note that there are some functions which  can
take  either a <window-id>or a <page-id>as an argument: therefore
it must be possible to distinguish  these  (e.g.  by  taking  the
identifiers  for  pages  from  a  range  of numbers which doesn't
overlap with that used for windows, or by keeping a master  index
which can identify the referent of any window or page identifier.

-- 1.5   Format of following function specifications ------------

Chapters two to seven, below, describe each of the commands  that
can  be  given  to  a PWM, and each of the reports that it may be
required to generate, for  the  use  of  PWM  implementors.   All
commands  and  reports  are  implemented as messages sent between
POPLOG and the PWM, as described above.

Each command or report has been given a formal name by  which  it
can be referred to in this document.  The names have signifigance
only in this document.  Each name has a three character prefix in
capitals,  which  helps  to  group the commands and reports.  For
example, all the reports have names beginning "REP"; any  message
whose name starts with REP is transmitted from the PWM to POPLOG;
all other messages are transmitted  in  the  opposite  direction.
Another  group  is  prefixed  with  "ADV",   short  for 'advise';
commands in this group are all requests to  the  PWM  to  provide
some  kind  of  information,  rather than to perform some action.
Many commands fall into complementary sets, with  the  same  name
following  the prefix: for example, SETwintitle sets the title of
a window, ADVwintitle asks the PWM  to  return  the  title  of  a
window, and the PWM responds with

At the right of the message name there may be  a  short  note  in
italics,  which  places  the function or report in the context of
present, planned, and past versions of the PWM.

The lines immediately following  the  message  name  specify  the
arguments  which  are  included in the message.  Each argument is
specified on a  line,  envlosed  in  angle  brackets.   The  word
following the opening bracket specifies the type of the argument;
where necessary for purposes of referral in the explanatory text,
this  word may be followed by a colon and a letter or word naming
that argument.

The way that messages are actually encoded  into  a  sequence  of
characters is given in an appendix.

-- 2   PWM MANAGEMENT FUNCTIONS ---------------------------------

-- 2.1   Identifying the nature and facilities of the PWM -------

ADVpwmident                  (not in first versions)
Return REPpwmident.

REPpwmident                  (not in first versions)
     <string: Machine>
     <number: Version>
     <integer: ScrnW>
     <integer: ScrnH>
     <integer: ScrnD>
     <string: Date>
     <string: Misc>
     <integer: BaseW>
     <integer: BaseH>
     <integer: FontW>
     <integer: FontH>
     <integer: FontB>
Machine is the name of the workstation the PWM is running on  (eg
"sun2").

Version is the version number of this PWM (eg 1.3).

ScrnW, ScrnH and ScrnD describe the dimensions of the workstation
in pixels (respectively width, height) and bits/pixel (depth).

Date is the date this PWM was made.  The format is  not  defined:
it  is  not expected this string will be used by programs, but it
might be useful to support staff in the event of a problem.

Misc may contain any miscellaneous information; the format is not
defined.   It  is  mainly for the use of implementors debugging a
PWM.

BaseW and BaseH are the current size in characters  of  the  base
window.

FontW, FontH and FontB describe the dimensions of  characters  in
the  standard  font that this invocation of the PWM will be using
for terminal emulation - in the (unlikely?) event that  the  font
being  used  for  this  purpose  is  not  a fixed-width font, the
maximum dimensions - (respectively width, height, baseline).

-- 2.2   Keeping PWM and POPLOG in synchronisation --------------

The PWM maintains two  variables  describing  the  state  of  its
connection  to POPLOG: -poplog_connected- describes whether there
is a POPLOG process that has established communication  with  the
PWM;  -poplog_listening-  describes whether the POPLOG process is
catching input from the PWM.  The major uses of  these  variables
are  that  when -poplog_connected- is true, the PWM will not send
REPpwmident (i.e. if a second POPLOG process is spawned while one
is  still  running,  the second will not be allowed access to the
PWM facilities); and while -poplog_listening- is false,  the  PWM
will  not  send any messages (i.e. it will behave strictly like a
normal terminal; for example if the POPLOG process is  suspended,
or  the PWM is being used to connect to a remote machine, and the
user has not yet run POPLOG, an ordinary shell would be  confused
by   messages  about  input  source  or  mouse  presses).   These
variables are manipulated by four commands:

COMhellopwm
Set -poplog_connected- and -poplog_listening- true.

COMgoodbyepwm
Set -poplog_connected- and -poplog_listening- false.

COMabyssiniapwm
Set -poplog_listening- false.

COMpopisback
Set -poplog_listening- true.

COMtidywindows
     <string>
The argument is a string of characters, each of which is a window
identifier.   If  any  of  the  windows that the PWM is currently
maintaining (apart from the base window) are not  in  this  list,
they should be killed.

This function needs to be expanded  to  cope  with  all  the  PWM
"objects"  which  can tie up resources, e.g. pages, fonts, menus,
cursors, etc.

ADVlivewindows                      (to be implemented)
Invokes a REPlivewindows report.

REPlivewindows                      (to be implemented)
     <string>
The string describes  the  windows  which  currently  exist.   It
consists  of  groups  of  three characters, a group for each live
window, which are to be interpreted as:
        <window-id> <type character> <elevator flags>

See the notes on creation of windows  for  explanation  of  these
flags.

REPpwmmishap                      (to be implemented)
     <integer: major number>
     <integer: minor number>
     <string: details>
The PWM may  spontaneously  produce  this  report  at  any  time.
POPLOG  should respond with a -mishap-.  The major number defines
the type of error;  the  minor  number  and  string  may  contain
further   details.    The   precise  interpretation  of  this  is
controlled by a table kept by POPLOG.

-- 2.3   Creation and destruction of windows --------------------

COMmakewindow                  (revised specification)
     <char: Type>
     <small-int: Flags>
     <integer: Width>
     <integer: Height>
     <string: Title>
Create a new window, and put it on screen.  The function  returns
a  <window-id>  if successful; otherwise it returns the pseudo-id
-1.

The character Type defines the type of window required, as
    `t` -> user text window
    `v` -> ved text window
    `g` -> graphics window

The string specifies the title to appear in the title bar of  the
window  (where  this  is  appropriate to the host window system).
When an icon title is appropriate, it is specified in one of  the
following  ways.   copied  the window is a "ved" window, the icon
label is taken from the first part of the  window  title;  unless
this  contains one or more "/" characters, in which case the icon
title is taken from the text following  the  last  "/".   If  the
window  is  a  user  text  or  graphics window, the icon label is
copied from the first part  of  the  window  title;  unless  this
contains  a  tab character, in which case the the string is split
at the tab character, and the window  title  is  taken  from  the
portion  of  the  string  preceeding the tab character, while the
icon label is taken from the portion of the string following it.

The arguments defining the size are understood as character units
in  the  first two cases, pixel units in the latter case.  In all
cases they are understood to represent the minimum internal  size
-  it  is  permissible for the PWM to create a window larger than
requested, but if for any reason it cannot create a window of  at
least the requested size it must return a failure result.

The 'flags'  argument  decomposes  into  several  one-bit  flags.
Currently, the meaning of only the two least signifigant bits has
been defined: bit 0, if set, requests  a  vertical  "scroll  bar"
("elevator");  bit  1,  if set, requests a horizontal scroll bar.
Either or both requests may be ignored if  inappropriate  to  the
host window system or the PWM.

COMkillwindow
     <window-id>
Kill (delete all references to) a window. If the  window  is  the
currently  selected  text window, the base window is selected for
text: if it is the current graphics window, the  base  window  is
selected  for  graphics.   If  the identifier does not describe a
live window, an error should be generated.

-- 2.4   Multiplexing user input on windows ---------------------

The current model of how input is handled is that the  PWM  sends
streams of characters to POPLOG, interspersing them with messages
indicating the source of subsequent characters.  It  is  possible
that  for  various  reasons  which  have  been discussed in other
reports, it may be necessary to change this model:  for  example,
by  using  messages  which mean not (necessarily) that subsequent
input comes from a particular window, but only that  that  window
has  been  selected for input by the user; or by sending messages
which indicate that there is input on some  window,  and  queuing
that input until POPLOG specifically unlocks it.

REPinputsrc
     <window-id:W>
Indicates that following input from the user  was  directed  into
the  window  W.  May be emitted at any time.  Currently it can be
expected that there will be input.

SETinputsrc                   (not in first version)
     <window-id>
Make the argument window be the recipient of subsequent  keyboard
input,  and  ensure that it is open and fully visible.  Note that
the user could override this action, and select  another  window,
before typing anything more at the keyboard.

How the window is  selected  for  input  will  be  implementation
specific:  on  the  Sun,  it  involves  opening  and exposing the
window, and moving the mouse cursor inside it; on other machines,
it  is  not  actually necessary to move the mouse, and on some it
may not even be necessary  to  have  the  selected  window  fully
exposed (but this should be done in any case).

This function resets the PWM's internal record  of  which  window
the  last  input  came  from,  so that a REPinputsrc message will
always follow the invocation of this function, if  there  is  any
more user input.

(This is a new function; it replaces (partly) a function to  move
the mouse cursor, which is no longer part of the specification.)

ADVinputsrc
Reset the PWMs internal record of the last source of input, to  a
null  value.   The  effect  is thus to ensure that any subsequent
input will be preceeded by a  notication  of  its  source.   Note
therefore  that  this,  unlike  any of the other "ADV" functions,
does not cause the PWM to immediately return a report.

-- 3   WINDOW MANAGEMENT ----------------------------------------

-- 3.1   Size ---------------------------------------------------

SETinternsize                  (not in first versions)
     <window-id>
     <integer: Width>
     <integer: Height>
Set the internal size of the window: that is,  the  size  of  the
area  that  is  available  to  be written or drawn on.  Width and
height are interpreted as pixel dimensions if  the  window  is  a
graphics window, as character dimensions otherwise.

(This function replaces one which sets the size in characters.)

ADVinternsize                  (not in first versions)
     <window-id>
Invokes a REPinternsize report.

REPinternsize                  (not in first versions)
     <window-id>
     <integer: Width>
     <integer: Height>
Reports the internal size of the window, in character units if it
is a text window or in pixel units if it is a graphics window.

(This  function  replaces  one  which   reports   the   size   in
characters.)

REPwinresized
     <window-id>
     <integer: Width>
     <integer: Height>
Reports that the size of a window has been changed.  The integers
represent the new internal size of the window, in character units
if it is a text window or in pixel units  if  it  is  a  graphics
window.

SETexternsize                  (not in first versions)
     <window-id>
     <integer: Width>
     <integer: Height>
Set the external size of the window in pixels,  subject,  in  the
case  of  text  windows,  to  being  rounded  down to exactly fit
character sizes.  That is, it is guaranteed that after successful
invocation  of this function the window will not occupy more than
the given space on the screen.

(This function replaces one which sets the size in pixels.)

ADVexternsize                  (not in first versions)
     <window-id>
Invokes a REPexternsize report.

REPexternsize                  (not in first versions)
     <window-id>
     <integer: Width>
     <integer: Height>
Reports the external size of the window, in pixel units.

(This function replaces one which reports the size in pixels.)

WMRstretchwin
     <window-id>
Invoke an interactive resize of the window by the user.   If  the
window is iconic this function has no effect.  Otherwise if it is
successful  REPinternsize  is  emitted.   This  function  can  be
ignored by a PWM incapable of implementing it.

-- 3.2   Position -----------------------------------------------

SETwinlocat
     <window-id>
     <integer: X>
     <integer: Y>
set the top-left corner of the currently selected window  to  X,Y
pixels from the top left corner of the screen.

ADVwinlocat
     <window-id>
Returns a message ( REPwinlocat)  defining  in  pixel  units  the
position  of  the top-left corner of the window from the top-left
corner of the screen.

WMRmovewin
     <window-id>
Invoke an interactive move of  the  window  by  the  user.   This
function can be ignored by a PWM incapable of implementing it.

ADViconlocat
     <window-id>
Return a message ( REPiconlocat) giving  the  coordinate  of  the
top-left  corner of the icon of the currently selected window, in
pixels from the top-left corner of the screen.   On  systems  not
supporting icons, the coordinate is returned as (0, 0).

SETiconlocat
     <window-id>
     <integer: X>
     <integer: Y>
set the top-left corner of the of the window's icon to X,Y pixels
from   the  top-left  corner  of  the  screen.   On  systems  not
supporting icons this function has no effect.

-- 3.3   Cosmetics ----------------------------------------------

SETwintitle
     <window-id>
     <string>
Set the title of the window to the string, or if there is a space
restriction to the largest possible substring from the left.

ADVwintitle
     <window-id>
Invoke a REPwintitle report.

REPwintitle
     <string>
Report the string which is the title of the window.

SETicontitle
     <window-id>
     <string>
Set the title of the window's icon to the string, or if there  is
a  space  restriction to the largest possible substring, from the
left.  In some systems, this  may  mean  the  string  which  will
appear for that window in some menu.

ADVicontitle
     <window-id>
Invoke a REPicontitle report.

REPicontitle
     <string>
Report the string which is the label of  the  window's  icon.  In
some systems, this may mean the string which will appear for that
window in some menu.

SETiconfile                (not yet in all versions)
     <window-id>
     <string>
Interpret string as a filename, and attempt to load an icon image
definition using that filename, to be the image used by the given
window's icon.

It is implementation specific as to the format  required  of  the
file  (it  will  presumably be in some format defined as standard
for the host machine).  It should also be noted that  the  string
will  be interpreted by the PWM, and therefore conform to the PWM
hosts' operating system; and if it is not an  absolute  pathname,
it  may  be specific to the PWM and/or the invocation as to which
directory the filename will be interpreted relative to.

The function can be ignored by  a  PWM  which  does  not  support
icons,  or  on  which icons cannot be dynamically altered (and no
errors should be generated in such a case).

SETiconimage                    (not yet implemented)
     <window-id>
     <integer: W>
     <integer: H>
     <integer: BypR>
     <small-int: BpP>
     <small-int: BpB>
     (raster data)
Consult the description of GFXdumpraster for the meaning  of  the
last  five  arguments,  and  how  the  raster data is passed from
POPLOG.

Read a raster definition from POPLOG, and set it to be the  image
used  by  the  given window's icon.  If one or both dimensions of
the given image are larger than the icon  size,  they  should  be
clipped;  if  either dimension is smaller than the icon size, the
remainder of  the  image  should  be  blanked  out,  except  that
machines  which  allow  a mask to be specified for icons (i.e. to
allow non-rectangular icons) may use a rectangular  mask  of  the
given  dimensions,  if  the implementator of the PWM considers it
reasonable.

Basically, it is not expected that the author of code using  this
function  can  expect  to know precisely the effect that would be
obtained on any machine that the PWM might be implemented on; but
they should known that the behaviour will be "sensible".

-- 3.4   Other window management functions ----------------------

WMRopenwin
     <window-id>
Open the window.  If the window is closed, this opens it; it also
goes  to  the  top  of  the  stack,  regardless of whether it was
opened.  No complaint is voiced if the window  is  already  open.
Calling  this  function  should  not evoke a REPwinopened message
(qv).

WMRclosewin
     <window-id>
Close the window.  If the system supports icons, it goes into  an
iconic  state;  otherwise  it  becomes  selectable on a menu.  In
either case it is no longer on screen in its full  form.  Calling
this  function should NOT evoke a REPwinclosed message (qv).  The
specification says nothing about the level of  the  icon  in  the
stack: this should follow the local window manager's conventions.

ADVwinopen
     <window-id>
Returns a  message  REPwinopened  or  REPwinclosed  according  to
whether the window is open or closed, respectively.

REPwinclosed
     <window-id>
This message is sent to POPLOG if the user has closed  a  window,
or in response to an ADVwinopen enquiry.

REPwinopened
     <window-id>
This message is sent to POPLOG if the user has opened  a  window,
or in response to an ADVwinopen enquiry.

WMRexposewin
     <window-id>
Expose the window (bring it to the top of the stack).

WMRhidewin
     <window-id>
Hide the currently selected window (send it to the bottom of  the
stack).

WMRrefreshwin
     <window-id>
Refresh the window. It is implementation specific as to what,  if
anything, this means.

REPwinquitreq
     <window-id>
This report, which may  be  emitted  spontaneously  by  the  PWM,
reports  that  the  user has requested that the window be killed.
No further action is taken by the PWM in response  to  this  user
request.

-- 4   TERMINAL EMULATION FUNCTIONS -----------------------------

-- 4.1   Simple terminal emulation ------------------------------

To support POPLOG's editor, VED,  a  subset  of  normal  terminal
control  comands  are  implemented.  These are the only functions
which do not fit into the  standardised  distribution  of  escape
sequences.

In general, there is no reason why the  PWM  should  emulate  one
terminal  rather  than  another,  although  it  is obviously more
convenient for POPLOG if all PWM's maintain the  same  emulation.
All current PWM's emulate the Visual 200 terminal, simply because
this is the terminal that VED  assumes  by  default  that  it  is
connected  to.   In principle some particular PWM could choose to
emulate another terminal if it seemed desirable for some reason.

Nor does the complete command set have to be supported: since  as
mentioned  above  the  PWM  is  not  intended to be used with any
client other than POPLOG, the subset that VED makes use of proves
sufficient.   This subset is detailed in an appendix: however one
point must be especially noted.  The standard  V200  command  for
directly  addressing the cursor encodes the cursor address in two
characters giving a range of 0-95 in each dimension.  Since a PWM
window  can  be  wider  than this (and potentially taller) it has
been found necessary for PWM's to support, in  addition  to  this
command, the ANSI cursor address function.

Finally, implementors should be aware of the special requirements
of  a multi-window terminal emulation: for example, graphics mode
and insertion mode  should  be  local  to  each  individual  text
window.

COMselecttextwin
     <window-id>
Select a window to be the output device for subsequent text.  The
window defined by <window-id> must be a text window (i.e. a "txt"
or "ved" window, or the base window).

COMoneinput
This sets the PWM into  "one-input"  mode.   In  this  mode,  any
keyboard  or mouse input that would normally be sent to POPLOG is
encoded into a REPinpevent message, and sent  without  regard  to
which  window  it  came  from.   The  role of this function is to
ensure that a single action by  the  user  results  in  a  single
action  by POPLOG (for example, it is used by VED with the prompt
"VED HERE: PRESS RETURN TO CONTINUE"); usually the nature of  the
event  is not required.  Note that this mode is cancelled as soon
as one input event message has been sent.

Input to POPLOG poses special problems.  Briefly, this is because
POPLOG  normally switches a terminal between cooked and raw modes
at frequent intervals, e.g. when  it  switches  between  VED  and
top-level,  or  when  it  has been printing outside VED from VED.
Switching modes cause the device driver to purge  input;  if  the
switch  was invoked because the user moved the mouse into another
window and started typing, this typing may be lost.  The  present
solution to this problem, which is not ideal but is currently the
best found, is for POPLOG to keep the device permanently  in  raw
(or  to  be  more accurate, half-cooked) mode, and for the PWM to
simulate  a  cooked  terminal  when  necessary.   This  basically
involves  the  PWM  doing  line  editing locally, and sending the
complete line to POPLOG when the user  presses  return  or  line-
feed.   There  are  four  commands which POPLOG can send, when it
would normally change the device state, to tell PWM which  device
mode it would like (the usual situation is for the base window to
be cooked, and ved windows to be raw).

COMbasecooked
Perform line-editing and buffering in the base window.

COMbaseraw
Pass all input on the base window directly through to POPLOG.

COMvedcooked
Perform line-editing and buffering in ved windows.

COMvedraw
Pass all input on ved windows directly through to POPLOG.

-- 4.2   Special functions for VED windows ----------------------

Three further commands have  been  proposed  for  "ved"  windows,
which   would   allow   them   to  support  VED  operations  more
efficiently.

VEDscrollleft            (no implementation scheduled)
     <integer: first-line>
     <integer: number-of-lines>
     <string>
This function is intended for use when VED wishes to  scroll  the
window  one  character to the right in the file (that is, so that
the text in the window appears to move to the left).  The  action
is to copy the rectangle of text which is defined as:
    from the <first-line>, <number-of-lines>;
    from the third column to the penultimate column, inclusive.

so that it maps onto the <first-line> and second column (i.e.  it
has  shifted  one  character  to  the  left).   The  string  then
represents  <number-of-lines>  pairs  of  characters,  which  are
printed  in  the  last  two  columns  of  each line in the range.
(Explanation: the first column is left alone entirely, because it
is  used  for marked range indicators, and will not have changed;
the last column is no good,  because  it  may  have  "long  line"
indicators.)    This  function has never been implemented and may
be dropped from the specification in the future.

VEDscrollright            (no implementation scheduled)
     <integer: first-line>
     <integer: number-of-lines>
     <string>
This function is intended for use when VED wishes to  scroll  the
window  one  character to the left in the file.  The action is to
copy the rectangle of text which is defined as:
    from the <first-line>, <number-of-lines>;
    from the second column to the column before  the  penultimate
column, inclusive.

so that it maps onto the <first-line> and second column (i.e.  it
has  shifted  one  character  to  the  right).   The  string then
represents  <number-of-lines>  pairs  of  characters,  which  are
printed  in the first and last columns of each line in the range.
This function has never been implemented and may be dropped  from
the specification in the future.

VEDsetlineno            (no implementation scheduled)
     <integer: line-number>
If the currently selected text  window  is  a  ved  window,  this
writes  the  number in decimal, right justified and padded on the
left with spaces in a four  character  field  starting  from  the
fifth  column on the top line of the window.  The intention is to
save the cost of two cursor  positioning  messages  and  actions.

This  function has never been implemented and may be dropped from
the specification in the future.

-- 4.3   Maintaining a text 'selection' -------------------------

The PWM should maintain a "text selection", which  is  simply  an
arbitrary run of text, which can be spliced into the input stream
and can be set to the text in a PWM text window.   This  is  most
useful if it can be integrated with a simlar facility in the host
workstation's  window  system,  enabling  text   to   be   easily
transferred  between  POPLOG  (the  PWM)  and  other applications
running  on  the  workstation:  for  example  the   Sun   "stuff"
mechanism, X-windows' "Cut Buffer", or GEM's "scrp" facility.

COMgettextsel
This function instructs the PWM  to  send  the  contents  of  the
current text selection (if any) to POPLOG as if the user has just
typed it at the keyboard.

COMsettextsel
     <window-id>
     <integer: L1>
     <integer: C1>
     <integer: L2>
     <integer: C2>
This function  instructs  the  PWM  to  reset  the  current  text
selection to the text displayed in the specifed text window, from
the character at line L1 and column C1 to the character  at  line
L2  and  column C2, inclusive.  If the window is a VED window the
first column of each line should be ignored.  If a line up to  L2
does  not  extend  to  the  right  margin  (or  if C2 specifies a
character cell after the last non-white-space character  on  line
L1)  then  the PWM should store either a line-feed or a carriage-
return after the last non-white-space  character  on  that  line,
according  to  the  conventions of the host window system: in the
absence of such a convention, a carriage return is preferable.

No action is taken if the window is not a text window, or if  the
character  specified  by  (L1,  C1) comes after that specified by
(L2, C2).   If either (L1, C1) or (L2, C2) specifies a  character
outside  the  window  (e.g.  a column is specified as 80 when the
window  is  60  columns  wide)  the  range  should   be   clipped
appropriately.

-- 5   GRAPHICS FUNCTIONS ---------------------------------------

-- 5.1   Selecting graphics window, raster op, and paint --------

GFXsetrasterop                  (specification revised)
     <small-int>
Many of the functions described  below  combine  two  sources  of
pixels  to  produce  a new image (typically, one source of pixels
will be the image that is being altered, the  "destination";  the
other  might be a raster (bit-image) or, for example, a line: the
"source".  This function sets the raster-op which  will  be  used
for subsequent calls to such functions.

The raster-op is encoded (ignoring the "small-int" coding used to
pass the argument) into four bits using the following rules:
     00112  = source   (take no account of existing image)
     01012  = destination (take no account of new image)

all other operations are then encoded by applying the appropriate
logical operator to these two constants.  Thus

     NOT.DST (invert the destination pixels) = ~01012= 10102
     NOT.SRC (invert the source pixels) =~00112   = 11002
     DST.OR.SRC =01012 |  00112   = 01112
     DST.AND.SRC =01012 & 00112   = 00012
     SET (use foreground colour) = (NOT.DST).OR.(DST)    = 11112
     CLR (use background colour) = 00002
and so on.  This is actually the scheme employed by GEM;  but  it
is  easy  to  convert  for any other machine, since (in the worst
case) it can be viewed an index into a sixteen-element table.

GFXsetpaintnum                  (not in first versions)
     <integer>
Some of the functions below use a "paint value".   This  function
sets  the  value  for  subsequent  calls  of such functions.  The
effect of various numbers is not defined, and will  probably  not
be  common between machines - in most cases, anyway, they will be
user definable: see  the  colour  functions  below.   However,  a
default  situation  of colour 0 being the background colour would
be sensible, in the absence of reasons against such  a  usage  on
some particular machine.

(The above two functions replace a single function in  the  first
versions.)

GFXselectsurface
     <surface-id>
Most of the graphics functions do not take an  explicit  argument
to indicate the window to which they will be applied, but use the
notion of a "current graphics window".  This function is used  to
select  a  window  or "page" to be the "current graphics window".
Note that although a page can be selected with this function, not
all the functions described below can operate on a page.

-- 5.2   Page creation and destruction --------------------------

GFXmakepage
     <integer: W>
     <integer: H>
Create a new graphics "page", that is an area of memory on  which
raster  graphics  functions  can  be  performed  as  if it were a
window.  If the call is successful, the PWM returns an identifier
for  the  page  (in REPstatus) otherwise it returns the pseudo-id
-1.

GFXkillpage
     <page-id>
Destroy the specified graphics "page",  releasing  any  resources
associated with it.

-- 5.3   Point, line and area fill ------------------------------

GFXwipearea
     <integer: X>
     <integer: Y>
     <integer: W>
     <integer: H>
Apply the currently selected raster-op  to  every  pixel  in  the
rectangle  of  the  currently selected window defined by the top-
left corner (X,Y) and width and  height  W,  H.   Clearly,  since
there  is  no source of pixels in this function, the only raster-
ops that would have any effect in conjunction with  it  are  SET,
CLR  and  NOT.DST.  However a special case is made if the current
raster-op when this function is invoked is SRC; in this case  the
current  paint value is used as an infinitely large source.  This
makes the function more useful on colour machines.

Note that if the width (W) argument is zero, the rectangle should
be  taken  to  extend to the right edge of the window or surface;
similarly if the height argument is  zero  the  rectangle  should
extend  to  the  bottom  edge of the surface.  Thus invoking this
function with all four arguments zero is guaranteed to  apply  to
the entire surface, regardless of its size.  A similar convention
applies, wherever a rectangle is specified in this manner, to all
the graphics functions listed below.

GFXpolyline
     <integer: X1>
     <integer: Y1>
      ....
     <integer: Xn>
     <integer: Yn>
The arguments to this function are a series of pairs of integers,
representing  coordinates;  the  number  of  such  coordinates is
undefined. The function instructs the PWM to  draw  a  series  of
lines,  using  the  current  raster-op  and paint value, from the
first coordinate to the next coordinate and so  on  to  the  last
coordinate.  Note that there is no explicit count of points given
in the message, to reduce communications overhead.  If there  are
less  than  four  integers, nothing is drawn; if there are an odd
number, the last one is ignored.

GFXsetpixelval
     <integer: X>
     <integer: Y>
     <integer: Paint>
Set the pixel identified by (X,Y) to the value Paint.  (If  Paint
is  a  number  greater than can be stored in the window, then the
least significant bits should be used.)

GFXadvpixelval
     <integer: X>
     <integer: Y>
Report (in REPinteger) the value of pixel (X,Y).

-- 5.4   Raster functions ---------------------------------------

GFXgetcomwidth                  (not in first versions)
     <character>
     <character>
This function is the first stage in a three stage  process  which
can  be used to establish the width of the communications channel
in each direction (the width is the number of bits  that  can  be
sent  in  each  byte:  normally eight bits, there are some remote
cases in which the eighth bit is  always  cleared,  and  so  only
seven  bits  can  be sent).  The two characters sent have the bit
patterns
            1 0 1 0 1 0 1 0
    and
            0 1 0 1 0 1 0 1
that is, performing an 'exclusive or' on the two  numbers  passed
on  this  way  should  give  a byte whose bits are 1 wherever the
communications channel allowed them to pass without interference,
and  0 elsewhere.  The width of the channel in the direction from
POPLOG to the PWM is then the number of consecutive 1  bits  from
the  least  signifigant  bit,  "left".   The PWM responds to this
function by sending REPcomwidth.

REPcomwidth                  (not in first versions)
     <character>
     <character>
     <integer>
The two characters are chosen as described above.  The integer is
the  width  of  the channel from POPLOG to the PWM, calculated as
above; it thus tells POPLOG how much data it can reliably send in
a byte.

GFXsetcomwidth                  (not in first versions)
     <integer>
POPLOG sends this message after receiving REPcomwidthin  response
to  GFXgetcomwidth,  as  the  third  stage  in  the process.  The
integer is the number of width of the channel from PWM to POPLOG,
calculated  from  the  two  characters sent in REPcomwidth.  This
value is stored by the PWM to determine how it  responds  to  the
GFXloadraster command, below.

It is POPLOG's responsibility to ensure  that  this  three  stage
process   to  determine  the  width  in  each  direction  of  the
communications link is carried out before dumping  or  loading  a
raster for the first time.

GFXdumpraster                    (expanded definition)
     <integer: X>
     <integer: Y>
     <integer: W>
     <integer: H>
     <integer: BypR>
     <small-int: BpP>
     <small-int: BpB>
     (raster data)
This function is used by POPLOG to dump a raster  (bit-image)  to
the currently selected surface.  The arguments X and Y define the
coordinate of the point on the destination surface at  which  the
top-left  corner  of  the image should be displayed.  The W and H
arguments define the width and height of the raster.  The integer
BypR  defines  how  many  bytes  will be send for each row of the
raster.  The final two arguments, BpP and BpB define  the  format
of  the  following  data  as  bits-per-pixel  and  bits-per-byte,
respectively.

The function instructs the PWM to read the data  for  the  raster
from  its standard communication line to POPLOG; the PWM will use
the H and BypR arguments to calculate how much  data  to  expect,
and  will  therefore consume all further data sent via this line,
using it to create the raster, until it has acquired this amount.

The arguments BpB defines how many bits in each byte of following
data  are  to  be  considered  signifigant: the least signifigant
<BpB> bits will then be taken from each byte of the data to  form
a  new  bit-stream.  This bit stream is then interpreted to image
data by taking each consecutive <BpP> bits for a pixel.  The data
for  each  pixel  in  the  first  row is sent (beginning with the
left-most pixel) and this is padded if necessary to occupy <BypR>
bytes  in  the  raw  data.   It  is  followed  by  the  data  for
consecutive rows in the same format.  There is no  indication  of
the end of the raster data.

Note that the raster data is not included in the message  itself;
it is assumed to follow it immediately.

GFXloadraster
     <integer: X>
     <integer: Y>
     <integer: W>
     <integer: H>
This function requests the PWM to send to POPLOG a description of
the  raster  defined  by  the  rectangle  of the current graphics
window with top-left corner at coordinate  (X,Y)  and  width  and
height W, H.  The PWM should clip these arguments as necessary to
the edges of the window, and then report, in  REPrastercome,  the
details.  It may (e.g. because the clipping reduced the rectangle
to a zero area) report a zero width and zero height.   Otherwise,
the  report should be followed by sending the raster to POPLOG in
the same format as described for GFXdumpraster, above.

REPrastercome                    (not yet implemented)
     <integer: W>
     <integer: H>
     <integer: BypR>
     <small-int: BpP>
     <small-int: BpB>
     (raster data)
This is the report sent from the PWM to POPLOG to pass POPLOG the
details  of the raster descriptiion that follows it.  The meaning
of all the arguments is as described for GFXdumpraster, above.

GFXcopyraster
     <surface-id: Ss>
     <surface-id: Sd>
     <small-int: Op>
     <integer: Xs>
     <integer: Ys>
     <integer: Ws>
     <integer: Hs>
     <integer: Xd>
     <integer: Yd>
This instructs the PWM to take the following actions, or  actions
with equivalent effects:
     - Copy the rectangular image identified by  top-left  corner
     (Xs,Ys)  and width and height Ws, Hs of "source" surface Ss,
     to a temporary area.
     - Apply the raster-op Op to the specified  rectangular  area
     of Ss.
     - Copy the saved image  to  "destination"  surface  Sd  with
     top-left   corner   (Xd,Yd)  using  the  currently  graphics
     raster-op.
The PWM need  not  actually  perform  exactly  these  steps:  for
example,  if the Op raster-op is something simple (such as CLR or
SET) and the old and new locations are on different  surfaces  or
don't  overlap,  it  may not be necessary to copy the raster to a
temporary area.

GFXwriterasfile
     <integer: X>
     <integer: Y>
     <integer: W>
     <integer: H>
     <string>
Save the specified rectangle of the current  surface  to  a  file
specified  by the string.  It is entirely implementation-specific
as to the format of the file, and indeed  the  interpretation  of
the  file-spec.  Presumably if the host-machine has some standard
format for saving bit-images in files it would make sense to  use
this.   It  should  be  remembered  that  the  string  is  to  be
interpreted as a filespec by the PWM, on the machine hosting  the
PWM,  relative (if appropriate) to the directory in which the PWM
was invoked.

GFXreadrasfile
     <integer: Xs>
     <integer: Ys>
     <integer: Ws>
     <integer: Hs>
     <integer: Xd>
     <integer: Yd>
     <string>
Interpret the string as a filespec, and attempt to  load  a  bit-
image  from the specified file.  It is assumed that the file will
be in the same format as that  used  by  GFXwriterasfile,  above.
The  arguments  Xd,  Yd specify the point on the current graphics
surface to which the top-left  corner  of  the  image  should  be
restored.  The arguments Xs, Ys, Ws and Hs may be used to specify
a rectangular sub-portion of the image from the  file,  and  only
this  part should be restored; following the usual conventions on
the meaning of zero width or height, so that zero values for  all
four of these arguments specifies the whole of the image from the
file.

-- 5.5   Fonts --------------------------------------------------

GFXsetfont
     <small-int>
Use the font referenced by the argument for subsequent  calls  of
GFXwritetext,  below.   This  is  known  as the "current graphics
font".  When the PWM is  started  up,  the  only  font  that  may
validly  be  referenced  is  the  standard font used for terminal
emulation, which is referenced as font 0.

GFXwritetext
     <integer: X>
     <integer: Y>
     <string>
Write the string  on  the  current  graphics  window,  using  the
current  graphics  font,  with  the baseline and left edge of the
first character at the position specified by (X,Y).   The  string
should be printed in one line - that is, if necessary, it must be
clipped, rather than wrapped. If the current graphics font  is  a
variable-width  font  the  characters  should  be  spaced  by the
"maximum width" of the font (see below).

GFXloadfont
     <string>
Load a font from the file specified by the string.  The file must
be in some format that is implementation specific: presumably, if
there is some standard font-file  format  defined  for  the  host
machine,  the PWM will use that.  See the notes on interpretation
of the filespec under GFXreadrasfile,  above.   If  the  font  is
succcesfully  loaded, its details are stored somewhere where they
can be referenced by a small integer, a font-identifier, and this
is  returned  (in REPnewfont, below). The font-identifier can now
be used as an argument to GFXsetfont, above.

REPnewfont
     <small-int>
     <integer: W>
     <integer: H>
     <integer: B>
Report the identifier and the width, height and  baseline  values
for the newly loaded font.  The width and height values represent
the amounts by which a notional  "printing  position"  should  be
incremented   when   printing  text  'normally  spaced'.   It  is
recognised that this is less information  that  is  required  for
full use of proportional fonts; it may in the future be necessary
to provide additional functions in this respect.  In the case  of
a proportional font, the maximum values should be returned.

GFXkillfont
     <small-int>
The argument must be a font identifier as defined above.   If  it
identifies  font  0  no action is taken: otherwise the details of
the font are destroyed, and the identifier is  no  longer  valid.
If  the  referenced font is the current graphics font at the time
this call is made, font  0 is selected as  the  current  graphics
font.

-- 5.6   Colour -------------------------------------------------

Colour is one of the areas where different window systems diverge
most  widely,  and  it  is  likely  that  users  writing portable
programs  using  colour  will  have  to  use  separate  code   to
initialise  colour  for each machine in any case.  However, there
are two functions which should be useful on  any  colour  machine
using colour maps (this is probably all colour machines) although
they may need revision if the PWM is ported  to  a  mchine  which
does  not specify colours via the RGB model.  They can be ignored
by any machine which does not support logical colours:

GFXsetmapentry
     <integer: E>
     <integer: R>
     <integer: G>
     <integer: B>
Set entry E in the colour map (for the  current  window)  to  the
values  specified  by  R,G,B.   If  the  entry number exceeds the
colour map size, do nothing.

GFXgetmapentry
     <integer: E>
Report the definition of logical colour E, in REPmapentry.

REPmapentry
     <integer: R>
     <integer: G>
     <integer: B>
Describes  the  logical  colour  specified  by  the  argument  to
GFXgetmapentry.  If there is no such colour, R,G and B should all
be -1.

Additionally, the Sun colour workstations support virtual  colour
maps  which  can  be  associated with one or more windows, called
Colour Map Segments (CMS).  The  following  functions  have  been
defined  for use with these: it is unlikely that they will have a
sensible interpretation on other workstations.

GFXmakecms
     <integer:S>
Make a new CMS, with S entries.  If successful, this  returns  an
identifier for the CMS in REPstatus.

GFXsetwincms
     <cms-id>
Associate the specified CMS with the current graphics window.

GFXkillcms
     <cms-id>
Kill (remove from storage and release any  associated  resources)
the  specified CMS.  Has no effect if the CMS is still associated
with any live window.

-- 6   FUNCTIONS FOR TRACKING THE MOUSE -------------------------

As mentioned above, one of the main design aims for the  PWM  has
been  to  shift  the  burden  of  processing  to the PWM wherever
possible, and reduce the traffic between it and POPLOG.   When  a
user moves the mouse, it typically produces an enormous volume of
input events to any process that is tracking the mouse; and if it
is  desired  to  give  some  kind of visual feedback of the mouse
movements, this may mean a great deal of processing - even if the
processing required for each individual event is quite slight.

There are a  number  of  "cliches"  which  are  used  to  provide
feedback  to  a  mouse user.  By implementing several of these at
the PWM, it is hoped that in very  many  cases  the  programmer's
requirements  for  feedback  can  be  met  without the processing
having to be done at the POPLOG end of the line.

Further, it is very often the case that only the  final  position
of  the  mouse  (for  example the position when a mouse button is
released)  is  actually   required   by   the   programmer:   the
intermediate  mouse  positions are often tracked only in order to
implement the visual feedback: thus supporting  feedback  at  the
PWM can massively reduce traffic.  Even if a program does require
intermediate positions, if it doesn't have to implement  feedback
it  can  often  simply  store  them (which can be done very fast)
until the interaction is finished: thus a deluge of messages from
the PWM can be survived.

In order to avoid recieving such a deluge  accidentally,  and  to
avoid  unwanted  and misleading feedback, the functions described
below are ignored if they are received when no mouse buttons  are
down,  and  cancelled  as soon as the mouse buttons are released.
Thus the normal use is that POPLOG receives a  message  from  the
PWM  indicating  that  the  user  has pressed a mouse button, and
responds with a message  invoking  tracking  and/or  feedback  as
described below.

The functions below are described separately: it happens that  at
the  moment  a single message is used to invoke either continuous
reporting of mouse movements or one of  the  feedback  modes,  or
both.   Most  of  the  kinds of feedback described below have two
modes: in the description below  they  are  listed  as  taking  a
"<boolean:  mode>"  argument,  and they are described as having a
slightly different behaviour if  this  argument  is  "true".   In
fact,  no such argument exists: rather all the functions in their
different modes have a number which is one of  the  arguments  to
the  actual  message  sent.   (This is the only such occurence of
lying about the arguments in this specification.)

None of the functions described in this section were in the first
versions of the PWM.

-- 6.1   Mouse reports and recording mouse positions ------------

TRKreportmoves
After receipt of this message and until the interaction is ended,
each  time  that  the PWM is informed that the mouse has moved it
reports the event  to  POPLOG,  as  REPmousemove.    The  message
includes the number of the button which is being pressed, and the
location of the mouse relative to the top-left of the window,  in
pixels  if the window is a graphics window and in character units
otherwise.

REPmousepress
     <small-int: Button>
     <integer: X>
     <integer: Y>
Reports that the user has pressed a mouse  button  at  coordinate
X,Y in the current input window.  If the window is a text window,
X and Y are in character units; otherwise they are in pixel units
(in  either  case relative to the top left corner of the window).
Note that although this message is described in this section,  it
quite  separate  from  the  mouse  tracking  functions and may be
emitted at any time.

REPmouserelease
     <small-int: Button>
     <integer: X>
     <integer: Y>
Reports that the user has released a mouse button  at  coordinate
X,Y in the current input window.  If the window is a text window,
X and Y are in character units; otherwise they are in pixel units
(in  either  case relative to the top left corner of the window).
Note that although this message is described in this section,  it
quite  separate  from  the  mouse  tracking  functions and may be
emitted at any time.  However, it will  not  be  emitted  without
having  been preceeded by a REPmousepress message: for example if
the user pressed a mouse button, then moved into a PWM window and
released it, no message will be sent to POPLOG.

REPmousemove
     <small-int: Button>
     <integer: X>
     <integer: Y>
Reports that the user has moved the mouse, while holding  down  a
mouse  button, at coordinate X,Y in the current input window.  If
the window is a text window, X and  Y  are  in  character  units;
otherwise they are in pixel units (in either case relative to the
top left corner of the window).  Note that this message will only
be sent after POPLOG has invoked TRKreportmoves.

REPmouseexit
     <small-int: Button>
Reports that the user has moved the  mouse  out  of  the  current
input  window  while  holding  a button down.  Note that although
this message is described in this section, it quite separate from
the  mouse  tracking  functions  and  may be emitted at any time.
However, it will not be emitted without having been preceeded  by
a  REPmousepress  message:  thus  a REPmousepress message, if the
client does not react to it (e.g. by invoking TRKreportmoves,  or
putting   up   a  menu)  should  always  be  followed  by  either
REPmouserelease or REPmouseexit.  On those systems which  do  not
directly  associate  input  with the window that the mouse is in,
this report need not be sent as soon  as  the  mouse  leaves  the
window; but while the mouse is outside the window no REPmousemove
reports should be sent, and when the button is released either  a
REPmouserelease or REPmouseexit message should be sent, according
to whether or not the mouse is inside the window when the  button
is released.

-- 6.2   Feedback modes -----------------------------------------

All the modes of visual feedback use  the  concept  of  a  moving
point  attached  to the mouse cursor.  It is the movement of this
point that is assumed to be of interest, and the various forms of
feedback are designed to support this.

Although the moving point that is being tracked is  conceived  of
as being "attached" to the mouse cursor, it need not lie directly
under it.  All  the  functions  listed  below  take  two  integer
arguments  X  and  Y;  these  define  the initial position of the
moving point, and by comparison with the position  of  the  mouse
when  the  "button  pressed" report was sent to POPLOG, specify a
constant two-dimensional offset to be applied  to  transform  the
mouse position to the position of the 'moving point'.

Further, although the movement of the mouse cursor itself  cannot
be  restricted,  the movement of the moving point that follows it
can be.  A rectangular area of the window can be  specified,  and
the  moving  point  will  then be restricted to travelling within
that area.  It will in effect be attached to the mouse cursor  by
a  piece  of strong elastic: if the mouse cursor moves out of the
limiting box, but remains in the window, the moving point will be
as  close  as  it  can  to  the mouse cursor without itself going
outside the limiting box.  All the feedback modes described below
take  four  integer  arguments (LX1, LY1, LX2, LY2) which defines
such a rectangular area. Making the box a point  size  (i.e.  LX1
equals LX2, and LY1 equals LY2) specifies no limitations.

Finally note that from POPLOG's point of view, all ordinates  are
in  a  mode  appropriate  to  the type of window.  Thus in a text
window, the original report of a mouse button being pressed gives
the   mouse's  location  in  character  coordinates,  with  0,  0
indicating the first character in the top row: the arguments to a
responding call of one of the functions described in this section
should be interpreted in the same coordinate system.

In all modes it should be remembered that the window on which the
feedback  is  displayed is the window in which the original mouse
input came - i.e. it need not be the  window  currently  selected
for text or graphics.

6.2.1   Moving points

TRKsketchline
     <integer: LX1>
     <integer: LY1>
     <integer: LX2>
     <integer: LY2>
     <integer: X>
     <integer: Y>
A line is drawn starting from the initial  value  of  the  moving
point  to  successive locations of it, using the current graphics
raster-op and paint (see the section on  graphics  functions  for
details).   Note that this is the only mode in which the contents
of the window will be changed at the end of the interaction.  (It
is  most  likely  to  be used in conjunction with TRKreportmoves,
enabling a POPLOG program to record the points between which  the
line was drawn.)

TRKcrosshairs
     <boolean: mode>
     <integer: LX1>
     <integer: LY1>
     <integer: LX2>
     <integer: LY2>
     <integer: X>
     <integer: Y>
The mouse cursor (which should be hidden during the  interaction)
is tracked by a horizontal and a vertical line drawn in inverting
paint, which pass through the moving point.  If the mode flag  is
true  the  lines  extend only to the boundaries of the limit box;
otherwise they extend to the edges of the window.

6.2.2   Rubberware

TRKrubberline
     <integer: LX1>
     <integer: LY1>
     <integer: LX2>
     <integer: LY2>
     <integer: X>
     <integer: Y>
     <integer: I>
     <integer: J>
A line is drawn in inverting paint from the fixed point (I, J) to
the moving point (initially (X, Y)).

TRKrubberbox
     <boolean: mode>
     <integer: LX1>
     <integer: LY1>
     <integer: LX2>
     <integer: LY2>
     <integer: X>
     <integer: Y>
     <integer: I>
     <integer: J>
A box is drawn with one corner at the fixed point (I, J) and  the
diagonally opposing corner at the moving point (initially (X,Y)).
if the mode flag is true the entire  area  of  the  window  lying
within the box is inverted; otherwise only the outline of the box
is drawn, in inverting paint.

6.2.3   Moving rectangles

TRKbouncybox
     <boolean: mode>
     <integer: LX1>
     <integer: LY1>
     <integer: LX2>
     <integer: LY2>
     <integer: X>
     <integer: Y>
     <integer: I>
     <integer: J>
A  box  is  drawn  with  top-left  corner  at  the  moving  point
(initially  (X,Y))  and  width  and  height  specified by I and J
respectively. If the mode flag is true the  entire  area  of  the
window  lying  within  the  box  is  inverted; otherwise only the
outline of the box is drawn, in inverting paint.

Note that the offset which connects the moving point to the mouse
cursor,  in  this  mode, is not simply the difference between the
initial value specified for the moving point and the position  of
the  mouse when the button was depressed, but is calculated so as
to "snap" the box, by  nearest  side  or  corner,  to  the  mouse
cursor,  in a manner which should make this kind of feedback more
intuitive.

The offset is calculated as follows: if the mouse lies within the
rectangle,  the  offset  is  calculated  in  the  normal  manner.
Otherwise if the mouse lies within the middle half of a side (but
outside  the  rectangle) it is snapped to the appropriate part of
that side; otherwise it is snapped to the corner.
TRKbouncyras
     <boolean: mode>
     <integer: LX1>
     <integer: LY1>
     <integer: LX2>
     <integer: LY2>
     <integer: X>
     <integer: Y>
     <integer: I>
     <integer: J>
     <integer: M>
     <integer: N>
     <surface-id: W>
A rectangular image is taken from  the  area  of  the  window  or
graphics surface W, the rectangle being specified by the top-left
corner (I,J) and width and height M, N.  The image is then  moved
around  the  (current  input)  window  so as to follow the moving
point.

If the mode flag is true, the moving image blocks out whatever is
beneath  it;  otherwise  it is combined with the image beneath it
using the exclusive-or function.  In either case (as in  all  the
feedback  modes except TRKsketchline) the window will be restored
to its previous state at the end of the interaction.

If the surface identified by W is the current input  window,  the
rectangular  image is "snapped" to the mouse cursor in a sensible
manner as in the TRKbouncybox function.  In any other  case,  the
top-left  corner  of  the  moving image is attached to the moving
point (initially (X,Y)).

6.2.4   Marking ranges of text

TRKinverttext
     <boolean: mode>
     <integer: LX1>
     <integer: LY1>
     <integer: LX2>
     <integer: LY2>
     <integer: X>
     <integer: Y>
This mode can only be used in a text (including VED)  window:  if
it  is  requested for any other kind of window an error should be
generated and the request ignored.

All the text in the window, from the fixed point (I,J) in  either
direction to the moving point will be inverted.

That is, if  the  two  points  lie  on  the  same  row,  all  the
characters  on the row between and including the characters under
the two points will be inverted.  If they do not lie on the  same
row  then:  the  characters from the first of these two points to
the end of the row will be inverted; on each row between the  two
points,  every  character  from the first character on the row to
the last will be inverted; on the row on which the  second  point
lies,  all  the characters from the first character on the row to
that point (inclusive) will be inverted.

The 'first character on the row' is the character in column 0 for
a  text  window,  and the character in column 1 for a VED window.
The 'last character on the row' is the character  in  the  right-
most  column of the window if the mode flag is true; otherwise it
is the character after the last non-space character on the line.

-- 7   USER INTERFACE FUNCTIONS ---------------------------------

-- 7.1   Menus --------------------------------------------------

USRdefinemenu                  (revised specification)
     <string>
The string defines  a  'pop-up'  menu  according  to  the  format
covered   in   a   separate   appendix.   If  the  definition  is
syntactically correct, the PWM should store the  details  of  the
menu  and return a "menu-id" (in REPstatus) by which the menu can
be referenced later; otherwise it should return the pseudo-id -1.

USRdodefmenu                  (revised specification)
     <window-id>
     <menu-id: M>
     <integer: X>
     <integer: Y>
Put up the defined menu M on screen, and return (in REPstatus)  a
number  to indicate which, if any, of the options was selected by
the user.  The PWM or its host window manager  decides  where  to
put  the  menu  (usually  somewhere close to the mouse cursor, at
least on non GEM-style systems); if the  window-id  references  a
live  window  then  the  arguments  X  and Y indicate a suggested
position (in pixels relative to the top-left of  that  window)  -
which  the  PWM may overrule.  If none of the options are chosen,
zero is returned.

USRdonewmenu                  (revised specification)
     <window-id>
     <string: M>
     <integer: X>
     <integer: Y>
Exactly as USRdodefmenu except that the string  M  is  parsed  to
define  the  menu,  which is then destroyed immediately after the
interaction.  This version is useful both for menus which have  a
short life, and in case the PWM has no more room to store further
menu definitions.

USRkillmenu                  (not in first versions)
     <menu-id>
If the menu-id references a defined menu, it should be destroyed;
otherwise  an  error should be generated - unless the id is zero,
in which case  no  complaint  should  be  voiced.   (The  special
treatment   for   menu   0  allows  compatability  with  previous
versions.)

-- 7.2   Scroll bars --------------------------------------------

REPscrollerpos                    (not yet implemented)
     <window-id>
     <integer: H>
     <integer: V>
May be emitted either in response to  an  ADVscrollerpos  message
from  POPLOG  or  spontaneously  in response to the user moving a
scroller.  Indicates the window, and the current position of  the
horizontal  and vertical scrollers - in either case, reporting -1
if the relevant scrollbar does not exist.  Thus if the report was
spontaneously  generated  at  least  one  of H and V must be non-
negative; but both may be negative if it was emitted in  response
to ADVscrollerpos on a window with no scrollbars.

ADVscrollerpos                    (not yet implemented)
     <window-id>
This invokes a REPscrollerpos as described above.

SETscrollerpos                    (not yet implemented)
     <window-id>
     <integer: Ph>
     <integer: Pv>
If the window has a horizontal elevator and Ph  is  non-negative,
this  sets  the  position of the moving part to Ph; similarly the
vertical elevator, if there is one, is set to  Pv  unless  it  is
negative.   No  complaint  is voiced if an attempt is made to set
the position of an elevator which does not exist.

SETscrollersize                    (not yet implemented)
     <window-id>
     <integer: Sh>
     <integer: Sv>
If the window has a horizontal elevator and Sh  is  non-negative,
this  sets  the size of the moving part to Sh; similarly the size
of the moving part of the vertical elevator, if there is one,  is
set  to  Sv  unless it is negative.  No complaint is voiced if an
attempt is made to set the size of an  elevator  which  does  not
exist.

-- 7.3   Prompt boxes -------------------------------------------

USRdoprompt             (specification under review)
     <integer>
     <string>
This displays some text in a box somewhere on the  screen,  waits
for  some  user  action,  removes  the box and returns a message,
REPinpevent, indicating what the user action  was.   The  integer
argument may be used to suggest how the text should be formatted,
as the width in characters of the box.

This function has been found to be  insufficiently  flexible  for
many  purposes.   It might be better to replace it with something
more powerful, for example  along  the  lines  of  GEM's  "dialog
boxes".  Alternately, these facilities could be provided in other
areas, and this function replaced with  a  simpler  notion  of  a
"confirmation" box.

-- 7.4   Customising the cursor image ---------------------------

There are wide variations between window systems on the extent to
which  mouse-following  cursors  can  be  customised.   POPLOG is
permitted to assume that there are at least three cursors  (which
can  be submitted to USRsetwincur) available: a "normal" one, the
default cursor; a "text" one, especially suitable for pointing at
text;  and  a  "graphics"  one,  especially suitable for use with
graphics.  These cursors are indexed respectively as 0, 1 and  2.
However, it is acceptable for either or both of the latter two to
be synonymous with the  first,  or  for  the  latter  two  to  be
synonymous,  if  the  limitations  of  the  workstation make this
necessary.

USRnewcurfile            (no implementation scheduled)
     <string>
The string is to be interpreted by the PWM as specifying  a  file
in  which a cursor is defined, presumably in some implementation-
specific format which is standard for the host machine.   If  the
PWM  can  successfully  load  it,  it  stores all the details and
returns a small integer (in  REPstatus)  by  which  they  can  be
addressed (a "cursor-id"); otherwise it returns the pseudo-id -1.

USRnewcurimage            (no implementation scheduled)
     <integer: W>
     <integer: H>
     <integer: BypR>
     <small-int: BpP>
     <small-int: BpB>
     <integer: Hx>
     <integer: Hy>
     <small-int: raster-op>
     (<raster>)
Consult the description  of  GFXdumpraster  for  how  the  raster
argument is passed, and that of GFXsetrasterop for details of how
the raster-op argument is interpreted.

Define a cursor using the passed raster, which should be of width
W,  height  H,  and  depth D bits per pixel.  If the host machine
supports nominating a point within the cursor to  be  the  actual
center of the cursor ("hot-spot", in Sun terminology) use the Hx,
Hy arguments for this purpose, in pixels relative to the top-left
corner  of the image (which is therefore 0, 0).  The image should
be clipped or expanded as necessary to suit  the  host  machine's
standard, minimum or maximum dimensions of a cursor.  If the host
machine supports nominating  a  raster-op  for  the  cursor,  the
argument  raster-op  should be used; if there are restrictions on
which raster-ops are acceptable and that given  is  unacceptable,
the SRC raster-op should be used instead.

If the PWM supports dynamic defining  of  cursors,  and  all  the
arguments  have  been receieved and found acceptable, the details

of the cursor should be stored, and a small integer returned  (in
REPstatus)  by  which they can be addressed.  If the depth of the
raster is unreasonable, an error should  be  generated.   In  the
event  of  any  other  problems,  or  if the PWM does not support
dynamic  definition  of  cursors,  the  pseudo-id  -1  should  be
returned.

USRsetwincur
     <window-id>
     <cursor-id>
If cursor-id references a valid cursor,  and  window-id  a  valid
window,  and  the host machine allows this action, set the mouse-
following  cursor  to  use  the  referenced   image   and   other
attributes,  for the given window.  Not all systems which support
dynamic setting of cursors associate cursors with windows; it  is
left  to  the  discretion of the implementor how best to simulate
this function.  (E.g. in GEM the cursor is  associated  with  the
screen  rather than a window; but selecting a window for input is
a relatively major function, so the cursor could  be  changed  as
necessary according to which window is selected.)

USRkillcursor
     <cursor-id>
The details of the cursor identified by the argument are deleted,
and the identifier is no longer valid.  No complaint is voiced if
the details cannot be erased, for example  because   the  PWM  is
running on a machine with a fixed set of cursors.

-- 7.5   Marking ranges of text ---------------------------------

USRinverttext
     <small-int: Mode>
     <window-id>
     <integer: L1>
     <integer: C1>
     <integer: L2>
     <integer: C2>
This function inverts a portion of  the  text  in  the  specified
window  (which must be a text window, i.e. the base window, a ved
window, or a user text window, otherwise the command is ignored).

All the text in the window, from the character  at  line  L1  and
column  C1  to the character at line L2 and column C2, inclusive,
is inverted.

That is, if  the  two  points  lie  on  the  same  row,  all  the
characters  on the row between and including the characters under
the two points will be inverted.  If they do not lie on the  same
row  then:  the  characters from the first of these two points to
the end of the row will be inverted; on each row between the  two
points,  every  character  from the first character on the row to
the last will be inverted; on the row on which the  second  point
lies,  all  the characters from the first character on the row to
that point (inclusive) will be inverted.

The 'first character on the row' is the character in column 0 for
a  text  window,  and the character in column 1 for a VED window.
The 'last character on the row' is the character  in  the  right-
most  column  of  the window if the Mode argument is greater than
zero; otherwise it is the  character  after  the  last  non-space
character on the line.

If the  the  character  specified  by  (L2,  C2)  is  before  the
character specified by (L1, C1) the command is ignored.

It is not specified that the inverting  should  be  preserved  if
POPLOG  alters  the  characters in the window in any way, e.g. by
scrolling the text.  Thus calling this function  twice  with  the
same arguments can only reliably be expected to leave no inverted
characters if there were no intervening  commands  which  altered
the   text   in  the  window.   However,  invoking  the  function
WMRrefreshwin should definitively remove any highlighting.

-- 8   FUTURE OF THE POPLOW WINDOW MANAGER ----------------------

-- 8.1   Possible extensions to the PWM -------------------------

This chapter discusses some of the features that it is  currently
planned  to  add  to  the  PWM, and some facilities that might be
useful - but which are perhaps less  likely  to  be  implemented.
They are in no particular order.

o Curves
     At present, the  graphics  facilities  do  not  support  any
     functions  for drawing curved figures.  The simpler forms at
     least are obviously not difficult to implement, even if  not
     directly   supported  by  the  host  workstation's  graphics
     library: indeed the  current  POPLOG  PWM  library  includes
     routines  for  filled and outlined circles and ellipses.  To
     the user,  these  are  indistinguishable  from  any  of  the
     built-in  graphics  primitives  -  except that they are much
     slower, mainly because of the amount of  communication  that
     is  involved  to  draw  a relatively high-resolution figure.
     The constraint that is relevant here is the desire  to  keep
     the size of the command set small: it is not clear how often
     these functions would be required.

o Multiple line styles
     Many of  the  window  systems  for  which  PWM's  are  being
     implemented  are  planned  support various line styles (e.g.
     different widths, dotted lines etc).   It  is  fairly  clear
     that  a  certain  group  of  users  of  the  PWM's  graphics
     functions would appreciate such functions, and they can  not
     elegantly  be simulated given the current set of primitives.
     The constraint that is most relevant in this  connection  is
     the  desire  to  keep  the  set  of PWM functions consistent
     across all implementations.  Obviously these functions could
     be implemented on all systems - given enough time.  To date,
     there has been a shortage of that resource on this project.

o Downloading of (graphics) routines
     That is, the  ability  to  wrap  several  functions  into  a
     routine  (eg  to  draw  a  truck) and then call this routine
     several times.

     For this to be useful in  all  but  a  very  few  cases,  it
     requires either a syntax which allows variable substitution,
     or a change in the semantics of the  graphics  functions  to
     allow relative arguments.

     There are (at least) three possible forms this could take:
         repeat n times (commands...)
         this is THE routine (commands...) ;   run THE routine
         define routine(commands...) -> N ;   run routine N

     This feature would require a  great  deal  of  effort:  it's
     value  needs to considered especially carefully in the light
     of the advent of NeWS (see the next section).

o Downloadable fonts
     This is currently percieved as a low  priority  requirement.
     In  practice  the main advantage of this feature would be an
     extension in portability.

o Fast local access
     Current implementations achieve full generality for the case

     in which a PWM running on some workstation is connected to a
     POPLOG running on a  remote  computer,  at  the  expense  of
     performance  in  the  "local" case where POPOLOG and the PWM
     are running on the same machine.  It would be  desirable  to
     be able to optimise performance in the latter case.

     In fact, at the  time  of  writing  this  feature  is  being
     actively  investigated,  and some possible designs have been
     prototyped.  It is hoped that this feature may  be  included
     in POPLOG V13.

o Fast (graphics) call forms
     That is, a syntax which will allow commands to specify  only
     some  of  the  arguments.   A  bit  pattern could be sent to
     specify which arguments are being supplied,  and  any  other
     arguments   required  would  be  filled  in  from  the  last
     invocation of  this  command.   For  example,  GFXcopyraster
     takes nine arguments.  There are many examples of its use in
     which the  function  is  called  repeatedly  with  only  two
     arguments being changed each time.

o Multiple tracking actions
     Currently the syntax for instructing the PWM to give  visual
     feedback   on   mouse   movements  only  allows  one  action
     specification to be applied to any interaction.   There  are
     likely  to  be applications which would find it useful to be
     able to concatenate several actions: for example, to allow a
     node  in  a  network  to  be  moved around with rubber lines
     attaching it to other nodes.

o Active areas
     Some programs would find it useful to be able to  specify  a
     portion  of a window to the PWM, and thereafter have the PWM
     send it messages whenever the mouse strayed into  this  area
     (i.e.  without  the  user  having to press a mouse button to
     send a message to POPLOG).

o Active areas on scroll bars
     A less  general  version  of  the  above:  have  the  client
     notified  when  the  mouse is moved into the scroll bar area
     (to allow lazy resizing and repositioning  of  the  slider).
     In fact it may have been noted that the scroll-bar functions
     described in chapter 7 have not yet been implemented; so far
     only  prototypes  of  this  mechanism have been experimented
     with,  and  more  experience  is  needed  in  this  area  to
     establish the best form for the interface to scroll bars.

o Automatically highlighted area
     Another specialisation which would answer a  subset  of  the
     demands  for  active  areas,  and would fit with the general
     intention of shifting some of the burden of processing  from
     POPLOG  to  the PWM; allow POPLOG to specify portions of the
     window, and instead of being notified when the mouse strayed
     ino  that  area,  have  the  area  automatically highlighted

     whenever the mouse is there.

o Software expansion slots
     Allowing users to add functions to the PWM  specifically  to
     support  their  project  or  site; for example, a user whose
     workstation has a digitiser with its own frame-buffer  might
     want  to  incorporate  it into the PWM so that the digitiser
     appears as a graphics "page".   One could have some commands
     reserved  to  users,  with an object file of "stub" routines
     provided, which the user can replace  before  relinking  the
     PWM.   This will necessarily be implementation specific.  It
     requires publishing the architecture, or at least some  part
     of it; and this imposes a subsequent requirement of support.

o Heirarchichal menus
     Many window systems support heirarchies of menus,  in  which
     some  options  on  a menu can be specially marked so that if
     the user selects one, instead of taking the  menu  away  and
     sending  a message to the client the window system puts up a
     secondary menu and invites the user to pick an  option  from
     that.   This  extension is under active investigation at the
     moment.

-- 8.2   The PWM, RAL-CSI, Sun-NeWS and X-WINDOWS ---------------

This section, which will examine the impact on the future of the Poplog
Window Manager of some of the emerging (but rival) standards for window
systems, is currently in preparation.  In particular, it is being held
back while NeWS (a beta-test copy of which has recently
been recieved  at  Sussex  University)  and  X  (which   the
university  has just received copies of for Sun and HP- Bobcats)
are evaluated.

-- 9   APPENDICES -----------------------------------------------

Appendix A - message specifications

The basic format of the messages sent from POPLOG to the  PWM  is
an  escape  character,  followed by one of two characters ("{" or
"}") indicating that this is a PWM command, followed  by  a  two-
character  code identifying the command, followed by arguments to
the command, followed by  a  one-  or  two-character  termination
code.

There are three types of argument: character arguments, which are
either  a literal character or a "small integer" in the range 0 -
95, encoded as the character whose ASCII  code  is  32  plus  the
number; integers, which may be positive or negative; and strings.
These are always sent in the same order: every command  has  zero
or  more  character  arguments,  followed by zero or more integer
arguments, followed by zero  or  one  string  arguments.   (Note:
whenever  an  argument  has  been  specified  in  the  preceeding
chapters as an "XXX-id" it is a small integer and is passed as  a
character argument.)

The character arguments  are  sent  consecutively  following  the
two-character command code, with no delimiter.  Integer arguments
are written out in decimal,  in  ASCII,  the  first  digit  being
preceeded  by  a  "-"  character  if  the  argument is a negative
integer, and are terminated by a ";"  character  or  the  command
termination code.

The character following the initial escape is "}" if the  command
includes  a  string  argument, or "{" otherwise.  Commands with a
string argument are terminated by  the  sequence  <escape>,  "\";
other commands are terminated by the character "t".

Thus,  from  the  character  following  the  escape,  a  PWM  can
determine  that this is a PWM command message, and whether or not
it includes a string argument (and  hence  how  the  end  of  the
message  will  be indicated) and that there are at least two more
characters to be read.  From these  two  characters,  a  PWM  can
determine  by  table  lookup how many character arguments to read
before beginning to interpret characters  as  integer  arguments,
string arguments, or terminators.  It can also determine how many
integer arguments  to  parse  from  the  message  before  looking
interpreting  characters  as part of a string argument; and of it
can determine the command in question.  Note that the if and only
if  there  is  no  string  argument,  the PWM can parse a message
without knowing how many integer arguments to expect;  and  there
are a few functions which take advantage of this feature.

Two examples:  this  sequence  (an  example  of  a  SETexternsize
command)  has a small-int argument 1 (ASCII 33 = "!") and integer
arguments 23 and 450:
    <escape> "{FS!23;450t"

And this sequence (an example of a COMmakewindow command)  has  a
character  argument "v", a small-int argument 0 (ASCII 32 = " "),
integer  arguments   80   and   24,   and   a   string   argument
"/poplog/pop/help/pwm":
    <escape> "}NWv 80;24;/poplog/pop/help/pwm" <escape> "\"

      Command name     Command   Number of    Number of   String
                        code     char. args   int. args    arg?

      ADVexternsize      AS          1            0         No
      ADViconlocat       Al          1            0         No
      ADVicontitle       At          1            0         No
      ADVinternsize      As          1            0         No
      ADVscrollerpos     AE          1            0         No
      ADVwinlocal        AL          1            0         No
      ADVwinopen         AI          1            0         No
      ADVwintitle        AT          1            0         No
      COMgettextsel      Ah          0            0         No
      COMkillwindow      Kw          1            0         No
      COMmakewindow      Nw          2            2         Yes
      COMselecttextwin   ST          1            0         No
      COMsettextsel      TS          1            4         No
      COMtidywindows     Sw          0            0         Yes
      GFXadvpixelval     Gp          0            2         No
      GFXcopyraster      GC          3            6         No
      GFXdumpraster      GD          2            5         No
      GFXgetcomwidth     Zw          2            0         No
      GFXgetmapentry     Gm          0            1         No
      GFXkillcms         KC          1            0         No
      GFXkillfont        Kf          1            0         No
      GFXkillpage        Ks          1            0         No
      GFXloadfont        Nf          0            0         Yes
      GFXloadraster      GR          0            4         No
      GFXmakecms         NC          0            1         No
      GFXmakepage        Ns          0            2         No
      GFXpolyline        GL          0            -         No
      GFXreadrasfile     Gr          0            6         Yes
      GFXselectsurface   SG          1            0         No
      GFXsetcomwidth     ZW          0            1         No
      GFXsetfont         SF          1            0         No
      GFXsetmapentry     GM          0            4         No
      GFXsetpaintnum     SP          0            1         No
      GFXsetpixelval     GP          0            3         No
      GFXsetrasterop     SR          1            0         No
      GFXsetwincms       SC          1            0         No
      GFXwipearea        GW          0            4         No
      GFXwriterasfile    Gw          0            4         Yes
      GFXwritetext       GT          0            2         Yes
      SETexternsize      FS          1            2         No
      SETiconfile        Fi          1            0         Yes
      SETiconimage       FI          3            3         No
      SETiconlocat       Fl          1            2         No
      SETicontitle       Ft          1            0         Yes
      SETinputsrc        SI          1            0         No
      SETinternsize      Fs          1            2         No
      SETscrollerpos     FE          1            2         No
      SETscrollersize    Fe          1            2         No
      SETwinlocat        FL          1            2         No
      SETwintitle        FT          1            0         Yes
      USRdefinemenu      Nm          0            0         Yes
      USRdodefmenu       Um          2            2         No
      USRdonewmenu       Um          1            2         Yes
      USRdoprompt        Up          0            1         Yes
      USRinverttext      TH          2            4         No
      USRkillcursor      Kc          1            0         No
      USRkillmenu        Km          1            0         No
      USRnewcurfile      Cf          0            0         Yes
      USRnewcurimage     Ci          3            5         No
      USRsetwincur       Fc          2            0         No
      VEDscrollleft      Vl          0            2         Yes
      VEDscrollright     Vr          0            2         Yes
      VEDsetlineno       Vn          0            1         No
      WMRclosewin        WC          1            0         No
      WMRexposewin       WE          1            0         No
      WMRhidewin         WH          1            0         No
      WMRmovewin         WM          1            0         No
      WMRopenwin         WO          1            0         No
      WMRrefreshwin      WR          1            0         No
      WMRstretchwin      WS          1            0         No

For implementation convenience, some commands which actually take
no arguments have been conflated to give a single command-code in
which a character argument determines which command  is  actually
intended: these messages are given in full below:
      ADVpwmident          "{APit"
      ADVlivewindows       "{APwt"
      COMoneinput          "{AP1t"
      COMgoodbyepwm        "{VC0t"
      COMhellopwm          "{VC1t"
      COMabyssiniapwm      "{VC2t"
      COMpopisback         "{VC3t"
      COMbasecooked        "{VC4t"
      COMbaseraw           "{VC5t"
      COMvedcooked         "{VC6t"
      COMvedraw            "{VC7t"
      ADVinputsrc          "{VC8t"

The functions for tracking the mouse  are  also  conflated  in  a
slightly more complex manner.  Because the action taken on actual
receipt of the message mostly involves  set-up  activities  which
are similar for all modes, it was found to be most simple to have
a single function called by the command parser,  which  consulted
the  first  character  argument  for  the kind of tracking action
required, and examined the number  of  arguments  for  additional
information.

It will be recalled from chapter six that most of  the  varieties
of  feedback  behaviour  offered  have  two  modes,  and that any
request  for  feedback  may  be  accompanied  by  a  request  for
intermediate  mouse  positions to be reported to POPLOG; and that
all the tracking modes can optionally recognise a limiting box.

The first character argument is therefore used to encode the kind
of  tracking  action required, whether in its normal or alternate
mode,  and  whether  or  not  intermediate  mouse  positions  are
required.   If  a  limit  box  is  specified, there are four more
integer arguments than there would otherwise be for that tracking
mode, and the last four integers specify the limit box.

Finally, the command to follow the moving mouse with a bit  image
requires  an additional small-int argument to specify the surface
on which the image is to be  found:  this  command  is  therefore
given  a  separate  code to enable it to be parsed correctly, and
the surface-id is in the second character argument.

The command codes are
      (set up tracking)  TA          1     -     No
      (set up image ")   TB          2     -     No

The first character argument is interpreted  as  follows:  bit  4
(decimal  32) specifies the alternate mode if set; bit 5 (decimal
64) specifies that intermediate positions are to be  reported  if
set;  bits  0-3 (decimal 0-15) specify the kind of feedback to be
provided, as follows (0 if none):
        TRKrubberline           1
        TRKsketchline          33
        TRKcrosshairs           2
        TRKrubberbox            3
        TRKbouncybox            4
        TRKbouncyras            5
        TRKinverttxt            6

(Neither TRKrubberline  nor  TRKsketchline  have  an  "alternate"
mode,  so the latter is treated, for the purposes of encoding the
command, as an alternative mode of the former.)

Appendix B - report specifications

A report is a message which is sent from the PWM to POPLOG.   The
basic  format  of the reports is guided by the same principles as
those applying to the messages sent from POPLOG to the  PWM:  the
character  following the escape is one of two which indicate that
this is a PWM report, and whether it contains a string, and hence
what the terminating sequence is; the next two characters specify
which report this is, and at the same  time  how  many  character
arguments  there are; the character arguments follow immediately;
any numeric arguments come after the character arguments and  are
separated  from  each  other  and  from  a  string,  if any, by a
semicolon.

However, the two lead-in characters are different from those used
for   messages  in  the  opposite  direction,  to  guard  against
misinterpretation  of  messages  accidentally  'reflected';   and
whereas  the  lead-in  characters  for messages from POPLOG are a
matching pair for mnemonic reasons, those for messages  from  the
PWM  have been chosen to avoid problems which arise if the escape
character is for some reason missed by the recieving process  (at
one  time  the braces - "{" and "}" were used, as for messages in
the opposite direction; it was  found  that  if  the  escape  was
mislaid, this could lead to a confusing situation in which POPLOG
was silently locked into a loop building ever more deeply  nested
vectors).   The  lead-in  characters  are  "^" for a report which
doesn't contain a string, and "~" for a report which  does.   The
terminating  sequences  are  the  same as those used for messages
from POPLOG to the PWM, namely "t" for  a  report  which  doesn't
contain a string, and <escape>, "\" for a report which does.

The reports below may be emitted spontaneously by the  PWM:  they
have  been grouped together so that the first character after the
lead-in character identifies the shape (in  terms  of  number  of
character  and  numeric  arguments)  REPwinresized with the mouse
events.

      Report name      Report    Number of    Number of   String
                        code     char. args   int. args    arg?

      REPinputsrc        II          1            0         No
      REPmouseexit       IM          1            0         No
      REPwinclosed       IC          1            0         No
      REPwinopened       IO          1            0         No
      REPwinquitreq      IQ          1            0         No

      REPelevatorpos     Me          1            2         No
      REPmousemove       MM          1            2         No
      REPmousepress      MP          1            2         No
      REPmouserlse       MR          1            2         No
      REPwinresized      Mr          1            2         No

      REPmishap          Er          0            2         Yes

The reports below are only issued by the PWM in response to  some
message  from  POPLOG,  and  are  not subject to the restrictions
mentioned above.  Indeed, they do not really need  two  character
identifiers,  since POPLOG always knows what kind of report it is
expecting: most of them, however, conform to the basic format for
consistency and to reduce errors.

      REPcomswidth       Zw           2       1       No
      REPexternsize      UR           1       2       No
      REPiconlocat       Fl           1       2       No
      REPicontitle       Ft           0       0       Yes
      REPinpevent        i            2       0       No
      REPinteger         ZD           0       1       No
      REPinternsize      Ur           1       2       No
      REPmapentry        GM           0       3       No
      REPnewfont         GF           1       3       No
      REPpwmident        RP           0       -       Yes
      REPrastercome      Gr           2       3       No
      REPstatus          ZI           1       0       No
      REPwinlocat        FL           1       2       No
      REPwintitle        FT           0       0       Yes

Note:

   o the report REPpwmident actually consists of  a  string  with
       several  fields,  as  described  in section 2.1, which are
       delimited by tab characters.

   o the report REPinpevent does not follow the format precisely,
       for historical reasons.

Appendix C - terminal control commands

These two-character escape sequences  are  accepted  as  terminal
control commands:

          <esc> A :   cursor_up
          <esc> B :   cursor_down
          <esc> C :   cursor_right
          <esc> D :   cursor_left
          <esc> F :   set_graphic_mode
          <esc> G :   reset_graphic_mode
          <esc> H :   home_cursor
          <esc> L :   insert_line
          <esc> M :   delete_line
          <esc> O :   delete_character
          <esc> Z :   send_terminal_id
          <esc> i :   set_insert_mode
          <esc> j :   reset_insert_mode
          <esc> t :   clear_line
          <esc> v :   clear_page
          <esc> x :   clear_endof_line
          <esc> y :   clear_endof_page

Either of these two sequences is accepted  as  a  cursor  address
command
              <esc> Y <charY> <charX>
              <esc> [ <intY> ; <intX> H
In the first sequence (Vi200 standard) X and Y are encoded as the
character  whose  ASCII  code is 32 plus the value; in the second
(ANSI standard) they are written in ASCII digits as  integers  in
base 10.

These two-character escape sequences, part of the standard  Vi200
command  set,  are  read  in  but  ignored  (i.e.  the  character
following the escape, if it is one  of  those  listed  below,  is
silently  consumed,  rather  than  being  subject  to  the normal
treatment of unknown escape sequences):

          <esc> - : (copy off)
          <esc> 1 : (set tab)
          <esc> 2 : (clear tab)
          <esc> 3 : (set foreground)
          <esc> 4 : (set background)
          <esc> 5 : (remote trans.)
          <esc> 6 : (set protect)
          <esc> 7 : (set non-prot.)
          <esc> 8 : (set batch mode)
          <esc> 9 : (set page mode)
          <esc> ; : (lock block)
          <esc> : : (reset block)
          <esc> = : (set pad)
          <esc> > : (reset pad)
          <esc> I : (cursor up-scroll)
          <esc> J : (erase e.o.p.)
          <esc> K : (erase e.o.l.)
          <esc> N : (set s.o.t. code)
          <esc> S : (reset auto tab)
          <esc> W : (transparent on)
          <esc> X : (trans.+copy off)
          <esc> \ : (reset hold screen)
          <esc> a : (set security)
          <esc> b : (reset security)
          <esc> c : (enable slow scrl.)
          <esc> d : (disable slow scrl.)
          <esc> e : (read term. stat.)
          <esc> f : (erase e.o.f.)
          <esc> g : (clear all tabs)
          <esc> h : (lock keyboard)
          <esc> k : (stop blink)
          <esc> l : (unlock keyboard)
          <esc> m : (set block mode)
          <esc> n : (reset block mode)
          <esc> o : (set line mode)
          <esc> q : (set auto tab)
          <esc> r : (read cursor addr)
          <esc> s : (blink line)
          <esc> u : (clear eop-bckgnd)
          <esc> w : (erase page)
          <esc> z : (back tab)

Appendix D - menu definitions

Menus are transmitted to the PWM as a string (see USRdefinemenu).
This appendix describes the format of such a string.

The basic syntax is

    <title> <delimiter> [ {<flag>} <option> <delimiter>]

where
     <title> and <option> are  arbitrary  strings  containing  no
     control characters.
     <delimiter> is either the character `^b` (8) or `^t` (9)
     <flag> is either the character `^A`, (1) or `^N` (14)

The signifigance of the delimiters is as follows:
    `^t` is simply a delimiter;
    `^b` requests a separator at this point
            (eg a horizontal line - mnemonic "bar").

The signifigance of the  optional  flag  character  preceding  an
option is as follows:
        ^A      -  this  option  should  be  displayed  in   half
            intensity, and should not be selectable.   ("Advisory")
        ^N      -  this  option  should  be  displayed  in   full
            intensity, but is selectable (default).    ("Normal")

Note:

   o that the menu string always end with a delimiter.

   o separators may not be supported on all systems; if they  are
       not  supported,  `^b`  is treated as exactly equivalent to
       `^t`.

   o non-selectable options may not be supported on all  systems:
       if  they  are  not  supported, they should be displayed as
       normal, but if one is selected, then the PWM should return
       the same result as it would for no option being selected.

Example - this menustring:

    'Moves:^b^HNorth^t^NSouth^t^NEast^t^HWest^bQuit^t'

requests a menu like this:

      Moves:   <- title - should be somehow distinguished
      North    <- this option should be non-selectable, grey
      South    <- this option should be selectable, black
       East    <- selectable, black
               <- separator
       West    <- non-selectable, grey
       Quit    <- selectable, black

    the '^b' after the title string could  equally  have  been  a
`^t`.

    the '^N' before the "South" and  "East"  options  could  have
been omitted, since it is the default (as was done for the "Quit"
option).  However, users might wish to include it  so  that,  for
example,  they  can  make  a  single  such string and then use it
repeatedly, changing which options are selectable by updating the
appropriate flag characters in the menu string.

    The result of invoking the menu is a number in the range 0 to
N,  where N is the number of options, selectable or otherwise, in
the menu. A result of zero indicates that the user dismissed  the
menu without selecting any of the "selectable" options; any other
integer refers to the option  selected,  numbered  from  1,  with
non-selectable  options  being  counted. E.g. on the example menu
above, possible results and their meanings would be:

            2 - "South"
            3 - "East"
            5 - "Quit"
            0 - none of the above.

--- C.all/doc/pwm ------------------------------------------------------
--- Copyright University of Sussex 1987. All rights reserved. ----------
