DataMuseum.dkPresents historical artifacts from the history of: Rational R1000/400 Tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Rational R1000/400 Tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - downloadIndex: ┃ D T ┃
Length: 103011 (0x19263) Types: TextFile Names: »DIO_HELP«
└─⟦5f3412b64⟧ Bits:30000745 8mm tape, Rational 1000, ENVIRONMENT 12_6_5 TOOLS └─ ⟦91c658230⟧ »DATA« └─⟦f6fec0485⟧ └─⟦this⟧ └─⟦d10a02448⟧ Bits:30000409 8mm tape, Rational 1000, ENVIRONMENT, D_12_7_3 └─ ⟦fc9b38f02⟧ »DATA« └─⟦f95d63c89⟧ └─⟦this⟧
@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.