   This file documents the MIT Scheme system.

   Copyright (C) 1988-2002 Massachusetts Institute of Technology

   Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.1 or
any later version published by the Free Software Foundation; with no
Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
Texts.  A copy of the license is included in the section entitled "GNU
Free Documentation License".

Custom Operations on X Graphics Devices
---------------------------------------

   Custom operations are invoked using the procedure
`graphics-operation'.  For example,

     (graphics-operation device 'set-foreground-color "blue")

 - operation on x-graphics-device: set-background-color color-name
 - operation on x-graphics-device: set-foreground-color color-name
 - operation on x-graphics-device: set-border-color color-name
 - operation on x-graphics-device: set-mouse-color color-name
     These operations change the colors associated with a window.
     COLOR-NAME must be a string, which is the X server's name for the
     desired color.  `set-border-color' and `set-mouse-color'
     immediately change the border and mouse-cursor colors.
     `set-background-color' and `set-foreground-color' change the
     colors to be used when drawing, but have no effect on anything
     drawn prior to their invocation.  Because changing the background
     color affects the entire window, we recommend calling
     `graphics-clear' on the window's device afterwards.  Color names
     include both mnemonic names, like `"red"', and intensity names
     specified in the `"#RRGGBB"' notation.

 - operation on x-graphics-device: draw-arc x y radius-x radius-y
          angle-start angle-sweep fill?
     Operation `draw-arc' draws or fills an arc.  An arc is a segment of
     a circle, which may have been stretched along the x- or y- axis to
     form an ellipse.

     The parameters X, Y, RADIUS-X and RADIUS-Y describe the circle and
     ANGLE-START and ANGLE-SWEEP choose which part of the circle is
     drawn.  The arc is drawn on the graphics device with the center of
     the circle at the virtual coordinates given by X and Y.  RADIUS-X
     and RADIUS-Y determine the size of the circle in virtual
     coordinate units.

     The parameter ANGLE-START determines where the arc starts.  It is
     measured in degrees in an anti-clockwise direction, starting at 3
     o'clock.  ANGLE-SWEEP determines how much of the circle is drawn.
     It too is measured anti-clockwise in degrees.  A negative value
     means the measurement is in a clockwise direction.

     Note that the angles are determined on a unit circle before it is
     stretched into an ellipse, so the actual angles that you will see
     on the computer screen depends on all of: RADIUS-X and RADIUS-Y,
     the window size, and the virtual coordinates.

     If FILL? is `#f' then just the segment of the circle is drawn,
     otherwise the arc is filled in a pie-slice fashion.

     This draws a quarter circle pie slice, standing on its point, with
     point at virtual coordinates (3,5):

          (graphics-opereration g 'draw-arc 3 5 .5 .5 45 90 #t)

 - operation on x-graphics-device: draw-circle x y radius
 - operation on x-graphics-device: fill-circle x y radius
     These operations draw a circle (outline) or a filled circle
     (solid) at on the graphics device at the virtual coordinates given
     by X and Y.  These operations could be implemented trivially
     interms of the `draw-arc' operation.

 - operation on x-graphics-device: set-border-width width
 - operation on x-graphics-device: set-internal-border-width width
     These operations change the external and internal border widths of
     a window.  WIDTH must be an exact non-negative integer, specified
     in pixels.  The change takes place immediately.  Note that
     changing the internal border width can cause displayed graphics to
     be garbled; we recommend calling `graphics-clear' on the window's
     device after doing so.

 - operation on x-graphics-device: set-font font-name
     Changes the font used when drawing text in a window.  FONT-NAME
     must be a string that is a font name known to the X server.  This
     operation does not affect text drawn prior to its invocation.

 - operation on x-graphics-device: set-mouse-shape shape-number
     Changes the shape of the mouse cursor.  SHAPE-NUMBER is an exact
     non-negative integer that is used as an index into the mouse-shape
     font; when multiplied by 2 this number corresponds to an index in
     the file
     `/usr/include/X11/cursorfont.h'.

 - operation on x-graphics-device: map-window
 - operation on x-graphics-device: withdraw-window
     These operations control the mapping of windows.  They correspond
     directly to Xlib's `XMapWindow' and `XWithdrawWindow'.

 - operation on x-graphics-device: resize-window width height
     Changes the size of a window.  WIDTH and HEIGHT must be exact
     non-negative integers.  The operation corresponds directly to
     Xlib's `XResizeWindow'.

     This operation resets the virtual coordinate system and the clip
     rectangle.

 - operation on x-graphics-device: move-window x y
     Changes the position of a window on the display.  X and Y must be
     exact integers.  The operation corresponds directly to Xlib's
     `XMoveWindow'.  Note that the coordinates X and Y do not take the
     external border into account, and therefore will not position the
     window as you might like.  The only reliable way to position a
     window is to ask a window manager to do it for you.

 - operation on x-graphics-device: get-default resource property
     This operation corresponds directly to Xlib's `XGetDefault'.
     RESOURCE and PROPERTY must be strings.  The operation returns the
     character string corresponding to the association of RESOURCE and
     PROPERTY; if no such association exists, `#f' is returned.

 - operation on x-graphics-device: copy-area source-x-left source-y-top
          width height destination-x-left destination-y-top
     This operation copies the contents of the rectangle specified by
     SOURCE-X-LEFT, SOURCE-Y-TOP, WIDTH, and HEIGHT to the rectangle of
     the same dimensions at DESTINATION-X-LEFT and DESTINATION-Y-TOP.

 - operation on x-graphics-device: font-structure font-name
     Returns a Scheme equivalent of the X font structure for the font
     named FONT-NAME.  If the string FONT-NAME does not name a font
     known to the X server, or names a 16-bit font, `#f' is returned.

 - procedure: x-font-structure/name font-structure
 - procedure: x-font-structure/direction font-structure
 - procedure: x-font-structure/all-chars-exist font-structure
 - procedure: x-font-structure/default-char font-structure
 - procedure: x-font-structure/min-bounds font-structure
 - procedure: x-font-structure/max-bounds font-structure
 - procedure: x-font-structure/start-index font-structure
 - procedure: x-font-structure/character-bounds font-structure
 - procedure: x-font-structure/max-ascent font-structure
 - procedure: x-font-structure/max-descent font-structure
     These procedures extract the components of the font description
     structure returned by the X graphics operation `font-structure'.  A
     more complete description of these components appears in
     documentation of the `XLoadQueryFont' Xlib call.  `start-index' is
     the index of the first character available in the font.  The
     `min-bounds' and `max-bounds' components are structures of type
     `x-character-bounds', and the `character-bounds' component is a
     vector of the same type.

 - procedure: x-character-bounds/lbearing character-bounds
 - procedure: x-character-bounds/rbearing character-bounds
 - procedure: x-character-bounds/width character-bounds
 - procedure: x-character-bounds/ascent character-bounds
 - procedure: x-character-bounds/descent character-bounds
     These procedures extract components of objects of type
     `x-character-bounds'.  A more complete description of them appears
     in documentation of the
     `XLoadQueryFont' Xlib call.

Win32 Graphics
==============

   MIT Scheme supports graphics on Microsoft Windows 95, Windows 98, and
Windows NT.  In addition to the usual operations, there are operations
to control the size, position and colors of a graphics window.  Win32
devices support images, which are implemented as device independent
bitmaps (DIBs).

   The Win32 graphics device type is implemented as a top level window.
`graphics-enable-buffering' is implemented and gives a 2x to 4x speedup
on many graphics operations.  As a convenience, when buffering is
enabled clicking on the graphics window's title bar effects a
`graphics-flush' operation.  The user has the benefit of the increased
performance and the ability to view the progress in drawing at the
click of a mouse button.

Win32 Graphics Type
-------------------

   Win32 graphics devices are created by specifying the symbol `win32'
as the GRAPHICS-DEVICE-TYPE argument to `make-graphics-device'.  The
Win32 graphics device type is implemented as a top-level window and
supports color drawing in addition to the standard Scheme graphics
operations.

   Graphics devices are opened as follows:

     (make-graphics-device 'win32 #!optional WIDTH HEIGHT PALETTE)

where WIDTH and HEIGHT specify the size, in pixels, of the drawing area
in the graphics window (i.e. excluding the frame).  PALETTE determines
the colors available for drawing in the window.

   When a color is specified for drawing, the nearest color available in
the palette is used.  Permitted values for PALETTE are

`'grayscale'
     The window allocates colors from a grayscale palette of
     approximately 236 shades of gray.

`'grayscale-128'
     The window allocates colors from a grayscale palette of 128 shades
     of gray.

`'standard'
     The standard palette has good selection of colors and grays.

`#f' or `'system'
     The colors available are those in the system palette.  There are
     usually 16 to 20 colors in the system palette and these are
     usually sufficent for simple applications like line drawings and
     x-vs-y graphs of mathematical functions.  Drawing with the system
     palette can be more efficient.

If PALETTE is not specified then the `standard' palette is used.

Custom Operations for Win32 Graphics
------------------------------------

   Custom operations are invoked using the procedure
`graphics-operation'.  For example,

     (graphics-operation device 'set-foreground-color "blue")

 - operation on win32-graphics-device: set-background-color color-name
 - operation on win32-graphics-device: set-foreground-color color-name
     These operations change the colors associated with a window.
     COLOR-NAME must be of one of the valid color specification forms
     listed below.  `set-background-color' and `set-foreground-color'
     change the colors to be used when drawing, but have no effect on
     anything drawn prior to their invocation.  Because changing the
     background color affects the entire window, we recommend calling
     `graphics-clear' on the window's device afterwards.

     The foreground color affects the drawing of text, points, lines,
     ellipses and filled polygons.

     Colors are specified in one of three ways:

    An integer
          This is the Win32 internal RGB value.

    By name
          A limited number of names are understood by the system.
          Names are strings, e.g. `"red"', `"blue"', `"black"'.  More
          names can be registered with the `define-color' operation.

    RGB (Red-Green-Blue) triples
          A triple is either a vector or list of three integers in the
          range 0-255 inclusive which specify the intensity of the red,
          green and blue components of the color.  Thus `#(0 0 0)' is
          black, `(0 0 128)' is dark blue and `#(255 255 255)' is white.

     If the color is not available in the graphics device then the
     nearest available color is used instead.

 - operation on win32-graphics-device: define-color name spec
     Define the string NAME to be the color specified by SPEC.  SPEC
     may be any acceptable color specification.  Note that the color
     names defined this way are available to any Win32 graphics device,
     and the names do _not_ have to be defined for each device.

     Color names defined by this interface may also be used when
     setting the colors of the Scheme console window, or the colors of
     Edwin editor windows.

 - operation on win32-graphics-device: find-color name
     Looks up a color previously defined by `define-color'.  This
     returns the color in its most efficient form for operations
     `set-foreground-color' or `set-background-color'.

 - operation on win32-graphics-device: draw-ellipse left top right
          bottom
     Draw an ellipse.  LEFT, TOP, RIGHT and BOTTOM indicate the
     coordinates of the bounding rectangle of the ellipse.  Circles are
     merely ellipses with equal width and height.  Note that the
     bounding rectangle has horizontal and vertical sides.  Ellipses
     with rotated axes cannot be drawn.  The rectangle applies to the
     center of the line used to draw the ellipse; if the line width has
     been set to greater than 1 then the ellipse will spill outside the
     bounding rectange by half of the line width.

 - operation on win32-graphics-device: fill-polygon points
     Draws a filled polygon using the current foreground color.  POINTS
     is a vector of real numbers.  The numbers are in the order x1 y1
     x2 y2 ... xn yn.  For example,

          (graphics-operation device 'fill-polygon #(0 0 0 1 1 0))

     draws a solid triangular region between the points (0, 0), (0, 1)
     and (1, 0).

 - operation on win32-graphics-device: load-bitmap pathname
     The graphics device contents and size are initialized from the
     windows bitmap file specified by PATHNAME.  If no file type is
     supplied then a `".BMP"' extension is added.  If a clip rectangle
     is in effect when this procedure is called, it is necessary to
     redefine the clip rectangle afterwards.

 - operation on win32-graphics-device: save-bitmap pathname
     The graphics device contents are saved as a bitmap to the file
     specified by PATHNAME.  If no file type is supplied then a `".BMP"'
     extension is added.  The saved bitmap may be incorporated into
     documents or printed.

 - operation on win32-graphics-device: move-window x y
     The graphics device window is moved to the screen position
     specified by X and Y.

 - operation on win32-graphics-device: resize-window width height
     The graphics device window is resized to the specified WIDTH and
     HEIGHT in device coordinates (pixels).  If a clip rectangle is in
     effect when this procedure is called, it is necessary to redefine
     the clip rectangle afterwards.

 - operation on win32-graphics-device: set-line-width width
     This operation sets the line width for future drawing of lines,
     points and ellipses.  It does not affect existing lines and has no
     effect on filled polygons.  The line width is specified in device
     units.  The default and initial value of this parameter is 1 pixel.

 - operation on win32-graphics-device: set-window-name name
     This sets the window title to the string NAME.  The window is
     given the name `"Scheme Graphics"' at creation.

 - operation on win32-graphics-device: set-font handle
     Sets the font for drawing text.  Currently not well supported.  If
     you can get a Win32 font handle it can be used here.

 - operation on win32-graphics-device: copy-area source-x-left
          source-y-top width height destination-x-left destination-y-top
     This operation copies the contents of the rectangle specified by
     SOURCE-X-LEFT, SOURCE-Y-TOP, WIDTH, and HEIGHT to the rectangle of
     the same dimensions at DESTINATION-X-LEFT and DESTINATION-Y-TOP.

OS/2 Graphics
=============

   MIT Scheme supports graphics under the OS/2 Presentation Manager in
OS/2 version 2.1 and later.  The OS/2 graphics device type is
implemented as a top level window.  In addition to the usual operations,
there are operations to control the size, position, and colors of a
graphics window.  OS/2 graphics devices support images, which are
implemented as memory presentation spaces.

   The custom graphics operations defined in this section are invoked
using the procedure `graphics-operation'.  For example,

     (graphics-operation device 'set-foreground-color "blue")

OS/2 Graphics Type
------------------

   OS/2 graphics devices are created by specifying the symbol `os/2' as
the GRAPHICS-DEVICE-TYPE argument to `make-graphics-device'.  The OS/2
graphics device type is implemented as a top-level window and supports
color drawing in addition to the standard Scheme graphics operations.

   Graphics devices are opened as follows:

     (make-graphics-device 'os/2 #!optional WIDTH HEIGHT)

where WIDTH and HEIGHT specify the size, in pixels, of the drawing area
in the graphics window (i.e. excluding the frame).

Color Operations for OS/2 Graphics
----------------------------------

   These operations control the colors used when drawing on an OS/2
graphics device.

 - operation on os2-graphics-device: color?
     This operation returns `#t' if the display supports color.

 - operation on os2-graphics-device: set-background-color color-name
 - operation on os2-graphics-device: set-foreground-color color-name
     These operations change the colors associated with a window.
     COLOR-NAME must be one of the valid color specification forms
     listed below.  `set-background-color' and `set-foreground-color'
     change the colors to be used when drawing, but have no effect on
     anything drawn prior to their invocation.  Because changing the
     background color affects the entire window, we recommend calling
     `graphics-clear' on the window's device afterwards.

     The foreground color affects the drawing of text, points, and
     lines.  Colors are specified in one of these ways:

    An integer between `0' and `#xffffff' inclusive
          This is the OS/2 internal RGB value.

    By name
          A limited number of names are understood by the system.
          Names are strings, e.g. `"red"', `"blue"', `"black"'.  More
          names can be registered with the `define-color' operation.

    RGB (Red-Green-Blue) triples
          A triple is a list of three integers between `0' and `#xff'
          inclusive which specify the intensity of the red, green and
          blue components of the color.  Thus `(0 0 0)' is black, `(0 0
          128)' is dark blue and `(255 255 255)' is white.

     If the color is not available in the graphics device then the
     nearest available color is used instead.

 - operation on os2-graphics-device: define-color name spec
     Define the string NAME to be the color specified by SPEC.  SPEC
     may be any acceptable color specification.  Note that the color
     names defined this way are available to any OS/2 graphics device,
     and the names do _not_ have to be defined for each device.

     Color names defined by this interface may also be used when
     setting the colors of the Scheme console window, or the colors of
     Edwin editor windows.

 - operation on os2-graphics-device: find-color name
     Looks up a color previously defined by `define-color'.  This
     returns the color in its most efficient form for operations
     `set-foreground-color' or `set-background-color'.

Window Operations for OS/2 Graphics
-----------------------------------

   These operations control the window that contains the OS/2 graphics
device.  They provide facilities to change the window's size and
position; to raise and lower the window relative to other windows on the
desktop; to hide or minimize the window, and to restore it from the
hidden or minimized state; to activate or deactivate the window (that
is, control the keyboard focus); and to control the text that appears in
the window's title bar.

 - operation on os2-graphics-device: window-position
     This operation returns the position of the graphics-device window
     on the desktop.  The position is returned as two values (see
     Continuations), which are the x and y coordinates of the
     position.  These coordinates are in units of pels (pixels), and
     measure the distance between the lower left hand corner of the
     desktop and the lower left hand corner of the graphics device
     window's frame.

 - operation on os2-graphics-device: set-window-position x y
     The graphics-device window is moved to the screen position
     specified by X and Y.  The coordinates X and Y are in units of
     pels (pixels), and measure the distance between the lower left hand
     corner of the desktop and the lower left hand corner of the
     graphics device window's frame.

 - operation on os2-graphics-device: window-size
     This operation returns the size of the client area of the
     graphics-device window.  The client area is the part of the window
     that you draw on; it does not include the window frame, title bar,
     etc.  The size is returned as two values (see Continuations),
     which are the width and height of the client area in units of pels
     (pixels).

 - operation on os2-graphics-device: set-window-size width height
     This operation sets the size of the client area of the
     graphics-device window to the specified WIDTH and HEIGHT, which
     are in units of pels (pixels).  The client area is the part of the
     window that you draw on; it does not include the window frame,
     title bar, etc.

 - operation on os2-graphics-device: window-frame-size
     This operation returns the size of the graphics-device window's
     frame.  This includes the client area, as well as the border,
     title bar, etc.  The size is returned as two values (see
     Continuations), which are the width and height of the frame in
     units of pels (pixels).

     The frame size is useful in conjunction with the window position
     and the desktop size to determine relative placement of the window
     or to guarantee that the entire window is visible on the desktop.

 - operation on os2-graphics-device: desktop-size
     This operation returns the size of the OS/2 desktop.  The size is
     returned as two values (see Continuations), which are the
     width and height of the frame in units of pels (pixels).

 - operation on os2-graphics-device: raise-window
     This operation raises the graphics-device window so that it is on
     top of any other windows on the desktop.

 - operation on os2-graphics-device: lower-window
     This operation lowers the graphics-device window so that it is
     below all other windows on the desktop.

 - operation on os2-graphics-device: hide-window
     This operation hides the graphics-device window.  The window
     disappears from the desktop, but still appears in the window list.

 - operation on os2-graphics-device: minimize-window
     This operation minimizes the graphics-device window.  The window
     disappears from the desktop, but still appears in the window list.
     Depending on how you have configured your desktop, the window may
     appear as an icon, either on the desktop or in the minimized
     window viewer.

 - operation on os2-graphics-device: maximize-window
     This operation maximizes the graphics-device window.  This causes
     the window to fill the entire desktop.

 - operation on os2-graphics-device: restore-window
     This operation restores the graphics-device window to its normal
     state.  If the window is hidden or minimized, it is shown again,
     at its former position on the desktop.  If the window is
     maximized, it is returned to its normal size.

 - operation on os2-graphics-device: activate-window
     This operation makes the graphics-device window be the active
     window.  This causes the window to be put in front of all other
     windows on the desktop, highlights its frame, and gives it the
     keyboard focus.

 - operation on os2-graphics-device: deactivate-window
     This operation deactivates the graphics-device window if it was
     active (otherwise it has no effect).  This causes some other
     window to be chosen to be active in its place.

 - operation on os2-graphics-device: set-window-title title
     This operation changes the text that appears in the graphics device
     window's title bar.  The new text is given by TITLE, which must be
     a string.

Event Operations for OS/2 Graphics
----------------------------------

   These operations allow you to read some of the events that are
generated by the Presentation Manager and put in the message queue of a
graphics-device window.

 - operation on os2-graphics-device: read-button
     This operation waits for the user to push a mouse button inside the
     client area of the graphics-device window.  It then returns four
     values (see Continuations) which are: the button number; the x
     and y coordinates of the mouse pointer at the time the button was
     pressed, in pels (pixels) relative to the lower left hand corner
     of the client area; and the graphics device that the mouse pointer
     was over at the time the button was pressed.

     Note that this operation only works when button events are selected
     (which is the default).

 - operation on os2-graphics-device: select-user-events mask
     This operation sets the event-selection mask for the graphics
     device to MASK.  The event-selection mask is an exact non-negative
     integer that specifies which types of incoming events are to be
     saved in the user-event queue for later retrieval by the
     `read-user-event' operation.  The mask is specified by setting the
     bits corresponding to the event types that you are interested in,
     as follows:

          Number  Mask    Description
          ------  -----   -----------
          0       #x001   Button press/release
          1       #x002   Close (close the window) [WM_CLOSE]
          2       #x004   Focus change [WM_SETFOCUS]
          3       #x008   Key press/release [WM_CHAR]
          4       #x010   Paint [WM_PAINT]
          5       #x020   Size change [WM_SIZE]
          6       #x040   Visibility change [WM_SHOW]
          7       #x080   Command [WM_COMMAND]
          8       #x100   Help [WM_HELP]
          9       #x200   Mouse-move [WM_MOUSEMOVE]

     Note that this operation does not affect any events that are
     already in the user-event queue.  Changing the mask only affects
     what events will be added to the queue in the future.

 - operation on os2-graphics-device: read-user-event
     This operation returns the next user event available from the
     user-event queue.  If there are no events in the queue, the
     operation waits for an event to arrive before returning.

   An event is a vector whose first element is the event-type number,
whose second element is the graphics device that the event refers to,
and whose remaining elements provide information about the event.  Here
is a table of the possible event types and their vector layout:

`#(0 DEVICE NUMBER TYPE X Y FLAGS)'
     A button event.  NUMBER is the button number, for example button
     number `0' is usually the left mouse button, `1' is usually the
     right button, etc.  TYPE specifies what occurred: `0' means the
     button was pressed, `1' means the button was released, `2' means
     the button was clicked, and `3' means the button was double
     clicked.  X and Y are the position of the mouse pointer at the
     time of the event, in units of pels (pixels) measured from the
     lower left corner of the client area of the associated window.
     Finally, FLAGS specifies what shift keys were pressed at the time
     of the button event; it is a mask word created by combining zero
     or more of the following flags: `#x08' means the shift key was
     pressed, `#x10' means the control key was pressed, and `#x20'
     means the alt key was pressed.

`#(1 DEVICE)'
     A close event.  The user has selected the close button from the
     system menu, or typed <Alt-f4>.

`#(2 DEVICE GAINED?)'
     A focus event.  If GAINED? is `#t', the keyboard focus is being
     gained, and if GAINED? is `#f', it is being lost.

`#(3 DEVICE CODE FLAGS REPEAT)'
     A keyboard event.  This is much too complicated to describe here.
     See the OS/2 toolkit documentation for details.

`#(4 DEVICE XL XH YL YH)'
     A paint event.  Part of the graphics-device window that was
     obscured has been revealed and the Presentation Manager is
     informing the window that it must repaint that area.  Scheme will
     take care of the painting for you, so this event isn't very useful.

`#(5 DEVICE WIDTH HEIGHT)'
     A size-change event.  The size of the graphics-device window has
     changed, and WIDTH and HEIGHT specify the new size in pels
     (pixels).

`#(6 DEVICE SHOWN?)'
     A visibility event.  Indicates that the graphics-device window has
     been hidden or revealed.  If SHOWN? is `#f', the window is hidden,
     and if it is `#t', the window is shown.

`#(7 DEVICE SOURCE MOUSE?)'
`#(8 DEVICE SOURCE MOUSE?)'
     A menu command.  SOURCE specifies which menu item was selected to
     cause this event, and MOUSE? is a boolean indicating whether the
     item was selected with the mouse or the keyboard.  The event-type
     number `7' indicates a command from a `WM_COMMAND' message, while
     `8' is a command from a `WM_HELP' message.

`#(9 DEVICE X Y HIT-TEST FLAGS)'
     The mouse was moved.  X and Y specify the position of the mouse,
     HIT-TEST contains the hit-test information, and FLAGS specifies
     the modifier keys that were pressed at the time.

 - operation on os2-graphics-device: discard-events
     This operation discards any events that are in the user-event
     queue.  This is sometimes useful when you want to prompt the user
     for some input and don't want to consider any previous input.

Miscellaneous Operations for OS/2 Graphics
------------------------------------------

   These operations allow you to: change the font used for drawing text
in a graphics-device window; take a snapshot of a graphics-device window
and return it as an image object; and draw multiple lines efficiently.

 - operation on os2-graphics-device: set-font font-name
     This operation sets the font used for drawing text in the
     graphics-device window.  FONT-NAME is a string describing the
     font; this string is in the form "<point-size>.<family-name>", for
     example, `"10.Courier"'.  You may specify any fixed-pitch font
     family, in any point size that is supported for that font family.
     This includes both image fonts and outline fonts.

 - operation on os2-graphics-device: capture-image x-left y-bottom
          x-right y-top
     This operation creates and returns an image that contains part of
     the client area of the graphics-device window.  The portion of the
     client area that is selected is specified by the four coordinate
     arguments, which are given in the current virtual coordinates for
     the device.  See Images, for more information about
     manipulating images.

 - operation on os2-graphics-device: draw-lines xv yv
     This operation draws multiple disjoint lines; it is like multiple
     calls to `graphics-draw-line' but much faster.  The arguments XV
     and YV are vectors of coordinates; these vectors must be the same
     length, and the length must be a multiple of two.  The contents of
     the vectors are alternating start/end pairs.  For example, the
     following are equivalent:

          (graphics-draw-line device xs ys xe ye)
          (graphics-operation device 'draw-lines
                              (vector xs xe)
                              (vector ys ye))

Win32 Package Reference
***********************

   The Win32 implementation is still in a state of development.  It is
expected that changes will be necessary when MIT Scheme is ported to
Windows NT on the DEC Alpha architecture.  In particular, the current
system is not arranged in a way that adequately distinguishes between
issues that are a consequence of the NT operating system and those
which are a consequence of the Intel x86 architecture.

Overview
========

   The Win32 implementation is still in a state of development.  It is
expected that changes will be necessary when MIT Scheme is ported to
Windows NT on the DEC Alpha architecture.  In particular, the current
system is not arranged in a way that adequately distinguishes between
issues that are a consequence of the NT operating system and those
which are a consequence of the Intel x86 architecture.

   Thus this documentation is not definitive, it merely outlines how the
current system works.  Parts of the system will change and any project
implemented using the win32 system must plan for a re-implementation
stage.

   The Win32 implementation has several components:

   * Special microcode primitives.

   * A foreign function interface (FFI) for calling procedures in
     dynamically linked libraries (DLLs).

   * An interface for Edwin.

   * The Win32 package provides support for using the features of the
     Windows 3.1 and Windows NT 3.1 environments.

   * Device Independent Bitmap utilities.  These are used by the win32
     Scheme Graphics implementation.  (The Scheme Graphics
     implementation is described in the Reference Manual).

   Note that all the names in the Win32 support are part of the `win32'
package.  The names are bound in the `(win32)' environment, and do not
appear as bindings in the user or root environments.  An effect of this
is that it is far easier to develop Win32 software in the `(win32)'
package environment or a child environment.

Foreign Function Interface
==========================

   The Win32 foreign function interface (FFI) is a primitive and fairly
simple system for calling procedures written in C in a dynamically
linked library (DLL).  Both user's procedures from a custom DLL and
system procedures (e.g. MessageBox) are called using the same mechanism.

   *Warning*: The FFI as it stands has several flaws which make it
difficult to use reliably.  It is expected that both the interface to
and the mechanisms used by the FFI will be changed in the future.  We
provide it, and this documentation, only to give people an early start
in accessing some of the features of Win32 from Scheme.  Should you use
it in an experiment we welcome any feedback.

   The FFI is designed for calling C procedures that use C data types
rather than Scheme data objects.  Thus it is not possible to write and
call a C procedure that returns, for example, a Scheme list.  The object
returned will always be an integer (which may represent the address of a
C data structure).

   *Warning*: It is extremely dangerous to try to pass Scheme callback
procedures to C procedures.  It is only possible by passing integer
`handles' rather than the actual procedures, and even so, if a garbage
collection occurs during the execution of the callback procedure
objects in Scheme's heap will have moved.  Thus in a foreign procedure
that has a callback and a string, after calling the callback the string
value may no longer be valid.  Playing this game requires a profound
knowledge of the implementation.

   The interface to the FFI has two main components: a language for
declaring the types of values passed to and returned from the foreign
procedures and a form for declaring foreign procedures.

Windows Types
-------------

   Foreign types are designed to represent a correspondence between a
Scheme data type that is used to represent an object within the Scheme
world and a C data type that represents the data object in the C world.
Thus we cannot manipulate true C objects in Scheme, nor can we
manipulate Scheme objects in C.

   Each foreign type has four aspects that together ensure that the
correspondence between the Scheme and C objects is maintained.  These
aspects are all encoded as procedures that either check for validity or
convert between representations.  Thus a foreign type is not a
declarative type so much as a procedural description of how to pass the
type.  The underlying foreign procedure call mechanism can pass integers
and vector-like Scheme objects, and returns integer values.  All other
objects must be translated into integers or some other basic type, and
must be recovered from integers.

   The aspects are:

CHECK
     A predicate that returns `#t' if the argument is of an acceptable
     Scheme type, otherwise returns `#f'.  The CHECK procedure is used
     for type-checking.

CONVERT
     A procedure of one argument which returns a Scheme object of one
     of the basic types.  It is used to convert an object into a
     `simpler' object that will eventually be converted into a C object.
     The legal simpler objects are integers and strings.

RETURN-CONVERT
     A procedure of one argument that, given an integer, returns a
     Scheme object of a type satisfying CHECK.  Its purpose is to
     convert the result returned by the foreign procedure into a Scheme
     value.

REVERT
     Some C procedures modify one or more of their arguments.  These
     arguments are passed by reference, i.e. as a pointer to their
     address.  Since a Scheme object might have a different memory
     layout and storage conventions, it must be passed by copy-in and
     copy-out rather than by reference.  REVERT is a procedure of two
     parameters, the original object passed and the result of CONVERT
     on that object.  REVERT may then inspect the converted object and
     copy back the changes to the original.

 - special form: define-windows-type name check convert return revert
 - special form: define-similar-windows-type name model [check [convert
          [return [revert]]]]
     Both forms define a windows type.  The first form defines a type
     in terms of its aspects as described above.  The second defines
     the type as being like another type, except for certain aspects,
     which are redefined.  NAME is the name of the type.  MODEL is the
     name of a type.  CHECK, CONVERT, RETURN and REVERT are procedures
     or the value `#f'.  A `#f' means use the default value, which in
     the second form means use the definition provided for MODEL.  The
     defaults are

    CHECK
          `(lambda (x) #t)', i.e. unchecked.

    CONVERT
          `(lambda (x) x)', i.e. no translation performed.

    RETURN
          `(lambda (x) x)', i.e. no translation performed.

    REVERT
          `(lambda (x y) unspecific)', i.e. no update performed

     The `unchecked' windows type (see below) is defined as:

          (define-windows-type unchecked #f #f #f #f)

     Windows types are _not_ first class values, so they cannot be
     stored in variables or defined using `define':

          (define my-type unchecked)            error-->  Unbound variable
          (define-similar-windows-type my-type unchecked)
                                                ;; the correct way

     Scheme characters must be converted to integers.  This is
     accomplished as follows:

          (define-windows-type char
             char?          ; check
             char->integer  ; convert
             integer->char  ; convert return value
             #f             ; cannot be passed by reference
          )

 - windows type: unchecked
     The type which is not checked and undergoes only the basic
     conversion from a Scheme integer to a C integer or from a Scheme
     string to a C pointer to the first byte of the string.  Returned
     `unchecked' values are returned as integers.

 - windows type: bool
     Scheme booleans are analogous to C integers `0' and `1'.  Windows
     type `bool' have been defined as:

          (define-windows-type bool
             boolean?
             (lambda (x) (if x 1 0))
             (lambda (x) (if (eq? x 0) #f #t))
             #f)

 - windows type: char
     Scheme characters are converted into C objects of type `char',
     which are indistinguishable from small integers.

 - windows type: int
 - windows type: uint
 - windows type: long
 - windows type: ulong
 - windows type: short
 - windows type: ushort
 - windows type: word
 - windows type: byte
     Various integer types that are passed without conversion.

 - windows type: string
     A string that is passed as a C pointer of type `char*' to the first
     character in the string.

 - windows type: char*
     A string or `#f'.  The string is passed as a pointer to characters.
     The string is correctly null-terminated.  `#f' is passed as the
     null pointer.  This is an example where there is a more complex
     mapping between C objects and Scheme objects.  C's `char*' type is
     represented as one of two Scheme types depending on its value.
     This allows us us to distinguish between the C string (pointer)
     that points to the empty sequence of characters and the null
     pointer (which doesnt point anywhere).

 - windows type: handle
 - windows type: hbitmap
 - windows type: hbrush
 - windows type: hcursor
 - windows type: hdc
 - windows type: hicon
 - windows type: hinstance
 - windows type: hmenu
 - windows type: hpalette
 - windows type: hpen
 - windows type: hrgn
 - windows type: hwnd
     Various kinds of Win32 handle.  These names correspond to the
     same, but all uppercase, names in the Windows C language header
     files.  Win32 API calls are the source of values of this type and
     the values are meaningless except as arguments to other Win32 API
     calls.  Currently these values are represented as integers but we
     expect that Win32 handles will in future be represented by
     allocated Scheme objects (e.g. records) that will allow predicates
     (e.g. `hmenu?') and sensible interlocking with the garbage
     collector to free the programmer of the current tedious allocation
     and deallocation of handles.

 - windows type: resource-id
     A Windows resource identifier is either a small integer or a
     string.  In C, this distinction is possible because pointers look
     like larger integers, so a machine word representing a small
     integer can be distinguished from a machine word that is a pointer
     to the text of the name of the resource.

Windows Foreign Procedures
--------------------------

   Foreign procedures are declared as callable entry-points in a module,
usually a dynamically linked library (DLL).

 - procedure: find-module name
     Returns a module suitable for use in creating procedures with
     `windows-procedure'.  NAME is a string which is the name of a DLL
     file.  Internally, `find-module' uses the `LoadLibrary' Win32 API,
     so NAME should conform to the specifications for this call.  NAME
     should be either a full path name of a DLL, or the name of a DLL
     that resides in the same directory as the Scheme binary
     `SCHEME.EXE' or in the system directory.

     The module returned is a description for the DLL, and the DLL need
     not necessarily be linked at or immediately after this call.  DLL
     modules are linked on need and unlinked before Scheme exits and
     when there are no remaining references to entry points after a
     garbage-collection.  This behavior ensures that the Scheme system
     can run when a DLL is absent, provided the DLL is not actually
     used (i.e. no attempt is made to call a procedure in the DLL).

 - variable: gdi32.dll
     This variable is bound to the module describing the `GDI32.DLL'
     library, which contains the Win32 API graphics calls, e.g.
     `LineTo'.

 - variable: kernel32.dll
     This variable is bound to the module describing the `KERNEL32.DLL'
     library.

 - variable: user32.dll
     This variable is bound to the module describing the `USER32.DLL'
     library.  This module contains many useful Win32 API procedures,
     like `MessageBox' and `SetWindowText'.

 - special form: windows-procedure (name (parameter type) ...)
          return-type module entry-name [options]
     This form creates a procedure, and could be thought of as
     "foreign-named-lambda".  The form creates a Scheme procedure that
     calls the C procedure identified by the exported entry point
     ENTRY-NAME in the module identified by the value of MODULE.  Both
     ENTRY-NAME and MODULE are evaluated at procedure creation time, so
     either may be expression.  ENTRY-NAME must evaluate to a string
     and MODULE must evaluate to a module as returned by `find-module'.
     These are the only parts of the form that are evaluated at
     procedure creation time.

     NAME is the name of the procedure and is for documentation
     purposes only.  This form _does not_ define a procedure called
     NAME.  It is more like `lambda'.  The name might be used for
     debugging and pretty-printing.

     A windows procedure has a fixed number of parameters (i.e. no
     `rest' parameters or `varargs'), each of which is named and
     associated with a windows type TYPE.  Both the name PARAMETER and
     the windows type TYPE must be symbols and are not evaluated.  The
     procedure returns a value of the windows type RETURN-TYPE.

     The following example creates a procedure that takes a window
     handle (`hwnd') and a string and returns a boolean (`bool') result.
     The procedure does this by calling the `SetWindowText' entry in the
     module that is the value of the variable `user32.dll'.  The
     variable `set-window-title' is defined to have this procedure as
     it's value.

          (define set-window-title
            (windows-procedure
             (set-window-text (window hwnd) (text string))
             bool user32.dll "SetWindowText"))

          (set-window-title my-win "Hi")
                                   =>  #t
                                   ;; Changes window's title/text

          set-window-title         =>  #[compiled-procedure  ...]
          set-window-text          error-->  Unbound variable

     When there are no OPTIONS the created procedure will (a) check its
     arguments against the types, (b) convert the arguments, (c) call
     the C procedure and (d) convert the returned value.  No reversion
     is performed, even if one of the TYPES has a reversion defined.
     (Reverted types are rare [I have never used one], so paying a cost
     for this unless it is used seems silly).

     The following options are allowed:

    `with-reversions'
          The reversions are included in the type conversions.

    `expand'
          A synonym for `with-reversions'.

    SCHEME CODE
          The SCHEME CODE is placed between steps (a) and (b) in the
          default process.  The Scheme code can enforce constraints on
          the arguments, including constraints between arguments such
          as checking that an index refers to a valid position in a
          string.

     If both options (i.e. `with-reversions' and Scheme code) are used,
     `with-reversions' must appear first.  There can be arbitrarily many
     Scheme expression.