Toolbox Gadgets
Changes with Window 1.85
Focus tracking
In order to allow the tracking of the focus the Window module will now issue a new event, Window_GadgetLostFocus when the focus moves from a gadget. This facility is necessary for the implementation of the new Number Range input mechanism.
Window_GadgetLostFocus is toolbox event &82891. The event does not contain any data except the toolbox header.
#define Window_GadgetLostFocus (Window_SWIChunkBase + 17)
typedef struct
{hdr ;
} WindowGadgetLostFocusEvent;
It may be necessary for external gadgets losing the focus to issue this event should they lose the focus. Gadgets which are provided entirely through Wimp icons within the parent Window should be automatically tracked by the Window module and the necessary event raised. Gadgets which are provided through nested windows will need to issue the event when the focus is lost (as indicated by Wimp Event Caret Lost). Gadgets which are not provided through nested windows or through icons may need to detect the focus being lost in some other manner.
Failure by external Gadgets to issue this message may prevent applications from detecting focus loss from their gadgets. It is not expected that the Window or other Toolbox modules will suffer from this lack at this time.
Gadget information
For the benefit of gadget developers it is now possible to list the gadgets currently known to the system through the command *Window_Gadgets. This will list the gadget identifiers, together with their size, as registered with the Window module.
Gadget handlers
Introduction
When the Window module wishes to notify a gadget of an event or operation it will call the gadget handler through the SWI supplied on registration (if the gadget's FeatureMask indicates that a 'Private handler' is present). These handler entry points have been extended in recent versions of the Window module. This document duplicates and extends on some of the details in AppNote 281.
The gadget handler is entered with the following conditions :
R0 = operation flags (dependant on reason code)
R1 = gadget type
R2 = reason code :
0 = reserved
1 = create new gadget
2 = delete gadget
3 = fade gadget
4 = gadget method
5 = reserved
6 = mouse click on gadget icon
7 = reserved
8 = reserved
9 = plot gadget
10 = set focus to gadget
11 = move gadget
12 = reserved
13 = parent window shown notification
14 = mouse scroll gadget
15 = gadget lost focus notification
16 = redraw request
17 = timer triggered
Others reserved
R3... reason code dependant
Gadget registration
Gadgets are registered using the SWI Window_RegisterExternal and removed using the SWI Window_DeregisterExternal. These SWIs have been extended in order to allow for greater flexibility in the future.
Registration SWIs
SWI Window_RegisterExternal 0x82885
On entry:
R0 = flags:
bit 0 = use extended form of gadget details
bits 1-31 must be 0
R1 = pointer to list of type details (see below) R2 = Gadget SWI number
On exit:
All registers preserved
This SWI registers the new Gadget type(s) with the Window module. The given SWI number will be called whenever the Window module encounters the given Gadget type and the features mask indicates that there is a handler available. See the registration section on valid types.
SWI Window_DeregisterExternal 0x82886
On entry:
R0 = flags, must be 0
R1 = type of Gadget to deregister
R2 = SWI that handled it.
On exit:
All registers preserved
This SWI deregisters a Gadget type. Note that if a module dies without deregistering the Window module will automatically deregister it on the next SWI call. However, this behaviour should not be relied upon - it is there to prevent unexpected behaviour with the rest of the system.
Type details
The type details can take one of two forms, depending on whether R0 bit 0 is set or clear. The basic form has bit 0 clear and, in C, has the following structure :
typedef struct {type ;
unsigned long validflags;
FeatureMask features;
} GadgetExtensionRecord;
The extended form adds an extra FeatureMask word, making the record 4 words long, rather then 3 :
typedef struct {type ;
unsigned long validflags;
FeatureMask features;
FeatureMask2 features2;
} GadgetExtensionRecord2;
The FeatureMask (and FeatureMask2) flags word takes the following form in C :
typedef struct {add:2 ,
remove:2,
postadd:2,
method:2,
reserved:2,
mclick:2,
reserved2:4,
plot:2,
setfocus:2,
move:2,
fade:2,
windowshow:2,
mscroll:2,
lostfocus:2,
redraw:2;
} FeatureMask;
typedef struct {timer:2 ,
unused2:2,
unused4:2,
unused6:2,
unused8:2,
unused10:2,
unused12:2,
unused14:2,
unused16:2,
unused18:2,
unused20:2,
unused22:2,
unused24:2,
unused26:2,
unused28:2,
unused30:2;
} FeatureMask2;
Each of these bits can take a value to indicate what type of handler is present in the gadget :
0 = No handler present
The operation will be ignored
1 = Default handler present
The Window module will perform whatever default processing the operation expects, for example a 'move' operation will apply simple position changes to the registered icons for the gadget.
2 = Private handler present
The Window module will call the gadget entry point to request the operation be performed.
3 = Reserved, must not be used
See the Gadget.Handlers document for details of the handlers and their API.
A number of functions exist be used to register and deregister gadgets :
extern _kernel_oserror *register_gadget_types(unsigned int flags,
GadgetExtensionRecord *rec, int SWIno);
extern _kernel_oserror *deregister_gadget_type(unsigned int flags,
int type,int SWIno);
extern _kernel_oserror *register_gadget_type(unsigned int flags, int type,
unsigned int valid, unsigned int mask,int SWIno);
extern _kernel_oserror *register_gadget_type2(unsigned int flags, nt type,
unsigned int valid, unsigned int mask, unsigned int mask2, int SWIno);
Handler entries
GADGET_ADD (1)
On Entry:
R2 = GADGET_ADD (1)
R3 = pointer to gadget template
R4 = ObjectId of parent window
R5 = Wimp window handle
On exit:
R0 = Handle to use in future calls
R1 = pointer to icon list
On receiving this reason code an extension module should create the new gadget from the given data and return its icon list and private handle. The template will already have been checked for valid flags. Any attached objects (like the Click show objects attached to action buttons) should be created using the GLib calls.
GADGET_REMOVE (2)
On entry:
R0 = flags :
bit 0 set if gadget should remove attached objects
bits 1-31 reserved, must be 0
R2 = GADGET_REMOVE (2)
R3 = pointer to private data
On exit:
All registers preserved
On receiving this reason code an extension module should remove the gadget. If the recurse bit is set then any attached objects such as Windows or Menus should not be removed. This is in common with the flag bit in the SWI Toolbox_DeleteObject.
GADGET_FADE (3)
On entry:
R2 = GADGET_FADE (3)
R3 = pointer to private data
R4 = state (non zero = fade)
R5 = ObjectId of window to which this Gadget belongs
On exit:
All registers preserved
On receiving this reason code an extension module should fade or unfade the gadget, according to the value in R4. A Gadget will have been faded by the client making a call to the Gadget_SetFlags method.
GADGET_METHOD (4)
On entry:
R2 = GADGET_METHOD (4)
R3 = pointer to private data
R4 = pointer to registers passed to Toolbox_ObjectMiscOp SWI
On exit:
Depends on Method
The window module raises this reason code when a task uses the SWI Toolbox_ObjectMiscOp on a Gadget provided by an extension module. R4 points to a register bank (in C terms this is the _kernel_swi_regs type) containing the values that the client passed to the SWI. If any information is to be returned to the client this bank should be updated. i.e. to return a value in R0 do not set R0 to the value but update the contents of the location pointed to by R4+0. Note that generic Gadget methods such as Gadget_SetFlags do not result in a call to GADGET_METHOD.
GADGET_MCLICK (6)
On entry:
R2 = GADGET_MCLICK (6)
R3 = pointer to private data
R4 = pointer to wimp event block
On exit:
R1 = claim
The window module raises this reason code when an icon belonging to the Gadget is clicked on. The event block in R4 is just like the one returned by Wimp_Poll when an icon is clicked on. An extension module would typically use this to update the state of the Gadget or return a 'high-level' Toolbox Event. By setting R1 to be non-zero the Window module will update the task's ID block so that when the wimp mouse click event is delivered it is marked as belonging to this Gadget. Although it is unlikely that the task will be interested in the underlying event it should still be claimed. Possible exceptions to this rule are when the menu mouse button is used - in this case, not claiming the click (R1 = 0) passes the mouse click on which would allow the Window's menu to be viewed. This is not true for a popup menu type Gadget though.
It is also possible to claim the event entirely so that the task will not see the mouse click. This is achieved by setting R1 to -1 on exit, but this should be avoided as this does not fit the Toolbox model and so should only be done in specialist cases.
GADGET_PLOT (9)
On entry:
R2 = GADGET_PLOT (9)
R3 = pointer to gadget template definition
On exit:
All registers preserved
The window module raises this reason code when !ResEd is plotting Gadgets. The extension module should use Wimp_PlotIcon or (Window_PlotGadget for composite Gadgets) to display the Gadget which is defined by the template.
GADGET_SETFOCUS (10)
On entry:
R0 = flags :
bit 0 = set if gadget the focus is being set 'upwards',
clear if the gadgets is being set 'downwards'.
bits 1-31 reserved, must be 0
R2 = GADGET_SETFOCUS (10)
R3 = pointer to private data
On exit:
All registers preserved
This call will be made when the Window module wishes to set the focus to a Gadget. The direction signals whether to set the focus to the before of after Gadget in the event of this Gadget being faded. Care should be taken when 'passing on' the focus as an infinite loop will be entered if all members of the list are faded. Gadgets which are composite and consist of a writable Gadget do not need to worry about this and should just set focus to their writable without checking their faded status, assuming that the before and after fields of the underlying writable have been set.
GADGET_MOVE (11)
On entry:
R2 = GADGET_MOVE (11)
R3 = pointer to private data
R4 = wimp window handle
R5 = pointer to new bounding box
R6 = window ObjectId
On exit:
All registers preserved
This call is made when the Gadget_Move method is applied to a Gadget. A composite gadget must supply a handler if it is going to be moved after creation as the default handler can only move the icons which belong directly to a Gadget. It is also of use if the Gadget supports resizing - the default mover will only move by an offset as it generally does not know how to handle and change in the size of the bounding box.
GADGET_POSTADD (12)
This call is beyond the scope of this document.
GADGET_WINDOWSHOW (13)
On entry:
R2 = GADGET_WINDOWSHOW (13)
R3 = pointer to private data
R4 = window ObjectId
R5 = wimp window handle
R6 = 1 if window is being shown, 0 if window is being hidden
On exit:
All registers preserved
This call is made to inform the gadget that its parent Window has been shown or has been hidden. Gadgets may wish to take action the first time they are shown or to stop an action once the window is hidden. A typical example of such a gadget might be a timer.
GADGET_MSCROLL (14)
On entry:
R2 = GADGET_MSCROLL (14)
R3 = pointer to private data
R4 = window ObjectId
R5 = wimp window handle
R6 = pointer to wimp event block
On exit:
All registers preserved
This call is made when the Window module receives a scroll event for an icon belonging to the gadget. In order for the WindowScroll module to generate such events the icons must have the correct validation string set. See the Desktop.Wimp.WindowScroll document for more details.
GADGET_LOSTFOCUS (15)
On entry:
R2 = GADGET_LOSTFOCUS (15)
R3 = pointer to private data
R4 = window ObjectId
R5 = wimp window handle
R6 = pointer to wimp event block
On exit:
All registers preserved
This call is made when the Window module detects that a gadget has lost the focus, either due to a cursor movement or the focus being moved to another icon (even temporarily by a Menu). Gadgets may wish to take action based on having lost the focus, such as validating input.
GADGET_REDRAW (16)
On entry:
R0 = flags:
bit 0 = 1 if the gadget needs to be redrawn entirely,
0 if part of the gadget is obscured
bit 1 = 1 if the gadget should be rendered faded,
0 if the gadget should be rendered normally
Others reserved
R2 = GADGET_REDRAW (16)
R3 = pointer to private data
R4 = pointer to redraw bounding box in workspace coordinates
R5 = pointer to window state block (as returned from Wimp_GetWindowState)
R6 = pointer to gadget bounding box in workspace coordinates
R7 = x screen coordinate of workspace coordinate 0,0
R8 = y screen coordinate of workspace coordinate 0,0
On exit:
All registers preserved
This call is made when the Window module needs to redraw a region of the window covered by a gadget. Gadgets which have the 'redraw' Feature set to include a 'Private Handler' will be automatically registered with the RedrawManager module and this entry point will be called to redraw their content. The 'Gadget_AtBack' flag is used to control whether the redraw occurs before or after icon rendering. Because the redraw operation uses the RedrawManager, the order of the such gadgets within the window will be arbitrary, but always before or after all other (non-Redraw) gadgets. The Redraw region will be bounded by the graphics window. See the RedrawManager documentation for more details.
GADGET_TIMER (17)
On entry:
R2 = GADGET_TIMER (17)
R3 = pointer to private data
R4 = window ObjectId
R5 = wimp window handle
On exit:
All registers preserved
This call is made when a Gadget's timer is triggered. The accuracy of gadget timers cannot be guaranteed. Gadget timers are started either on creation or when the window is shown. They are stopped when the window is hidden.
GADGET_???? (?)
Over time more handlers may become available and so the SWI handler should not assume that only the handlers it has requested will result in a call out. For a handler in C this would result in nothing being done by the default case.
|