home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
GEMini Atari
/
GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso
/
files
/
utility
/
wnx1091
/
xes_dev1.doc
< prev
next >
Wrap
Text File
|
1991-10-20
|
35KB
|
730 lines
XES: eXtended Environment System
=================================
Official Documentation for XES Programmers
October 20,1991
by
Charles H. Medley, Jr.
ENiGMA Software
659 Kennedy Street, N.E.
Washington, D.C. 20011
(202) 636-9078
Simple Overview
+-+-+-+-+-+-+-+
The XES consists of two parts:
o The TRAP #5 Dispatcher.
o The User Mode Handler.
Every XES function is accessed by passing parameter(s) on the
stack, and then doing a TRAP #5. To allow for full independence
between copies of Wind-X, and their utilities, the TRAP #5 simply
"fixes" up the parameters and passes them to a subroutine I call
the User Mode Handler.
The purpose of the User Mode Handler is to replace large,
memory hogging subroutines that would be required for almost every
WNX application with a simple call.
This allows the XES to serve as a way to do complicated AES
functions, and replace large subroutines that would normally be
needed within an application with one call. A good example of
this is XES_REDRAW (43) which can handle window redraws for an
XES-based application, with just a few lines of code. I will go
into detail on how each call works later on in this document.
The method used by the XES is this:
o Wind-XES does a JSR into the WNX application to
begin to run it.
o When the WNX does a call to the XES (via TRAP #5)
it's execution is stopped, and the system is put in
supervisor mode. The data and address registers
are saved (A1-A6 and D3-D7 are saved).
o The Trap Handler adjusts the value on the stack
where the RTE is to occur (from the TRAP #5) and
saves the RTE address for use by the User Mode
Handler, and then does an RTE back to the parent
copy of Wind-X's User Mode Handler after setting.
o The User Mode Handler performs the function
requested and JSRs back into the WNX's code at the
location that the TRAP #5 would have RTE'd back to.
This means that you should NOT try to fix the
stack up, like you do after a normal call to
GEMDOS, because the User Mode Handler has already
dealt with that. The original A1-A6/D3-D7 values
are restored (as of 9/09/90 version incarnation of
the XES).
o This occurs over and over until either the WNX
process hits an RTS that doesn't have a
corresponding BSR/JSR within it's code, or until it
reaches a XES_SUBMIT call.
One thing to note is that all data and address registers
should be assumed to be unknown values when a WNX is first JSRed
to. This may change by the time Wind-XES makes it to market, but
for the most part, this isn't needed. Also, note that the SR is
not properly restored after the TRAP #5 call, so don't count on
the CCR remaining unchanged after a TRAP #5 as you can with other
TRAPs.
How To Write For the XES
+-+-+-+-+-+-+-+-+-+-+-+-
A WNX application has to do two things first:
1) It must call XES_INIT with the address of a
parameter block of the form:
Name Size Purpose
---- ---- -------
WNX_id (word) one word I.D. number,
assigned by the XES.
WNX_idname (16 bytes) unique 16 byte identifier
set by WNX.
WNX_apid (word) application I.D. of parent
copy of Wind-X
WNX_grafhandle (word) graphics handle of parent
WNX_global (long) ptr to parent's GLOBAL
array
WNX_vdiparams (long) ptr to parent's VDI
array
WNX_aesparams (long) ptr to parent's AES array
WNX_messagebuf (long) ptr to parent's message
buffer
WNX_in (8 words) WNX_in array
WNX_out (8 words) WNX_out array
WNX_flags (word) event flags (a la the AES
call evnt_multi)
WNX_link (long) address for resuming
execution (used by XES)
WNX_tcount (word) timer count in 20ms
between events.
WNX_troutine (long) address of TIMER routine
WNX_mroutine (long) address of MESSAGE routine
WNX_broutine (long) address of BUTTON routine
WNX_kroutine (long) address of KEYBOARD
routine
WNX_rroutine (long) address of REDRAW routine
WNX_termroutine (long) address if WNX terminates
(this runs after a
WNX_flush call!)
The values for WNX_id, WNX_apid, WNX_grafhandle,
WNX_global, WNX_vdiparams, WNX_aesparams,
WNX_messagebuf, and WNX_link are set by the XES
immediately after this call.
2) Now, the WNX must do a XES_RSRCINIT with a pointer
to a binary resource that has yet to be fixed up to
the proper screen coordinates. Because the GEM AES
is not friendly to programmers who design resources
in color, various options are allowed with a one
word flag which permits you to determine if the
resource is scaled in any way relative to the
screen font size (which is how GEM does it), and if
so, how. This first call to XES_RSRCINIT will
initialize the resource that will be displayed in
the main Wind-XES window.
Note: You may also use a resource that has been
previously fixed, but the provision for this is
not fully implemented as of 8/23/91. Also, Laser
C's RCP.PRG can generate a .C file that is, in
essence, a .RSC file that you can "imbed" in your C
applications. It will need a "fixup", so simply
pass a pointer to the array it defines, and Wind-
XES will work everything out...
3) At this point, the WNX application can do anything
it wishes (i.e. initialize system variables, find
out information about the screen, etc...) and even
call the XES until it does a XES_SUBMIT. It is
good practice to do the XES_SUBMIT and NOT an RTS
on this part of the code. The WNX application is
required to supply pointers to subroutines that
should be executed by Wind-XES when events that
it is looking for occur BEFORE the XES_SUBMIT is
done. By making the processing the GEM events
modular this helps improve execution speed, and
makes life easier on WNX programmers, particularly
those who are writing piecemeal.
For more information on the XES_INIT, XES_RSRCINIT, and
XES_SUBMIT, consult the section on XES functions.
As a note to more sophisticated (and usually dangerous)
programmers, there are ways to determine if an application is
running as a WNX, as an ACC or as a GEM program. When an
application is a desk accessory, the value P_PARENT (at
basepage+36 in your application) will be 0. For WNX applications,
this points to the basepage of the parent copy of Wind-X, which is
what is running the WNX as a child process. However, to ensure
that you can tell it is not running as a GEM program, you can
simply look at P_RESERVED (basepage+40) where you will see a
longword containg the ASCII equivalent of the string "XES".
(NOTE: Atari has officially changed this. The current method
would be to check to see if your P_RESERVED (basepage+40) is the
longword $00584553 ("XES"), and if it is, you are a .WNX. If not,
then check the current value of A0, and if A0 is null, you are a
.PRG, otherwise, you are an .ACC. This method won't work inside
the Laser C shell, though.)
Handling Events the ENiGMA Way...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
If you look at the structure of the parameter block used in
XES_INIT, you see that you have to supply pointers to routines to
be executed on events. As stated earlier, you must assume all
data and address registers are unknown when these routines start!
(NOTE: This may change by release day!)
The way this works is that Wind-XES catches events, and first
it handles any of its own (i.e., window redraws of the main
Wind-XES window, etc...), and then begins to dispatch to each of
its children, which can then take action on the events.
To aid the WNX programmer, Wind-XES passes some valuable
information, depending on the event type, to the WNX in the
WNX_out array...
"Link" Events
*-*-*-*-*-*-*
To get access to these, set bit #6 of the WNX_flags.
This feature should be able to work, but has yet to be
tested. If you are writing a WNX, try to avoid using this
call until we have verified it is 100% working!
"Link" allows you to recieve information as if you had
done an EVNT_MULTI. You recieve information in your WNX_out
array giving your information about the type of event(s) that
occurred.
WNX_out+0.W = bits 0-5 tell which events occurred.
WNX_out+2.W = mouse x coordinate at time of event.
WNX_out+4.W = mouse y coordinate " " " " .
WNX_out+6.W = the button state.
WNX_out+8.W = states of the alternate, shift, and
control keys.
WNX_out+10.W = number of times left button was clicked.
WNX_out+12.W = key scan code for keyboard event.
WNX_out+14.W = the handle of the active GEM window (the
one on top!). The handle is negated if
the window is NOT the Wind-XES window,and
and is positive if it is the Wind-XES
window.
"Link" mode also tells Wind-XES to turn operation over
to the WNX application at the address contained in WNX_link.
This is so that a programmer can dynamically change the
"return" address without mucking with the stack.
A "Link" mode call should not terminate with an RTS, but
instead, with a XES_SUBMIT, which places the address that the
TRAP #5 would have RTE'd back to in WNX_link.
Be cautious with "link" mode!
Keyboard Events
*-*-*-*-*-*-*-*
Bit 0 of the WNX_flags must be set to be able to check
for keyboard events. The WNX application will get control of
the CPU, and the routine pointed to by WNX_kroutine will be
JSRed to.
Parameters passed to the WNX are:
WNX_out+0.W = scan code of key that was pressed.
WNX_out+14.W = the handle of the active GEM window (the
one on top!). The handle is negated if
the window is NOT the Wind-XES window,
and is positive if it is the Wind-XES
window.
The keyboard routine should terminate with either an RTS
or a XES_SUBMIT.
Mouse Button Events
*-*-*-*-*-*-*-*-*-*
Bit 1 of WNX_flags must be set to handle mouse button
events. The routine pointed to by WNX_broutine is JSRed to.
Due to an idiosyncracy of Wind-X, you can only wait for
a "left mouse button pressed" event. This limits you to a
"one button" mouse for this kind of input. Future revisions
may change this but no such plan has been implemented.
WNX_out+0.W = mouse button state.
WNX_out+2.W = x coordinate of mouse.
WNX_out+4.W = y coordinate of mouse.
WNX_out+6.W = number of times mouse entered the state.
WNX_out+8.W = the states of the alternate, control and
shift keys during the event.
WNX_out+10.W = index of the object clicked on (this
applies only to the resource displayed in
the main Wind-XES window, and no
"simulated" FORM_DO call has been
performed. Call XES_FORMDO with this
value in WNX_in+6.W to perform a FORM_DO-
like action.
WNX_out+14.W = the handle of the active GEM window (the
one on top!). The handle is negated if
the window is NOT the Wind-XES window,
and is positive if it is the Wind-XES
window.
You can use mouse button events to handle events for not
just the main Wind-XES window, but a window opened by the
WNX. Simply do an XES_XFORMDO for the window you need to
know about!
Message Events
*-*-*-*-*-*-*-
Bit 4 must be set in WNX_flags for the WNX to process
GEM messages. The routine pointed to by WNX_broutine is
JSRed to.
This is very important: A WNX must never alter the
contents of the message buffer (the address of which is in
WNX_messagebuf) because other WNXes may have a need to check
for events!
With this, you can check for GEM events, and even send a
message to another resident application, including other
WNXes (provided they, too, are looking for messages).
WNX_out+0.W = RESERVED (usually 1)
WNX_out+2.W = type of message.
WNX_out+14.W = the handle of the active GEM window (the
one on top!). The handle is negated if
the window is NOT the Wind-XES window,
and is positive if it is the Wind-XES
window.
Timer Events
*-*-*-*-*-*-
Bit 5 must be set for a timer event to be processed by a
WNX. The routine pointed to by WNX_troutine is JSRed to.
A WNX can wait for a timer event for no less than
20ms, which is the finest timer event possible on the ST.
There are no guarantees by either GEM, the AES, or the XES
that exactly 20ms has elapsed between calls. In fact, one
should check the system clock (via the BIOS) or install an
interrupt (which should NEVER call the XES!) to handle time-
critical code...
(IMPORTANT NOTE: Never give less than a 1/5 second (i.e., a
WNX_tcount of 10) delay between timer events when your timer
routine is calling GEMDOS, BIOS or XBIOS. Right now, some
testing has indicated a problems occurring when programs are
run while such tight time constraints are being placed on the
system. Case in point is the sample code provided for the
BIN2C.WNX file converter, which does disk writes on the timer
routine. On my 16mhz 68000 machine, when WNX_tcount is set
to 10, it works reliably with programs being run and
terminate in rapid succession (using DC Desktop or the normal
ST Desktop on TOS 1.2.). With a WNX_tcount of 1, the program
will crash under the same conditions. This is why BIN2C.WNX
is not very fast... <grin>)
When a WNX is given control after a timer event, the
following parameters are passed:
WNX_out+0.W = reserved (usually 1)
WNX_out+2.L = number of timer events processed by the
parent copy of Wind-XES since it was
launched. (naturally, limited to 32
bits!)
WNX_out+14.W = the handle of the active GEM window (the
one on top!). The handle is negated if
the window is NOT the Wind-XES window,
and is positive if it is the Wind-XES
window.
The Purposes of WNX_rroutine and WNX_termroutine
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
WNX_rroutine is automatically JSRed to if it is nonzero.
No bits in WNX_flags need be set. WNX_rroutine is executed
every time the main Wind-XES window is redrawn, and it should
not do an XES_DRAW of an object in that window during the
execution of WNX_rroutine. No parameters are placed in
WNX_out.
A good use for WNX_rroutine is checking things that may
change. The ENiGMA Control Panel checks both the system time
and date and pops in to supervisor mode to check the system
palette in order to accurately represent any changes to these
values.
WNX_termroutine is run when a WNX is about to terminate
and get flushed from memory. As stated earlier in this
documentation, it should be used for housekeeping purposes,
like restoring stolen vectors, etc... However, if D0.L is
equal to the ASCII value of the 24 bits that make up the
string "XES", the WNX is kept in memory, but Wind-XES will
act oblivious to it. As of 9/09/90, this feature is not
fully implemented, but will be at the time of release.
XES Functions (08/23/91 Revision)
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
All XES functions, excluding XES_INIT are performed like so:
move.w <function_id>,-(a7)
move.w #-1,-(a7)
trap #5
...where the <function_id> is the number corresponding to the
XES function you want. XES_INIT works like so:
xes_init move.l <pointer to parameter blk>,-(a7)
move.w #0,-(a7)
trap #5
The following are descriptions of the various XES functions.
The descriptions are in a format, like this:
<name of function> (<function number (decimal)>)
<WNX_in parameters>
<WNX_out parameters>
<description of the function>
XES_submit (-1)
in: none.
out: none.
This allows a WNX to stop execution of itself and to turn
over control to the XES so that other processes can get a chance
to run. In most cases, an RTS without a corresponding JSR/BSR
would suffice, but you should use XES_submit after your WNX
initialization code.
XES_init (0)
in: none.
out: none.
This initializes the XES parameter block of your application
and makes sure it is recognized by the system. You should NOT
have any code preceding this, as your program may be flushed due
to any number of reasons (i.e. insufficient RAM, conflicts with
other application's interfaces, etc...).
XES_rsrcinit (1)
in: WNX_in+0.W = non-zero causes .RSC to be fixed up.
WNX_in+2.W = type of fixup.
0 = no scaling.
1 = scale pixel coords only.
2 = scale both pixel and
character coords.
WNX_in+4.L = if WNX_in+0 = 0, a pointer to the binary
resource to be fixed up, or else it is a
pointer to a structure like this:
pointer to a .RSC header
pointer to the first tree in the .RSC
Where the .RSC header is of the same
format as the header of a binary resource
file (.RSC).
out: WNX_out+0.W = number of trees in resource, or 0 if the
call failed.
WNX_out+2.L = address of first tree in resource.
WNX_out+6.L = address of the tree list in resource.
The first time this call is made, it should be done
immediately after a XES_init. This first call tells Wind-XES what
the resource that it will be displaying in the main Wind-XES
window for this WNX will be. When Wind-XES is loading a utility
in, it checks to see if it will fit from the width and height
coordinates of the largest resource tree contained in that
resource, and if there is not enough space in the Wind-XES window,
the application is flushed immediately. Subsequent calls to
XES_rsrcinit can be used to initialize resources for other
purposes, such as windows (see Paint-X).
XES_sibling (2)
in: WNX_in+0.L = pointer to 16 byte i.d. name field.
out: WNX_out+0.W = number of WNXes in system with that i.d.
name.
WNX_out+2.L = a pointer to "tempbuf", which is a
buffer containing a list of the matching
.WNXes in the system. The format of an
entry in this structure is:
application i.d. of parent.W
WNX i.d. of matching child.W
If both are null, you are at the end of
the "match" list.
This function's sole purpose is to provide a way for a WNX to
find out if multiple copies of itself have been installed. For
some programs, mainly vector stealers, having multiple copies
installed can create headaches. All this function does is find
out how many copies are installed. A new function
(WNX_inqsibling) will probably be added which returns information
about each of the WNX processes that matches.
XES_mesagwrite (4)
in: WNX_in+0.L = pointer to recipient list/ap_id of ACC to send to.
WNX_in+4.W = length of message (up to 256 bytes)
WNX_in+6.L = pointer to message
out: none.
The eXtended Environment System can allow a WNX to write messages
selectively to another WNX process. The recipient list
is a structure of the form:
(parent's ap_id).W | (32 bit bit field, representing the
32 potential children of that parent).L
A set bit means to write to that child.
XES_malloc (38)
in: WNX_in+0.L = amount of memory to allocate
out: WNX_out+0.L = 0 if failed, or location of allocated
RAM.
This function is used in order to fix a bug in some revisions
of TOS that frees up memory allocated by a desk accessory. This
happens mainly when a DA (or WNX, for that matter) is trying to do
a M_ALLOC while a GEM program is running at the same time. When
GEMDOS does the M_ALLOC, it incorrectly gives the "ownership" of
that block of RAM to the GEM program. This function is the only
known "illegal" call in Wind-X, but it is necessary in order to
prevent this GEMDOS bug from affecting program performance.
To free up this RAM, simply use M_FREE (the GEMDOS call).
XES_flush (39)
in: none.
out: none.
Tells the XES to terminate the execution of this application,
and to free up the memory used by it. The WNX will still have the
WNX_termroutine executed before being flushed, so it can do any
cleanup it finds necessary (i.e., restore altered system vectors,
close windows, etc...)
XES_genv (40)
in: none.
out: WNX_out+0.L = address of the Line-A structure.
WNX_out+4.L = ptr to virtual workstation attributes (a
45 word structure).
WNX_out+8.W = screen width (in pixels).
WNX_out+10.W = screen height (in pixels).
WNX_out+12.W = X scale of screen font to an 8x8 screen
font (i.e., a 16x8 system screen font
would make this value 2.
WNX_out+14.W = Y scale of screen font to an 8x8 screen
font.
This call simply lets the WNX know about the system's
graphics capabilities. You should note that the GEM work area is
not the same as the screen size. To avoid doing a WIND_GET to
find the work area on the desktop, use XES_pwindow instead, since
during the accessory loading process, calling the AES would be
unpredictable from a WNX (and calling the AES during a WNX
initialization should be avoided!).
The scales of the screen fonts is handy for when you have a
slider defined for a resource, and the resource changes size due
to the changes from an 8x8 screen font (color STs) to 8x16 screen
font (monochrome). This usually is a problem for applications
that have vertical sliders, and the problem occurs naturally under
GEM, and is not limited to Wind-X. (In fact, this is a neat fix
for it!)
XES_pwindow (41)
in: none.
out: WNX_out+0.W = X coordinate of the Wind-XES window
containing this application.
WNX_out+2.W = Y coordinate of the Wind-XES window.
WNX_out+4.W = W (width) of the Wind-XES window.
WNX_out+6.W = H (height) of the Wind-XES window.
WNX_out+8.W = X coord of desktop work area.
WNX_out+10.W = Y coord of " " " " .
WNX_out+12.W = W of the " " " " .
WNX_out+14.W = H of the " " " " .
The purpose of this function was mainly to discourage
programmers from using the GEM AES WIND_GET call to find out how
large the desktop work area was during their program
initialization, which may occur during the loading of desk
accessories. AES calls by a WNX, from within Wind-XES running a
DA during the loading of DAs can cause unexpected problems.
Basically, WNX_out+8 to WNX_out+14 work like that WIND_GET
call to find out the coordinates of the desktop work area.
WNX_out+0 to WNX_out+6 allow the application to find the
coordinates of the main window used by the copy of Wind-XES
running it.
XES_draw (42)
in: WNX_in+0.W = index of the starting object's depth for
the XES_draw.
WNX_in+2.W = index of the ending object's depth.
out: none.
This call is used to allow a WNX to redraw its interface
inside of the Wind-XES window. A good example of this is the
TIME.WNX program, which updates even when other windows are
overlapping it. XES_draw is intelligent enough to output properly
even with other windows overlapping the main Wind-XES window,
which contains the resource you're redrawing, and this allows
for "background" output.
XES_redraw (43)
in: WNX_in+0.W = handle of the window to redraw.
WNX_in+2.W = alignment flag.
0 = use ob_x and ob_y of resource.
-1 = align to window's work area.
WNX_in+4.L = address of the resource tree to use
during the redraw.
out: none.
This is a potent function which allows for quick and easy
redraws of windows that contain resource trees. All you need to
provide for the call is the handle of the window to redraw, a flag
fr alignment, and the address of the tree to use for the redraw.
There ARE limitations:
o Wind-XES currently only draws 10 levels deep into the
resource tree.
o Wind-XES does not check for proper pointers and values
in this routine, so BE CAREFUL!
These limitations may be removed by release day.
The beauty of this call is that with six lines of code, you
can redraw a window. For example, in Paint-X, two resources are
initialized, and the second resource has a pointer to its first
resource tree called "rsrcptr2". This is the resource with the
icons showing the drawing tools, among other things.
xes_redraw_example
move.w w_handle,WNX_in
move.w #-1,WNX_in+2
move.l rsrcptr2,WNX_in+4
move.w #43,-(a7)
move.w #-1,-(a7)
trap #5
However, you should always have your WNX_mroutine, which
catches GEM message events ready to catch the window redraw
requests from GEM for your WNX's window if you wish to do this
properly, as Wind-XES doesn't notify you officially of the
redraw (GEM does this very well, you know!). It is a simple
matter to check for the redraw message and to make sure the
window handle matches yours before calling XES_redraw.
XES_chrsrc (50)
in: WNX_in+0.W = index of the new tree to use.
out: WNX_out+0.W = the new tree's index (-1 if failed)
This call allows you to use a resource that has different
resoruce tree "forks" within the Wind-XES main window. A good
example is the ENiGMA Control Panel (ECP.WNX) which has several
levels the user can interact with, thanks to this call.
XES_stredit (64)
in: WNX_in+0.W = handle of the window this resource is in.
WNX_in+2.L = address of resource tree containing
editable object.
WNX_in+6.W = index of the editable object (must be
F_text or F_boxtext!).
WNX_in+8.W = key press to check (uses scan-code
method, like C_RAWIO and EVNT_KEYBD).
WNX_in+10.W = requested cursor position inside of
editable field. (-1 makes the cursor
position the first empty character inside
of the displayed string).
out: WNX_out+0.W = ASCII character's value. -1 if call
failed.
WNX_out+2.W = new cursor position (-1 if call failed).
This function lets the programmer use editable text objects
within the framework of Wind-XES without halting other processes.
Care should be taken because the user can edit multiple WNX
processes simulaneously (i.e., the same keypress goes to four
different applications!). However, the advantage is that it
allows all of the WNX tasks to continue running without the
interruption a GEM AES FORM_DO will cause.
The limitation on this call is that the window containing the
editable object MUST be on top. This prevents keypresses from
going to processes that are underneath the "active" window, and
makes handling the XES_stredit call much