DEFINITION MODULE GKSDev;

(*
    Title: 	Graphical Kernel System Workstation Interface
    LastEdit:	"Tue Feb 26 11:15:21 1985"
    Author: 	jd
		Cambridge University Computer Laboratory
*)

FROM Vector IMPORT RVEC, RBOX;

FROM GKSTypes IMPORT
    SEGMENT, PRIMITIVE, TRANSFORM,
    PATH, PRECISION, PIXELS, ESCAPECODE, GDPCODE;

FROM SYSTEM IMPORT 
    WORD;

EXPORT QUALIFIED
    OpenDev, CloseDev, ActivateDev, DeactivateDev, ClearDev, UpdateDev,
    SetDevLine, SetDevMarker, SetDevText, SetDevArea, SetDevPattern,
    SetDevColour, SetDevChar, SetDevPatternRef,
    DevLine, DevMarker, DevFill, DevText, DevPixels, DevGdp,
    DevEscape, DevMessage,
    ReDrawDev, SegAdd, SegDelete, SegPrimChange,
    SegTransform, SegVisible, SegLit, SegPriority;


        (********** General **********)

PROCEDURE OpenDev (device: ARRAY OF CHAR;
        VAR DisplaySurface, PixelSurface: RBOX;
        VAR Defer, ImplicitReDraw: BOOLEAN);

        (* Connect yourself to some device and return the following:
            1) the viewing surface measured in meters. The lowerleft
               corner of this should be the point (0.0, 0.0)
            2) the viewing surface measured in pixels. This box
               defines a transformation which will be applied to every point
               before it reaches you, so specify the coordinates which are 
               most convenient.
            3) the initial deferral state. If TRUE, picture changes can be
               deferred by GKS until the next Update.
            4) the initial redraw state. If TRUE, GKS can redraw the picture
               on its own initiative if necessary.
         *)

PROCEDURE CloseDev;
        (* shut down the device *)

PROCEDURE ActivateDev;
        (* you will probably be called upon to draw shortly *)

PROCEDURE DeactivateDev;
        (* you will not be needed for a while; put away pens which could dry
           out, for example
        *)

PROCEDURE ClearDev (obligatory: BOOLEAN);
        (* IF NOT obligatory THEN the device need not be cleared if it is
           believed already to be so.
        *)

PROCEDURE UpdateDev ();
        (* Push out any buffered commands to the device *)


        (********** Selection of Current Primitive Attributes **********)


(* Provide the closest possible representation of these attributes *)

PROCEDURE SetDevLine (style: CARDINAL; width: REAL);
        (* find out what kind of line is wanted from LineStyle (style).
           width is a multiplier for your nominal line width.
        *)

PROCEDURE SetDevMarker (style: CARDINAL; size: REAL);
        (* find out what kind of marker from MarkerStyle (style).
           size is a multiplier for your nominal marker size.
        *)

PROCEDURE SetDevText (font: CARDINAL; precision: PRECISION): REAL;
        (* font 1 is defined to be able to represent the character set
           ISO 646, whatever that is. Otherwise it's up to you. Precision
           is an indication of the accuracy with which the characters should
           be placed. You must return the width/height ratio of the font
           so that GKS can calculate accurate character spacing.
        *)

PROCEDURE SetDevArea (style, pattern: CARDINAL);
        (* style may be an index into AREASTYLE. Pattern should be ignored
           if the style is hollow or solid.
        *)

PROCEDURE SetDevPattern (pixels: PIXELS);

PROCEDURE SetDevColour (red, green, blue: REAL);

PROCEDURE SetDevChar (slant, rotation, height, width: REAL;
        VAR space: RVEC; abut: BOOLEAN);
        (* slant and rotation are counterclockwise angles in degrees, and
           may be positive or negative.
           slant is the angle of the character vertical from its baseline,
               and is usually 90.0.
           rotation is the angle of the character baseline from the
               horizontal, and is usually 0.0.
           height and width are the desired font height and width in device
               coordinates. They are adjustments of the values you gave to 
               SetDevText on the last call.
           space is a vector which can be used to move between characters.
               When added to the position of one character (as defined by its
               its lower left corner), it gives the position of the
               next character to be written.
           abut is TRUE if the lower right corner of one character is 
               coincident with the lower left corner of the next in the
               direction of writing. It can be used to omit explicit
               positioning of adjacent characters, but note that you may be
               being asked to change the size of this font and to write on
               a slanted line. This may lead you to make a more conservative
               estimate of whether characters abut or not.
        *)

PROCEDURE SetDevPatternRef (VAR at, up, base: RVEC);
        (* at is the reference point for the lower left hand corner of the
           pattern; up and base are vectors from the origin which determine
           the enclosing parallelogram of the pattern.
        *)



        (********** Output Functions **********)

(* all point coordinates are in device coordinates *)

PROCEDURE DevLine (high: INTEGER; VAR at: ARRAY OF RVEC);
        (* draw a line connecting at[0], at[1], ..., at[high] *)

PROCEDURE DevMarker (high: INTEGER; VAR at: ARRAY OF RVEC);
        (* draw markers at at[0], at[1], ..., at[high]  *)

PROCEDURE DevText (VAR at: RVEC; VAR in: RBOX; VAR s: ARRAY OF CHAR);
        (* the first character should appear at 'at', and the remainder
           follow along the current character path. Only a substring of the
           text should actually be visible, however; these are the characters
           which lie within the box in. Clipping is optional only in
           PRECISION mode StringPrecision. Try to process escapes in the
           string in the style of BFormatIO, and stop processing it either
           when you hit its upper bound or you see a 0C
        *)

PROCEDURE DevFill (high: INTEGER; VAR boundary: ARRAY OF RVEC);
        (* fill the area defined by the line boundary[0], .. boundary[high] *)

PROCEDURE DevPixels (VAR boundary: ARRAY OF RVEC; VAR ClipTo: RBOX;
        rowhigh, columnhigh: INTEGER; VAR pixels: ARRAY OF CARDINAL);
        (* boundary started out as a box, but may have been transformed
           into a parallelogram by now. Divide it into
           (rowhigh+1)*(columnhigh) pixels and display the appropriate colour.
           Only pixels lying within ClipTo should be displayed.
        *)

PROCEDURE DevGdp (function: GDPCODE; arg: WORD;
        high: INTEGER; VAR points: ARRAY OF RVEC; ClipTo: RBOX);
        (* 'Generalized Drawing Primitive', an escape graphics function
           provided to call non-standard workstation drawing functions.
           Only the display surface inside ClipTo may be altered.
        *)

PROCEDURE DevEscape (function: ESCAPECODE; VAR w: WORD; VAR a: ARRAY OF WORD);
        (* another escape function for non-graphics operations *)

PROCEDURE DevMessage (high: INTEGER; VAR s: ARRAY OF CHAR);
        (* Display the text string in any convenient place *)


        (********** Segment Functions **********)

(* These procedures determine the device "intelligence". GKS calls them
   before any change to the display file of the workstation to give the
   device an opportunity of doing the operation itself. Any contextual
   information, such as pen numbers, and the list of segments to be displayed
   may be found by looking at the WS structure pointed at by CurrentWS; this
   is you! 

   Devices may refuse to do the given operation if their hardware is not
   suitable. A result of FALSE will indicate this. GKS will either call the
   drawing primitives directly in the case of an addition to the display file,
   or will clear and redraw in the case of a modification
*)


PROCEDURE ReDrawDev (): BOOLEAN;
        (* An offer to let you redraw the display all on your own *)

PROCEDURE SegAdd (s: SEGMENT): BOOLEAN;
        (* A new one has just been added to your list *)

PROCEDURE SegDelete (s: SEGMENT): BOOLEAN;
        (* This one is about to be removed from your list *)

PROCEDURE SegPrimChange (s: SEGMENT; p: PRIMITIVE; new: BOOLEAN): BOOLEAN;
        (* Called either when
            1) a new primitive is added to the open segment (new = TRUE).
               A reply of FALSE will cause GKS to call the appropriate
               display function.
            2) an existing primitive is modified by a change in the definition
               of one of its attributes. A reply of FALSE will cause clear
               and redraw, either by you (ReDraw), or by GKS otherwise.
        *)

PROCEDURE SegTransform (s: SEGMENT; T: TRANSFORM): BOOLEAN;
        (* GKS is about to update the segment transformation. Can you move
           it without redrawing all other segments?
        *)

PROCEDURE SegVisible (s: SEGMENT; on: BOOLEAN): BOOLEAN;
        (* or make it invisible or invisible? *)

PROCEDURE SegLit (s: SEGMENT; on: BOOLEAN): BOOLEAN;
        (* or highlight the primitives in it? *)

PROCEDURE SegPriority (s: SEGMENT; priority: REAL): BOOLEAN;
        (* or change its display priority? *)

END GKSDev.
