From 4f6092090200052f5383b4d69f2c77afc56f03bb Mon Sep 17 00:00:00 2001 From: Stephen Adams Date: Sun, 5 Dec 1993 16:17:38 +0000 Subject: [PATCH] *** empty log message *** --- v7/doc/ref-manual/scheme.texinfo | 936 +++++++++++++++++++++++++++++- v7/doc/user-manual/user.texinfo | 951 +------------------------------ 2 files changed, 944 insertions(+), 943 deletions(-) diff --git a/v7/doc/ref-manual/scheme.texinfo b/v7/doc/ref-manual/scheme.texinfo index 35a854c8c..3f3877edd 100644 --- a/v7/doc/ref-manual/scheme.texinfo +++ b/v7/doc/ref-manual/scheme.texinfo @@ -2,7 +2,7 @@ @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 @@ -184,6 +184,7 @@ facilities available for developing programs in MIT Scheme, and the * File-System Interface:: * Error System:: * Graphics:: +* Win32 Package Reference:: * Index:: --- The Detailed Node Listing --- @@ -431,6 +432,23 @@ X Graphics * 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 @@ -14436,7 +14454,7 @@ can be signalled by any @sc{i/o} operation, whether or not it involves files. @end defvr -@node Graphics, Index, Error System, Top +@node Graphics, Win32 Package Reference, Error System, Top @chapter Graphics @cindex graphics @@ -15534,11 +15552,923 @@ These operations alter the current values of the text characteristics. 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 diff --git a/v7/doc/user-manual/user.texinfo b/v7/doc/user-manual/user.texinfo index 45e71f186..1886d554b 100644 --- a/v7/doc/user-manual/user.texinfo +++ b/v7/doc/user-manual/user.texinfo @@ -120,26 +120,25 @@ Scheme with Edwin and GNU Emacs. * 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 @@ -205,23 +204,6 @@ Comparison of Edwin 3.82 to Emacs 18.57 * 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 @@ -230,8 +212,8 @@ Device Independent Bitmap Utilities @menu -* Unix:: -* PC Operating Systems:: +* Unix:: +* PC Operating Systems:: @end menu @node Unix, PC Operating Systems, , Installation @@ -242,7 +224,7 @@ Installation information for Unix versions goes here. @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 @@ -259,7 +241,7 @@ Note that we have only tested the DOS version on Microsoft DOS 5.0. @menu * System requirements:: * Manifest:: -* PC Installation:: Installation +* PC Installation:: Installation @end menu @node System requirements, Manifest, , PC Operating Systems @@ -648,7 +630,7 @@ General release notes @menu * Unix Release Notes:: -* C Back-End Release Notes:: +* C Back-End Release Notes:: * DOS:: @end menu @@ -3503,7 +3485,7 @@ Like typing @kbd{C-c C-b} when running Scheme without Emacs 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. @@ -4114,919 +4096,8 @@ the matching delimiter. 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 -- 2.25.1