home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
pmos2002.zip
/
DEF
/
windows.def
< prev
Wrap
Text File
|
1998-01-26
|
22KB
|
417 lines
DEFINITION MODULE Windows;
(****************************************************************)
(* *)
(* Text-mode screen windows. *)
(* *)
(* Programmer: P. Moylan *)
(* Last edited: 26 January 1998 *)
(* Status: Working *)
(* *)
(****************************************************************)
(************************************************************************)
(* *)
(* REMARK: There are two versions of the basic 'write' procedure. *)
(* Procedure WriteChar treats every character as a printable character, *)
(* so it can write any character in the standard character set. This *)
(* is the output procedure recommended for general use. Control *)
(* operations are supplied by separate procedures such as WriteLn, *)
(* SetCursor, etc., so there is no need to resort to the BASIC *)
(* programmers' trick of writing long strings of obscure control codes. *)
(* But for people who can't break this bad habit, procedure Write is *)
(* supplied; this treats character codes 0..31 as control codes. *)
(* Its main intended uses are to echo keyboard input, and to print a *)
(* file which contains embedded control characters; but it may be *)
(* used for other purposes if desired. *)
(* *)
(* Warning: I have not bothered to look after all the control codes, *)
(* just the ones I found a use for. Most of them print as a *)
(* two-character sequence ^<letter>. *)
(* *)
(************************************************************************)
(************************************************************************)
(* *)
(* NOTE ON CRITICAL SECTIONS: When using this module in a multitasking *)
(* environment, there are numerous critical sections because several *)
(* tasks may be using the same physical screen. These sections are *)
(* protected by semaphores. (For the case where we are not using the *)
(* multitasking kernel, there is a version of module Semaphores which *)
(* contains dummy procedures). The general philosophy is to assume *)
(* that critical section protection is needed for inter-window *)
(* conflicts, but that no protection is needed for operations on a *)
(* single window because the most common situation is that each window *)
(* is used by only one task. If there happen to be windows which are *)
(* shared by two or more tasks, the associated synchronization problems *)
(* must be resolved by the caller; they are not resolved in module *)
(* Windows, on the grounds that the extra overhead is not justified *)
(* just to support a case which rarely happens in practice. *)
(* *)
(* *)
(* LATEST DEVELOPMENT *)
(* *)
(* Because of the addition of the MouseControl module, it can happen in *)
(* practice, so I've added partial protection. The following *)
(* procedures are indivisible with respect to one another, as far as *)
(* shared uses of a window are concerned: *)
(* OpenWindow, CloseWindow, ShiftWindowRel, ScrollUp, ScrollDown, *)
(* WriteChar, WriteLn, SetCursor, Hide, PutOnTop. *)
(* Minor technicality: in some cases there is an implied PutOnTop, or *)
(* similar side-effect, and this is not always part of the indivisible *)
(* section. I can't think of any case where this would matter to the *)
(* user. I don't like making protected sections too large, since this *)
(* can degrade overall system responsiveness. *)
(* *)
(* Note: procedures WriteString and Write, while not indivisible in *)
(* the above sense, are protected at the "write a character" level. *)
(* *)
(************************************************************************)
CONST
MaxRowNumber = 24;
MaxColumnNumber = 79;
TYPE
Window; (* is private *)
Colour = (black, blue, green, cyan, red, magenta, brown, white,
darkgrey, lightblue, lightgreen, lightcyan, lightred,
lightmagenta, yellow, intensewhite);
(* Note: Any of these colours may be used as a foreground colour, *)
(* but in most applications only [black..white] are suitable as *)
(* background colours. The others may be used, but they can give *)
(* strange effects such as a blinking display. Use with care! *)
RowRange = [0..MaxRowNumber];
ColumnRange = [0..MaxColumnNumber];
Rectangle = RECORD
top, bottom: RowRange;
left, right: ColumnRange;
END (*RECORD*);
FrameType = (noframe, simpleframe, doubleframe);
DividerType = (nodivider, simpledivider, doubledivider);
DisplayPage = [0..3];
PROCEDURE OpenWindow (VAR (*OUT*) w: Window;
ForegroundColour, BackgroundColour: Colour;
firstline, lastline: RowRange;
firstcol, lastcol: ColumnRange;
FrameDesired: FrameType;
DividerDesired: DividerType);
(* Create a new window. Note that row and column numbers start *)
(* from 0. NOTE: If the window has a box drawn around it (the case *)
(* FrameDesired <> noframe), this subtracts from the space *)
(* available for text. *)
PROCEDURE OpenWindowHidden (VAR (*OUT*) w: Window;
ForegroundColour, BackgroundColour: Colour;
firstline, lastline: RowRange;
firstcol, lastcol: ColumnRange;
FrameDesired: FrameType;
DividerDesired: DividerType);
(* Like OpenWindow, but the window does not appear on the screen *)
(* until the first PutOnTop(w). *)
PROCEDURE OpenSimpleWindow (VAR (*OUT*) w: Window;
firstline, lastline: RowRange;
firstcol, lastcol: ColumnRange);
(* Identical to OpenWindow, except that you don't get any choice *)
(* about the colours or frame. The window is white-on-black with *)
(* a simple frame and no dividers for the scrolling region. This *)
(* version of OpenWindow is useful for those with monochrome *)
(* displays who don't want to be bothered with importing the types *)
(* Colour, FrameType, and DividerType. *)
PROCEDURE ChangeScrollingRegion (w: Window; firstline, lastline: RowRange);
(* Changes the scrolling region of window w to the new line *)
(* boundaries given, and sets the cursor of this window to the *)
(* start of the scrolling region. Row numbers are window-relative; *)
(* that is, line 0 is the top line of the window (which is where *)
(* the border is, unless you have no border). *)
PROCEDURE NewScrollingRegion (w: Window; firstline, lastline: RowRange;
firstcolumn, lastcolumn: ColumnRange);
(* Changes the scrolling region of w to be the specified rectangle, *)
(* but unlike ChangeScrollingRegion this procedure does not redraw *)
(* the dividers. Furthermore the old scrolling region set by *)
(* ChangeScrollingRegion is remembered and may be restored by a *)
(* call to ResetScrollingRegion. *)
PROCEDURE ResetScrollingRegion (w: Window);
(* Changes the scrolling region of w back to what it was the last *)
(* time ChangeScrollingRegion was called. If ChangeScrollingRegion *)
(* was never called, the scrolling region goes back to being the *)
(* entire window minus the frame (if any). *)
PROCEDURE SetWrapOption (w: Window; enabled: BOOLEAN);
(* If the parameter is TRUE - this is the initial default - then *)
(* subsequent text written to the window will wrap to the next *)
(* line when it hits the right of the scrolling region. Setting *)
(* the parameter to FALSE disables this feature. *)
PROCEDURE ShiftWindowRel (w: Window; rowchange, columnchange: INTEGER);
(* Moves w on the screen. The second and third arguments may be *)
(* negative. The amount of move may be reduced to prevent a move *)
(* off the edge of the screen. *)
PROCEDURE ShiftWindowAbs (w: Window; top: RowRange; left: ColumnRange);
(* Like ShiftWindowRel, except that we directly specify the target *)
(* position of the top left corner in screen coordinates. *)
PROCEDURE CloseWindow (w: Window);
(* Destroys the window. Note that this could have side-effects *)
(* if procedure InstallCloseHandler (see below) has been called. *)
PROCEDURE Hide (w: Window);
(* Makes this window invisible on the screen. It is still possible *)
(* to write to the window, but the output will not appear until *)
(* a PutOnTop(w) is executed. *)
PROCEDURE PutOnPage (w: Window; p: DisplayPage);
(* Moves window w to another display page. The default is to put *)
(* every window on page 0 when it is first opened. To override *)
(* the default, call this procedure after opening the window. *)
PROCEDURE PageOf (w: Window): DisplayPage;
(* Returns the display page on which window w resides. *)
PROCEDURE PutOnTop (w: Window);
(* Makes sure that window w is fully visible on the screen. (This *)
(* also cancels the effect of a Hide(w).) Rarely needed, since *)
(* many window operations automatically put their window on top. *)
PROCEDURE IdentifyTopWindow (VAR (*OUT*) w: Window; page: DisplayPage;
VAR (*INOUT*) row: RowRange;
VAR (*INOUT*) col: ColumnRange): BOOLEAN;
(* On entry w is unspecified and (page,row,col) describes a *)
(* position on the screen. On exit w is equal to the top window *)
(* containing this screen location, and (row,col) have been altered *)
(* to be window-relative coordinates. Exception: if there is no *)
(* visible window containing the given point, the function result *)
(* is FALSE, the returned w is meaningless, and row and col are *)
(* unchanged. *)
PROCEDURE RefreshDisplay;
(* Rewrites every open window. Should not normally be needed, but *)
(* available for use in cases the display is corrupted by, for *)
(* example, software which bypasses this module and writes directly *)
(* to the screen. *)
PROCEDURE SetActivePage (page: DisplayPage);
(* Changes the active display page. Not needed unless you are *)
(* switching among multiple pages. *)
PROCEDURE CurrentPage(): DisplayPage;
(* Returns the currently active display page. *)
TYPE PageChangeHandler = PROCEDURE (DisplayPage);
PROCEDURE RequestPageChangeNotification (Proc: PageChangeHandler);
(* Sets up Proc as a procedure to be called on a page change. *)
TYPE CloseHandlerProc = PROCEDURE (Window, DisplayPage);
PROCEDURE InstallCloseHandler (w: Window; P: CloseHandlerProc);
(* Sets up P as a procedure to be called when the window is closed. *)
(* It is legal to define multiple handlers for the same window. *)
PROCEDURE WindowLocation (w: Window): Rectangle;
(* Returns the current location of w on the screen. *)
PROCEDURE SetCursor (w: Window; row: RowRange; column: ColumnRange);
(* Sets the cursor for window w to the given row and column. The *)
(* coordinates are window-relative; that is, they start at (0,0) at *)
(* the top left of the window. *)
PROCEDURE SaveCursor (w: Window; VAR (*OUT*) row, column: CARDINAL);
(* Returns the current cursor position. The coordinates are *)
(* window-relative; that is, they start at (0,0) at the top left of *)
(* the window. *)
PROCEDURE CursorLeft (w: Window);
(* Moves the window cursor one position left. If it falls off the *)
(* left edge of the window, it moves to the right edge in the same *)
(* row. *)
PROCEDURE CursorRight (w: Window);
(* Moves the window cursor one position right. If it falls off the *)
(* right edge of the window, it moves to the left edge in the same *)
(* row. *)
PROCEDURE CursorUp (w: Window);
(* Moves the window cursor one position up. If it falls off the *)
(* top edge of the window, it moves to the bottom edge in the same *)
(* column. *)
PROCEDURE CursorDown (w: Window);
(* Moves the window cursor one position down. If it falls off the *)
(* bottom edge of the window, it moves to the top edge in the same *)
(* column. *)
PROCEDURE ScrollUp (w: Window);
(* Scrolls the scrolling region of window w up by one row, filling *)
(* the vacated row with spaces. *)
PROCEDURE ScrollDown (w: Window);
(* Scrolls the scrolling region of window w down by one row, *)
(* filling the vacated row with spaces. *)
PROCEDURE WriteLn (w: Window);
(* Go to next line in window, scrolling if necessary. N.B. The *)
(* window does not scroll if you are not in the scrolling region *)
(* at the time of the WriteLn. *)
PROCEDURE WriteChar (w: Window; ch: CHAR);
(* Write one character. Control characters are not given special *)
(* treatment; they produce something visible just like any other *)
(* character. Wraps to the next line before writing if the write *)
(* would put us on or beyond the right border of w. *)
PROCEDURE Write (w: Window; ch: CHAR);
(* Like WriteChar, but codes in the range 0..31 are treated as *)
(* control characters. This procedure is not recommended for *)
(* general use, as it leads to obscure programs. (Instead, do the *)
(* control operations by direct calls to the cursor control *)
(* procedures which are also supplied in this module). It is *)
(* supplied mainly to help those who are used to the conventions of *)
(* the "standard" Modula-2 I/O modules such as InOut. *)
PROCEDURE WriteString (w: Window; text: ARRAY OF CHAR);
(* Write a string of characters, stopping at the first NUL *)
(* character or the end of the array, whichever comes first. *)
PROCEDURE ReadBack (w: Window; r: RowRange; c: ColumnRange): CHAR;
(* Returns the character which currently occupies relative location *)
(* (r,c) on the display of window w. *)
PROCEDURE ReadChar (w: Window; VAR (*OUT*) ch: CHAR);
(* Read one character, and echo it. *)
PROCEDURE LookaheadChar (w: Window): CHAR;
(* Reads a character without consuming it. That is, the character *)
(* remains available to be read by ReadChar. This allows the *)
(* caller to check whether the character is really wanted. *)
PROCEDURE ReadCharWithoutEcho (w: Window; VAR (*OUT*) ch: CHAR);
(* Read one character, but don't echo it. However, a blinking *)
(* cursor is still displayed to prompt for the character. (If you *)
(* don't want the blinking cursor, use procedure GetKey). *)
PROCEDURE GetKey (w: Window): CHAR;
(* Read one character, without any prompt to the user. The reason *)
(* for specifying a window parameter is to ensure that keyboard *)
(* input comes to us only when this window has input focus. *)
(* (If you want the input regardless of input focus, use procedure *)
(* Keyboard.InKey). *)
PROCEDURE PressAnyKey (w: Window);
(* Types a "Press any key to continue" message. *)
PROCEDURE ReadString (w: Window; VAR (*OUT*) result: ARRAY OF CHAR);
(* Reads a character string, terminated by carriage return. *)
PROCEDURE EditString (w: Window; VAR (*INOUT*) result: ARRAY OF CHAR;
fieldsize: CARDINAL);
(* Reads a character string, where a default result is supplied by *)
(* the caller. The final result is the state of the string at the *)
(* time where the keyboard user types a carriage return or Esc, or *)
(* uses a cursor movement key to move out of the displayed field. *)
(* The terminating character remains available, via Keyboard.InKey, *)
(* to the caller. At most fieldsize characters of the string can *)
(* be edited, and perhaps fewer if the result array is smaller or *)
(* if there is insufficient space in the window. *)
PROCEDURE EditAborted (): BOOLEAN;
(* Checks the next keyboard input. Returns TRUE for Escape, FALSE *)
(* for anything else. Escape or Carriage Return are consumed, any *)
(* other character is returned to the Keyboard module. *)
PROCEDURE SetColours (w: Window; row: RowRange; col: ColumnRange;
nchar: CARDINAL; foreground, background: Colour);
(* Sets a field of nchar characters, starting at (row,col), to *)
(* the specified foreground and background colours. The location *)
(* is given in window-relative coordinates, not absolute screen *)
(* positions. NOTE: Do not assume that this procedure can wrap *)
(* around to a new line. It normally cannot. *)
PROCEDURE ColourSwap (w: Window; row: RowRange; col: ColumnRange;
nchar: CARDINAL);
(* Sets a field of nchar characters, starting at (row,col), to *)
(* "reverse video" by swapping the foreground and background *)
(* colours. Notice that the process is reversible: you get back to *)
(* "normal video" by calling this procedure again. The location is *)
(* given in window-relative coordinates, not absolute screen *)
(* positions. NOTE: Do not assume that this procedure can wrap *)
(* around to a new line. It normally cannot. *)
PROCEDURE Blink (w: Window; r: RowRange; c: ColumnRange; nchar: CARDINAL);
(* Toggles the blinking status - that is, turns blinking on if it *)
(* was off, and vice versa - for nchar characters, starting at *)
(* relative location (r,c) in window w. *)
(* NOTE: This procedure will not wrap around to a new row. *)
PROCEDURE EraseLine (w: Window; option: CARDINAL);
(* Erases some or all of the current line (but never the border). *)
(* The erased characters are replaced by space characters. The *)
(* window cursor is moved to the location of the first erased *)
(* character. If w is not the currently active window, the changes *)
(* will not be visible until w is on top again. The options are: *)
(* 0 the whole of the line, except for the border *)
(* 1 from the current cursor position onwards *)
(* 2 from the start to just before the cursor *)
(* If we are inside a scrolling region, then only that part of the *)
(* line inside the scrolling region is affected. *)
END Windows.