{Begin SubSec Display Streams}
{Title Display Streams}
{Text

Streams are used as the basis for all I/O operations.  Files are implemented as streams that can support character printing and reading operations, and file pointer manipulation.  Display streams are a type of stream that also provides an interface for translation, clipping, and figure generation on bitmaps.  All of the operations that can applied to streams can be applied to display streams.  For example, a display stream can be passed as the argument to {fn PRINT}, to print something on the bitmap of a display stream.  In addition, special functions are provided to draw lines and curves and perform other graphical operations on display streams.  Calling these functions on a stream that is not a display stream will generate an error.

Windows are closely related to display streams and can be thought of as a type of display stream.  (In the near future, windows will be a type of display stream.)  All of the functions that operate on display streams also accept windows.    


Display streams can be created with the following function:

{FnDef {Name DSPCREATE} {Args DESTINATION}
{Text
Returns a display stream, with initial settings as indicated below.  If {arg DESTINATION} is specified, it is used as the destination bitmap, otherwise the screen bitmap is used.
}}


Each window has an associated display stream.  To get the window of a particular display stream, use:

{FnDef {Name WFROMDS} {Args DISPLAYSTREAM DONTCREATE} 
{Text
Returns the window associated with {arg DISPLAYSTREAM}, creating a window if one does not exist (and {arg DONTCREATE} is {lisp NIL}).  Returns {lisp NIL} if the destination of {arg DISPLAYSTREAM} is not a screen bitmap that supports a window system.

If {arg DONTCREATE} is non-{lisp NIL}, {fn WFROMDS} will never create a window, and returns {lisp NIL} if {arg DISPLAYSTREAM} does not have an associated window.

{fn TTYDISPLAYSTREAM} calls {fn WFROMDS} with {arg DONTCREATE} = {lisp T}, so it will not create a window unnecessarily.  Also, if {fn WFROMDS} does create a window, it calls {fn CREATEW} with {arg NOOPENFLG} = {lisp T}.  This reduces the number of empty windows that appear.
}}


{Begin SubSec Manipulating Display Streams}
{Title Manipulating Display Streams}
{Text

The following functions manipulate the fields of a display stream (they may also be given a window, in which case the associated display stream is used).  These functions return the old value (the one being replaced).  A value of {lisp NIL} for the new value will return the current setting without changing it.  These functions do not change any of the bits in the display stream's destination bitmap; just the effect of future operations done through the display stream.


Warning:  The window system maintains the Destination, XOffset, YOffset, and ClippingRegion fields of each window's display stream, adjusting them during window operations.  Users should be very careful about changing these fields in a window's display stream (with {fn DSPDESTINATION}, {fn DSPXOFFSET}, {fn DSPYOFFSET}, or {fn DSPCLIPPINGREGION}).


{FnDef {Name DSPDESTINATION} {Args DESTINATION DISPLAYSTREAM} {Text
Destination:  The bitmap that the display stream modifies.  This can be either the screen bitmap, or an auxilliary bitmap in order to construct figures, possibly save them, and then display them in a single operation.  Initially the screen bitmap.
}}

{FnDef {Name DSPXOFFSET} {Args XOFFSET DISPLAYSTREAM}}
{FnDef {Name DSPYOFFSET} {Args YOFFSET DISPLAYSTREAM}
{Text
XOffset:  The X origin of the display stream's coordinate system in the destination bitmap's coordinate system.  Initially 0 (no X-coordinate translation).

YOffset:  The Y origin of the display stream's coordinate system in the destination bitmap's coordinate system.  Initially 0 (no Y-coordinate translation).

Display streams have their own coordinate system.  Having the coordinate system local to the display stream allows objects to be displayed at different places by translating the display stream's coordinate system relative to its destination bitmap.
}}

{FnDef {Name DSPCLIPPINGREGION} {Args REGION DISPLAYSTREAM}
{Text
ClippingRegion:  A region that limits the extent of characters printed and lines drawn (in the display stream's coordinate system).  Initially set so that no clipping occurs.
}}



{FnDef {Name DSPXPOSITION} {Args XPOSITION DISPLAYSTREAM}}
{FnDef {Name DSPYPOSITION} {Args YPOSITION DISPLAYSTREAM}
{Text
XPosition:  The current X position.  Initially 0.

YPosition:  The current Y position.  Initially 0.

{fn DSPXPOSITION} and {fn DSPYPOSITION} specify the "current position" of the display stream, the position (in the display stream's coordinate system) where the next printing operation will start from.  The functions which print characters or draw on a display stream update these values appropriately.
}}

{FnDef {Name DSPTEXTURE} {Args TEXTURE DISPLAYSTREAM}
{Text
Texture:  A texture that is the background pattern used for the display stream.  Initially the value of {var WHITESHADE}.
}}

{FnDef {Name DSPFONT} {Args FONT DISPLAYSTREAM}
{Text
Font:  A Font Descriptor that specifies the font used when printing characters to the display stream.  Initially Gacha 10.

Note:  {fn DSPFONT} determines its new font descriptor from {arg FONT} by the same coercion rules that {fn FONTPROP} and {fn FONTCOPY} use, with one additional possibility: If {arg FONT} is a list of the form
{lisp ({arg PROP{sub 1}} {arg VAL{sub 1}} {arg PROP{sub 2}} {arg VAL{sub 2}} {ellipsis})}
where {arg PROP{sub 1}} is acceptable as a font-property to {fn FONTCOPY}, then the new font is obtained by
{lisp ({fn FONTCOPY} ({fn DSPFONT}  NIL DISPLAYSTREAM)
{arg  PROP{sub 1}} {arg VAL{sub 1}} {arg  PROP{sub 2}} {arg VAL{sub
2}} {ellipsis})}.
}}

{FnDef {Name DSPLEFTMARGIN} {Args XPOSITION DISPLAYSTREAM}
{Text
LeftMargin:  An integer that is the X position after an end-of-line (in the display stream's coordinate system) - initially 0.
}}

{FnDef {Name DSPRIGHTMARGIN} {Args XPOSITION DISPLAYSTREAM}
{Text
RightMargin:  An integer that is the maximum X position that characters will be printed by {lisp PRIN1} - initially the value is the right edge of the window.
}}


The line length of a window or image stream (as returned by {fn LINELENGTH}, {PageRef Fn LINELENGTH}) is computed by dividing the distance between the left and right margins by the width of an uppercase "A" in the current font.  The line length is changed whenever the Font, LeftMargin, or RightMargin are changed or whenever the window is reshaped.


{FnDef {Name DSPSOURCETYPE} {Args SOURCETYPE DISPLAYSTREAM}
{Text
SourceType:  The {fn BITBLT} sourcetype used when printing characters to the display stream.  Must be either {lisp INPUT} or {lisp INVERT}.  Initially {lisp INPUT}.
}}


{FnDef {Name DSPOPERATION} {Args OPERATION DISPLAYSTREAM}
{Text
Operation:  The default {lisp BITBLT} operation ({lisp REPLACE}, {lisp PAINT}, {lisp INVERT}, or {lisp ERASE}) used when printing or drawing on the display stream.  Initially {lisp REPLACE}.
}}


{FnDef {Name DSPLINEFEED} {Args DELTAY DISPLAYSTREAM}
{Text
LineFeed:  An integer that specifies the Y increment for each linefeed, normally negative.  Initially minus the height of the initial font (Gacha 10).
}}


{FnDef {Name DSPSCROLL} {Args SWITCHSETTING DISPLAYSTREAM}
{Text
Scroll:  A flag that determines the scrolling behavior of the display stream; either {lisp ON} or {lisp OFF}.  If {lisp ON}, the bits in the display streams's destination are moved after any linefeed that moves the current position out of the destination bitmap. Any bits moved out of the current clipping region are lost.  Does not adjust the XOffset, YOffset, or ClippingRegion fields.  Initially {lisp OFF}.  (Note:  if {arg SWITCHSETTING} is {lisp NIL}, the Scroll field is {it not} changed, and the previous value is returned.)
}}


}{End SubSec Manipulating Display Streams}


{Begin SubSec Drawing on Windows and Display Streams}
{Title Drawing on Windows and Display Streams}
{Text


{FnDef {Name DSPFILL} {Args REGION TEXTURE OPERATION DISPLAYSTREAM}
{Text
Fills {arg REGION} of the destination bitmap (within the clipping region) with {arg TEXTURE} (a pattern of bits).  If {arg REGION} is {lisp NIL}, the whole destination (within the clipping region) is used.  If {arg TEXTURE} or {arg OPERATION} are {lisp NIL}, the values from {arg DISPLAYSTREAM} are used.
}}


{FnDef {Name FILLCIRCLE} {Args X Y RADIUS TEXTURE DISPLAYSTREAM}
{Text
Fills in a circular area of radius {arg RADIUS} about the point ({arg X},{arg Y}) in the destination bitmap of {arg DISPLAYSTREAM} with {arg TEXTURE}.  {arg DISPLAYSTREAM}'s position is left at ({arg X},{arg Y}).

{note can't specify OPERATION??}
}}



{FnDef {Name DSPRESET} {Args DISPLAYSTREAM}
{Text
Sets the X position of {arg DISPLAYSTREAM} to its left margin, sets its Y position to the top of the clipping region minus the font ascent, and fills its destination bitmap with its background Texture.
}}


{FnDef {Name MOVETO} {Args X Y DISPLAYSTREAM}
{Text
Changes the current position of {arg DISPLAYSTREAM} to the point {lisp ({arg X},{arg Y})}.
}}


{FnDef {Name RELMOVETO} {Args DX DY DISPLAYSTREAM}
{Text
Changes the current position to the point {lisp ({arg DX},{arg DY})}
coordinates away from current position of {arg DISPLAYSTREAM}.
}}


{FnDef {Name MOVETOUPPERLEFT} {Args IMAGESTREAM REGION}
{Text
Moves the current position to the beginning position of the top line of text.  If {arg REGION} is non-{lisp NIL}, it must be a {lisp REGION} and the X position is changed to the left edge of {arg REGION} and the Y position changed to the top of {arg REGION} less the font ascent of {arg IMAGESTREAM}.  If {arg REGION} is {lisp NIL}, the X position is changed to the left margin of {arg IMAGESTREAM} and the Y position is changed to the top of the clipping region of {arg IMAGESTREAM} less the font ascent of {arg IMAGESTREAM}.
}}


{FnDef {Name DSPBACKUP} {Args WIDTH DISPLAYSTREAM}
{Text
Backs up {arg DISPLAYSTREAM} over a character which is {arg WIDTH} screen points wide.  {fn DSPBACKUP} fills the backed over area with the display stream's background texture and decreases the X position by {arg WIDTH}.  If this would put the X position less than {arg DISPLAYSTREAM}'s left margin, its operation is stopped at the left margin.  It returns {lisp T} if any bits were written, {lisp NIL} otherwise.
}}


{FnDef {Name CENTERPRINTINREGION} {Args EXP REGION DISPLAYSTREAM} 
{Text
Prints {arg EXP} so that is it centered within {arg REGION} of the {arg DISPLAYSTREAM}.  If {arg REGION} is {lisp NIL}, {arg EXP} will be centered in the clipping region of {arg DISPLAYSTREAM}.
}}


}{End SubSec Drawing on Windows and Display Streams}



{Begin SubSec Drawing Lines and Curves}
{Title Drawing Lines and Curves}
{Text

Interlisp-D provides several functions for drawing lines and curves onto the destination bitmap of a display stream or window.  The curve drawing functions take their {fn BITBLT} operation from the display stream, while for straight lines the Operation may be specified as an argument to the drawing function, with the display stream's operation only being used by default.

The following functions produce straight lines of the specified width (in screen points; the default is 1) in the display stream's destination bitmap.  They do not allow "brush" patterns; however, they do support {lisp INVERT} mode inwhich redrawing a line will erase it.  These functions are intended for interactive applications where efficiency is important.  {fn DRAWCURVE} can be used to draw lines with brushes.


{FnDef {Name DRAWTO} {Args X Y WIDTH OPERATION DISPLAYSTREAM COLOR}
{Text
Draws a line from the current position to the point {lisp ({arg X},{arg Y})} onto the destination bitmap of {arg DISPLAYSTREAM}.  The position of {arg DISPLAYSTREAM} is set to {lisp ({arg X},{arg Y})}.

If the destination bitmap has multiple bits per pixel, {arg COLOR} is a color specification that determines the color used to draw the line (See {PageRef Tag ColorSpecifications}).  If {arg COLOR} is {lisp NIL}, this will be the {fn DSPCOLOR} of {arg DISPLAYSTREAM}.
}}



{FnDef {Name RELDRAWTO} {Args DX DY WIDTH OPERATION DISPLAYSTREAM COLOR}
{Text
Draws a line from the current position to the point {lisp ({arg DX},{arg DY})} coordinates away onto the destination bitmap of {arg DISPLAYSTREAM}.  The position of {arg DISPLAYSTREAM} is set to the end of the line.
If {arg DX} and {arg DY} are both 0, nothing is drawn.
}}


{FnDef {Name DRAWLINE} {Args X{sub 1} Y{sub 1} X{sub 2} Y{sub 2} WIDTH OPERATION DISPLAYSTREAM COLOR}
{Text
Draws a line from the point {lisp ({arg X{sub 1}},{arg Y{sub 1}})} to the point {lisp ({arg X{sub 2}},{arg Y{sub 2}})} onto the destination bitmap of {arg DISPLAYSTREAM}.  The position of {arg DISPLAYSTREAM} is set to {lisp ({arg X{sub 2}},{arg Y{sub 2}})}.
If {arg X{sub 1}} equals {arg X{sub 2}} and {arg Y{sub 1}} equals {arg Y{sub 2}}, a point is drawn at {lisp ({arg X{sub 1}},{arg Y{sub 1}})}.
}}


{FnDef {Name DRAWBETWEEN}
{Args POSITION{sub 1} POSITION{sub 2} WIDTH OPERATION DISPLAYSTREAM COLOR}
{Text
Draws a line from the point {arg POSITION{sub 1}} to the point {arg POSITION{sub 2}} onto the destination bitmap of {arg DISPLAYSTREAM}.  The position of {arg DISPLAYSTREAM} is set to {arg POSITION{sub 2}}.
}}



{index brush Term}

A curve is drawn by placing a brush pattern centered at each point along the curve's trajectory.  A brush pattern is defined by its shape, size, and color.  The predefined brushes are {lisp ROUND}, {lisp SQUARE}, {lisp HORIZONTAL}, {lisp VERTICAL}, and {lisp DIAGONAL}; new brushes can be created using the {fn INSTALLBRUSH} function, described below.  A brush size is an integer specifying the width of the brush in screen points.  The color is a color specification (see {PageRef Tag ColorSpecifications}), which is only used if the curve is drawn on a multiple bits per pixel bitmap.

A brush is specified to the various drawing functions as a shape-width-color list (such as {lisp (SQUARE 2)} or {lisp (VERTICAL 4 RED)}).  A brush can also be specified as a positive integer, which is interpreted as a {lisp ROUND} brush of that width.  Finally, if a brush is specified as {lisp NIL}, a {lisp (ROUND 1)} brush is used as default.

If a brush is a litatom, it is assumed to be a function which is called at each point of the curve's trajectory with three arguments: the X-coordinate or the point, the Y-coordinate, and the display stream.

The appearance of a curve is also determined by its {term dashing} characteristics.  Dashing is specified by a list of positive integers.  If a curve is dashed, the brush is placed along the trajectory for the number of points indicated by the first element of the dashing list.  The brush is {it off}, not placed in the bitmap, for a number of points indicated by the second element.  The third element indicates how long it will be on again, and so forth.  The dashing sequence is repeated from the beginning when the list is exhausted.  A curve or line is not dashed if the dashing argument to the drawing function is {lisp NIL}.

The curve functions use the display stream's clipping region and operation.  Most types of image streams only support the {lisp PAINT} operation when drawing curves.  When drawing to the display, the curve-drawing functions accept the operation {lisp INVERT} if the brush argument is 1.  For brushes larger than 1, these functions will use the {lisp ERASE} operation instead of {lisp INVERT}.  For the display, the curve-drawing functions treat the {lisp REPLACE} operation the same as {lisp PAINT}.

{FnDef {Name INSTALLBRUSH} {Args BRUSHNAME BRUSHFN BRUSHARRAY}
{Text
Installs a new brush called {arg BRUSHNAME} with creation-function {arg BRUSHFN} and optional array {arg BRUSHARRAY}.  {arg BRUSHFN} will be called to create new instances of {arg BRUSHNAME}-type brushes; the sixteen smallest instances will be pre-computed and cached.  "Hand-crafted" brushes can be supplied as the {arg BRUSHARRAY} argument.  Changing an existing brush can be done by calling {fn INSTALLBRUSH} with new {arg BRUSHFN} and/or {arg BRUSHARRAY}.
}}

{FnDef {Name DRAWCURVE} {Args KNOTS CLOSED BRUSH DASHING DISPLAYSTREAM}
{Text
Draws a spline curve.  {arg KNOTS} is a list of positions to which the spline will be fitted.  {arg CLOSED} is a flag which indicates whether or not the spline is to be closed. The other arguments are interpreted as described above.

{note should include a short description of spline curves}
}}


{FnDef {Name DRAWCIRCLE} {Args X Y RADIUS BRUSH DASHING DISPLAYSTREAM}
{Text
Draws a circle of radius {arg RADIUS} about the point {lisp ({arg X},{arg Y})} onto the destination bitmap of {arg DISPLAYSTREAM}.
{arg DISPLAYSTREAM}'s position is left at {lisp ({arg X},{arg Y})}.
(Dashing may not be implemented for this function yet.) The other arguments are interpreted as described above.
}}


{FnDef {Name DRAWELLIPSE} {Args X Y SEMIMINORRADIUS SEMIMAJORRADIUS ORIENTATION BRUSH DASHING DISPLAYSTREAM}
{Text
Draws an ellipse with a minor radius of {arg SEMIMINORRADIUS} and a major radius of {arg SEMIMAJORRADIUS} about the point {lisp ({arg X},{arg Y})} onto the destination bitmap of {arg DISPLAYSTREAM}.
{arg ORIENTATION} is the angle of the major axis in degrees, positive in the counterclockwise direction.
{arg DISPLAYSTREAM}'s position is left at {lisp ({arg X},{arg Y})}.
(Dashing may not be implemented for this function yet.) The other arguments are interpreted as described above.
}}




}{End SubSec Drawing Lines and Curves}



}{End SubSec Display Streams}




{Begin SubSec Typescript Facilities: The "T" File}
{Title Typescript Facilities: The "T" File}
{Text

Output to the file {lisp T} and echoing of type-in is directed to a distinguished
terminal display stream.  This is initialized to be a display stream at the top of the screen, but that initial setting can be modified by the function {fn TTYDISPLAYSTREAM}.


{FnDef {Name TTYDISPLAYSTREAM} {Args DISPLAYSTREAM}
{Text
Selects the display stream or window {arg DISPLAYSTREAM} to be the terminal output channel, and returns the previous terminal output display stream.  {fn TTYDISPLAYSTREAM} puts {arg DISPLAYSTREAM} into scrolling mode and calls {fn PAGEHEIGHT} with the number of lines that will fit into {arg DISPLAYSTREAM} given its current Font and ClippingRegion.{note why?  -- lmm}  The linelength of {fn TTYDISPLAYSTREAM} is computed (like any other display stream) from its LeftMargin, RightMargin, and Font.  If one of these fields is changed, its linelength is recalculated.  If one of the fields used to compute the number of lines (such as the ClippingRegion or Font) changes, {lisp PAGEHEIGHT} is not automatically recomputed.  {lisp (TTYDISPLAYSTREAM (TTYDISPLAYSTREAM))} will cause it to be recomputed.

If the window system is active, the line buffer is saved in the old {lisp TTY} window, and the line buffer is set to the one saved in the window of the new display stream, or to a newly created line buffer (if it does not have one).  Caution:  It is possible to move the {fn TTYDISPLAYSTREAM} to a nonvisible display stream or to a window whose current position is not in its clipping region.
}}




{FnDef {Name PAGEHEIGHT} {Args N}
{Text
If {arg N} is greater than 0, it is the number of lines of output that will be printed to {lisp TTYDISPLAYSTREAM} before the page is held.{index page holding}  A page is held before the {arg N}+1 line is printed to {lisp TTYDISPLAYSTREAM} without intervening input if there is no terminal input waiting to be read.  The output is held with the screen video reversed until a character is typed.  Output holding is disabled if {arg N} is 0.  {fn PAGEHEIGHT} returns the previous setting.
}}

{note put FULLPAGEFN here?}

}{End SubSec Typescript Facilities: The "T" File}



{Begin SubSec Carets}
{Title Carets}
{Text

The window system uses a flashing caret to indicate the position of the next window typeout.  There is only one caret visible at any one time.  The caret in the current process is always visible; if it is hidden by another window, its window is brought to the top.  An exception to this rule is that the flashing caret's window is not brought to the top if the user is buttoning or has a shift key down.  This prevents the destination window (which has the tty and caret flashing) from interfering with the window one is trying to select text to copy from.

{FnDef {Name CARET} {Args NEWCARET}
{Text
Sets the shape that blinks at the location of the next output to the current process.  {arg NEWCARET} is either (1) {lisp NIL} - no changes, returns a {lisp CURSOR}{note ptr to CURSORs?} representing the current caret, (2) {lisp OFF} - turns the caret off, (3) a {lisp CURSOR} which gives the new caret shape or (4) {lisp T} - reset the caret to the value of {var DEFAULTCARET}.{index DEFAULTCARET Var}  {var DEFAULTCARET} can be set to change the initial caret for new processes.  The hotspot of {arg NEWCARET} indicates which point in the new caret bitmap should be located at the current output position.  The previous caret is returned.  Note: the bitmap for the caret is not limited to the dimensions {var CURSORWIDTH} by {var CURSORHEIGHT}.
}}


{FnDef {Name CARETRATE} {Args ONRATE OFFRATE}
{Text
Sets the rate at which the caret for the current process will flash.  The caret will be visible for {ARG ONRATE} milliseconds, then not visible for {arg OFFRATE} milliseconds.   If {arg OFFRATE} is {lisp NIL} then it is set to be the same as {arg ONRATE}.  If {arg ONRATE} is {lisp T}, both the "on" and "off" times are set to the value of the variable {var DEFAULTCARETRATE}{index DEFAULTCARETRATE Var} (initially 333).  The previous value of {fn CARETRATE} is returned.  If the caret is off, {fn CARETRATE} return NIL.
}}

}{End SubSec Carets}