As I said in the last instalment, one of the most important parts of any WIMP application is the poll routine.
Event mask (in r0)
The event mask is a 32-bit number (an int) which either allows or disallows various event types.
SWI Wimp_Poll
On entry:
r0 event mask r1 pointer to a 256 byte block r3 pollword pointer in RMA
On exit:
r0 event reason code r1 pointer to block of data
The mask is possibly one of the best examples of using a bit structure (I covered this in C from the Top Part 10). By setting any bit to 1, that operation will be masked out.
Setting (or passing) mask as 0 will mean that the poll will accept all of the event codes passed back.
Bit Meaning when set 0 Don't return NULL reason 1 Don't return Redraw window; queue it. 2-3 0 4 Don't return Pointer Leaving 5 Don't return Pointer Entering 6 Don't return Mouse Click; queue it. 7 0 8 Don't return Key Pressed; queue it. 9-10 0 11 Don't return Lose Caret 12 Don't return Gain Caret 13 Don't return pollword nonzero 14-16 0 17 Don't return User Message
The 256-byte block can mean anything. It will contain window handles, menu handles, messages, mouse clicks, scroll requests (and the list goes on).
We could set up this memory block very simply with something akin to
int *block=malloc(256);
(which must also be checked to ensure there is enough memory available in the first place!) but given that the value out will be the same as the value in, how can we read this without ending up in a right mess?
In Basic, we would use a rather messy method (in my opinion) of using lines like
CASE (reason%) OF WHEN 6 : PROCclick(block%!8) WHEN 24 : PROCkeypress(block%!24) ENDCASE
This can lead to all sorts of problems in remembering what the contents of block% contain.
In C, we have the struct function to get around this sort of problem. It is far simpler to set up a series of typedef'd structs, then place these inside another master structure within a union and then, as a catcher, have an int array outside of the structure which will take up 256 bytes.
The example here, inside the program, would have a block of memory on the stack reserved for it using malloc.
The major advantage of using this type of structure is that we know what exactly is going on within the poll memory block.
This is also a very good example of using a library to save you time in the long run - could you imagine the pain in the neck problems of having to decode the block by hand or setting up the poll struct at the start of each application?
To save time, I have included on the cover disc (and therefore also on the Archive website) a header file called Wimp_Block. Have a look at it and see how it works.
Reason Action 0 No reason 1 Redraw window 2 Open window 3 Close window 4 Pointer leaving window 5 Pointer entering window 6 Mouse click 7 User drag box 8 Key pressed 9 Menu selection 10 Scroll request 11 Lose caret 12 Gain caret 13 Pollword non-zero 14-16 Reserved 17 User message 18 User message recorded 19 User message acknowledge typedef struct poll_win{ int window_handle ; int min_x; int min_y; int max_x; int max_y; int scroll_x; int scroll_y; int open_handle; int flags; } poll_win; typedef struct wimp_block{ union{ int null; pointer redraw; poll_win open_win; } poll; char mem[256]; } wimp_block;
Priority :
Highest : 17-19
Next : 1-6, 8, 9
Next : all other codes
Lowest : 0
For the moment, you don't need to worry about what any of these reason codes actually mean; they will be explained as we go along.
The format of the wimp_poll routine is much the same as any other switch/case system.
r1 passes back a reason code which the switch must act upon. The simplest of these, is NULL.
A NULL event means that nothing has happened which the application must act upon. It just sits there doing nothing. When nothing is happening, the RISC OS multitasking system knows this, so dedicates less time to that application until a non-NULL event occurs in the application to wake it up.
All of the other reason codes are for acting on or with a window.
That's all for this time. I'll develop the idea of libraries for the wimp_poll routine next time. Be warned though, it will not be short, but once done, will make life simpler.
Source: | Archive Magazine 14.6 |
Publication: | Archive Magazine |
Contributor: | Paul Johnson |