@database "TOS release notes, 24 June 1993"
@options "-i -s +zz -t4 -d10"
@author "Atari Corp."
@$VER: tos4rn.stg (9/1/2001)
@subject "Documentation/Manual"


@node "Main" "TOS release notes, 24 June 1993"

@{0B}        TOS release notes, 24 June 1993@{0}


   Copyright 1992,1993 ATARI CORP
   All Rights Reserved

        I.  Changes to TOS and related products

            I.1. Changes to the Desktop

            I.2. Changes to the AES

            I.3. Changes to the VDI

            I.4. Changes to the Viewer

            I.5. Changes to the XControl

        II. @{"AES supplemental documentation" LINK "AES supplemental documentation"}

            II.1. Application library enhancements

                  II.1.1. appl_init()
                  II.1.2. appl_read()
                  II.1.3. appl_find()
                  II.1.4. appl_search()
                  II.1.5. appl_getinfo()

            II.2. Window library enhancements

                  II.2.1. Supplement for wind_get() and wind_set()
                  II.2.2. Supplement for wind_update()

                          II.2.2.1. Discussion of wind_update()

                  II.2.3. Window iconifying
                  II.2.4. Window library toolbar support

                          II.2.4.1. Division of labor
                          II.2.4.2. Window management calls
                          II.2.4.3. Support for overlapping windows
                          II.2.4.4. Redrawing and updating
                          II.2.4.5. Window library routines
                          II.2.4.6. Defines

            II.3. Event library enhancements

                  II.3.1. MN_SELECTED
                  II.3.2. New predefined AES messages
                  II.3.3. Event library toolbar support

            II.4. Graphic library enhancements

                  II.4.1. graf_mouse()

            II.5. Menu library enhancements

                  II.5.1. Using the extended menu library
                  II.5.2. Using a menu bar
                  II.5.3. Pop-Up Menus
                  II.5.4. Submenus
                  II.5.5. Scrolling Menus
                  II.5.6. Drop-Down List Menus
                  II.5.7. Keyboard scrolling
                  II.5.8. Extended menu library routines

                          II.5.8.1. menu_bar()
                          II.5.8.2. menu_register()
                          II.5.8.3. menu_popup()
                          II.5.8.4. menu_attach()
                          II.5.8.5. menu_istart()
                          II.5.8.6. menu_settings()

            II.6. Object library enhancements

                  II.6.1. objc_sysvar()
                  II.6.2. Three dimensional objects
                  II.6.3. Color icon format

                          II.6.3.1. Restriction on color icon data

            II.7. Resource library enhancements

                  II.7.1. rsrc_rcfix()
                  II.7.2. Extended RSC file format

            II.8. Shell library enhancements

                  II.8.1. shel_get()
                  II.8.2. shel_put()
                  II.8.3. shel_write()

        III. Addenda

            III.1. Softloaded resources
            III.2. Discussion of GEM.CNF
            III.3. Discussion of AES environment variables
            III.4. The _IDT cookie
            III.5. Replacing the system font
            III.6. @{"Changing the desktop font" LINK "Changing the desktop font"}
            III.7. SpeedoGDOS TEDINFO objects
            III.8. Drag and drop protocol

                  III.8.1. Originator side
                  III.8.2. Recipient side
                  III.8.3. Caveats
                  III.8.4. Sample code


@endnode


@node "Changes to the Desktop"

Changes to TOS and related products: Desktop

1.  The DESKTOP has been separated from the AES and can now be
    soft-loaded. This will allow alternative desktops to be loaded
    when 'shell drive:\path\filename' is inserted into the GEM.CNF
    file.
2.  The system no longer hangs when you move the mouse cursor into
    the Desk menu while launching a new application.
3.  The busy bee is now visible during a copy, move and delete from
    the desktop. Previously, the mouse would remain an arrow when
    these functions took place.
4.  Show File to the Desktop (w/o VIEWER), will no longer use the
    mouse buttons to scroll with. This feature was removed when the
    desktop was separated from the AES.
5.  It is now possible to select the font and size to be used when
    showing files as text.
6.  After launching an application under MultiTOS the icon now gets
    deselected.
7.  The TOS version is now displayed in the "Desktop info..."
    dialog box.
8.  The Help menus have been updated.
9.  Under MultiTOS, it is now possible to set a limit on the amount
    of memory which an application can allocate; this is done via
    "Install Application..."
10. It is now possible to run accessories from the Desktop. There
    is no longer a fixed limit on the number of accessories.
11. Arbitrary objects (e.g. text fragments) may be dragged onto the
    desktop from applications which support the new drag and drop
    protocol.
12. The Desktop now forces the mouse to be on, and in an arrow
    shape, whenever one of its windows is topped.
13. The Desktop now uses the XBIOS keyboard tables for doing
    control and alternate key detection.
14. When the user selects icons or text lines in desktop windows
    using the rubber band and the rubber band exceeds the window's
    work area, the window will start to scroll.


@endnode


@node "Changes to the AES"

Changes to TOS and related products: AES

1.  The ABOUT menu item can now be disabled. When the new
    hierarchical menu routines first came out, 'menu_ienable()'
    would not work on the ABOUT menu item.
2.  The ABOUT menu item text can now be changed. When the new
    hierarchical menu routines first came out, 'menu_text()' would
    not work on the ABOUT menu item.
3.  The bug with menu_attach() not removing or changing submenus
    has been fixed.
4.  The maximum height of a pop-up menu is now two characters less
    than the height of the screen.
5.  The problem of moving the mouse into the menu bar while a popup
    is displayed has been fixed.
6.  The memory used by the True Color icons are now allocated in
    one large block, instead of a Malloc() per icon. This change
    will increase the memory allocation efficiency under MultiTOS.
7.  @{"Drop-Down List menus" LINK "Drop-Down List Menus"} are now supported (AES versions >= 4.1).
    These menus are pop-up menus with up, down and slider buttons
    to the right of the menu. Please see the updated menu document
    about these and other menu manager OS functions.
8.  MultiTOS makes sure now that after a @{"menu_bar" LINK "menu_bar()"}(tree, 0) the menu
    stays disabled even after an application was swapped out and in.
9.  Popup menus are no longer blocked when the mouse enters the
    menu bar while a popup menu is displayed.
10. objc_edit: A FBOXTEXT object or BOXTEXT object with outlined
    flag set and right or left aligned text will now always draw
    the cursor properly. Right aligned text works correctly now.
11. The file selector parts (slider, arrows, etc.) now use the
    window part colors set by the window color CPX.
12. Changing default window colors by doing a
    wind_set(...,WF_DCOLOR,...) (as the window color CPX does) now
    causes all existing windows which use the default colors to
    change to the new colors also. If a part of a window does *not*
    have a default color set for it (e.g. if an application does an
    explicit wind_set(...,WF_COLOR,...) ) then it will not change
    when the default color is modified.
13. In video modes with 16 or more colors, the default window part
    colors are all solid. Of course this can be modified by the
    user.
14. Alert box icons are now in color.
15. Two new alert icons are now available: [4] is an "info" icon,
    and [5] is a "floppy disk" icon.
16. The appl_getinfo() system call has been extended to return a
    variety of additional information. See the detailed description
    of @{"appl_getinfo" LINK "appl_getinfo()"}() later in these notes.
17. All alert boxes have been arranged so that the "OK" or "Retry"
    button is on the left, and the "Cancel" button is on the right.
    (Some critical error alerts used to have these reversed.)
18. There are several new messages: WM_BOTTOM, WM_ICONIFY,
    WM_UNICONIFY, and WM_ALLICONIFY.
19. A new gadget (the "SMALLER") is provided to allow for
    iconification of windows and/or applications.
20. It is now possible to select an application from the Desk menu
    even if it is not responding to WM_TOPPED messages.
21. Color icons are now selected correctly in all resolutions.
22. All parts of alert boxes may be used to move the boxes now.
23. objc_find() has been modified to work the way it did in older
    versions of TOS (i.e. it no longer looks at the borders of
    objects).
24. Icon height and width in alert boxes is now calculated
    accurately (previously it was hard-coded to "4").
25. The resolution change code now handles failure gracefully (it
    used to get "stuck" and cause problems for future resolution
    changes).
26. Various aesthetic fixes have been applied to window parts.
27. Single-clicking on the move bar of a topped window now sends a
    WM_BOTTOMED message (33) to the application which owns the
    window. The application should normally respond to this message
    by doing a wind_set(WF_BOTTOM) call for the window.
28. Double clicking on a window's move bar now sends a WM_FULLED
    message for the window, if the window has a full box and is not
    iconified.
29. Under MultiTOS, the AES now redirects BIOS device 2 so that
    Bconin calls will actually get their data from the AES (like
    evnt_keybd).
30. The MultiTOS AES no longer busy waits for events.
31. The default height at which menus will begin to scroll has been
    set to two characters less than the height of the screen. The
    previous default was 16 menu items.
32. The Desk Accessory menu, when scrollable, will scroll starting
    from the first desk accessory. The DA menu will be scrollable
    when the height of the menu exceeds the maximum height.
    Previously, the DA menu would begin scrolling from the first
    application. This was changed when it was discovered that if
    there are an inordinate number of DAs and the scrolling height
    is reached, the scrolling routine would break.
33. The concept of a TOOLBAR is now supported (AES versions >=
    4.1). The Toolbar must be the width of the window and is
    positioned below the INFO line. For more information, please
    see the TOOLBAR document.
34. Submenus that are scrollable no longer need to have their
    parent be at the ROOT.
35. @{"Drop-down list menus" LINK "Drop-Down List Menus"} no longer need to have their parent be at
    the ROOT.
36. Submenus that are scrollable can be scrolled using the UP and
    DOWN arrow keys.
37. @{"Drop-down list" LINK "Drop-Down List Menus"} menus can be scrolled using the UP, DOWN,
    SHIFT-UP and SHIFT-DOWN arrow keys.


@endnode


@node "Changes to the VDI"

Changes to TOS and related products: VDI

1. Multi-plane fill patterns now work.
2. The mode where VDI seedfills the current color in true color is
   fixed.
3. Pixel-packed transform form no longer reverses the bit ordering
   of each pixel, which is compatible with existing video board
   screen drivers.
4. Minor code optimization. This included the removal of
   unnecessary loading of some Line-A variables. Therefore,
   applications that relied on Line-A variables being initialized
   after certain calls can no longer expect those variables to have
   accurate information. Of course, applications should not be
   using Line-A, as a general rule.


@endnode


@node "Changes to the Viewer"

Changes to TOS and related products: Viewer

1. The VIEWER program can now display characters using the upper
   byte. Previously, the VIEWER program was unable to display such
   characters (ie: umlauts etc.).
2. The VIEWER program now supports iconifying of its windows.


@endnode


@node "Changes to the XControl"

Changes to TOS and related products: XControl

1.  XCONTROL now uses malloc() instead of Malloc() thereby
    increasing memory allocation efficiency under MultiTOS.
2.  XCONTROL will now always dynamically allocate CPXs, except for
    resident CPXs.
3.  XCONTROL will now allocate enough CPX headers for 1-1/2 times
    the number of CPXs actually loaded. This means that if 10 CPXs
    were loaded at boot time, 5 more CPXs may be placed into the
    CPX directory and reloaded also, without having to reboot the
    system. Previously, XCONTROL allowed the user to set the
    minimum number of slots. (a.k.a. CPX headers). This has been
    removed.
4.  XCONTROL will now default to the 12 hour clock for the USA
    version only.
5.  XCONTROL now correctly uses wind_calc() to calculate its window
    size.
6.  XCONTROL no longer returns a pointer to a local GRECT for its
    custom GetFirstRect and GetNextRect calls.
7.  Because of these changes, XCONTROL is now up to version 1.31.
8.  SOUNDTT.CPX has been updated to utilize the 3D effects. This
    CPX is only for the TT and MegaSTE. It is not intended for the
    Falcon.
9.  OUTLINE now recognizes the keyword 'Fonts' as well as 'Font'.
10. OUTLINE now recognizes 'Atari Wingbats' fonts.
11. OUTLINE will no longer lockup if it can't parse the keyword.
12. OUTLINE now correctly uses wind_calc() to calculate its window
    size.
13. PRINTER now correctly uses wind_calc() to calculate it window
    size.


@endnode


@node "appl_find()"

Application library enhancements: appl_find()

3.4.4 APPL_FIND

Purpose:

     Finds the ap_id of another application in the system.

     An application must know the ap_id before it can establish
     communications with another application.

@{0B} --------------------- NEW FOR V4.0 ---------------------- @{0}

     a,  If the high word of ap_fpname is 0xFFFF, then the low word
         should contain the MiNT id of that application. The
         appl_find call will convert the MiNT id into the
         corresponding AES id.

     b,  If the high word of ap_fpname is 0xFFFE, then the low word
         should contain the AES id of that application. The
         appl_find call will convert the AES id into the
         corresponding MiNT id.

     c,  If ap_fpname is a zero pointer, the appl_find will return
         the AES id of the current process.

Parameters:

     control[0] = 13
     control[1] = 0
     control[2] = 1
     control[3] = 1
     control[4] = 0

     int_out[0] = ap_fid
     addr_in[0] = ap_fpname

     ap_fid = the ap_id of the application for which the  current
              application is searching.

     -1 - GEM AES could not find the application.

     ap_fpname  - address of a null-terminated string  containing
                  the filename of the application for which the
                  current application is searching.

     The string must be 8 characters long. If the filename has
     fewer than 8 characters, the programmer must fill out the
     rest of the string with blank spaces.

Sample call to C language binding:

     ap_fid = appl_find( ap_fpname );


@endnode


@node "appl_search()"

Application library enhancements: appl_search()

 3.4.9 APPL_SEARCH

 Purpose:

@{0B} --------------------- NEW FOR V4.0 ---------------------- @{0}

     Searches all the existing AES processes in the system.

 Parameters:
     control[0] = 18
     control[1] = 1
     control[2] = 3
     control[3] = 1
     control[4] = 0

     int_in[0]     = ap_smode
     addr_in[0]    = ap_sname
     int_out[0]    = ap_sreturn
     int_out[1]    = ap_stype
     int_out[2]    = ap_sid

     ap_smode - Search mode of the function
                0 = search first ( all the processes )
                1 = search next  ( all the processes )
                2 = search system shell ( only one )

     ap_sname - Buffer that will hold the name of the AES process
                the size must be 9 or more characters long

     ap_stype - Process's type

                1 = System process
                2 = Application
                4 = Accessory

       ap_sid - Process's AES id

   ap_sreturn - a coded return message

                0 - No more file
                1 - No error exists

Sample call to C language binding:

 ap_sreturn = appl_search(ap_smode, ap_sname, &ap_stype, &ap_sid);


@endnode


@node "appl_read()"

Application library enhancements: appl_read()

3.4.2 APPL_READ

Purpose:

     Reads a specified number of bytes from a message pipe.

     If there is no message in the pipe, AES will change the
     current application into WAIT state until the request is
     satisfied.

     It is strongly recommended to read 16 bytes at a time
     because of the way the AES works.

@{0B} --------------------- NEW FOR V4.0 ---------------------- @{0}

         If ap_rid equals -1, this function will do a read only
         if there is data in the message pipe. Otherwise, it will
         return immediately.

Parameters:

     control[0] = 11
     control[1] = 2
     control[2] = 1
     control[3] = 1
     control[4] = 0

     int_in[0]  = ap_rid
     int_in[1]  = ap_rlength
     int_out[0] = ap_rreturn
     addr_in[0] = ap_rpbuff

Description:

     ap_rid  -  the ap_id of the process whose message pipe the
                application is reading (usually its own)

     ap_rlength  - the number of bytes to read from the message
                   pipe

     ap_rreturn - a coded return message

       0 - an error exists
       n - (positive integer) - no error exists

     ap_rpbuff  - address of the buffer that will hold the bytes
                  the application is reading

Sample call to C language binding:

     ap_rreturn = appl_read ( ap_rid, ap_rlength, ap_rpbuff );


@endnode


@node "appl_init()"

Application library enhancements: appl_init()

3.4.1. APPL_INIT

   Purpose:

     Initalizes the application and establishes a number of
     internal GEM AES data structures prior to calls to other AES
     function calls.

@{0B} --------------------- NEW FOR V4.0 ---------------------- @{0}

     This must be the first call prior to all the other AES
     functions. Fail to do this will have unpredictable result!

     The best way to detect if the AES is present is first to set
     the global[0] to zero then check global[0] again after
     appl_init call. If global[0] is non zero then AES is present
     otherwise AES is not installed.

     Global[1] will return -1 to indicate current AES supports
     multitasking environment.

     The global[13] contains the current maximum character that is
     used by AES to do vst_height before writing text to the
     screen. Changed 9/29/92

     The global[14] contains the current maximum character that is
     used by AES to do vst_height before writing text to the
     screen. Changed 9/29/92

     Note:
     Some AES bindings have been hard-wired to always return a 1 in
     int_out[0] instead of the true AES application ID. Please
     check all bindings carefully.

   Parameters:

     control[0] = 10
     control[1] = 0
     control[2] = 1
     control[3] = 0
     control[4] = 0

     int_out[0] = ap_id

     ap_id - If appl_init was successful, ap_id is a zero or a
     positive number. GEM AES places this number in the Global
     Array, and the application uses it with future calls to AES
     routines.

     If APPL_INIT was not successful, the value of ap_id is -1.
     The application should make no further AES calls.

   Sample call to C language binding:

   ap_id = appl_init();


@endnode


@node "appl_getinfo()"

Application library enhancements: appl_getinfo()

3.4.10 APPL_GETINFO

Purpose:

@{0B} --------------------- NEW FOR V4.0 ---------------------- @{0}

This function is to allow application to get general information
about the AES and the system environment.

 Parameters:
     control[0] = 130
     control[1] = 1
     control[2] = 5
     control[3] = 0
     control[4] = 0

     int_in[0]     = ap_gtype
     int_out[0]    = ap_greturn
     int_out[1]    = ap_gout1
     int_out[2]    = ap_gout2
     int_out[3]    = ap_gout3
     int_out[4]    = ap_gout4

     ap_gtype - Get information type:

        0 - Get AES regular font information:
            ap_gout1 - font height
            ap_gout2 - font id
            ap_gout3 - font type:
                        0 - system font
                        1 - FSM font
                        2 and on to be defined in the future

        1 - Get AES small font information:
            ap_gout1 - font height
            ap_gout2 - font id
            ap_gout3 - font type:
                        0 - system font
                        1 - FSM font
                        2 and on to be defined in the future

        2 - Get AES current resolution number and the number of
            color is being supported by the object library.

            ap_gout1 - resolution number
            ap_gout2 - number of colors supported by AES object
                       library
            ap_gout3 - color icons:
                                0 - Not supported
                                1 - Supported
            ap_gout4 - new resource file format:
                                0 - Not supported
                                1 - Supported

        3 - Get AES language.

            ap_gout1 - currently used language:
                       0 - English
                       1 - German
                       2 - French
                       3 - reserved
                       4 - Spanish
                       5 - Italian
                       6 - Swedish (not implemented)

@{0B} --------------------- NEW FOR V4.1 ---------------------- @{0}

        4 - Get general AES environment info #1

            ap_gout1 - 0 - non-pre-emptive multitasking
                       1 - pre-emptive multitasking
            ap_gout2 - 0 - @{"appl_find" LINK "appl_find()"} cannot convert from MiNT to
                  AES ids
                       1 - extended appl_find modes supported
            ap_gout3 - 0 - @{"appl_search" LINK "appl_search()"} not implemented
                       1 - appl_search implemented
            ap_gout4 - 0 - @{"rsrc_rcfix" LINK "rsrc_rcfix()"} not implemented
                       1 - rsrc_rcfix implemented

        5 - General AES environment info #2

            ap_gout1 - 0 - objc_xfind not implemented
                       1 - objc_xfind implemented
            ap_gout2 - 0 - reserved, always 0
            ap_gout3 - 0 - GEM/3 menu_click not implemented
                       1 - menu_click implemented
            ap_gout4 - 0 - GEM/3 shel_r/wdef not implemented
                       1 - shel_r/wdef implemented

        6 - General AES environment info #2

            ap_gout1 - 0 - @{"appl_read" LINK "appl_read()"}(-1) not implemented
                       1 - appl_read(-1) implemented
            ap_gout2 - 0 - @{"shel_get" LINK "shel_get()"}(-1) not implemented
                       1 - shel_get(-1) implemented
            ap_gout3 - 0 - @{"menu_bar" LINK "menu_bar()"}(-1) not implemented
                       1 - menu_bar(-1) implemented
            ap_gout4 - 0 - menu_bar(MENU_INSTL) not implemented
                       1 - menu_bar(MENU_INSTL) implemented

        7 - Reserved for OS extensions. MultiTOS sets
            ap_gout1,2,3,4 to 0.

        8 - Mouse support

            ap_gout1 - 0 - @{"graf_mouse" LINK "graf_mouse()"} modes 258-260 not supported
                       1 - graf_mouse modes 258-260 supported
            ap_gout2 - 0 - application must maintain mouse form
                       1 - mouse form maintained by OS on a
                           per-application basis

        9 - Menu support

            ap_gout1 - 0 - submenus not supported
                       1 - MultiTOS style submenus
            ap_gout2 - 0 - popup menus not supported
                       1 - MultiTOS style popup menus
            ap_gout3 - 0 - scrollable menus not supported
                       1 - MultiTOS style scrollable menus
            ap_gout4 - 0 - extended MN_SELECTED not supported
                       1 - words 5/6/7 in MN_SELECTED message give
                           extra info

        10 - shel_write() info

             ap_gout1 - @{"shel_write" LINK "shel_write()"}() modes supported:
                        bit 0-7:  indicates highest legal value for
                                  (sh_wdoex & 0x00ff)
                        bit 8-15: indicates which bits in (sh_wdoex
                                  & 0xFF00) are supported as in
                                  MultiTOS
             ap_gout2 - 0 - shel_write(0) launches an application
                        1 - shel_write(0) cancels previous
                            shel_write()
             ap_gout3 - 0 - shel_write(1) launches an application
                            immediately
                        1 - @{"shel_write" LINK "shel_write()"}(1) takes effect after
                            current application exits (like TOS 1.4)
             ap_gout4 - 0 - ARGV parameter passing not possible
                        1 - sh_wiscr controls ARGV parameter passing

        11 - window support

             ap_gout1 - extended WF_ functions available in
                      wind_get/set (0=not available, 1=available)
                      bit 0: WF_TOP returns window below current one
                      bit 1: wind_get(WF_NEWDESK) supported
                      bit 2: WF_COLOR get/set supported
                      bit 3: WF_DCOLOR get/set supported
                      bit 4: WF_OWNER supported in wind_get
                      bit 5: WF_BEVENT get/set supported
                      bit 6: WF_BOTTOM supported
                      bit 7: WF_ICONIFY supported
                      bit 8: WF_UNICONIFY supported
                      bits 9-15 reserved, 0
             ap_gout2 - reserved, 0
             ap_gout3 - new gadgets supported:
                      (0=supported, 1=not supported)
                      bit 0: iconifier
                      bit 1: explicit "bottomer" gadget
                      bit 2: shift+click to send window to bottom
                      bit 3: "hot" close box
                      all other bits: reserved, 0
             ap_gout4 - 0 - wind_update check and set not allowed
                        1 - wind_update check and set allowed

        12 - messages sent to applications

             ap_gout1 - bit field of extra messages supported (1)
                      (0=no,1=yes)
                      bit 0: WM_NEWTOP message meaningful
                      bit 1: WM_UNTOPPED message sent
                      bit 2: WM_ONTOP message sent
                      bit 3: AP_TERM message sent
                      bit 4: MultiTOS shutdown and resolution change
                             messages supported
                      bit 5: AES sends CH_EXIT
                      bit 6: WM_BOTTOM message sent
                      bit 7: WM_ICONIFY message sent
                      bit 8: WM_UNICONIFY message sent
                      bit 9: WM_ALLICONIFY message sent
             ap_gout2 - bit field of extra messages supported (2)
                        (currently all bits are reserved and 0)
             ap_gout3 - message behaviour
                        bit 0: WM_ICONIFY message gives coordinates
                               (0=no,1=yes)

        13 - object information

             ap_gout1 - 0 - no 3D objects
                        1 - 3D objects supported via objc_flags
             ap_gout2 - 0 - @{"objc_sysvar" LINK "objc_sysvar()"} supported
                        1 - MultiTOS 1.01 objc_sysvar
                        2 - extended objc_sysvar
             ap_gout3 - 0 - only system font for TEDINFO structures
                        1 - SPEEDO and GDOS fonts allowed in TEDINFO
             ap_gout4 - reserved for OS extensions (MultiTOS always
                        sets this to 0)
                        suggestion: use this to indicate presence
                        of new object types like radio buttons

        14 - form library information

             ap_gout1 - 0 - no flying dialogs
                        1 - flying dialogs supported
             ap_gout2 - 0 - keyboard tables not supported
                        1 - Mag!X style keyboard tables
             ap_gout3 - 0 - last cursor position not returned
                        1 - last cursor position returned
             ap_gout4 - reserved, 0

   ap_greturn - a coded return message

                1 - No error
                0 - Error

Sample call to C language binding:

 ap_greturn = \
 appl_getinfo(ap_gtype, &ap_gout1, &ap_gout2, &ap_gout3, &ap_gout4);


@endnode


@node "Supplement for wind_update()"

Window library enhancements: wind_update()

11.3.8 WIND_UPDATE

@{0B} --------------------- NEW FOR V4.0 ---------------------- @{0}

        The new 'check and set mode' is defined as follows:

        If the wi_ubegend value is 257 (BEG_UPDATE|0x0100)or 259
        (BEG_MCTRL|0x0100), the AES will first check for
        current wind_update() ownership. If nobody owns it or the
        current owner is the caller itself then normal wind_update
        procedure will be performed. Otherwise, wind_update() will
        return an error (0) in wi_ureturn.

        See also Discussion of wind_update()


@endnode


@node "Discussion of wind_update()"

Window library enhancements: discussion of wind_update()

        Wind_update is a semaphore that lets applications request
        control of the screen. The application will either be
        granted access to the screen or be put on hold until the
        current owner of the screen semaphore releases its control.

        The purpose of wind_update is to let an application take
        control of the whole screen when it is writing data to the
        screen or its windows. This function is to ensure the
        application that after the wind_update(1) is successful,
        the status of the screen will remain the same until the
        wind_update(0) call. Other applications' window open,
        close, move, etc. calls will be suspended to prevent the
        state of the screen from changing while it is "locked."

        It is especially important to an application that the
        screen must not change when it is walking the rectangle
        list using wind_get(WF_FIRSTXYWH/WF_NEXTXYWH). It is
        recommended that you call wind_update ONLY when necessary
        for walking the rectangle list and making VDI calls to
        write to the screen. Because other processes calling
        wind_update will block until you let go, it is not a good
        idea to hold onto the screen semaphore longer than
        necessary in a multitasking environment. Traditionally,
        some programs have been written using a model like this:

        /* lock the screen during initialization */

                wind_update(TRUE);

                ...initialize...

                /* main loop */

                while (!done)
                {
                        /* unlock the screen, wait for events */
                        wind_update(FALSE);

                        evnt = evnt_multi(...);

                        /* lock the screen again and process events */
                        wind_update(TRUE);

                        if (evnt & MU_MESAG)
                        {
                                ...
                        }
                        if ...
                }

        This is not a good model for AES programming, because the
        screen is locked at all times, except when the program is
        blocked waiting for events in its evnt_multi() call. A more
        correct model for AES programming is to leave the
        wind_update() semaphore alone except at the very moment
        that you need it, which is during screen updates when you
        are walking the rectangle list.


@endnode


@node "graf_mouse()"

Graphic library enhancements: graf_mouse()

8.3.9 GRAF_MOUSE

Purpose:

        Changes the mouse to one of a predefined set or to an
        application defined form.

        The application should change the mouse back to ARROW after
        it finishes with its current action. Do not leave the mouse
        in any form other than ARROW.

@{0B} --------------------- NEW FOR V4.0 ---------------------- @{0}

        Currently, applications have free access to the graf_mouse
        function to change the mouse form without any restriction.
        However, in the new multiprogramming environment in which a
        lot of applications may present in the system at the same
        time will pose a big problem. Rules will be implemented so
        that AES can take control of the mouse form and decide
        which application can change the mouse form and which one
        can't.

        During a normal circumstance, a mouse should always stays
        in ARROW form. In this case, the mouse form ownership is
        free and any application can change it at its will. Once
        the mouse form is being changed to something other than
        the ARROW, ownership is transfered to that application
        until it changes the mouse back to ARROW. So, as a courtesy
        to other applications, the current owner should change the
        mouse back to ARROW as soon as it finishes with its work.

        However, in some circumstances, an application may want to
        change mouse form immediately without any delay. For
        example, the foreground application changes the mouse to a
        busy bee and user clicks on the background to do a drag
        operation on a different application. It is very logical
        that the mouse should be changed to a flat hand for the
        dragging. In this case, AES provides a way to force the
        current mouse to the next owner in order to deal with this
        type of situation. Please read the gr_monumber section
        below.

Parameters:

        control[0] = 78
        control[1] = 1
        control[2] = 1
        control[3] = 1
        control[4] = 0

         int_in[0] = gr_monumber
        int_out[0] = gr_moreturn
        addr_in[0] = gr_mofaddr

        gr_monumber - a code identifying a predefined form

          0 - arrow
          1 - text cursor
          2 - busy bee
          3 - hand with pointing finger
          4 - flat hand, extended fingers
          5 - thin cross hair
          6 - thich cross hair
          7 - outline cross hair
        255 - mouse form stored in gr_mofaddr
        256 - hide mouse form
        257 - show mouse form

@{0B} --------------------- NEW FOR V4.0 ---------------------- @{0}

        258 - save current mouse form
        259 - restore to the last saved mouse form
        260 - restore to previous mouse form

        In the event that the application must change the mouse
        form, set the highest bit ( Bit 15 ) of gr_monumber to 1
        and OR in with the desired mouse form number. After
        finishing the work, call the graf_mouse with value 0 to set
        the mouse back to arrow. It is suggested that the
        application to make this call in the following way:

            wind_update(1)
                graf_mouse(0x8000|gr_monumber, 0);
                actions()
                graf_mouse(0, 0);
            wind_update(0)

        gr_moreturn - a coded return message

        0 - an error exits
        n ( positive integer ) - no error exists.

        gr_mofaddr - the address of a 35-word buffer that fits the
                     mouse form definition block specified in the
                     GEM programmer's guide

        ----------------------------------------------------------

Sample call to C language binding:

  gr_moreturn = graf_mouse( gr_monumber, gr_mofaddr );


@endnode


@node "shel_get()"

Shell library enhancements: shel_get()

13.3.5 SHEL_GET

Purpose:

  Lets an application read data from the AES's internal shell buffer.

  The length of the buffer should not be more than 1024 bytes.

@{0B} --------------------- NEW FOR V4.0 ---------------------- @{0}

     sh_greturn - returns the size of the data. The data can be
     longer than 1024 bytes. The application's buffer will not be
     filled with more than sh_glen bytes, even if there is more
     data in AES's internal buffer.

     5/5/92
     If sh_glen is -1, it is the inquiry mode.

Parameters:

  control(0) = 122
  control(1) = 1
  control(2) = 1
  control(3) = 1
  control(4) = 0

  int_in(0)  = sh_glen

  addr_in(0) = sh_gbuff

  int_out(0) = sh_greturn

Description:

  sh_greturn - a coded return message

  0 - an error exists
  n ( positive integer ) - no error exists

  sh_glen - the length of the buffer.

            If the value is -1, it is the inquiry mode in which
            sh_greturn will return the size of the current shel_get
            buffer.

  sh_gbuff - the address of the buffer.

Sample call to C language binding:

  sh_greturn = shel_get( sh_gbuff, sh_glen );


@endnode


@node "shel_put()"

Shell library enhancements: shel_put()

13.3.6 SHEL_PUT

Purpose:

  Lets the application save data into the AES's shell internal
  buffer.

Note:
  Currently, the AES desktop is using this buffer to store  the
  desktop.inf data. Any usage of this buffer may corrupt the
  data that are already stored in there.

  The length of the data that goes into the buffer should not be
  more than 1024 bytes.

@{0B} --------------------- NEW FOR V4.0 ---------------------- @{0}

     The AES will allocate memory to store the data if the
     current buffer size is smaller than the sh_plen size. The
     default buffer size is 1024 bytes and the maximum size
     must be be less than 32K bytes.

Parameters:

  control(0) = 123
  control(1) = 1
  control(2) = 1
  control(3) = 1
  control(4) = 0

  int_in(0)  = sh_plen

  addr_in(0) = sh_pbuff

  int_out(0) = sh_preturn

  sh_preturn - a coded return message

  0 - an error exists
  n ( positive integer ) - no error exists

  sh_plen - the length of the buffer.

  sh_pbuff - the address of the buffer.

Sample call to C language binding:

  sh_preturn = shel_put( sh_pbuff, sh_plen );


@endnode


@node "run application"

shel_write() enhancements: exec modes

-> Sh_wodex:   0 - Launch program. The actual sh_wisgr value will be
                   determined by the AES.
               1 - Launch an application
               3 - Launch an accessory.

   (value 2 is reserved)

Default directory will be set according to the file's full path
except for the extended mode if bit 10 is set.

AES will create a process of that application and will not wait
for it to terminate (i.e. the process is started concurrently).

sh_wreturn will return the process's AES id. If it is 0, an
error exists.

If sh_wodex is 0, the AES will determine the actual launching mode by
looking at the file's extension.  What file extensions are considered
for launching is determined by the AES environment variables GEMEXT,
TOSEXT, and ACCEXT.

Sh_wisgr: This parameter is only valid when Sh_wodex is 1

          1 for GEM application
          0 for TOS application

The launching a non-gem (TOS) type application by @{"shel_write" LINK "shel_write()"} is
implemented in the following way:

The AES will look into the environment for a variable named TOSRUN. It
should contain a full path of a tos handler program to which the AES
will pass the current (TOS) program name into the command tail. If
there is an error, of launching this tos handler program, AES will
return immediately. If TOSRUN does not exist, the AES will use the
default way (MW.PRG's message pipe method) to launch that program.

For example:

Launch a program named C:\E.TOS and the current
TOSRUN=C:\BIN\TOSHAND.PRG

The following action will take place:

The TOSHAND.PRG will be launched, the command tail will be preserved.
However, an ARGV= will be created in the environment in the following
way.

    ARGV=\0
    C:\E.TOS\0
    file1\0 ( If there is any )
    file2\0 ( If there is any )
    \0

    Note:

    The TOSHAND.PRG will be launched as a GEM program regardless of its
    real type. The PATH will not be used to search the program so that
    TOSHAND.PRG can use TOSRUN to locate where it is.

Sh_wiscr: Request AES for setting up ARGV style parameter passing in
          the environment string

       0 - No
       1 - Yes

This feature is intended for application which passes one or more
arguments in the command tail.

The AES will extract arguments from the command tail (seperated
by spaces) and construct an ARGV element (as the last element) in
the environment in the following fashion:

       ARGV=\0
       Progam name\0
       Argument1\0
       Argument2\0
       Argument3\0
       \0

A value of 0x7f will be put into the first byte of original command
tail to indicate a valid ARGV presents in the environment, application
should ignore the content in the command tail (5/22/92).

See The Atari Extended Argument Specification (ARGV), a separate
document.


@endnode


@node "extended mode"

shel_write() enhancements: extended mode

The @{"shel_write" LINK "shel_write()"} call also allows the user to launch the program or
accessory in a customized way. The high byte (bit 15 to bit 8) of
sh_wodex is checked to see if any of the bits is set. If so, it is
an extended call. Each bit is assigned to have a special meaning,
the low byte meaning is not affected.

                                SH_WODEX

                        High Byte      |    Low Byte
     Bit Number: 15 14 13 12 11 10 9 8 | 7 6 5 4 3 2 1 0
                ----------------------------------------
                                            No Change
      8 -> Psetlimit value
      9 -> Prenice value
     10 -> Default directory string
     11 -> Environment string
     12 -> Reserved
     13 -> Reserved
     14 -> Reserved
     15 -> Reserved

In extended mode, sh_wpcmd will be treated as a pointer pointing
to a set of long (32 bit) values. Each value after the first
corresponds to one of the bits in sh_wodex: if that bit is set then
the corresponding LONG value is used, otherwise it is ignored. The
values and their associated bit numbers are as follows:

 a, LONG[0] Pointer to the program name string
        (must be the first element)
 b, LONG[1] Psetlimit value.                    (bit 8)
 c, LONG[2] Prenice value.                      (bit 9)
 d, LONG[3] Default directory string pointer    (bit 10)

 The directory path (LONG[3]) should look something like:

 C:\ or C:\FOLDER or C:\FOLDER1\FOLDER2 ...

 However, if the pointer is zero, then the default directory
 will be the directory that the program itself was found in.

 e, LONG[4] Application defined environment string pointer (bit 11)


@endnode


@node "path searching"

shel_write() enhancements: path searching

PATH SEARCHING

When using sh_wodex mode 0, 1, and 3, the program name string
(LONG[0]) may contain full path and file name specifying the file to
launch, or it may contain simply the name of the program. In that
case, AES will search each directory in the PATH variable in AES'
environment for a file with that name and a legal program
extension, as specified in the TOSEXT, GEMEXT, and ACCEXT
environment variables.

In mode 0 and mode 3, ACCPATH variable will be searched also.
(4/30/92)

If the program is found using one of the GEMEXT extensions, it is
launched as a GEM application. If it is found using one of the
TOSEXT extensions, it is launched like TOS programs are (see
elsewhere). If it is found using one of the ACCEXT extentions, it
is loaded as a desk accessory.

If the program name string includes an extension, that extension is
checked against those in GEMEXT, TOSEXT, and ACCEXT to determine how
to launch the program. If the extension is not found in any of
those environment variables, an error is returned.

If the supplied program name includes any directory separators
(backslashes) or drive specifiers (a letter and a colon) then the
path and extension searching will not be done. If there are no
drive or directory specifiers but there is an extension (a dot),
then the path searching is done but the extension searching is not.
This is illustrated in the following table:

PATH NAME                   PATH SEARCH     EXT SEARCH
-------------               -----------     ----------
C:\BIN\MW.PRG                   No              No
C:\BIN\MW                       No              Yes     4/27/92
C:\BIN\MW.                      No              No
\MW.PRG                         No              No
MW.PRG                          Yes             No
MW.                             Yes             No
MW                              Yes             Yes

sh_wodex mode 1 explicitly calls for the program to be launched as a
GEM application or a TOS application (based on sh_wisgr). Mode 3
explicitly calls for the file to be loaded as an accessory. Mode 0
causes AES to decide, based on the extension.


@endnode


@node "shel_write()"

Shell library enhancements: shel_write()

13.3.2  SHEL_WRITE                                   Update 5/7/92

Purpose:

     Tells GEM AES whether to run another application and, if so,
     which application to run.

@{0B} --------------------- NEW FOR V4.0 ---------------------- @{0}

     Shel_write is expanded to have multiple functionalities. Please
     study the following documentation carefully.

Parameters:
     control(0) = 121
     control(1) = 3
     control(2) = 1
     control(3) = 2
     control(4) = 0

     int_in(0)  = sh_wdoex
     int_in(1)  = sh_wisgr
     int_in(2)  = sh_wiscr

     int_out(0) = sh_wreturn

     addr_in(0) = sh_wpcmd
     addr_in(1) = sh_wptail

Description:

     sh_wdoex - a coded instruction to exit the system or run
                another application when the user exits the
                current application.

     0 - run application
     1 - @{"run another application in GEM or TOS mode" LINK "run application"}
     3 - @{"run an accessory" LINK "run application"}
     4 - set shutdown mode
     5 - resolution change
     7 - send message to all processes
     8 - manipulate AES environment
     9 - inform the AES about new messages
     10 - @{"send the AES a message" LINK "send the AES a message"}

     More special features:

     a) extended mode
     b) path searching

     sh_wisgr - function depneds on the sh_wdoex value.

     sh_wiscr - function depends on the sh_wdoex value.

     sh_wreturn - return value depends on the sh_wdoex function.

     sh_wpcmd - the address of the new command file to execute

     sh_wptail - the address of the command tail for the next
                 program

        The first byte is the length of the command tail, the
        actual command tail should start from the second byte
        position in the buffer and should be NULL terminated.

        ( 11/03/92 )
        In V4.0, however, if the first byte has a value of 0xFF,
        the length of the buffer will be determined by AES by
        looking forthe NULL character. In theory, application can
        pass more than 128or 256 bytes to AES to create a long ARGV
        enviornment by settingsh_wiscr to one.

Sample call to C language binding:

     sh_wreturn = shel_write( sh_wdoex, sh_wisgr, sh_wiscr,
                              sh_wpcmd, sh_wptail );


@endnode


@node "set shutdown mode"

shel_write() enhancements

  -> Sh_wodex value 4

     Set the system in shutdown or normal mode depends on sh_wiscr
     value.

     Once the AES is in the shutdown mode, the @{"shel_write" LINK "shel_write()"} launch file
     capability mode 0-2 will be turned off.

     sh_wisgr 2 - Complete shutdown mode

              AES will check for all applications and accessories
              excluding the caller to make sure they all recognize
              AP_TERM message. If succeeded, AES will then send out
              AP_TERM to applications and AC_CLOSE to accessories.
              Accessories also get AP_TERM after the AC_CLOSE message.

              Note: the caller will receive none of the messages.

     sh_wisgr 1 - Partial shutdowm mode

              AES will check for all applications excluding the
              caller to make sure they all recognize AP_TERM
              message. If succeeded, AES will then send out AP_TERM
              to applications and AC_CLOSE to accessories. Note:
              the caller will receive none of the messages.

     sh_wisgr 0 - Abort the shutdown sequence.

              Note: Only the original caller of shutdown mode can
              abort the shutdown sequence.

@{0B}Please see @{"shel_write" LINK "shel_write()"} mode 9 of how an application informs AES
@{0B}    that it can recognize the AP_TERM message.@{0}


@endnode


@node "resolution change"

shel_write() enhancements

-> Sh_wodex value 5   (Changed 9/29/92)

Request the AES to change resolution. The sh_wiscr's value affects
the meaning of sh_wisgr. If AES accepts the resolution change
request, then it will put the system in SHUT DOWN mode. An
application can either shut down and exit or deny to shut down by
sending a AP_TFAIL message to the AES.

a, If sh_wiscr is zero, then sh_wisgr is the physical device id to
   perform VDI's open physical workstation call. To get the current
   physical device id, do the Getres()+2.

   The following are the existing physical device id values:

   2 -> 320x200        ST Low
   3 -> 640x200        ST Medium
   4 -> 640x400        ST High
   6 -> 640x480        TT Medium
   8 -> 1280x960       TT High
   9 -> 320x480        TT Low

b, If sh_wiscr is one, then sh_wisgr is the video mode word for use
   in the FALCON030 machine. Sh_wiscr value from 2 and up are
   reserved for future use.


@endnode


@node "send message to all processes"

shel_write() enhancements

-> Sh_wodex value 7

Sends a message (broadcast) to all processes except AES, SCREEN and
the sender. In this mode, the sh_wpcmd will be treated as a pointer
pointing to a 16 byte message buffer. Sh_wisgr and sh_wiscr are
ignored.


@endnode


@node "manipulate AES environment"

shel_write() enhancements

-> Sh_wodex value 8

This @{"shel_write" LINK "shel_write()"} mode allows applications to manipulate AES
environment variables.

  1, sh_wisgr = 0    Inquire the environment buffer size

     Sh_wreturn returns the size in bytes

  2,  sh_wisgr = 1   Add/Remove string

     In this mode to add or remove an AES environment name.

     The sh_wpcmd is the new environment string.

     a, To add a new environment string, the input should look like
        'NEW=STRING\0'

     b, To remove an environment string, the input should look like
        'NEW=\0'

     3, sh_wisgr = 2    Copy the environment buffer

        The sh_wpcmd is the output buffer in which the AES will copy
        the current environment buffer to.

        The output buffer size is specified by sh_wiscr.

        Sh_wreturn returns the number of bytes not copied.


@endnode


@node "inform the AES about new messages"
@next "rsrc_rcfix()"

shel_write() enhancements

-> Sh_wodex value 9

Inform the AES of what kind of new message that the application
can recognize.

Sh_wisgr is the input parameter in which each of the 16 bits
represents a message type.

Bit 0 - AP_TERM
Bit 1-15 Not defined at this moment.


@endnode


@pnode "send the AES a message"

-> Sh_wodex value 10

Send the AES a message.

Sh_wpcmd is the 16 byte message buffer

@endnode


@node "rsrc_rcfix()"
@prev "inform the AES about new messages"

Resource library enhancements: rsrc_rcfix()

12.3.6    RSRC_RCFIX

Purpose:

@{0B} --------------------- NEW FOR V4.0 ---------------------- @{0}

     Fixes up a raw resource data that is already loaded into the
     memory by the application.

     - It converts all the object's locations and sizes into pixel
       coordinates.
     - The resource must be the same as those generated by the
       resource construction set.
     - If there is another resource already loaded into the system
       for the application, the application is required to do a
       rsrc_free() to free up the memory before calling this
       function.
     - Application still needs to do rsrc_free() before terminate.

Parameters:
        control[0] = 115
        control[1] = 0
        control[2] = 1
        control[3] = 1
        control[4] = 0

     int_out[0] = rc_return
     addr_in[0] = rc_header

     rc_return = Return value, always equals to 1
     rc_header = Resource header memory location. It must be
                 followed by resource data.

Sample call to C language binding:

     rc_return = rsrc_rcfix( rc_header );


@endnode


@node "Extended RSC file format"

Resource library enhancements: extended RSC file format

The following is a description of the modifications to a GEM
Application Resource File to include color icons. The modifications
are minor changes to the existing resource file header as well as
the resource file itself. A new array of pointers for extensions to
the resource file will be attached to the old file format, which
will be followed by extension data. For color icons, the extension
data consists of a table and color icondata.

The original specification of the Application Resource File
consisted of a header which was followed by the structures
described by the header. The first word of the header, rsh_vrsn,
was always zero, but the new version of the header will now contain
a value that has the third bit on (e.g. 0x0004).

The array is an extension array. Each long in the extension array
is a specifically defined slot that contains information about
extensions to the resource file. The first slot must contain the
size of the actual file. The second slot is defined as the offset
to color icon data structures. Other slots will be defined at a
future date. If a slot contains a 0L, then that is the end of the
array, and if a slot contains a -1L, then that slot's extension is
not used. Hence, if a resource file contained color icons and no
other extensions, the array would contain the file size in the
first long, an offset in the second long, and a 0L in the third.
Note that since the array contains long offsets, the resource file
can now be larger than 64K. In addition, the array must start on a
word boundary.

The offset found in the color icon slot will point to space
reserved for a table of pointers. The table should have as many
entries as there are CICONBLK's plus one. However, all the pointers
should be initialized to 0L, except for the last entry which should
have a -1L. After the last entry, the color icon data should
follow. In general,the data should consist of one after another,
preserving the structures within the resource file except for some
pointer modifications (see below).

Within the actual Resource File, objects can now be of G_CICON
type. Given anob_type of G_CICON, the ob_spec will contain a
zero-based value of which color iconto use. In other words, if an
ob_spec contains a zero, the object will point to thefirst color
icon. This scheme is similar to the monochrome icon format.

In summary, an Application Resource File that has color icons
should consist of two sections:

The first section should be a resource file as defined by prior
AES documentation, except that objects can be of G_CICON type and
that the first word is now an offset to the second section.

The first section is immediately followed by the second which
consists of space for an extension array, a table of pointers to
color icons, and the color icon structures themselves. The
following is a description of how the resource file, the table, and
the color icon structures should look in the file (Note: Unless
specified, all pointers may contain dummy values, and all offsets
are relative to the beginning of the file.):

Resource File Header
{
    WORD rsh_vrsn             /* should have bit 2 on */
    WORD rest_of_header[17]   /* the rest of the resource file
                               * header, unchanged */
}
Resource File
{
/* standard format, except objects may be of ob_type G_CICON
   (see above) */
}
Table of Extensions
{
    LONG filesize   /* size of the file */
    LONG color_ic   /* slot for color icons, containing an offset
                     * to Table CICONBLK's */
    LONG dummy[?]   /* more extension slots, to be defined */
    LONG end_extensions    /* always 0L */
}
Table of CICONBLK's with (number of CICONBLK's) entries
{
   0L
   0L
   ... (last entry of color icons)
   -1L (end of table marker, this entry will never be converted to
        actual memory pointer)
}
for ( number of CICONBLK's )
{
   ICONBLK - (monochrome icon, same as the AES definition)
   {
       LONG    - monochrome mask pointer
       LONG    - monochrome data pointer
       LONG    - text, 0L if no text
       WORD[5] - color info, character, placement vectors
       WORD    - width in pixels
       WORD    - height in pixels
       WORD[4] - dimension and placement of text box
   }

   LONG  -  number of CICON's of different resolutions

   WORD[n] - monochrome bitmap data, where n = # of words in mono
             icon
   WORD[n] - monochrome mask data, where n = # of words in mono
             icon
   BYTE[12] - text string (max of 12 characters)

   for (number of different resolution CICON's)
   {
       WORD - number of planes
       LONG - color data pointer
       LONG - color mask pointer
       LONG - select data pointer, if 0L then no extra data or mask
              follows
       LONG - select mask pointer
       LONG - next_res, 1L indicates more icons to follow

       WORD[n]  - color data, where n = (# of words in mono icon) *
                  num_planesWORD[n]  - mask data, where n = # of
                  words in mono icon
       if (select data pointer )
       {
           WORD[n] - select data, where n = (# of words in mono
                     icon) * num_planes
           WORD[n] - select mask, where n = # of words in mono
                     icon
       }
    }         /* end different resolutions */
}    /* end number of CICONBLK's */

Rsh_vrsn
The first word in the resource file header, rsh_vrsn, no longer
contains the offset to the table of extensions. The third bit must
be set to 1 (i.e. 0100).

Table of Extensions
Please note, the table of extensions must begin on a word boundary.

Reuse of Icons
If no appropriate color icon exists for the current video mode, AES
will now take four-plane icons and reuse the data in eight-plane
and true color mode. In addition, eight-plane icon data will be
converted to true-color mode. Therefore, a deskicon.rsc containing
only four-plane icons is sufficient for all modes above four planes.

Color Icon Table
The color icon table is now has a -1 terminator, so that it is
initialized with 0L forall icon slots along with the extra -1L as a
terminator.


@endnode


@node "Window library toolbar support"

Window Library Enhancements - Toolbar Support

11.1  Introduction

This section describes the additional features of the Window
Library. All enhancements are backwards compatible with previous
versions of the AES, so existing applications will continue
to work. The new feature will work on all machines with an AES
version greater than 4.1.

The enhancements to the Window Library are:

o Toolbar support has been added to the AES.
o wind_set() may be used to attach, change or remove a Toolbar from
  a window.
o wind_get() may be used to see which Toolbar, if any, is attached
  to a window. In addition, wind_get() may be used to get the the
  Toolbar rectangle list for custom redraws.
o Mouse clicks on objects within the Toolbar generate Message
  Events.
o GEM AES will handle the Toolbar when a window needs to be moved,
  sized or redrawn.

11.2.1 Toolbar Introduction

A Toolbar is an OBJECT tree that is located below the INFO line of
a window but above the work area. Toolbars are a convenient way for
applications to display button and status information.


@endnode


@node "Division of labor"

Window Library Enhancements - Toolbar Support

11.2.2  Division of Labor

GEM AES and the application divide responsibility for proper
TOOLBAR management. GEM AES's responsibilities include the
following:

o Updating the x and y position of the Toolbar when the window is
  moved, sized and/or fulled.
o Ensuring that the  window is configured to the size required for
  the window parts and Toolbar.
o Setting the width of the Toolbar (ROOT) to be the width of the
  window.
o Redrawing the Toolbar when a WM_REDRAW message is received.
o Sending a Message Event to the application whenever the user
  clicks on a TOUCHEXIT object within the Toolbar. The state of the
  SHIFT, ALT and CTRL keys and the number of button clicks that
  occurred are also sent.

The application is responsible for the following:

o Building an object tree with any buttons designated as TOUCHEXITs.
o If the Toolbar contains any child objects that are meant to be
  the width of the window, the application is responsible for
  changing the ob_width of that object. The width would normally
  have to be changed whenever the application receives a FULLER
  and/or a SIZER message.
o Handling user-defined objects within the Toolbar.
o Redrawing any objects that changes their visual appearance. The
  application must take care that the redraw is properly clipped to
  the window. This is done by walking the rectangle list of the
  Toolbar and redrawing accordingly.
o Screen resolution differences are up to the application to
  resolve. For example, the height of an icon in ST Medium is
  different than in TT Medium.
o The colors used by the Toolbar are the responsibility of the
  application.


@endnode


@node "Window management calls"

Window Library Enhancements - Toolbar Support

11.2.3  Window Management Calls

An application will use the calls below to manage the Toolbar.

o To attach a Toolbar to a window, the application should call
  wind_set(wid, WF_TOOLBAR, ... ); with the address of the Toolbar.
  If the call is made while the window is open, the window will
  adjust itself to take into account the height of the Toolbar.

o To change the Toolbar from one Toolbar to another, the
  application should call wind_set( wid, WF_TOOLBAR, ... ); with
  the address of the new Toolbar. If the call is made while the
  window is open, the window will adjust itself to take into
  account the height of the new Toolbar.

o To remove the Toolbar from the window, the application need only
  call wind_set( wid, WF_TOOLBAR, ... ); with NULL parameters. If
  the call is made while the window is open, the window will adjust
  itself to take into account the lack of a Toolbar.

o Closing a window with wind_close() does not remove the Toolbar
  from the window. In this way, the application may reopen the
  window with the Toolbar still present.

o Deleting a window with wind_delete() will remove any attached
  Toolbar.

o To receive mouse clicks on Toolbar objects, all button objects
  should be set to TOUCHEXIT. When the user clicks on a TOUCHEXIT,
  GEM AES generates a Message Event. The message WM_TOOLBAR has a
  maximum length of 16 bytes and is defined as:

   o word 0  -       WM_TOOLBAR
   o word 1  -       ap_id of the application that sent the message.
   o word 2  -       0
   o word 3  -       the handle of the window
   o word 4  -       the object click on
   o word 5  -       the number of clicks
   o word 6  -       the state of the SHIFT, ALT and CTRL keys
   o word 7  -       0


@endnode


@node "Support for overlapping windows"

Window Library Enhancements - Toolbar Support

11.2.4  Support of Overlapping Windows

GEM AES can handle the redraws for the Toolbar when windows
overlap. However, a window with a Toolbar will not generate any
Message Events unless it is the TOP window.


@endnode


@node "Redrawing and updating"

Window Library Enhancements - Toolbar Support

11.2.5  Redrawing and Updating

To redraw the Toolbar, the application should walk the rectangle
list. The current way to get the rectangle list is to call
wind_get() with WF_FIRSTXYWH and WF_NEXTXYWH. However, these
parameters will only return the rectangles for the work area of the
window. Therefore, in order to get the rectangle list for the
Toolbar area, the application should call wind_get() with
WF_FTOOLBAR and WF_NTOOLBAR, which will return the first Toolbar
rectangle and the next Toolbar rectangle respectively.

The application will need to redraw the Toolbar for the following:

o If the Toolbar contains a user-defined object, the redraw must be
  done by the support code for that object. Since the window will
  not necessarily be the top window, redrawing via the rectangle
  list is crucial.

o If the application changes the state of an object within the
  Toolbar, the object will need to be redrawn. For example, the
  application changes the ob_state of a button to SELECTED. The
  dirty area will consist of the object's rectangle plus the
  effects of any 3D, Shadowing, outline etc.. Again, since the
  window will not necessarily be the top window, redrawing via the
  rectangle list is crucial.

The application may have to update the Toolbar for the following:

o If the Toolbar contains an object that is meant to be the width
  of the window AND is not the ROOT object, the application will
  need to set the width of the object in response to several
  Message Events. These messages include FULLER and SIZER events.
  Simply set the width of the object before calling wind_set( wid,
  WF_CURRXYWH, ... ); to set the new current size of the window.

o If the window is iconified, the application need not handle the
  Toolbar until the window is no longer iconified.

o If the window is sized and/or fulled such that the width of the
  window is smaller than the Toolbar, the Toolbar will merely be
  clipped. Buttons that are clipped are obviously not accessible.
  In these situations, the application may elect to change the
  height of the Toolbar and reposition the buttons at its
  discretion. When the applications calls wind_set( wid,
  WF_CURRXYWH, ... ) to set the new current size of the window, GEM
  AES will rebuild the window based upon the new height of the
  Toolbar.

o If the application wishes to merely switch one Toolbar with
  another, the application should call wind_set( wid, WF_TOOLBAR,
  ... ) with the new OBJECT tree.

o In the same instance, if the application wishes to remove the
  Toolbar, the application should call wind_set( wid, WF_TOOLBAR,
  ... ) with NULL parameters.


@endnode


@node "Window library routines"

Window Library Enhancements - Toolbar Support

11.3  Window Library Routines - Toolbar Support Addendum

The Toolbar code affect the following routines. For more
information about these and other routines, please see the GEM AES
documentation.

11.3.5  WIND_GET() - Gets information on a particular window

        #include        <aes.h>

        result=wind_get( handle, field, x,y,w,h );

        WORD    result  error result
        WORD    handle; window handle
        WORD    field;  information wanted
        WORD    *x;     value depends upon information requested
        WORD    *y;     value depends upon information requested
        WORD    *w;     value depends upon information requested
        WORD    *h;     value depends upon information requested

The Toolbar field values are:

        WF_TOOLBAR      -       30
             - x and y give the address of the Toolbar object tree.
             - x is the high word of the address
             - y is the low word of the address

        WF_FTOOLBAR     -       31
             - the coordinates of the first rectangle in the
               Toolbar's rectangle list.
             - x ( X - coordinate )
             - y ( Y - coordinate )
             - w ( width )
             - h ( height )

        WF_NTOOLBAR     -       32
             - the coordinates of the next rectangle in the
               Toolbar's rectangle list.
             - x ( X - coordinate )
             - y ( Y - coordinate )
             - w ( width )
             - h ( height )

11.3.6  WIND_SET() - Sets new values for the fields that determine
                     how a window is displayed.

        #include        <aes.h>

        result=wind_set( handle, field, x,y,w,h );

        WORD    result  error result
        WORD    handle; window handle
        WORD    field;  information to set
        WORD    x;      value depends upon field
        WORD    y;      value depends upon field
        WORD    w;      value depends upon field
        WORD    h;      value depends upon field

The Toolbar field values are:

        WF_TOOLBAR      -       30
             - Used to attach, change or remove a Toolbar. To
               remove a Toolbar, set (x,y) to NULL.
             - x is the high word of the address
             - y is the low word of the address

11.3.9  WIND_CALC() - Calculates the X- and Y-coordinates and the
                      width and height of a window's work area or
                      border area.

This routine calculates the X and Y coordinates and the width and
height of a window's work area or border area. wind_calc() does
this by adding up the widths and heights of the window parts passed
in via 'kind'. Since no window handle is involved, wind_calc()
cannot calculate the work area or border area of a window that has
an attached Toolbar.

However, it is possible to adjust the values returned since the
application knows about the height of the Toolbar. The height of
the Toolbar should include the area occupied by any 3D effects,
shadowing, border thickness etc.

To compensate for the Toolbar, simply increase the height of the
border area by the height of the Toolbar. In addition, since the
work area is below the Toolbar, increase the y - coordinate of
the work area by the same amount. The height of the work area
remains the same.


@endnode


@node "Defines"

Window Library Enhancements - Toolbar Support

11.4 DEFINES

Please be sure to include these defines in your AES.H include file
for your compiler.

# define WF_TOOLBAR      30      Toolbar parameter for wind_get/set
# define WF_FTOOLBAR     31      Get the First Toolbar rectangle
# define WF_NTOOLBAR     32      Get the Next Toolbar rectangle
# define WM_TOOLBAR      37      Toolbar Button Event Message


@endnode


@node "Event library toolbar support"

Event Library Enhancements - Toolbar Support

4.2.5.1 Predefined GEM AES Messages

The Toolbar adds a new Message Event to the existing list of AES
Messages. For additional information on the Event Library, please
see the AES Documentation.

GEM AES provides several predefined message types. Each type has a
maximum length of 16 bytes. All the predefined message types define
the first three words in the same way:

o WORD 0 - A number identifying the message type.
o WORD 1 - The ap_id of the application that sent the message.
o WORD 2 - The length of the message, not counting the predefined
           16 bytes.

4.2.5.14        WM_TOOLBAR

GEM AES uses this message to tell the application which Toolbar
object the mouse clicked on. The object must be a TOUCHEXIT and not
disabled. In addition, the window must be the TOP window.

    o WORD    0       37
    o WORD    3       the handle of the application's window
    o WORD    4       the Toolbar object clicked on
    o WORD    5       the number of mouse button clicks
    o WORD    6       the state of the SHIFT, ALT and CTRL keys


@endnode


@node "Menu library enhancements"

Menu Library Enhancements

5.1 Introduction

This section describes the additional features of the Menu Library.
All enhancements are backwards compatible with previous versions of
the AES, so existing applications will continue to work. The new
features will work on all machines with an AES version number of
3.3 and up.

The enhancements to the Menu Library are:

o   Hierarchical menus are now supported.
o   Pop-Up Menus are now supported.
o   Scrolling menus are supported for pop-up menus and submenus.
    Scrolling for the first level menus of a menu bar are not
    supported.
o   @{"Drop-Down List menus" LINK "Drop-Down List Menus"} are now supported (AES versions >= 4.1)

@{0B}Hierarchical Menus@{0}

Hierarchical menus allow a menu item to be the title of a submenu.
Menu items with a right arrow signify that a submenu is attached.
Hierarchical menu items must be of the type G_STRING. As a rule,
the Desk Menu of a menu bar is not allowed to have submenus.

Two delay values are used to prevent the rapid appearance and
disappearance of submenus:

o   Submenu Display Delay

    This delay is used to prevent the rapid flashing of submenus as
    the mouse pointer is dragged thru a menu item with an attached
    submenu. The mouse pointer must remain within the menu item for
    the delay period before the submenu is displayed. The default
    Submenu Display Delay is 1/5 of a second. menu_settings() can
    be used to inquire the current delay value, or to set a new
    delay.

o   Submenu Drag Delay

    This delay is used to prevent the disappearance of the submenu
    as the mouse pointer is dragged toward the submenu from a menu
    item. The default Submenu Drag Delay is 10 seconds.
    @{"menu_settings" LINK "menu_settings()"}() can be used to inquire the current delay value,
    or to set a new delay.

There are several actions that will cancel the Submenu Drag Delay
prematurely:

1)  If the mouse pointer is dragged away from the direction of the
    submenu, the submenu will disappear.

2)  If the mouse pointer remains in the same position after the
    drag has begun, the submenu will also disappear.

3)  If the user clicks on the left mouse button before the mouse
    pointer has entered the submenu, the system will return to the
    application the menu item that started the drag.

4)  If the mouse pointer is dragged vertically into another menu
    item, the submenu will disappear.

As a rule, only one level of hierarchical menus should be used.
The actual number of recursions possible is currently set to 4.

@{0B}Pop-Up Menus@{0}

Pop-up menus are menus that are not in the menu bar. They can be
placed anywhere on the screen and once displayed, act like any
other menu.

@{0B}Scrolling Menus@{0}

When the number of menu items exceeds the menu scroll height, a
scroll indicator appears at the bottom of the menu. The scroll
indicators are displayed as UP or DOWN ARROWS. Clicking on the
bottom arrow will scroll the menu items. When the last item is
shown, the DOWN ARROW indicator disappears. Note that as soon as
the menu started scrolling, the UP ARROW indicator appeared at the
top of the menu. This is to show that there are now menu items in
that direction. The default menu scroll height is 16.
menu_settings() can be used to inquire the current menu scroll
height, or to set a new menu scroll height.

When the user clicks and holds down the left mouse button, there is
a 1/4 of a second delay after one menu item has scrolled. After the
delay, scrolling continues uninterrupted. This delay is used to
prevent rapid scrolling for those just clicking on the scroll
indicators. @{"menu_settings" LINK "menu_settings()"}() can be used to inquire the current
delay, or to set a new delay.

Another delay value is used to slow down the scrolling speed. This
prevents the menu items from scrolling by too fast. menu_settings()
can be used to inquire the current delay, or to set a new delay.

Pop-up menus and submenus might consist of objects other than
G_STRINGS. Such a menu might consist of user-defined objects that
display the system's fill patterns. The system cannot scroll
non-G_STRING object types. Scrolling non-G_STRING object types will
crash the system. Pop-up menus and submenus containing non-G_STRING
object types should have its scroll_flag field set to FALSE.

The first-level menus of a menu bar are set to be non-scrollable.
This is due to the parent-child relationships between the menu
titles, menus and menu items. Therefore, scrolling is applicable
only to pop-up menus and submenus.

@{0B}Drop-Down List Menus@{0}

@{"Drop-down list menus" LINK "Drop-Down List Menus"} are pop-up menus with up, down and vertical
slider buttons attached to the right of the menu. The height of the
Drop-Down Menu is fixed to eight (8) menu items. Menus with greater
than eight menu items will be truncated and the slider will be
scaled accordingly.

Menus with fewer than eight menu items have two choices. The first
choice is to display the menu as is. The menu will be displayed as
a pop-up menu without the attached slider buttons. The second
choice is to pad the menu with disabled blank strings to ensure at
lease eight menu items.

The size of the slider is based upon the number of children in the
tree and the number of menu items displayed. Therefore, the
application should not pad the menu with blank disabled menu
items if there are more than eight enabled menu items.

For example, the application has allocated an object tree for 50
menu items. However, only the first 30 menu items are actually
used. The application should 'objc_delete' the unused menu
items.

Since the slider structure is to the right of the menu, the menu
should not have any submenu attachments. Any attached submenus will
not be displayed.

A drop-down list is displayed the same way as a pop-up menu by
calling 'menu_popup()'. The only difference is that the field
'mn_scroll' should be set to negative one (-1).


@endnode


@node "Using the extended menu library"

Menu library enhancements

5.2 Using the Extended Menu Library

The existing Menu Library functions are still applicable to pop-up
menus and submenus. The Menu Library will continue to have the
following responsibilities:

o   displaying the appropriate menu bar for each active application
o   enabling and disabling menu items
o   displaying check marks in menus
o   returning a highlighted menu title to its normal state
o   displaying context-sensitive menu text
o   displaying a desk accessory's name on the Desk Menu

To use pop-up menus and submenus in one's application:

Create an object tree consisting of a G_BOX and as many G_STRINGS
within the G_BOX as required. The G_BOX is the menu and the
G_STRINGS are the menu items. An object tree is not limited to just
one menu and can contain one, two or more menus. If a menu item is
expected to have a submenu attachment, the G_STRING must be padded
with blanks to the width of the menu.

The object tree does not need to be created with the Resource
Construction Set. It can be created  during runtime by the
application. However, the programmer is responsible for this
procedure.

Attaching a submenu to a menu item is done by calling menu attach.
A submenu is associated to a menu item by placing a right arrow two
characters in from the right edge. Any characters at that location
will be overwritten.

The high-byte of the object's type field is used to store an
internal Menu ID. The values between 128 and 192 are used by the
new menu system.

In addition, bit 11 of the object's ObFlag field will be set. Bit
11 is defined as: '#define SUBMENU 0x800'. Applications using the
Extended Object Type AND SUBMENUS should first check the object's
ObFlag field to see if the value in the Extended Object Type is a
submenu attachment.

Each process can have up to 64 unique submenu attachments.
Attaching the same submenu to multiple menu items counts as one
attachment.

In addition to attaching a submenu, menu_attach() can be used to
change or remove a submenu. @{"menu_attach" LINK "menu_attach()"}() can also be used to find
out what submenu, if any, is attached to a menu item. menu_istart()
can be used to set and get the starting menu item of a submenu.

menu_settings() can be used to set the menu delay values and to set
the height at which pop-up menus and submenus will start to scroll.


@endnode


@node "Using a menu bar"

Menu library enhancements

5.2.1 Using a Menu Bar

Supplement to 5.2  Using the Menu Library

When the user chooses an item, the Screen Manager writes a message
to the pipe. Control then returns to the application, which must
read the pipe.

The pipe message contains the following:

o   a code indicating that it is a menu message (MN_SELECTED)
o   the object index of the menu title selected
o   the object index of the menu item chosen
o   the object tree of the menu item chosen (NEW)
o   the object index of the parent of the menu item (NEW)

(If the user does not choose an item, or if the user selects a
disabled menu item, the Screen Manager does not write a message to
the pipe.)

After processing the chosen item, the application makes a Menu
Library call to dehighlight the menu title and waits for the next
message to come through the message pipe.


@endnode


@node "Extended menu library routines"

Menu Library Enhancements

5.3-b   Extended Menu Library Routines

The additions to the Menu Library routines are:

o @{"menu_popup" LINK "menu_popup()"}:    Displays a pop-up menu or drop-down list anywhere
                 on the screen. Clipping is performed for a
                 standard menu. Menus with user-defined objects
                 will have to perform their own clipping.

o @{"menu_attach" LINK "menu_attach()"}:   Lets an application attach, change, remove or
                 inquire about a submenu associated with a menu
                 item.

o @{"menu_istart" LINK "menu_istart()"}:   Lets an application set and inquire the starting
                 menu item of a pop-up menu or submenu

o @{"menu_settings" LINK "menu_settings()"}: Lets an application set and inquire the delay and
                 height parameters of the submenus.

@{"menu_popup" LINK "menu_popup()"} and @{"menu_attach" LINK "menu_attach()"} use a new structure for passing and
receiving submenu data. The MENU structure is defined as follows:

   typedef struct _menu
   {
      OBJECT *mn_tree;   - the object tree of the menu
      WORD    mn_menu;   - the parent object of the menu items
      WORD    mn_item;   - the starting menu item
      WORD    mn_scroll; - the scroll field status of the menu
                           0  - The menu will not scroll
                           >0 - The menu will scroll if the number
                                of menu items exceed the menu
                                scroll height. The non-zero value
                                is the object at which scrolling
                                will begin.This will allow one
                                to have a menu in which the
                                scrollable region is only a part of
                                the whole menu. The value must be a
                                menu item in the menu.

                                menu_settings() can be used to
                                change the menu scroll height.

                         NOTE:  If the scroll field status is >0,
                                the menu items must consist
                                entirely of G_STRINGS.

                         <0  -  The menu will be displayed as a
                                @{"Drop-Down List" LINK "Drop-Down List Menus"}.

      WORD   mn_keystate; - The CTRL, ALT, SHIFT Key state at the
                            time the mouse button was pressed.
   } MENU;

menu_settings() uses a new structure for setting and inquiring the
submenu delay values and the menu scroll height. The delay values
are measured in milliseconds and the height is based upon the
number of menu items.

    typedef struct _mn_set
    {
       LONG  Display; - the submenu display delay
       LONG  Drag;    - the submenu drag delay
       LONG  Delay;   - the single-click scroll delay
       LONG  Speed;   - the continuous scroll delay
       WORD  Height;  - the menu scroll height
    }MN_SET;

o  Submenu Display Delay:

   The delay is used to prevent the rapid flashing of submenus as
   the mouse pointer is dragged thru a menu item with an attach
   submenu. The default value is 200 milliseconds (1/5th of a
   second).

o  Submenu Drag Delay:

   The delay is used to prevent the disappearance of the submenu as
   the mouse pointer is dragged toward the submenu from a menu
   item. The default value is 10000 milliseconds (10 seconds).

o  Single-Click Scroll Delay:

   This is the delay period after one menu item has initiallly
   scrolled. After the delay, scrolling continues at the rate
   specified by the Continuous Scroll Delay. The delay is used to
   prevent rapid scrolling for those just clicking on the scroll
   indicators. The default value is 250 milliseconds (1/4th of a
   second).

o  Continuous Scroll Delay:

   This is the delay period after each menu item has scrolled. The
   delay is used to slow down the scrolling speed. The default
   value is 0 milliseconds.

o  Menu Scroll Height:

   This value is the height at which a pop-up menu or a submenu
   will start to scroll if its scroll field is TRUE. The default
   value is 16 menu items (see also Changes to the AES).

The following sections describe these routines.

        @{"menu_popup" LINK "menu_popup()"}

        @{"menu_attach" LINK "menu_attach()"}

        @{"menu_istart" LINK "menu_istart()"}

        @{"menu_settings" LINK "menu_settings()"}


@endnode


@node "menu_bar()"

Menu Library Enhancements: menu_bar()

5.3.1     MENU_BAR

   Purpose:

     Displays or erases the application's menu bar

     The application should always call MENU_BAR to erase the menu
     prior to its APPL_EXIT call.

@{0B} --------------------- NEW FOR V4.0 ---------------------- @{0}

     If me_bshow is -1, the menu_bar will become an inquiry call in
     which it will return the current menu owner's AES process id.
     If the return value is -1, then there is no menubar owner.

     It is important to point out that the current menu bar can be
     swappped out at any time. If the application wants to update
     or redraw its menu bar, it is recommended to first check to
     see if it still own the menu bar and then proceed to its
     functions. However, the menu bar owner can still bechanged
     after menu_bar call. So the safest way to do menu bar update
     function should be as follow:

     wind_update(1);     /* wait until the screen stable down  */
                        /* so nobody can change the menu      */

     id = menu_bar( 0x0L, -1 );

     if ( id == my_id )
     {
        /* update the menu and draw it */
     }
     else
     {
        /* update the menu but don't draw it */

     }

     wind_update(0);

   Parameters:

     control[0] = 30
     control[1] = 1
     control[2] = 1
     control[3] = 1
     control[4] = 0

     int_in[0]  = me_bshow
     int_out[0] = me_breturn
     addr_in[0] = me_btree


      me_bshow - a code for whether the application displays the
                 menu bar.

      0 - erase the menu bar
      1 - display the menu bar

@{0B} --------------------- NEW FOR V4.0 ---------------------- @{0}

      -1 - Inquire current menu owner.

     me_breturn - a coded return message.

     0 - an error exists
     n ( positive integer ) - no error exists

     For inquiry mode, -1 indicates no menu owner, otherwise n is
     the current menu owner's AES id.

     me_btree - the address of the object tree that  forms  this
                menu.

Sample call to C language binding:

   me_breturn = menu_bar( me_btree, me_bshow );


@endnode


@node "menu_register()"

Menu Library Enhancements: menu_register()

5.3.6  MENU_REGISTER

Purpose:
        Places a desk accessory's menu item string on the menu and
        returns the accessory's menu item identifier. The menu can
        list no more than six desk accessories.

@{0B} --------------------- NEW FOR V4.0 ---------------------- @{0}

        The AES can handle as many accessories as possible
        provided that the drop-down menu is tall enough to hold
        all the accessories' name or that is enough memory to load
        in all the accessories.
        Applications can call menu_register to change the name that
        appears in the menu bar for that application. The
        parameters are the same.

     Parameters:

     control[0] = 35
     control[1] = 1
     control[2] = 1
     control[3] = 1
     control[4] = 0

     int_in[0] = me_rapid
     int_out[0] = me_rmenuid

     addr_in[0] = me_rpstring

     Description:

     me_rapid - The AES process identifier of the desk accessory or
                application. This value is the ap_id returned by
                the @{"appl_init" LINK "appl_init()"} call. If this value equals -1, the
                me_rpstring will be used to replace the current
                accessory's process name.

     me_rmenuid - The desk accessory's or application's menu item
                identifier.
                -1 - no more room on the menu.

     me_rpstring - The address of the desk accessory's or
                application's menu text string. This string must
                contain not more than 16 characters and must be
                ended with a dot or null.

     Sample call to C language binding:

                me_rmenuid = menu_register( me_rapid, me_rpstring );


@endnode


@node "menu_popup()"

Menu Library Enhancements: menu_popup()

5.3.7   MENU_POPUP

Purpose:

Allows an application to display a popup menu anywhere on the
screen. The popup menu may also have submenus. If the number of
menu items exceed the menu scroll height, the menu may also be set
to scroll. menu_settings() can be used to set the height at which
all menus will start to scroll.

This call will also display a drop-down list anywhere on the
screen. The drop-down list may NOT have submenus. The height of the
drop-down list is set to eight (8) menu items. If the number of
menu items is greater than eight, the menu will be set to scroll.
If the menu has fewer than eight menu items, the menu will be
displayed as a popup menu. Set the field 'mn_scroll' to negative
one (-1) to display a drop-down list.

Parameters:

     control(0)  =  36
     control(1)  =  2
     control(2)  =  1
     control(3)  =  2
     control(4)  =  0

     int_in(0)   =  me_xpos
     int_in(1)   =  me_ypos

     int_out(0)  =  me_return

     addr_in(0)  =  me_menu
     addr_in(1)  =  me_mdata

o    me_xpos - the left edge of where the starting menu item will
               be displayed

o    me_ypos - the top edge of where the starting menu item will be
               displayed

o    me_return - a coded return message

                 0 - FAILURE: The data returned by me_mdata is
                              invalid
                 1 - SUCCESS: The data returned by me_data is valid

     FAILURE is returned if the user did not click on an enabled
     menu item

o    me_menu  - pointer to the pop-up MENU structure.  The
                structure must be initialized with the object tree
                of the pop-up menu, the menu object, the starting
                menu item and the scroll field status.

o    me_mdata - pointer to the data MENU structure. If menu_popup
                returns TRUE,  me_mdata will contain information
                about the submenu that the user selected. This
                includes the object tree of the submenu, the menu
                object, the menu item selected and the scroll field
                status for this submenu.

        ------------------------------------------------

        Sample call to C language binding:

        me_return = menu_popup( MENU *me_menu, word me_xpos,
                                word me_ypos, MENU *me_mdata);


@endnode


@node "menu_attach()"

Menu Library Enhancements: menu_attach()

5.3.8   MENU_ATTACH

Purpose:

Allows an application to attach, change, remove or inquire about a
submenu associated with a menu item.

Parameters:

     control(0)  =  37
     control(1)  =  2
     control(2)  =  1
     control(3)  =  2
     control(4)  =  0

     int_in(0)   =  me_flag
     int_in(1)   =  me_item

     int_out(0)  =  me_return

     addr_in(0)  =  me_tree
     addr_in(1)  =  me_mdata

o  me_flag - the action to be performed by menu_attach.

   The options for me_flag are:

   0  Inquire data about the submenu that is associated with the
      menu item. The data concerning the submenu is returned in
      me_mdata.

   1  Attach or change a submenu associated with a menu item.
      me_mdata must be initialized by the application. The data
      must consist of the object tree of the submenu, the menu
      object, the starting menu item and the scroll field status.
      Attaching a NULLPTR structure will remove the submenu
      associated with the menu item. There can be a maximum of 64
      associations per process. Bit 11 of the object's ObFlag will
      be set if a submenu is actually attached.

   2  Remove a submenu associated with a menu item. me_mdata should
      be set to NULLPTR. Bit 11 of the object's ObFlag will be
      cleared.

o  me_item - the menu item that the submenu will be attached to

o  me_return - a coded return message

   0 - FAILURE: the submenu was not attached for whatever reasons
   1 - SUCCESS: the submenu was attached, changed or removed
                successfully

o  me_tree - the object tree of the menu item that will have a
             submenu attach to

o  me_mdata - pointer to the MENU structure. The contents of
              me_mdata are dependant upon the value of me_flag:

   0  Upon return from menu_attach, me_mdata will contain the MENU
      data regarding the submenu associated with the menu item.

   1  me_mdata must be initialized with the new submenu MENU data.
      The submenu will be attached to the menu item - me_item.

   2  me_mdata should be set to NULLPTR. The submenu associated
      with the menu item will be removed.

   ------------------------------------------------

   Sample call to C language binding:

   me_return = menu_attach( word me_flag, object *me_tree,
                                word me_item, MENU *me_mdata );


@endnode


@node "menu_istart()"

Menu Library Enhancements: menu_istart()

5.3.9   MENU_ISTART

Purpose:

Allows an application to set or inquire the starting menu item of a
submenu that is associated with a menu item. The submenu is shifted
vertically so that the starting menu item is aligned with the menu
item that is associated with this submenu.

Parameters:

     control(0)  =  38
     control(1)  =  3
     control(2)  =  1
     control(3)  =  1
     control(4)  =  0

     int_in(0)   =  me_flag
     int_in(1)   =  me_imenu
     int_in(2)   =  me_item

     int_out(0)  =  me_return

     addr_in(0)  =  me_tree

o    me_flag - the action to be performed by menu_istart

     0  Inquire the starting menu item for the submenu

     1  Set the starting menu item for the submenu to be me_item

o    me_imenu - the menu object of the submenu that is either to be
                set or inquired

o    me_item - the starting menu item that is either to be set or
               inquired

o    me_return - a coded return message

     0 - FAILURE: the submenu is not associated with a menu item.
                  The submenu must be attached via @{"menu_attach" LINK "menu_attach()"}
                  before this call can be made.

     >0 - SUCCESS: the starting menu item is currently set to this
                   value.

o    me_tree - the object tree of the menu item that we are setting
               or inquiring about

     ------------------------------------------------

     Sample call to C language binding:

     me_return = menu_istart( word me_flag, object *me_tree,
                                word me_imenu, word me_item );


@endnode


@node "menu_settings()"
@next "MN_SELECTED"

Menu Library Enhancements: menu_settings()

5.3.10  MENU_SETTINGS

Purpose:

Allows an application to set or inquire the submenu delay values
and the menu scroll height value.

Parameters:

     control(0)   =  39
     control(1)   =  1
     control(2)   =  1
     control(3)   =  1
     control(4)   =  0

     int_in(0)    =  me_flag

     int_out(0)   =  me_return

     addr_in(0)   =  me_values


o    me_flag - the action to be taken by menu_settings

     0  Inquire the current delay and menu scroll height values.
     1  Set the delay and menu scroll height values

o    me_return - always returns 1 (one)

o    me_values - pointer to the MN_SET structure.  me_values is
                 dependant upon the value of me_flag:

     0   Upon the return of menu_settings, me_values will contain
         the current delay and menu scroll height values.

     1   me_values must be initialized. The delay and menu scroll
         height values will be set to those values found in
         me_values. A value set to NIL will be ignored.

     ------------------------------------------------

     Sample call to C language binding:

     me_return = menu_settings( word me_flag, MN_SET *me_values );


@endnode


@pnode "AES supplemental documentation"

The following sections contain documentation supplemental to
existing AES manual, and clarifications of existing document
related to hierarchical submenus and the menu bar.

@endnode


@node "MN_SELECTED"
@prev "menu_settings()"

AES Supplemental Documentation: MN_SELECTED

GEM AES uses this message to notify an application that a user has
selected a menu item.

o   word 0   = 10
o   word 3   = the object index of the menu title selected
o   word 4   = the object index of the menu item selected
o   word 5,6 = the object tree of the menu item selected
o   word 7   = the parent object of the menu item selected


@endnode


@node "Pop-Up Menus"

AES Supplemental Documentation: Pop-Up Menus

5.4.1   Pop-Up Menus

o   The button on a dialog box that brings up a pop-up menu should
    be shadowed.

o   It would be nice if the pop-up menu was shadowed also.

o   While the pop-up menu is displayed, if it has a title, the
    title should be inverted.

o   The pop-up menu should be aligned on a byte boundary. This
    speeds up the drawing of the menu considerably.

o   The pop-up menu will be shifted vertically in order to line up
    the start object with the given coordinates.

o   If the menu exceeds the top of the screen, it will be shifted
    down.

o   No horizontal adjustments will be done to the menu.


@endnode


@node "Submenus"

AES Supplemental Documentation: Submenus

5.4.2   Submenus

o   Menu items expecting a submenu attachment must be of type
    G_STRING.

o   Menu items should be padded with blanks to the width of the
    menu.

o   Menu items expecting a submenu attachment should not have any
    keyboard short-cut characters.

o   Submenus will automatically be displayed on a byte boundary.

o   The menu will be shifted vertically to align the start object
    with the menu item. In addition, the menu will be shifted to
    remain entirely on the screen in the vertical plane.

o   The submenu will be displayed at the right edge of the menu
    item. If the menu extends off the edge of the screen, the menu
    will be displayed to the left of the menu item. If it exceeds
    the left edge of the screen, the menu will be shifted right a
    character at a time, until it fits.

o   There can be a maximum of 64 submenu attachments per process.

o   A menu item with an attached submenu uses the high-byte of its
    object type field. Values 128 thru 192 are used by the submenu
    menu system.

o   A menu item with an attached submenu will have Bit 11 of its
    object flag field SET.

    The bit is defined as:   #define SUBMENU 0x800

o   Applications using the Extended Object Type should check the
    object's ObFlag field to see if Bit 11 is SET. If the bit is
    SET, the menu item has a submenu attached.

o   A submenu should not be attached to itself.

o   Attaching a submenu to different menu items counts as one
    attachment. There will only be one scroll flag and one start
    object.

o   As a user interface guideline, there should only be one level of
    hierarchical menus. The system currently allows up to four
    levels of recursion.

o   menu_istart() works only on submenus attached with
    menu_attach().

o   Menu items with attached submenus cannot have keyboard
    shortcuts.


@endnode


@node "Scrolling Menus"

AES Supplemental Documentation: Scrolling menus

5.4.3   Scrolling Menus

o   In order to scroll properly, all menu items must be G_STRINGS.
    Menus that contain objects other than G_STRINGS should set the
    scroll flag to 0.

o   The first-level menus of a menu bar are not scrollable.

o   Pop-up menus and submenus with greater than sixteen items can
    be scrolled if their scroll flag is set. The number of items to
    scroll at can be adjusted with @{"menu_settings" LINK "menu_settings()"}.

o   If the pop-up menu or submenu is designed to be a toolbox,
    (ie: fill patterns), set the scroll flag to FALSE.

o   Setting the scroll flag to one of the menu items will initiate
    scrolling from that menu item if the number of items exceeds the
    menu height limit.

o   One should NOT set the scroll object to the last menu item of a
    menu.

o   Setting the scroll object to a value less than the first menu
    item defaults to the first menu item.

o   Setting the scroll object to a value greater than or equal to
    the last menu item defaults to the first menu item.


@endnode


@node "Drop-Down List Menus"

AES Supplemental Documentation: Drop-Down List Menus

5.4.4   Drop-Down List Menus

o   The button on a dialog box that brings up a drop-down list
    should be shadowed.

o   The menu items of a drop-down list must consist entirely of
    G_STRINGS.

o   The button should be inverted when the drop-down list is
    displayed.

o   The drop-down list menu should be shadowed also.

o   To the right of the button should be a boxchar containing
    a character of '0x0f'. This character consists of three
    horizontal lines. The boxchar should be treated just like
    the button.

o   While the drop-down list is displayed, if it has a title, the
    title should be inverted also.

o   The drop-down list should be displayed below the button.

o   The width of the button should match the width of the menu.

o   The boxchar should be aligned with the slider structure
    that will appear to the right of the menu.

o   No horizontal or vertical adjustments will be made to the
    position of the menu.

o   It is advantageous to align the menu on a byte boundary. This
    speeds up the drawing of the menu considerably.

o   Submenus should not be attached to any menu items. Any
    submenus that are attached will not be displayed.

o   The height of the drop-down list is fixed to eight (8) items.

o   Menus with greater than eight (8) menu items will be
    scrolled via the slider structure.

o   Menus with fewer than eight (8) menu items will be displayed
    as a pop-up. No slider structure will be displayed. The
    alternative is to pad the menu with disabled blank strings
    up to eight menu items.

o   The function 'menu_popup()' is used to display pop-up menus
    as well as drop-down lists. Set the field 'mn_scroll' to
    negative one (-1) to display the menu as a drop-down list.


@endnode


@node "Keyboard scrolling"

Addendum: Keyboard scrolling

Minimal keyboard support has been added to the menu manager. Menus
that are scrollable can be scrolled using the UP and DOWN arrow
keys. @{"Drop-down list menus" LINK "Drop-Down List Menus"} can also be scrolled using the UP and
DOWN arrow keys. In addition, @{"Drop-down list" LINK "Drop-Down List Menus"} menus can be paged
using SHIFT-UP and SHIFT-DOWN arrow keys. These features are
available on AES versions >= 4.1.


@endnode


@node "Softloaded resources"

Addendum: Softloaded resources

It is now possible to load the TOS resource files. At boot time,
TOS looks for the following files in the MULTITOS directory of the
boot drive:

        GEM.RSC         - AES resource file
        DESKTOP.RSC     - Desktop's resource file
        KEYBD.TBL       - XBIOS Keyboard table

The resource files are ordinary GEM resource files but with version
number checking. The first byte in the resource header of the
resource file contains the version number.

The format of the KEYBD.TBL file is:

        [ unshifted keyboard table (128 Bytes)     ]
        [ shifted keyboard table (128 Bytes)       ]
        [ caps lock keyboard table (128 Bytes)     ]
        { alternate unshifted keyboard table **    }
        { alternate shifted keyboard table **      }
        { alternate caps lock keyboard table **    }

        **: An alternate keyboard table is a list of two bytes
            pairs. The list is NUL terminated.

Use an assembler (madmac), aln and fixrom to create the tables. You
can get the data for the tables from bios.s.

This works only a 100% on machines with the AKP code (since 5/92)
in the BIOS. Older versions have the alternate key handling hard
coded while the BIOS with AKP uses tables for the alternate
key handling.

Example: The German keyboard table:

;
;       Keyboard Table for ATARI ST/TT/FALCON030
;       Keyboard: German
;       02/12/92 (from bios.s)
;       Used for loadable keyboard tables
;
;       Makefile lines:
;       --------------
;       keybd.tbl: kbtblgrm.s
;       mac kbtblgrm.s
;       aln -o keybdgrm.tbl -a 0 x x kbtblgrm.o
;       fixrom keybdgrm.tbl
;
;
;       NOTE:   Alternate keyboard table will only work on machines with
;               _AKP cookie set. This was introduced in 05/92.

        .even
        .data

        dc.w    $2771                           ; magic word for keybd table

        dc.b    $00,$1b,'1','2','3','4','5','6' ; unshifted
        dc.b    '7','8','9','0',$9e,$27,$08,$09
        dc.b    'q','w','e','r','t','z','u','i'
        dc.b    'o','p',$81,'+',$0D,$00,'a','s'
        dc.b    'd','f','g','h','j','k','l',$94
        dc.b    $84,'#',$00,'~','y','x','c','v'
        dc.b    'b','n','m',',','.','-',$00,$00
        dc.b    $00,$20,$00,$00,$00,$00,$00,$00

        dc.b    $00,$00,$00,$00,$00,$00,$00,$00
        dc.b    $00,$00,'-',$00,$00,$00,'+',$00
        dc.b    $00,$00,$00,$7f,$00,$00,$00,$00
        dc.b    $00,$00,$00,$00,$00,$00,$00,$00
        dc.b    '<',$00,$00,'(',')','/','*','7'
        dc.b    '8','9','4','5','6','1','2','3'
        dc.b    '0','.',$0D,$00,$00,$00,$00,$00
        dc.b    $00,$00,$00,$00,$00,$00,$00,$00

grmshif:
        dc.b    $00,$1b,'!','"',$dd,'$','%','&' ; shifted
        dc.b    '/','(',')','=','?','`',$08,$09
        dc.b    'Q','W','E','R','T','Z','U','I'
        dc.b    'O','P',$9a,'*',$0D,$00,'A','S'
        dc.b    'D','F','G','H','J','K','L',$99
        dc.b    $8e,'^',$00,'|','Y','X','C','V'
        dc.b    'B','N','M',';',':','_',$00,$00
        dc.b    $00,$20,$00,$00,$00,$00,$00,$00

        dc.b    $00,$00,$00,$00,$00,$00,$00,$37
        dc.b    $38,$00,'-',$34,$00,$36,'+',$00
        dc.b    $32,$00,$30,$7f,$00,$00,$00,$00
        dc.b    $00,$00,$00,$00,$00,$00,$00,$00
        dc.b    '>',$00,$00,'(',')','/','*','7'
        dc.b    '8','9','4','5','6','1','2','3'
        dc.b    '0','.',$0D,$00,$00,$00,$00,$00
        dc.b    $00,$00,$00,$00,$00,$00,$00,$00

grmcl:
        dc.b    $00,$1b,'1','2','3','4','5','6' ; caps lock
        dc.b    '7','8','9','0',$9e,$27,$08,$09
        dc.b    'Q','W','E','R','T','Z','U','I'
        dc.b    'O','P',$9a,'+',$0D,$00,'A','S'
        dc.b    'D','F','G','H','J','K','L',$99
        dc.b    $8e,'#',$00,'~','Y','X','C','V'
        dc.b    'B','N','M',',','.','-',$00,$00
        dc.b    $00,$20,$00,$00,$00,$00,$00,$00

        dc.b    $00,$00,$00,$00,$00,$00,$00,$00
        dc.b    $00,$00,'-',$00,$00,$00,'+',$00
        dc.b    $00,$00,$00,$7f,$00,$00,$00,$00
        dc.b    $00,$00,$00,$00,$00,$00,$00,$00
        dc.b    '<',$00,$00,'(',')','/','*','7'
        dc.b    '8','9','4','5','6','1','2','3'
        dc.b    '0','.',$0D,$00,$00,$00,$00,$00
        dc.b    $00,$00,$00,$00,$00,$00,$00,$00

        ; alternate keyboard tables

grmatran:
        dc.b    $1a,'@@',  $27,'[',  $28,']',  0 ; alternate unshifted
grmashif:
        dc.b    $1a,$5c,  $27,'{',  $28,'}',  0 ; 5c is '\', alt shift
grmacl:
        dc.b    $1a,'@@',  $27,'[',  $28,']',  0 ; alt caps lock


@endnode


@node "Window iconifying"

Addendum: Window Iconifying

How to use the AES Window Iconify Feature

1.) The SMALLER Gadget

To create a window which can be iconified the application has to
specify the SMALLER gadget in the window "kind" parameter of a
wind_create() call.

Example:
    wind_create(NAME|SIZER|MOVER|CLOSER|FULLER|SMALLER, x, y, w, h);

Binding:
# define SMALLER 0x1000


2.) New Messages

There are three new messages for the iconify feature: WM_ICONIFY,
WM_UNICONIFY, and WM_ALLICONIFY.

When the user clicks on the SMALLER gadget of a window, the AES
will send a WM_ICONIFY message to the application. The application
should then iconify its window.

Double clicking on the work area of an iconified window will cause
the AES to send a WM_UNICONIFY message to the application. The
application should respond to that message by bringing the window
back to its original state.

When the user holds down the CONTROL key while selecting the
SMALLER gadget of a window, the AES will send a WM_ALLICONIFY
message. The application should then close all its windows and open
a new, iconified window. This iconified window represents all of the
application's windows. The application has to keep track itself
that all its windows are closed and the "All Iconified" window is
open. A double click on the work area of this iconified window
will cause the AES to send a WM_UNICONIFY message. The application
should then reopen its windows and close the "All Iconified" window.

WM_ICONIFY:
        msgbuff[0] = WM_ICONIFY (34)
        msgbuff[3] = window handle
        msgbuff[4] = x coordinate of icon window
        msgbuff[5] = y coordinate of icon window
        msgbuff[6] = width of icon window
        msgbuff[7] = height of icon window

WM_UNICONIFY:
        msgbuff[0] = WM_UNICONIFY (35)
        msgbuff[3] = window handle
        msgbuff[4] = x coordinate of original window
        msgbuff[5] = y coordinate of original window
        msgbuff[6] = width of original window
        msgbuff[7] = height of original window


WM_ALLICONIFY:
        msgbuff[0] = WM_ALLICONIFY (36)
        msgbuff[3] = window handle
        msgbuff[4] = x coordinate of icon window
        msgbuff[5] = y coordinate of icon window
        msgbuff[6] = width of icon window
        msgbuff[7] = height of icon window

Binding:
#define WM_ICONIFY      34
#define WM_UNICONIFY    35
#define WM_ALLICONIFY   36

3.) New wind_set() Calls

There are three new calls to wind_set():

        WORD wind_set(handle, WF_ICONIFY, x, y, w, h)
        WORD handle;
        WORD x, y, w, h;

This call will iconify a window to the given width and height and
place it at the given coordinates. All window gadgets but the move
and title bar will be removed by this call. The font in the title
bar will be set to SMALL (6 point). A WM_REDRAW message will be
send to the application to redraw the work area of the iconified
window. It is recommended to draw an icon inside the work area. The
standard size of an iconified window is 72 by 72.

The AES will now look for double clicks inside the work area to
send a WM_UNICONIFY message to the application.

If an application closes an iconified window and then opens it
again, it will still be in the iconified state. Before closing a
window an application should check if the window is iconified
and if so, bring it back to its original state before closing it.

        WORD wind_set(handle, WF_UNICONIFY, x, y, w, h)
        WORD handle;
        WORD x, y, w, h;

This call will uniconify a window to the given width and height and
place it at the given coordinates, meaning the window will go back
to its originalstate. All of the window's gadgets will again be
added by this call. The font in the title bar will be reset to IBM.
A WM_REDRAW message will be send to the application to redraw its
work area.

        WORD wind_set(handle, WF_UNICONIFYXYWH, x, y, w, h)
        WORD handle;
        WORD x, y, w, h;

This call will set the coordinates and size which will be send to a
window when it gets the WM_UNICONIFY message. Normally the AES
sends the coordinates and size of the window which it had before it
got iconified. This call is needed if a window is opened in
iconified state.

Binding:
#define WF_ICONIFY              26
#define WF_UNICONIFY            27
#define WF_UNICONIFYXYWH        28


4.) New wind_get() Calls

There are two new calls to wind_get():

        WORD wind_get(handle, WF_ICONIFY, iconified, icn_w, icn_h, dummy)
        WORD handle;
        WORD *iconified, *icn_w, *icn_h, *dummy;

This call will return the state of a window. A value of TRUE states
that the window is iconified.

        iconified == TRUE       --> window is iconified
        iconified == FALSE      --> window is not iconified

It also returns the width and height the AES sends to windows when
they get iconified.

        WORD wind_get(handle, WF_UNICONIFY, x, y, w, h)
        WORD handle;
        WORD *x, *y, *w, *h;

This call will return the x and y coordinates as well as the width
and height of an iconified window's orignal coordinates and size.
That are the coordinates and size of the window before it was
iconified.

5.) Example Code

        .
        WINDOW  *win;
        .
        .
        win->handle = wind_create(NAME|SIZER|MOVER|CLOSER|FULLER|SMALLER,
                        full.g_x, full.g_y, full.g_w, full.g_h);
        .
        .

        event = evnt_multi( MU_MESAG|MU_BUTTON|MU_KEYBD, 2, 1, 1,
                              0, 0, 0, 0, 0,
                              0, 0, 0, 0, 0,
                              (LONG) msgbuff,   /* message buffer       */
                              0, 0,             /* timer counter        */
                              &mx, &my, &button, &kstat, &kreturn, &clicks
                          );
        .
        .
        if (event & MU_MESAG) {
                switch (msgbuff[0]) {
                        .
                        .
                case WM_ICONIFY:
                    if ((win = get_win(msgbuff[3])) == NULL)
                        break;
                    form_dial(FMD_SHRINK,
                        msgbuff[4], msgbuff[5], msgbuff[6], msgbuff[7],
                        win->work.g_x, win->work.g_y,
                        win->work.g_w, win->work.g_h);

                    wind_set(msgbuff[3], WF_ICONIFY,
                        msgbuff[4], msgbuff[5], msgbuff[6], msgbuff[7]);

                    wind_get(msgbuff[3], WF_WORKXYWH,
                        &win->work.g_x, &win->work.g_y,
                        &win->work.g_w, &win->work.g_h);
                    break;

                case WM_UNICONIFY:
                    if ((win = get_win(msgbuff[3])) == NULL)
                        break;
                    form_dial(FMD_GROW,
                        win->work.g_x, win->work.g_y,
                        win->work.g_w, win->work.g_h,
                        msgbuff[4], msgbuff[5], msgbuff[6], msgbuff[7]);

                    wind_set(msgbuff[3], WF_UNICONIFY,
                        msgbuff[4], msgbuff[5], msgbuff[6], msgbuff[7]);

                    wind_get(msgbuff[3], WF_WORKXYWH,
                        &win->work.g_x, &win->work.g_y,
                        &win->work.g_w, &win->work.g_h);
                    break;

                case WM_REDRAW:
                    if ((win = get_win(msgbuff[3])) == NULL)
                        break;
                    wind_get(msgbuff[3], WF_ICONIFY, &iconified,
                        &dummy, &dummy &dummy);
                    if (iconified)
                        redraw_iconWindow(win, msgbuff[4], msgbuff[5],
                            msgbuff[6], msgbuff[7]);
                    else
                        redraw_normalWindow(win, msgbuff[4], msgbuff[5],
                            msgbuff[6], msgbuff[7]);
                    break;
                .
                .
                .


@endnode


@node "Replacing the system font"
@next "SpeedoGDOS TEDINFO objects"

Addendum: Replacing the System Font

By using the AE_FONTID and AE_PNTSIZE variables in the GEM.CNF
file, the user can now replace the system font and or change its
size. NOTE: The replacement font has to be a SpeedoGDOS font.

Sample GEM.CNF lines:

AE_FONTID=5             # use Speedo GDOS font with Font ID 5
AE_PNTSIZE=18           # Use a point size 18

or:

AE_PNTSIZE=24           # change the size of the system font to 24 points


@endnode


@pnode "Changing the desktop font"

Changing the font the desktop uses in its windows

Using the "Set Color & Style..." dialog box the user is able
change the font as well as the size of the font which the GE
desktop uses in its windows.

@endnode


@node "SpeedoGDOS TEDINFO objects"
@prev "Replacing the system font"

TEDINFO objects supporting Speedo GDOS fonts

It is possible now to specify not only IBM and SMALL as the font
used by a TEDINFO object. The available options for te_font are:

#define GDOS_PROP       0       /* Speedo GDOS font                         */
#define GDOS_MONO       1       /* Speedo GDOS font, force monospace output */
#define GDOS_BITM       2       /* GDOS bit map font                        */
#define IBM             3       /* System font                              */
#define SMALL           5       /* Small system font                        */

Also, the TEDINFO structure has changed. The old structure looked
like this:

TEDINFO
{
        LONG  te_ptext;       /* ptr to text (must be 1st) */
        LONG  te_ptmplt;      /* ptr to template           */
        LONG  te_pvalid;      /* ptr to validation chrs.   */
        WORD  te_font;        /* font                      */
        WORD  te_resrvd1;     /* reserved                  */
        WORD  te_just;        /* justification- left, right...*/
        WORD  te_color;       /* color information word    */
        WORD  te_resrvd2;     /* reserved                  */
        WORD  te_thickness;   /* border thickness          */
        WORD  te_txtlen;      /* length of text string     */
        WORD  te_tmplen;      /* length of template string */
};

The reserved fields are used now and the strucure has changed to:

TEDINFO
{
        LONG  te_ptext;       /* ptr to text (must be 1st) */
        LONG  te_ptmplt;      /* ptr to template           */
        LONG  te_pvalid;      /* ptr to validation chrs.   */
        WORD  te_font;        /* font                      */
        WORD  te_fontid;      /* GDOS font id              */
        WORD  te_just;        /* justification- left, right...*/
        WORD  te_color;       /* color information word    */
        WORD  te_fontsize;    /* GDOS font size in points  */
        WORD  te_thickness;   /* border thickness          */
        WORD  te_txtlen;      /* length of text string     */
        WORD  te_tmplen;      /* length of template string */
};

If the te_font field contains GDOS_PROP, GDOS_MONO, GDOS_BITM the
application specifies in te_fontid which GDOS font the AES uses to
draw this TEDINFO field. The AES sets the font size to the number
of points according to the te_fontsize field.

GDOS_MONO will force the output of a Speedo GDOS font to be
monospaced.

All the above works fine with editable text fields (FTEXT objects),
too. Also, you are now able to specify SMALL as the font (te_font
field) in FTEXT objects.

@{0B}NOTE: ATARI SPEEDO GDOS VERSION 4.11 (OR GREATER) IS REQUIRED.
@{0B}@{0}
Sample Code:

        .
        .
        init_vdi();
        init_aes();
        .
        .
        rsrc_gaddr(R_TREE, BOX, &tree);

        ted = (TEDINFO*) tree[TEXT1].ob_spec;
        ted->te_font = GDOS_PROP;  /* use Speedo GDOS font */
        ted->te_just = TE_LEFT;    /* left justified       */
        ted->te_fontid = 5;        /* use font with ID 5   */
        ted->te_fontsize = 18;     /* 18 points            */

        ted = (TEDINFO*) tree[FTEXT1].ob_spec;
        ted->te_font = GDOS_MONO;  /* use Speedo GDOS font, force monospaced */
        ted->te_just = TE_RIGHT;   /* right justified      */
        ted->te_fontid = 6;        /* use font with ID 5   */
        ted->te_fontsize = 8;      /* 8 points             */

        ted = (TEDINFO*) tree[FBOXTEXT2].ob_spec;
        ted->te_font = GDOS_MONO;  /* use Speedo GDOS font, force monospaced */
        ted->te_just = TE_CNTR;    /* centered             */
        ted->te_fontid = 5;        /* use font with ID 5   */
        ted->te_fontsize = 10;     /* 10 points            */

        form_dial(FMD_START, ...);
        objc_draw(tree, ...);

        form_do(tree, FTEXT1);
        .
        .


@endnode


@node "Drag and drop protocol"

Addendum: Drag and Drop protocol, revision 1.1

Here is a protocol applications can use to communicate "drag &
drop" operations, i.e. to allow the user to drag an object from an
application's window to the window of a different application. This
is somewhat like cutting and pasting to/from the clipboard, but
without the necessity for explicit cut and paste operations.
Moreover, this protocol ensures that the data is actually
transferred to the correct process (whereas clipboard data is
globally shared, and can be modified or deleted by any process).

In the following, the "originator" is the application that owns the
window the object was originally located in, and the "recipient" is
the application that owns the window into which the object is
dropped. It is assumed that these are two *different* applications.


@endnode


@node "Originator side"

Drag & drop protocol: Originator side

Originator's side

When the user drags and releases an object, the application should
make the appropriate wind_get() call to find out the window id and
window owner of the window under the mouse at the time the button
was released. If the window owner is not the current application,
then the current application becomes the originator of a drag &
drop sequence.

The originator of the drag & drop creates a (bidirectional) pipe
named DRAGDROP.xx, where 'xx' is some unique 2 character
combination (this could be formed from the process id, or the
application could just try Fcreate() until it finds a combination
that works; Fcreate will fail if a pipe with the same name already
exists). 2 letters allows for 626 simultaneous drag and drop
operations to be in progress at once, which should be plenty.

It then constructs and sends an AES message to the window owner, as
follows:

word 0: AP_DRAGDROP
word 1: originator's application id
word 2: 0 (number of extra bytes in message)
word 3: id of the window that was dropped onto
word 4: mouse X position at the time of the drop
word 5: mouse Y position at the time of the drop
word 6: keyboard shift key status at the time of the drop
word 7: 2 byte pipe identifier (see above)

If word 3 is -1, then there is no specific window which is the
target of the drag and drop message. Usually this will be used with
"ARGS" data to indicate that a new window should be opened for the
indicated file(s).

The originator then waits (with Fselect) for data to arrive on the
pipe. If the Fselect times out (probably a 3 or 4 second time out
would be sufficient) then the recipient doesn't understand drag &
drop. Otherwise, the sender reads 1 byte from the pipe, which will
be one of the following values:

DD_OK           meaning "go ahead, send data"
DD_NAK          meaning "I don't want any data on that window"

If DD_OK is received, the originator should then read 32 bytes from
the pipe. These 32 bytes consist of 8 data types, each 4 bytes
long, which are a list of the data types that the receiving
application can understand, in order of preference. This list is
not binding, nor is it exhaustive; it is intended only as a
guideline. The originator should not abort the transfer if it can't
send any of the types on the list; it should go throught the normal
exchange with any types that it can send, and leave it up to the
recipient to abort if necessary. If the recipient has fewer than 8
"preferred" data types, it will pad the 32 bytes with zeros.

Data types are always 4 bytes long, and consist either of a period
followed by a 3 byte file extension, or a 4 byte "special" type.
Extensions are the same as the file name extensions used for normal
files or scrap files; for example, ".TXT" would be an ASCII text
file with lines terminated by cr/lf sequences. "Special" types are
other kind of data. For example, the data type "ARGS" denotes a
command line with arguments seaparated by spaces. The desktop sends
a drag & drop message with type "ARGS" when you drag a group of
files or folders to an application window; the file and folder
names, separated by spaces, form the data for this message. Note
that if any of the file names in the command lines contains a
space, then it will be surrounded by single quotes. Inside of
single quotes, two consecutive single quotes stand for a single
quote. For example, if a file named Eric's File would be passed to
an application as 'Eric''s File'. This obviously is of concern only
for non-DOS file systems, but applications should be aware of this.

The data type "PATH" is a request by the originator for the GEMDOS
path or file name associated with the target window, and is handled
specially. See below for complete details.

After the originator has consulted the recipient's list of
preferred data types, it then constructs a header consisting of:
(the length of each field is given in parentheses after its
description)

(1) The type of data (e.g. ".TXT" or ".IMG") as a 4 byte file
extension. Some special types are reserved: "ARGS" means that the
data is a command line with arguments separated by spaces. For
example, if you drag a group of icons from the desktop to a window,
the receiving application will get a drag & drop message with type
"ARGS" containing the file names of all files dragged and dropped.
Application data types must begin with a "." and should form a valid
file extension (similar to the extensions used for data exchange on
the clipboard). (4 bytes)

(2) The length of the data in bytes. (4 bytes)

(3) The data's name. This is arbitrary (and can be empty);
typically this would be a brief description of the type of data and
the application that created it (e.g. "TOSWIN text"). Typically
this field will be used to label an icon. (variable length,
terminated by 0)

(4) A file name associated with the data. This may be related to
(3), obviously, but need not be. It should be just the root of the
name, and should not include any path or drive letter. Example:
"TOSWIN.TXT". (variable length, terminated by 0).

There may be extra bytes in the header following the file name; for
now applications should ignore any such following data, but in the
future we could add new header fields.

The originator writes to the pipe 2 bytes representing the length
of the header, and then writes the header itself. It then reads a 1
byte reply. This reply can be any one of the following:

   DD_OK: go ahead, send the actual data to the pipe
   DD_NAK: abort the drag & drop
   DD_EXT: I don't understand the file type, try something else
   DD_LEN: I don't want so much data all at once
   DD_TRASH: the data was dropped on a trash can
   DD_PRINTER: the data was dropped on a printer icon
   DD_CLIPBOARD: the data was dropped on a clipboard icon

   all other values: reserved for future use

If DD_TRASH, DD_PRINTER, or DD_CLIPBOARD is returned, the
originating application should terminate the drag and drop exchange
by Fclosing the pipe, and should take whatever action it considers
appropriate (e.g. printing the data).

If the reply is DD_EXT, the drag & drop originator either builds
another header with a different data type, or closes the pipe
(causing the recipient to get EOF on the pipe) to abort. Either the
originator and recipient eventually agree on a data type, or else
one or the other aborts the transfer.

If and when DD_OK is received, the originator writes its data to
the pipe. It must be sure to write the number of bytes it
specified. It then closes the pipe with Fclose(). Exception: if the
agreed upon data type is "PATH", then the originator *reads* the
specified number of bytes from the pipe.

The "PATH" data type is a way for applications to request a file or
path name from recipients. If the recipient agrees to "accept" a
PATH data type, then it will in fact write the path name
(terminated by a \) or the full file name of the file associated
with the target window. If no file name or path name is logically
associated with the window, then the recipient must not accept
the PATH data type for that window.


@endnode


@node "Recipient side"

Drag & drop protocol: Recipient's Side

When an application receives an AP_DRAGDROP message, it should
immediately open the pipe U:\PIPE\DRAGDROP.xx, where 'xx' is the 2
character identifier in the last word of the message. It then does
the following:

(1) Write a 1 byte DD_OK message to the pipe.

(2) Write a 32 byte list of 8 preferred data types (see above).
This list can be used by the originator as a guideline, but is not
binding. The list should be padded with 0 bytes; in the extreme
case (if the application has no preferences) it may be entirely
zeros.

(3) Read a 2 byte message header length (n) from the pipe.

(4) Read n bytes from the pipe. This header is described above, and
contains the data type, data size, and a user defined name for the
data (the name may be empty).

(5) Check the data type. If the data type is NOT one that the
application can understand, it should write a 1 byte DD_EXT message
to the pipe and wait for another header, i.e. go back to step (3).

(6) Check the data size. If the recipient can't handle so much
data, it should write a 1 byte DD_LEN message to the pipe and go
back to step (2).

(7) Write a 1 byte DD_OK message to the pipe to tell the originator
to start sending data.

(8) Read S bytes from the pipe, where S is the size of the data as
specified in the message header. EXCEPTION: if the data type is
"PATH" and the recipient wishes to respond, it should actually
*write* S (or fewer) bytes to the pipe. Those bytes should specify
the full GEMDOS path name associated with the window (terminated by
a backslash, \) or the full GEMDOS path+file name associated with
the window.

(9) Fclose the pipe.

When both originator and recipient have closed the pipe, it will
automatically be deleted by the kernel (this is MiNT's normal
action for pipes).

The recipient must always check each read for an error condition or
end of file; if either of these is detected, the originator of the
drag and drop has aborted the transaction. If the recipient wishes
to abort the transaction, it should send DD_NAK as a reply in place
of DD_OK.


@endnode


@node "Caveats"

Drag & drop protocol: Caveats

Applications involved in a drag and drop exchange should take care
to avoid deadlocks or fatal signals. To this end, the following
actions are recommended:

(1) The drag & drop pipe should be created with the "hidden" bit
set. This causes reads to return end of file when the other end of
the pipe is closed.

(2) The applications should ignore the SIGPIPE signal (number 13)
during the exchange. SIGPIPE is generated when an application
writes to a pipe with no readers, and the default action for this
signal is to terminate the application.

(3) Neither application should do a wind_update() call during the
exchange.


@endnode


@node "Sample code"

Drag & drop protocol: Sample code

/*
 * Header file for using the drag & drop
 * protocol.
 * Copyright 1992,1993 Atari Corporation.
 */

#define AP_DRAGDROP     63

#define DD_OK           0
#define DD_NAK          1
#define DD_EXT          2
#define DD_LEN          3
#define DD_TRASH        4
#define DD_PRINTER      5
#define DD_CLIPBOARD    6

/* timeout in milliseconds */
#define DD_TIMEOUT      4000

/* number of bytes of "preferred
 * extensions" sent by receipient during
 * open
 */
#define DD_NUMEXTS      8
#define DD_EXTSIZE      32L

/* max size of a drag&drop item name */
#define DD_NAMEMAX      128

/* max length of a drag&drop header */
#define DD_HDRMAX       (8+DD_NAMEMAX)

#ifndef Word
#define Word short
#define Long long
#endif

/*
 * Drag & drop sample code.
 * Copyright 1992 Atari Corporation
 *
 * global variables used:
 * gl_apid: our AES application id
 *
 * BUGS/CAVEATS:
 * This code is not re-entrant (it uses a static
 * variable for the pipe name and for saving the
 * SIGPIPE signal handler).
 *
 * While doing the drag and drop, the SIGPIPE
 * signal (write on an empty pipe) is ignored
 */

#include <osbind.h>
#include <mintbind.h>
#include <string.h>
#include <gemdefs.h>
#include <aesbind.h>
#include <vdibind.h>
#include "dragdrop.h"

#ifndef EACCDN
#define EACCDN -36
#endif

#ifndef SIGPIPE
#define SIGPIPE 13
#endif

#ifndef SIG_IGN
#define SIG_IGN 1L
#endif

#ifndef WF_OWNER
#define WF_OWNER 20
#endif

#ifndef FA_HIDDEN
#define FA_HIDDEN 0x2
#endif

extern int gl_apid;

static char pipename[] = "U:\\PIPE\\DRAGDROP.AA";
static long oldpipesig;

#ifdef DEBUGGING
#define debug_alert(x, y) form_alert(x, y)
#else
#define debug_alert(x, y)
#endif

/* Code for originator */

/*
 * create a pipe for doing the drag & drop,
 * and send an AES message to the recipient
 * application telling it about the drag & drop
 * operation.
 *
 * Input Parameters:
 * apid:        AES id of the window owner
 * winid:       target window (0 for background)
 * msx, msy:    mouse X and Y position
 *              (or -1, -1 if a fake drag & drop)
 * kstate:      shift key state at time of event
 *
 * Output Parameters:
 * exts:        A 32 byte buffer into which the
 *              receipient's 8 favorite
 *              extensions will be copied.
 *
 * Returns:
 * A positive file descriptor (of the opened
 * drag & drop pipe) on success.
 * -1 if the receipient doesn't respond or
 *    returns DD_NAK
 * -2 if appl_write fails
 */

int
ddcreate(apid, winid, msx, msy, kstate, exts)
        int apid, winid, msx, msy, kstate;
        char exts[];
{
        int fd, i;
        int msg[8];
        long fd_mask;
        char c;

        pipename[17] = pipename[18] = 'A';
        fd = -1;
        do {
                pipename[18]++;
                if (pipename[18] > 'Z') {
                        pipename[17]++;
                        if (pipename[17] > 'Z')
                                break;
                }
/* FA_HIDDEN means "get EOF if nobody has pipe open for reading" */
                fd = Fcreate(pipename, FA_HIDDEN);
        } while (fd == EACCDN);

        if (fd < 0) {
                debug_alert(1, "[1][Fcreate error][OK]");
                return fd;
        }

/* construct and send the AES message */
        msg[0] = AP_DRAGDROP;
        msg[1] = gl_apid;
        msg[2] = 0;
        msg[3] = winid;
        msg[4] = msx;
        msg[5] = msy;
        msg[6] = kstate;
        msg[7] = (pipename[17] << 8) | pipename[18];
        i = appl_write(apid, 16, msg);
        if (i == 0) {
                debug_alert(1, "[1][appl_write error][OK]");
                Fclose(fd);
                return -2;
        }

/* now wait for a response */
        fd_mask = 1L << fd;
        i = Fselect(DD_TIMEOUT, &fd_mask, 0L, 0L);
        if (!i || !fd_mask) {   /* timeout happened */
                debug_alert(1, "[1][ddcreate: Fselect timeout][OK]");
abort_dd:
                Fclose(fd);
                return -1;
        }

/* read the 1 byte response */
        i = Fread(fd, 1L, &c);
        if (i != 1 || c != DD_OK) {
                if (i != 1)
                        debug_alert(1, "[1][ddcreate: read error][OK]");
                else
                        debug_alert(1, "[1][ddcreate: DD_NAK][OK]");
                goto abort_dd;
        }

/* now read the "preferred extensions" */
        i = Fread(fd, DD_EXTSIZE, exts);
        if (i != DD_EXTSIZE) {
                debug_alert(1, "[1][Error reading extensions][OK]");
                goto abort_dd;
        }

        oldpipesig = Psignal(SIGPIPE, SIG_IGN);
        return fd;
}

/*
 * see if the recipient is willing to accept a certain
 * type of data (as indicated by "ext")
 *
 * Input parameters:
 * fd           file descriptor returned from ddcreate()
 * ext          pointer to the 4 byte file type
 * name         pointer to the name of the data
 * size         number of bytes of data that will be sent
 *
 * Output parameters: none
 *
 * Returns:
 * DD_OK        if the receiver will accept the data
 * DD_EXT       if the receiver doesn't like the data type
 * DD_LEN       if the receiver doesn't like the data size
 * DD_NAK       if the receiver aborts
 */

int
ddstry(fd, ext, name, size)
        int fd;
        char *ext, *name;
        long size;
{
        Word hdrlen, i;
        char c;

/* 4 bytes for extension, 4 bytes for size, 1 byte for
 * trailing 0
 */
        hdrlen = 9 + strlen(name);
        i = Fwrite(fd, 2L, &hdrlen);

/* now send the header */
        if (i != 2) return DD_NAK;
        i = Fwrite(fd, 4L, ext);
        i += Fwrite(fd, 4L, &size);
        i += Fwrite(fd, (long)strlen(name)+1, name);
        if (i != hdrlen) return DD_NAK;

/* wait for a reply */
        i = Fread(fd, 1L, &c);
        if (i != 1) return DD_NAK;
        return c;
}

/* Code for either recipient or originator */

/*
 * close a drag & drop operation
 */

void
ddclose(fd)
        int fd;
{
        (void)Psignal(SIGPIPE, oldpipesig);
        (void)Fclose(fd);
}

@{0B}
@{0B}/* Code for recipient */
@{0B}@{0}

/*
 * open a drag & drop pipe
 *
 * Input Parameters:
 * ddnam:       the pipe's name (from the last word of
 *              the AES message)
 * preferext:   a list of DD_NUMEXTS 4 byte extensions we understand
 *              these should be listed in order of preference
 *              if we like fewer than DD_NUMEXTS extensions, the
 *              list should be padded with 0s
 *
 * Output Parameters: none
 *
 * Returns:
 * A (positive) file handle for the drag & drop pipe, on success
 * -1 if the drag & drop is aborted
 * A negative error number if an error occurs while opening the
 * pipe.
 */

int
ddopen(ddnam,preferext)
        int ddnam;
        char *preferext;
{
        int fd;
        char outbuf[DD_EXTSIZE+1];

        pipename[18] = ddnam & 0x00ff;
        pipename[17] = (ddnam & 0xff00) >> 8;

        fd = Fopen(pipename, 2);
        if (fd < 0) return fd;

        outbuf[0] = DD_OK;
        strncpy(outbuf+1, preferext, DD_EXTSIZE);

        oldpipesig = Psignal(SIGPIPE, SIG_IGN);

        if (Fwrite(fd, (long)DD_EXTSIZE+1, outbuf) != DD_EXTSIZE+1) {
                ddclose(fd);
                return -1;
        }

        return fd;
}

/*
 * ddrtry: get the next header from the drag & drop originator
 *
 * Input Parameters:
 * fd:          the pipe handle returned from ddopen()
 *
 * Output Parameters:
 * name:        a pointer to the name of the drag & drop item
 *              (note: this area must be at least DD_NAMEMAX bytes long)
 * whichext:    a pointer to the 4 byte extension
 * size:        a pointer to the size of the data
 *
 * Returns:
 * 0 on success
 * -1 if the originator aborts the transfer
 *
 * Note: it is the caller's responsibility to actually
 * send the DD_OK byte to start the transfer, or to
 * send a DD_NAK, DD_EXT, or DD_LEN reply with ddreply().
 */

int
ddrtry(fd, name, whichext, size)
        int fd;
        char *name;
        long *size;
        char *whichext;
{
        Word hdrlen;
        int i;
        char buf[80];

        i = Fread(fd, 2L, &hdrlen);
        if (i != 2) {
                return -1;
        }
        if (hdrlen < 9) {       /* this should never happen */
                return -1;
        }
        i = Fread(fd, 4L, whichext);
        if (i != 4) {
                return -1;
        }
        whichext[4] = 0;
        i = Fread(fd, 4L, size);
        if (i != 4) {
                return -1;
        }
        hdrlen -= 8;
        if (hdrlen > DD_NAMEMAX)
                i = DD_NAMEMAX;
        else
                i = hdrlen;
        if (Fread(fd, (long)i, name) != i) {
                return -1;
        }
        hdrlen -= i;

/* skip any extra header */
        while (hdrlen > 80) {
                Fread(fd, 80L, buf);
                hdrlen -= 80;
        }
        if (hdrlen > 0)
                Fread(fd, (long)hdrlen, buf);

        return 0;
}

/*
 * send a 1 byte reply to the drag & drop originator
 *
 * Input Parameters:
 * fd:          file handle returned from ddopen()
 * ack:         byte to send (e.g. DD_OK)
 *
 * Output Parameters:
 * none
 *
 * Returns: 0 on success, -1 on failure
 * in the latter case the file descriptor is closed
 */

int
ddreply(fd, ack)
        int fd, ack;
{
        char c = ack;

        if (Fwrite(fd, 1L, &c) != 1L) {
                Fclose(fd);
        }
        return 0;
}

#if 0
/******************************************************************
 *      Here are some sample functions that use the               *
 *      drag & drop functions above to implement the protocol.    *
 *      These are not complete, working functions yet, but are    *
 *      intended to serve as a "skeleton" for the actual          *
 *      functions that would appear in a drag & drop application. *
 *                                                                *
 *      The following global variables are defined:               *
 *      gl_ourexts: the drag & drop data types we understand      *
 ******************************************************************/

/* modify this as necessary */
char gl_ourexts[DD_EXTSIZE] = "ARGS.RTF.TXT";

/*
 * rec_ddmsg: given a drag & drop message, act as
 * a recipient and get the data
 *
 * Input Parameters:
 * msg:         Pointer to the 16 byte AES message
 *              returned by evnt_multi or evnt_mesag
 *
 * calls the following functions to actually perform the paste
 * operation:
 *
 * parseargs(char cmdlin[]):
 *      Given a null terminated string of arguments, separated
 *      by spaces, parse it and perform whatever actions are
 *      appropriate on the arguments (usually file and folder
 *      names)
 *
 * paste_rtf(int win, int fd, long size):
 *      Read "size" bytes from the open file descriptor "fd",
 *      and paste it into the window whose handle is "win".
 *      The data is assumed to be in RTF format.
 *
 * paste_txt(int win, int fd, long size):
 *      Read "size" bytes from the open file descriptor "fd",
 *      and paste it into the window whose handle is "win".
 *      The data is assumed to be ASCII text.
 */

void
rec_ddmsg(msg)
        int msg[];
{
        int winid;
        int msx, msy, kstate;
        int fd, pnam;
        int i;
        char txtname[DD_NAMEMAX], ext[5];
        char *cmdline;
        long size;

        winid = msg[3];
        msx = msg[4];
        msy = msg[5];
        kstate = msg[6];
        pnam = msg[7];

        fd = ddopen(pnam, ourexts);
        if (fd < 0) return;

        for(;;) {
                i = ddrtry(fd, txtname, ext, &size);
                if (i < 0) {
                        ddclose(fd);
                        return;
                }
                if (!strncmp(ext, "ARGS", 4)) {
                        cmdline = malloc((size_t)size+1);
                        if (!cmdline) {
                                ddreply(fd, DD_LEN);
                                continue;
                        }
                        ddreply(fd, DD_OK);
                        Fread(fd, size, cmdline);
                        ddclose(fd);
                        cmdline[size] = 0;
                        parseargs(cmdline);
                        return;
                }
                else if (!strncmp(ext, ".RTF", 4) {
                        ddreply(fd, DD_OK);
                        paste_rtf(winid, fd, size);
                        ddclose(fd);
                        return;
                }
                else if (!strncmp(ext, ".TXT", 4) {
                        ddreply(fd, DD_OK);
                        paste_txt(winid, fd, size);
                        ddclose(fd);
                        return;
                }
                ddreply(fd, DD_EXT);
#ifdef DEBUGGING
                { char foo[40];
                strcpy(foo, "[1][rec_ddmsg: unknown extension: |");
                strcat(foo, ext);
                strcat(foo, "][OK]");
                debug_alert(1, foo);
                }
#endif /* DEBUGGING */
        }
}

/*
 * send_ddmsg: construct and send a drag & drop message;
 * we only can send the 1 type of data (specified
 * by ext)
 *
 * Input Parameters:
 * msx, msy:    coordinates where data was dropped
 * kstate:      keyboard state at time of drop
 * name:        name of the data
 * ext:         data type (4 byte extension)
 * size:        size of data
 * data:        pointer to data
 *
 * Output Parameters: none
 *
 * Returns:
 * 0 on success
 * 1 if no window was found
 * 2 if the window belongs to us
 * 3 if the receipient didn't accept the data
 * or a negative error code from the functions
 * above
 */

int
send_ddmsg(msx, msy, kstate, name, ext, size, data)
        int msx, msy, kstate;
        char *name, *ext;
        long size;
        char *data;
{
        int fd;
        int apid, winid;
        int dummy, i;
        char recexts[DD_EXTSIZE];
        extern int gl_apid;

        winid = wind_find(msx, msy);
        if (!winid) {
                debug_alert(1, "[1][Window not found][OK]");
                return 1;
        }
        if (!wind_get(winid, WF_OWNER, &apid, &dummy, &dummy, &dummy)) {
                debug_alert(1, "[1][Owner not found][OK]");
                return 2;
        }

        if (apid == gl_apid) {
                debug_alert(1, "[1][Same owner][OK]");
                return 1;       /* huh? that shouldn't happen */
        }

        fd = ddcreate(apid, winid, msx, msy, kstate, recexts);
        if (fd < 0) {
                debug_alert(1, "[1][Couldn't open pipe][OK]");
                return fd;
        }
        if ((i = ddstry(fd, ext, name, size)) != DD_OK) {
                if (i == DD_EXT) {
                        debug_alert(1, "[1][Bad extension][OK]");
                } else {
                        debug_alert(1, "[1][Receiver canceled][OK]");
                }
                ddclose(fd);
                return 3;
        }
        Fwrite(fd, size, data);
        ddclose(fd);
        return 0;
}
#endif /* 0 */


@endnode


@node "Discussion of AES environment variables"

Addendum: discussion of AES environment variables

    NAME            MEANING

    ACCPATH         A comma-separated list of directories which
                    will be searched for *.ACC at startup time.
                    When an accessory is found in a given
                    directory, that directory will be the
                    accessory's default directory when it starts.
                    The root directory of the boot device is always
                    searched in addition to any directories
                    appearing in ACCPATH.

    PATH            A comma-separated list of directories which
                    will be searched for programs when @{"shel_write" LINK "shel_write()"}
                    is called in mode 0, 1, or 3. See shel_write.
                    In addition, shel_find() and rsrc_load() will
                    look in all directories in this path when
                    searching for files.

    TOSEXT          A comma-separated list of extensions which are
                    to be considered "TOS programs." See shel_write.

    GEMEXT          A comma-separated list of extensions which are
                    to be considered "GEM programs." See @{"shel_write" LINK "shel_write()"}.

    ACCEXT          A comma-separated list of extensions which are
                    to be considered "accessories." See shel_write.


@endnode


@node "Discussion of GEM.CNF"

Addendum: Discussion of GEM.CNF

A file called GEM.CNF may appear in the root directory of the boot
device, or in a folder called "\MULTITOS".

It is a text file. Each line must begin in the first column. A
line beginning with a number sign ("#") is a comment. A command in
this file is separated from its argument with a single space.

The commands are:

        setenv <NAME=VALUE>

            This command places NAME=VALUE in the AES environment.

        run <program>

            This command causes AES to run the indicated program at
            boot time. The program is launched as a GEM program and
            is run concurrently, just as if you'd double-clicked it.

        shell <program>

            This command launches the indicated program, just like
            "run" does, but sets a flag inside AES which prevents
            it from launching the Desktop. You should use this
            command if you run a "desktop replacement" program and
            you don't want the Atari Desktop to appear.

        AE_SREDRAW=0

            The AES normally sends a full-screen redraw message
            when a GEM program starts up (calls @{"appl_init" LINK "appl_init()"}). If this
            command is in AES.CNF that message will not be sent.
            This will soon be an environment variable instead.

        AE_TREDRAW=0

            The AES normally sends a full-screen redraw message
            when a GEM program finishes (calls appl_exit). If this
            command is in AES.CNF that message will not be sent.
            This will soon be an environment variable instead.

EXAMPLES:

        setenv PATH=.,c:\bin,c:\gem
        setenv TOSEXT=TOS,TTP
        setenv GEMEXT=PRG,APP,GTP
        setenv ACCEXT=ACC
        setenv ACCPATH=c:\acc
        run c:\mint\clock.prg
        shell c:\mint\mw.prg
        AE_TREDRAW=0
        AE_SREDRAW=0

BUGS:

A program started with "run" or "shell" can't be given arguments.

The PATH doesn't get searched when a program is started with "run"
or "shell."


@endnode


@node "The _IDT cookie"

Addendum: the _IDT cookie

         IDT - International Day and Time Cookie         9/10/92

Beginning from AES 3.3 and up, the desktop will use the _IDT cookie to
determine how to set up the date and time format. The _IDT should look
like the following.

_IDT LONG WORD: HIGH WORD |         LOW WORD
                ------------------------------------------------
Bit Number:     31 - 16   |  15-12       11-8        7-0 bit
Meaning:        Reserved  |  Time        Date        Date Seperator
Value:                       0 12 hour   0 MM-DD-YY  ASCII value
                             1 24 hour   1 DD-MM-YY  (A zero value
                                         2 YY-MM-DD   equivalent to
                                         3 YY-DD-MM   '/')
The current default values are:

Country         Time    Date    Seperator
-----------------------------------------
USA             0       0       /
Germany         1       1       .
French          1       1       /
Spain           1       1       /
Italy           1       1       /
Sweden,Norway
Finland         1       2       -


@endnode


@node "Restriction on color icon data"

Object library enhancements: restriction on color icon data

Due to a bug found in the VDI, the seventh word in the color icon
data cannot contain 0x0001. The VDI looks at the wrong location to
see whether or not it should skip a transform form on the icon
data. The end result is that icons that have the seventh word of
data set to 0x0001 will be blitted in the wrong data format. For
those who are writing icon editors, a check on the data is
recommended to prevent this strange behavior.

Since this is a rather obscure occurence, icon designers should not
need to worry about this problem unless a particular icon does not
display correctly (i.e. the data is scrambled). If the icon is
incorrectly displayed, change the image so that the first sixteen
pixels on the fourth line contain different data, until the image
becomes unscrambled.


@endnode


@node "Color icon format"

Object library enhancements: color icon format

Color Icon Format (v.2.1)    Sept 8, 1992

The color icon feature is implemented in AES version 3.3 and up.

This document specifies the format for TOS color icons. The format
features the ability to take advantage of all resolutions and to
perform limited animation when an icon is selected. Below is a
description of the actual data structure. The structure itself and
how it is going to be used is explained in the description that
follows. At the end of this document, a file format for a color
icon resource file is outlined.

Data Structure:

typedef struct cicon_data
{
    int num_planes;  /* number of planes in the following data */
    int *col_data;   /* pointer to color bitmap in standard form */
    int *col_mask;   /* pointer to single plane mask of col_data */
    int *sel_data;   /* pointer to color bitmap of selected icon */
    int *sel_mask;   /* pointer to single plane mask of selected
                      * icon */
    struct cicon_data *next_res;  /* pointer to next icon for a
                                   *  different resolution */
} CICON;

typedef struct cicon_blk
{
    ICONBLK monoblk;        /* default monochrome icon */
    CICON *mainlist;        /* list of color icons for
                             * different resolutions */
} CICONBLK;

#define G_CICON    33             /* object type number for AES */

Description:

The AES Object Library uses the CICONBLK structure to hold the data
that defines color icons. The object type G_CICON points with its
ob_spec pointer to a CICONBLK structure.

CICONBLK is a color icon block; a color icon block contains a
monochrome icon block and a list of color icons. The list,
mainlist, is a linked list of color icons that supports different
resolutions. The monochrome icon block, monoblk, is the default
icon displayed when mainlist does not contain an icon for the
current resolution. Furthermore, the monochrome icon and all of the
color icons in mainlist share the dimensions, placement, and all
textual information contained in monoblk.

CICON is the structure that contains the color data. A CICON can
contain pointers to two sets of icon data: one for the color icon,
col_data, and one for the color icon inits selected state,
sel_data. In both cases, the data is an array of words, and is
indevice-independent format. The number of planes of data is
determined by num_planes (Note: in mainlist, CICON's must have an
unique num_planes). Each CICON must have a valid pointer to data in
col_data, but sel_data is optional. In other words, if sel_data is
NULL, then when the icon is selected, the icon will be drawn
darkened (i.e. dithered). Both col_data and sel_data pointers have
masks: col_mask and sel_mask, respectively. Any other CICON's (with
a different number of planes) are pointed to by next_res.

See also Extended RSC file format


@endnode


@node "Three dimensional objects"

Object library enhancements: 3d effects

         Three Dimensional Objects                       1/21/93

Three dimensional objects are implemented in AES version 3.4 and
up.

Defines:

#define FL3DMASK        0x0600
#define     FL3DNONE            0x0000
#define     FL3DIND             0x0200
#define     FL3DBAK             0x0400
#define     FL3DACT             0x0600

#define LK3DIND         1
#define LK3DACT         2
#define INDBUTCOL       3
#define ACTBUTCOL       4
#define BACKGRCOL       5
#define AD3DVALUE       6

Description:

The AES uses 2 new bits in the ob_flags field of objects to
indicate what kindof 3D shading effects (if any) should be used on
the object. These are bits 9 and 10 of ob_flags.

If both bits are clear (FL3DNONE) then no 3D shading effects are
applied to the object.

If (ob_flags & FL3DMASK) is FL3DIND, then the object is an
"indicator." Typically indicators are used in dialog boxes to
indicate some sort of state; for example, whether an option is "on"
or "off." Radio buttons should always be indicators.

If (ob_flags & FL3DMASK) is FL3DACT, then the object is an
"activator." Activators don't have a persistent state, but rather
are usually controls of some sort. For example, the "OK" and
"Cancel" buttons in dialog boxes should be activators.

If (ob_flags & FL3DMASK) is FL3DBAK, then the object is a
"background" object. Background objects are usually not selectable,
and do not typically display 3D effects other than inheriting the
"3D background object" color (see below); the only 3D effects
applied to background objects is that "outlined" background objects
appear to be raised above the objects behind them, and
disabled background objects are "shaded out" in the background 3D
color instead of with a white dither pattern.

The colors (and effects, for indicators and activators) of 3D
objects may be controlled by the @{"objc_sysvar" LINK "objc_sysvar()"} function. Any 3D
object which is color 0 (white) and has a hollow fill pattern will
be drawn in the 3D default color set for its object type, instead
of in white. 3D objects which are not white or which have a
non-hollow fill pattern will be drawn in the color and pattern
specified, as usual.


@endnode


@node "objc_sysvar()"

Object library enhancements: objc_sysvar()

6.4.9   OBJC_SYSVAR

Purpose:

Allows an application to set or inquire the colors and effects for
3D objects. Applications should not change 3D colors or effects
except at the explicit request of the user, because all such
changes are global (i.e. they affect all processes).

Parameters:

     control(0)  =  48
     control(1)  =  4
     control(2)  =  3
     control(3)  =  0
     control(4)  =  0

     int_in(0)   =  ob_smode
     int_in(1)   =  ob_swhich
     int_in(2)   =  ob_sival1
     int_in(3)   =  ob_sival2

     int_out(0)  =  ob_sreturn
     int_out(1)  =  ob_soval1
     int_out(2)  =  ob_soval2


o    ob_smode - whether the call is to get or set attributes

     0  Inquire (get) attributes

     1  Set attributes

o    ob_swhich - which attributes are being set or inquired; this
                 also affects the meaning of the other values,
                 as follows:

     LK3DIND  Get/set attributes for indicator objects. If ob_smode
              is 0, then ob_soval1 indicates whether the text of
              indicator objects does (1) or does not (0) move when
              the object is selected, and ob_soval2 indicates
              whether the object does (1) or does not (0) change
              color when selected. If ob_smode is 1, then ob_sival1
              controls whether indicator object text will (1) or
              will not (0) move when the object is selected, and
              ob_sival2 controls whether indicator objects will (1)
              or will not (0) change color when selected. The
              default is ob_sival1 = 1 andob_sival2 = 0.

     LK3DACT  Get/set attributes for activator objects. The
              meanings of ob_soval1, ob_soval2, ob_sival1, and
              ob_sival2 are the same as for LK3DIND, except that
              they apply to activator objects rather than indicator
              objects. The defaults for activator objects is
              ob_sival1 = 0 and ob_sival1 = 1.

     INDBUTCOL Get/set default color for indicator objects. This is
               the color which hollow, white indicator objects
               (e.g. buttons) will be drawn in instead of white. If
               ob_smode is 0, then ob_soval1 is the current color
               index of the default indicator object color. If
               ob_smode is 1, then ob_sival1 is the new color index
               for indicator objects.

     ACTBUTCOL Get/set default color for activator objects. Same
               as INDBUTCOL, but applies to activators rather than
               indicators.

     BACKGRCOL Get/set default color for 3D background objects.
               Same asINDBUTCOL, but applies only to 3D background
               objects.

     AD3DVALUE Get pixel adjustments for 3D indicators and
               activators. ob_smode must be 0. ob_soval1 is set to
               the number of pixels by which 3D indicators and
               activators are expanded on each side horizontally
               (to accomodate 3D effects), and ob_soval2 is the
               number of pixels by which they are expanded
               vertically. Remember that this adjustment is applied
               to each side of the object, so the objects width or
               height is increased by twice this amount. Background
               3D objects never change in size.

o    ob_sreturn - a coded return message

     0 - FAILURE: an illegal value has been given for ob_swhich or
                  for ob_smode

     >0 - SUCCESS: the objc_sysvar call succeeded

     ------------------------------------------------

     Sample call to C language binding:

     ob_return = objc_sysvar(word ob_smode, word ob_swhich,
                             word ob_sival1, word ob_soval1,
                             word *ob_soval1, word *ob_soval2);


@endnode


@node "New predefined AES messages"

Event library enhancements: new AES messages

     The following are the new predefined system messages
     implemented in the new AES:


     1, WM_UNTOPPED - 30        Version 3.3 and up

        word 0 - 30
        word 3 - window handle

        This message is sent when the current top window is being
        untopped by other window.

        The application doesn't need to take any action. This
        message is for your information only.

        By the time this message is received by the owner of the
        formerly-topped window, that window is not likely to be on
        top.

     2, WM_ONTOP - 31           Version 3.3 and up

        word 0 - 31
        word 3 - window handle

        This message is sent when the application's window is
        placed on top, generally through no action of its own (i.e.
        another window is closed). The application does not have to
        take any action.

        Note: Since a lot of window events can happen between the
              time the window managers send out this message and
              the time the application actually receives the
              message, the window in question may not actually be
              on top any more.

     3, AP_TERM - 50       Request to terminate the current process
                           Version 4.0 and up

        word 0 - 50
        word 5 - Code identifying the reason of shuting down

        This message is sent when the system requests that the
        application terminate. This occurs, for instance, when the
        user requests a resolution change. The response to this
        message should be to close windows, shut down, and
        terminate.

        This message is sent when the system or other applications
        request the target process (application or accessory) to
        terminate (exit). This may due to a resolution change or
        simply the other application wants to take over the system.

        Upon receiving this message and if the process decides to
        terminate itself, it should proceed with the normal
        termination sequences like closing all its windows, freeing
        the resources, free the menu etc.

        However, process must inform the system if it chooses not
        to terminate or it has error that prevents it from
        terminating itself. Use @{"shel_write" LINK "shel_write()"} mode 10 to inform the
        AES if such situation should arise.

        From the caller point of view:

            The caller should check the return code to see if the
            request is granted or denied.

            If everything is OK, then caller should go back to its
            evnt_multi loop to wait for message SHUT_COMPLETED.
            This message will only be sent to the caller once. The
            message structure is defined as below:

            word[0] = SHUT_COMPLETED  (60)
            word[3] = 1 - Shut down is succeeful,
                      0 - Shut down failed.

            If there is an error i.e. word[3] is zero, then word[4]
            will contain the AES id of the process that has error
            and word[5] is the actual error code from that process.
            Otherwise, if the whole shutdown process is
            succcessful, the caller itself may choose to or not to
            exit the system depending on its initial purpose of
            calling this function.

            From the receiver point of view:

            Application will receive AP_TERM message and accessory
            will receive the AC_CLOSE during the shutdown. If is is
            a complete shut down, the accessory will also receive
            AP_TERM message.

            The message structure is defined as below:

            word[0] = AP_TERM or AC_CLOSE
            word[5] = Reason for shutting down.

                      For example:

                      AP_TERM for just shutting down
                      AP_RESCHG for changing resolution

            If receiver choose not to comply with the request, it
            should send a AP_TFAIL message to AES by using the
            @{"shel_write" LINK "shel_write()"}(10, ...)

            See also AP_TFAIL message.

     4, AP_TFAIL - 51        Fail to terminate or close.
                             Version 4.0 and up

        This message is sent when the receiver of AP_TERM or
        AC_CLOSE message decides not to close or terminate or it
        just has problem somewhere and and would like to inform AES
        about the problem.

        The message structure should look like:

        word[0] = AP_TFAIL (51)
        word[1] = Your error code

        This message should be sent by using @{"shel_write" LINK "shel_write()"}(10 ...).

     5, AP_RESCHG - 57       Code identifying reason to terminate
                             or close. Version 4.0 and up.

        This message is used in conjunction with AP_TERM message.

     6, SHUT_COMPLETED - 60     Version 4.0 and up

        This message is sent to the initial caller of shuting down.
        Please read also AP_TERM above.

     7, RESCH_COMPLETED - 61  Message from AES to report the
                              resolution change condition. Version
                              4.0 and up

        This message is sent to the caller who request the AES to
        do resolution change. When a process requests to do a
        resolution change and the request is granted. It should
        wait on this message from the AES.

        The message structure is defined as follow:

        word[0] = RESCH_COMPLETED
        word[3] = 1 for no error, 0 for error

        If there is no error, the caller must exit the system in
        order to complete the resolution change process.

     8, AP_DRAGDROP - 63              Version 4.0 and up

        word[0] = AP_DRAGDROP
        word[1] = sender's id
        word[3] = window, or -1 for a request for a new window
        word[4] = mouse x
        word[5] = mouse y
        word[6] = keyboard state
        word[7] = pipe name

        This message is sent by the desktop (or any other
        application) to another application in order to inform that
        application that the user has dragged an object to one of
        its windows, or that the user wishes it to open a new
        window. See the @{"drag and drop protocol specification" LINK "Drag and drop protocol"} for
        more details on how the two applications negotiate the
        exchange of data.

     9, SH_WDRAW - 72                         Version 4.0 and up

        word[0] = SH_WDRAW
        word[3] = drive affected

        This message is sent by applications to the desktop to
        inform it that it should update its windows for a certain
        drive. word[3] indicates which drive: 0 for drive A:, 1 for
        drive B:, and so on. If word[3] is -1, then the desktop
        will update all of its windows. This message is useful an
        application that is doing file copying or deleting in the
        background. After the application has modified files on a
        drive, it should inform the desktop so that the user can
        see the correct information in his windows.

     10, CH_EXIT - 80                          Version 4.0 and up

        word[0] = CH_EXIT
        word[3] = Child process's AES id
        word[4] = Child's exit code

        This message is sent back to the process when its child
        process is terminated.

        Note: Process created by using the @{"shel_write" LINK "shel_write()"} call will be
              chilren of the AES. AES remembers what process called
              shel_write and sends that process CH_EXIT to the
              caller when the process exits.


@endnode


@node "Supplement for wind_get() and wind_set()"

Window library enhancements: wind_get()/wind_set()

     6/23/92

     The window redraw message has been greatly optimized. The
     changes are in the WM_TOP and WM_SIZE of the window messages.
     For WM_TOP, there will be no redraw message to follow if the
     window is not being covered, otherwise, the covered areas will
     be merged to form a big redraw rectangle in the next WM_REDRAW
     message.

     For WM_SIZE, no redraw message will be sent if the window is
     sized from big to small and the x and y coordinates remain the
     same, otherwise, redraw message will be sent.

   11.3.5  WIND_GET / WIND_SET

     wi_gfield - A numerical value describing the wind_get operation

     WF_TOP - 10        Version 3.3 and up

          Returns handle in wi_gw1, owner's AES id in wi_gw2
          and the handle of the window below it in wi_gw3

     WF_NEWDESK - 14    Version 3.3 and up

          Get the current system background window's object
          pointer. The value is returned in wi_gw1 and wi_gw2.

     WF_COLOR - 18      Version 3.3 and up      changed 7/8/92

          Get the window's element color by handle. The value
          are returned in wi_wg2 and wi_wg3. See also WF_DCOLOR.

     WF_DCOLOR - 19     Version 3.3 and up      changed 7/8/92

          Get the default element color. The values are returned in
          wi_gw2 and wi_gw3.

      Note: The binding for wind_get for getting the window's color
           elements is as follows:

           wind_get( wi_handle, wi_field, &wi_gw1, &wi_gw2,
                                            &wi_gw3, &wi_gw4 );

           where wi_gw1 should contain the element number as an
           input, the output values will be placed in the wi_gw2
           and wi_gw3.

           The wi_gw1 value should be put in the intin[2].

     WF_OWNER - 20      Version 3.3 and up     changed 7/8/92

          Get the window owner's AES id, window open status.

          wi_gw1 returns AES id of the owner
          wi_gw2 returns if the window is opened (1)
                 or closed (0)
          wi_gw3 handle of the window above it
          wi_gw4 handle of the window below it

          Note: If the window is closed, the wi_gw3 and wi_gw4
                values will be meaningless.

     WF_BEVENT - 24     Version 3.31 and up     changed 7/8/92

            If you set bit zero of the WF_BEVENT attribute of a
            window to one, a button click in that window's work
            area will not cause a WM_TOPPED message to be sent to
            that window. Instead, the button click will satisfy
            evnt_button or the button-click option of an evnt_multi
            call.

            Example:

            To turn on this feature for a particular window, set
            bit 0 of wi_sw1 to 1.

            wind_set( wi_handle, WF_BEVENT, 0x0001, 0, 0, 0 );

            To turn off this feature for a particular window, set
            bit 0 of wi_sw1 to 0.

            wind_set( wi_handle, WF_BEVENT, 0x0000, 0, 0, 0 );

            To inquire the WF_BEVENT status of a particular window:

            wind_get( wi_handle, WF_BEVENT,
                                &wi_sw1,&wi_sw2,&wi_sw3,&wi_sw4);

            The return value is in the wi_sw1.

            Note:

            The rest of the bits and parameters are reserved for
            future improvement and they should all be zero!

      WF_BOTTOM - 25    Version 3.31 and up

            This function mode sets an already opened window to the
            bottom of the window stack (excluding the background
            window) and brings up next logical window to top.
            However, if the target window is only opened window in
            the system, this window will still remain on top and be
            active.

            Example:

            To set a particular window to the bottom.

            wind_set(wi_handle, WF_BOTTOM, 0, 0, 0, 0);

            To inquire the current bottom window handle.

            wind_get( wi_handle, WF_BOTTOM,
                                 &wi_sw1,&wi_sw2,&wi_sw3,&wi_sw4);

            The handle will return in the wi_sw1;


@endnode
