home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
GEMini Atari
/
GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso
/
zip
/
program
/
lynxlib.zoo
/
lynxlib.doc
< prev
next >
Wrap
Text File
|
1991-01-26
|
37KB
|
982 lines
Documentation to LynxLib version .9 beta test.
December 22, 1990
The LynxLib library, except for portions created by others, is
property of Robert Fischer and is Copyright 1990 by Robert Fischer.
LynxLib is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. In no case will the author be
liable for any damages incurred by using LynxLib.
To contact the author, call or write:
Robert Fischer
80 Killdeer Road
Hamden, CT 06517
(203) 288-9599
LynxLib is subject to the following conditions:
* You may distribute LynxLib to anyone you wish, as long as you make
no money off of it and it's an original, unmodified version of
LynxLib. In distributing it, you may distribute object code, but you
_must_ distribute source code along with it. You may only change
LynxLib enough to work with your specific compiler, and you must use
#ifdef statements, so that if no compiler name is defined, it will
compile under Mark Williams C. If you find some section of code which
doesn't work, for example, under Megamax C, you would do the
following:
#ifdef MEGAMAX
~~~~ your new code for MEGAMAX C ~~~~~~~~
#else
~~~~~ the old code for Mark Williams C ~~~~~~~~
#endif
* If you wish to distribute a modified version of the source code,
distribute in a way so that the user can also have the original
version. For example, if you change the function natoi() in the file
ATOI.C, you must distribute the original ATOI.C along with your
modified ATOI.C. Any additions or changes you make to LynxLib must be
labelled as such. You may not remove code from LynxLib.
* Whenever you distribute a modified version, you must send it to the
me (Robert Fischer) with a short description of what your improvements
are, and I will incorporate your improvements, if I feel that they
improve LynxLib, in the next version of LynxLib. As long as your
improvements don't make LynxLib incompatible with older versions, they
will probably be included. I reserve the right to not incorporate
your change, although I will try to incorporate changes which add more
features and make LynxLib easier to use.
* If I decide to incorporate your change, it remains yours, but you
given up rights to withold copies of your modification or charge money
for it. It _will_ be distributed to the world at that point. It's
your responsibility that the source code you give me is actually yours
to give to me. For example, I don't want to receive source code
ripped off of Microsoft, use it, and then get Microsoft on my back...
* If I incorporate your changes, I'll include your name at the point
of modification in LynxLib.
* If I decide not to incorporate your changes, I will write a letter
to you stating as such within 15 days of receiving them. (If you
leave no way to contact you, the source code becomes mine to do
whatever I want with.) They then remain yours, to do whatever you wish
with.
Following is brief documentation on all supported user functions in
LynxLib.
-----------------------------------------------------------------
ALLOCA.C: Allocates memory on the stack
alloca -- (mostly) portable public-domain implementation -- D A Gwyn
This implementation of the PWB library alloca() function,
which is used to allocate space off the run-time stack so
that it is automatically reclaimed upon procedure exit,
was inspired by discussions with J. Q. Johnson of Cornell.
alloca( size ) returns a pointer to at least `size' bytes of
storage which will be automatically reclaimed upon exit from
the procedure that called alloca(). Originally, this space
was supposed to be taken from the current stack frame of the
caller, but that method cannot be made to work for some
implementations of C, for example under Gould's UTX/32.
As a special case, alloca(0) reclaims storage without
allocating any. It is a good idea to use alloca(0) in
your main control loop, etc. to force garbage collection.
alloca (size) /* returns pointer to storage */
unsigned size; /* # bytes to allocate */
Include files: ALLOCA.H
See also: none
/* ----------------------------------------------------------- */
ATOI.C: Converts between integers and strings
BOOLEAN natoi(stringg, base, result)
char *stringg;
int base;
int *result;
/* Returning a FALSE indicates an error. */
Converts an int to a string, in any base
BOOLEAN natol(stringg, base, result)
char *stringg;
int base;
long *result;
/* Returning a FALSE indicates an error. */
Converts a long to a string, in any base
/* Converts integer to string of specified length. */
/* Fills with leading zeros. */
fitoa(val, len, base, s)
int val, len, base;
char *s;
/* Converts unsigned integer to string of specified length. */
/* Fills with leading zeros. */
ufitoa(val, len, base, s)
unsigned val, len, base;
char *s;
char *catoi(stringg, base, result)
/* Converts a string to an integer and
returns *character of 1st non-numeral */
char *stringg;
int base;
int *result;
/* If no number found, doesn't destroy the previous contents of *result */
This returns the address of the first non-numeral in the string
stringg. That's useful if you need to parse a string filled with
numbers and other things.
Include files: ATOI.H
See also: none
-----------------------------------------------------------------
CLOCK.S: Read the clock, and make a delay
_read_clock:
wait(delay) int delay;
Waits 'delay'/200 seconds
-----------------------------------------------------------------
CLOCK.S: Read the clock, and make a delay
_read_clock:
wait(delay) int delay;
Waits 'delay'/200 seconds
-----------------------------------------------------------------
COLSW.C: Switch the mapping of the colors in a picture file. This is
useful, for example, if you want to make pretty colors which rotate
nicely in NEOChrome, from a file with mixed-up colors.
For example, if the old picture had red as color 5 and green as color
3, you could change it so that green is color 5 and red is color 3.
colsw(pic, pal, newpal) /* Does the above operation on a picture */
/* Takes a low-res picture, switches around its colors, but does not */
/* change its appearance. */
BYTE *pic; /* The picture & palette to do this to */
PALETTE pal;
PAL_TRANS newpal; /* The palette translation table */
A PAL_TRANS is a translation table for colsw(). In the above routine,
then pal[newpal[n]] = pal[n]. In other words, color in position n is
transferred to position newpal[n].
typedef BYTE PAL_TRANS[16];
Include files: TOS.H, COLSW.H
See also: PICTURE.C (to load and save the picture)
-----------------------------------------------------------------
DATECONV.C: Convert between the date formats. This is flexible, letting
you convert between a myraid of date formats.
dtoa(date, divide, order, s) /* Date to string */
date_rec date; /* System-format date */
char divide; /* Divider to use ('/', '-', or '\0' if none to be used) */
int order; /* Bit string specifying what should be in each field */
/* It's twelve bits long, and bits are in groups of four. Each group */
/* holds either a 0 (DAY), 1 (MONTH) or 2 (YEAR). So 0x102 means MMDDYY. */
char *s; /* String to put output in */
ttoa(time, divide, showsec, s) /* Time to string */
time_rec time; /* Time to convert */
char divide; /* Divider character, NIL if none */
BOOLEAN showsec; /* Convert seconds too? */
char *s; /* Output string */
BOOLEAN atot(t, s)
/* Returns FALSE if no time found, or on error */
time_rec *t;
register unsigned char *s;
Converts string to time. Handles 12/24 hr, with or without seconds,
with or without dividers between the fields. Without dividers, all
fields must be two characters long.
BOOLEAN atod(d, order, s)
/* Returns FALSE if no date found, or on error */
date_rec *d;
int order; /* Order expected, as with dtoa */
register unsigned char *s;
Converts string to date. Handles a variety of formats, with or
without dividers. Expects the month, day and year in the order
specified by order.
BOOLEAN atotd(td, order, s)
/* Converts a date&time of the form "DATE TIME" to GEMDOS_TD_REC */
GEMDOS_TD_REC *td;
int order; /* Order for date */
char *s;
This combines the above two, and works on strings such as "12/3/90
0923", meaning December 3 (or March 12, depending on order), 9:23 AM.
BOOLEAN cmp_date(adate, atime, bdate, btime)
/* Returns TRUE if the adtm > bdtm */
date_rec adate;
time_rec atime;
date_rec bdate;
time_rec btime;
Include files: TOS.H DATECONV.H
See also:
-----------------------------------------------------------------
EXINPUT.C
int fsel_exinput(path, file, button, label)
/* Binding to the new AES call, as found in the Rainbow TOS */
/* developer's release notes, August 7, 1989, page 26 */
int *path, *file;
int *button;
char *label;
This works just like fsel_input, only it allows a message in the
string label to appear in the file selector. It checks the TOS
version number, and if it's before TOS 1.4, fsel_exinput uses its own
message-display system for the file selector.
Include files:
See also:
-----------------------------------------------------------------
GDOS.S
BOOLEAN gdos_there()
Tests if GDOS is there, as given by ATARI. Returns TRUE if it is,
FALSE if it isn't.
Include files:
See also:
-----------------------------------------------------------------
GEMVAR.C
Variables needed for VDI, AES. That way, you don't need to define
intin[], ptsin[], etc. all the time in your program. Simply include
gemvar.o in your linking.
Include files:
See also:
-----------------------------------------------------------------
GETCOOKI.C
/* getcookie(): C procedure to find cookies and values
This is taken from Atari's STE Developer Notes, January 12, 1990.
BOOLEAN getcookie(cookie, p_value)
LONG cookie; LONG *p_value;
Returns FALSE if 'cookie' is not found in the cookie jar. If the
cookie is found, it returns TRUE and places the cookie's value into
*p_value. If p_value == NULL, it doesn't put the value anywhere, but
simply tells you whether the cookie is there.
Include files: GETCOOKI.H
See also:
-----------------------------------------------------------------
MAXMIN.C
max(a, b) int a, b;
min(a, b) int a, b;
Simple routines to return the maximum and minimum of a and b.
Include files:
See also:
-----------------------------------------------------------------
MYGEM.C: A bunch of useful routines for use with AES
gem_ok(s) /* Puts up a GEM OK box */
char *s;
Puts up an alert box with the message s in it and an OK button.
gem_err(s) /* Puts up a GEM error box */
char *s;
Similar to gem_ok(), except it puts up an 'Abort' button.
dial_form(d, n) /* Does a form_dial on box d, with mode n */
register OBJECT *d;
int n;
Performs a dial_form() call with mode n on the area covered by box d.
Useful for making growing/shrinking boxes easily, drawing dialog boxes.
draw_box(d) /* Draws a dialog box */
OBJECT *d;
Draws the entire dialog box d. Very easy to use.
map_obtree(d, this, last, routine)
/* General object tree walking routine. Applies an operation
to every node in the tree. This routine was gotton out of
issue 5 of PROGEM, by Tim Oren. */
OBJECT *d; /* Tree to walk */
int this; /* Node to start at. */
int last; /* Node to stop at (This node won't be affected) */
int (*routine)(); /* Routine to apply to every node of tree */
/* routine takes the arguments: routine(d, obj)
OBJECT *d; (* Address of object tree *)
int obj; (* Object in object tree *)
If your routine wants no more walking on the subtree, it
returns TRUE. Normaly, it should return FALSE.
set_rchecked(d, obj, box, obox, redraw, checked)
/* Sets a little box to checked or non-checked, and makes an object
subtree disappear, according to checked */
OBJECT *d; /* The object tree to work in */
int obj; /* Index into the tree */
int box; /* object to set or unset HIDETREE */
int obox; /* object to redraw, to see effects on box */
BOOLEAN redraw; /* Redraw obox? */
BOOLEAN checked; /* Boolean value representing checkedness of obj when */
/* flip_checked was called. flip_checked() flips this value. */
/* TRUE means the box is checked, FALSE means it is unchecked. */
This is a little complicated. Often, you want to make a box which the
user is allowed to check or uncheck. When the user checks it, you
want some other part of the object tree to disappear. This command
allows that. You call it with obj (the box to check or uncheck), box
(the object to hide) and obox (an object around box). obox is needed
because simply redrawing box after you've hidden it won't do anything.
You must have another object containing box which you need to redraw.
center_form(d)
OBJECT *d;
Centers a dialog box. Very easy.
Routines found in MYGEM.H:
#define undraw_box(d) dial_form(d, FMD_FINISH);
Erases the box d from the screen.
#define draw_obj(d, obj) objc_draw(d, obj, 256, 0, 0, 0, 0);
Draws an object with all its subtrees.
Include files: NOBDEFS.H, GEMDEFS.H, MYGEM.H
See also:
-----------------------------------------------------------------
PATHNAME.C: Handles pathnames in fancy ways
add_slash(name)
char *name;
Adds a back-slash to the end of name if there isn't already one.
trim_slash(name)
char *name;
Takes a back-slash off the end of name if there's one.
ppath(path, drvltr, dir, leaf)
/* Parses a path name and returns its component parts */
char *path; /* Input path name */
char *drvltr; /* Output: drive letter of path */
/* 0 = default, 'A' = drive A, ... */
char *dir; /* Directory part of name: */
/* '.\' - default directory */
/* '\' - root directory */
/* '.\xxx\' - subfolder of default dir */
/* '\xxx\' - subfolder of root */
char *leaf; /* Leaf name or wildcard pattern */
resolve_pname(ipath, dflt)
/* Converts path to fully specified form, supplying current default */
/* drive and directory. */
/* Eliminates all occurrences of '.' and '..' */
/* BUGS: The default directory given in dflt is used as the default
for ALL drives. For example, if ipath=c:x and dflt=e:\r\,
then ipath is resolved to c:\r\x */
char *ipath; /* Path name to be resolved. Output returned here, too */
char *dflt; /* Default pathname to use for ambiguous things. */
/* If defalt is '', use GEMDOS's defaults */
resolve_dname(idir, dflt)
/* Resolves a directory name */
char *idir;
char *dflt;
get_curdir(pname) /* gets the current directory */
char *pname;
The same as pwd in the UN*X shell.
trim_leaf(pname) /* Removes the leaf from a name */
/* E:\C turnes to E:\, E:\C\ turns to E:\C\ */
register char *pname;
BOOLEAN g_file_attrib(name, modebits, td, size)
/* Gets the file attributes according to directory */
char *name; /* name of file */
WORD *modebits; /* File's modebits */
GEMDOS_TD_REC *td; /* Files date and time */
long *size; /* Filesize */
Given name, this routine fills in the rest of the variables.
BOOLEAN s_file_attrib(name, modebits, td)
char *name;
WORD modebits;
GEMDOS_TD_REC td;
The complement to g_file_attrib
BOOLEAN cd(d, odrive, opath)
/* Changes current directory to dir. Returns the previous default
drive in odrive and the previous default path on the drive specified
in d in opath. Returns TRUE on success */
char *d;
int *odrive;
char *opath;
BOOLEAN existd(d) /* Sees if a directory exists */
char *d;
{
fle_name defpath; /* Saved default path */
int defdrive; /* Saved default drive */
BOOLEAN ret;
BOOLEAN create_dir(d) /* Creates a directory if it doesn't already exist */
/* d may be a file-name. Then the dir. of that name will be created */
char *d;
For example, create_dir("c:\xxx\yyy\zzz\file") on an empty disk C:\
will create the directories c:\xxx, c:\xxx\yyy and then
c:\xxx\yyy\zzz, ready for the file c:\xxx\yyy\zzz\file to be put into.
pleaf(leaf, root, ext)
/* Parses a leaf into a root and extender */
char *leaf, *root, *ext;
Example. Changes the leaf "FILE.XXX" into root "FILE" and ext "XXX"
Include files:
See also:
-----------------------------------------------------------------
PEEKPOKE.C: Pretty wimpy. Just one routine to poke values in
byte-reversed form, for messing with boot sectors and such.
poke_ibm(addr, val)
/* Byte-reverses val, and puts it into address addr, even an odd address */
BYTE *addr;
WORD val;
Include files: See also:
-----------------------------------------------------------------
PICTURE.C: Loads, converts, displays and saves pictures between many
different formats: NEOchrome, DEGAS (not DEGAS compressed), SPC, SPU
(Spectrum), plain (32000 bytes of data without color information),
TINY (although not all TINY files work for some reason), and even
DOODLE (hey C-64 fans, now you can read your old DOODLE pictures).
Two experimental formats SPLAY and COMPRESS were taken out because
they never really worked. You can easily add your own format. The
structure pic_rec contains information about a picture in a standard
form -- the palette, the bitmap, etc. You need not worry about it.
To load a picture, you use load_pic(). So display it, you use
switch_pic() and then switch_norm() to undisplay it. To save it
(currently only as a NEO file), use save_neo(). To convert between
resolutions, use change_res(), but currently it only converts from
low-res to high-res. A lot could be added to PICTURE.C
BOOLEAN load_pic(pic, name) /* Loads a picture from disk */
register pic_rec *pic; /* The place to load it to */
char *name; /* The name of the picture to load */
/* Returns TRUE if the picture loaded OK */
switch_pic(pic) /* Switches screen to the specified picture */
register pic_rec *pic; /* The picture to switch to */
switch_norm(pic) /* Switches back to the normal screen */
register pic_rec *pic; /* The picture to switch from */
BOOLEAN save_neo(pic, name)
register pic_rec *pic; /* The place to load it to */
char *name; /* The name of the picture to load */
/* Returns TRUE if the picture saved OK */
BOOLEAN change_res(pic, dest_res)
/* Converts a picture from its current resolution to the destination res */
/* Currently, only converts low to high */
pic_rec *pic; /* Picture to convert */
int dest_res; /* Destination resolution */
Include files: PICTURE.H
See also: Coroutines and virtual files. PICTURE.C uses them, although
you don't have to know about them to use PICTURE.C
-----------------------------------------------------------------
SETCOOKI.C: Put a cookie in the cookie jar, and return the cookie
made. If the cookie jar is full, setcookie() must allocate a new
cookie jar. To allow flexible memory allocation (for example, you
might want to allocate permenant memory using PMalloc() in TRICKS.C),
you can tell setcookie() which memory allocator to use, as a routine
which takes a long telling the number of bytes to allocate, and
returns a 0L if it couldn't allocate those bytes, or the address
otherwise. setcookie() uses the standard GEMDOS Malloc() if you give
it a NULL.
setcookie(cook, val, mem_alloc)
LONG cook; /* Cookie to set */
LONG val; /* Value of cookie */
charpfunc *mem_alloc; /* Memory allocator, if needed */
/* If NULL, Malloc is used */
Include files:
See also:
-----------------------------------------------------------------
SINDEX.C: Implements the sindex() string routine
char *sindex(s, pat)
/* Searches for the string pat within the string s. */
/* Returns the pointer to the portion of the string where this occurs, */
/* or NULL if it doesn't occur */
register char *str;
register char *pat;
Include files: NSTRING.H
See also:
-----------------------------------------------------------------
STRING.C: Various miscellaneous string routines
str_upper(s) /* Converts string to upper case */
register char *s;
char *pstrcpy(dest, source)
/* Does a strcpy, but returns the address of the NIL in dest */
register char *dest;
register char *source;
This is useful for appending together many strings without wasting CPU
time. Upon copying source to dest, it returns the address of the NIL
it just wrote in dest, allowing you to pstrcpy() another string there
to append. For example, to append strings s1, s2 and s3 into d:
char *c;
c = pstrcpy(d, s1);
c = pstrcpy(c, s2);
c = pstrcpy(c, s3);
char *strdup(string)
register char *string;
Allocates new memory for a string the same length of string using
malloc(), and copies the old to the new.
char *pstrlen(s)
char *s;
Finds the NIL character in s and returns its addresss.
Include files: NSTRING.H
See also:
-----------------------------------------------------------------
TRICKS.C: Memory allocation tricks
char *malloc_highend(size)
/* Malloc's at the high end of memory */
LONG size;
/* Allocates a "permanent" memory block in high memory */ char
*PMalloc(size) LONG size; The memory that this allocates will stay
around after a Pterm() call because it's made to officially belong to
the Desktop or TOS, some process that never exits. This works only on
TOS 1.4 or greater. It uses entirely documented variables, but
temporarily modifies one which ATARI says should never be touched. It
does work.
term_res(out)
/* Terminates and stays resident, saving the text, data, bss and basepage */
int out; /* Output code */
Include files: TRICKS.H
See also:
-----------------------------------------------------------------
UPROOT.C
* routine to send a one-shot media-definitely-changed
* message to GEMDOS (via Rwabs).
uproot(drv)
int drv;
Include files:
See also:
-----------------------------------------------------------------
VOLUME.C: Get and set the volume name of a disk
* Returns TOS error code in case of trouble
int get_vname(drvnum, label)
int drvnum;
char *label;
The volume label returned is "NOLABEL" if there's no label on the disk.
* set_vname
* Replaces old volume name(s) with new one
* Deletes volume name if newname is empty string (old TOS only)
* Returns TOS error code in case of trouble
int set_vname(drvnum, newname)
int drvnum;
char *newname;
Include files:
See also:
-----------------------------------------------------------------
WHERIS.C: Stuff for searching environment variables
BOOLEAN existf(n) /* Finds out if file n exists */
char *n;
search_env(envvar, fname, fullname, use_this)
/* Searches all the directories in the environment variable */
/* envvar and tests each one, according to use_this(), to see */
/* if it is wanted. When use_this() returns TRUE, it quits */
char *envvar; /* The environment variable to search on */
char *fname; /* The file leaf name */
char *fullname; /* The full pathname to output */
BOOLEAN (*use_this)();
/* Routine to determine which file names to keep & which to throw out */
/* Returns a TRUE to stop the execution */
use_this() should be declared as: BOOLEAN use_this(name) char *name;
wheris(envvar, fname, fullname)
/* Finds an already made file from an environment variable */
char *envvar; /* The environment variable to search on */
char *fname; /* The file leaf name */
char *fullname; /* The full pathname to output */
This searches the environment variable, which is assumed to containe a
list of folders. It checks each to see if the file fname is in that
folder.
first_path(envvar, fname, fullname)
/* Matches fname with the first directory in envvar */
char *envvar; /* The environment variable to search on */
char *fname; /* The file leaf name */
char *fullname; /* The full pathname to output */
This sees if fname is in the first folder listed in the environment
variable envvar.
Include files:
See also:
-----------------------------------------------------------------
WHICHTOS.C
* whichtos(&version, &date)
* Returns TOS version and TOS build date in its arguments
void whichtos(tosver, tosdate)
unsigned *tosver, *tosdate;
Include files:
See also:
-----------------------------------------------------------------
WILD.C: Fancy wildcard-matching routines
BOOLEAN match_wild(wild, stringg) /* Sees if stringg matches with wild */
char *stringg;
char *wild;
This matches strings against wildcards, but without '.' as a special
character. Thus, anything matches to '*', and only items with a '.'
in them match to '*.*'
BOOLEAN match_fwild(wild, fname)
/* Matches a file wildcard to a file -- takes care of '*.*' */
char *wild;
char *fname;
This matches filenames just the way that GEMDOS does it. Thus, '*.*'
here means all files.
BOOLEAN match_fwilds(wild, fname)
/* Matches a whole sequence of wildcards to a file */
char *wild; /* The string of wildcards */
char *fname; /* Leaf_name to match to the wildcards */
This matches a file against a sequence of wildcards as found in The
Vault: If you give more than one mask, \vault\ uses them from left to
right. For example, *.pas *.c backs up all the `.PAS' and `.C' files.
A mask preceded by an exclamation point (!) excludes the matching
files. For example, *.* !*.BAK backs up all files except the `.BAK'
files. Each new mask adds to or subtracts from the set of files
specified by all preceding masks. For example, *.* !TEST.* *.C starts
with all files, then removes those matching `TEST.*', then adds back
all files matching `*.C'. Note that `TEST.C' will be backed up by
these rules.
Include files:
See also:
-----------------------------------------------------------------
WINDNEW.C
/* Binding for the wind_new() command documented in the */
/* Rainbow TOS Release Notes */
wind_new()
Wind_new() does something like initalize the window manager. Warning:
this does NOT check for TOS 1.4 or greater.
Include files:
See also:
-----------------------------------------------------------------
-----------------------------------------------------------------
COROUTINES: Coroutines gives your application limited multitasking.
It doesn't allow two processes to run simultaneously, but it _does_
allow them to pass off control from one to the other.
In regular C code, suppose you have something such as:
int a() {~~~~~a bunch of code~~~~~}
int b() {~~~~~a bunch of code~~~~~ a(); ~~~~~a bunch of code~~~~~}
Then function b() would become the master and function a() the slave.
Function a() runs to completion and then reports some answer back to
b(). But suppose you wanted a() to report back to b() in the middle
of running, and then resume again at b()'s discression. That's what
coroutines are for.
The master process is allowed to start as many slave processes at it
wants. Each time it does this, the slave process runs until it
decides to report back to the master by a subroutine call. The master
then continues running as if the slave had returned, _but_ it can let
the slave continue at any point it wishes. Below are the details of
the routines. Look at the file COSAMPLE.C to see how it works.
CCOMON.S: Part of the Coroutine Package
* Process control block structure
* typedef enum {P_NEW, P_BLOCKED, P_READY, P_RUNNING, P_DEAD} procstate;
*
* typedef struct {
* proc_state state; process state
* char *stack; current stack pointer
* message *msg; message value
* } pcb
* Coroutine master
* Uses C calling conventions
* invoke(f, x, p)
* Calls f(x) in process p. Returns when p blocks or terminates.
* func *f; Function to call
* LONG x; argument to give it
* pcb *p; process control block for that function
*
* BOOLEAN resume(p, m, ret_msg)
* pcb *p;
* message m;
* message *ret_msg; Return message from slave
* returns FALSE if p terminates, TRUE if it's still going
*
* Called by master.
* Resumes process p, which should be in state P_READY.
* Passes p.msg to the resumed process as a returned value.
* message to_master(to_msg)
* message to_msg
*
* Called by slave function.
* Blocks current process and passes control back to master.
* When process is resumed, the message in the pcb is passed as
* the value of the function.
CO.C: The C part of coroutines
BOOLEAN init_co(f, arg, stacksize, p)
/* Returns FALSE on error */
func *f; /* Cofunction to init */
LONG arg; /* Argument to that function */
long stacksize; /* Size of stack to make */
pcb *p; /* Process stack ID to put stack in */
This makes a process out of a function, giving it a stack and a pcb.
You must always call init_co() on a slave before you call invoke()
kill_co(p) /* This kills a coroutine by freeing its stack */
pcb *p;
You don't have to have let the coroutine terminate before you kill it.
Include files:
See also: COSAMPLE.C
-----------------------------------------------------------------
-----------------------------------------------------------------
Virtual Files:
In the normal C library, you can open a file off of the disk and read
it using primitives such as getc(), etc. You can even redirect input
and output from various sources, such as the keyboard, the modem port,
etc. Virtual files extend this idea by giving you the possibility to
redirect output from any means which can implement the VFILE
primitives: a normal file, a block of memory, even a coroutine!
The vfile primitives are vfread() and vfwrite(). You aren't allowed
to seek in virtual files. You can then link on extra modules to give
different kinds of virtual files, by writing a read, write, open and
close for every specific kind of virtual file. Lookat FFILE.C for a
simple, specific example.
unsigned vfread(buf, size, num, file) /* Analog of fread() */
/* Returns number of chars read */
char *buf; /* Buf to read to */
unsigned size; /* Size of data objects */
unsigned num; /* Number of objects */
VFILE *file; /* File to read from */
long vfwrite(buf, size, num, file) /* Analog of fwrite() */
/* As a hack, this does not return any error, ever. It always returns
num, pretending there's no error. */
char *buf; /* Buf to read to */
unsigned size; /* Size of data objects */
unsigned num; /* Number of objects */
VFILE *file; /* File to read from */
BOOLEAN vputs(out, s) /* Writes the string s to out, doesn't append '\n' */
VFILE *out; /* File to write to */
register char *s; /* String to write */
Following are various modules for virtual files:
Include files: VFILE.H
See also: PICTURE.C for some good examples of how to use virtual files.
-----------------------------------------------------------------
FFILE.C
/* VFILE driver for normal C streams */
VFILE *open_ffile(name, mode) /* Works just like fopen() */
char *name;
char *mode;
Include files: VFILE.H
See also:
-----------------------------------------------------------------
MEMFILE.C: MFILE lets you treat a block of memory as a sequential
file. For example, if you have a picture in memory and you have a
program which expects to read a picture from a VFILE, you'd make the
picture into a MFILE.
/* Memory file driver for VFILE */
typedef struct { /* A file in memory */
char *base; /* Base of the file */
char *end; /* Last char in file +1 */
char *next; /* Next character to be read or written */
BOOLEAN eof; /* Has end of file been reached? */
} MFILE;
VFILE *open_mfile(base, len)
/* This opens an MFILE and returns a VFILE * */
char *base; /* Start of MFILE */
long len; /* Length of MFILE */
Include files: VFILE.H
See also:
-----------------------------------------------------------------
COFILE.C: Cofiles use coroutines and virtual files. It allows the
master to read and write to the slave process as if it's a file, and
the slave receives read and write commands from the master as if it's
reading and writing from a file. Generally, you set it up so the
slave is either always reading or always writing.
typedef struct { /* A slave's end of the the cofile */
long size;
BOOLEAN eof;
} SLAVE_FILE;
typedef struct {
pcb f; /* The function which the cofile is made of */
long size; /* Current size of file (amount read or written) */
BOOLEAN eof; /* TRUE if end of file has been reached */
SLAVE_FILE *slave;
} COFILE;
VFILE *open_cofile(f, x, stacksize, slave_vfile)
func *f; /* Function to make a cofile of */
LONG x; /* Argument to f */
long stacksize; /* Size to make cofile's stack */
VFILE **slave_vfile; /* Slave's cofile handle */
Include files: VFILE.H
See also:
-----------------------------------------------------------------
HEADER FILES:
Header files in LynxLib generally have the form, for a header file
called FOO.H:
#ifndef FOO_H
#define FOO_H
~~~~ definitions for FOO.H ~~~~~~
#endif
This way, you can include FOO.H as many times as you like without ill
effects. Following are header files not associated with a specific
module above:
E_OSBIND.H:
You shouldn't need to ever use this. It #includes TOS.H, TOSMEM.H,
SYSVAR.H and VT52.H, and is only included for compatibility with an
old version of LynxLib.
LINEA.H:
Common include file for C interface to low level Line A calls, by:
J.R. Bammi
decvax!cwruecmp!bammi
bammi%case@csnet-relay.ARPA
bammi@case.CSNET
NOBDEFS.H:
This is the standard OBDEFS.H header file, but with some
changes. It is to be used in place of OBDEFS.H. The structure OBJECT
is the same, except that the element ob_spec, instead of just being a
LONG, is now a union of bitfields and such, allowing you to access
color bits, etc. easily. Unfortunately, you can't initalize
bitfields, so I've included the structure MW_OBECT, which is the same
as Mark William's definition of OBJECT.
STDDEF.H:
These are standard definitions which are used just about everywhere.
One note, NULL means a NULL pointer. NIL is the character terminating
strings.
The structures xywh and such are mostly useful when defining boxes (as
in AES and VDI).
The new() macro makes life really easy for allocating memory. Given a
pointer p to some structure, such as:
typedef struct {
int a,b;
} X_STRUCT;
X_STRUCT *p;
You can now replace "p = malloc(sizeof(X_STRUCT))" with "new(p)". It
reduces typing and is also semantically more correct. If you happened
to change the type of p from *X_STRUCT to *Y_STRUCT, the malloc() call
would become wrong, but the new() call would continue to work.
The definitions leaf_name, fle_name, file_root and file_extender are
strings to hold various parts of file names.
STRING.H: The standard STRING.H found on most C-compilers, but not in MWC.
STRINGS.H: There's some confusion about whether STRING.H is not
STRINGS.H. Programs which include STRING.H or STRINGS.H will work
with this.
SYSVAR.H:
This defines all the documented (and one undocumented, in TOS 1.0)
variables, in a way which is useful. They're all casted in such a way
that you need only use them (but make sure you go into supervisor mode
first). For example, FVERIFY is a flag found at 0x444. To change its
value, simply use "FVERIFY = 17;", or whatever. VBLQUEUE is an array
of pointers to functions. To look at the sixth entry, use
VBLQUEUE[6]. The lower-case variables are the same, except without
any fancy casting.
TOS.H:
A greatly expanded version of the standard OSBIND.H file. In
addition to the standard macro definitions, it includes many many many
structures used by GEMDOS and BIOS, and error return codes. The
definitions are arranged by the function they're used with.
TOSMEM.H:
More structures used by TOS, but these aren't usually as useful as
those in TOS.H
VT52.H:
The VT-52 escape sequences for screen display.
ROUND.O:
Various things for rounding and dividing.