DataMuseum.dk

Presents historical artifacts from the history of:

Rational R1000/400

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about Rational R1000/400

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download

⟦4f78bc550⟧ TextFile

    Length: 103010 (0x19262)
    Types: TextFile
    Notes: R1k Text-file segment

Derivation

└─⟦8527c1e9b⟧ Bits:30000544 8mm tape, Rational 1000, Arrival backup of disks in PAM's R1000
    └─ ⟦5a81ac88f⟧ »Space Info Vol 1« 
        └─⟦056db2655⟧ 
            └─⟦this⟧ 

TextFile


  @node !Io.Direct_Io

  This package provides the capabilities for Direct_Io as required
  by the Ada Language Reference Manual, Chapter 14.  It provides
  facilities for direct I/O upon files whose components are of the
  same (nonlimited) type.  This type must be a safe type---that is,
  any type that does not contain access types or task types in any of
  its components.  If a create or an open operation is attempted with
  an instantiation on an unsafe type, the Io_Exceptions.Use_Error
  exception will be raised.

  The fundamental abstraction provided by package Direct_Io is the
  File_Type type.  Objects of this type are file handles that can be
  mapped to files.  A file is viewed as a set of elements occupying
  consecutive positions in linear order; a value can be transferred
  to or from an element of the file at any selected position.  The
  position of an element is specified by its index.  The first
  element, if any, has index 1; the index of the last element,
  if any, is called the current size (which is 0 if there are no
  elements).
  @node !Io.Direct_Io.Close

  procedure Close (File : in out File_Type);

  Severs the association between the file handle and its associated
  file.
  @node !Io.Direct_Io.Count

  type Count is new Integer range 0 .. Integer'Last / Element_Type'Size;

  Defines the valid range of direct file index positions.
  @node !Io.Direct_Io.Create

  procedure Create (File : in out File_Type;
                   Mode :        File_Mode := Inout_File;
                   Name :        String    := "";
                   Form :        String    := "");

  Establishes a new file with the given name and associates this file
  with the specified file handle.

  The specified file is left open.
  @node !Io.Direct_Io.Delete

  procedure Delete (File : in out File_Type);

  Deletes the file associated with the specified file handle.

  The specified file is closed, and the file ceases to exist.
  @node !Io.Direct_Io.Element_Type

  type Element_Type is private;

  Defines the type of the items that form the files for each
  particular instantiation.
  @node !Io.Direct_Io.End_Of_File

  function End_Of_File (File : File_Type) return Boolean;

  Returns true if the current index exceeds the size of the file;
  otherwise, the function returns false.

  This function operates on a file of the In_File or Inout_File mode.
  @node !Io.Direct_Io.File_Mode

  type File_Mode is  (In_File, Inout_File, Out_File);

  Specifies the mode of access for which a file is open.

  In_File denotes a file with read-only access, Out_File denotes a
  file with write-only access, and Inout_File denotes a file with
  read/write access.
  @node !Io.Direct_Io.File_Type

  type File_Type is limited private;

  Defines the type of the file handle unique to each instantiation of
  the package.

  Objects of this type are file handles that can be mapped to
  external files.
  @node !Io.Direct_Io.Form

  function Form (File : File_Type) return String;

  Returns the null string ("") in all cases.

  When the Form parameter to the Create and Open procedures is
  supported in the future, the Form value provided to the call to
  the Open or Create procedure will be returned.
  @node !Io.Direct_Io.Index

  function Index (File : File_Type) return Positive_Count;

  Returns the current index of the specified file.

  This function operates on a file of any mode.
  @node !Io.Direct_Io.Is_Open

  function Is_Open (File : File_Type) return Boolean;

  Returns true if the file handle is open (that is, if it is
  associated with a file); otherwise, the function returns false.
  @node !Io.Direct_Io.Mode

  function Mode (File : File_Type) return File_Mode;

  Returns the mode for which the specified file is open.
  @node !Io.Direct_Io.Name

  function Name (File : File_Type) return String;

  Returns the name of the file currently associated with the
  specified file handle.

  For temporary files, this function returns the unique name provided
  by the Rational Environment during the creation of the file.
  @node !Io.Direct_Io.Open

  procedure Open (File : in out File_Type;
                 Mode :        File_Mode;
                 Name :        String;
                 Form :        String    := "");

  Associates the specified file handle with an existing file having
  the specified name.
  @node !Io.Direct_Io.Positive_Count

  subtype Positive_Count is Count range 1 .. Count'Last;

  Defines the valid range of direct file index positions for a
  nonempty file.
  @node !Io.Direct_Io.Read

  procedure Read (File :     File_Type;
                 Item : out Element_Type;
                 From :     Positive_Count);
  procedure Read (File :     File_Type;
                 Item : out Element_Type);

  Reads an item from the specified file and returns the value of this
  element in the Item parameter.

  This procedure operates on a file of the In_File or Inout_File
  mode.  It sets the current index of the specified file to the index
  value specified by the From parameter.  Both forms of the procedure
  then return, in the Item parameter, the value of the element that
  resides at the current index.  The current index is then increased
  by 1.
  @node !Io.Direct_Io.Reset

  procedure Reset (File : in out File_Type;
                  Mode :        File_Mode);
  procedure Reset (File : in out File_Type);

  Resets the specified file so that reading from or writing to its
  elements can be restarted from the beginning of the file.

  The file index is set to 1.  If a Mode parameter is supplied, the
  current mode of the given file is set to the specified mode.
  @node !Io.Direct_Io.Set_Index

  procedure Set_Index (File : File_Type;
                      To   : Positive_Count);

  Sets the current index of the file to the specified index value
  (which may exceed the current size of the file).

  This procedure operates on a file of any mode.
  @node !Io.Direct_Io.Size

  function Size (File : File_Type) return Count;

  Returns the current size of the file associated with the specified
  file handle.

  This function operates on a file of any mode.
  @node !Io.Direct_Io.Write

  procedure Write (File : File_Type;
                  Item : Element_Type;
                  To   : Positive_Count);
  procedure Write (File : File_Type;
                  Item : Element_Type);

  Writes the value of the Item parameter to the specified file.

  This procedure operates on a file of the Inout_File or Out_File
  mode.  It sets the index of the given file to the index value given
  by the To parameter.  Both forms of the procedure then overwrite
  the current index of the file with the value of the Item parameter.
  The current index is then increased by 1.

  If a value for the index is greater than the current size of the
  specified file, the file is automatically extended to include this
  value.
  @node !Io.Io_Exceptions

  The exceptions in package Io_Exceptions can be raised by
  I/O operations.  The general conditions under which these
  exceptions can be raised are described in this section.  Specific
  circumstances under which they can be raised are provided for
  each operation exported by an I/O package.  If more than one
  error condition exists, the corresponding exception that appears
  earliest in the package is the one that is raised.

  Every other I/O package renames one or more of the exceptions
  exported from this package.  Rather than repeat the following
  descriptions in each of these packages, documentation of the
  renaming declarations is omitted in the subsequent sections.

  The Rational Environment provides additional information about
  exceptions raised by the I/O packages that describes why a given
  exception occurred.  This information, typically displayed
  in parentheses after the exception name, is documented in the
  reference entry for each exception.
  @node !Io.Io_Exceptions.Data_Error

  Data_Error : exception;

  Defines an exception raised by the Read procedure if the element
  read cannot be interpreted as a value of the required type.

  This exception is also raised by a Get or Read procedure if an
  input sequence fails to satisfy the required syntax or if the value
  input does not belong to the range of the required type or subtype.

  This exception is also raised by the Read and Write procedures of
  package Polymorphic_Sequential_Io (DIO) if these operations are
  attempted on files containing unsafe types (that is, containing
  access or task types as any of their components).

  The additional information supplied by the Environment when this
  exception is raised has the following meaning:

  o Input_Syntax_Error:  The input value has incorrect syntax.

  o Input_Value_Error:  The input value is out of range.

  o Output_Type_Error:  The output value is an unsafe type.

  o Output_Value_Error:  An attempt has been made to write a value
    out of range.
  @node !Io.Io_Exceptions.Device_Error

  Device_Error : exception;

  Defines an exception raised if an I/O operation cannot be completed
  because of a malfunction of the underlying system.

  The additional information supplied by the Environment when this
  exception is raised has the following meaning:

  o Device_Data_Error:  A hardware error such as a parity error has
    occurred.

  o Illegal_Reference_Error:  An illegal reference has been
    attempted.

  o Illegal_Heap_Access_Error:  An Illegal_Heap_Access exception was
    raised when the operation was attempted.

  o Page_Nonexistent_Error:  A nonexistent page was referenced.

  o Write_To_Read_Only_Page_Error:  A write to a read-only page was
    attempted.
  @node !Io.Io_Exceptions.End_Error

  End_Error : exception;

  Defines an exception raised by an attempt to skip (read past) the
  end of a file.
  @node !Io.Io_Exceptions.Layout_Error

  Layout_Error : exception;

  Defines an exception raised in TIO, packages Text_Io and Io, by
  a call to operations that violate the limits of Count and by
  an attempt to put too many characters to a string; also raised
  in package Window_Io (DIO) by an attempt to position the cursor
  outside the image boundary.

  The additional information supplied by the Environment when this
  exception is raised has the following meaning:

  o Column_Error:  A column exceeds the line or page length.

  o Illegal_Position_Error:  A position parameter is illegal.

  o Item_Length_Error:  An item length is too big or small.
  @node !Io.Io_Exceptions.Mode_Error

  Mode_Error : exception;

  Defines an exception raised by specifying a file whose mode
  conflicts with the desired operation.

  For example, this exception is raised by a call to Set_Input or Get
  when a file of the Out_File mode is provided.

  The additional information supplied by the Environment when this
  exception is raised is:

  o Illegal_Operation_On_Infile

  o Illegal_Operation_On_Outfile
  @node !Io.Io_Exceptions.Name_Error

  Name_Error : exception;

  Defines an exception raised by a call to the Create or Open
  procedure if the string given for the Name parameter does not
  allow the identification of a legal unique file.

  The Name_Error exception is raised by the Create procedure under
  any of the following conditions:

  o The filename does not conform to the syntax of a name.

  o An object of the nonfile class with the same name as the filename
    already exists in the context in which the creation is attempted.

  o The context in which the creation is attempted cannot contain
    files.  Files are allowed only in directories or worlds.

  The additional information supplied by the Environment when this
  exception is raised has the following meaning:

  o Ambiguous_Name_Error:  A name does not identify a unique
    object.

  o Illformed_Name_Error:  A name does not conform to the syntax for
    a legal Environment filename.

  o Nonexistent_Directory_Error:  A library in the name does not
    exist.

  o Nonexistent_Object_Error:  The specified object does not exist.

  o Nonexistent_Version_Error:  The specified version of the object
    does not exist.
  @node !Io.Io_Exceptions.Status_Error

  Status_Error : exception;

  Defines an exception raised by an attempt to operate upon a file
  handle that is not open and by an attempt to open a file handle
  that is already open.

  The additional information supplied by the Environment when this
  exception is raised has the following meaning:

  o Already_Open_Error:  The file handle is already open.

  o Not_Open_Error:  The file handle is not open.
  @node !Io.Io_Exceptions.Use_Error

  Use_Error : exception;

  Defines an exception raised if an operation is attempted that is
  not possible for reasons that depend on the file and the executing
  job's access rights.

  This exception is raised by an attempt to create when there are
  objects of nonfile classes with similar names, by an attempt to
  open or reset with a mode that is not supported for the file,
  and by a call to the Open parameter for a terminal object if the
  terminal is already assigned to a job.

  This exception is raised by the Delete procedure, among other
  circumstances, when the corresponding file is an object that cannot
  be deleted.

  This exception is raised by the Create and Open procedures in
  packages Direct_Io and Sequential_Io (DIO) if they are attempted
  with instantiations on unsafe types (that is, types containing
  access or task types as any of their components).

  The additional information supplied by the Environment when this
  exception is raised has the following meaning:

  o Access_Error:  There are insufficient access rights to perform
    the operation.

  o Capacity_Error:  The output file is full.

  o Check_Out_Error:  The object is not checked out using the
    configuration management and version control system.

  o Class_Error:  There is an existing object of a different class.

  o Frozen_Error:  An attempt is made to change a frozen object.

  o Line_Page_Length_Error:  An improper value for line or page
    length is encountered.

  o Lock_Error:  Another job has locked the object.

  o Reset_Error:  The file cannot be reset or have its mode
    changed.

  o Unsupported_Error:  The operation is not supported.
  @node !Io.Polymorphic_Sequential_Io

  This package provides facilities for sequential I/O upon files
  whose components are of one or more (nonlimited) types.  These
  types must be safe types, which is any type that does not contain
  access types or task types as any of its components.  If a read
  or a write operation is attempted with an instantiation on an
  unsafe type, the Data_Error exception will be raised.  This package
  provides the capabilities similar to those required by the Ada
  Language Reference Manual, Chapter 14, for Sequential_Io, except
  that polymorphism is supported.

  The package provides the nested generic package Operations,
  containing read and write operations, which can be instantiated
  for each of the desired types.

  The fundamental abstraction provided by package Polymor-
  phic_Sequential_Io is the File_Type type.  Objects of this type are
  file handles that can be mapped to files consisting of a sequence
  of values that are transferred in the order of their appearance.
  @node !Io.Polymorphic_Sequential_Io.Append

  procedure Append (File : in out File_Type;
                   Name :        String;
                   Form :        String     := "");

  Opens the specified file for writing at the end of the file.

  This procedure associates the specified file handle with an
  existing file having the specified name.  The file is left open
  and the mode is set to Out_File.
  @node !Io.Polymorphic_Sequential_Io.Close

  procedure Close (File : in out File_Type);

  Severs the association between the specified file handle and its
  associated file.
  @node !Io.Polymorphic_Sequential_Io.Create

  procedure Create (File : in out File_Type;
                   Mode :        File_Mode := Out_File;
                   Name :        String    := "";
                   Form :        String    := "");

  Establishes a new file with the specified name and associates this
  file with the specified file handle.

  The specified file is left open.
  @node !Io.Polymorphic_Sequential_Io.Delete

  procedure Delete (File : in out File_Type);

  Deletes the file associated with the specified file handle.

  The file is closed, and the file ceases to exist.
  @node !Io.Polymorphic_Sequential_Io.End_Of_File

  function End_Of_File (File : File_Type) return Boolean;

  Returns true if no more elements can be read from the specified
  file; otherwise, the function returns false.

  This function operates on a file of the In_File mode.
  @node !Io.Polymorphic_Sequential_Io.File_Mode

  type File_Mode is (In_File, Out_File);

  Specifies the mode of access for which a file is open.

  In_File denotes a file with read-only access; Out_File denotes a
  file with write-only access.
  @node !Io.Polymorphic_Sequential_Io.File_Type

  type File_Type is limited private;

  Defines a file handle type for files to be processed by operations
  in this package.
  @node !Io.Polymorphic_Sequential_Io.Form

  function Form (File : File_Type) return String;

  Returns the null string ("") in all cases.

  When, in the future, the Form parameter to the Create and Open
  procedures is supported, this function will return the Form value
  specified in the call to the Create or Open procedure.
  @node !Io.Polymorphic_Sequential_Io.Is_Open

  function Is_Open (File : File_Type) return Boolean;

  Returns true if the file handle is open (that is, if it is
  associated with a file); otherwise, the function returns false.

  @node !Io.Polymorphic_Sequential_Io.Mode

  function Mode (File : File_Type) return File_Mode;

  Returns the mode for which the specified file handle is open.
  @node !Io.Polymorphic_Sequential_Io.Name

  function Name (File : File_Type) return String;

  Returns the name of the file currently associated with the file
  handle.

  For temporary files, this function returns the unique name provided
  by the Rational Environment during the creation of the file.
  @node !Io.Polymorphic_Sequential_Io.Open

  procedure Open (File : in out File_Type;
                 Mode :        File_Mode;
                 Name :        String;
                 Form :        String     := "");

  Associates the file handle with an existing file having the
  specified name and sets the mode of the file to the specified
  mode.

  The specified file is left open.
  @node !Io.Polymorphic_Sequential_Io.Reset

  procedure Reset (File : in out File_Type;
                  Mode :        File_Mode);
  procedure Reset (File : in out File_Type);

  Resets the specified file so that reading from or writing to its
  elements can be restarted from the beginning of the file.

  If a Mode parameter is supplied, the current mode of the specified
  file is set to the specified mode.
  @node !Io.Polymorphic_Sequential_Io.Operations

  The following package exports operations for reading and writing to
  package Polymorphic_Sequential_Io files.  It can be instantiated
  as many times as required on any safe types to enable objects of
  these types to be read and to be written to files.
  @node !Io.Polymorphic_Sequential_Io.Operations.Element_Type

  type Element_Type is private;

  Denotes the type for which the read and write operations are
  defined.
  @node !Io.Polymorphic_Sequential_Io.Operations.Read

  procedure Read (File :     File_Type;
                 Item : out Element_Type);

  Reads an element from the specified file and returns the value of
  this element in the Item parameter.

  This procedure operates on a file of the In_File mode.
  @node !Io.Polymorphic_Sequential_Io.Operations.Write

  procedure Write (File : File_Type;
                  Item : Element_Type);

  Writes the value of the Item parameter to the specified file.

  This procedure operates on a file of the Out_File mode.
  @node !Io.Sequential_Io

  This package provides the capabilities for Sequential_Io as
  required by the Ada Language Reference Manual, Chapter 14.  It
  provides facilities for sequential I/O upon files whose components
  are of the same (nonlimited) type.  This type must be a safe
  type, which is any type that does not contain access types or
  task types in any of its components.  If a create or an open
  operation is attempted with an instantiation on an unsafe type,
  the Io_Exceptions.Use_Error exception will be raised.

  The fundamental abstraction provided by package Sequential_Io is
  the File_Type type.  Objects of this type are file handles that
  can be mapped to files consisting of a sequence of values that are
  transferred in the order of their appearance.
  @node !Io.Sequential_Io.Close

  procedure Close (File : in out File_Type);

  Severs the association between the specified file handle and its
  associated file.

  The specified file is left closed.
  @node !Io.Sequential_Io.Create

  procedure Create (File : in out File_Type;
                   Mode :        File_Mode := Out_File;
                   Name :        String    := "";
                   Form :        String    := "");

  Establishes a new external file with the specified name and
  associates this file with the specified file handle.

  The specified file is left open.
  @node !Io.Sequential_Io.Delete

  procedure Delete (File : in out File_Type);

  Deletes the file associated with the specified file handle.

  The specified file is closed, and the file ceases to exist.
  @node !Io.Sequential_Io.Element_Type

  type Element_Type is private;

  Defines the type of the items that form the files for each
  particular instantiation.
  @node !Io.Sequential_Io.End_Of_File

  function End_Of_File (File : File_Type) return Boolean;

  Returns true if no more elements can be read from the specified
  file; otherwise, the function returns false.

  This function operates on a file of the In_File mode.
  @node !Io.Sequential_Io.File_Mode

  type File_Mode is  (In_File, Out_File);

  Specifies the mode of access for which a file is open.

  In_File denotes a file with read-only access; Out_File denotes a
  file with write-only access.
  @node !Io.Sequential_Io.File_Type

  type File_Type is limited private;

  Defines the file handle type unique to each instantiation of the
  package.

  Objects of this type denote file handles that can be mapped to
  files.
  @node !Io.Sequential_Io.Form

  function Form (File : File_Type) return String;

  Returns the null string ("") in all cases.

  If, in the future, the Form parameter to the Create and Open
  procedures is supported, this function will return the Form value
  provided in the call to the Create or Open procedure.
  @node !Io.Sequential_Io.Is_Open

  function Is_Open (File : File_Type) return Boolean;

  Returns true if the file handle is open (that is, if it is
  associated with a file); otherwise, the function returns false.
  @node !Io.Sequential_Io.Mode

  function Mode (File : File_Type) return File_Mode;

  Returns the mode for which the specified file handle is open.
  @node !Io.Sequential_Io.Name

  function Name (File : File_Type) return String;

  Returns the name of the file currently associated with the
  specified file handle.

  For temporary files, this function returns the unique name provided
  by the Rational Environment during the creation of the file.
  @node !Io.Sequential_Io.Open

  procedure Open (File : in out File_Type;
                 Mode :        File_Mode;
                 Name :        String;
                 Form :        String    := "");

  Associates the file handle with an existing file having the
  specified name and sets the mode of the file to the specified
  mode.

  The file is left open.
  @node !Io.Sequential_Io.Read

  procedure Read (File :     File_Type;
                 Item : out Element_Type);

  Reads an element from the specified file and returns the value of
  this element in the Item parameter.

  This procedure operates on a file opened with the In_File mode.
  @node !Io.Sequential_Io.Reset

  procedure Reset (File : in out File_Type;
                  Mode :        File_Mode);
  procedure Reset (File : in out File_Type);

  Resets the specified file so that reading from or writing to its
  elements can be restarted from the beginning of the file.

  If a Mode parameter is supplied, the current mode of the specified
  file is set to the specified mode.
  @node !Io.Sequential_Io.Write

  procedure Write (File : File_Type;
                  Item : Element_Type);

  Writes the value of the Item parameter to the specified file.

  This procedure operates on a file of the Out_File mode.
  @node !Io.Window_Io

  This package provides facilities for performing I/O to windows on
  the terminal screen.

  Package Window_Io offers the user direct control over the creation
  and manipulation of images contained in windows on the screen.
  In TIO, packages Text_Io and Io provide simply sequential output
  to the screen, but package Window_Io allows the user to get and
  put characters and strings to any place in the image, similar to
  package Direct_Io.  This offers additional flexibility in creating
  the user interface for tool applications written for the Rational
  Environment.  Whereas Text_Io primarily supports an interrogative
  style of user interface, Window_Io can be used to create a variety
  of menu-driven interfaces, form-based input for data, and displays
  in which the program controls scrolling.

  The fundamental abstraction provided by package Window_Io is
  the File_Type type.  Objects of this type (called file handles
  hereafter) essentially denote quarter-plane images.  A portion of
  this image is made visible through a window on the terminal screen.
  File handles can be opened twice---once for input and once for
  output.  All puts to an image must go through a file handle opened
  with the Out_File mode.  All gets from an image must go through a
  file handle opened with the In_File mode.

  Images are segmented into a matrix of lines and columns.  Lines
  are numbered from 1 starting from the top of the image; columns
  are numbered from 1 starting from the left side of the image.  Each
  character resides at a particular line and column number.  Lines
  also have length; the length is the column number of the last
  character on the line, including blank characters.  Finally, all
  images have associated with them the notion of the last line in
  that image.

  Window_Io introduces the notion of a cursor.  All images have
  associated with them a current cursor position.  A program can
  request information about the location of the cursor in an image,
  and it can also reposition the cursor as required.  Input to, and
  output from, an image is always performed relative to this current

  cursor position.  Input and output operations can also implicitly
  reposition the cursor during their execution.

  Package Window_Io provides access to the terminal's ability to
  display characters in a variety of fonts and character sets.  A
  program can write read-only text to the screen that users are
  unable to modify and can write characters designated as a prompt
  that will disappear when users type on the characters.

  An application can also take control of the keystroke stream
  coming from the terminal keyboard.  This control of the keystroke
  stream allows the program to interpret individual keystrokes and
  to redefine their resulting effect.  Facilities are provided to
  define mnemonic names for certain keys for more readable use
  within the program.    Finally, when a program is executing as
  the current job, applications can take advantage of the Rational
  Editor commands.  For example, an application could use the
  Commands.Editor.Window.Beginning_Of command (EI) to reposition
  the window on an image.

  Two Case Studies

  Package Window_Io offers a powerful set of facilities for creating
  user interfaces to display information to the user and for
  requesting information from the user.  As in the Rational Editor,
  information can be displayed in a structured manner and then edited
  by the user.  The edited information can be checked to verify that
  all user modifications are acceptable and that actions are taken
  based upon the change.  This method offers a much greater degree
  of flexibility than the sequential interrogative style interfaces
  available through package Text_Io (TIO).

  The objective of this section is to provide a more concrete
  understanding of the facilities provided by package Window_Io
  and the application domain to which they apply.  The approach will
  be to discuss in some detail the development of two user interface
  abstractions, the form and the menu.

  Some basic concepts necessary for all window-based applications
  using package Window_Io will be discussed first.  How to set up
  some useful definitions for display fonts and for names of keyboard
  keys will be investigated.  Then some useful utilities for moving
  the cursor and manipulating images will be defined.

  The first abstraction case study focuses on the essential
  requirements and implementation strategies for a form as a method
  of information entry for users.  Finally, a variety of menu
  abstractions for operation selection will be discussed, and one
  of them will be developed in detail.

  Basic Concepts

  Images and Windows

  All objects in the Environment have an image, part or all of which
  appears in a window on the terminal screen.  Package Window_Io
  provides facilities for creating and manipulating images in
  windows.  There are two useful ways of thinking about this.  In
  one sense, package Window_Io allows applications to create windows
  in which text images can be formed.  In a more formal sense,
  Window_Io is another way of creating a text object that has an
  image displayed in a window.  There is one important difference,
  however.  Text objects created by package Window_Io have no
  corresponding file in the directory structure.

  As with other I/O packages, these objects can be opened for input
  or output, closed and later reopened, and deleted.  Consult the
  reference entries later in this section for the effects of the
  following procedures:

  o procedure Create

  o procedure Open

  o procedure Close

  o procedure Delete

  Input to and Output from Images

  All images have the notion of a current position for the cursor
  in that image.  All input and output procedures work relative to
  the current cursor position.  Normally, applications will first
  move the cursor to the appropriate position in an image (unless
  it is already there) and then call the desired input or output
  procedure.

  Several forms of input are provided for both Character and String
  types.  Basically, an application can either extract a character
  or string from an image or request that the user provide some input
  from the keyboard.

  Several forms of output are also provided for both Character and
  String types.  An application can either insert text into an image
  or replace existing text with an Overwrite procedure.

  Consult the reference entries in this section for the effects of
  the following procedures:

  o procedure Position_Cursor

  o procedure Get

  o procedure Get_Line

  o procedure Insert

  o procedure Overwrite

  o procedure New_Line

  Operations are also available for deleting text from images,
  including:

  o procedure Delete

  o procedure Delete_Lines

  Other operations provide information about the image in a window,
  including:

  o procedure Report_Cursor

  o function Line_Length

  o function Last_Line

  Definitions and Utilities

  Fonts

  All characters are written to the terminal screen in what is called
  a font.  Fonts describe exactly how a character will be displayed
  on the screen.  Fonts have two major components:  an indication of
  the character set and an array of display attributes.  The Rational
  Terminal supports two character sets:  a normal alphanumeric set
  and a graphics set.  Package Window_Io defines two named constants
  (Plain and Graphics) for use in defining fonts indicating use of
  each character set.  Some font declarations that applications might
  find useful are:
  with Window_Io;
  package Fonts is
      Normal       : constant
                  Window_Io.Font := Window_Io.Font'(Window_Io.Plain,
                                                   (others => False));
      Graphics     : constant
                  Window_Io.Font := Window_Io.Font'(Window_Io.Graphics,
                                                   (others => False));
      Inverse_Bold : constant
                  Window_Io.Font := Window_Io.Font'(Window_Io.Plain,
                                                   (Inverse => True,
                                                    Bold => True,
                                                    others => False));
      Underscore   : constant
                  Window_Io.Font := Window_Io.Font'(Window_Io.Plain,
                                                   (Underscore => True,
                                                    others => False));
  end Fonts;

  Notes:

  o The Window_Io procedures that display either characters or
    strings (Insert and Overwrite) include a parameter for indicating
    the desired font for display.

  o These same output procedures also have a parameter for the kind
    of designation with which characters are to be written.  Three
    kinds of designations are supported:

    . Text:  Output is displayed as plain text, which can then be
      modified by a user with the Rational Editor.

    . Prompt:  Output is displayed as a prompt that will disappear 
      when the user types on it.  The user can turn a prompt into 
      text with:

        Commands.Editor.Set.Designation_Off

    . Protected:  Once displayed on the screen, the output is read-
      only and cannot be modified by the user.  If a user does attempt
      to modify protected text with the Rational Editor, the bell
      will sound and a message will appear in the Message window
      indicating that this part of the image is read only.

  o Use of the graphics character set for drawing boxes is discussed
    in "Graphics Utilities," below.

  Keys

  For applications requiring complete control over keyboard input
  from the user, package Window_Io offers mechanisms to catch
  keystrokes, to determine which key was pressed, and to decide
  on some action as a result.

  When the user presses a key on the keyboard, that key is
  interpreted and placed into the character stream.  Normally,
  keystrokes are passed directly to the Rational Editor, which
  decides what effect the keystrokes will have.  The user has the
  ability, with package Raw nested within package Window_Io, to
  interrupt the flow of keystrokes to the editor, to get keys one at
  a time from the stream, and to initiate an application-specific
  effect based on the value of the key.  Use of this technique is
  fully described in "Menus," below.  The Key type in package Raw
  is defined as:

       type Key is new Natural range 0 .. 1023;

  It is useful to define mnemonic names for keys to enhance the
  readability of code that requires references to particular keys.
  Package Key_Names, discussed in the example below, exports some
  named key objects.  In the body of the package, these objects are
  initialized to an Environment-defined value for a keyboard key
  during elaboration.

  with Window_Io;
  package Key_Names is
      package Raw renames Window_Io.Raw;
      subtype Key_Type is Raw.Key;
      Up            : Key_Type;
      Down           : Key_Type;
      Left           : Key_Type;
      Right          : Key_Type;
      Window         : Key_Type;
      Window_Up      : Key_Type;
      Window_Down    : Key_Type;
      Definition     : Key_Type;
      Enter          : Key_Type;
      User_Interrupt : Key_Type;
      Next_Item      : Key_Type;
      Previous_Item  : Key_Type;
      function Is_Alphabet_Key (K : Key_Type) return Boolean;
  end Key_Names;
  with System_Utilities;
  package body Key_Names is
      Is_Found : Boolean;
      Terminal : constant
                String := System_Utilities.Terminal_Type;
  begin
      Raw.Value (For_Key_Name => "UP", On_Terminal => Terminal,
                Result => Up, Found => Is_Found);
      Raw.Value (For_Key_Name => "DOWN", On_Terminal => Terminal,
                Result => Down, Found => Is_Found);
      Raw.Value (For_Key_Name => "LEFT", On_Terminal => Terminal,
                Result => Left, Found => Is_Found);
      Raw.Value (For_Key_Name => "RIGHT", On_Terminal => Terminal,
                Result => Right, Found => Is_Found);
      ...
      if Terminal = "VT100" then
          Raw.Value (For_Key_Name => "Numeric_8",
                    On_Terminal => Terminal,
                    Result => Definition, Found => Is_Found);
      elsif Terminal = "Rational"
          Raw.Value (For_Key_Name => "F10", On_Terminal => Terminal,
                    Result => Definition, Found => Is_Found);
      end if;
      ...
  end Key_Names;

  Notes:

  o The names of keys for each supported terminal type are located
    in !Machine.Edi-tor_Data.Visible_Key_Names.  This information
    is captured as an enumeration type for each terminal.  The string
    representation of these enumeration values should be passed into
    the Raw.Value procedure as in the example above.

  o The System_Utilities.Terminal_Type function (SMU) returns a
    string value indicating the type of terminal the user specified
    at login.  Since different terminals may have different mappings
    from names in Visible_Key_Names to actual key values, this
    function can be used to ensure that key input from a different
    terminal is interpreted in the same way.

  o Since all keyboards do not provide an identical set of keys, each
    supported terminal will have a different set of enumerated values
    in Visible_Key_Names.  In this case, the terminal type will need
    to be tested before the Raw.Value function is called.  Note that,
    in the body of the package Key_Names example above, the name
    for Definition is F10 for the Rational Terminal and Numeric_8
    for the VT100.  This mapping is captured in the Vt100_Commands
    and Rational_Commands procedures in the !Machine.Editor_Data
    directory.

  Package Raw also exports:
       subtype Simple_Key is Key range 0 .. 127;

  Simple keys correspond to ASCII characters so that we can use the 
  ASCII names for references instead of defining our own.  The following
  example demonstrates references to simple keys:

      A_Key : Raw.Key;
      ...
  begin
      ...
      if A_Key in Raw.Simple_Key then
          case Raw.Convert (A_Key) is
             when `A' =>
                 ...  -- perform some operation indicated by `A'
             when `?' =>
                 ...  -- perform some other operation
             ...
          end case;
      end if;

  Window Utilities

  It is also useful to define and implement utilities for moving the
  cursor around images and manipulating images in various ways.  The
  following example defines an initial set of utilities (there is
  certainly an opportunity for several more):

  with Window_Io;
  package Window_Utilities is
      procedure Beginning_Of_Line (Window : Window_Io.File_Type);
      procedure End_Of_Line (Window : Window_Io.File_Type);
      procedure Next_Line (Window : Window_Io.File_Type);
      -- retain the current column position
      procedure Home (Window : Window_Io.File_Type);
      procedure Erase (Window : Window_Io.File_Type);
      procedure Continue (Input_Window : Window_Io.File_Type;
                         Output_Window : Window_Io.File_Type;
                         Prompt : String;
                         Line   : Window_Io.Line_Number;
                         Column : Window_Io.Column_Number);
      function Query (Input_Window : Window_Io.File_Type;
                     Output_Window : Window_Io.File_Type;
                     Prompt : String;
                     Line   : Window_Io.Line_Number;
                     Column : Window_Io.Column_Number) return String;
      type Iterator is private;  -- for all lines in an image
      function Initialize (Window : Window_Io.File_Type) return Iterator;
      function Done (Iter : Iterator) return Boolean;
      function Value (Iter : Iterator) return String;
      procedure Next (Iter : in out Iterator);
  private
      type Iterator is ...
  end Window_Utilities;

  Some selected bodies for these utilities are:

  with Window_Io;
  with Fonts;
  package body Window_Utilities is
      procedure Next_Line (Window : Window_Io.File_Type) is
          Current_Line   : Window_Io.Line_Number;
          Current_Column : Window_Io.Column_Number;
      begin
          Window_Io.Report_Cursor (Window, Current_Line, Current_Column);
          if Window_Io.Last_Line (Window) /= Current_Line then
             Window_Io.Position_Cursor
                  (Window, Current_Line + 1, Current_Column);
          end if;
      end Next_Line;
      procedure Erase (Window : Window_Io.File_Type) is
      begin
          Window_Io.Position_Cursor (Window);
          Window_Io.Delete_Lines (Window, Window_Io.Last_Line (Window));
      end Erase;
      procedure Continue (Input_Window : Window_Io.File_Type;
                         Output_Window : Window_Io.File_Type;
                         Prompt : String;
                         Line   : Window_Io.Line_Number;
                         Column : Window_Io.Column_Number)
             is separate;
      function Query (Input_Window : Window_Io.File_Type;
                     Output_Window : Window_Io.File_Type;
                     Prompt : String;
                     Line   : Window_Io.Line_Number;
                     Column : Window_Io.Column_Number) return String is
      begin
          Window_Io.Position_Cursor (Output_Window, Line, Column);
          -- write out the prompt
          Window_Io.Overwrite (Output_Window, Prompt,
                           Fonts.Inverse_Bold, Window_Io.Prompt);
          -- reposition the cursor on top of the prompt
          Window_Io.Position_Cursor (Input_Window, Line, Column);
          --  return the user's input
          return Window_Io.Get_Line (Input_Window, "");
      end Query;
  end Window_Utilities;

  The Query procedure may require more explanation.  When the cursor
  is positioned on text written with a prompt designation, the
  Get_Line procedure waits for the user to input a response.  When
  the user commits the response, the entered characters are returned
  to the program.  To ensure that a prompt is available for the
  Get_Line procedure, the Query procedure first writes out the prompt
  and then repositions the cursor on top of it before calling the
  Get_Line procedure.

  The Continue procedure is similar to the Query procedure in
  that it waits for the user to commit a response.  It does not
  return the response but merely indicates that the user wants to
  continue.  In this case, part of the prompt is written with a
  protected designation to prevent it from disappearing if the user
  accidentally types on top of it.

  separate (Window_Utilities)
  procedure Continue (Input_Window : Window_Io.File_Type;
                     Output_Window : Window_Io.File_Type;
                     Prompt : String;
                     Line   : Window_Io.Line_Number;
                     Column : Window_Io.Column_Number) is
      Char : Character;
  begin
      Window_Io.Position_Cursor (Output_Window, Line, Column);
      --insert the prompt to hang on
      Window_Io.Insert (Output_Window, " ",
                       Fonts.Inverse_Bold, Window_Io.Prompt);
      Window_Io.Insert (Output_Window, Prompt,
                       Fonts.Inverse_Bold, Window_Io.Protected);
      Window_Io.Position_Cursor (Input_Window, Line, Column);
      Window_Io.Get (Input_Window, "", Char);
      Window_Io.Position_Cursor (Output_Window, Line, Column);
      Window_Io.Delete_Lines (Output_Window, 2);
  end Continue;

  Graphics Utilities

  The Rational Terminal supports a graphics character set that is
  useful for drawing straight-line structures.  A full description of
  the graphics character set appears in the Rational Terminal User's
  Manual.  The following example demonstrates how to draw a box in an
  image:
  with Window_Io;
  with Fonts;
  procedure Draw_Box (Window : Window_Io.File_Type;
                     On_Line : Window_Io.Line_Number;
                     On_Column : Window_Io.Column_Number;
                     Height : Natural;
                     Width  : Natural) is
          Upper_Left_Corner  : constant Character := 'l';
          Upper_Right_Corner : constant Character := 'k';
          Lower_Left_Corner  : constant Character := 'm';
          Lower_Right_Corner : constant Character := 'j';
          Vertical_Line      : constant Character := 'x';
          Horizontal_Line    : constant Character := 'q';
      begin
          Window_Io.Position_Cursor (Window, On_Line, On_Column);
          Window_Io.Overwrite (Window, Upper_Left_Corner, Fonts.Graphics);
          for I in 1 .. Width loop
             Window_Io.Overwrite
                       (Window, Horizontal_Line, Fonts.Graphics);
          end loop;
          Window_Io.Overwrite (Window, Upper_Right_Corner, Fonts.Graphics);
          Window_Io.Position_Cursor (Window, On_Line + 1, On_Column);
          for I in 1 .. Height loop
             Window_Io.Overwrite (Window, Vertical_Line, Graphics);
             Window_Io.Move_Cursor (Window, 1, - 1);
          end loop;
          Window_Io.Position_Cursor
                   (Window, On_Line + 1, On_Column + Width + 1);
          for I in 1 .. Height loop
             Window_Io.Overwrite (Window, Vertical_Line, Graphics_Set);
             Window_Io.Move_Cursor (Window, 1, - 1);
          end loop;
          Window_Io.Position_Cursor
                   (Window, On_Line + Height + 1, On_Column);
          Window_Io.Overwrite (Window, Lower_Left_Corner, Graphics_Set);
          for I in 1 .. Width loop
             Window_Io.Overwrite (Window, Horizontal_Line, Graphics_Set);
          end loop;
          Window_Io.Overwrite (Window, Lower_Right_Corner, Graphics_Set);
      end Draw_Box;

  The Form Abstraction

  A form provides a method of getting structured information from
  a user in a somewhat unstructured way.  A form with various
  entries defined by the application can be displayed in a window.
  Control should then be returned to the Rational Editor to allow
  completion of the form by the user.  With the full power of the
  editor available to the user, information can be entered in any
  order using any of the editor features.  When the user indicates
  that the form is complete, the image should be parsed and responses
  returned to the application for interpretation.

  Other considerations might include the ability to indicate errors
  in user responses, to redisplay the form for correction with the
  editor, and then to resubmit the response.

  In particular, it might be desirable for the display to look something 
  like this:

  NAME :  [Input]
  ADDRESS :  [Input]
  TELEPHONE NUMBER :  [(Area Code) Number]
  AGE :  [Positive Number]

  One possible specification for this abstraction might be the following:

  with Fonts;
  with Window_Io;
  with Unbounded_String;
  generic
      type Form_Item is (<>);  --Defines entries of the form
      with function Image (Item : Form_Item) return String;
      -- provides a string representing the name of the entry
  package Forms is
      type Form_Entry is private;
      -- defines a prompt and display attributes for an entry
      type Form_Definition is array (Form_Item) of Form_Entry;
      procedure Initialize (Definition : in out Form_Definition);
      -- initialize all entries with default values
      procedure Modify (The_Entry : in out Form_Entry;
                       New_Prompt : String;
                       Font : Window_Io.Font := Fonts.Inverse_Bold;
                       Kind : Window_Io.Designation := Window_Io.Prompt);
      -- allows modification of an entry's prompt
      procedure Display (Output_Window : Window_Io.File_Type;
                        Form : Form_Definition);
      procedure Get_User_Response
                    (Form_Output : Window_Io.File_Type;
                     Form_Input : Window_Io.File_Type;
                     Definition : in out Form_Definition);
      function Response (An_Entry : Form_Entry) return String;
      -- multiple line input is separated by Ascii.Lf characters
      Unable_To_Parse_Response : exception;
  private
      Item_Size : constant := 80;
      package Unbounded is new Unbounded_String (Item_Size);
      type Form_Entry is
          record
             Prompt      : Unbounded.Variable_String;
             Prompt_Font : Window_Io.Font;
             Prompt_Kind : Window_Io.Designation;
          end record;
  end Forms;

  Design Issues
  o This particular choice of specification is generic on a discrete
    type and is intended to be instantiated with an enumeration type.
    The image function is used by the Display procedure to write out
    entry names.  If this spec were instantiated with the following
    type:
  type Form_Entries is (Name, Address, Telephone_Number, Age);

    the image of the form presented above could be accomplished.

  o The Modify procedure is intended to allow an application to
    redefine its own prompt strings or to modify the prompt display
    attributes to indicate errors.

  o Note that the Get_User_Response procedure contains an in out
    Form_Definition parameter.  This allows the image to be parsed
    and the responses to be returned in the Form_Definition itself.

  o It is expected that an application using this abstraction
    would generally call the Display procedure before calling
    Get_User_Response.  The display operation might have been used
    internally in Get_User_Response and might not have been exported.
    If, however, an application desires to display a form with errors
    and asks the user whether or not to continue editing, the display
    must be separate; it has been made so for this reason.

  o The Response function can be used to return the user's response
    for a particular entry.

  Implementation Issues

  See the body of package Forms in the following example for
  reference.

  o The most interesting issue is how to return control to the
    Rational Editor to allow the user to complete the form.  This
    is accomplished by positioning the cursor at the end of the image
    and calling the Window_Io.Get procedure with the null string
    for the prompt.  Since the cursor is at the end of the file,
    the program will wait until the user commits the response.  The
    value returned from the Get procedure is not important and is
    not looked at.  The Get procedure is used only to signal that the
    user has completed editing and that the form can now be parsed.

  o If the prompt string passed to the Modify procedure is the
    null string, the prompt string is unchanged, but the fonts and
    designation are changed.  This is useful for retaining the user's
    response and modifying the display attributes to indicate an
    error.

  with Window_Utilities;
  with String_Utilities;
  package body Forms is
      procedure Modify (The_Entry : in out Form_Entry;
                       New_Prompt : String;
                       Font : Window_Io.Font := Fonts.Inverse_Bold;
                       Kind : Window_Io.Designation := Window_Io.Prompt) is
      begin
          if New_Prompt /= "" then
             Unbounded.Copy (The_Entry.Prompt, New_Prompt);
          end if;
          The_Entry.Prompt_Font := Font;
          The_Entry.Prompt_Kind := Kind;
      end Modify;

      procedure Display (Output_Window : Window_Io.File_Type;
                        Form : Form_Definition) is
          A_Char             : Character;
          First_Prompt_Line   : Window_Io.Line_Number;
          First_Prompt_Column : Window_Io.Column_Number;
          First_Prompt_Found  : Boolean := False;
      begin
          Window_Utilities.Erase (Output_Window);
          Window_Io.Position_Cursor (Output_Window);
          for Item in Form_Item loop
             Window_Io.Insert
                  (Output_Window, Image (Item) & " : ",
                   Kind => Window_Io.Protected);
             for I in 1 .. Unbounded.Length (Form (Item).Prompt) loop
                 A_Char := Unbounded.Char_At (Form (Item).Prompt, I);
                 if A_Char = Ascii.Lf then
                     Window_Io.New_Line (Output_Window, 1);
                 else
                     Window_Io.Insert
                          (Output_Window, A_Char,
                           Image => Form (Item).Prompt_Font,
                           Kind => Form (Item).Prompt_Kind);
                 end if;
             end loop;
             Window_Io.New_Line (Output_Window, 1);
          end loop;
      end Display;

      procedure Parse (Input_Window : Window_Io.File_Type;
                      Form : in out Form_Definition) is separate;
      -- implementation of a body for parse is left to the user
      procedure Get_User_Response (Form_Output : Window_Io.File_Type;
                                  Form_Input : Window_Io.File_Type;
                                  Definition : in out Form_Definition) is
          Out_Char : Character;
      begin
          Window_Io.Get (Form_Input, "", Out_Char);
          Parse (Form_Input, Definition);
      end Get_User_Response;
  end Forms;

  The Menu Abstraction

  The menu abstraction offers a rich set of user interface options
  for applications.  Generally, it presents a set of selections to
  the user that, when activated, produces some effect.  Other kinds
  of menus are collections of objects whose images are displayed by
  the menu.  Objects can be selected and operations applied to them.
  This may or may not change their image in the menu.

  The menu in the example below can be used by an application to
  offer a set of choices to a user.  Selection of a choice implies
  that some operation will be performed.  The user should be able
  to move from choice to choice with the arrow keys and to indicate
  selection with the [Enter] key.  Selections might also be made by
  pressing the first letter of the menu choice's name.

  An application will require a way to build menu definitions,
  display them, and cause an operation to be performed when a
  particular menu choice is selected.  Another issue is the layout
  of the menu on the screen.  The two options that this example will
  offer are a vertical layout and a horizontal layout.

  The following example is a generic specification for the simple
  menu described above:

  with Window_Io;
  with New_Keys;
  generic
      type Element is private;
      with function Line_Image (E : Element) return String;
      with procedure Apply_Operation (To_Element : Element;
                                    Window : Window_Io.File_Type;
                                    Column_Offset : Natural := 0;
                                    Line_Offset : Natural := 0);
      with function Is_Quit_Key return Boolean;
      with function Is_Selection_Key return Boolean;
  package Single_Selection_Electric_Menus is
      subtype Window_Type is Window_Io.File_Type;
      type Menu_Definition is private;
      function Make return Menu_Definition;
      procedure Add (E : Element; To : in out Menu_Definition);
      type Layout is (Vertical, Horizontal);
      procedure Get_User_Selection
                    (Menu : Window_Type; Definition : Menu_Definition;
                     Column_Offset : Natural := 0;
                     Line_Offset : Natural := 0;
                     Presentation : Layout := Vertical);

  private
      type Node;
      type Menu_Definition is access Node;
      type Node is
          record
             Elem       : Element;
             First_Char : Character;
             Line       : Window_Io.Line_Number;
             Column     : Window_Io.Column_Number;
             Next       : Menu_Definition;
             Previous   : Menu_Definition;
          end record;
  end Single_Selection_Electric_Menus;

  Design Issues

  The following discussion refers to the example in the previous
  section, "The Menu Abstraction."

  o This example is generic on the Element type for the menu
    selection.  The Element type must have a line image and an
    Apply_Operation procedure that will initiate some operation
    based on the value of the element.  Note that this procedure has
    some additional parameters to indicate the current window and
    some offsets within that window.  These parameters are essential
    if the operation one wants to perform is the display of another
    nested menu.

  o Generic formals are functions identifying which keys indicate
    that the user would like to quit the menu and which keys indicate
    the selection of a particular operation.  The arrow keys for
    traversal over the elements of the menu have been hard-wired into
    the body but could have been made generic as well.  The layout
    form (either horizontal or vertical) might also affect which
    arrow keys are operative.  A horizontal layout might use the left
    and right arrows; a vertical layout might use the up and down
    arrow keys.

  o The package exports a Make operation that builds an empty menu
    definition.  The user can then add elements to build up the final
    definition.

  o No Display procedure is exported.  There seems to be no reason
    to separate the display from requesting a response from the
    user.  Since the user could manipulate the display image, in some
    situations, before being asked for a response, it seems unwise to
    offer the opportunity for no reason.  If a compelling reason were
    identified, the Display procedure from the body could be exported
    easily.

  o Another option for the Get_User_Selection operation is to make it
    a function that returns the element selected.  The client program
    will then determine the operation to be performed.  The penalty
    is that the client program will have to decide when to quit.
    In this case it would also be necessary to export the display
    operation to avoid having to redisplay the menu each time a user
    selection is requested.

  Implementation Issues

  Global issues will be discussed in this section.  Issues pertinent
  to individual subprograms will be addressed with the corresponding
  code.

  o A doubly linked list has been chosen to implement menu
    definitions.  Note that each node of the list also stores
    information about the position of the element in the display
    and about the first character of the element's image for electric
    completion.

  o Several helper functions have been defined in the body:

    . Find_Def:  Returns the next node of the menu definition whose
      element begins with the character First.  If an element is not
      found, the Definition_Not_Found exception is raised.

    . Initialize_Placement:  Determines the layout of all elements in
      the menu.

    . Display:  Writes the images for each element of the menu at the
      appropriate position.

    . Erase:  Erases the menu image from the image.  Note that, when
      nested menus are displayed in the same window, only the current
      menu should be erased.
  package body Single_Selection_Electric_Menus is
      Definition_Not_Found : exception;
      function Make return Menu_Definition is
      begin
          return null;
      end Make;
      procedure Add (E : Element; To : in out Menu_Definition) is
          Temp      : Menu_Definition;
          Line : constant String := Line_Image (E);
      begin
          if To = null then
             To          := new Node'(E, Line (Line'First),
                                     1, 1, null, null);
             To.Next     := To;
             To.Previous := To;
          else
             Temp           := To.Previous;
             Temp.Next      := new Node'(E, Line (Line'First),
                                        1, 1, null, Temp);
             Temp.Next.Next := To;
             To.Previous    := Temp.Next;
          end if;
      end Add;
      -- helper functions for Get_User_Response
      function Find_Def
             (First : Character; Def : Menu_Definition)
                      return Menu_Definition is separate;

      procedure Initialize_Placement
               (Def : in Menu_Definition;
                Column_Offset : Natural; Line_Offset : Natural;
                Presentation : Layout) is separate;
      procedure Display
               (Menu : Window_Type; Definition : Menu_Definition;
                Column_Offset : Natural; Line_Offset : Natural;
                Presentation : Layout) is separate;
      procedure Erase
               (Menu : Window_Type; Definition : Menu_Definition;
                Column_Offset : Natural := 0) is separate;
      procedure Get_User_Selection
               (Menu : Window_Type; Definition : Menu_Definition;
                Column_Offset : Natural := 0;
                Line_Offset : Natural := 0;
                Presentation : Layout := Vertical) is separate;
  end Single_Selection_Electric_Menus;
  separate (Single_Selection_Electric_Menus)
  function Find_Def (First : Character;
                    Def : Menu_Definition) return Menu_Definition is
     Temp : Menu_Definition := Def;
  begin
      if Temp = null then
          raise Definition_Not_Found;
      elsif Temp.First_Char = First then
          return Temp;
      else
          Temp := Temp.Next;
          while Temp /= Def loop
             if Temp.First_Char = First then
                 return Temp;
             else
                 Temp := Temp.Next;
             end if;
          end loop;
      end if;
      raise Definition_Not_Found;
  end Find_Def;
  separate (Single_Selection_Electric_Menus)
  procedure Initialize_Placement
                (Def : in Menu_Definition;
                 Column_Offset : Natural; Line_Offset : Natural;
                 Presentation : Layout) is
      Temp        : Menu_Definition := Def;
      Next_Line   : Positive := Line_Offset + 1;
      Next_Column : Positive := Column_Offset + 1;
  begin
      Temp.Line   := Next_Line;
      Temp.Column := Next_Column;

      case Presentation is
          when Vertical =>
             Next_Line := Next_Line + 1;
          when Horizontal =>
             Next_Column := Next_Column +
                 Line_Image (Temp.Elem)'Length + 4;
             if Next_Column > 80 then
                 Next_Column := Column_Offset + 1;
                 Next_Line := Next_Line + 1;
             end if;
      end case;
      Temp := Temp.Next;
      while Temp /= Def loop
          Temp.Line   := Next_Line;
          Temp.Column := Next_Column;
          case Presentation is
             when Vertical =>
                 Next_Line := Next_Line + 1;
             when Horizontal =>
                 Next_Column := Next_Column +
                     Line_Image (Temp.Elem)'Length + 4;
                 if Next_Column > 80 then
                     Next_Column := Column_Offset + 1;
                     Next_Line := Next_Line + 1;
                 end if;
          end case;
          Temp := Temp.Next;
      end loop;
  end Initialize_Placement;
  with Fonts;
  separate (Single_Selection_Electric_Menus)
  procedure Display
            (Menu : Window_Type; Definition : Menu_Definition;
             Column_Offset : Natural; Line_Offset : Natural;
             Presentation : Layout) is
      Temp_Def : Menu_Definition := Definition;
  begin
      Window_Io.Position_Cursor
           (Menu, Temp_Def.Line, Temp_Def.Column);
      Window_Io.Overwrite (Menu, Line_Image (Temp_Def.Elem),
                          Fonts.Inverse_Bold);
      Temp_Def := Temp_Def.Next;
      while Temp_Def /= Definition loop
          Window_Io.Position_Cursor
              (Menu, Temp_Def.Line, Temp_Def.Column);
          Window_Io.Overwrite (Menu, Line_Image (Temp_Def.Elem),
                              Fonts.Normal);
          Temp_Def := Temp_Def.Next;
      end loop;

      -- repositions the cursor on the first element
      Window_Io.Position_Cursor
           (Menu, Temp_Def.Line, Temp_Def.Column);
  end Display;

  Most of the interesting issues are associated with the next
  example, an implementation of the Get_User_Selection procedure.
  In this procedure, the menu is first displayed in the window.  The
  raw keystroke stream is then opened and One_Key is taken from the
  stream.  The value of this key is then interpreted.  If the key is
  a traversal key (an arrow key), the currently highlighted element
  is unhighlighted and the new node is highlighted.  If the key is
  a letter of the alphabet, an attempt is made to find an element
  that begins with that character; the Apply_Operation procedure is
  called if an element is found.  The Apply_Operation procedure is
  also called when the key indication user selection is pressed.  If
  the quit key is pressed, the menu raw stream is closed, the menu
  is erased, and the Get_User_Selection procedure is exited.  If any
  other key is pressed, the terminal bell is sounded.

  Note that the raw stream is closed before each call to
  Apply_Operation.  It is then reopened after the call returns.  This
  example establishes this convention for good reason.  Package Raw
  does not export an operation to indicate whether or not the stream
  is open.  Thus, a program cannot tell whether it has to perform
  an Open procedure.  If a program tries to open a stream that is
  already open, the Io_Exceptions.Status_Error exception is raised.
  The convention of a closed character stream across procedure calls
  was established for this implementation.
  separate (Single_Selection_Electric_Menus)
  procedure Get_User_Selection
            (Menu : Window_Type; Definition : Menu_Definition;
             Column_Offset : Natural := 0;
             Line_Offset : Natural := 0;
             Presentation : Layout := Vertical) is
      Current_Node  : Menu_Definition := Definition;
      Selected_Font : Window_Io.Font := Fonts.Inverse_Bold;
      package Raw renames Window_Io.Raw;
      Character_Stream : Raw.Stream_Type;
      One_Key          : Raw.Key;
      function "=" (A, B : Raw.Key) return Boolean renames Raw."=";
  begin
      Initialize_Placement (Definition, Column_Offset, Line_Offset,
                           Presentation);
      Display (Menu, Definition, Column_Offset, Line_Offset,
                           Presentation);
      Raw.Open (Character_Stream);
      loop
          Window_Io.Position_Cursor
              (Menu, Current_Node.Line, Current_Node.Column);
          Raw.Get (Character_Stream, One_Key);
          -- interpretation of the keystroke from the user:
          if (Presentation = Vertical and One_Key = New_Keys.Up) or
             (Presentation = Horizontal and One_Key = New_Keys.Left)
            then
             Window_Io.Position_Cursor
                  (Menu, Current_Node.Line, Current_Node.Column);
             Window_Io.Overwrite       -- turn off selection
                  (Menu, Line_Image (Current_Node.Elem), Fonts.Normal);
             Current_Node := Current_Node.Previous;
             Window_Io.Position_Cursor
                  (Menu, Current_Node.Line, Current_Node.Column);
             Window_Io.Overwrite      -- turn on selection
                  (Menu, Line_Image (Current_Node.Elem), Selected_Font);
          elsif (Presentation = Vertical and One_Key = New_Keys.Down) or
               (Presentation = Horizontal and One_Key = New_Keys.Right)
             then
             Window_Io.Position_Cursor
                  (Menu, Current_Node.Line, Current_Node.Column);
             Window_Io.Overwrite       -- turn off selection
                  (Menu, Line_Image (Current_Node.Elem), Fonts.Normal);
             Current_Node := Current_Node.Next;
             Window_Io.Position_Cursor
                  (Menu, Current_Node.Line, Current_Node.Column);
             Window_Io.Overwrite       -- turn on selection
                  (Menu, Line_Image (Current_Node.Elem), Selected_Font);
          -- electric selection on first character:
          elsif New_Keys.Is_Alphabet_Key (One_Key) then
             declare
                 Char     : Character :=
                     String_Utilities.Upper_Case
                      (Window_Io.Raw.Convert (One_Key));
                 New_Node : Menu_Definition;
             begin
                 New_Node := Find_Def (Char, Current_Node.Next);
                 Window_Io.Position_Cursor
                      (Menu, Current_Node.Line, Current_Node.Column);
                 Window_Io.Overwrite
                      (Menu, Line_Image (Current_Node.Elem), Fonts.Normal);
                 Current_Node := New_Node;
                 Window_Io.Position_Cursor
                      (Menu, Current_Node.Line, Current_Node.Column);
                 Window_Io.Overwrite (Menu,
                          Line_Image (Current_Node.Elem), Selected_Font);
                 Raw.Close (Character_Stream);
                 Apply_Operation (Current_Node.Elem, Menu,
                                  Column_Offset, Line_Offset);
                 -- ensure correct cursor position after apply
                 Window_Io.Position_Cursor
                      (Menu, Current_Node.Line, Current_Node.Column);
                 Raw.Open (Character_Stream);
             exception
                 when Definition_Not_Found =>
                     Window_Io.Bell (Menu);
             end;
          elsif Is_Select_Key (One_Key) then
             Raw.Close (Character_Stream);
             Apply_Operation (Current_Node.Elem, Menu,
                              Column_Offset, Line_Offset);
             Window_Io.Position_Cursor
                  (Menu, Current_Node.Line, Current_Node.Column);
             Raw.Open (Character_Stream);
          elsif Is_Quit_Key (One_Key) then
             Raw.Close (Character_Stream);
             Erase (Menu, Definition, Column_Offset);
             exit;
          else
             Window_Io.Bell (Menu);
          end if;
      end loop;
  end Get_User_Selection;

  Disconnecting from a Menu

  One useful operation for applications that capture the key stream
  is to allow the user to leave the current window to do something
  else, possibly returning later to continue working.  An application
  might decide to recognize window traversal operations such as
  Window.Up and Window.Down.  The question now becomes how to
  disconnect from the current job and wait for the user to indicate a
  desire to reconnect.  It is desirable to allow this without forcing
  the user to interrupt the program and then explicitly reconnect to
  the numbered job using the Job.Connect procedure.

  The solution to this is fairly straightforward.  When the program
  recognizes that the user intends to leave (a [Window] - [up] key
  sequence, for example), the program disconnects itself and then
  waits on a prompt with a call to Window_Io.Get.  This is exactly
  the same approach used to return the user to the Rational Editor
  in a form.  When the user terminates the Get procedure with a
  Commit procedure, the job is implicitly reconnected, continuing
  to process keystrokes from the user.  Since the user is returned
  to the Rational Editor and has the ability to modify the image
  in window, it is a good idea to redraw the image, if possible,
  to ensure the integrity of the display.  The following program
  fragment should provide the basic implementation approach.

      procedure Hang (Output_Window : Window_Io.File_Type;
                     Input_Window : Window_Io.File_Type;
                     Key : Raw.Key) is
      begin
          Window_Utilities.Home (Output_Window);
          Window_Io.New_Line (Output_Window, 1);
          if Key = New_Keys.Up then
             Editor.Window.Previous;
          elsif Key = New_Keys.Down then
             Editor.Window.Next;
          else
             null;
          end if;
          Job.Disconnect;
          -- note that the program moved to the new window with the
          -- editor before disconnecting; calls to the editor can
          -- come only from connected jobs
         Window_Utilities.Continue
              (Input_Window, Output_Window,
               Prompt => "Type ENTER on this window to Reconnect",
               Line => 1, Column => 1);
      end Hang;

  The following example is a fragment of the key processor that
  recognizes the user's intent to leave and call the Hang procedure.
  It also calls a procedure to reset the window image when the user
  reconnects.
          ...
          elsif One_Key = New_Keys.Window_Up then
             Hang (Menu_Output, Menu_Input, New_Keys.Up);
             Reset_Screen;
          elsif One_Key = New_Keys.Window_Down then
             Hang (Menu_Output, Menu_Input, New_Keys.Down);
             Reset_Screen;
          elsif One_Key = New_Keys.Window then
             Raw.Get (Character_Stream, Second_Key);
             if Second_Key = New_Keys.Up then
                 Hang (Menu_Output, Menu_Input, New_Keys.Up);
                 Reset_Screen;
             elsif Second_Key = New_Keys.Down then
                 Hang (Menu_Output, Menu_Input, New_Keys.Down);
                 Reset_Screen;
             else
                 Window_Io.Bell (Menu_Output);
             end if;
          ...
  @node !Io.Window_Io.Attribute

  type Attribute is
      record
          Bold        : Boolean;
          Faint       : Boolean;
          Underscore  : Boolean;
          Inverse     : Boolean;
          Slow_Blink  : Boolean;
          Rapid_Blink : Boolean;
          Unused_0    : Boolean;
          Unused_1    : Boolean;
      end record;

  Defines the attributes that characters can have when displayed on
  the screen.

  A character's display depends on the user's terminal setup.  The
  actual effect of the Inverse attribute depends on the background
  mode currently in use.  The Bold and Faint attributes indicate
  display with brighter green if the terminal is set up in dim mode,
  and they will display dimmer green if the terminal is set up to
  display in bold.

  The Rational Terminal and the terminal controller do not support
  all possible combinations of the attribute fields.  The available
  combinations anticipate the most useful combinations.  In general,
  the attribute fields have the following effects (restrictions are
  described below):

  Bold           Character appears in brighter green

  Faint          Character appears in brighter green

  Underscore    Character is underlined

  Inverse        Character background appears in the inverse of the
                  terminal's current background

  Slow_Blink    Character blinks

  Rapid_Blink   Character blinks

  Unused_0      Reserved

  Unused_1      Reserved
  @node !Io.Window_Io.Bell

  procedure Bell (File : File_Type);

  Rings the terminal bell.

  Note:  There is only one bell.  It can be rung with any Window_Io
  file handle, even those handles that have not been opened.
  @node !Io.Window_Io.Character_Set

  type Character_Set is new Natural range 0 .. 15;

  Defines the possible character sets for the display.
  @node !Io.Window_Io.Char_At

  function Char_At (File : File_Type) return Character;

  Returns the character at the current cursor position.
  @node !Io.Window_Io.Close

  procedure Close (File : in out File_Type);

  Removes access to the image with this file handle.

  The image is not deleted or removed from the terminal screen.
  @node !Io.Window_Io.Column_Number

  subtype Column_Number is Positive;

  Defines the column number of a character in an image.

  Columns are numbered starting with 1 from the far left side of the
  image.
  @node !Io.Window_Io.Count

  subtype Count is Natural;

  Defines the number of times that an operation should be repeated.

  @node !Io.Window_Io.Create

  procedure Create (File : in out File_Type;
                   Mode :        File_Mode := Out_File;
                   Name :        String;
                   Form :        String    := "");

  Creates an image for performing I/O.

  Normally, a new empty image is created when this procedure is
  called, and a window containing the image appears on the terminal
  screen.  All named images can be opened twice, once for input and
  once for output.  If an image is already open for the current job
  with the specified name and is open with a mode other than the one
  currently requested, the existing image will be opened for the new
  mode.
  @node !Io.Window_Io.Default_Font

  function Default_Font (For_Type : Designation) return Font;

  Returns the default font for each kind of designation.

  For both the text and protected designations, the attributes are
  all Vanilla (that is all set to false).  The prompt designation
  returns a font whose Inverse attribute is set to true.  All
  designations use the Plain character set in their default font.
  @node !Io.Window_Io.Delete

  procedure Delete (File : in out File_Type);

  Deletes the image associated with the file handle and removes the
  window containing the image from the terminal screen and the Window
  Directory.

  Any other handles associated with this image are implicitly closed.
  @node !Io.Window_Io.Delete

  procedure Delete (File       : File_Type;
                   Characters : Count);

  Deletes the specified number of characters from the current line,
  starting with the character at the current cursor position.

  The position of the cursor is unchanged.  If the count specified is
  greater than the number of characters remaining on the line, all
  the subsequent characters on that line are deleted and no exception
  is raised.
  @node !Io.Window_Io.Delete_Lines

  procedure Delete_Lines (File  : File_Type;
                         Lines : Count      := 1);

  Deletes the specified number of lines from the image, starting at
  the current line.

  The column number of the cursor is unchanged, but it will be
  placed on the line following the last deleted line.  If the count
  specified is greater than the number of lines remaining in the
  image, all the subsequent lines in that image are deleted and no
  exception is raised.
  @node !Io.Window_Io.Designation

  type Designation is (Text, Prompt, Protected);

  Defines the behavior of edited characters and strings written to an
  image.

  Prompt

  Displays output as a prompt that disappears when the user
  types on it.  The user can turn a prompt into text with
  Commands.Editor.Set.Designation_Off (EI).

  Protected

  Displays output that is protected (that is, read-only output, which
  cannot be modified by the user).

  Text

  Displays output as plain text that can be modified by a user with
  the Rational Editor.
  @node !Io.Window_Io.End_Of_File

  function End_Of_File (File : File_Type) return Boolean;

  Returns true if the cursor is positioned at the end of the last
  line in the image; otherwise, the function returns false.
  @node !Io.Window_Io.End_Of_Line

  function End_Of_Line (File : File_Type) return Boolean;

  Returns true if the cursor is positioned at the end of the line;
  otherwise, the function returns false.
  @node !Io.Window_Io.File_Mode

  type File_Mode is (In_File, Out_File);

  Defines the access mode for which an image can be opened.

  An image can be opened for one or both modes with a separate file
  handle.
  In_File

  Denotes an image with read-only access.

  Out_File

  Denotes an image with write-only access.
  @node !Io.Window_Io.File_Type

  type File_Type is private;

  Defines a handle for an image.
  @node !Io.Window_Io.Font

  type Font is
      record
          Kind : Character_Set;
          Look : Attribute;
      end record;

  Defines the way in which ASCII characters written to an image are
  displayed.
  @node !Io.Window_Io.Font_At

  function Font_At (File : File_Type) return Font;

  Returns the font of the character that appears at the current
  cursor position.

  If the cursor is positioned after the last character on a line, the
  line is padded at the end with blanks written with the Normal font.
  Thus, the Font_At function returns Normal in this case.
  @node !Io.Window_Io.Form

  function Form (File : File_Type) return String;

  Returns the null string ("") regardless of the value provided to a
  call to the Open or the Create procedure.

  In the future, the Form parameter will be supported, and this
  function will return the actual value provided to the Open or the
  Create procedure.
  @node !Io.Window_Io.Get

  procedure Get (File   :     File_Type;
                Prompt :     String      := "[input]";
                Item   : out Character);

  Returns the character at the current cursor position in an image.

  This procedure has three slightly different effects depending on
  the cursor position and the designation of the character written at
  that position:

  o If the character located at the current cursor position is not
    written with a prompt designation (that is, with either a text or
    a protected designation), that character is immediately returned
    in the Item parameter.  The cursor is repositioned after the
    character extracted from the image.  The actual image remains
    unchanged.

  o If the character at the current cursor position has been written
    with a prompt designation, execution is suspended until the user
    provides the requested character reply.

  o If the cursor is located at the end of the image, the prompt
    string is displayed and execution is suspended until the user
    provides the requested character reply.

  Note that in the second and third cases above, the program does not
  return until the user commits the response.
  @node !Io.Window_Io.Get

  procedure Get (File   :     File_Type;
                Prompt :     String    := "[input]";
                Item   : out String);

  Returns string input from the image.

  This procedure has three slightly different effects depending on
  the cursor position and the designation of the character written at
  that position:

  o If the character located at the current cursor position is not
    written with a prompt designation (that is, with either a text or
    a protected designation), the sequence of characters starting at
    the current cursor position and continuing for the length of the
    Item variable is returned in the Item parameter.  The cursor is
    repositioned after the last character read from the image.  The
    actual image remains unchanged.

  o If the character at the current cursor position has been written
    with a prompt designation, execution is suspended until the user
    provides the number of characters necessary to fill the Item
    parameter.

  o If the cursor is located at the end of the image, the prompt
    string is displayed and execution is suspended until the user
    provides the requested number of characters.

  Notes:

  o In the second and third cases above, the program does not return
    until the user commits the response.

  o If the user intends to use this procedure to extract a string
    from an image but specifies an item string that has more
    characters than remain in the image, the user will be prompted
    with the specified prompt string at the end of the image for the
    remainder of the characters necessary to fill the Item string
    completely.

  @node !Io.Window_Io.Get_Line

  function Get_Line (File   : File_Type;
                    Prompt : String    := "[input]") return String;

  Returns string input from a line in an image.

  This procedure has three slightly different effects depending on
  the cursor position and the designation of the character written at
  that position:

  o If the character located at the current cursor position is not
    written with a prompt designation (that is, with either a text
    or a protected designation), the string returned will contain
    characters starting with the character located at the current
    cursor position through the last character on that line.  Use of
    this procedure has the side effect of repositioning the cursor at
    the first character of the next line.  The actual image remains
    unchanged, however.

  o If the character at the current cursor position has been written
    with a prompt designation, execution will be suspended until the
    user provides the requested string.

  o If the cursor is located at the end of the image, the prompt
    string is displayed and execution will be suspended until the
    user provides the requested string.

  Notes:

  o Extraction of an entire line is best accomplished with the
    Line_Image function also declared within this package.

  o The program will not return until the user commits the response.

  o A fringe case occurs when the cursor is located on the last line
    of the image.  In this case, the Get_Line function partially
    fills the return string with the characters in the line but also
    prompts the user at the end of the line for more characters.  Any
    characters offered by the user are appended to the return string.
  @node !Io.Window_Io.Get_Line

  procedure Get_Line (File   :     File_Type;
                     Prompt :     String    := "[input]";
                     Item   : out String;
                     Last   : out Natural);

  Returns string input from a line in an image.

  This procedure has three slightly different effects depending on
  the cursor position and the designation of the character written at
  that position:

  o If the character located at the current cursor position is not
    written with a prompt designation (that is, with either a text
    or a protected designation), the string returned in the Item
    parameter will contain characters starting with the character
    located at the current cursor position through the last character
    on that line.  The Last parameter indicates the index of the
    last valid character index of the Item parameter.  If the length
    of the Item string is not large enough to hold all remaining
    characters on that line, the returned string will contain only
    the subset that will fit.  Use of this procedure has the side
    effect of repositioning the cursor after the last character of
    the string extracted from the image.  The actual image remains
    unchanged, however.

  o If the character at the current cursor position has been written
    with a prompt designation, execution is suspended until the user
    provides the requested string.  The actual characters returned
    in the Item parameter are governed by the rules outlined in the
    first item above.

  o If the cursor is located at the end of the image, the prompt
    string is displayed and execution will be suspended until the
    user provides the requested string.

  Notes:

  o The program will not return until the user commits the response.

  o The user should not depend on the validity of any characters
    after the index indicated by the value of the Last parameter.

  o If the cursor is positioned after the last character on a line,
    the Last parameter is set to 0, indicating that no valid output
    characters were placed in the Item parameter.

  o A fringe case occurs when the cursor is located on the last line
    of the image.  In this case, the Get_Line procedure partially
    fills the return string with the characters in the line but also
    prompts the user at the end of the line for more characters.  Any
    characters offered by the user are appended to the Item string
    until it is full.
  @node !Io.Window_Io.Graphics

  Graphics : constant Character_Set := 1;

  Defines a named constant for the graphics character set.

  A complete description of the graphics character set is provided in
  the Rational Terminal User's Manual.
  @node !Io.Window_Io.Insert

  procedure Insert (File  : File_Type;
                   Item  : Character;
                   Image : Font        := Normal;
                   Kind  : Designation := Text);
  procedure Insert (File  : File_Type;
                   Item  : String;
                   Image : Font        := Normal;
                   Kind  : Designation := Text);

  Inserts a character or string into the current line at the current
  cursor position.

  The character at the current cursor position and all subsequent
  characters on that line are shifted to the right.  If the cursor
  is positioned beyond the last character on a line, the Insert
  procedure will place the character or string in the image beginning
  at the current cursor position and will fill the intervening
  space with blanks.  In every case, the actual cursor position is
  positioned after the last character in the inserted string.

  Note:  To prevent unnecessary scrolling, the screen cursor (the
  actual cursor on the screen) is not placed at the position of
  the image cursor but remains at the original position before the
  insert.  Multiple inserts will still work off the image cursor
  position, placing the inserted characters in the image.  The screen
  cursor can be resynchronized with the actual cursor with a call to
  the Move_Cursor or the Position_Cursor procedure.
  @node !Io.Window_Io.Is_Open

  function Is_Open (File : File_Type) return Boolean;

  Returns true if the file handle is open; otherwise, the function
  returns false.
  @node !Io.Window_Io.Job_Number

  function Job_Number return String;

  Returns a string representing the predefined field name Job_Number
  for the banner of a window.

  This is useful for input to the Set_Banner procedure and the
  Read_Banner function.
  @node !Io.Window_Io.Job_Time

  function Job_Time return String;

  Returns a string representing the predefined field name Job_Time
  for the banner of a window.

  This is useful for input to the Set_Banner procedure and the
  Read_Banner function.
  @node !Io.Window_Io.Last_Line

  function Last_Line (File : File_Type) return Line_Number;

  Returns the number of the last line in the image.

  If the image is empty (that is, contains no characters), the line
  number returned from the Last_Line function is 1.
  @node !Io.Window_Io.Line_Image

  function Line_Image (File : File_Type) return String;

  Returns the image of the line on which the cursor currently
  resides.

  The string returned includes all characters in the line including
  trailing blanks but not including a line terminator character.
  This function has higher performance than the Get_Line procedure
  and is generally preferred for extracting text from an image.
  @node !Io.Window_Io.Line_Length

  function Line_Length (File : File_Type) return Count;

  Returns the number of characters in the line in which the cursor
  currently resides.
  @node !Io.Window_Io.Line_Number

  subtype Line_Number is Positive;

  Defines the legal range for line numbers in an image.
  @node !Io.Window_Io.Mode

  function Mode (File : File_Type) return File_Mode;

  Returns the mode for which the specified file handle has been
  opened.
  @node !Io.Window_Io.Move_Cursor

  procedure Move_Cursor (File          : File_Type;
                        Delta_Lines   : Integer;
                        Delta_Columns : Integer;
                        Offset        : Natural   := 0);

  Repositions the cursor relative to its current position in the
  image.
  @node !Io.Window_Io.Name

  function Name (File : File_Type) return String;

  Returns the name of the image that was specified when the file
  handle was created or opened.
  @node !Io.Window_Io.New_Line

  procedure New_Line (File  : File_Type;
                     Lines : Count      := 1);

  Inserts the specified number of lines after the current line.

  If the cursor is positioned in the middle of a line of characters,
  a line terminator is inserted, effectively breaking the line into
  two lines.

  The cursor is positioned at the beginning of the line following the
  last inserted line.
  @node !Io.Window_Io.Normal

  Normal : constant Font := Font'(Plain, Vanilla);

  Defines a named constant for a font, selecting the normal settings
  for the character set and attributes.
  @node !Io.Window_Io.Open

  procedure Open (File : in out File_Type;
                 Mode :        File_Mode := Out_File;
                 Name :        String;
                 Form :        String    := "");

  Opens a file handle for input or output with its corresponding
  image.

  Images can be opened twice, once for input and once for output.

  If no image has been created previously with the specified name, a
  new image is created and a window containing the image will appear
  on the terminal screen.  If an image with the specified name has
  been created previously but has been closed, the old image can be
  reopened.  If an image is currently open with the specified name
  and mode, a new image is created and displayed on the terminal
  screen.
  @node !Io.Window_Io.Overwrite

  procedure Overwrite (File  : File_Type;
                      Item  : Character;
                      Image : Font        := Normal;
                      Kind  : Designation := Text);
  procedure Overwrite (File  : File_Type;
                      Item  : String;
                      Image : Font        := Normal;
                      Kind  : Designation := Text);

  Replaces characters or strings in the current line beginning at the
  current cursor position.

  If the new string contains more characters than exist on the
  current line, the line is extended to include all characters in the
  new string.  If the cursor is positioned beyond the last character
  on a line, the Overwrite procedure places the character or string
  in the image beginning at the current cursor position and fills the
  intervening space with blanks.  In every case, the actual cursor is
  positioned in the image after the last character in the overwritten
  string.

  Note:  To prevent unnecessary scrolling, the screen cursor (the
  actual cursor on the screen) is not placed at the position of
  the image cursor but remains at the original position before the
  overwrite.  Multiple overwrites will still work off the image
  cursor, placing the overwritten string in the image.  The screen
  cursor can be resynchronized with the actual cursor with a call to
  the Move_Cursor or the Position_Cursor procedure.
  @node !Io.Window_Io.Plain

  Plain : constant Character_Set := 0;

  Defines a named constant for the alphanumeric character set.
  @node !Io.Window_Io.Position_Cursor

  procedure Position_Cursor (File   : File_Type;
                            Line   : Line_Number   := Line_Number'First;
                            Column : Column_Number := Column_Number'First;
                            Offset : Natural       := 0);

  Places the cursor at the specified line and column.

  If the new cursor position is beyond the last character on a line,
  the length of the line is extended up to the new cursor position
  and the intervening space is filled with blanks.

  If the new cursor position is beyond the currently defined last
  line in the image, the number of the last line in the image is
  updated to reflect the new cursor position.

  If the new cursor position is outside the current window, the
  window is repositioned relative to the new cursor position, either
  through specification of a positive offset (defined below) or
  through the use of the default offset, with an orientation selected
  by the Rational Editor.
  @node !Io.Window_Io.Positive_Count

  subtype Positive_Count is Count range 1 .. Count'Last;

  Defines the allowable range for cursor positions.
  @node !Io.Window_Io.Read_Banner

  function Read_Banner (File       : File_Type;
                       Field_Name : String) return String;

  Returns the text residing in the specified field of the banner of
  the window.
  @node !Io.Window_Io.Report_Cursor

  procedure Report_Cursor (File   :     File_Type;
                          Line   : out Line_Number;
                          Column : out Column_Number);

  Identifies the current position of the cursor in the image.
  @node !Io.Window_Io.Report_Location

  procedure Report_Location (File   :     File_Type;
                            Line   : out Line_Number;
                            Column : out Column_Number);

  Reports the location on the terminal screen of the upper-left
  border of the window containing the specified image.

  The upper-left corner of the terminal screen is line 1, column 1.
  @node !Io.Window_Io.Report_Origin

  procedure Report_Origin (File   :     File_Type;
                          Line   : out Line_Number;
                          Column : out Column_Number);

  Reports the location of the upper-left corner of the window in the
  specified image.
  @node !Io.Window_Io.Report_Size

  procedure Report_Size (File    :     File_Type;
                        Lines   : out Positive_Count;
                        Columns : out Positive_Count);

  Reports the number of lines and columns in a window.

  Essentially, this procedure reports the amount of space available
  in a window.  The size of the image is unrelated to this data.
  The number of lines in an image is reported by the Last_Line
  function.
  @node !Io.Window_Io.Set_Banner

  procedure Set_Banner (File       : File_Type;
                       Field_Name : String;
                       Value      : String);

  Substitutes a new image for a particular field name in the banner
  of a window.
  @node !Io.Window_Io.Vanilla

  Vanilla : constant Attribute := (others => False);

  Defines a named constant for all attribute fields set to false.
  @node !Io.Window_Io.Raw

  This package allows programs to capture raw input from the terminal
  keyboard.

  Keystrokes can be considered the basic unit of data from the user.
  Instead of sending keystroke input to the Rational Editor, a
  program can capture keystrokes directly and interpret them as
  desired.  When keystrokes are taken from the raw terminal stream,
  they are not automatically echoed to the terminal.  This allows an
  application using these facilities to be extremely flexible in its
  response to input from the user.

  There is only one raw keystroke stream per terminal port.  Streams
  are not available on a per-window basis.  Only connected jobs
  can take input from the keyboard.  When a job is disconnected,
  keystroke input is redirected to the Rational Editor.
  @node !Io.Window_Io.Raw.Close

  procedure Close (Stream             : in out Stream_Type;
                  Flush_Pending_Input :        Boolean     := False);

  Disables the program's access to keystrokes from the keyboard and,
  if requested, discards any remaining characters in the buffer.

  Subsequent keystrokes are directed to the Rational Editor.
  @node !Io.Window_Io.Raw.Convert

  function Convert (C : Character) return Simple_Key;

  Returns the corresponding simple key for all characters.
  @node !Io.Window_Io.Raw.Convert

  function Convert (K : Simple_Key) return Character;

  Returns the corresponding character for a given simple key.
  @node !Io.Window_Io.Raw.Disconnect

  procedure Disconnect (Stream : in out Stream_Type);

  Frees the user's keyboard and returns input to the Rational Editor.

  The stream remains open, allowing the job to wait for input if the
  user decides to reconnect to the job.

  @node !Io.Window_Io.Raw.Get

  procedure Get (Stream :     Stream_Type;
                Item   : out Key);
  procedure Get (Stream :     Stream_Type;
                Item   : out Key_String);

  Retrieves a key or series of keys from the stream.

  If there are no pending keys in the stream, or not enough keys to
  fill the desired string, execution of the program is suspended
  until the user enters the required number of keystrokes at the
  keyboard.
  @node !Io.Window_Io.Raw.Image

  function Image (For_Key     : Key;
                 On_Terminal : Terminal) return String;

  Returns the corresponding image for a key on a particular
  terminal type as defined in the Environment package
  !Machine.Editor_Data.Visible_Key_Names.
  @node !Io.Window_Io.Raw.Key

  type Key is new Natural range 0 .. 1023;

  Defines the possible range of keys.
  @node !Io.Window_Io.Raw.Key_String

  type Key_String is array (Positive range <>) of Key;

  Defines an unconstrained array type for use in holding a series of
  keys.
  @node !Io.Window_Io.Raw.Open

  procedure Open (Stream : in out Stream_Type);

  Disconnects keystroke input from the Rational Editor and opens the
  keystroke stream for use by the currently executing job.
  @node !Io.Window_Io.Raw.Simple_Key

  subtype Simple_Key is Key range 0 .. 127;

  Defines the allowable range for simple keys.

  Simple keys correspond to the 128 ASCII characters as defined in
  PT, package Standard.  The value of the simple keys corresponds to
  the 'Pos attribute of the Character type.
  @node !Io.Window_Io.Raw.Stream_Type

  type Stream_Type is private;

  Defines a handle for access to the keystroke stream.
  @node !Io.Window_Io.Raw.Terminal

  subtype Terminal is String;

  Defines a subtype string for holding terminal names.

  The following terminal names are currently supported:

  o  Rational

  o  VT100
  @node !Io.Window_Io.Raw.Unknown_Key

  Unknown_Key : exception;

  Defines an exception raised by the Value function if the specified
  key name does not have a corresponding key for the specified
  terminal.
  @node !Io.Window_Io.Raw.Value

  function Value (For_Key_Name : String;
                 On_Terminal  : Terminal) return Key;

  Returns the corresponding key for a key name defined in package
  !Machine.Editor_Data.Visible_Key_Names.
  @node !Io.Window_Io.Raw.Value

  procedure Value (For_Key_Name :     String;
                  On_Terminal  :     Terminal;
                  Result       : out Key;
                  Found        : out Boolean);

  Provides the corresponding key for a key name defined in package
  !Machine.Editor_Data.Visible_Key_Names