home *** CD-ROM | disk | FTP | other *** search
/ ST-Computer Leser 2002 January / STC_CD_01_2002.iso / SYSTEM / XAAES936 / DOCS / PROGRAMM.TXT < prev    next >
Text File  |  2001-05-22  |  18KB  |  390 lines

  1. XaAES - XaAES ain't AES
  2. ╜1995, Data Uncertain Software
  3. Written By Craig Graham.
  4. --
  5.  
  6.                         PROGRAMMERS DOCUMENTATION
  7.  
  8. This document is intended to give an overview of the underlying architecture
  9. of the XaAES GUI and details for XaAES specific programming.
  10.  
  11. NOTE: I should really move over to using sockets to speed things up instead of
  12. using pipes, but I'll have to write an installer to setup MiNT-net first
  13. (a worthy project....)
  14.  
  15. CONTENTS
  16.  
  17. 1. INTRODUCTION
  18. 2. ARCHITECTURE OF XAAES
  19. x. WIDGET HANDLERS
  20.  
  21. y. AES Extentions
  22.  
  23. 1) Introduction
  24. ----------------
  25.  
  26. After using MultiTOS, then AES4.1, I became frustrated at the lack of a decent
  27. GUI to use the real power of the MiNT kernal - X-Windows is all very
  28. well, but I cann't run GEM programs on it (and it's only black & white under
  29. MiNT). The W window system is ok but not widely used or available. The Mgr
  30. system (Bellcore Windows Manager) is seriously out of date (looks and feels
  31. rubbish), and again no GEM.
  32.  
  33. MultiTOS (even AES4.1) is too slow. Geneva didn't run with MiNT (and, having
  34. tried the new MiNT compatible version, I can say it wasn't very compatible
  35. - at least AES4.1 is quite stable, if a little slow). MagiC lives in a very
  36. fast, very small world all it's own (no networking support, few programs
  37. written to exploit it).
  38.  
  39. Firstly it is important to note that you can use & program XaAES without
  40. reading this - it provides a GEM compatible call interface via the
  41. standard GEM AES trap vector (trap 2).
  42.  
  43. More advanced programs can be produced using XaAES's non-blocking call
  44. interface which allows programs to make multiple calls without blocking
  45. to wait for replies from the AES.
  46.  
  47. Here's a few important general points about XaAES before we get technical:
  48.  
  49. o It works only with MiNT - the architecture was designed to use MiNT,
  50.   and so you must have it.
  51. o Being written especially for MiNT, it is a real MultiTasking GUI
  52.   that can run GEM programs, not a slow & unwieldy kludge like MultiTOS.
  53. o Groovy sculpted 3D interface.
  54. o Colour icon support for all machines.
  55. o No busy waiting in the AES.
  56. o Client-Server architecture.
  57. o The source is freely available. Anyone can change the code, if they send
  58.   patches to me with descriptions I'll included them into the next version.
  59.   In fact the whole point of this document is to give people enough info
  60.   to work on the code themselves.
  61. o Built with a 'real' C compiler (Lattice) not GNU
  62.   (in spite of the denisons of comp.sys.atari.st.tech and the gem-list
  63.   who wanted me to use GNU).
  64. o Extended fast interface for use by XaAES aware programs.
  65.   Extended call interface allows XaAES aware applications to make AES calls
  66.   without blocking to wait for replies they don't want, and to make multiple
  67.   AES calls (calls to the AES server are queued).
  68. o Works with NVDI (NOTE: NVDI must be loaded before XaAES in order to work,
  69.   otherwise strange things will happen).
  70.  
  71. 2) Architecture Of XaAES
  72. -------------------------
  73. XaAES is really three distinct comoponents:
  74.  
  75.  o XaAES GUI server. This is deals with all the windows & stuff. It uses the
  76.    existing VDI to produce it's graphics (and works fine with NVDI).
  77.    Most of the time the server is blocked reading from it's command pipe
  78.    - this means that unless it is actually doing something it doesn't use
  79.    any CPU time at all. The server runs completely in user mode, and so
  80.    can be pre-empted by MiNT at any time (unlike MultiTOS).
  81. o The GEM trap interface handler. This is actually part of the GUI server,
  82.    but it is run under the process id of the client (so I don't allow it
  83.    to access any of XaAES's data structures). It serves to serialise calls
  84.    to the AES, and drop them into a command pipe to the sercer. It then blocks
  85.    the client to wait for the AES server to service the command and reply.
  86.    This bit is quite dodgy as it makes OS calls from inside a trap
  87.    interupt, and I'm not altogether certain this was a legal thing to do.
  88.    It works, so it stays....
  89.    As of beta2, there has also been a direct call mechanism as well, which
  90.    allows certain functions to be called directly by the client in the way
  91.    normal GEM does, bypassing the command pipe altogether.
  92. o The 'moose.xdd' mouse device handler. This provides the mouse handling
  93.    services required by XaAES via a new MiNT device /dev/moose. This is
  94.    written in assembler (by James Cox), and although written especially
  95.    for XaAES, it is an independent program which could be used by other
  96.    applications as well as XaAES.
  97.  
  98. The XaAES GUI server manages the window system, and commumicates with the rest
  99. of the system via MiNT pipes. In order to run standard GEM programs, it also
  100. replaces the standard AES trap handler with a small routine that fields trapped
  101. calls and drops them into a server command pipe on behalf of the application
  102. (this is done transparently, the application see's it as being the ordinary
  103. GEM AES trap). This is slightly slower than accessing the command pipe
  104. directly, but is totally compatible with GEM.
  105.  
  106. 3) The XaAES Kernal
  107. ---------------------
  108.  
  109. The XaAES kernal consists of a small assembler routine to catch the TRAP#2
  110. vector, another small C routine in handler.c which provides the interface to
  111. the XaAES pipe based client/server AES for normal GEM applications.
  112.  
  113. 3.1) The Command Pipe Interface
  114. ---------------------------------
  115.  
  116. Most commands go via the clients private command pipe.
  117.  
  118. The server must first be introduced to the client however, so there is a
  119. shared command pipe '/pipe/XaAES.cmd', where appl_init() will drop an
  120. XA_NEW_CLIENT message.
  121.  
  122. The server then responds by creating a bi-directionial command/reply pipe for
  123. the application. The client then uses this to communicate with the AES server
  124. kernal. (NOTE: The server uses Fselect() on all the client command pipes.)
  125. When an AES trap occurs, the handler drops the pointer to the parameter block
  126. into its command pipe.
  127.  
  128. There are then 3 modes that the AES could have been called in.
  129.  
  130. If standard GEM emulation mode (trap2 entered with d0=0xc8) the handler then
  131. drops back into user mode and blocks whilst reading on the current process's
  132. reply pipe. This allows other processes to execute whilst XaAES is performing
  133. AES functions (the XaAES server runs wholely in user mode so its more MiNT-
  134. friendly than MultiTOS). The server writes back to the clients reply pipe with
  135. the reply when it has serviced the command - this unblocks the client which
  136. then returns from the exception.
  137.  
  138. If NOREPLY mode is used, the AES doesn't block the calling process to wait
  139. for a reply - and indeed, won't generate one.
  140.  
  141. If NOBLOCK mode is used, the AES doesn't block the calling process - but does
  142. place the result in the client's reply pipe. The client is then expected to
  143. handle it's own reply pipe. This allows multiple AES calls to be made without
  144. blocking a process, so an app could make all it's GEM initialisation calls
  145. at one go, then go on to do it's internal initialisation before coming back
  146. to see if the AES has serviced its requests (less blocking in the client,
  147. and better multitasking).
  148. The result will be a short with the low byte being one of:
  149.    XA_OK              - The op-code was supported & was executed
  150.    XA_UNIMPLEMENTED   - You may have used a valid op-code, but XaAES doesn't
  151.                         yet support it.
  152.    XA_ILLEGAL         - The op-code was invalid in the first place, or there
  153.                         was some other problem with the parameters....
  154.    XA_T_WAIT          - Re-select for a evnt_timer format timeout
  155.    XA_M_WAIT          - Re-select for a evnt_multi format timeout
  156.  
  157. For either XA_T_WAIT or XA_M_WAIT, the upper 3 bytes will contain a timeout
  158. value. This should be multiplied by 16 to get the timeout in milliseconds:
  159.  
  160. So, you would make the call then get the response using this method:
  161.       /* Do some GEM call here */
  162.       Fread(reply_pipe_handle,sizeof(short),&response);
  163.       timeout=response&0xfff0;
  164.       response&=0xf;
  165.       if ((response==XA_T_WAIT)||(response==XA_M_WAIT))
  166.       {
  167.          select_mask=1L<<reply_pipe_handle;
  168.          timeout=Fselect(timeout,&select_mask,NULL,NULL);
  169.          if (!timeout)
  170.             /* Command timed out */
  171.          else
  172.             /* Command didn't time out */
  173.       }
  174.  
  175. You can use NOBLOCK mode in conjunction with evnt_multi() to do nifty tricks
  176. like using Fselect() to wait for AES events and serial data, or perhaps listen
  177. to a socket, all at the same time......
  178.  
  179. NOTE: The reply pipe is opened on behalf of the client by appl_init(). The file
  180. handle can be found either by calling appl_pipe() from the XaAESLIB extention
  181. library, or from the application's global array at global[12].
  182.  
  183. The main kernal handler is in kernal.c : void kernal(void);
  184.  
  185. When an AES function packet is read from the command pipe, and the op-code is
  186. used to call an AES function handler routine via the Ktable[] array. A NULL
  187. in this array indicates an un-implemented function, otherwise it contains a
  188. pointer to an 'AES_function' type function. These functions are always of type:
  189.  
  190.    short XA_objc_draw(XA_CLIENT *client, AESPB *pb) { }
  191.  
  192. The pb parameter (obviously) always points to the AES parameter block for the
  193. call, and client is the internal structure of the client making the call.
  194. NOTE: In XaAES MiNTpid==AESid.
  195.  
  196. Details of a client can be found in the XA_CLIENT clients[];  array
  197. (index on clnt_pid).
  198.  
  199. The return value of a call is crucial - if the function returns TRUE (1) then
  200. the kernal will write to the clients reply pipe 'u:\pipe\XaClnt.<PID>' to
  201. unblock the process (in NOBLOCK or NOREPLY modes, the client won't have
  202. blocked anyway).
  203. If FALSE (0) is returned by the function, then the kernal leaves the client
  204. blocked - this is how functions like evnt_multi() block to wait for an event.
  205. The occurance of the event causes the value to be written to the reply pipe to
  206. unblock the client.
  207.  
  208. x) Widget Handlers
  209. -------------------
  210. XaAES uses callback functions to handle all window widgets. These are refered
  211. to as 'behaviours'. Each widget has 4 behaviours - CLICK, DCLICK, DRAG &
  212. DISPLAY. These are held in an XA_WIDGET structure (see the file XA_TYPES.H).
  213. Each window has a set of these structures associated with it. The advantage
  214. of this is that the behaviour of a widget can be modified on a window by
  215. window basis (how it's displayed, what happens when it's clicked on, etc).
  216.  
  217. CLICK  - called whenever the user single clicks on the widget
  218. DCLICK - called when the user double clicks on the widget
  219. DRAG   - called with the mouse button down when the user clicks and holds the
  220.          button down on the widget
  221. DISPLAY- called to display the widget whenever the window is redrawn or the
  222.          status of the widget changes. XaAES will set up appropriate clip
  223.          rectangles before calling this behaviour, so all it has to do is draw
  224.          the thing - taking into account the status of the widget (selected,
  225.          etc).
  226.  
  227. Not all widgets will need all the behaviours. For example, the standard GEM
  228. closer widget has only CLICK and DISPLAY behaviours, you cann't drag the
  229. closer and a double click does nothing, so they are left as NULL to signify
  230. that they aren't valid.
  231.  
  232. GENERAL PRINCIPLE: If a widget isn't to behave in a certain way, set that
  233. behaviour to NULL.
  234.  
  235. A widget handler is passed two parameters when it is called :
  236.    XA_WINDOW *wind   - the window which the widget is a part of
  237.    XA_WIDGET *widg - the widget descriptor
  238.  
  239. These contain all the info a widget needs.
  240.  
  241. /* Widget positions are defined as relative locations */
  242. typedef struct
  243. {
  244.     XA_RELATIVE relative_type;    /* Where is the position relative to? */
  245.     RECT r;                        /* Position */
  246. } XA_WIDGET_LOCATION;
  247.  
  248. The handler itself should be of this type:
  249.  
  250.    typedef short WidgetBehaviour(XA_WINDOW *wind, XA_WIDGET *widg);
  251.  
  252. The XA_WIDGET structure looks like this:
  253.  
  254.     typedef struct xa_widget
  255.     {
  256.         XA_WIDGET_LOCATION loc;            /* Location of widget relative to window extents */
  257.         WidgetBehaviour *behaviour[COUNT_XACB];    /* Callback function pointers to the behaviours of the widget */
  258.         OB_STATES stat;                    /* Current status (selected, etc) */
  259.         XA_WIDGETS type;                /* HR: For convenience, makes it possible to dusconnect type from index */
  260.         short mask;                        /* HR: disconnect NAME|SMALLER etc from emumerated type XA_WIDGETS */
  261.         short click_x, click_y;            /* If we are displaying because we've been clicked on, this is the location  */
  262.                                         /* of the click (this is only used by the slider widget really) */
  263.         short rsc_index,            /* HR: If a bitmap widget, index in rsc file */
  264.               arrowx,                /* HR: WM_ARROWED msg type */
  265.               limit,                /* HR: on which limit to stop */ 
  266.               slider_type;            /* HR: which slider should move for scroll widget */
  267.         void *stuff;                /* Pointer to widget dependant context data, if any */
  268.         short start;                /* HR: If stuff is a OBJECT tree, we want start drawing here */
  269.     } XA_WIDGET;
  270.  
  271. The behaviour[] array contains pointers to all the behaviours for the widget.
  272.  
  273. loc.r.w & loc.r.h define the size of the widget - used to detect mouse events on the
  274. widget. When a mouse event occurs, the click_x & click_y values are filled in
  275. with the location of the click event prior to calling the widget handler.
  276.  
  277. All widgets have relative locations like X-Windows widgets (attribute 'loc').
  278. This is useful, as you can specify a widget as (RB, 1, 1) and it will always
  279. be displayed starting with it's coords in the bottom-right of the window.
  280. Possible relative coords are:
  281.  
  282.    LT : top left
  283.    CT : centred top (y relative to top, x recalculated to be window width / 2)
  284.    RT : top right
  285.    LB : bottom left
  286.    CB : centred bottom
  287.    RB : bottom right
  288.  
  289. An example use of this is the SIZER widget, which always keeps the same
  290. location relative to the bottom-right of the window, even when the window
  291. moves & changes size.
  292. The utility routine
  293.  
  294.    void rp_2_ap(XA_WINDOW *wind, XA_WIDGET *widg, RECT *r);
  295.  
  296. changes relative coords into absolute screen coordinates (returned in r.x & r.y).
  297.  
  298. When displaying, a widget should check it's state attribute 'stat' (normally
  299. XAW_PLAIN). If this is set to XAW_SELECTED then the widget should display
  300. itself in some 'selected' form - anything will do, just invert it like
  301. old GEM, or do a 3D push like AES4, maybe do some little animations like
  302. my default widget set does.
  303.  
  304. The final element of the XA_WIDGET structure is void *stuff; this is provided
  305. so certain widgets can have extra information kept with them - the scroll bars
  306. for instance keep a pointer to an XA_SLIDER_WIDGET structure here to maintain
  307. their size & position information.
  308.  
  309. It is intended that a user program in the know will be able to change the
  310. default behaviours of it's own window widgets, so a desktop could change
  311. the CLICK behaviour of the close widget for directory windows to make the
  312. window go back up a level instead of sending a WM_CLOSED, and perhaps display
  313. as a << arrow instead of a closer box.
  314.  
  315. User programs can also add their own custom widgets to a window, and they will
  316. behave in exactly the same way as the standard GEM widgets (the same behaviour
  317. based system).
  318.  
  319. Widgets should be informative and 'nice', so the XaAES versions of the
  320. standard GEM widgets (CLOSE, RESIZE, etc) are implemented as colour bitmaps
  321. (designed using Interface - get it it's cool) with seperate 'selected'
  322. images.
  323.  
  324. y. AES EXTENSIONS
  325. -------------------
  326. XaAES provides several extensions to the standard AES that provide more
  327. features. This section details exactly what these features are.
  328. Where possible, I've tied up with the oAESis authors to get support for these
  329. features in two AES's.
  330.  
  331. The file XAAESLIB.H provides bindings for the extended functions.
  332.  
  333. y.0 wind_get()
  334. --------------
  335. short XA_version;
  336. wind_get(0,'XA',&XA_version) will return 'XA' and writes its version number
  337. to XA_version. N.B.! The version no of XaAES, not the AES version!
  338. ie: 0x0912
  339.  
  340. XaAES doesnt install a cookie.
  341. I want to make an end to this awfull concept.
  342.  
  343. So this way you can detect XaAES.
  344. The idee is adopted from Martin Osieka's WINX, which returns 'WX'
  345. for wind_get(0,'WX')
  346.  
  347. y.1 appl_init()
  348. ----------------
  349. The file handle of the clients command/reply pipe is available in global[12].
  350.  
  351. y.2 shel_write()
  352. -----------------
  353. We've extended shel_write() to support the concept of a multi-user system
  354. provided by MiNT.
  355.  
  356. When a program uses shel_write to launch a child, the default behaviour
  357. (under XaAES) is that the 'AES child' inherits the user id & group id of the
  358. process that launched it.
  359.  
  360. An extension to the AES4.0 shel_write() mode 0 is provided in the form of:
  361.  
  362.    #define SW_UID 0x1000   /* Set user id of launched child */
  363.    #define SW_GID 0x2000   /* Set group id of launched child */
  364.  
  365.    typedef struct _xshelw {
  366.       char *newcmd;
  367.       LONG psetlimit;
  368.       LONG prenice;
  369.       char *defdir;
  370.       char *env;
  371.       short uid;            /* New child's UID */
  372.       short gid;            /* New child's GID */
  373.    } XSHELW;
  374.  
  375. This is used in the same way as the AES4.0 SHELW structure and is compatible
  376. - using the extended structure won't kill AES4.0, the UID/GID fields will
  377. simply be ignored.
  378. The extra fields uid & gid allow you to explicitly set the child's user &
  379. group id.
  380.  
  381. NOTE: This was agreed with the authors of Geneva and oAESis as well as XaAES...
  382.  
  383. y.3 evnt_multi()
  384. ----------------
  385. Event mask MU_MX ia available.
  386. #define MU_MX 0x0100
  387.  
  388. It reports any mouse movement, no need for a rectangle.
  389. It can be used in conjunction with MU_M1/2
  390.