@iftex
@finalout
@end iftex
-@comment $Id: scheme.texinfo,v 1.39 1993/11/22 22:45:08 nick Exp $
+@comment $Id: scheme.texinfo,v 1.40 1993/12/05 16:17:38 adams Exp $
@comment %**start of header (This is for running Texinfo on a region.)
@setfilename scheme
@settitle MIT Scheme Reference
* File-System Interface::
* Error System::
* Graphics::
+* Win32 Package Reference::
* Index::
--- The Detailed Node Listing ---
* X Graphics Type::
* Utilities for X Graphics::
* Custom Operations on X Graphics Devices::
+
+Win32 Package Reference
+
+* Win32 Package Overview::
+* Foreign function interface::
+* Device Independent Bitmap Utilities::
+
+Foreign Function Interface
+
+* Windows Types::
+* Windows Foreign Procedures::
+* Win32 API names and procedures::
+
+Device Independent Bitmap Utilities
+
+* DIB procedures::
+* Other parts of the DIB Utilities implementation::
@end menu
@node Acknowledgements, Overview, Top, Top
files.
@end defvr
-@node Graphics, Index, Error System, Top
+@node Graphics, Win32 Package Reference, Error System, Top
@chapter Graphics
@cindex graphics
They have no effect on text drawn prior to their invocation.
@end defop
+@c WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
+@node Win32 Package Reference, Index, Graphics, Top
+@chapter Win32 Package Reference
+
+@ifinfo
+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.
+@end ifinfo
+
+@menu
+* Win32 Package Overview::
+* Foreign function interface::
+* Device Independent Bitmap Utilities::
+@end menu
+
+
+@node Win32 Package Overview, Foreign function interface, , Win32 Package Reference
+@section 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.
+@cindex limitations
+
+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:
+
+@itemize @bullet
+
+@item
+Special microcode primitives.
+
+@item
+A foreign function interface (FFI) for calling procedures in dynamically
+linked libraries (DLLs).
+
+@item
+An interface for Edwin.
+
+@item
+The Win32 package provides support for using the features of the
+Windows 3.1 and Windows NT 3.1 environments.
+
+@item
+Device Independent Bitmap utilities. These are used by the win32 Scheme
+Graphics implementation. (The Scheme Graphics implementation is
+described in the Reference Manual).
+
+@end itemize
+
+Note that all the names in the Win32 support are part of the
+@code{win32} package. The names are bound in the @code{(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 @code{(win32)} package environment or a child environment.
+
+@node Foreign function interface, Device Independent Bitmap Utilities, Win32 Package Overview, Win32 Package Reference
+@section 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.
+
+@cindex limitations
+@strong{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).
+
+@cindex warning
+@strong{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.
+
+@menu
+* Windows Types::
+* Windows Foreign Procedures::
+* Win32 API names and procedures::
+@end menu
+
+@node Windows Types, Windows Foreign Procedures, , Foreign function interface
+@subsection Windows Types
+
+@cindex Windows types
+@cindex foreign type declarations
+@cindex types, Windows
+@cindex defining foreign 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:
+
+@table @var
+
+@item check
+A predicate that returns @code{#t} if the argument is of an acceptable
+Scheme type, otherwise returns @code{#f}.
+The @var{check} procedure is used for type-checking.
+
+@item 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.
+
+@item return-convert
+A procedure of one argument that, given an integer, returns a Scheme
+object of a type satisfying @var{check}.
+Its purpose is to convert the result returned by the foreign procedure
+into a Scheme value.
+
+@item 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.
+@var{Revert} is a procedure of two parameters, the original object
+passed and the result of @var{convert} on that object.
+@var{Revert} may then inspect the converted object and copy back the
+changes to the original.
+
+@end table
+
+@deffn {special form+} define-windows-type name check convert return revert
+@deffnx {special form+} define-similar-windows-type name model [check [convert [return [revert]]]]
+@cindex defining foreign types
+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.
+@var{Name} is the name of the type.
+@var{Model} is the name of a type.
+@var{Check}, @var{convert}, @var{return} and @var{revert} are
+procedures or the value @code{#f}.
+A @code{#f} means use the default value, which in the second form means
+use the definition provided for @var{model}.
+The defaults are
+
+@table @var
+@item check
+@code{(lambda (x) #t)}, i.e.@: unchecked.
+@item convert
+@code{(lambda (x) x)}, i.e.@: no translation performed.
+@item return
+@code{(lambda (x) x)}, i.e.@: no translation performed.
+@item revert
+@code{(lambda (x y) unspecific)}, i.e.@: no update performed
+@end table
+
+The @code{unchecked} windows type (see below) is defined as:
+
+@example
+(define-windows-type unchecked #f #f #f #f)
+@end example
+
+Windows types are @emph{not} first class values, so they cannot be
+stored in variables or defined using @code{define}:
+
+@example
+(define my-type unchecked) @error{} Unbound variable
+(define-similar-windows-type my-type unchecked) @r{;; the correct way}
+@end example
+
+Scheme characters must be converted to integers. This is accomplished
+as follows:
+
+@example
+(define-windows-type char
+ char? @r{; check}
+ char->integer @r{; convert}
+ integer->char @r{; convert return value}
+ #f @r{; cannot be passed by reference}
+)
+@end example
+@end deffn
+
+@deffn {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 @code{unchecked} values are returned as integers.
+@end deffn
+
+@deffn {windows type} bool
+Scheme booleans are analogous to C integers @code{0} and @code{1}.
+Windows type @code{bool} have been defined as:
+
+@example
+(define-windows-type bool
+ boolean?
+ (lambda (x) (if x 1 0))
+ (lambda (x) (if (eq? x 0) #f #t))
+ #f)
+@end example
+@end deffn
+
+@deffn {windows type} char
+Scheme characters are converted into C objects of type @code{char},
+which are indistinguishable from small integers.
+@end deffn
+
+@deffn {windows type} int
+@deffnx {windows type} uint
+@deffnx {windows type} long
+@deffnx {windows type} ulong
+@deffnx {windows type} short
+@deffnx {windows type} ushort
+@deffnx {windows type} word
+@deffnx {windows type} byte
+Various integer types that are passed without conversion.
+@end deffn
+
+@deffn {windows type} string
+A string that is passed as a C pointer of type @code{char*} to the first
+character in the string.
+@end deffn
+
+@deffn {windows type} char*
+A string or @code{#f}. The string is passed as a pointer to characters.
+The string is correctly null-terminated. @code{#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 @code{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).
+@end deffn
+
+@deffn {windows type} handle
+@deffnx {windows type} hbitmap
+@deffnx {windows type} hbrush
+@deffnx {windows type} hcursor
+@deffnx {windows type} hdc
+@deffnx {windows type} hicon
+@deffnx {windows type} hinstance
+@deffnx {windows type} hmenu
+@deffnx {windows type} hpalette
+@deffnx {windows type} hpen
+@deffnx {windows type} hrgn
+@deffnx {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.@: @code{hmenu?}) and
+sensible interlocking with the garbage collector to free the programmer
+of the current tedious allocation and deallocation of handles.
+@end deffn
+
+@deffn {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.
+@end deffn
+
+
+@node Windows Foreign Procedures, Win32 API names and procedures, Windows Types, Foreign function interface
+@subsection Windows Foreign Procedures
+
+Foreign procedures are declared as callable entry-points in a module,
+usually a dynamically linked library (DLL).
+
+
+@deffn {procedure+} find-module name
+@cindex loading DLLs
+@cindex DLL, loading
+Returns a module suitable for use in creating procedures with
+@code{windows-procedure}. @var{Name} is a string which is the name of a
+DLL file. Internally, @code{find-module} uses the @code{LoadLibrary}
+Win32 API, so @var{name} should conform to the specifications for this
+call. @var{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
+@file{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 behaviour 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).
+@end deffn
+
+
+@defvr {variable+} gdi32.dll
+@cindex DLL, GDI32.DLL
+This variable is bound to the module describing the @file{GDI32.DLL}
+library, which contains the Win32 API graphics calls, e.g.@:
+@code{LineTo}.
+@end defvr
+
+@defvr {variable+} kernel32.dll
+@cindex DLL, KERNEL32.DLL
+This variable is bound to the module describing the @file{KERNEL32.DLL}
+library.
+@end defvr
+
+@defvr {variable+} user32.dll
+@cindex DLL, USER32.DLL
+This variable is bound to the module describing the @file{USER32.DLL}
+library. This module contains many useful Win32 API procedures, like
+@code{MessageBox} and @code{SetWindowText}.
+@end defvr
+
+
+@deffn {special form+} windows-procedure (name (parameter type) ...) return-type module entry-name [options]
+@cindex defining foreign procedures
+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
+@var{entry-name} in the module identified by the value of @var{module}.
+Both @var{entry-name} and @var{module} are evaluated at procedure
+creation time, so either may be expression. @var{Entry-name} must
+evaluate to a string and @var{module} must evaluate to a module as
+returned by @code{find-module}.
+These are the only parts of the form that are evaluated at procedure
+creation time.
+
+@var{Name} is the name of the procedure and is for documentation
+purposes only. This form @emph{does not} define a procedure called
+@var{name}. It is more like @code{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 @var{type}. Both the name @var{parameter} and the windows
+type @var{type} must be symbols and are not evaluated. The procedure
+returns a value of the windows type @var{return-type}.
+
+The following example creates a procedure that takes a window handle
+(@code{hwnd}) and a string and returns a boolean (@code{bool}) result.
+The procedure does this by calling the @code{SetWindowText} entry in the
+module that is the value of the variable @code{user32.dll}. The
+variable @code{set-window-title} is defined to have this procedure as
+it's value.
+
+@example
+(define set-window-title
+ (windows-procedure (set-window-text (window hwnd) (text string))
+ bool user32.dll "SetWindowText"))
+
+(set-window-title my-win "Hi") @result{} #t
+ @r{;; Changes window's title/text}
+
+set-window-title @result{} #[compiled-procedure ...]
+set-window-text @error{} Unbound variable
+@end example
+
+
+When there are no @var{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 @var{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:
+
+@table @asis
+@item @code{with-reversions}
+The reversions are included in the type conversions.
+
+@item @code{expand}
+A synonym for @code{with-reversions}.
+
+@item @var{Scheme code}
+The @var{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.
+@end table
+
+If both options (i.e.@: @code{with-reversions} and Scheme code) are used,
+@code{with-reversions} must appear first. There can be arbitrarily many
+Scheme expression.
+@end deffn
+
+@node Win32 API names and procedures, , Windows Foreign Procedures, Foreign function interface
+@subsection Win32 API names and procedures
+
+This section is a moving target.
+@cindex Win32 API names
+@cindex naming conventions
+
+The @code{#define} values from @file{wingdi.h} and @file{winuser.h} are
+available as bindings in the @code{(win32)} package environment. The
+@code{#define} symbols are all uppercase; these have been translated to
+all lowercase Scheme identifiers, thus @code{WM_LBUTTONUP} is the scheme
+variable @code{wm_lbuttonup}. As Scheme is case insensitive, the
+upper-case version may be used and probably should to make the code look
+more like conventional Windows code. The Scheme bindings have been
+produced automagically. Most of the @code{#define}-symbols contain an
+underscore so there are not many name clashes. There is one very
+notable name clash, however: @code{ERROR} is @code{#define}d to 0, which
+shadows the scheme procedure @code{error} in the root package
+environment. To signal an error, use @code{access}:
+
+@example
+((access error ()) "Whine moan" ...)
+@end example
+
+
+The set of procedures is incomplete because procedures have been added
+on a by-need basis for the implementation of other parts of the system,
+e.g.@: Scheme Graphics. Look in the implementation for further details.
+
+Win32 API procedure names have been uniformly converted into Scheme
+identifiers as follows:
+
+@itemize @bullet
+@item
+A leading uppercase letter is translated into a lowercase letter.
+@item
+Subsequent sequences of uppercase letters are translated into lowercase
+letters preceeded by a hyphen (minus symbol), i.e.@: hyphens are inserted
+at a lowercase to uppercase transition.
+@item
+Predicates beginning with @code{Is} finally have a
+question-mark appended.
+@end itemize
+Example: applying these rules to @code{IsWindow} yields
+@code{is-window?}, and @code{GetDC} is translated into @code{get-dc}.
+
+
+@c [It might be worthwhile just keeping the same names. As the
+@c Win32 API procedure names are uniformly `WordWordWordACRONYMWord', case
+@c insensitivity is unlikely to be a problem. The only problem is the
+@c potential for a clash between a procedure name and a type
+@c name.]
+
+
+@node Device Independent Bitmap Utilities, , Foreign function interface, Win32 Package Reference
+@section Device Independent Bitmap Utilities
+
+
+The Device Independent Bitmap (DIB) utilities library @file{DIBUTILS.DLL}
+and the associated procedures in @file{dib.scm} in the Win32 system
+source is an example of how to use the foreign function interface to
+access and manipulate non-Scheme objects.
+@cindex DLL, DIBUTILS.DLL
+
+@deffn {windows type} dib
+In the C world a DIB is a @dfn{handle} to a piece of memory containing
+the bits that represent information about the image and the pixels of
+the image. The handle is a machine-word sized piece of data which may
+be thought of as a 32 bit integer. The handle may be null (i.e.@: zero),
+indicating that there is no block of memory describing the DIB. The
+null value is usually returned by C functions that are supposed to
+create a DIB but failed, for some reason like the memory could not be
+allocated or a file could not be opened.
+
+In the Scheme world a DIB is a structure containing information
+about the bitmap (specifically the integer that represents the handle).
+We also include @code{#f} in the @code{dib} windows type to mirror the
+null handle error value.
+@example
+(define dib-result
+ (lambda (handle)
+ (if (= handle 0)
+ #f
+ (make-dib handle))))
+
+(define dib-arg
+ (lambda (dib)
+ (if dib
+ (cell-contents (dib-handle dib))
+ 0)))
+
+(define-windows-type dib
+ (lambda (thing) (or (dib? thing) (eq? thing #f)))
+ dib-arg
+ dib-result)
+@end example
+@end deffn
+
+
+@menu
+* DIB procedures::
+* Other parts of the DIB Utilities implementation::
+@end menu
+
+@node DIB procedures, Other parts of the DIB Utilities implementation, , Device Independent Bitmap Utilities
+@subsection DIB procedures
+
+The following procedures have typed parameters, using the same
+convention as @code{windows-procedure}.
+
+@deffn {procedure+} open-dib (filename string)
+Return type: @var{dib}. Calls the @code{OpenDIB} entry of
+@file{DIBUTILS.DLL}. If the return value is not @code{#f} then the file
+@var{filename} was found, successfully opened, and the contents were
+suitable for loading into memory as a device independent bitmap.
+@end deffn
+
+@deffn {procedure+} write-dib (filename string) (dib dib)
+Return type: @var{bool}. Calls the @code{WriteDIB} entry of
+@file{DIBUTILS.DLL}. Returns @code{#t} if the file @var{filename} could
+be opened and written to. After this operation the file contains the
+bitmap data in a standard format that is understood by @code{open-dib}
+and various system utilities like the bitmap editor. Any problems
+resulting in failure are signalled by a @code{#f} return value.
+@end deffn
+
+@deffn {procedure+} bitmap-from-dib (dib dib) (palette hpalette)
+Return type: @var{hbitmap}.
+Calls the @code{BitmapFromDib} entry of @file{DIBUTILS.DLL}. The returned
+value is a device dependent bitmap. The colours from the DIB are
+matched against colors in @var{palette}.
+@end deffn
+
+@deffn {procedure+} dib-from-bitmap (bitmap hbitmap) (style dword) (bits word) (palette hpalette)
+Return type: @var{dib}.
+Returns a DIB containing the same image as the device dependent bitmap
+@var{bitmap}.
+@var{Style} determines the kind of DIB, e.g.@: compression style.
+Calls the @code{DibFromBitmap} entry of @file{DIBUTILS.DLL}.
+@end deffn
+
+@deffn {procedure+} dib-blt (dest hdc) (x int) (y int) (w int) (h int) (src dib) (src-x int) (src-y int) (raster-op long)
+Return type: @var{bool}. Calls the @code{DibBlt} entry of
+@file{DIBUTILS.DLL}. Similar to the Win32 API @code{BitBlt} call, but
+draws a DIB rather than a piece of another device context. Draws the
+@var{dib} on device context @var{hdc} at position (@var{x},@var{y}). A
+rectangle of width @var{w} and height @var{h} is copied from position
+(@var{src-x},@var{src-y}) of @var{dib}.
+@var{Raster-op} is supposed to allow the source and destination to be
+combined but I don't think I got this right so stick to @code{SRCCOPY}.
+@end deffn
+
+@deffn {procedure+} %delete-dib (dib-handle handle)
+Return type: @var{bool}.
+Calls the @code{DeleteDIB} entry of @file{DIBUTILS.DLL}.
+Note that the parameter is a @var{handle}, and not a @var{dib}.
+This allows us to destroy a DIB and reclaim its memory by knowing only
+the handle value, and not needing the @code{dib} record.
+The importance of this is that if the @code{dib} record is GC-ed then a
+GC hook can reclaim the storage knowing only the handle.
+@end deffn
+
+@deffn {procedure+} delete-dib (dib dib)
+Return type: @var{bool}.
+This procedure calls @code{%delete-dib} to reclaim the storage occupied
+by a DIB.
+After being deleted, the DIB should not be used.
+This procedure allows the programmer to reclaim external heap storage
+rather than risking it running out before the next garbage collection.
+@end deffn
+
+@deffn {procedure+} dib-height (dib dib)
+Return type: @var{int}.
+Calls the @code{DibHeight} expand entry of @file{DIBUTILS.DLL}, which returns
+the height of the bitmap in pixels.
+@end deffn
+
+@deffn {procedure+} dib-width (dib dib)
+Return type: @var{int}.
+Calls the @code{DibWidth} entry of @file{DIBUTILS.DLL}, which returns
+the width of the bitmap in pixels.
+@end deffn
+
+@deffn {procedure+} copy-bitmap (bm hbitmap)
+Return type: @var{hbitmap}.
+Calls the @code{CopyBitmap} of @file{DIBUTILS.DLL}, which creates a new
+bitmap with the same size and contents as the original.
+@end deffn
+
+@deffn {procedure+} create-dib (width int) (height int) (style int) (depth int) (palette hpalette)
+Return type: @var{dib}.
+Calls the @code{CreateDIB} entry of @file{DIBUTILS.DLL}.
+Creates a DIB of @var{width} by @var{height} pixels and @var{depth} bits
+of colour information.
+The @var{style} parameter determines how the bitmap is stored.
+I have only ever used @code{BI_RGB}.
+If @var{depth}<=8 then the @var{palette} determines the DIB's colour table.
+@end deffn
+
+@deffn {procedure+} crop-bitmap (bm hbitmap) (left int) (top int) (right int) (bottom int)
+Return type: @var{hbitmap}.
+Calls the @code{CropBitmap} entry of @file{DIBUTILS.DLL}.
+Returns a new bitmap containing the image from a region of the original.
+@end deffn
+
+@deffn {procedure+} dib-set-pixels-unaligned dib (pixels string)
+Return type: @var{bool}.
+Calls the @code{DIBSetPixelsUnaligned} entry of @file{DIBUTILS.DLL}. Stuffs
+bytes from @var{pixels} into the bitmap. There are no alignment
+constraints on @var{pixels} (the usual way of doing this is to use the
+@code{SetDIBits} function which requires that every scan line of the
+bitmap is 32-bit word aligned, even if the scan lines are not a multiple
+of 4 bytes long). doing this
+@end deffn
+
+@node Other parts of the DIB Utilities implementation, , DIB procedures, Device Independent Bitmap Utilities
+@subsection Other parts of the DIB Utilities implementation
+
+
+The @file{DIBUTILS.DLL} library is an ordinary DLL. See the standard
+Microsoft Windows documentation on how to create DLLs. Look at the code
+in the @file{WIN32/DIBUTILS} directory of the Scheme source.
+
+Please note:
+@itemize @bullet
+@item
+@cindex DLL, exports
+For the foreign function interface to find the procedures they must be
+declared as exports in the @file{.DEF} definition file.
+
+@item
+To load the @file{.DLL} file use the @code{find-module} Scheme function.
+Look at @file{WIN32/DIB.SCM} to see how this is done.
+
+@item
+The current system works with C procedures with the @code{__stdcall} and
+@code{__cdecl} calling conventions but @emph{not} the @code{__fastcall}
+calling convention.
+@end itemize
+
+
+@c @node Writing windows procedures, Procedure Index, Device Independent Bitmap Utilities, Top
+@c @section Writing windows procedures
+@c
+@c @cindex warning
+@c @strong{Warning:} Do not try to do this. It is very hard to get it even
+@c partly right and probably impossible to make the program 100% reliable.
+@c
+@c It is possible to write Scheme procedures that determine the behaviour
+@c of windows and controls on the screen. To succeed at this you need a
+@c good understanding of how you would do the same thing in C using the
+@c Windows SDK, the limitations of mixed language working when C calls
+@c Scheme, and lots of patience because debugging this kind of code is very
+@c painful.
+@c The only major example of this kind of code is the Scheme Graphics
+@c implementation (source in @file{WIN32/GRAPHICS.SCM}, but you will need
+@c to read @file{RUNTIME/GRAPHICS.SCM} and the DIB utilities too).
+@c
+@c Currently, Scheme `wndprocs' are run during interrupt processing. They
+@c are run in the dynamic context of whatever was running when the
+@c interrupt was signalled. Any procedure that relies upon a fluid
+@c variable cannot be used reliably. Thus doing, say, a @code{display}
+@c might result in the output unintentionally being inserted in a file
+@c rather than appearing on the screen. Errors are not handled, thus a
+@c call to @code{(+ #f 5)} can result in the interrupt processing mechanism
+@c becoming confused, and subsequently causing the system to lock up, as
+@c all user input ultimately is processed using this same mechanism.
+@c Obviously this state of affairs is not satisfactory and I intend to
+@c improve things by running the wndprocs in a known dynamic context and
+@c trapping errors, but not until Edwin's I/O handling is changed to
+@c separate it more from this mechanism, and definitely not until after the
+@c release.
+@c
+@c @menu
+@c * Procedures::
+@c * Scheme WndProcs::
+@c @end menu
+@c
+@c @node Procedures, , , Writing windows procedures
+@c @subsection Procedures
+@c
+@c @deffn {procedure+} get-handle index
+@c Return a magic number that cannot be found any other way.
+@c Subject to change, the current behaviour is:
+@c
+@c @table @code
+@c @item 0
+@c The handle of the instance, @code{hInstance}, of the Scheme application
+@c @item 1
+@c The handle of the master tty window
+@c @item 3
+@c The address of the C function that invokes a Scheme wndproc.
+@c @end table
+@c @end deffn
+@c
+@c @deffn {procedure+} create-scheme-window ex-style class name style x y w h parent menu inst param proc
+@c Creates a window by calling @code{CreateWindowEx} with all the
+@c parameters except @var{proc}.
+@c
+@c @table @var
+@c @item ex-style
+@c Integer.
+@c @item class
+@c String. Must name a window class created with a @code{lpfnWndProc}
+@c entry that has the value of @code{(get-handle 3)}.
+@c @item name
+@c String. Title of window.
+@c @item style
+@c Integer.
+@c @item x y
+@c Integer. Window position.
+@c @item w h
+@c Integer. Window size.
+@c @item parent
+@c Integer. Handle of parent window.
+@c @item menu
+@c Integer or string. Number or name of menu resource for this window's
+@c menu.
+@c 0 means no menu.
+@c @item inst
+@c Integer, should be the result of @code{(get-handle 0)}.
+@c @item param
+@c Integer.
+@c @item proc
+@c @var{Proc} is a Scheme procedure with four parameters, i.e.@: of the form
+@c
+@c @example
+@c (lambda (@var{hwnd} @var{msg} @var{wparam} @var{lparam})
+@c ...)
+@c @end example
+@c This procedure is the Scheme analogue of the C function that would
+@c normally have been installed as the @code{lpfnWndProc} of the window
+@c class.
+@c @end table
+@c @end deffn
+@c
+@c @deffn {procedure+} subclass-window! hwnd subclass-behaviour
+@c Replace @var{hwnd}'s wndproc with a wndproc formed by calling
+@c @var{subclass-behaviour} on the original wndproc.
+@c @end deffn
+@c
+@c @deffn {procedure+} register-class style wndproc clsExtra wndExtra hInstance hIcon hCursor hBackground menu-name class-name
+@c A way to call @code{RegisterClass} without first constructing a C
+@c @code{WNDCLASS} object.
+@c @end deffn
+@c
+@c @deffn {procedure+} default-scheme-wndproc
+@c The Scheme equivalent of the C @code{DefWindowProc}.
+@c @end deffn
+@c
+@c @node Scheme WndProcs, , Procedures, Writing windows procedures
+@c @subsection Scheme WndProcs
+@c
+@c
+@c A Scheme wndproc is of the form
+@c
+@c @cindex wndproc
+@c @example
+@c (lambda (hwnd msg wparam lparam)
+@c (cond ((= msg WM_CREATE)
+@c ...)
+@c (...
+@c ...)
+@c (else
+@c (default-scheme-wndproc hwnd msg wparam lparam))))
+@c @end example
+@c
+@c @cindex wndproc, higher-order
+@c Scheme has the advantage over C that first class procedures can be used
+@c to organize the data used by the window.
+@c A useful idiom idiom is to parameterize the code with the default
+@c behaviour.
+@c This example behaves like @var{default-wndproc}, except that it
+@c beeps every time the left mouse button is pressed.
+@c
+@c @example
+@c (define ((my-wndproc default-wndproc) hwnd msg wparam lparam)
+@c (define (default) (default-wndproc hwnd msg wparam lparam))
+@c (cond ((= msg WM_LBUTTONDOWN)
+@c (message-beep MB_OK)
+@c (default))
+@c (else
+@c (default))))
+@c @end example
+@c
+@c @noindent
+@c @code{my-wndproc} is suitable for use with @code{subclass-window!}
+@c For example,
+@c
+@c @example
+@c (subclass-window! (get-handle 1) my-wndproc)
+@c @end example
+@c Will cause the main Scheme window to beep every time the left mouse
+@c button is pressed, but otherwise work normally.
+@c
+@c In a similar fashion, Scheme wndprocs can be closed over state
+@c describing the object that the window displays or edits.
+@c An idiom for a complex kind of window is to have a record (structure)
+@c representing the object, and to create the window procedure with that
+@c object in scope.
+@c The following extended example is a framework for an editor.
+@c The @code{whizz-editor} record's @code{hwnd} field is set at window
+@c creation time so that we can get the window handle from the record. The
+@c utility of this is demonstrated in @code{whizz-editor/set-title}.
+@c
+@c @example
+@c (define-structure whizz-editor
+@c hwnd
+@c magic-flag?
+@c @var{other stuff})
+@c
+@c
+@c (define (make-whizz-editor-wndproc data)
+@c ;; @r{The following string is created once before the window comes}
+@c ;; @r{into existence}
+@c (define window-local-string (make-string 100))
+@c
+@c ;; @r{The normal wndproc}
+@c (define ((wndproc default-wndproc) hwnd msg wparam lparam)
+@c (define (default) (default-wndproc hwnd msg wparam lparam))
+@c (cond ((= msg WM_CREATE)
+@c (set-whizz-editor-hwnd! data hwnd)
+@c ...
+@c (default))
+@c (...
+@c ... (if (whizz-editor-magic-flag? data) ... ...)
+@c ...)
+@c (else
+@c (default))))
+@c
+@c wndproc)
+@c
+@c
+@c (define (create-whizz-editor)
+@c (let* ((data (make-whizz-editor 0 ...))
+@c (wndproc (make-whizz-editor-wndproc data))
+@c
+@c (create-scheme-window
+@c 0 "WHIZZ_EDITOR_CLASS" "Whizz Editor"
+@c (+ WS_VISIBLE WS_OVERLAPPED)
+@c CW_USEDEFAULT CW_USEDEFAULT CW_USEDEFAULT CW_USEDEFAULT
+@c 0 0 (get-handle 0) 0
+@c (wndproc default-scheme-wndproc)))
+@c data))
+@c
+@c (define (whizz-editor/set-title wh title)
+@c (set-window-text (whizz-editor-hwnd wh) title))
+@c @end example
+@c
+@c @noindent
+@c Now we are ready to create a Whizz Editor and set its title:
+@c
+@c @example
+@c (define my-editor (create-whizz-editor))
+@c (whizz-editor/set-title my-editor "A new title")
+@c @end example
+@c
+@c @node Procedure Index, Concept Index, , Top
+@c @unnumbered Index of Procedures, Special Forms, and Variables
+@c @printindex fn
+@c
+@c @node Concept Index, , Procedure Index, Top
+@c @unnumbered Index of Concepts
+@c @printindex cp
+@c
+@c @node Procedure Index, , Writing windows procedures, Top
+@c @unnumbered Index
+@c @printindex fn
+@c
+@c @c @summarycontents
+@c
+@c @contents
+@c
+@c @c Local Variables:
+@c @c eval: (auto-save-mode -1)
+@c @c End:
+@c
+@c @bye
+
+@c WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
+
@ifset sicpstuff
@include pictures.texinfo
@end ifset
-@node Index, , Graphics, Top
+@node Index, , Win32 Package Reference, Top
@unnumbered Index
@printindex cp
* Compiling Files::
* GNU Emacs Interface::
* Edwin::
-* Win32 Package Reference::
* Concept Index::
--- The Detailed Node Listing ---
Installation
-* Unix::
-* PC Operating Systems:: DOS, Windows, and Windows NT
+* Unix::
+* PC Operating Systems::
DOS, Windows, and Windows NT installation
* System requirements::
* Manifest::
-* PC Installation::
+* PC Installation:: Installation
Release Notes
* Unix Release Notes::
-* C Back-End Release Notes::
+* C Back-End Release Notes::
* DOS::
DOS, Windows 3.1, and Windows NT Release Notes
* Documented Emacs variables missing from Edwin::
* Variables that should be per-buffer in Edwin::
* Edwin Bugs::
-
-Win32 Package Reference
-
-* Overview::
-* Foreign function interface::
-* Device Independent Bitmap Utilities::
-
-Foreign Function Interface
-
-* Windows Types::
-* Windows Foreign Procedures::
-* Win32 API names and procedures::
-
-Device Independent Bitmap Utilities
-
-* DIB procedures::
-* Other parts of the DIB Utilities implementation::
@end menu
@node Installation, Release Notes, Top, Top
@menu
-* Unix::
-* PC Operating Systems::
+* Unix::
+* PC Operating Systems::
@end menu
@node Unix, PC Operating Systems, , Installation
@c NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
-@node PC Operating Systems, ,Unix, Installation
+@node PC Operating Systems, , Unix, Installation
@section DOS, Windows, and Windows NT installation
This section describes how to install MIT Scheme on DOS, Windows 3.1, and
@menu
* System requirements::
* Manifest::
-* PC Installation:: Installation
+* PC Installation:: Installation
@end menu
@node System requirements, Manifest, , PC Operating Systems
@menu
* Unix Release Notes::
-* C Back-End Release Notes::
+* C Back-End Release Notes::
* DOS::
@end menu
Like evaluating @code{(proceed)} (@code{xscheme-send-proceed}).
@end table
-@node Edwin, Win32 Package Reference, GNU Emacs Interface, Top
+@node Edwin, Concept Index, GNU Emacs Interface, Top
@chapter Edwin
This chapter describes how to start Edwin, the MIT Scheme text editor.
column zero.
@end itemize
-@c WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
-@node Win32 Package Reference, Concept Index, Edwin, Top
-@chapter Win32 Package Reference
-
-@ifinfo
-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 architecture.
-@end ifinfo
-
-@menu
-* Overview::
-* Foreign function interface::
-* Device Independent Bitmap Utilities::
-@end menu
-
-
-@node Overview, Foreign function interface, , Win32 Package Reference
-@section 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.
-@cindex limitations
-
-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:
-
-@itemize @bullet
-
-@item
-Special microcode primitives.
-
-@item
-A foreign function interface (FFI) for calling procedures in dynamically
-linked libraries (DLLs).
-
-@item
-An interface for Edwin.
-
-@item
-The Win32 package provides support for using the features of the
-Windows 3.1 and Windows NT 3.1 environments.
-
-@item
-Device Independent Bitmap utilities. These are used by the win32 Scheme
-Graphics implementation. (The Scheme Graphics implementation is
-described in the Reference Manual).
-
-@end itemize
-
-Note that all the names in the Win32 support are part of the
-@code{win32} package. The names are bound in the @code{(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 @code{(win32)} package environment or a child environment.
-
-@node Foreign function interface, Device Independent Bitmap Utilities, Overview, Win32 Package Reference
-@section 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.
-
-@cindex limitations
-@strong{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).
-
-@cindex warning
-@strong{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.
-
-@menu
-* Windows Types::
-* Windows Foreign Procedures::
-* Win32 API names and procedures::
-@end menu
-
-@node Windows Types, Windows Foreign Procedures, , Foreign function interface
-@subsection Windows Types
-
-@cindex Windows types
-@cindex foreign type declarations
-@cindex types, Windows
-@cindex defining foreign 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:
-
-@table @var
-
-@item check
-A predicate that returns @code{#t} if the argument is of an acceptable
-Scheme type, otherwise returns @code{#f}.
-The @var{check} procedure is used for type-checking.
-
-@item 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.
-
-@item return-convert
-A procedure of one argument that, given an integer, returns a Scheme
-object of a type satisfying @var{check}.
-Its purpose is to convert the result returned by the foreign procedure
-into a Scheme value.
-
-@item 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.
-@var{Revert} is a procedure of two parameters, the original object
-passed and the result of @var{convert} on that object.
-@var{Revert} may then inspect the converted object and copy back the
-changes to the original.
-
-@end table
-
-@deffn {special form+} define-windows-type name check convert return revert
-@deffnx {special form+} define-similar-windows-type name model [check [convert [return [revert]]]]
-@cindex defining foreign types
-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.
-@var{Name} is the name of the type.
-@var{Model} is the name of a type.
-@var{Check}, @var{convert}, @var{return} and @var{revert} are
-procedures or the value @code{#f}.
-A @code{#f} means use the default value, which in the second form means
-use the definition provided for @var{model}.
-The defaults are
-
-@table @var
-@item check
-@code{(lambda (x) #t)}, i.e.@: unchecked.
-@item convert
-@code{(lambda (x) x)}, i.e.@: no translation performed.
-@item return
-@code{(lambda (x) x)}, i.e.@: no translation performed.
-@item revert
-@code{(lambda (x y) unspecific)}, i.e.@: no update performed
-@end table
-
-The @code{unchecked} windows type (see below) is defined as:
-
-@example
-(define-windows-type unchecked #f #f #f #f)
-@end example
-
-Windows types are @emph{not} first class values, so they cannot be
-stored in variables or defined using @code{define}:
-
-@example
-(define my-type unchecked) @error{} Unbound variable
-(define-similar-windows-type my-type unchecked) @r{;; the correct way}
-@end example
-
-Scheme characters must be converted to integers. This is accomplished
-as follows:
-
-@example
-(define-windows-type char
- char? @r{; check}
- char->integer @r{; convert}
- integer->char @r{; convert return value}
- #f @r{; cannot be passed by reference}
-)
-@end example
-@end deffn
-
-@deffn {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 @code{unchecked} values are returned as integers.
-@end deffn
-
-@deffn {windows type} bool
-Scheme booleans are analogous to C integers @code{0} and @code{1}.
-Windows type @code{bool} have been defined as:
-
-@example
-(define-windows-type bool
- boolean?
- (lambda (x) (if x 1 0))
- (lambda (x) (if (eq? x 0) #f #t))
- #f)
-@end example
-@end deffn
-
-@deffn {windows type} char
-Scheme characters are converted into C objects of type @code{char},
-which are indistinguishable from small integers.
-@end deffn
-
-@deffn {windows type} int
-@deffnx {windows type} uint
-@deffnx {windows type} long
-@deffnx {windows type} ulong
-@deffnx {windows type} short
-@deffnx {windows type} ushort
-@deffnx {windows type} word
-@deffnx {windows type} byte
-Various integer types that are passed without conversion.
-@end deffn
-
-@deffn {windows type} string
-A string that is passed as a C pointer of type @code{char*} to the first
-character in the string.
-@end deffn
-
-@deffn {windows type} char*
-A string or @code{#f}. The string is passed as a pointer to characters.
-The string is correctly null-terminated. @code{#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 @code{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).
-@end deffn
-
-@deffn {windows type} handle
-@deffnx {windows type} hbitmap
-@deffnx {windows type} hbrush
-@deffnx {windows type} hcursor
-@deffnx {windows type} hdc
-@deffnx {windows type} hicon
-@deffnx {windows type} hinstance
-@deffnx {windows type} hmenu
-@deffnx {windows type} hpalette
-@deffnx {windows type} hpen
-@deffnx {windows type} hrgn
-@deffnx {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.@: @code{hmenu?}) and
-sensible interlocking with the garbage collector to free the programmer
-of the current tedious allocation and deallocation of handles.
-@end deffn
-
-@deffn {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.
-@end deffn
-
-
-@node Windows Foreign Procedures, Win32 API names and procedures, Windows Types, Foreign function interface
-@subsection Windows Foreign Procedures
-
-Foreign procedures are declared as callable entry-points in a module,
-usually a dynamically linked library (DLL).
-
-
-@deffn {procedure+} find-module name
-@cindex loading DLLs
-@cindex DLL, loading
-Returns a module suitable for use in creating procedures with
-@code{windows-procedure}. @var{Name} is a string which is the name of a
-DLL file. Internally, @code{find-module} uses the @code{LoadLibrary}
-Win32 API, so @var{name} should conform to the specifications for this
-call. @var{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
-@file{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 behaviour 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).
-@end deffn
-
-
-@defvr {variable+} gdi32.dll
-@cindex DLL, GDI32.DLL
-This variable is bound to the module describing the @file{GDI32.DLL}
-library, which contains the Win32 API graphics calls, e.g.@:
-@code{LineTo}.
-@end defvr
-
-@defvr {variable+} kernel32.dll
-@cindex DLL, KERNEL32.DLL
-This variable is bound to the module describing the @file{KERNEL32.DLL}
-library.
-@end defvr
-
-@defvr {variable+} user32.dll
-@cindex DLL, USER32.DLL
-This variable is bound to the module describing the @file{USER32.DLL}
-library. This module contains many useful Win32 API procedures, like
-@code{MessageBox} and @code{SetWindowText}.
-@end defvr
-
-
-@deffn {special form+} windows-procedure (name (parameter type) ...) return-type module entry-name [options]
-@cindex defining foreign procedures
-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
-@var{entry-name} in the module identified by the value of @var{module}.
-Both @var{entry-name} and @var{module} are evaluated at procedure
-creation time, so either may be expression. @var{Entry-name} must
-evaluate to a string and @var{module} must evaluate to a module as
-returned by @code{find-module}.
-These are the only parts of the form that are evaluated at procedure
-creation time.
-
-@var{Name} is the name of the procedure and is for documentation
-purposes only. This form @emph{does not} define a procedure called
-@var{name}. It is more like @code{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 @var{type}. Both the name @var{parameter} and the windows
-type @var{type} must be symbols and are not evaluated. The procedure
-returns a value of the windows type @var{return-type}.
-
-The following example creates a procedure that takes a window handle
-(@code{hwnd}) and a string and returns a boolean (@code{bool}) result.
-The procedure does this by calling the @code{SetWindowText} entry in the
-module that is the value of the variable @code{user32.dll}. The
-variable @code{set-window-title} is defined to have this procedure as
-it's value.
-
-@example
-(define set-window-title
- (windows-procedure (set-window-text (window hwnd) (text string))
- bool user32.dll "SetWindowText"))
-
-(set-window-title my-win "Hi") @result{} #t
- @r{;; Changes window's title/text}
-
-set-window-title @result{} #[compiled-procedure ...]
-set-window-text @error{} Unbound variable
-@end example
-
-
-When there are no @var{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 @var{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:
-
-@table @asis
-@item @code{with-reversions}
-The reversions are included in the type conversions.
-
-@item @code{expand}
-A synonym for @code{with-reversions}.
-
-@item @var{Scheme code}
-The @var{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.
-@end table
-
-If both options (i.e.@: @code{with-reversions} and Scheme code) are used,
-@code{with-reversions} must appear first. There can be arbitrarily many
-Scheme expression.
-@end deffn
-
-@node Win32 API names and procedures, , Windows Foreign Procedures, Foreign function interface
-@subsection Win32 API names and procedures
-
-This section is a moving target.
-@cindex Win32 API names
-@cindex naming conventions
-
-The @code{#define} values from @file{wingdi.h} and @file{winuser.h} are
-available as bindings in the @code{(win32)} package environment. The
-@code{#define} symbols are all uppercase; these have been translated to
-all lowercase Scheme identifiers, thus @code{WM_LBUTTONUP} is the scheme
-variable @code{wm_lbuttonup}. As Scheme is case insensitive, the
-upper-case version may be used and probably should to make the code look
-more like conventional Windows code. The Scheme bindings have been
-produced automagically. Most of the @code{#define}-symbols contain an
-underscore so there are not many name clashes. There is one very
-notable name clash, however: @code{ERROR} is @code{#define}d to 0, which
-shadows the scheme procedure @code{error} in the root package
-environment. To signal an error, use @code{access}:
-
-@example
-((access error ()) "Whine moan" ...)
-@end example
-
-
-The set of procedures is incomplete because procedures have been added
-on a by-need basis for the implementation of other parts of the system,
-e.g.@: Scheme Graphics. Look in the implementation for further details.
-
-Win32 API procedure names have been uniformly converted into Scheme
-identifiers as follows:
-
-@itemize @bullet
-@item
-A leading uppercase letter is translated into a lowercase letter.
-@item
-Subsequent sequences of uppercase letters are translated into lowercase
-letters preceeded by a hyphen (minus symbol), i.e.@: hyphens are inserted
-at a lowercase to uppercase transition.
-@item
-Predicates beginning with @code{Is} finally have a
-question-mark appended.
-@end itemize
-Example: applying these rules to @code{IsWindow} yields
-@code{is-window?}, and @code{GetDC} is translated into @code{get-dc}.
-
-
-@c [It might be worthwhile just keeping the same names. As the
-@c Win32 API procedure names are uniformly `WordWordWordACRONYMWord', case
-@c insensitivity is unlikely to be a problem. The only problem is the
-@c potential for a clash between a procedure name and a type
-@c name.]
-
-
-@node Device Independent Bitmap Utilities, , Foreign function interface, Win32 Package Reference
-@section Device Independent Bitmap Utilities
-
-
-The Device Independent Bitmap (DIB) utilities library @file{DIBUTILS.DLL}
-and the associated procedures in @file{dib.scm} in the Win32 system
-source is an example of how to use the foreign function interface to
-access and manipulate non-Scheme objects.
-@cindex DLL, DIBUTILS.DLL
-
-@deffn {windows type} dib
-In the C world a DIB is a @dfn{handle} to a piece of memory containing
-the bits that represent information about the image and the pixels of
-the image. The handle is a machine-word sized piece of data which may
-be thought of as a 32 bit integer. The handle may be null (i.e.@: zero),
-indicating that there is no block of memory describing the DIB. The
-null value is usually returned by C functions that are supposed to
-create a DIB but failed, for some reason like the memory could not be
-allocated or a file could not be opened.
-
-In the Scheme world a DIB is a structure containing information
-about the bitmap (specifically the integer that represents the handle).
-We also include @code{#f} in the @code{dib} windows type to mirror the
-null handle error value.
-@example
-(define dib-result
- (lambda (handle)
- (if (= handle 0)
- #f
- (make-dib handle))))
-
-(define dib-arg
- (lambda (dib)
- (if dib
- (cell-contents (dib-handle dib))
- 0)))
-
-(define-windows-type dib
- (lambda (thing) (or (dib? thing) (eq? thing #f)))
- dib-arg
- dib-result)
-@end example
-@end deffn
-
-
-@menu
-* DIB procedures::
-* Other parts of the DIB Utilities implementation::
-@end menu
-
-@node DIB procedures, Other parts of the DIB Utilities implementation, , Device Independent Bitmap Utilities
-@subsection DIB procedures
-
-The following procedures have typed parameters, using the same
-convention as @code{windows-procedure}.
-
-@deffn {procedure+} open-dib (filename string)
-Return type: @var{dib}. Calls the @code{OpenDIB} entry of
-@file{DIBUTILS.DLL}. If the return value is not @code{#f} then the file
-@var{filename} was found, successfully opened, and the contents were
-suitable for loading into memory as a device independent bitmap.
-@end deffn
-
-@deffn {procedure+} write-dib (filename string) (dib dib)
-Return type: @var{bool}. Calls the @code{WriteDIB} entry of
-@file{DIBUTILS.DLL}. Returns @code{#t} if the file @var{filename} could
-be opened and written to. After this operation the file contains the
-bitmap data in a standard format that is understood by @code{open-dib}
-and various system utilities like the bitmap editor. Any problems
-resulting in failure are signalled by a @code{#f} return value.
-@end deffn
-
-@deffn {procedure+} bitmap-from-dib (dib dib) (palette hpalette)
-Return type: @var{hbitmap}.
-Calls the @code{BitmapFromDib} entry of @file{DIBUTILS.DLL}. The returned
-value is a device dependent bitmap. The colours from the DIB are
-matched against colors in @var{palette}.
-@end deffn
-
-@deffn {procedure+} dib-from-bitmap (bitmap hbitmap) (style dword) (bits word) (palette hpalette)
-Return type: @var{dib}.
-Returns a DIB containing the same image as the device dependent bitmap
-@var{bitmap}.
-@var{Style} determines the kind of DIB, e.g.@: compression style.
-Calls the @code{DibFromBitmap} entry of @file{DIBUTILS.DLL}.
-@end deffn
-
-@deffn {procedure+} dib-blt (dest hdc) (x int) (y int) (w int) (h int) (src dib) (src-x int) (src-y int) (raster-op long)
-Return type: @var{bool}. Calls the @code{DibBlt} entry of
-@file{DIBUTILS.DLL}. Similar to the Win32 API @code{BitBlt} call, but
-draws a DIB rather than a piece of another device context. Draws the
-@var{dib} on device context @var{hdc} at position (@var{x},@var{y}). A
-rectangle of width @var{w} and height @var{h} is copied from position
-(@var{src-x},@var{src-y}) of @var{dib}.
-@var{Raster-op} is supposed to allow the source and destination to be
-combined but I don't think I got this right so stick to @code{SRCCOPY}.
-@end deffn
-
-@deffn {procedure+} %delete-dib (dib-handle handle)
-Return type: @var{bool}.
-Calls the @code{DeleteDIB} entry of @file{DIBUTILS.DLL}.
-Note that the parameter is a @var{handle}, and not a @var{dib}.
-This allows us to destroy a DIB and reclaim its memory by knowing only
-the handle value, and not needing the @code{dib} record.
-The importance of this is that if the @code{dib} record is GC-ed then a
-GC hook can reclaim the storage knowing only the handle.
-@end deffn
-
-@deffn {procedure+} delete-dib (dib dib)
-Return type: @var{bool}.
-This procedure calls @code{%delete-dib} to reclaim the storage occupied
-by a DIB.
-After being deleted, the DIB should not be used.
-This procedure allows the programmer to reclaim external heap storage
-rather than risking it running out before the next garbage collection.
-@end deffn
-
-@deffn {procedure+} dib-height (dib dib)
-Return type: @var{int}.
-Calls the @code{DibHeight} expand entry of @file{DIBUTILS.DLL}, which returns
-the height of the bitmap in pixels.
-@end deffn
-
-@deffn {procedure+} dib-width (dib dib)
-Return type: @var{int}.
-Calls the @code{DibWidth} entry of @file{DIBUTILS.DLL}, which returns
-the width of the bitmap in pixels.
-@end deffn
-
-@deffn {procedure+} copy-bitmap (bm hbitmap)
-Return type: @var{hbitmap}.
-Calls the @code{CopyBitmap} of @file{DIBUTILS.DLL}, which creates a new
-bitmap with the same size and contents as the original.
-@end deffn
-
-@deffn {procedure+} create-dib (width int) (height int) (style int) (depth int) (palette hpalette)
-Return type: @var{dib}.
-Calls the @code{CreateDIB} entry of @file{DIBUTILS.DLL}.
-Creates a DIB of @var{width} by @var{height} pixels and @var{depth} bits
-of colour information.
-The @var{style} parameter determines how the bitmap is stored.
-I have only ever used @code{BI_RGB}.
-If @var{depth}<=8 then the @var{palette} determines the DIB's colour table.
-@end deffn
-
-@deffn {procedure+} crop-bitmap (bm hbitmap) (left int) (top int) (right int) (bottom int)
-Return type: @var{hbitmap}.
-Calls the @code{CropBitmap} entry of @file{DIBUTILS.DLL}.
-Returns a new bitmap containing the image from a region of the original.
-@end deffn
-
-@deffn {procedure+} dib-set-pixels-unaligned dib (pixels string)
-Return type: @var{bool}.
-Calls the @code{DIBSetPixelsUnaligned} entry of @file{DIBUTILS.DLL}. Stuffs
-bytes from @var{pixels} into the bitmap. There are no alignment
-constraints on @var{pixels} (the usual way of doing this is to use the
-@code{SetDIBits} function which requires that every scan line of the
-bitmap is 32-bit word aligned, even if the scan lines are not a multiple
-of 4 bytes long). doing this
-@end deffn
-
-@node Other parts of the DIB Utilities implementation, , DIB procedures, Device Independent Bitmap Utilities
-@subsection Other parts of the DIB Utilities implementation
-
-
-The @file{DIBUTILS.DLL} library is an ordinary DLL. See the standard
-Microsoft Windows documentation on how to create DLLs. Look at the code
-in the @file{WIN32/DIBUTILS} directory of the Scheme source.
-
-Please note:
-@itemize @bullet
-@item
-@cindex DLL, exports
-For the foreign function interface to find the procedures they must be
-declared as exports in the @file{.DEF} definition file.
-
-@item
-To load the @file{.DLL} file use the @code{find-module} Scheme function.
-Look at @file{WIN32/DIB.SCM} to see how this is done.
-
-@item
-The current system works with C procedures with the @code{__stdcall} and
-@code{__cdecl} calling conventions but @emph{not} the @code{__fastcall}
-calling convention.
-@end itemize
-
-
-@c @node Writing windows procedures, Procedure Index, Device Independent Bitmap Utilities, Top
-@c @section Writing windows procedures
-@c
-@c @cindex warning
-@c @strong{Warning:} Do not try to do this. It is very hard to get it even
-@c partly right and probably impossible to make the program 100% reliable.
-@c
-@c It is possible to write Scheme procedures that determine the behaviour
-@c of windows and controls on the screen. To succeed at this you need a
-@c good understanding of how you would do the same thing in C using the
-@c Windows SDK, the limitations of mixed language working when C calls
-@c Scheme, and lots of patience because debugging this kind of code is very
-@c painful.
-@c The only major example of this kind of code is the Scheme Graphics
-@c implementation (source in @file{WIN32/GRAPHICS.SCM}, but you will need
-@c to read @file{RUNTIME/GRAPHICS.SCM} and the DIB utilities too).
-@c
-@c Currently, Scheme `wndprocs' are run during interrupt processing. They
-@c are run in the dynamic context of whatever was running when the
-@c interrupt was signalled. Any procedure that relies upon a fluid
-@c variable cannot be used reliably. Thus doing, say, a @code{display}
-@c might result in the output unintentionally being inserted in a file
-@c rather than appearing on the screen. Errors are not handled, thus a
-@c call to @code{(+ #f 5)} can result in the interrupt processing mechanism
-@c becoming confused, and subsequently causing the system to lock up, as
-@c all user input ultimately is processed using this same mechanism.
-@c Obviously this state of affairs is not satisfactory and I intend to
-@c improve things by running the wndprocs in a known dynamic context and
-@c trapping errors, but not until Edwin's I/O handling is changed to
-@c separate it more from this mechanism, and definitely not until after the
-@c release.
-@c
-@c @menu
-@c * Procedures::
-@c * Scheme WndProcs::
-@c @end menu
-@c
-@c @node Procedures, , , Writing windows procedures
-@c @subsection Procedures
-@c
-@c @deffn {procedure+} get-handle index
-@c Return a magic number that cannot be found any other way.
-@c Subject to change, the current behaviour is:
-@c
-@c @table @code
-@c @item 0
-@c The handle of the instance, @code{hInstance}, of the Scheme application
-@c @item 1
-@c The handle of the master tty window
-@c @item 3
-@c The address of the C function that invokes a Scheme wndproc.
-@c @end table
-@c @end deffn
-@c
-@c @deffn {procedure+} create-scheme-window ex-style class name style x y w h parent menu inst param proc
-@c Creates a window by calling @code{CreateWindowEx} with all the
-@c parameters except @var{proc}.
-@c
-@c @table @var
-@c @item ex-style
-@c Integer.
-@c @item class
-@c String. Must name a window class created with a @code{lpfnWndProc}
-@c entry that has the value of @code{(get-handle 3)}.
-@c @item name
-@c String. Title of window.
-@c @item style
-@c Integer.
-@c @item x y
-@c Integer. Window position.
-@c @item w h
-@c Integer. Window size.
-@c @item parent
-@c Integer. Handle of parent window.
-@c @item menu
-@c Integer or string. Number or name of menu resource for this window's
-@c menu.
-@c 0 means no menu.
-@c @item inst
-@c Integer, should be the result of @code{(get-handle 0)}.
-@c @item param
-@c Integer.
-@c @item proc
-@c @var{Proc} is a Scheme procedure with four parameters, i.e.@: of the form
-@c
-@c @example
-@c (lambda (@var{hwnd} @var{msg} @var{wparam} @var{lparam})
-@c ...)
-@c @end example
-@c This procedure is the Scheme analogue of the C function that would
-@c normally have been installed as the @code{lpfnWndProc} of the window
-@c class.
-@c @end table
-@c @end deffn
-@c
-@c @deffn {procedure+} subclass-window! hwnd subclass-behaviour
-@c Replace @var{hwnd}'s wndproc with a wndproc formed by calling
-@c @var{subclass-behaviour} on the original wndproc.
-@c @end deffn
-@c
-@c @deffn {procedure+} register-class style wndproc clsExtra wndExtra hInstance hIcon hCursor hBackground menu-name class-name
-@c A way to call @code{RegisterClass} without first constructing a C
-@c @code{WNDCLASS} object.
-@c @end deffn
-@c
-@c @deffn {procedure+} default-scheme-wndproc
-@c The Scheme equivalent of the C @code{DefWindowProc}.
-@c @end deffn
-@c
-@c @node Scheme WndProcs, , Procedures, Writing windows procedures
-@c @subsection Scheme WndProcs
-@c
-@c
-@c A Scheme wndproc is of the form
-@c
-@c @cindex wndproc
-@c @example
-@c (lambda (hwnd msg wparam lparam)
-@c (cond ((= msg WM_CREATE)
-@c ...)
-@c (...
-@c ...)
-@c (else
-@c (default-scheme-wndproc hwnd msg wparam lparam))))
-@c @end example
-@c
-@c @cindex wndproc, higher-order
-@c Scheme has the advantage over C that first class procedures can be used
-@c to organize the data used by the window.
-@c A useful idiom idiom is to parameterize the code with the default
-@c behaviour.
-@c This example behaves like @var{default-wndproc}, except that it
-@c beeps every time the left mouse button is pressed.
-@c
-@c @example
-@c (define ((my-wndproc default-wndproc) hwnd msg wparam lparam)
-@c (define (default) (default-wndproc hwnd msg wparam lparam))
-@c (cond ((= msg WM_LBUTTONDOWN)
-@c (message-beep MB_OK)
-@c (default))
-@c (else
-@c (default))))
-@c @end example
-@c
-@c @noindent
-@c @code{my-wndproc} is suitable for use with @code{subclass-window!}
-@c For example,
-@c
-@c @example
-@c (subclass-window! (get-handle 1) my-wndproc)
-@c @end example
-@c Will cause the main Scheme window to beep every time the left mouse
-@c button is pressed, but otherwise work normally.
-@c
-@c In a similar fashion, Scheme wndprocs can be closed over state
-@c describing the object that the window displays or edits.
-@c An idiom for a complex kind of window is to have a record (structure)
-@c representing the object, and to create the window procedure with that
-@c object in scope.
-@c The following extended example is a framework for an editor.
-@c The @code{whizz-editor} record's @code{hwnd} field is set at window
-@c creation time so that we can get the window handle from the record. The
-@c utility of this is demonstrated in @code{whizz-editor/set-title}.
-@c
-@c @example
-@c (define-structure whizz-editor
-@c hwnd
-@c magic-flag?
-@c @var{other stuff})
-@c
-@c
-@c (define (make-whizz-editor-wndproc data)
-@c ;; @r{The following string is created once before the window comes}
-@c ;; @r{into existence}
-@c (define window-local-string (make-string 100))
-@c
-@c ;; @r{The normal wndproc}
-@c (define ((wndproc default-wndproc) hwnd msg wparam lparam)
-@c (define (default) (default-wndproc hwnd msg wparam lparam))
-@c (cond ((= msg WM_CREATE)
-@c (set-whizz-editor-hwnd! data hwnd)
-@c ...
-@c (default))
-@c (...
-@c ... (if (whizz-editor-magic-flag? data) ... ...)
-@c ...)
-@c (else
-@c (default))))
-@c
-@c wndproc)
-@c
-@c
-@c (define (create-whizz-editor)
-@c (let* ((data (make-whizz-editor 0 ...))
-@c (wndproc (make-whizz-editor-wndproc data))
-@c
-@c (create-scheme-window
-@c 0 "WHIZZ_EDITOR_CLASS" "Whizz Editor"
-@c (+ WS_VISIBLE WS_OVERLAPPED)
-@c CW_USEDEFAULT CW_USEDEFAULT CW_USEDEFAULT CW_USEDEFAULT
-@c 0 0 (get-handle 0) 0
-@c (wndproc default-scheme-wndproc)))
-@c data))
-@c
-@c (define (whizz-editor/set-title wh title)
-@c (set-window-text (whizz-editor-hwnd wh) title))
-@c @end example
-@c
-@c @noindent
-@c Now we are ready to create a Whizz Editor and set its title:
-@c
-@c @example
-@c (define my-editor (create-whizz-editor))
-@c (whizz-editor/set-title my-editor "A new title")
-@c @end example
-@c
-@c @node Procedure Index, Concept Index, , Top
-@c @unnumbered Index of Procedures, Special Forms, and Variables
-@c @printindex fn
-@c
-@c @node Concept Index, , Procedure Index, Top
-@c @unnumbered Index of Concepts
-@c @printindex cp
-@c
-@c @node Procedure Index, , Writing windows procedures, Top
-@c @unnumbered Index
-@c @printindex fn
-@c
-@c @c @summarycontents
-@c
-@c @contents
-@c
-@c @c Local Variables:
-@c @c eval: (auto-save-mode -1)
-@c @c End:
-@c
-@c @bye
-
-@c WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
-@node Concept Index, , Win32 Package Reference, Top
+@node Concept Index, , Edwin, Top
@unnumbered Concept Index
@printindex cp