`Syntax10.Scn.Fnt ZParcElemsAlloc Syntax16b.Scn.FntSyntax8.Scn.Fnt Syntax12.Scn.FntKSyntax12b.Scn.Fnt I' @?'LineElemsAlloc ?' Z j8FoldElemsNew#Syntax10.Scn.Fnttt Permission to use, copy, modify and distribute this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of ETH not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. ETH makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty. ETH DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ETH BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. Syntax Font, Copyright 1968 Linotype AG Syntax is a registered trademark of Linotype AG. The Syntax font is owned and used by permission of Linotype AG. RASTER DATA DESCRIBING THE SYNTAX FONT IS SUPPLIED WITH THIS RELEASE OF OBERON AND MAY BE USED ONLY IN CONJUNCTION WITH THE OBERON SOFTWARE. ANY OTHER USE OF THE SYNTAX FONT REQUIRES A LICENSE FROM LINOTYPE AG. PostScript versions of the fonts in the Syntax family are available from Linotype, Inc. and its subsidiaries. Oberon and Oberon for Windows are trademarks of Eidgenssische Technische Hochschule, Zrich Microsoft, MS and MS-DOS are registered trademarks of Microsoft Corporation. NT, Win32, Win32s, Windows and Windows NT are trademarks of Microsoft Corporation. IBM is a registered trademark of International Business Machines Corporation. Intel is a registered trademark and i486 is a trademark of Intel Corporation. Syntax10i.Scn.Fnt 8 Z 2  Z Syntax12i.Scn.Fnt8)N'*,*' 6)>)e Z ab 2 [0 Z  Courier12.Scn.Fnt2 Z B Z    Zu U(g  qd g= Z   .8G. Zr  l9 ^  Z %h#.  Hb: K0  n  3z0P Z Kp1*8! ca49 Z 7+(WB='nI2u  k(JYF  %UQ)/W    G O 2  a #  4    ["7F ,." 1+Qv "'fO [!B ;0,> "C(*X  0 Q'0%;  zv  ,(% 40 Q' Z  GW4)G$U  0 Q'UIH93F~0 Q' e  S8.G 8 /  0 Q'50 Q' = F     a; + TableElemsAlloc;Syntax10.Scn.Fnt/Syntax12.Scn.Fnt/nohead V /left 30 /top 10 /column LLLL /table n register n register 0 EAX / AX / AL 4 ESP / SP / AH 1 ECX / CX / CL 5 EBP / BP / CH 2 EDX / DX / DL 6 ESI / SI / DH 3 EBX / BX / BL 7 EDI / DI / DL  ϒOberonTM for Windows User's Guide Release 4.0-2.0 (Sept 96) Matthias Hausner Christoph Steindl Copyright 1993-95, ETH Zrich, JKU Linz Contents 1 Introduction 2 Installation and Startup 3 Release Notes 4 Differences to the Original Oberon 5 Module Reference 5.1 Standard Modules 5.2 Modules unique to Oberon for Windows 6 Calling Windows API and DLL functions from Oberon Programs 7 The Compiler    Disclaimer and legal issues (click on one of the triangles)   1 Introduction Oberon for Windows is an implementation of OberonTM for Microsoft Windows NT, Microsoft Windows 95, and Microsoft Windows 3.1. Both the programming language Oberon-2 and the Oberon System have been implemented. For a complete description of the language and the system, the following books are recommended: N. Wirth and M. Reiser: Programming in Oberon - Steps beyond Pascal and Modula-2 Addison Wesley, 1992, ISBN 0-201-56543-9 Tutorial for the Oberon programming language and concise language reference. H. Mssenbck: Object-Oriented Programming in Oberon-2 Springer-Verlag, 1993, ISBN 3-540-56411-X Covers the basic concepts of OOP, shows typical application patterns, and gives useful design hints. Presents the design and implementation of an object-oriented window system with an integrated text and graphics editor. Contains Oberon-2 language definition. H. Mssenbck: Objektorientierte Programmierung in Oberon-2 Springer-Verlag, 1993, ISBN 3-540-55690-7 German version of Object-Oriented Programming in Oberon-2 M. Reiser: The Oberon System. User Guide and Programmer's Manual Addison Wesley, 1991, ISBN 0-201-54422-9 User manual for the Oberon programming environment and reference for the standard module library. Includes working examples of how to extend the Oberon system with new commands and frame classes. N. Wirth and J. Gutknecht: Project Oberon. The Design of an Operating System and Compiler Addison Wesley, 1992, ISBN 0-201-54428-8 Program listings with explanations for the whole Oberon system, including the compiler for NS32000. The Oberon-2 language reference is also available as on-line documentation in Oberon2.Report.Text. The original Oberon implementation is an operating system running on a proprietary hardware, the Ceres workstation. Oberon for Windows, however, is not an operating system but runs as a Windows application. The screen output of the Ceres workstation is shown in a Windows window. This window can be controlled by the Window Manager, i.e. it can be moved, resized or iconized. Upon application startup, the Oberon window is maximized and covers the entire screen area. The size of the virtual Ceres screen is the size of the client area of the maximized Oberon window. This size remains fixed, even if the window is resized. If the Oberon window does not cover the whole screen, only the upper left corner of the virtual Ceres display is visible. The Oberon user interface was designed with a large bitmap display in mind. Oberon works best with a display of 1024 by 768 pixels or bigger. However, Oberon for Windows will run with any size display, but working with VGA resolution is far from optimum. Bug Reports Serious problems or bug reports can be mailed to oberon@ssw.uni-linz.ac.at or sent to Oberon for Windows, Abteilung fr Systemsoftware, Johannes Kepler Universitt Linz, Austria. Please try to be as specific and concise as possible, since this makes processing of messages faster and easier. You should also mention the version number and host operating system you use (just copy the line that appears in the log viewer when Oberon is started). Please allow one week for answers. Acknowledgements Many people have contributed to Oberon for Windows. The heap management and runtime support for types were initially implemented for DECOberon by Rgis Crelier. Niklaus Mannhart wrote the compiler back-end. Marc Brandis answered many questions about the Oberon system and Microsoft Windows. Many thanks also go to Robert Hess who greatly helped to master the Windows API. Last but no least I would like to thank all those who helped by testing and using Oberon for Windows and pointing out deficiencies.  2 Installation and Startup See the Readme file for instructions on how to install Oberon. Starting Oberon Oberon for Windows is started with the following command syntax:  oberon [-h heapsize-in-MB] [-x module command] [-b bootfile-name] [-i ini-file] [-t] [-l] [-s] where - heapsize-in-MB is the size of the allocated Oberon heap in megabytes (default: -h 4) - the command module.command is executed (default: -x Oberon Loop) - bootfile-name is the name of the boot file (default: -b Oberon.Hex) The boot file must be in the same directory as oberon.exe. - ini-file is the name of a file that is used to store configuration data (default: oberon.ini), see description of module Registry. If no explicit path is given, the file is searched for in the following directories: (1) current directory, (2) Windows system directory, (3) Windows directory, (4) in all directories listed in the PATH environment variable. - Option t means "no title bar". The Oberon window is maximized such that the client area of the window covers the whole screen, i.e. the title bar of the window is not visible. - Option l enables output written with the module Console. Console is a useful module for low-level debug output. If this option is not specified, output from module Console is lost. Under Windows NT, output written with Console appears in a console window which is allocated when Oberon is started. Under Windows 3.1, a development utility called DBWIN.EXE (from Microsoft) can be used to display the output. (Technically, under Windows 3.1 the API function OutputDebugString is used to write console output, and under NT the C library printf function is used) - Option s slows down the startup process. The messages generated during the startup process can then be read more easily. Quitting Oberon The command System.Quit terminates the Oberon application. This is the normal way to exit Oberon for Windows. Alternatively, the application can be terminated by choosing "Close" in the application window's system menu or by using the keyboard accelerator Alt-F4. Converting Old Files to Files without Headers After installing Oberon for Windows 95/NT you might want to use your old files, which contain a header that was used to store the long file name. You can skip these headers from the files by executing the command Win31File.SkipHeader which takes a list of files as parameters. 3 Release Notes New Features in this Release - Pictures in various colours, improved colour palette handling - Full reference information generated by compiler, used by System.State and trap viewer; implemented in module Ref, described in Ref.Text, used by HeapInspector, Mirrors - Windows 95/NT version: no mapping of file names - Paths in Oberon.Ini can be specified relative to startup directory. - Available packages: FileManager, FTP, Web, Mail Restrictions and Known Bugs in Release 4.0-1.4 - Modules Diskette, Backup, and Tar are not supported under Windows 3.1. - The Oberon window should be the topmost window on the screen, or scrolling may not work correctly. - On Windows 3.1, SHARE sometimes causes troubles resulting in a dialog box "Sharing violation", or in traps when opening a file. If this happens, increase the value after the /F option on share's command line arguments and reboot the machine. (SHARE /F:16348 /L:255 are the minimal values.) If this does not help, remove SHARE completely from AUTOEXEC.BAT. Changes since Release 4.0-1.3 - Various compiler bugs have been fixed. - Installable printer drivers and a PostScript printer driver (see Printing below). - TextFrames support cursor up/down keys. - Middle-Right interclick on a text file name opens a viewer containing that text. Changes since Release 4.0-1.2 - An installation program has been added. - New command System.CreateDir added. - System.Directory writes full path names of files instead of just the file names. - The file translation table $filedir.$$$ will not be deleted in a directory that has the read-only attribute set. This allows for network installations of Oberon for Windows where the system files reside on a server directory that may be shared.  4 Differences to the Original Oberon This section is about the differences to the original Oberon system from a user's point of view. The original Oberon system is described in The Oberon System by M. Reiser (see section 1). The differences in module interfaces are described in the next section. Printing Oberon for Windows supports printer drivers that can be installed at run time. The default printer driver uses Windows' regular printing mechanisms to produce output. Since Oberon's Syntax font family is not available under Windows, it is substituted with a similar TrueType font. A second printer driver produces a PostScript file as output, which in turn can be sent to any PostScript printer with a utility command like lpr. The generated PostScript file is self-contained in that it containes a complete description of the used Oberon fonts. Default Printer Driver. When printing, the default printer and its default settings as specified in Windows' Print Manager is used. The default printer driver can be installed by executing the command Printers.InstallDefault. In the original Oberon on Ceres, the commands Edit.Print, Draw.Print etc. accept a print server name as the first Parameter (usually called Pluto). This server name is ignored in when using the default printer driver. The Oberon font families Syntax and Syndor are not available as printer fonts. They are substituted by TrueType fonts instead. By default, both fonts are substituted by the TrueType font Arial. This default mapping can be changed by defining the Key PrinterFonts in the registry section System (see below). PostScript File Generator. The PostScript printer driver can be installed by executing the command PSPrinter.Install. When using this printer driver, commands like Edit.Print or Draw.Print must be followed by a legal DOS file name. This name is used to create the PostScript file. E.g. the command Edit.Print &out.ps * (omit the ampersand in the Windows 95/NT version of Oberon, see section about Oberon files and DOS files) would create a PostScript file named out.ps in the current directory. This printer driver uses original Oberon printer fonts to produce output. (Oberon printer font files end in *.Pr3.Fnt.) In the standard distribution, only the printer fonts for the Syntax and Math font families are distributed. Additional fonts can be ftp'ed from neptune.inf.ethz.ch/pub/Oberon/Windows. An attempt to print text containing characters in a font whose printer font is not available results in a runtime error. Registry Oberon for Windows has a mechanism to store configuration data permanently. The permanent storage is called the registry. The registry is structured hierarchically into sections and keys. Each section can be thought of as a dictionary that associates a value with a key. Module Registry provides a program interface to the registry (see below). The user interface is embodied in the commands System.Set and System.Get. System.Set ( ^ | section key := [ value ] ) Enter a section and key in the registry and associate a value with it. If a value is not given, the entry for the given section and key is removed from the registry. Section, key, and value may be either names or strings. System.Get ( ^ | section [ key ] ) Inspect the value of a given section and key in the registry. If a key is not given, all keys contained in section are listed together with their associated values. Section and key may be either names or strings. Currently, there are two registry sections supported by Oberon for Windows. The section System contains system-specific settings. The section Fontmap contains a list of screen fonts that are to be substituted by other fonts (see Font Substitution on the Screen below). The keys of section System are  Key Value -------------------------------------------------------------------- DefaultFont A font name. The font will be used as the default font the next time Oberon is started. E.g.: System.Set System DefaultFont := Syntax8.Scn.Fnt PrinterFonts A list of pairs of the form Font Substitution { ";" Font Substitution }. When printing a document, the fonts of the family Font are substituted with the font Substitution. Changes will take effect upon the next time Oberon is started. See the description of Module Printer for more details. E.g.: If your system has a TrueType font Helvetica installed, the command System.Set System PrinterFonts := "Syntax Helvetica" will configure Oberon to print Syntax fonts as Helvetica. Directories A list of absolute path names, separated by semicolons. When Oberon opens a file and no explicit path is given, it looks first in the current directory, then in all the directories listed here, and finally in the Oberon directory.  Font Substitution on the Screen The Oberon for Windows font subsystem allows the user to map specific fonts onto different fonts. It may for example be convenient to map Syntax10.Scn.Fnt to Syntax8.Scn.Fnt on VGA displays. The font mapping table is stored in the registry. If a section Fontmap is present, the keys of the section are interpreted as font names and the associated values are the substituted fonts. You can for example substitute Syntax8.Scn.Fnt for Syntax10.Scn.Fnt by issuing the command System.Set Fontmap Syntax10.Scn.Fnt := Syntax8.Scn.Fnt. The mapping will be stored permanently in the registry. You must restart Oberon for Windows for the changes to become effective. To inspect all mappings, execute the command System.Get Fontmap ~. To remove a particular mapping, execute System.Set Fontmap Syntax10.Scn.Fnt := ~. See the description of commands System.Set and System.Get for detailed information. Note: This feature is supposed to mend problems on displays with small resolutions like VGA screens, where one could substitute the font Syntax10.Scn.Fnt by Syntax8.Scn.Fnt, for example. The fonts are substituted on the display only, but not when printed. Moreover, the metrics of parcs are not affected by font substitution. Oberon Files vs. DOS Files Oberon for Windows 95/NT uses the built-in support for long file names of Windows 95/NT. Oberon for Windows 3.1 distinguishes between Oberon files and DOS files. In order to support 32 character file names, Oberon files contain a small header of information containing their file name (see the description of module Files for further details). DOS files do not contain such a header. To specify a DOS file (Oberon for Windows 3.1 version only), you must prepend an ampersand character "&" to the file name proper. For example, to edit the DOS ASCII test file c:\autoexec.bat, you will have to execute the command Edit.Open c:\&autoexec.bat . To store the file in plain ascii format, mark the viewer containing the text (its name in the title bar is c:\&autoexec.bat) and execute EditTools.StoreAscii *. Files from Oberon implementatios other than Oberon for Windows or DOSOberon do not contain that header. Nevertheless they can be opened like other Oberon files. When they are stored the next time, a header is inserted. To remove the header, just execute System.CopyFiles Drive:\Path\Filename.Ext => Drive:\Path\&Filename.Ext ~. If you copy Oberon files to floppy with the DOS copy command and read them in on a non-Windows Oberon, the file will still contain a header and you will see it when you open the file with Edit.Open (the header starts with the letters "oB"). To copy files on floppy correctly, use the command System.CopyFiles and specify A or B as the destination drive. For the sake of convenience, file names on floppies are always interpreted as DOS files, it is not necessary to prepend the "&" character. When files are stored on floppy disks using either the Backup or Tar utility, the header is ommitted. The files can be read by any other Oberon implementation that supports these tools. Support for Multiple Directories The original Oberon implementation uses a flat file directory, i.e. does not support subdirectories. Oberon for Windows allows to open files from any directory, including floppy disks. For each directory that contains Oberon files, a translation table is built that associates 32 character Oberon file name to DOS file names. These directories containing Oberon files must be specified in the registry section System under the key name Directories. When Oberon opens a file and no explicit path is given, it looks first in the current directory and then in all the directories listed under the registry entry System Directories. The translation tables are stored in the respective directories. The file name for the tables is "$FILEDIR.$$$". If ever the translation table becomes inconsistent, it is sufficient to delete these files and restart Oberon. The tables will be built up from scratch using the information found in the file headers of Oberon files. See the description of module Files for further details. Directories on floppy disks have no translation table and the files in such a directory do not have a header. When storing a file on floppy, the file name is simply truncated to conform to the "eight plus three" naming convention. Only paths that start with "A:" or "B:" are supposed to refer to a floppy disk. There is no mapping of long names to 8.3 names for the names of directories. Oberon imposes no restrictions on the length of the names of directories. If the underlying operating system permits long directory names (like Windows 95 and Windows NT), the names of directories can be longer than 8.3 characters, otherwise the will be truncated. Support for systems with two-button mice For PCs with a two button mouse, the Ctrl-key of the PC keyboard emulates the middle mouse button. The first time Oberon for Windows detects a middle-mouse-key-down event, this emulation is disabled. 5 Module Reference This section describes differences to the standard modules described in The Oberon System by M. Reiser (see section 1). It also describes modules unique to Oberon for Windows. 5.1 Standard Modules Files The interface to the file system is identical with that of the original Oberon system. However, due to the underlying operating system, some differences need to be discussed. Oberon file names may be as long as 32 characters and may contain more than one dot, whereas on the DOS FAT file system names are restricted to the well-known "eight plus three" characters with a single dot between the file name and the file name extension. In order to be compatible with other Oberon implementations, Oberon for Windows maintains a translation table that maps Oberon file names to DOS file names. This table is kept in memory while Oberon is runing and is written to disk when the application is exited. Since this table is of extreme importance for the proper working of Oberon, it is stored again in a distributed manner: Files that are created by Oberon have a 34 byte header stored 'inside' the file itself. The header consists of a two byte tag and the 32 byte Oberon file name. When the cached translation table is not found at system startup, or if the cached table is found to be inconsistent, it is newly built up by scanning all files in the directory and extracting the Oberon file name from their headers. This header is never 'seen' from inside Oberon. Sometimes one would like to create regular DOS files or open files that have not been created by Oberon for Windows. To distinguish DOS files from Oberon files, an ampersand character "&" is prefixed to the file name proper. The ampersand itself is not part of the file name, but just directs the Files module to treat the file as a DOS file, i.e. expecting no header when the file is opened and writing no header when the file is registered. For example, the autoexec.bat file could be opened for editing with the command Edit.Open c:\&autoexec.bat and stored with the command EditTools.WriteAscii *. When files are stored on floppy disks using either the Backup or Tar utility, the header is ommitted. The files can be read by any other Oberon implementation that supports these tools. This way of integrating DOS files into Oberon has proven to be most convenient. However, it has some drawbacks, too. Files created on Oberon for Windows are not binary compatible with files created on other Implementations of Oberon. E.g. files created on a Unix implementation that are downloaded electronically to either a FAT or NTFS directory do not have a header. Nevertheless they can be opened like other Oberon files. Files created with DosOberon do have the same kind of header and can be opened without the prefix. Oberon for Windows allows to open files from any directory, including floppy disks. Translation tables for directories are built on demand. You can specify a number of directories which are sought automatically when a file shall be opened in the section Directories in the file OBERON.INI. When Oberon starts up, it builds the translation table for these directories. After the system has successfully booted, the cached translation tables are destroyed, such that after a system crash they are rebuilt from scratch. Upon normal exit of Oberon, the translation tables of all directories which have either been specified in the Directories section of the OBERON.INI file or are currently used are written to disk. The files that contain this table have the name "$FILEDIR.$$$". If ever the translation table becomes inconsistent, it is sufficient to delete these files and restart Oberon. Directories on floppy disks have no translation table and the files in such a directory do not have a header. When storing a file on floppy, the file name is simply truncated to conform to the "eight plus three" naming convention. Only paths that start with "A:" or "B:" are supposed to refer to a floppy disk. Following a summary of differences to the original Oberon implementation: Open (name: ARRAY OF CHAR): File; New (name: ARRAY OF CHAR): File; Delete (name: ARRAY OF CHAR; VAR res: INTEGER); Rename (old, new: ARRAY OF CHAR; VAR res: INTEGER); File names may consist of a drive specifier, a path, and a file name. An ampersand character previous to the first character of the file name specifies a DOS file, i.e. a file with no header. Display The procedures DefCC, DefCP, DrawCX, FadeCX, InitCC, InitCP, SetCursor are not implemented. Procedure SetMode inspects only set element {2}, i.e. SetMode can only be used to switch betwee black-on-white and white-on-black mode. Procedure Map returns always 0 (the display bitmap is not directly accessible). The procedure NewPattern(VAR image: ARRAY OF SET; ... ) constructs a pattern from the bitmap given in image. image[1] defines the bottom line of the pattern. image[0] is not used. The procedures CopyPatternC, ReplPatternC, ReplConstC, CopyBlockC, and DotC take a frame parameter F against which the display output is clipped. ReplPatternC also takes a "pin point" or "pattern origin" xp, yp to align pattern output. Input Input.Time() returns 'ticks' in increments of 1/Input.TimeUnitth of seconds (1/1000th of seconds). Some special keys on the Ceres keyboard are mapped to the PC keyboard as follows:  PC Keyboard Ceres Keyboard Function Backspace DEL Delete - delete right in text frames F1 SETUP mark viewer F9 PF1 white on black background F10 PF2 minimize window if no titlebar is visible F11 PF3 black on white background F12 - set default color palette Ctrl-Enter LINE FEED line feed Home - redraw screen Pause BREAK insert a parc at caret position Shift-Pause Shift-Break insert a page-breaking parc at caret position F2 No Scroll screen refresh in Draw Ctrl-F2 Ctrl-No Scroll  Fonts TrueType fonts are supported in a transparent way. Fonts.This(name) also loads TrueType fonts. name has the following syntax: name = Family size styles ".Scn.Fnt" E.g., Fonts.This("Arial43bi.Scn.Fnt") returns the font "Arial" in boldface and italics and in 43 pixels size. Texts Some minor changes have been done in the Scanner to allow for reading of file names with drive and path specifiers. The syntax of legal tokens of class Texts.Name is: Name = ["&"] NamePart { "." NamePart }. NamePart = (letter | "." | "\") { letter | digit | "\" | ":" | "&" | "$" }. A single "&" character is of class Char. Printer The Oberon fonts Syntax and Syndor are not available as printer fonts. They are substituted by TrueType fonts instead. By default, both fonts are substituted by the TrueType font Arial. This default mapping can be changed by defining the Key PrinterFonts in the registry section System. PageHeight and PageWidth are only valid after a call to Printer.Open. They specify the page size in 300 dpi pixels. UseListFont(name) has no effect. GetChar(font, ch, dx, x, y, w, h) returns the printer metrics of a character in 300 dpi. In Open(name, user, password), the parameters are ignored. In Page(nofcopies), the parameter is ignored. Exactly one page is sent to the printer. System The command Quit leaves Oberon. The command ChangeDir ( "^" | newdir ) changes the current directory. The command CreateDir ( "^" | newDir ) creates a new directory newDir. The command Directory ([path]template["/"{option}] | "^") accepts a path specifier in front of the template. All Oberon files in the directory viewer are listed alphabetically, followed by the DOS files and the directories. Valid options are described in Directories.Text. For further information using directories see the file "Directories.Text". System.Open looks for a text with name System.Menu.Text. If it is available, it is displayed in the menu frame instead of the standard menu text. This way it is possible to configure the menu string shown in viewers opened with System.Open, e.g. the menu can also contain text elements like PopupElems or MenuElems. Note: the height of the menu frame is not adapted to the text displayed, i.e. if the text is too large to fit into the menu frame, it is clipped and only a black bar is visible. The commands System.Set and System.Get serve to store values in the registry and to inspect the contents of the registry (see Registry in section 4). Types Interface module to the type system. Necessary to implement persistent objects. Ref Inferface module to the reference information. Necessary to implement programs working on programs (metaprogramming). Oberon Time() returns Input.Time() Kernel The garbage collector (procedure GC) may be called at any time, since local pointers on the stack are used as roots during the mark phase of the garbage collection. The garbage collector is also activated upon a call to NEW or SYSTEM.NEW if not enough heap space is available to allocate. The garbage collector supports finalization, that is an application may register an object with the garbage collector. The collector will notify the application if the object is collected. The procedure Kernel.RegisterObject registers an object for finalization: RegisterObject(obj: SYSTEM.PTR, finalizer: Finalizer); TYPE Finalizer = PROCEDURE (obj: SYSTEM.PTR); When the object is collected from the heap, the collector calls the procedure finalizer which has been specified when registering the object. An object which has been registered n times will be finalized exactly n times. The order in which objects are finalized is unspecified. LoadLibrary(name: ARRAY OF CHAR) loads the library (DLL) with name. Returns a handle to the library that can be used calling GetAdr. It calls the Windows API function LoadLibrary. FreeLibrary(lib: LONGINT) calls the Windows API function FreeLibrary. GetAdr(lib: LONGINT; symbol: ARRAY OF CHAR; VAR adr: LONGINT) returns in adr the address of the exported name symbol in the library given by lib. GetAdr essentially calls the Windows API function GetProcAddress. 5.2 Modules unique to Oberon for Windows Printers Module Printers defines the abstract interface to a printer driver and contains the implementation of the standard Windows printer. Printer dirvers may be exchanged by implementing a concrete object of type Printers.Printer and installing it with Printers.Install. The calls to the standard Oberon module Printer are forwarded to the corresponding method of the printer driver currently installed in Printers.Current.  DEFINITION Printers; IMPORT Fonts; (* The type Printer defines the abstract interface to a printer driver. The methods behave like the procedures of the standard Oberon module Printer. They are described in The Oberon System by M. Reiser (see references above). The method GetChar returns the metrics of a character in 300 dpi resolution. *)  TYPE Printer = POINTER TO PrinterDesc; PrinterDesc = RECORD pageHeight, pageWidth, res: INTEGER; PROCEDURE (P: Printer) Circle (x0, y0, r: INTEGER); PROCEDURE (P: Printer) Close; PROCEDURE (P: Printer) ContString (str: ARRAY OF CHAR; VAR fname: ARRAY OF CHAR); PROCEDURE (P: Printer) Ellipse (x0, y0, a, b: INTEGER); PROCEDURE (P: Printer) GetChar (f: Fonts.Font; ch: CHAR; VAR dx, x, y, w, h: INTEGER); PROCEDURE (P: Printer) Line (x0, y0, x1, y1: INTEGER); PROCEDURE (P: Printer) Open (name, user: ARRAY OF CHAR; password: LONGINT); PROCEDURE (P: Printer) Page (nofcopies: INTEGER); PROCEDURE (P: Printer) Picture (x, y, w, h, mode: INTEGER; adr: LONGINT); PROCEDURE (P: Printer) ReplConst (x, y, w, h: INTEGER); PROCEDURE (P: Printer) ReplPattern (x, y, w, h, patno: INTEGER); PROCEDURE (P: Printer) Spline (x0, y0, n, open: INTEGER; X, Y: ARRAY OF INTEGER); PROCEDURE (P: Printer) String (x, y: INTEGER; str: ARRAY OF CHAR; VAR fname: ARRAY OF CHAR); PROCEDURE (P: Printer) UseColor (red, green, blue: INTEGER); PROCEDURE (P: Printer) UseListFont (name: ARRAY OF CHAR); END ; VAR Current-: Printer; (* the currently installed printer driver *) StdPrt-: StdPrinter; (* the default Windows printer driver *) PROCEDURE Install (P: Printer); (* install the printer driver P in variable Current *) PROCEDURE InstallDefault; (* installs the default Windows printer in variable Current *) END Printers.   PSPrinter Module PSPrinter implements an alternative printer driver that generates a PostScript file. The file can then be sent to a PostScript printer with an external utility command like lpr. The name of the PostScript file is specified with the print command. Edit.Print c:\&out.ps * for example prints the text in the marked viewer and produces a PostScript file named out.ps in the root directory of drive c (see section about Oberon files and DOS files). Note the ampersand character & in front of the file name. It is important that the PostScript file be a plain ASCII file (see also the section on files and file names). The printer driver is installed by executing the command PSPrinter.Install. The command Printers.InstallDefault re-installs the default printer driver. Note: This printer driver uses original Oberon printer fonts to produce output. (Oberon printer font files end in *.Pr3.Fnt.) In the standard distribution, only the printer fonts for the Syntax and Math font families are distributed. Additional fonts can be ftp'ed from neptune.inf.ethz.ch/pub/Oberon/Windows. An attempt to print text containing characters in a font whose printer font is not available results in a runtime error. Registry Module Registry is an interface to the initialization file specified at startup time. It serves to store configuration data for the system and applications. The registry is structured hierarchically into sections and keys. Sections may contain an arbitrary number of keys. To each (section, key) pair, a value is associated. DEFINITION Registry; CONST Done = 0; NotFound = 2; RegistryNotFound = 1; TYPE EntryHandler = PROCEDURE (key, value: ARRAY OF CHAR); VAR res: INTEGER; res = NotFound: either a section or a key specified is not contained in the registry. res = RegistryNotFound: no initialization file was given at startup time. PROCEDURE Get (section, key: ARRAY OF CHAR; VAR value: ARRAY OF CHAR); Retrieve the value associated with a (section, key) pair. PROCEDURE Set (section, key, value: ARRAY OF CHAR); Associate a value with the pair (section, key) and store it in the registry. If value = "", an existing value is deleted and the (section, key) pair is removed from the registry. PROCEDURE Enumerate (section: ARRAY OF CHAR; handler: EntryHandler); Enumerate all keys and their associated value for a given section. For each key found in the section, the handler is called END Registry.   The user interface to the registry is provided by means of the commands System.Set and System.Get. Clipboard Module Clipboard supports data exchange across applications via the Windows clipboard. The command Clipboard.Copy copies the most recent text selection to the clipboard. Cut is like Copy, but also deletes the selection. Paste gets the text in the clipboard and inserts it at the caret position. Clipboard.Snapshot takes a snapshot of the marked viewer and puts it into the clipboard. If no viewer is marked, a snapshot of the entire Oberon window is taken. Configuration At system startup, the module System searches a module Configuration and loads it if present. The module is loaded before any viewers have been opened. If the module is present, the system does not open the log viewer and system tool. Instead, the module body of Configuration is responsible to initialize the display. The module can furthermore do any custom initializations. If a module Configuration can not be found, the log viewer and system tool are opened normally. A minimal configuration module would therefore be: MODULE Configuration; IMPORT Oberon, MenuViewers, TextFrames; CONST LogMenu = "System.Close ...."; StandardMenu = "System.Close ...."; VAR X, Y: INTEGER; V: MenuViewers.Viewer; BEGIN Oberon.AllocateSystemViewer(0, X, Y); V := MenuViewers.New(TextFrames.NewMenu("System.Log", LogMenu), TextFrames.NewText(Oberon.Log, 0), TextFrames.menuH, X, Y); Oberon.AllocateSystemViewer(0, X, Y); V := MenuViewers.New(TextFrames.NewMenu("System.Tool", StandardMenu), TextFrames.NewText(TextFrames.Text("System.Tool"), 0), TextFrames.menuH, X, Y); END Configuration.   6 Calling Windows API and DLL functions from Oberon Programs It is possible to call Windows API functions from within Oberon. This is done by declaring a procedure variable for each API function to call and initialising it with the address of the respective API function. The address is determined by calling the procedure Kernel.GetAdr. The following example demonstrates how this is done: VAR lib: LONGINT; MessageBox: PROCEDURE (owner, text, title, style: LONGINT): LONGINT; ... BEGIN lib := Kernel.LoadLibrary("user32"); (* get handle to user32.dll *) Kernel.GetAdr(lib, "MessageBoxA", SYSTEM.VAL(LONGINT, MessageBox)); (* get address of MessageBoxA *) ... Kernel.LoadLibrary calls the Windows LoadLibrary API function, and Kernel.GetAdr essentially calls GetProcAddress. With this simple mechanism it is possible to call any API function in any DLL. A few things must be paid attention to. All parameters must have 32-bit size. Return values are 32-bit. For some Windows API functions there actually exist two versions, one that accepts Unicode parameters and one that does not. The latter have an "A" appended to their name. In general, all API functions that accept string parameters follow this rule. (When compiling a C program, the preprocessor changes MessageBox to MessageBoxA, for example.) Special care must be taken when using Oberon procedures as callback functions. The Windows calling convention specifies that EBX, ESI and EDI are callee-saved registers. The Oberon compiler saves no registers, thus the first action in a callback procedure must be to save these three registers, and to restore them just before the procedure returns. E.g.: PROCEDURE MyCallback (...); VAR EBX, ESI, EDI: LONGINT; BEGIN SYSTEM.GETREG(3, EBX); SYSTEM.GETREG(6, ESI); SYSTEM.GETREG(7, EDI); .... SYSTEM.PUTREG(3, EBX); SYSTEM.PUTREG(6, ESI); SYSTEM.PUTREG(7, EDI); END MyCallback; 7 The Compiler The Compiler implements Oberon-2 as defined in the language report contained in the file Oberon2.Report.Text. This section describes system specific topics. Module SYSTEM The numbering of the registers in GETREG(n, v) and PUTREG(n, v) is defined in the table below. The size of v determines the size of the register, i.e. GETREG(0, ch), where ch is of type CHAR, reads the contents of AL. If v is a constant, the register is taken to be 32 bits. The function CC(n) is not implemented.  Numbering of 80x86 registers  Code procedures The compiler allows for inline expanded "assembly" procedures. The syntax for code procedures is PROCEDURE "-" ident [FormalPars] [ byte { "," byte } ] ";" When the compiler translates a call to a code procedure, the parameters are evaluated and pushed onto the stack (from right to left). The last parameter in the parameter list can be addressed with 8[ESP]. The bytes specified are then inlined, and finally the stack pointer is reset. Code procedures must not be exported.