The following describes the source files for Opus and the setup for compilation. A brief description of the interface for accessories also is given. /***************************************************************/ /* Source file and compilation description */ /***************************************************************/ The .PAS source files comprise the compilable modules, while the corresponding .DEF files contain the procedure and function definitions only and serve as include files. My compilation setup is as follows, and to place the files in different locations, you will have to alter the include file definitions at the start of every .PAS file to reflect the new pathnames. Personal Pascal v 2.01 or greater. 1-meg ST, 20 meg hard drive. The following files are copied to a 320K ramdisk I: root directory. 1. compiler.prg 2. linker.prg 3. pasgem 4. paslib 5. gctv.inc 6. gemsubs.def 7. globsubs.def 8. vdi_aes.def 9. auxsubs.def 10. opus.i The remaining files are located in directory "d:\pascal\opus\". You *must* run pascal.prg from this directory in order for the linker to place the .O files here. You also must make sure the pascal.inf file is the one I included. Also, make sure that gemsubs.def and auxsubs.def are the ones I included, *not* the files OSS supplied. A description of the source files follows; they are typically abbreviated, since the linker "additional link files" command line has a very limited length! Note: files preceded by an asterisk contain routines of general interest cited under "Lagniappe" in the article. Filename Description BF.PAS Block and File routines. * E.PAS The expression evaluator. Contains my_exp and my_ln. GL.PAS GLobal subroutines, i.e. commonly needed ones. Includes procedures for creating and deleting cells, dependent cell list management. GR.PAS GRaphic display. Screen display routines are found here. M.PAS Message handler. Routines to handle GEM messages are found here, including the messages I defined myself for use with desk accessories. * NC.PAS Number Conversion routines. real_to_string and string_to_real are found here. OPUS.PAS The main file. Data initialization, main program loop. -1- P.PAS Printer handling. R.PAS Resource handling. These procedures maintain, display, and animate dialogs, and most implement the functions they represent (one exception is print_spreadsheet, which calls do_print in P.PAS to do the actual printing). S.PAS Some string utilities. * V.PAS VDI and AES routines not included in Personal Pascal. map_tree, set_text, and get_text are found here as well as lots of other good stuff. W.PAS Window input. Originally a general purpose routine for input into a window, this has been extensively modified to be specific to Opus. It animates the edit area and function menu. OPUS.I The resource construction set header. GCTV. INC Global Constants, Types and Variables. The remaining files should be more or less self-explanatory. /***************************************************************/ /* Communication with desk accessories */ /***************************************************************/ I've provided the hooks to expand Opus through desk accessories, using the GEM message pipeline. Now, space precludes a detailed discussion, especially since Tom Hudson wrote a great tutorial in the Summer 1987 Start magazine, which served as my reference. So, I ask that you consult this article, and I will give a description of the messages Opus supports. You also will need to include the definitions of any Opus-specific types. First, the message names and numbers are defined in GCTV.INC. They are handled in M.PAS. Brief descriptions of each follows. PresentMsg An acc can send this message, and if Opus is present, it will reply, returning the current row and column of the active cell in msg[3] and msg[4]. AssignedMsg Tests whether the cell at row and column specified in msg[3] and msg[4] is assigned or not, returning the result in msg[5]. Also returns the address of the cell or NIL in msg[3] (the most significant byte) and msg[4] (the lsb). RedrawMsg Force Opus to refresh its window(s). DataMsg Return the address of "data," the sparse matrix and main data structure. NewMsg Creates a new cell at row and column indicated in msg[3] and msg[4]. Returns address or NIL in msg[3] and msg[4]. DeleteMsg Deletes the cell at row and column indicated by msg[3] and msg[4]. -2- LocateMsg Returns the address of the cell or NIL of the cell at row and column indicated by msg[3] and msg[4], returning the address in msg[3] and msg[4]. DefRangeMsg Returns the start and end rows and columns of a block selected in Opus, or returns 0 in msg[3] if a block isn't selected. GetRangeMsg Calls the routine which displays the "select range" dialog used by "save block," returning 1 in msg[7] if the user selected OK or 0 in msg[7] if the user chose Cancel. The start and end rows and columns are returned in msg[3..6]. MfdbAddrMsg Returns the addresses of the screen and memory mfdbs, so that the accessory need not define its own. Also allows the acc to use Opus's 32K blit buffer. RealToStrMsg Allows acc to use real_to_string. The address of the real to be converted should be specified in msg[3] and msg[4], while the address of the string should be placed in msg[5] and msg[6]. msg[7] should contain have the high bit set if the number is to be converted to scientific notation, and should otherwise equal the number of decimal places. ex. msg[7] := $8002 means use sci. not. and 2 decimal places. StrToRealMsg Allows the acc to use Opus's string_to_real function. The string's address should appear in msg[3] and msg[4], while the address of the real should appear in msg[5] and msg[6]. TranslateMsg Converts a cell reference to row and column numbers, i.e. "B10" yields 10,2. The address of the string should appear in msg[3] and msg[4]. msg[5] will contain 1 if the conversion was successful and 0 otherwise. msg[3] and msg[4] will contain the row and column. StringaCellMsg Converts row and column specified in msg[3] and msg[4] to the cell reference representation, i.e. 2,3 goes to "C2." RecalcMsg Recalcs the spreadsheet. 'Nuff said. Note that after processing an accessory-generated message, Opus sends a reply to the accessory. The acc should wait for the reply before proceeding. Well, that's all for now. If you have any questions, feel free to contact me at Delphi- MedStud Compuserve- 72277,2315 Genie- DougH -3-