[net.micro.atari16] Progem 15/16 part 1 of 2

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