bammi@cwruecmp.UUCP (08/10/86)
Here are the next two parts of Tim Orens Progem series. To effectively use part 16, you will need the new release of the resource construction set - RCS.PRG (version 2.0), that was posted to ataridev on Compuserve. Note that the Megamax (or Tdi Modula) resource construction set blows up, so it will not suffice. The part 16 distribution consists of the following files: wind16.prf The article apndx12.prf The associated appendix (gemcl16.c & gemcl16.h) gemcl16.rsc.uue UUencoded gemcl16.rsc gemcl16.dfn.uue UUencoded gemcl16.dfn (with rcs v2.0 a .def is a .dfn file) gemcl16.rsh The C file for the above resourse. After UnSharing these articles, run the *.uue files through `uudecode' to get the binaries. -------------------------------cut ---- snip ---- idhar katyea---------------- #!/bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #!/bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # tut.prf # wind15.prf # apndx11.prf # This archive created: Sat Aug 9 17:30:38 1986 # By: Jwahar R. Bammi () export PATH; PATH=/bin:$PATH echo shar: extracting "'tut.prf'" '(1312 characters)' if test -f 'tut.prf' then echo shar: over-writing existing file "'tut.prf'" fi sed 's/^X//' << \SHAR_EOF > 'tut.prf' X.!**************************************************************************** X.! X.! ANTIC PUBLISHING INC., COPYRIGHT 1985. REPRINTED BY PERMISSION. X.! X.! ** Professional GEM ** by Tim Oren X.! X.! Proff File by ST enthusiasts at X.! Case Western Reserve University X.! Cleveland, Ohio X.! uucp : decvax!cwruecmp!bammi X.! csnet: bammi@case X.! arpa : bammi%case@csnet-relay X.! compuserve: 71515,155 X.! X.!**************************************************************************** X.! X.! Begin Tutorial X.! X.!*************************************************************************** X.! X.! X.so macros.prf X.so wind1.prf X.so wind2.prf X.so wind3.prf X.so wind4.prf X.so wind5.prf X.so wind6.prf X.so wind7.prf X.so wind8.prf X.so wind9.prf X.so wind10.prf X.so wind11.prf X.so wind12.prf X.so wind13.prf X.so wind14.prf X.so wind15.prf X.so wind16.prf X.! X.! Add any further Parts Above X.! X.cl 0 APPENDICES X.so apndx1.prf X.so apndx2.prf X.so apndx3.prf X.so apndx4.prf X.so apndx5.prf X.so apndx6.prf X.so apndx7.prf X.so apndx8.prf X.so apndx9.prf X.so apndx10.prf X.so apndx11.prf X.so apndx12.prf X.! X.! Add any further Appendicies Above X.! X.so toc.prf X.! X.! X.!**************************************************************************** X.! X.! End Tutorial X.! X.!*************************************************************************** SHAR_EOF if test 1312 -ne "`wc -c 'tut.prf'`" then echo shar: error transmitting "'tut.prf'" '(should have been 1312 characters)' fi echo shar: extracting "'wind15.prf'" '(14235 characters)' if test -f 'wind15.prf' then echo shar: over-writing existing file "'wind15.prf'" fi sed 's/^X//' << \SHAR_EOF > 'wind15.prf' X.!**************************************************************************** X.! X.! ANTIC PUBLISHING INC., COPYRIGHT 1985. REPRINTED BY PERMISSION. X.! X.! ** Professional GEM ** by Tim Oren X.! X.! Proff File by ST enthusiasts at X.! Case Western Reserve University X.! Cleveland, Ohio X.! uucp : decvax!cwruecmp!bammi X.! csnet: bammi@case X.! arpa : bammi%case@csnet-relay X.! compuserve: 71515,155 X.! X.!**************************************************************************** X.! X.! X.!**************************************************************************** X.! X.! Begin Part XV X.! X.!**************************************************************************** X.! X.PART XV Coping with GEMDOS X.PP XWhile it's fun playing with windows and object trees, one of Xthe day-to-day realities of working with the ST is its operating Xsystem, GEMDOS. A successful application should insulate the user Xfrom the foibles and occasional calamities of the machine's file Xsystem. The GEM environment provides some minimal tools for doing Xthis, but a good deal of responsibility still rests with you, the Xprogrammer. X.PP XThis column (#15 in the ST PRO GEM series) tries to address Xthe GEM/DOS integration problem by providing you some stock code Xfor common functions, along with a discussion of some of the worst X"gotchas" lurking for the unwary. The download for this column is XGMCL15.C, and it can be found in DL3 of PCS-58. You should obtain Xand list this file before proceeding. X.SH A BIT OF HISTORY. XThere has been a good deal of confusion Xin the Atari press and among developers over what GEMDOS is, and Xhow it relates to TOS and CP/M-68K. It's important to clear this Xup, so you can get a true picture of what GEMDOS is intended to Xdo. The best way is to tell the story of GEMDOS' origins, which I Xcan do, because I was there. X.PP XAs most developers are aware, GEM was first implemented on Xthe IBM PC. PC GEM performed two functions. The first was a Xwindowed graphics extension to the PC environment. The second was Xa visual shell, the Desktop, which ran on top of the existing Xoperating system, PC-DOS. X.PP XWhen work started on moving GEM to the ST, there were two big Xproblems. First, no STs actually existed. Second, there was no Xoperating system on the 68000 with which GEM and the Desktop could Xrun. Unix was too large, and CP/M-68K lacked a number of Xcapabilities, such as hierarchical files, which were needed to Xsupport GEM. X.PP XWork on porting the graphics parts of GEM to the 68000 had to Xstart immediately to meet schedules. Therefore, CP/M-68K running Xon Apple Lisa's was used to get this part of the project off the Xground. Naturally, the Alcyon C compiler and other tools which Xwere native to this environment were used. X.PP XIn parallel, an effort was begun to write a new operating Xsystem for the 68000, which would ultimately become the ST's file Xsystem. It was designed to be a close clone of PC-DOS, since it Xwould perform the same functions for GEM in the new Xenvironment. At this point, the term TOS was introduced. TOS Xreally meant "the operating system, whatever it may be, that will Xrun on the ST", since not even the specifications, let alone the Xcode, were complete at that time. X.PP XThe first engineer to work on "TOS" at Digital Research was XJason Loveman. This name leaked to the press, and in some Xdistorted fashion generated a rumor about "Jason DOS", which was Xstill just the same unfinished project. As "TOS" became more Xsolid, the developer's tools were ported to the new environment Xone by one, and the GEM programming moved with them. CP/M-68K was Xcompletely abandoned, though the old manuals for C and the tools Xlived on and are still found in the Atari developer's kit. X.PP XAll of this work had been done on Lisas or Compupro systems Xfitted with 68000 boards. At this point, workable ST prototypes Xbecame available. An implementation of "TOS" for the target Xmachine was begun, even before the basic operating system was Xfully completed. X.PP XThe other intent for the new operating system was to be a Xbase for GEM on other 68000 systems as well as the ST. Because of Xthis, Digital Research named it GEMDOS when it was finally Xcomplete, thus providing the final bit of nomenclature. "TOS" as Xnow found in the ST is in fact a particular implementation of Xgeneric GEMDOS, including the ST specific BIOS. X.PP XSo, GEMDOS is a PC-DOS clone, but, not quite. There are Xenough differences to cause problems if they are ignored. X(Remember, it looks like a duck, and quacks like a duck, but it's Xnot a duck.) X.SH GOING FOR IT. XAs a first example, consider the routines Xopen_file() and create_file() at the beginning of the download. XThey make use of the GEMDOS calls Fopen() and Fcreate(). You will Xnotice that these names are not the ones specified in the Digital XResearch GEMDOS manual. Developers who have used PC GEM will Xalso observe that they are radically different from the function Xnames in the PC-DOS bindings. X.PP XIn fact, all of the GEMDOS function calls on the ST are Xdefined as macros in the file osbind.h, distributed with the Xdeveloper's kit. At compile time they are turned into calls to Xthe assembly language routine gemdos(), part of the osbind.o Xbinary. So, if you find the naming conventions to be particularly Xoffensive for some reason, just edit the appropriate macros in Xosbind.h. X.PP XIn DRI's PC-DOS bindings, any error codes were returned in Xthe global variable DOS_ERR. In the GEMDOS bindings, the Xoperation result or an error code is returned as the value of the Xcalling function. In the case of Fopen() and Fcreate(), the Xresult is a valid file handle if it is positive. A negative Xresult is always an error code, indicating that the operation Xfailed. X.PP XAn application which encounters a GEMDOS error should display Xan alert, and query for retry or abort. The type of loop Xstructure exemplified by open_file() and create_file() should Xbe usable with most GEMDOS functions which might fail. The AES Xprovides a function, form_error, which implements a set of X"canned" error alerts appropriate to the various possible errors. X.PP XHowever, this is where the fun starts. For unknown reasons, Xthe form_error on the ST expects to see PC-DOS, not GEMDOS, error Xcodes as it's input! Therefore you need a routine to translate one Xinto the other. The routine dos_error() in the download provides Xthis function. The GEMDOS errors are in the same sequence as Xthose for PC-DOS, but their numerical order is reversed and Xshifted. Notice also that dos_error() does NOT perform the Xtranslation if the error code is less than -50. These codes have Xno PC-DOS equivalent; computing a bogus translation will cause Xform_error to crash. Instead, they are passed through verbatim, Xresulting in a "generic" alert which gives only the error number. X.PP XThe other major task in integrating a GEM application with Xthe file system is selecting file names for input and output. XAgain, the AES provides some assistance with the fsel_input call, Xwhich invokes the standard file selector dialog. X.PP XThere are several drawbacks to the standard file selector. XOne is that the "ITEM SELECTOR" title is constant and cannot be Xchanged by the application. This could cause confusion for Xthe user, since it may not be clear which of several functions, Xclosely spaced in the FILE menu, was actually invoked. While it Xmight be possible to find and "rewire" the AES resource that Xdefines the file selector, it is unlikely that such an approach Xwould be portable to a later version of ST GEM. X.PP XA viable approach to eliminating confusion is to display a Xsmall "marquee" box, with a message defining the operation, on the Xscreen just above the file selector. To do this, you must Xinitialize the location of the box so that it is outside of the Xfile selector's bounds, and then draw it just before invoking the Xfile selector. This way they will appear together. Before Xreturning to its main event loop, the application should post a Xredraw message for the "marquee" area. The AES will merge this Xredraw with the one generated by fsel_input, and the result will Xbe received by the application's evnt_multi. X.PP XAnother problem with the file selector is that it resets your Xapplication's virtual workstation clip rectangle without warning. XThere are other AES functions, such as objc_draw, which also do Xthis, but the file selector can be troublesome because it may be Xthe only AES call used by some VDI-based ST applications. X.PP XThe veteran developer will also notice that the file selector Xtakes and returns the path and filename as two separate strings, Xwhile the GEMDOS file functions require a fully pathed file name. XAlso, the file selector doesn't remember its "home" directory; you Xare responsible for determining the default directory, and keeping Xtrack of any changes. The remainder of the download and column is Xdevoted to set of utilities which should alleviate some of the X"grunt work" of these chores. X.PP XThe top level routine in this collection is get_file(). It Xis called with two string arguments. The first must point to a Xfour byte string area containing the desired file name extension X(three characters plus a null). The second is the default file Xname. X.PP XIf the default file name is non-null, then get_file() invokes Xparse_fname() to break it into path and name. Parse_fname() also Xadds the necessary "wild card" file specification to the path, Xusing the extent name given as input. X.PP XIf no default file was supplied, or the default did not Xcontain a path, the routine get_path() is invoked to find the Xcurrent default directory and construct a legal path string for Xit. X.PP XThe results of these manipulations are supplied to Xfsel_input. Notice that the result of the file selector is Xreturned via its third argument, rather than as a function value. XIf the result is TRUE, get_file() merges the temporary path and Xfile string, storing the result via the second input parameter. XThis result string is suitable for use with Fopen, and may be Xresubmitted to get_file() when the next operation is invoked by Xthe user. X.PP XParse_fname() is straight-forward C. It looks backward along Xthe file to find the first character which is part of the path. XThe tail of the filename is copied off, and its former location is Xoverlaid with the wild card specification. X X Get_path() is a bit more interesting. It makes use of two XGEMDOS functions, Dgetdrv() and Dgetpath() to obtain the default Xdisk drive and directory, respectively. Note that Dgetpath() will Xreturn a null string if the current default is the root, but it Xputs a back-slash at the beginning of the path otherwise. This Xforces a check for insertion in the root case, since the file Xselector wants to see something like "A:\*.RSC", rather than X"A:*.RSC". After making this fix, get_path() concatenates the Xwild card specification derived from the input extent. X.PP XThe last routine in the download is new_ext(). This utility Xis useful if your application uses more than one associated file Xat a time. For instance, the Resource Construction Set uses both Xan RSC and a DEF file, with the same base name. New_ext() takes a Xfully formed file name, and replaces its old extent with the new Xone which you supply. This lets you quickly generate both file Xnames after one call to the file selector. Notice that new_ext() Xlooks BACKWARD along the name to find the delimiting period, since Xthis character can also be part of a subdirectory name in the Xpath. X.PP XSo we reach the end of the code and this column. Hopefully Xboth will keep you profitably occupied for a while. July's column Xwill return to graphics topics, with a look at writing customized Xrubber box and drag box routines, and ways to implement your own X"pop-up" menus. August will bring techniques for displaying Xprogress indicators, associating dialog and menu entries with Xkeystrokes, and customizing objc_edit. X.SH I CAN'T HEAR YOU! XThe Feedback mailbag has been noticably Xflat of late. There have been a number of compliments on the Xcolumn, which are much appreciated, and some suggestions for Xtopics which fall outside the bounds of this series. The latter Xhave been passed on to Antic for possible inclusion in their new XST quarterly, START. X.PP XOne recurring problem is finding the downloads. A number of Xthe earlier columns say they are in PCS-132 (the old SIG*ATARI), Xand one says PCS-57 (mea culpa). In fact, ALL of the downloads Xare now in DL3 of PCS-58 (ATARI16). Filenames for first nine Xcolumns are all in the form GEMCLx.C, where x is the column's Xdigit. For reasons unknown to me, the next two files were named XGEMC10.C and GEMC11.C; the latest two downloads are called XGMCL13.C and GMCL15.C. The latter naming pattern should continue Xinto the future. X.PP XUndoubtedly, one reason for the shortage of questions is the Xamazing ability to get a quick answer on the Developer's SIG, PCS- X57. This is a good sign of a strong Atari community on XCompuserve. However, the SIG message style doesn't really lend Xitself to lengthy explanation, so suggestions for longer topics Xare always welcome here. X.PP XFinally, I am now beginning the process of collecting these Xcolumns and some additional material into a book. In doing so, it Xwould be helpful to know if you feel that any part of GEM has Xbeen slighted in my discussions. If so, let me know. Your Xsuggestions will appear in future columns and finally make their Xway into the book. X.! X.! X.!***************************************************************************** X.!* * X.!* End Part 15 * X.!* * X.!***************************************************************************** SHAR_EOF if test 14235 -ne "`wc -c 'wind15.prf'`" then echo shar: error transmitting "'wind15.prf'" '(should have been 14235 characters)' fi echo shar: extracting "'apndx11.prf'" '(3975 characters)' if test -f 'apndx11.prf' then echo shar: over-writing existing file "'apndx11.prf'" fi sed 's/^X//' << \SHAR_EOF > 'apndx11.prf' X.!**************************************************************************** X.! X.! ANTIC PUBLISHING INC., COPYRIGHT 1985. REPRINTED BY PERMISSION. X.! X.! ** Professional GEM ** by Tim Oren X.! X.! Proff File by ST enthusiasts at X.! Case Western Reserve University X.! Cleveland, Ohio X.! uucp : decvax!cwruecmp!bammi X.! csnet: bammi@case X.! arpa : bammi%case@csnet-relay X.! compuserve: 71515,155 X.! X.!**************************************************************************** X.! X.! Begin Appendix 11 X.! X.!*************************************************************************** X.! X.! X.AP XI Sample Code for Part XV X/*------------------------------*/ X/* includes */ X/*------------------------------*/ X X#include "portab.h" /* portable coding conv */ X#include "machine.h" /* machine depndnt conv */ X#include "osbind.h" /* BDOS defintions */ X#include "gemdefs.h" X X/*------------------------------*/ X/* open_file */ X/*------------------------------*/ X WORD Xopen_file(file_name) X BYTE *file_name; X { X LONG dos_hndl; X X FOREVER X { X dos_hndl = Fopen(file_name, 0); X if (dos_hndl >= 0) X return ((WORD) dos_hndl); X if ( !dos_error((WORD) dos_hndl) ) X return (-1); X } X X return (-1); /* Appease lint */ X } X.bp X/*------------------------------*/ X/* create_file */ X/*------------------------------*/ X WORD Xcreate_file(file_name) X BYTE *file_name; X { X LONG dos_hndl; X X FOREVER X { X dos_hndl = Fcreate(file_name, 0); X if (dos_hndl >= 0) X return ((WORD) dos_hndl); X if ( !dos_error((WORD) dos_hndl) ) X return (-1); X } X X return (-1); /* Appease lint */ X } X.bp X/*------------------------------*/ X/* dos_error */ X/*------------------------------*/ X WORD Xdos_error(tos_err) X WORD tos_err; X { X WORD f_ret; X X graf_mouse(ARROW, 0x0L); X if (tos_err > -50) X { X tos_err += 31; X tos_err = -tos_err; X } X f_ret = form_error(tos_err); X return (f_ret); X } X.bp X/*------------------------------*/ X/* get_file */ X/*------------------------------*/ X WORD Xget_file(extnt, got_file) X BYTE *extnt, *got_file; X { X WORD butn, ii; X BYTE tmp_path[64], tmp_name[13]; X X tmp_name[0] = '\0'; X tmp_path[0] = '\0'; X X if (*got_file) X parse_fname(got_file, tmp_path, tmp_name, extnt); X if (!tmp_path[0]) X get_path(&tmp_path[0], extnt); X X fsel_input(tmp_path, tmp_name, &butn); X if (butn) X { X strcpy(got_file, tmp_path); X for (ii = 0; got_file[ii] && got_file[ii] != '*'; ii++); X got_file[ii - 1] = '\0'; X strcat (got_file, "\\"); X strcat(got_file, tmp_name); X return (TRUE); X } X else X return (FALSE); X } X.bp X/*------------------------------*/ X/* parse_fname */ X/*------------------------------*/ X VOID Xparse_fname(full, path, name, extnt) X BYTE *full, *path, *name, *extnt; X { X WORD i, j; X BYTE *s, *d; X X for (i = strlen(full); i--; ) /* scan for end of path */ X if (full[i] == '\\' || full[i] == ':') X break; X if (i == -1) X strcpy(name, full); /* "Naked" file name */ X else X { X strcpy(name, &full[i+1]); X for (s = full, d = path, j = 0; j++ < i + 1; X *d++ = *s++); X strcpy(&path[i+1], "*."); X strcat(path, extnt); X } X } X.bp X/*------------------------------*/ X/* get_path */ X/*------------------------------*/ X VOID Xget_path(tmp_path, spec) X BYTE *tmp_path, *spec; X { X WORD cur_drv; X X cur_drv = Dgetdrv(); X tmp_path[0] = cur_drv + 'A'; X tmp_path[1] = ':'; X Dgetpath(&tmp_path[2], 0); X if (strlen(tmp_path) > 3) X strcat(tmp_path, "\\"); X else X tmp_path[2] = '\0'; X strcat(tmp_path, "*."); X strcat(tmp_path, spec); X } X.bp X/*------------------------------*/ X/* new_ext */ X/*------------------------------*/ X VOID Xnew_ext(o_fname, n_fname, ext) X BYTE *o_fname, *n_fname, *ext; X { X WORD ii, jj; X X strcpy(n_fname, o_fname); X for (ii = (jj = strlen(n_fname)) - 1; ii && n_fname[ii] != '.'; ii--); X if (!ii) X n_fname[ii = jj] = '.'; X strcpy(&n_fname[++ii], ext); X } X.! X.!**************************************************************************** X.! X.! End Appendix 11 X.! X.!**************************************************************************** SHAR_EOF if test 3975 -ne "`wc -c 'apndx11.prf'`" then echo shar: error transmitting "'apndx11.prf'" '(should have been 3975 characters)' fi # End of shell archive exit 0 -- Jwahar R. Bammi Usenet: .....!decvax!cwruecmp!bammi CSnet: bammi@case Arpa: bammi%case@csnet-relay CompuServe: 71515,155