[net.sources] OSSI: SIWindows

hinrichs@unc.UUCP (11/21/86)

(***************************************************************************)
(***                                                                     ***)
(***                                                                     ***)
(***                     O  S  S  I                                      ***)
(***                     ==========                                      ***)
(***                                                                     ***)
(**)               DEFINITION MODULE SIWindows;                          (**)
(***               ===========================                           ***)
(***                                                                     ***)
(***   This module handles windows on a raster display.                  ***)
(***                                                                     ***)
(***---------------------------------------------------------------------***)
(***                                                                     ***)
(***   Hardware:          independent                                    ***)
(***   Operating System:  independent                                    ***)
(***   Compiler:          independent                                    ***)
(***                                                                     ***)
(***   Version:      4.0                                                 ***)
(***   Implemented:  see copyright                                       ***)
(***   Date:         1986-11-17                                          ***)
(***                                                                     ***)
(***---------------------------------------------------------------------***)
(***                                                                     ***)
(***   Copyright 1986 by                                                 ***)
(***      E. S. Biagioni                                                 ***)
(***      G. Heiser                                                      ***)
(***      K. Hinrichs                                                    ***)
(***      C. Muller                                                      ***)
(***                                                                     ***)
(***   Institut fuer Informatik                                          ***)
(***   ETH Zuerich                                                       ***)
(***   CH 8092 Zuerich                                                   ***)
(***   Switzerland                                                       ***)
(***                                                                     ***)
(***   Department of Computer Science                                    ***)
(***   University of North Carolina                                      ***)
(***   Chapel Hill, North Carolina 27514                                 ***)
(***   U.S.A.                                                            ***)
(***                                                                     ***)
(*** Permission to copy without fee all of this material is granted      ***)
(*** provided that the copies are not made or distributed for direct     ***)
(*** commercial advantage, that this OSSI copyright notice is            ***)
(*** included in the copy, that the module is not modified in any way    ***)
(*** except where necessary for compilation on a particular system,      ***)
(*** and that the module is always distributed in its original form.     ***)
(*** Distribution of this module in a modified form without including    ***)
(*** the original version is a violation of this copyright notice.       ***)
(***                                                                     ***)
(***---------------------------------------------------------------------***)
(***                                                                     ***)
(***   Updates:                                                          ***)
(***                                                                     ***)
(***                                                                     ***)
(***************************************************************************)

(* In the following by 'application program' or 'program' we mean the
   program which uses the window modules of OSSI. By 'interactive user'
   or 'user' we mean the interactive user of such an application program.

   This module handles windows on a raster display. Windows are rectangles
   on the screen that can be used for output.

   Since different kinds of information may be output to a window, this
   module supports general purpose window operations. These include
   creation and deletion of windows, setting and inquiring window
   attributes, changing size and location of a window.

   Position and size of a window are specified in absolute screen
   coordinates. The screen coordinate system has its origin (0,0) at the
   pixel in the upper left hand corner of the screen. Units are the
   addressable raster points on the screen (pixels), counted left to
   right and top to bottom. Windows must fit completely within the screen.

   The contents of a window are addressed in local window coordinates.
   The window coordinates are in the same units as screen coordinates,
   the origin (0, 0) being the pixel in the upper left hand corner of the
   inner (usable) rectangle of the window; coordinates increase left to
   right and top to bottom.

   Points are identified by their screen or window coordinates. These
   coordinates are given as (h, v), where h denotes the horizontal and v
   the vertical coordinate. The window coordinates of points above the
   visible part of a window have a negative v-component, the window
   coordinates of points to the left of the visible part of a window have
   a negative h-component.

   A window has a default paint mode, initialized to paint. Except where an
   explicit paint mode is specified on an operation, all window output is
   done using the default paint mode. This allows for example inverted
   text output. The default paint mode may be set by the programmer.

   Window contents can be read or written with bitmaps. A bitmap is
   equivalent to an array of bits, each bit corresponding to a raster
   point. *)


FROM SISystem IMPORT
   BYTE,
   SIResult;

FROM SISets IMPORT
   Set;


EXPORT QUALIFIED
   Direction,
   ScrollPos,
   Rectangle,
   Window,
   Bitmap,
   ExternalBitmap,
   UpdateProcedure,
   WindowProcedure,
   Attributes,
   AttributeSet,
   PaintMode,
   SetRectangleByBounds,
   SetRectangleBySize,
   ScreenSize,
   ComputeOuterRectangle,
   NoUpdate,
   CreateWindow,
   DeleteWindow,
   CloseWindow,
   IsClosed,
   HideWindow,
   IsFullyVisible,
   PutOnTop,
   MoveWindow,
   ChangeWindow,
   GetOuterRectangle,
   GetInnerRectangle,
   SetInnerRectangle,
   GetTitle,
   SetTitle,
   GetAttributes,
   GetDefaultPaintMode,
   SetDefaultPaintMode,
   GetUpdateProcedure,
   SetUpdateProcedure,
   GetScrollPos,
   SetScrollPos,
   LocateWindow,
   GetWindowCoordinate,
   GetScreenCoordinate,
   ClearRectangle,
   ClearWindow,
   RefreshWindow,
   MoveRectangle,
   CreateBitmap,
   GetExternalBitmap,
   DisposeBitmap,
   BitmapToWindow,
   WindowToBitmap,
   BitmapStorage,
   BitmapToBytes,
   BytesToBitmap,
   ForEachWindowDo;


TYPE Direction       = (horizontal, vertical);

     ScrollPos       = REAL;  (* always in [0,1] *)

     Rectangle       = RECORD
                         left, top, right, bottom: INTEGER;
                       END (* Rectangle *);

     Window;

     Bitmap;
     (* represents a rectangle of pixels; the pixel in the upper left
        corner of the rectangle has coordinates (0, 0). *)

     ExternalBitmap  = RECORD
                         rows, columns: CARDINAL;
                         pixels: Set;
                       END (* ExternalBitmap *);
     (* external representation of a bitmap which allows to operate on single
        pixels. The bitmap with the given number of rows and columns is
        linearized in pixels. pixels is a Set containing elements in the
        range from 0 to (rows * columns - 1); pixel (i, j) is set if element
        (j * columns + i) is contained in the set. *)

     UpdateProcedure = PROCEDURE (Window, Rectangle);
     (* refreshes the part of the window given by the rectangle (in window
        coordinates). *) 

     WindowProcedure = PROCEDURE (Window);

     Attributes      = (hasBorder, hasTitle, hasVerScroll, hasHorScroll,
                        mayBeClosed, mayBeDeleted, mayBeMoved, mayBeChanged,
                        saveWindow);
     (* The window attributes specify the properties of a window. These
        properties may influence the appearance of a window on the screen,
        e.g. the window has scroll bars or a menu with entries for closing
        or deleting a window.
        Scrolling, closing, deleting, moving and changing the window by the 
        interactive user can be enabled; such actions are detected by
        SIEvents.GetEvent.
        hasBorder:    the window is drawn with a border.
        hasTitle:     a title bar is drawn.
        hasVerScroll: a mechanism for vertical scrolling is enabled.
        hasHorScroll: a mechanism horizontal scrolling is enabled.
        mayBeDeleted: enables deleting the window by the interactive user;
                      a deleted window is no longer under the control of the
                      user and cannot be accessed any more.
        mayBeClosed:  enables closing the window by the interactive user
                      (e.g. by pointing the pointing device to a specially
                      marked spot or by a menu); a closed window is still
                      under the control of the user, i.e. the user can open
                      it again later on, e.g. by selecting an icon or a list
                      entry which corresponds to the closed window. A closed
                      window is visible on the screen in a condensed form; if
                      a closed window for which saveWindow is set is opened
                      again and it has not been changed, it appears the same
                      as before closing. Output can be transferred to a
                      closed window. If saveWindow is set this output will
                      be visible after an open operation. The only operations
                      which can be performed on a closed window by the
                      interactive user are the open (e.g. by selecting an
                      icon or a list item which corresponds to this window)
                      and the delete operation. However, if closed windows
                      are represented by icons the user might be able to move
                      them around etc.; such operations will not be
                      considered by OSSI (and therefore are not reported as
                      events) and have no effect on the window itself.
        mayBeMoved:   the interactive user may move the window using the
                      pointing device in a system dependent manner.
        mayBeChanged: the interactive user may change the size and location
                      of the window with the pointing device.
        saveWindow:   when a window is closed, or invisible, or part of the
                      window is overlapped, its contents are stored and later
                      replaced directly; the update procedure is not called.
        The inner window is what can actually be used to display user
        information. It is given by the outer rectangle reduced by space
        needed for title, border, scrollbars, etc. The size of the inner
        rectangle of a window may be further reduced by a call to the
        procedure SetInnerRectangle. All output to a window is clipped to its
        inner rectangle. *)

     AttributeSet   = SET OF Attributes;

     PaintMode = (paint, erase, invert, replace, mask);
     (*  Defines the mode of painting operations. They may be used in two
         contexts: with only a destination bitmap, and when copying a source
         (e.g. the pattern) to a destination (e.g. the window). Operating on
         the destination only can be seen as a special case, with all source
         bits 1.
         The effect of each operation is as follows:  | source implicitly 1
         paint   : d := d OR s      ; overwrite       |   d := 1     ; paint
         erase   : d := d AND NOT s ; erase if s is 1 |   d := 0     ; erase
         invert  : d := d XOR s     ; invert          |   d := NOT d ; invert
         replace : d := s           ; replace         |   d := 1     ; paint
         mask    : d := d AND s     ; erase if s is 0 |   d := d     ; no op *)


(* The two following rectangle initialization procedures are provided for
   convenience only. *)
 
PROCEDURE SetRectangleByBounds (VAR r: Rectangle;
                                left, top, right, bottom: INTEGER);

PROCEDURE SetRectangleBySize (VAR r: Rectangle;
                              left, top: INTEGER; width, height: CARDINAL);

PROCEDURE ScreenSize (VAR width, height: CARDINAL);
(* returns the width and height (in pixels) of the available screen. *)

PROCEDURE ComputeOuterRectangle (innerWidth, innerHeight: CARDINAL;
                                 attr: AttributeSet;
                                 VAR outerWidth, outerHeight: CARDINAL);
(* computes the size of an outer rectangle with the given attributes required
   to allow an inner rectangle of given height and width. *)

PROCEDURE NoUpdate (w: Window; r: Rectangle);
(* is a default update procedure which does nothing. It may be used for
   windows with attribute saveWindow set. *)

PROCEDURE CreateWindow (VAR w: Window; outer: Rectangle; attr: AttributeSet;
                        title: ARRAY OF CHAR; update: UpdateProcedure;
                        VAR result: SIResult);
(* creates window w and places it on top of all existing windows.
   The location of the window is given by outer (in screen coordinates).
   The whole rectangle must fit on the screen.

   attr specifies window attributes, which are fixed over the lifetime
   of the window.

   title is ignored if hasTitle is not set, update is ignored if saveWindow
   is set.

   Windows may be totally visible, partially or totally covered by other
   windows. Output is possible even to invisible portions of windows.
   This will simply be ignored if saveWindow is not set or if output is
   to an area outside the window, so clipping is performed. If previously
   covered parts of a window become visible again (by deleting or changing
   another window), the newly visible part is refreshed. In the case of a
   window with saveWindow set, this is done automatically, otherwise the
   update procedure is called for the refresh. The clipping coordinates
   are set to the inner rectangle, whose size may be reduced by a call to
   SetInnerRectangle. Clipped information is lost, i.e. not available
   when the window is increased. If the window has been created
   successfully result will return SIDone.

   If the window has scroll bars the procedure SetScrollPos should be
   called after successful creation. Initially the scroll boxes in the
   scroll bars will be set to 0.0. *)

PROCEDURE DeleteWindow (VAR w: Window);
(* deletes a window. If the window was visible on the screen it becomes
   invisible. The associated storage is released. w is set to an invalid
   value and may not be used later on. This procedure works even if
   mayBeDeleted is NOT set. *)

PROCEDURE CloseWindow (w: Window);
(* closes a window. The user is allowed to reopen a closed window.
   For further information see under mayBeClosed in the definition of
   Attributes. This procedure works even if mayBeClosed is NOT set. *)

PROCEDURE IsClosed (w: Window): BOOLEAN;
(* returns TRUE if window w is closed. *)

PROCEDURE HideWindow (w: Window);
(* makes the window invisible on the screen. The interactive user cannot
   control this window any more, i.e. cannot move, resize, close, delete
   or open it. *)

PROCEDURE IsFullyVisible (w: Window): BOOLEAN;
(* is TRUE if w is visible on the screen and not covered by other windows.
   If w is closed or hidden the procedure returns FALSE. *)

PROCEDURE PutOnTop (w: Window);
(* makes window fully visible. If the window was closed it is opened again.
   If the window was hidden (by HideWindow) or closed and it has not been
   changed the window will appear the same as it was before it was hidden or
   closed. *)

PROCEDURE MoveWindow (w: Window; left, top: INTEGER);
(* moves w to a new position on the screen. left and top are the screen
   coordinates of new upper left corner of the window. If the window
   would not be fully within the screen this procedure has no effect.
   This procedure works even if mayBeMoved is NOT set. *)

PROCEDURE ChangeWindow (w: Window; outer: Rectangle);
(* changes position and size of w as specified by outer (in screen
   coordinates). If outer does not lie fully within the screen this
   procedure has no effect. The inner rectangle is reset to the maximum
   possible size. This procedure works even if mayBeChanged is NOT set. *)


(* The following procedures set or inquire window characteristics. *)

PROCEDURE GetOuterRectangle (w: Window; VAR outer: Rectangle);
(* returns the outer rectangle of the window in screen coordinates. *)

PROCEDURE GetInnerRectangle (w: Window; VAR inner: Rectangle);
(* returns inner rectangle of the window. The coordinates are relative
   to the pixel in the upper left corner of the outer rectangle of the
   window. *)

PROCEDURE SetInnerRectangle (w: Window; inner: Rectangle);
(* enables the user to specify an inner rectangle smaller than the
   default given by what is left from outer after drawing border, title,
   scrollbars, etc. Coordinates are as screen coordinates but relative
   to the outer rectangle of the window. The specified rectangle is
   clipped to the default (= maximum) inner rectangle. *)

PROCEDURE GetTitle (w: Window; VAR title: ARRAY OF CHAR);
(* inquires the title of a window; it will return an empty string if
   hasTitle is not set. *)

PROCEDURE SetTitle (w: Window; title: ARRAY OF CHAR);
(* specifies a new title; it is ignored if hasTitle is not set. *)

PROCEDURE GetAttributes (w: Window; VAR attr: AttributeSet);
(* inquires the window attributes. *)

PROCEDURE GetDefaultPaintMode (w: Window; VAR mode: PaintMode);
(* inquire default paint mode of a window. *)

PROCEDURE SetDefaultPaintMode (w: Window; mode: PaintMode);
(* sets a new default paint mode for a window. *)

PROCEDURE GetUpdateProcedure (w: Window; VAR update: UpdateProcedure);
(* will return the procedure NoUpdate if saveWindow is set. *)

PROCEDURE SetUpdateProcedure (w: Window; update: UpdateProcedure);
(* specifies a new update procedure. This procedure will have no effect if
   saveWindow is set. *)

PROCEDURE GetScrollPos (w: Window; d: Direction;
                        VAR scrollPos: ScrollPos);
(* returns the scroll position for direction d (horizontal or vertical). If
   the scroll bar corresponding to d does not exist (i.e. has<d>Scroll has
   not been set when the window was created) the value returned in scrollPos
   is undefined. *)

PROCEDURE SetScrollPos (w: Window; d: Direction;
                        scrollPos, amountShown: ScrollPos);
(* sets the scroll position for direction d (horizontal or vertical). If
   the scroll bar corresponding to d does not exist (i.e. has<d>Scroll has
   not been set when the window was created) this procedure has no effect.
   amountShown indicates how much of the document is visible (this may be
   needed to figure out the step size when flipping pages; on some systems
   that information is reflected in the size of the scroll box). This
   procedure should always be called after a window with scroll bars has
   been created or resized. *)

PROCEDURE LocateWindow (h, v: INTEGER; VAR inWindow: BOOLEAN; VAR w: Window);
(* returns whether the point (h, v) (in screen coordinates) is contained
   in a window. If inWindow is TRUE w returns some window in whose outer
   rectangle the point is located. If possible, a window that is visible
   at the given position is returned. *)

PROCEDURE GetWindowCoordinate (h, v: INTEGER;
                               VAR inWindow, inInnerRectangle: BOOLEAN;
                               VAR w: Window; VAR hw, vw: INTEGER);
(* returns whether the point (h, v) (in screen coordinates) is contained
   in a window. If inWindow and inInnerRectangle are TRUE w returns some
   window in whose inner rectangle the point is located and (hw, vw) are
   the window coordinates (hw, vw) corresponding to screen coordinates
   (h, v). If inInnerRectangle = FALSE, (h, v) lies within the outer but
   not within the inner rectangle of w, and (hw, vw) return (0, 0). *)

PROCEDURE GetScreenCoordinate (h, v: INTEGER; w: Window; VAR hs, vs: INTEGER);
(* returns screen coordinates (hs, vs) corresponding to window w and window
   coordinates (h, v). *)

PROCEDURE ClearRectangle (w: Window; r: Rectangle);
(* overwrites the rectangle which is clipped to the inner rectangle of w
   with an empty source using the default paint mode of w. *)

PROCEDURE ClearWindow (w: Window);
(* erases the inner rectangle of w irrespective of the setting of the
   default paint mode. *)

PROCEDURE RefreshWindow (w: Window);
(* redraws the visible portion of w. If saveWindow is not set the contents
   of w is redrawn by calling the refresh procedure. *)

PROCEDURE MoveRectangle (from, to: Window; r: Rectangle;
                         left, top: INTEGER);
(* copy all information contained in the rectangle r (in window coordinates)
   in window from to the destination in window to given by left, top (in
   window coordinates). If necessary, r is clipped to the inner rectangle
   of from and then only the clipped rectangle is moved. The moved rectangle
   is clipped to the inner rectangle of to. If saveWindow is not set for
   window from, this may result in a call of the update procedure for
   the clipped source rectangle. *)

PROCEDURE CreateBitmap (external: ExternalBitmap; VAR bm: Bitmap;
                        VAR result: SIResult);
(* converts an external to an internal bitmap representation. result will
   be different from SIDone if not enough memory is available. *)

PROCEDURE GetExternalBitmap (bm: Bitmap; VAR external: ExternalBitmap;
                             VAR result: SIResult);
(* converts an internal to an external bitmap representation. result will
   be different from SIDone if not enough memory is available. The pixel
   storage of the external bitmap will be allocated by this call and
   should be returned (using SISets.ReturnSet) when it is no longer
   needed. *)

PROCEDURE DisposeBitmap (VAR bm: Bitmap);
(* destroys the internal bitmap and deallocates its resources. bm is set to
   an invalid value. *)

PROCEDURE BitmapToWindow (w: Window; bm: Bitmap; left, top: INTEGER);
(* copies bm to rectangle with upper left corner at (left, top). bm is
   clipped to the inner rectangle of w. *)

PROCEDURE WindowToBitmap (w: Window; source: Rectangle;
                          VAR bm: Bitmap; VAR result : SIResult);
(* source is in window coordinates and clipped to the inner rectangle of w,
   and the contents of this clipped rectangle is copied into bm. result
   will be different from SIDone if not enough memory is available. 
   This procedure may call the update procedure if the attribute saveWindow
   is not set for the window. *)

PROCEDURE BitmapStorage (bm: Bitmap): CARDINAL;
(* this value is the number of bytes required to store the bitmap bm
   when using BitmapToBytes. *)

PROCEDURE BitmapToBytes (bm: Bitmap; VAR bytes: ARRAY OF BYTE;
                         startIndex: CARDINAL; VAR result: SIResult);
(* stores the bitmap bm into the buffer bytes beginning at startIndex.
   result is different from SIDone if the bitmap is invalid or
   if it does not fit into the buffer. The storage required is
   BitmapStorage (bm) bytes. *)

PROCEDURE BytesToBitmap (VAR bm: Bitmap; VAR bytes: ARRAY OF BYTE;
                         startIndex: CARDINAL; VAR result: SIResult);
(* creates a new bitmap equal to the one that was previously stored
   in the buffer bytes starting at startIndex (the data may have
   been copied around, and the buffer need not be the same as was
   used for BitmapToBytes. Only the data needs to be the same).
   If these conditions are observed and enough storage is available,
   result will be SIDone, it will be something else otherwise.
   Notice the bitmap bm will be created by this call, so if it
   is a preexisting bitmap some storage will become inaccessible. *)

PROCEDURE ForEachWindowDo (execute: WindowProcedure);
(* calls execute once for each window. First it calls execute for all
   windows which are not closed and not hidden in bottom-to-top order,
   then it calls execute for the remaining closed and hidden windows.
   This procedure may be used to refresh all windows, to get all defined
   windows, etc. *)


END SIWindows.