Foundation Editor Technical Reference

The Foundation Shell...

The heart of Foundation is the Foundation shell.  It is a GS/OS aware desktop
application.  The shell has been carefully crafted to be as general as is
humanly possible... to service complex editors specifically tuned to the type
they edit... to utilize custom resource selectors that extend the intuitive
desktop interface... and to do these things quickly and elegantly... now and in
the future.

It is fairly generalized in that, with few exceptions, it ONLY knows that a
resource is some arbitrary data structure stuck in the resource fork of a file.
Such generalization is necessary to make certain that Foundation stays healthy
as Apple changes and evolves the world of Apple IIGS resources.  Consider how
limited Foundation would be if it assumed that the resources defined as of this
writing were all the resources you'd ever need to access... or if the addition
of another standard type forced us to replace all the installed shells with
revised versions.  We presume... we don't assume!


The Resource Editor Module (REM)...
Resource editors and selectors are to Foundation's shell what Desk Accessories
are to the Desktop.  The shell provides the backbone of the Event and Resource
Managers and the editors are called upon to preform amazing feats of magic.

Basically, a Resource Editor Module is an extended file (filetype $BC, auxType
$4006) whose data fork consists of a standard REM entry point header followed
by the code to support those entry points.  This code may be the complete
editor, just enough code to support code resources, or perhaps a combination
thereof.  In addition, it may optionally provide a custom resource selector.
Your code may be written in any GS assembler, APW C, Orca/C, Orca/Pascal, or any
other high level GS language that generates either APW or Orca stack frames.


REM RESOURCE FORK
The resource fork must contain one remStartRes resource ($7FFF) for each
resource type that your editor supports, and should provide the help resources
($7FFE) your editor may use.  (An editor should have at least one help resource,
but may have as many as the programmer wishes to maintain context sensitivity).

The remStartRes and remHelpRes resource formats are:

     remStartRes         $7FFF

     $00  version        word      minimum = 3
     $00  version        word      must be 0
     $02  resType        word      set to type REM supports
     $04  minShell       long      GS version long $01000000
     $08  rFlag          word      see below
     $10  rMenu ID       long      rMenu or script resource ID or null
     $14  byte...        resName   pString containing resource type name.

     rFlag bit 15   Supports Add Type menu
               14   Supports Custom selector
               12   Template Alias (reserved for ScriptEdit)
               6    Supports REM_GETLINK (0 if type has no dependents)
               5    Uses Data Converter
               4    320 Mode Aware (0 if 320 invalid)
               2    APW stack frame
               0    Foundation 2 aware (set to 1)

          (All other bits are reserved and must be set to 0)

A typical editor will have rFlag set to $8041, indicating that it is Foundation
2 aware, it has dependents and thus supports REM_GETLINK, and it wants to appear
in the Add Type menu.  $8051 would have the same attributes and also support the
320 graphics mode.  (Hint- if you are working on items that only work well in
640 mode, like say, Finder related resources, or if you need a 640x200 screen
to accomplish what you want, you will NOT want to have bit 4 set.  For example,
the HexEdit and ScriptEdit will not operate in 320 mode.  Several shell features
will be disabled in 320 mode as well.)


     remHelpRes          $7FFE

     $00  helpText       Ascii text describing editor.


In addition to these items, other resources can be present as well for use by
the editor.  A Version and Comment resource should be present, though they are
not required. If you want to have a menu in the Shell menu bar when your editor
is in use, you should have the rMenu, rMenuItem and associated rPStrings (and
possibly rItemStructs) required for them.  The MenuID the referred to in
remStartRes must contain the resource ID of this menu.  You may use resources
for all of the editor's data structures just as you might for your own
application.  However, there are some limitations documented below owing to
the nature of using resources in a resource editor.  You might also want to
keep a default sample of the type of resource you edit for creating new
resources allowing the end user to customize it.  You may find this preferable
to building a default from within your code.

Your editor can also set and use its own preferences.  These should be stored
in a REMPreference ($7FFB) resource stored in the Foundation.Data file.  Do not
store this in your editor.  Since the Foundation.Data file is stored in the
Foundation.User directory, which is to be kept in a user folder on an AppleShare
network, this allows AppleShare friendly access despite the fact that the
editor itself will be in a common folder where it could be multiply accessed.
To access these preferences for loading or saving, use fLoadResource using the
resource type your editor is dealing with as the resource ID, and the
fdResFileID returned in the REM_STARTUP call as the file to access it from.
The Foundation.Data fork is also an ideal place to store your default data,
the type and ID of which should be referenced in the REMPreference resource..

REM DATA FORK
The REM Header is defined in the source file REMHEADER.ASM. If you are writing
your REM in APW C or ORCA C or Pascal, then REMHEADER should be used as the
ROOT object at the beginning of your editor. The header itself has this form:

     remHeaderRec
     ------------
     $00  Address in your code of REM_OPEN -1
     $04  Address in your code of REM_CLOSE -1
     $08  Address in your code of REM_WRITE -1
     $12  Address in your code of REM_EVENT -1
     $16  Address in your code of REM_ACTIVATE -1
     $20  Address in your code of REM_GETLINK -1
     $24  Address in your code of REM_VIDMODE -1
     $28  Address in your code of REM_PRINT -1
     $32  Resource ID of current Help Text (type $7FFE) *
     $36  Pointer to a special Window Draw Proc         **
     $40  Address in your code of REM_STARTUP -1
     $44  Address in your code of REM_SHUTDOWN -1
     $48  Vector for FINLINE callbacks  (Assembly)
     $52  Vector for FSTACK callbacks   (C or Pascal)
     $58  Pointer to the shell extended event record    **

          * - value set by editor for shell's use
         ** - value set by shell for editor's use

Each of the above entry address must be supported in one way or another by the
editor.  Some may not be needed for a particular editor, however all should be
at least stubbed to provide a sane return should they be called.


SHELL-REM INTERACTION
NOTE- The following makes reference in several places to "Shell Callbacks."
For more information on these (always begining with the lower case f, as in
fLoadResource or fGetPrivateData) see the Foundation Editor Callback Reference.

Shortly (and we mean shortly!) after Foundation is started, it looks for REM
files in the Foundation.Edit folder, opening the resource fork for each one it
finds.  As each fork is opened, all remStartRes resources are loaded, and two
internal tables are built to track REM file and resource type information.
The resource forks for the REMs are not closed until Foundation shuts down.

The first time the user (or a REM) selects a resource type for editing the
shell will load the REM data fork (code) and call the REM_STARTUP function
prior to calling REM_OPEN. Subsequent editing requests of the same resource
type, or other resource types supported by the REM will bypass REM_STARTUP as
long as the REM remains loaded.

During the open call, unless the OpenSilent bit is set in the fFlags word,
the REM should open at least one window and setup that window's refcon by using
the fAddPrivateData callback. (IMPORTANT NOTE- do not manipulate the window's
refcon directly, as the shell uses it as well.  Always use the
fAdd/fSetPrivateData calls to manipulate your data.)  This will initialize the
window for automatic dispatching for subsequent events and without it the
window will never recieve any events, including activate events.  The REM will
be operating within the shell's main event loop and to assure editor/window
associativity, the refcon must be set. The information that must be referenced
reference the resource either passed in the parameter block, or created by the
editor as part of the open call.  Using callbacks to access the window's
refcon gives us the freedom to enhance the refcon data without having to worry
about REM compatibility later.  The fGetWindowTitle callback should be used to
get a standardized title pString if your window has a titlebar.

If the OpenSilent bit is set, your editor should simply create a new resource,
using the ID and data provided in the REM_OPEN call if given, otherwise
replacing them with default data and/or a valid ID, returning the new ID in
the resID field.  When returning from REM_OPEN with OpenSilent, you should
also make sure you clean up as you would in a REM_CLOSE (see below) call, since
it is implicit from the singular nature of the call.

After the REM opens a window and returns to the shell, an activate event will
be posted in the event queue by the system.  This will cause the shell to
examine the activating window to determine who owns it, and then a REM_ACTIVATE
call will be made to the REM.  Subsequent events will be dispatched, as
appropriate, as REM_EVENT, REM_CLOSE, and other calls.

When the shell shuts down a REM, a REM_SHUTDOWN call is issued.  At some point
in the shell's development, we will handle REM "caching" and shutdown inactive
REMs when memory requirements become critical.

EDITORS AND SELECTORS
In addition to one or more resource editors, a REM may also support custom
resource selectors, which would provide an alternative method of resource
selection to the standard resource list window.  For example, an Icon selector
might display the icons themselves, allowing the user to double click on the
icon to select it.  The callback fSelectorRequest allows a selector to access
the functions used in the standard resource selector window.

The method of communicating with the selector is through the editor entry
points.  The Shell indicates whether the call applies to an editor or a
selector.


THE STANDARD REM FUNCTIONS
The remHeaderRec shown above stores the address of the ten functions your REM
must support to properly interact with the shell.  They are modeled loosely
after the structure of a New Desk Accessory (NDA), though substantially expanded
to address some of the more specific functions that an editor and the shell must
deal with.  The minimum routine for any of these functions would simply be a
return instruction.

When a REM function is called, a pointer to the functions parameter block is on
the stack directly above a 3 byte RTL address back to the shell.  Foundation
does not make any assumptions regarding the language you are programming in.
Because different languages support different calling conventions, the parameter
block pointer may either be left alone, or removed from the stack by your
function.  Upon completing its work, your call simply returns with an RTL.

The REMHEADER.ASM file is provided as a model for assembly language programmers.
REMHEADER.ROOT is an assembled copy of REMHEADER.ASM, and should be used with
APW C, ORCA/C and ORCA/Pascal instead of the compiler generated ROOT file. The
function names and callback vectors are all upper case (for example- REM_OPEN).
The remaining fields are set for upper case or mixed case support so case
insensitive languages and C can all be happy.  ASM65816 macros are provided in
M16.Foundation for all callbacks through the FINLINE vector. ORCA/Pascal
interfaces and the C header files are provided to access the callbacks via the
FSTACK vector.

Calls expect errors to be reported in the accumulator (a word returned from the
high-level languages).  Zero should be returned upon completion of a successful
call.  The shell does not rely upon the state of the carry bit.  Callbacks also
return any errors in the accumulator, with the carry bit set if an error is
returned.

The Lets take a few minutes to examine each of these functions from a REMs
perspective.  One syntax note here: We use the words input and output here to
describe input TO your function and output TO the shell.  Pay attention because
this will change when we get to the callbacks.


REM_OPEN


Called by the shell in one of five possible cases:

     o  An existing resource needs to be edited.  This is the most common case.

     o  A new item needs to be created from scratch.   The REM can provide
        default data for the new item, and the editor must assign the resource's
        new ID.

     o  A new item needs to be created with default data provided from some
        other source.  The data is provided in a handle, and the new item may
        or may not have a pre-assigned ID.

     o  A new item needs to be created, but the REM should simply make it and
        return without opening an editor window. Again, default data may be
        provided, and generally, the ID will be pre-assigned.  This case will be
        most commonly employed to fix missing dependent resource problems.
        This, (OpenSilent) is the only case where an editor should NOT open a
        window for editing.

     o  The REM supports a resource selector and the user has requested that the
        selector is to be opened.  The Data parameter will contain a handle to
        the list member record array that the shell would normally have used in
        the standard type window's item list.  The selector may use this as
        needed, however it should not modify the item strings referenced by
        pointers nor the ID values within the array.  The handle becomes the
        property of the selector, and must be disposed of when the selector is
        through with it.


REM_OPEN Parameter Block (reference fOpenRec)

     $00 resType        word input- REMs supporting more than one resource type
                        will find this useful to determine which type is
                        requested.
     $02 resID          long input- ID of the resource.  If null, the editor
                        must create a new resource and return the ID.
     $06 fFlag          word input- described below.
     $08 Data           handle input- in some instances this will contain a
                        handle for use as default data.  For selectors, this
                        will contain a list member handle (see below).
     $0C wColorPtr      pointer input- if the REM uses a window with a title
                        bar, this is a pointer to the correct window color
                        record for the current file.


          Bit values for the fFlags word are:

               bit 12           ScriptEdit request (reserved)
               bit 11           HexEdit request (reserved)
               bit 10           REM Selector request (if set the call applies to
                                a selector and not an editor).
               bit 9            Resource data is provided.
               bit 8            Create resource and return without opening a
                                window (OpenSilent).
               bits 7           The state of bits 0-4 should be applied for
                                shell menu items.
               bit 4            Select All active
               bit 3            Print/Page Setup active
               bit 2            Clear active
               bit 1            Cut/Copy/Paste active
               bit 0            Undo active

                (All other bits should be ignored)


          REM_Open Data list member handle for Selectors:

             Handle to item array of:
               $00 text       pointer to an item pString ("00000000 name")
               $04 flag       byte (5th byte of a standard list member record)
               $06 nref       long ID of item.





REM_CLOSE


Called when a REM's window is to close.  The close call is made when, through
some action, the user has finished working with a particular resource, or when
the file is closed with pending REM windows open.

REM_CLOSE Parameter Block (reference fCloseRec)

     $00 resType        word input- REMs supporting more than one resource type
                        will find this useful to determine which type is
                        requested.
     $02 resID          long input- ID of the resource.
     $06 fFlag          word input- described below.
     $08 windowPtr      pointer input- this is the GrafPortPtr for the window.


          Bit values for the fFlags word are:

               bit 12           ScriptEdit request (reserved)
               bit 11           HexEdit request (reserved)
               bit 10           REM Selector request (if set the call applies
                                to a selector and not an editor).
               bits 7           The state of bits 0-4 should be applied for
                                shell menu items
               bit 4            Select All active
               bit 3            Print/Page Setup active
               bit 2            Clear active
               bit 1            Cut/Copy/Paste active
               bit 0            Undo active

                (All other bits should be ignored)




REM_WRITE


Called when the shell requires that the resource to be valid on disk. The write
call uses the close parameter block, however the REM should leave the window
open because the editing session is not terminating. There are several times
when the disk based resource must match the resource being edited, such as
during a Save or Save As operations.

The window MAY NOT be the front window when this call is issued, therefore the
window pointer in the record must be used by the REM.


REM_WRITE Parameter Block (reference fCloseRec)

     $00 resType        word input- REMs supporting more than one resource type
                        will find this useful to determine which type is
                        requested.
     $02 resID          long input- ID of the resource to write.
     $06 fFlag          word input- described below.
     $08 windowPtr      pointer input- this is the GrafPortPtr for the window.


          Bit values for the fFlags word are:

               bit 12           ScriptEdit request (reserved)
               bit 11           HexEdit request (reserved)
               bit 10           REM Selector request (if set the call applies
                                to a selector and not an editor).
               bits 7           The state of bits 0-4 should be applied for
                                shell menu items
               bit 4            Select All active
               bit 3            Print/Page Setup active
               bit 2            Clear active
               bit 1            Cut/Copy/Paste active
               bit 0            Undo active

                (All other bits should be ignored)




REM_EVENT


This is the most often made call, and the place where most of your work will be
done.

The default TaskMask ($1F7FFF) passed to all REMs and selectors:

          inNull                   wInContent
          mouseDownEvt             wInDrag
          mouseUpEvt               wInGrow
          keyDownEvt               wInZoom
          autoKeyEvt               wInFrame
          updateEvt                wTrackZoom
          wInDesk                  wHitFrame
          wClickCalled

          app3Evt   (the item referenced has been renamed)
           (if this is received, call fGetWindowTitle to get the new name)

The following events would apply to selectors only:

          app1Evt   (the item referenced has been added)
          app2Evt   (the item referenced has been deleted)
          app4Evt   (the item referenced has been changed)

Foundation allows editors and selectors to associate a TaskMask to a window.
Use the fAddPrivateData and fSetPrivateData callbacks to set a window's
TaskMask as appropriate.

The TaskRecord referenced through the fEventPtr address in the REM Header
contains valid activate event data, including the grafPortPtr in wmTaskData.


REM_EVENT Parameter Block (reference fEventRec)

     $00 resType        word input- REMs supporting more than one resource type
                        will find this useful to determine which type is
                        requested.
     $02 resID          long input- ID of the resource.
     $06 fFlag          word input- described below.
     $08 taskCode       word input- the result of the TaskMaster call.


          Bit values for the fFlags word are:

               bit 12           ScriptEdit request (reserved)
               bit 11           HexEdit request (reserved)
               bit 10           REM Selector request (if set the call applies
                                to a selector and not an editor)
               bits 7           The state of bits 0-4 should be applied for
                                shell menu items
               bit 4            Select All active
               bit 3            Print/Page Setup active
               bit 2            Clear active
               bit 1            Cut/Copy/Paste active
               bit 0            Undo active

                (All other bits should be ignored)




REM_ACTIVATE


Called when an activate event applies to an editor's window. The activate call
informs a REM that it is becoming active or inactive. call is made when,
through some action, the user has finished working with a particular resource.

On a deactivate event the REM must make sure the resource handle contains any
updated data, because some other editor may need to update a instance of the
resource when it regains control - the only common location is the resource's
handle.

The TaskRecord referenced through the fEventPtr address in the REM Header
contains valid activate event data, including the grafPortPtr in wmTaskData.


REM_ACTIVATE Parameter Block (reference fActivateRec)

     $00 resType        word input- REMs supporting more than one resource
                        type will find this useful to determine which type is
                        requested.
     $02 resID          long input- ID of the resource.
     $06 fFlag          word input- described below.
     $08 linkHand       handle input- if the editor supports REM_GETLINK, this
                        handle will contain a resource dependency link record
                        for use with the fQueryLinkHand callback to determine
                        if any of the resource's dependents have been changed
                        since the last activate.


          Bit values for the fFlags word are:

               bit 15           Set if this is an activate event, clear if
                                deactivate
               bit 12           ScriptEdit request (reserved)
               bit 11           HexEdit request (reserved)
               bit 10           REM Selector request (if set the call applies
                                to a selector and not an editor)
               bits 7           The state of bits 0-4 should be applied for
                                shell menu items
               bit 4            Select All active
               bit 3            Print/Page Setup active
               bit 2            Clear active
               bit 1            Cut/Copy/Paste active
               bit 0            Undo active

                (All other bits should be ignored)




REM_GETLINK


This is a call which is required for one of the more special parts of the
Foundation architecture.  As you are doubtless aware, there are resources that
have dependent or 'child' resources which the host or 'parent' requires to
function properly.  (We're sure you've noticed when they are missing System
Death $1E06 (the "sliding Apple") gets you).

REM_GETLINK enables the shell to determine these resource interdependencies by
allowing an editor that works with dependents to make the shell aware of it.
The shell then builds a dependency link, which is used for intelligent
cut/copy/paste, delete and clear operations.

An example- deleting a Window could also take its Title pString, Control List,
Controls, Control pStrings and so on (sometimes seemingly into infinity) away
too.  Similarly, copying the same window could take all that extra baggage
along with it as well.

Only editors for resource types that can reference other resources should set
the rFlag bit 6 in the remStartRes resource (Supports REM_GETLINK).  The editor
will be called whenever a dependency link is generated that includes an item of
the editor's resource type.

When an editor gets a REM_GETLINK call it must do the following:

     1. Call fLoadResource to get the resource in the parameter block.

     2. Scan that resource for references to other resource references.

     3. Call fExtendLinkHand once for each dependent resource type/id
        discovered in the scan.

     4. Call fReleaseResource to dispose of the original resource.


REM_GETLINK Parameter Block (reference fLinkRec)

     $00 resType        word input- REMs supporting more than one resource
                        type will find this useful to determine which host
                        type is requested.
     $02 resID          long input- the ID of the host resource.
     $06 resFileID      word input- The file ID of the resource fork containing
                        the host resource.
     $08 linkHand       handle input- this handle contains a resource dependency
                        link record for use with the fExtendLinkHand callback.




REM_VIDMODE


Called by the shell to tell the editor or selector that we are shifting gears
and moving into a different video mode. Based on the type of window you have,
there are a number of options you would want to pursue:


     o  When switching to 320 mode, if your window is larger than 320x180 you
        might want to resize it.  In either case, some controls may seem bizarre
        looking after the change and will need tweaking.

     o  A color scheme that looks good in 640 mode may well look absolutely
        atrocious in 320 mode, and vice versa.  You might want to touch things
        up a bit.  (Of course, there ARE those who LIKE Orange and Green
        together!)

     o  You might jut want to run and hide- that is simply make your window
        invisible-  DON'T DO THAT!!!!  If your REM can work in both modes,
        make it so.  If it doesn't- DO NOT SET THE 320 Mode Aware bit in your
        remStartRes rFlag field and the shell will take care of hiding your
        window for you. Sorry- there is no way to support a 320 mode only REM,
        and 320 mode windows WILL appear in 640 mode.

When switching between 640/320 mode and back again, the shell informs the user
(via text screen) as to which windows are hidden/unhidden, moved, etc.

Selectors especially should be crafted to make sure they function properly in
both modes if the editor of the same type supports both modes.

The window MAY NOT be the front window when this call is issued, therefore the
window pointer in the record must be used by the REM.


REM_VIDMODE Parameter Block (reference fVidModeRec)

     $00 resType        word input- REMs supporting more than one resource type
                        will find this useful to determine which type is
                        requested.
     $02 resID          long input- ID of the resource.
     $06 fFlag          word input- described below.
     $08 windowPtr      pointer input- this is the GrafPortPtr for the window.
     $0C wColorPtr      pointer input- if the REM uses a window with a title
                        bar, this is a pointer to the correct window color
                        record for the current file in the new mode.


          Bit values for the fFlags word are:

               bit 14           Set if switching to 640 mode.
               bit 12           ScriptEdit request (reserved)
               bit 11           HexEdit request (reserved)
               bit 10           REM Selector request (if set the call applies
                                to a selector and not an editor).
               bits 7           The state of bits 0-4 should be applied for
                                shell menu items
               bit 4            Select All active
               bit 3            Print/Page Setup active
               bit 2            Clear active
               bit 1            Cut/Copy/Paste active
               bit 0            Undo active

                (All other bits should be ignored)




REM_PRINT

Is the call the shell tells the editor or selector that the user has selected
Page Setup or Print.  A REM only need worry about this call if it has set bit 3
(Print/Page Setup Active) in the fFlags word in some prior call.  Printing can
be very useful for many resource types- for example, printing a hard copy of the
Window you are building, a graphic image or Text Block...  and there are other
things that might not be as useful (rTwoRects come to mind here). If your REM
supports printing, here is the entry point.  The print routines themselves are
all up to the REM.


REM_PRINT Parameter Block (reference fCloseRec)

     $00 resType        word input- REMs supporting more than one resource type
                        will find this useful to determine which type is
                        requested.
     $02 resID          long input- ID of the resource.
     $06 fFlag          word input- described below.
     $08 windowPtr      pointer input- this is the GrafPortPtr for the window.


          Bit values for the fFlags word are:

               bit 13           Set if Page Setup request, clear for Print
               bit 12           ScriptEdit request (reserved)
               bit 11           HexEdit request (reserved)
               bit 10           REM Selector request (if set the call applies
                                to a selector and not an editor).
               bits 7           The state of bits 0-4 should be applied for
                                shell menu items.
               bit 4            Select All active
               bit 3            Print/Page Setup active
               bit 2            Clear active
               bit 1            Cut/Copy/Paste active
               bit 0            Undo active

                (All other bits should be ignored)


REM_STARTUP


Tells you that your REM is being brought to life.  It is called only when the
REM is first loaded.  When the REM gets this call, it should do whatever it
needs to do to setup globals, etc. This is the only time when the Foundation
Shell, Data and REM resource fileID's are passed.  Also, the REM's specific
memory manager ID is passed here.  Note that REMs supporting multiple types
will only be called once.


REM_STARTUP Parameter Block (reference fStartStopRec)

     $00 edUserID           word input- REM userID to be used whenever creating
                            new handles or other Memory Manager related
                            actions.
     $02 edResFileID        word input- REM resource file ID.
     $04 shResFileID        word input- shell resource file ID.
     $06 fdResFileID        word input- preferences resource file ID.


REM_SHUTDOWN


Called when a REM is unloaded.  The parameter block is identical to REM_STARTUP
above.


WARNING:    The REM must release any memory allocated at startup during the
            shutdown call.  There is no guarantee that once the REM is released
            that it will be reloaded.
