@end enumerate
@end titlepage
-@node Top, Running Scheme, (dir), (dir)
+@node Top, Installation, (dir), (dir)
@menu
+* Installation::
* Running Scheme:: Running Scheme
* REPL:: The Read-Eval-Print Loop
* Debugging:: Debugging
* Compiling Files:: Compiling Files
* GNU Emacs Interface:: GNU Emacs Interface
* Edwin:: Edwin
+* Win32 Package Reference::
* Variable Index:: Variable, Declaration, and Option Index
* Key Index:: Key Index
* Concept Index:: Concept Index
+--- The Detailed Node Listing ---
+
+Running Scheme
+
--- The Detailed Node Listing ---
+Installation
+
+* Generic Unix::
+* C-backend::
+* Microsoft Windows and Windows NT installation::
+* DOS::
+
+Microsoft Windows and Windows NT installation
+
+* System requirements::
+* Manifest::
+* Installation-win32:: Installation
+* Known Problems::
+
Running Scheme
* Basics of Starting Scheme:: Basics of Starting Scheme
+* Customizing Scheme::
* Command-Line Options:: Command-Line Options
* Environment Variables:: Environment Variables
+* Starting Scheme from Microsoft Windows 3.1/NT::
* Leaving Scheme:: Leaving Scheme
+Environment Variables
+
+* General Environment Variables::
+* Environment variables for Bchscheme::
+* Environment variables for PC versions::
+* Environment variables that affect Edwin::
+
The Read-Eval-Print Loop
* The Prompt and Level Number:: The Prompt and Level Number
* Standard Names:: Standard Names
* In-line Coding:: In-line Coding
* Operator Reduction:: Operator Reduction
-@end menu
+Win32 Package Reference
+
+* Overview::
+* Foreign function interface::
+* Device Independent Bitmap Utilities::
+
+Foreign Function Interface
+* Windows Types::
+* Windows Foreign Procedures::
+* Win32 API names and procedures::
-@node
+Device Independent Bitmap Utilities
+
+* DIB procedures::
+* Other parts of the DIB Utilities implementation::
+@end menu
+
+@node Installation, Running Scheme, Top, Top
@chapter Installation
-@node
+@menu
+* Generic Unix::
+* C-backend::
+* Microsoft Windows and Windows NT installation::
+* DOS::
+@end menu
+
+@node Generic Unix, C-backend, , Installation
@section Generic Unix
Installation information for Unix versions goes here.
(perhaps several a multitude of unixes?
-@node
+@node C-backend, Microsoft Windows and Windows NT installation, Generic Unix, Installation
@section C-backend
Installation information for C back-end versions goes here?
@c NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
-@node
+@node Microsoft Windows and Windows NT installation, DOS, C-backend, Installation
@section Microsoft Windows and Windows NT installation
+This section describes how to install MIT Scheme on Microsoft Windows
+3.1 and Microsoft Windows NT. For the most part installing under these
+platforms is the same.
+
+@menu
+* System requirements::
+* Manifest::
+* Installation-win32:: Installation
+* Known Problems::
+@end menu
+
+@node System requirements, Manifest, , Microsoft Windows and Windows NT installation
+@subsection System requirements
+
+MIT Scheme requires at least a 386DX with 8Mb RAM.
+The bare minimum disk space required is 5.5Mb, which gives you a command
+line interface for Scheme. We strongly recommend a more advanced
+environment. To build the Edwin editor band requires an additional
+4.3Mb. The whole installation without source code occupies 36Mb.
+
+@node Manifest, Installation-win32, System requirements, Microsoft Windows and Windows NT installation
+@subsection Manifest
+
+The installation comprises the following files:
+
+@example
+bin.zip @r{Scheme binaries}
+lib.zip @r{Smaller files from Scheme library}
+runtime.zip @r{@file{runtime.com} band}
+eddel.zip @r{@file{eddel.com}: a kit to build @file{edwin.com} band}
+compedl.zip @r{@file{compdel.com}: a kit to build @file{compiler.com} band}
+
+bcirun1.zip @r{Debugging information for runtime system}
+bcirun2.zip @r{ " " " " "}
+bcirun3.zip @r{ " " " " "}
+bcied1.zip @r{Debugging information for Edwin}
+bcied2.zip @r{ " " " "}
+bcied3.zip @r{ " " " "}
+bcicomp1.zip @r{Debugging information for compiler}
+bcicomp2.zip @r{ " " " "}
+bcicomp3.zip @r{ " " " "}
+win32s.zip @r{Win32s installation floppy from Microsoft}
+@end example
+
+
+@node Installation-win32, Known Problems, Manifest, Microsoft Windows and Windows NT installation
+@subsection Installation
+
+In each of the following steps the amount of disk space consumed is
+indicated in square brackets.
+These sizes do not include the @file{.zip} files which are required
+only during installation.
@enumerate
+@item
+MIT Scheme under Windows 3.1 requires the Win32s system to be installed.
+If you have not previously installed the Win32s system then you should
+create a floppy disk containing the contents of the @file{win32s.zip}
+file, e.g:
+
+@example
+a:
+unzip @var{wherever}\win32s.zip
+@end example
+
+Run the @file{setup} command on the floppy disk.
+
+@example
+a:setup
+@end example
+
@item
Decide on where to install MIT Scheme.
We suggest the default: @file{C:\SCHEME}.
-Create the root directory which we from now on refer to as @var{root}.
+Create the root directory which we from now on refer to as @var{scheme}.
If for example, you choose the default:
@example
@end example
@noindent
-@var{root} is the string @code{C:\scheme}
+@var{scheme} is the string `@code{C:\scheme}'.
@item
-In the @var{root} directory unzip the following essential files:
-@file{BIN.ZIP}, @file{LIB.ZIP}, @file{RUNTIME.ZIP}.
+In the @var{scheme} directory unzip the following essential files:
+@file{bin.zip}, @file{lib.zip} and @file{runtime.zip} [5.5Mb].
@example
-unzip bin.zip
-unzip lib.zip
-unzip runtime.zip
+unzip @var{wherever}\bin.zip
+unzip @var{wherever}\lib.zip
+unzip @var{wherever}\runtime.zip
@end example
+(@var{Wherever} stands for the place that you have put the @file{.zip}
+files, which might be another directory or a floppy disk.)
+
+@item
+If you are installing for Windows 3.1 only, do @emph{one} of the following:
+@itemize @bullet
@item
-If you are installing for Windows 3.1 only, either (a) put the following
-line in the @file{AUTOEXEC.BAT} file to ensure that the
-@file{@var{root}\bin\win31} directory is on the path:
+Put the following line in the @file{autoexec.bat} file to ensure that
+the @file{@var{scheme}\bin\win31} directory is on the path:
@example
-path %PATH%;@var{root}\bin\win31
+path %PATH%;@var{scheme}\bin\win31
@end example
-@noindent
-or (b) copy the files from @file{@var{root}\bin\win31} into
-@file{@var{root}\bin}.
-
-
@item
-If you are installing for Windows NT only, either (a) as system
-administrator add @file{@var{root}\bin\nt} to the @code{PATH in the
-environment (Registry ...) or (b) as an individual place
-@code{PATH=}@var{root}@code{\bin\nt} in your enviroment (use the control
-panel's system option}, or (c) copy the files from
-@file{@var{root}\bin\nt} into @file{@var{root}\bin}.
+Copy the files from @file{@var{scheme}\bin\win31} into
+@file{@var{scheme}\bin}.
+@end itemize
+@item
+If you are installing for Windows NT only, do @emph{one} of teh
+following:
+@itemize @bullet
+@item
+As system
+administrator add @file{@var{scheme}\bin\nt} to the @code{PATH} in the
+system environment (using the Registry Editor, @code{regedt32})
+@item
+As an individual place @code{PATH=}@var{scheme}@code{\bin\nt} in your
+environment (use the control panel's system option)
+@item
+Copy the files from @file{@var{scheme}\bin\nt} into
+@file{@var{scheme}\bin}.
+@end itemize
@item
If you are installing for both Windows 3.1 and Windows NT then you must
-use an option from the above that does not involve copying files, i.e.
-you must arrange for Windows 3.1 to be run with
-@file{@var{root}\bin\win31} on the path and for Windows NT to be run
-with @file{@var{root}\bin\nt} on the path.
+use use environment variables and the @code{PATH} rather than copying
+files, i.e. you must arrange for Windows 3.1 to be run with
+@file{@var{scheme}\bin\win31} on the path and for Windows NT to be run
+with @file{@var{scheme}\bin\nt} on the path.
@item
the environment variable @code{MITSCHEME_LIBRARY_PATH} is defined:
@example
-set MITSCHEME_LIBRARY_PATH=@var{root}\lib
+set MITSCHEME_LIBRARY_PATH=@var{scheme}\lib
@end example
Manager
@example
-@var{root}\bin\scheme
+@var{scheme}\bin\scheme
@end example
@noindent
If there are any problems at this stage review the installation so far.
-
+Remember that you might have to restart your machine to get the effect
+of any changes that you made in @file{autoexec.bat}.
@item
Now you should create a Program Manager group for MIT Scheme.
using the @code{File|Run} option:
@example
-@var{root}\bin\scheme -load @var{root}\etc\pmgrp
+@var{scheme}\bin\scheme -load @var{scheme}\etc\pmgrp
@end example
@noindent
@item
To install the Edwin editor you need to build the @file{edwin.com} band.
-First unpack the delta file:
+First unpack the delta file @file{eddel.com} [1.6Mb]:
@example
-cd @var{root}
-unzip eddel.com
+cd @var{scheme}
+unzip @var{wherever}\eddel.zip
@end example
To build @file{edwin.com} start the `build EDWIN.COM band' icon, or run
the following command:
@example
-@var{root}\bin\scheme -large -load @var{root}\etc\build -eval (edwin.com)
+@var{scheme}\bin\scheme -large -load @var{scheme}\etc\build -eval (edwin.com)
@end example
@noindent
-This will load in @file{eddel.com} and create the new band.
+This will load in @file{eddel.com} and create the new band [4.3Mb].
After a successful build the program will exit.
@item
To install the compiler you need to build the @file{compiler.com} band.
-First unpack the delta file:
+First unpack the @file{compdel.com} delta file [2.5Mb]:
@example
-cd @var{root}
-unzip compdel.com
+cd @var{scheme}
+unzip @var{wherever}\compdel.zip
@end example
To build @file{compiler.com} start the `build COMPILER.COM band' icon,
or run the following command:
@example
-@var{root}\bin\scheme -large -load @var{root}\etc\build -eval (compiler.com)
+@var{scheme}\bin\scheme -large -load @var{scheme}\etc\build -eval (compiler.com)
@end example
@noindent
-This will load in @file{compdel.com} and create the new band.
-After a successful build the program will exit.
+This will load in @file{compdel.com} and create the new
+@file{compiler.com} band [4.8Mb]. After a successful build the program
+will exit.
@item
If you want both Edwin and the compiler in one band you should build the
-@file{all.com} band.
-First unpack the delta files:
+@file{all.com} band. First unpack the delta files [4.1Mb unless already
+unpacked in previous steps]:
@example
-cd @var{root}
-unzip eddel.com
-unzip compdel.com
+cd @var{scheme}
+unzip @var{wherever}\eddel.zip
+unzip @var{wherever}\compdel.zip
@end example
To build @file{all.com} start the `build ALL.COM band' icon, or run the
following command:
@example
-@var{root}\bin\scheme -large -load @var{root}\etc\build -eval (all.com)
+@var{scheme}\bin\scheme -large -load @var{scheme}\etc\build -eval (all.com)
@end example
@noindent
-This will load in both @file{eddel.com} and @file{compdel.com} and
-create the new band. After a successful build the program will exit.
+This will load in both @file{eddel.com} and @file{compdel.com} into the
+runtime band and create the new band [6.7Mb]. After a successful build
+the program will exit.
@item
Any combination of @file{edwin.com}, @file{compiler.com} and
-@file{all.com} may be used. It is not necessary to build either of
-@file{edwin.com} and @file{compiler.com} before building and using
-@file{all.com}. After building the bands you may tidy the MIT Scheme
-group by removing the mincer icons and recover disk space
-by deleting the delta files.
+@file{all.com} may be used. They may be built in any order: it is not
+necessary to build either of @file{edwin.com} and @file{compiler.com}
+before building and using @file{all.com}. After building the bands you
+may tidy the MIT Scheme group by removing the mincer icons and recover
+disk space by deleting the delta files [4.1Mb] and the
+@file{runtime.com} band [2.3Mb] if you do not need it.
To create icons that use @code{bchscheme} instead of @code{scheme} copy
the icons and edit the command lines to change `scheme' to `bchschem'
(that is right: no tailing `e').
@item
-Debugging information can be installed by uncompressing the files in the
-Scheme root directory @var{root}. The most useful is the runtime
-debugging info which is in @file{RUNBCI.ZIP}. These files can be
-installed in another directory. If this is done then set the
-@var{MITSCHEME_INF_DIRECTORY} environment variable to this directory.
-@file{EDWINBCI.ZIP} and @file{COMPBCI.ZIP} hold the debugging info files
-for Edwin and the compiler respectively.
+Debugging information can be installed by uncompressing the
+@file{bci*.zip} files in the Scheme root directory @var{scheme}. The
+total space required for all of the debugging information is 11.3Mb.
+The most useful is the runtime debugging info which is in
+@file{bcirun1.zip} through @file{bcirun3.zip} [3.6Mb installed].
+
+Debugging information files can be installed in the Scheme root
+directory or in another directory. If another directory is chosen then
+set the @code{MITSCHEME_INF_DIRECTORY} environment variable to this
+directory. @file{bcied1.zip} through @file{bcied3.zip} [3.8Mb
+installed] and @file{bcicomp1.zip} through @file{bcicomp3.zip} [4Mb
+installed] hold the debugging information files for Edwin and the
+compiler respectively.
@end enumerate
-@node
-@subsection random junk
-
-@table @asis
-@item Win32s DLLs
-
-@item *
-
-@item Binaries
-Choice 1: 3.1 xor NT: put DLLs with scheme.exe
-Choice 2: 3.1 and NT: (a) two bin directories
-(b) One bin, DLLs in separate directories, these directories on the
-path.
-
-
-@end table
-
-@node
-@subsection Manifest
-
-
-BIN.ZIP
+@node Known Problems, , Installation-win32, Microsoft Windows and Windows NT installation
@subsection Known Problems
-@itemize @asis
+@itemize @bullet
-@item *
-MIT Scheme is a lot more robust under NT than Windows 3.1
+@item
+MIT Scheme is more robust under NT than Windows 3.1
-@item Exclusive file access [NT]
+@item
+Exclusive file access [NT].
Can't write a file that is still open for reading. (e.g.
mismatched paren in @code{(load "foo.scm")}. Work-around: Quit to top
level. Do a @code{(gc-flip)} to force file to be closed. Now you will
be able to save the file.
+@item
+@code{MITSCHEME_INF_DIRECTORY} sometimes does not work.
+The runtime system cannot find the debugging information unless it is on
+the @file{C:} drive.
-
-@item Edwin autoloads
+@item
+Edwin autoloads.
A few files that are automatically part of Edwin under unix are not part
of Edwin in the PC. These can be loaded manually from the auto-load
directory, for example, by putting
-@node
-@subsection NT build
-
-The windows/NT version can only be built under Windows NT.
-
-@table @asis
-@item no TOUCH command
-Create the following 1 line script in @file{TOUCH.BAT}:
-
-@example
-echo on > %1
-@end example
-
-@item can't find @file{w32sut.h}
-These files are a part of Win32S: @file{w32sut.h}, @file{?.dll}, @file{?.dll}
-You need to copy @file{w32sut.h} from
-@end table
-
-
-TTD
-
-w32sut.h & dlls to ntutl/config
+@c @node
+@c @subsection NT build
+@c
+@c
+@c @table @asis
+@c @item Build
+@c The Windows/NT version can be built only under Windows NT.
+@c
+@c @item no TOUCH command
+@c Create the following 1 line script in @file{TOUCH.BAT}:
+@c
+@c @example
+@c echo on > %1
+@c @end example
+@c
+@c @item can't find @file{w32sut.h}
+@c These files are a part of Win32S: @file{w32sut.h}, @file{?.dll}, @file{?.dll}
+@c You need to copy @file{w32sut.h} from
+@c @end table
+@c
+@c
+@c w32sut.h & dlls to ntutl/config?
@c NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
-@node
+@node DOS, , Microsoft Windows and Windows NT installation, Installation
@section DOS
Installation information for DOS version goes here
-@node Running Scheme, REPL, Top, Top
+@node Running Scheme, REPL, Installation, Top
@chapter Running Scheme
This chapter describes how to run MIT Scheme on a unix system or a PC
running DOS, Microsoft Windows or Windows NT.
-It also describes how you can customize the behaviour of MIT Scheme
+It also describes how you can customize the behavior of MIT Scheme
using command-line options and environment variables.
@menu
* Basics of Starting Scheme:: Basics of Starting Scheme
+* Customizing Scheme::
* Command-Line Options:: Command-Line Options
* Environment Variables:: Environment Variables
+* Starting Scheme from Microsoft Windows 3.1/NT::
* Leaving Scheme:: Leaving Scheme
@end menu
-@node Basics of Starting Scheme, Command-Line Options, Running Scheme, Running Scheme
+@node Basics of Starting Scheme, Customizing Scheme, , Running Scheme
@section Basics of Starting Scheme
Usually, MIT Scheme is invoked by typing
@cindex subsystem versions
@cindex SF, version
-@cindex CREF, version
@cindex compiler, version
@cindex Edwin, version
@cindex student package, version
@cindex compatibility package, version
Following this there may be additional version numbers for specific
subsystems. @samp{SF} refers to the scode optimization program
-@code{sf}, @samp{Liar} is the native-code compiler, @samp{CREF} is the
-cross-reference generator, @samp{Edwin} is the Emacs-like text editor,
+@code{sf}, @samp{Liar} is the native-code compiler,
+@samp{Edwin} is the Emacs-like text editor,
and @samp{Student} is the S&ICP compatibility package.
@cindex compiler, starting
to load the world image containing the compiler.
-@node
+@node Customizing Scheme, Command-Line Options, Basics of Starting Scheme, Running Scheme
@section Customizing Scheme
You can customize your setup by using a variety of tools:
and constant space is available.
-@node Command-Line Options, Environment Variables, Basics of Starting Scheme, Running Scheme
+@node Command-Line Options, Environment Variables, Customizing Scheme, Running Scheme
@section Command-Line Options
Scheme accepts the command-line options detailed in the following
and if that is not defined, 0 is used, disabling overlapped writes.
@end table
-@node Environment Variables, Leaving Scheme, Command-Line Options, Running Scheme
+@node Environment Variables, Starting Scheme from Microsoft Windows 3.1/NT, Command-Line Options, Running Scheme
@section Environment Variables
are specific to MIT Scheme. The environment variables are organised
according to the parts of MIT Scheme that they affect.
-@node
+@menu
+* General Environment Variables::
+* Environment variables for Bchscheme::
+* Environment variables for PC versions::
+* Environment variables that affect Edwin::
+@end menu
+
+@node General Environment Variables, Environment variables for Bchscheme, , Environment Variables
@subsection General Environment Variables
@table @asis
@end table
-@node
+@node Environment variables for Bchscheme, Environment variables for PC versions, General Environment Variables, Environment Variables
@subsection Environment variables for Bchscheme
@table @asis
@code{-gc-write-overlap}.
@end table
-@node
+@node Environment variables for PC versions, Environment variables that affect Edwin, Environment variables for Bchscheme, Environment Variables
@subsection Environment variables for PC versions
These environment variables only make sense to the Microsoft Windows,
@end table
-@node
+@node Environment variables that affect Edwin, , Environment variables for PC versions, Environment Variables
@subsection Environment variables that affect Edwin
@table @asis
@end table
-@node
+@node Starting Scheme from Microsoft Windows 3.1/NT, Leaving Scheme, Environment Variables, Running Scheme
@section Starting Scheme from Microsoft Windows 3.1/NT
There are two distinct versions of MIT Scheme that run on IBM
-@node Leaving Scheme, , Environment Variables, Running Scheme
+@node Leaving Scheme, , Starting Scheme from Microsoft Windows 3.1/NT, Running Scheme
@section Leaving Scheme
There are two ways you can leave Scheme. The first is to evaluate
* The Current REPL Environment:: The Current REPL Environment
@end menu
-@node The Prompt and Level Number, Interrupting, REPL, REPL
+@node The Prompt and Level Number, Interrupting, , REPL
@section The Prompt and Level Number
@cindex prompt, REPL
* Debugger:: The Debugger
@end menu
-@node Subproblems and Reductions, Debugger, Debugging, Debugging
+@node Subproblems and Reductions, Debugger, , Debugging
@section Subproblems and Reductions
@cindex subproblem
* Declarations:: Declarations
@end menu
-@node Compilation Procedures, Declarations, Compiling Files, Compiling Files
+@node Compilation Procedures, Declarations, , Compiling Files
@section Compilation Procedures
@deffn {procedure+} cf filename [destination]
* Operator Reduction:: Operator Reduction
@end menu
-@node Standard Names, In-line Coding, Declarations, Declarations
+@node Standard Names, In-line Coding, , Declarations
@subsection Standard Names
Normally, all files have a line
Like evaluating @code{(proceed)} (@code{xscheme-send-proceed}).
@end table
-@node Edwin, Variable Index, GNU Emacs Interface, Top
+@node Edwin, Win32 Package Reference, GNU Emacs Interface, Top
@chapter Edwin
This chapter describes how to start Edwin, the MIT Scheme text editor.
state that prevents Edwin from running.
@end deffn
\f
-@node Variable Index, Key Index, Edwin, Top
+@c WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
+@node Win32 Package Reference, Variable 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
+Microsoft 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
+
+@c @node Acknowledgements, Overview, Top, Top
+@c @unnumbered Acknowledgements
+@c
+@c Somebody must have helped!
+@c GJR, Alan Bawden.
+
+@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
+Microsoft 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.
+@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 compononents:
+
+@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
+Microsoft Windows 3.1 and Microsoft 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 umy-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 nul-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-window "Hi") @result{} #t
+ @r{;; Changes window's title/text}
+
+set-window-title @result{} #[compiled-procedure 56 ...]
+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}.
+
+
+[It might be worthwhile just keeping the same names. As the
+Win32 API procedure names are uniformly `WordWordWordACRONYMWord', case
+insensitivity is unlikely to be a problem. The only problem is the
+protential for a clash between a procedure name and a type
+name.]
+
+
+@node Device Independent Bitmap Utilities, , Foreign function interface, Win32 Package Reference
+@section Device Independent Bitmap Utilities
+
+
+The Device Independent Bitmap (DIB) utilities DLL @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 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, 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 "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 "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 "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 "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 "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
+rectange 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 "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 "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 "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 "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 "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 "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 "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 documentation on how to create DLLs. Look at the code in the
+@file{WIN32/DIBUTILS} directory of the Scheme source.
+
+Please note:
+@itemize
+@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
+\f
+@node Variable Index, Key Index, Win32 Package Reference, Top
@unnumbered Variable, Declaration, and Option Index
@printindex fn