@tabsize 4

@node XaAES
@subject "AES extensions in XaAES"


		                  Welcome to XaAES
		      A multitasking GEM replacement for MiNT

		This document descibes the AES functions or extensions
		   that are specific to XaAES and cannot be found in
		        any other AES. For all AES behaviour
		          please read the documentation on
		        those other AES's or the documentation
		        belonging to the standard Atari AES


		 XaAES adds functionality to the following functions:

		               wind_create  (menu bar)
		               wind_set     (menubar, toolbar and wheel)
		               wind_get     (detect XaAES)
		               evnt_multi   (wheel, toolbar,
		                             normalized keyboard events
		                             and extended arrowed)

		XaAES turns wheel events into WM_ARROWED events by default

		         related VDI function: vex_wheel_v

	       The new names and defines can be found in the header
	      np_aes.h which is part of the XaAES source distribution.


		              Greetings, Henk Robbers.
		                  march 10 2003

	                      Acknoledgment

@endnode

@node "wind_create"
@alias MENUBAR

	Change in the window attributes:

	New attribute:       MENUBAR
	bit number   :       12
	value        :       0x1000

	function     :       reserves room for a menu bar widget
	                     in the window.
	                     The menu_bar itself is attached to the
	                     window by wind_set

	note         :       The attribute replaces the unused
	                     HOTCLOSEBOX attribute.
                         There are only 16 bits available currently.

@endnode

@node "wind_get"

	wind_get

	New command:         'XA'

	Usage:

		short version;
		short have_XaAES = wind_get(0, 'XA', &version, 0L, 0L, 0L);

		The AES will return the value 'XA' if it is XaAES;
		If 'XA' is returned, version will have the XaAES version
		number.

		binding:
			cntrl[0]     : 104
			      1      : 2
			      2      : 5
			      3      : 0
			      4      : 0
			intin[0]     : window handle
			      1      : value 'XA'         /* 0x5841 */
			intout[0]    : reply
			       1     : version 
			               /* format: 0x0964 for version V0.964 */

@endnode

@node "wind_set"

	wind_set

	New command:         WF_MENU			value  33
	                     WF_WHEEL                  40
	Extended command:    WF_TOOLBAR                30

@endnode

@node "evnt_multi"

	Message identifier     :   WM_TOOLBAR
	New event masks        :   MU_WHEEL, MU_MX, MU_NORM_KEYBD,
	                           MU_DYNAMIC_KEYBD

	New arrow              :   WA_WHEEL
	value                  :   8

	New event mask         :   MU_WHEEL
	bit number             :   6
	value                  :   0x0040

	New event mask         :   MU_MX
	bit number             :   7
	value                  :   0x0080

	New event mask         :   MU_NORM_KEYBD
	bit number             :   8
	value                  :   0x0100

	New event mask         :   MU_DYNAMIC_KEYBD
	bit number             :   9
	value                  :   0x0200

@endnode

@node "WF_MENU"

	WF_MENU

	Usage:	
		You can attach a menu bar object tree to a MENUBAR widget
		by calling:
		
		OBJEC *tree;
		wind_set(handle, WF_MENU, tree)
	
		If the window was created without the MENUBAR attribute,
		the call is ignored.
		
		You get MN_SELECTED message in the extended way adopted
		from AES 4.1  (Involving return of object tree pointer)

@endnode

@node "WF_WHEEL"
@alias "WM_ARROWED"
@alias "WA_WHEEL"

	Existing applications will automatically react on wheel events.
	If the top window has arrow widgets, the default action of XaAES
	on 	wheel turns will be that a appropriate number of WM_ARROWED
	messages is sent to the application.

	The WM_ARROWED sent is completely compatable to real
	WM_ARROWED messages.

	    Each single wheel turn click is translated to a WM_ARROWED
	    message.

    	m[0]   : WM_ARROWED
    	m[1]   : 0
    	m[2]   : 0
    	m[3]   : window handle
    	m[4]   : The appropriate standard WA_..LINE
    				vertical wheel .. is UP or DN
    				horizontal wheel .. is LF or RT

	For wheel aware programs additional information is provided:
	
	    m[5]   :  either 'MW' or 'Mw'
	              'MW' (0x4d57) on the first wheel click
	              'Mw' (0x4d77) on subsequent wheel clicks
	              
	    m[6]   :  0
	    m[7]   :  original wheel amount

		Making it possible to amalgamate wheel turns at will.
		(for instance, turn a large wheel amount into a slider
		   operation)

	WF_WHEEL for wind_set
	
	    This command can be used to influence the behaviour of mouse
	    wheel actions, either for all windows of a application or a
	    particular window.
	
	Usage:
		bool send_WA_WHEEL;
		wind_set(handle, WF_WHEEL, send_WA_WHEEL);

		handle   :  a window handle or 0.
		            0 meaning: all windows of the calling application.

	send_WA_WHEEL = true:

	    If send_WA_WHEEL is true, XaAES will send a specific arrow
	    value to the app in stead of the standard arrows.
	    
	    The new arrow is WA_WHEEL, value 8.
	    
	    	m[0]   : WM_ARROWED
	    	m[1]   : 0
	    	m[2]   : 0
	    	m[3]   : window handle
	    	m[4]   : WA_WHEEL
            m[5]   : 0

	    WA_WHEEL arrow comes with 2 additional values in the message
	    buffer:
	    
	    	m[6]   :  wheel number
	    	m[7]   :  wheel amount
	    	
	 send_WA_WHEEL = false
	 	compatable WM_ARROWED is sent. (see top of this page)
	 
		
@endnode

@node "MU_WHEEL"
		
	MU_WHEEL

		If the event mask MU_WHEEL is passed to event_multi
		XaAES will report mouse wheel to the application, together
		with mouse position and keyboard state as follows:

	binding excerpt:
		intin[0]   : events|MU_WHEEL
		             the mask can be used together with MU_KEYBD,
		             if both passed, MU_NORM_KEYBD prevails.
		....
		intout[0]  : events|MU_WHEEL
		             if the MU_WHEEL event occurs
		       1   : x position of moouse
		       2   : y position of mouse
		       3
		       4   : wheel number
		       5
		       6   : wheel amount (clicks produced by turning the wheel)


	example call:
	
		event = evnt_multi(events|MU_WHEEL, 2,3,1,
		                      0,0,0,0,0,
		                      0,0,0,0,0,
		                      0,0,
		                      &mx, &my,
		                      &wheel_number,
		                      &keyboardstate,
		                      &wheel_amount
		                  )

	Notes:
	   MU_WHEEL will only be sent if there is not a top window or
	   the top window doesnt have arrow widgets. (and of course
	   if MU_WHEEL was in the event mask).
	   
	   Wheel aware programs can then make use of wheel events in
	   all cases.

	   Currently only on available MILAN's running the latest version
	   of TOS 4.08 which includes the VDI function 'vex_wheel_v'.
	   http://www.ccac.rwth-aachen.de/~michaels/index.php/milan

	   Of course, when MU_BUTTON is received, the wheel_number and
	   wheel_amount replies must be interpreted as buttin number
	   and button clicks.
		
	   For ease of implementation and compatability, XaAES never
	   sends MU_BUTTON|MU_WHEEL together.

@endnode

@node vex_wheel_v

	prototype:
	    void vex_wheel_v(short handle, long pusrcode, long *psavcode);

	binding:
	    comtrl[0]  :  Opcode 134
	           1   :  0
	           2   :  0
	           3   :  0
	           4   :  0
	           6   :  handle
	           7,8 :  pusrcode
	           9,10:  psavcode
	
	
	When pusrcode is called by the VDI, d0.w will have wheel_number,
	                                    d1.w will have wheel_amount


@endnode

@node "WF_TOOLBAR"
@alias "WM_TOOLBAR"

	WF_TOOLBAR

		Just like in N.Aes (and MagiC I believe) you can attach a
		toolbar to a windows work area.

		XaAES lifts any restriction on such toolbars
		     (ie: N.Aes; touchexit buttons only)

		This means that a XaAES toolbar is no different from any
		dialogue handled by form_do().

		As a consequence you can implement non-modal dialogues
		in the most simple and natural way. Quite the opposite
		from the WDIALOG design.

		I ceased devoloping the WDIALOG method in XaAES as soon
		as I hurt my nose against the call back approach.

	[1]Usage:
		OBJECT *tree;
		short start, edit_obj;
		wind_set(handle, WF_TOOLBAR, tree, start, edit_obj)


	Binding excerpt:
		intin[0]    :    window handle
		      1     :    WF_TOOLBAR
		      2,3   :    OBJECT *tree
		      4     :    start     /* object index of the item
		                              where to start drawing */
		      5     :    edit_obj  /* current edit object; where the
		                              cursor will be placed. */

	Notes:
		There is no need for a attribute passed to wind_create,
		because for the AES the toolbar is part of the work area.
		The user must be aware of the fact and calculate for himself
		the position of the rest of the work area if such a area
		is present. Such area comes into being when the window is
		opened using a larger inner rectangle than the rectangle
		occupied by the object tree.

		Toolbars are treated as true widgets, hence any drawing
		will be done automatically when needed.
		WM_REDRAW is handled just like any other window.
		No objc_draw required.


	WM_TOOLBAR
		Because a toolbar is a widget, you will get events from
		user action on the toolbar.
		
		When the user action on the toolbar triggers a EXIT condition,
		(clicking a exit button or toucjexit object (or press return))
		a message is set to the application. This means that the
		application must be waiting in a evnt_multi() or evnt_mesag()
		AES call.
		
		The application will receive information on the event in the
		16 byte (8 words) message buffer as follows:
		
		short mp[8];
		
		mp[0]   :    WM_TOOLBAR
		   1    :    0 (reserved)
		   2    :    0 (reserved)
		   3    :    window handle
		   4    :    The object which caused the exit condition
		   5    :    Number of clicks used (1 or 2)
		   6    :    keyboard status
		   7    :    (new) The current editable object (where the cursor is)

		The only difference between the XaAES and N.Aes implementation
		is m[7], due to the fact that XaAES toolbars can have any kind
		of object type.
		The window handle gives you the opportunity to have
		any number of non modal dialogues active concurrently
		and handle them in the classic way in the central
		(and only) evnt_multi loop.

	[2]Usage of wind_set(h,WF_TOOLBAR,...):

		If as a result of a toolbar interaction object(s) need to
		be redrawn (or changed), just call again:
		
		wind_set(handle, WF_TOOLBAR, tree, start, edit_obj);
		
		tree    :  the same object tree pointer
		start   :  object index where to start drawing
		edit_obj:  Best thing to do is recycle m[5]
		
		XaAES will know that this toolbar is already attached and
		hence only redraw the object and its siblings.
		
		All redrawing is done correctly over the rectangle list


	A concise example of the use of XaAES's toolbar concept can be
	found here: DIALTEST, or in the source distribution of XaAES,
	in a similar prigram.

@endnode

@node "MU_MX"

	MU_MX
		
		If the event mask MU_MX is passed to event_multi
		XaAES will report ANY mouse movement to the application,
		thus making artificial supplying of rectangles obsolete.
		
		Especially the annoying use of a 1 pixel wide rectangle 
		can now be avoided.
		
		The new position of the mouse that caused the event is
		returned in the usual place together with the state of
		the keyboard.
		
	binding excerpt:
		intin[0]   : events|MU_MX
		....
		intout[0]  : events|MU_MX     if the MU_MX event occurs
		       1   : new x position
		       2   : new y position

	exemple:
		short mx, my;
		event = evnt_multi(events|MU_MX, ...... &mx, &my,....);
		if (event & MU_MX)
			have_a_mouse_movement(/* in mx and my */);

		
@endnode

@node "MU_NORM_KEYBD"

	MU_NORM_KEYBD
		
		XaAES needed for itself normalized keycodes to be able
		to evaluate CTRL|ALT keys smoothly.
		So I thought it might be usefull to give applications
		the opportunity to get those as well.
		
		If the event mask MU_NORM_KEYBD is passed to evnt_multi
		the application will receive a normalized keycode in stead
		of the standard AES keycode and together with the
		state of the mouse.

		The normalization process is that of Harald Siegmund's
		    NKCC

	binding excerpt:
		intin[0]   : events|MU_NORM_KEYBD
		             the mask can be used together with MU_KEYBD,
		             if both passed, MU_NORM_KEYBD prevails.
		....
		intout[0]  : events|MU_NORM_KEYBD
		             if the MU_NORM_KEYBD event occurs
		....
		       4   : normalized keycode
		       5   : normalized keycode

	note:
		For conveniemce the code is passed in both intout 4 and 5
		4 formally received the status bits
		5 formally received the scancode
		
		Now you can still use 4 for status bits and 5 for the keycode.

@endnode

@node "MU_DYNAMIC_KEYBD"

	MU_DYNAMIC_KEYBD:

		Reserved only, not implemented yet.
		Its function should be to allow a key to be held down
		for a while and then released.
		It should let the keyboard behave as
		a large bunch of mouse buttons, where a MU_DYNAMIC_KEYBD
		event is caused on both press down and release of the
		key. No events are caused when the key remains up or down.

		It is mostly intended for use by games.

@endnode

@node dialtest
@alias DIALTEST

/* Test XaAES dialogue functions */

#include <prelude.h>
#include <tos_gem.h>
#include <stdio.h>
#include "tests.h"

static void putnum(OBJECT *o, int i, int v)
{
	TEDINFO *ted = o[i].spec.tedinfo;
	sprintf(ted->text,"%d",v);
}


int main(void)
{
	int x, y, w, h,
	    edob = FT2,
	    xa,
	    version=0x666;

	appl_init();
	graf_mouse(0,0);

	if (wind_get(0,'XA',&version) == 'XA')				/* detect XaAES */
	if (rsrc_load("tests.rsc"))
	{
		int obno = -1;
		OBJECT *db,*pop,*pops,*menu; TEDINFO *ted;

		rsrc_gaddr(0, T, &db);
		rsrc_gaddr(0, POPS, &pops);
		rsrc_gaddr(0, POP, &pop);
		rsrc_gaddr(0, TMENU, &menu);

		ted = db[XA_VERSION].spec.tedinfo;

		menu_bar(menu, 1);
	
		sprintf(ted->text,"%04x",version);

		form_center(db, &x, &y, &w, &h);
		putnum(db,DTX,x);
		putnum(db,DTY,y);
		putnum(db,DTW,w);
		putnum(db,DTH,h);
		putnum(db,OBX,db->x);
		putnum(db,OBY,db->y);
		putnum(db,OBW,db->w);
		putnum(db,OBH,db->h);

		{
			int w1,w2,w3,w4;
			int m[8],event,s,b,kr,br,wi;
			int kind = INFO|NAME|MOVER|CLOSER|MENUBAR;

			bool cont = true;

			wi = wind_create(kind,0,0,640,400);
			wind_set(wi, WF_NAME, "dial_test");
			wind_set(wi, WF_INFO, " Example program for toolbars ");
			wind_set(wi, WF_TOOLBAR, db, 0, edob);
			wind_set(wi, WF_MENU, menu);
			wind_calc(WC_BORDER, kind,
							0, 0, db->w, db->h,
							&w1, &w2, &w3, &w4);
			wind_open(wi, 40, 40, w3, w4);

			do
			{
				event = evnt_multi(MU_BUTTON|MU_KEYBD|MU_MESAG,
								2,3,0,
								0,0,0,0,0,
								0,0,0,0,0,
								m,
								0,0,
								&x,&y,
								&b,&s,&kr,&br);
				if (event&MU_MESAG)
				{
					switch (m[0])
					{
					case WM_TOOLBAR:
						obno = m[4];
						edob = m[5];
						if (obno == OK)
							cont = false;
						if (obno == LARGE_POP)
						{
							int x, y;
							MENU mn = {0};
							
							mn.tree = pops;
							mn.menu = FORM_POPS;
							
							objc_offset(db, LARGE_POP, &x, &y);
							menu_popup(&mn, x, y, &mn);
						}

						db[obno].state &=~ SELECTED;
						wind_set(wi, WF_TOOLBAR, db, obno, edob);		/* redraw toolbar. */ 
						break;
					case WM_TOPPED:
						wind_set(wi, WF_TOP);
						break;
					case WM_CLOSED:
						cont = false;
						break;
					case WM_MOVED:
						wind_set(wi, WF_CURRXYWH, m[4],m[5],m[6],m[7]);
						break;
					case MN_SELECTED:
						if (m[3] == MDIAL and m[4] == QUIT)
							cont = false;
					case AP_TERM:
						cont = false;
					}
				}
				
			} while (cont);

			wind_close(wi);
			wind_delete(wi);
		}

		form_dial(FMD_FINISH, 0,0,0,0,x,y,w,h);
		rsrc_free();
	}

	appl_exit();
	return 0;
}

@endnode

@node Acknoledgment

	Thanks go to Michael Schwingen for his suggestions on
	WF_WHEEL, WA_WHEEL and WM_ARROWED
	and actual implementation of vex_wheel_v in TOS 4.08
	
@endnode

@pnode "Henk Robbers"
Henk Robbers.
te Amsterdam

mailto:h.robbers@chello.nl
http://members.ams.chello.nl/h.robbers/Home.html
@endnode

@pnode "Michael Schwingen"
Michael Schwingen

mailto:michael@schwingen.org
http://www.ccac.rwth-aachen.de/~michaels/
@endnode
