C the WIMP

3. Wimp Poll

As I said in the last installment, one of the most important parts of any WIMP application is the poll routine.

Recap

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

Event mask (in r0)

The event mask is a 32 bit number (an int) which either allows or disallows various event types

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 mask is possibly one of the best examples of using a bit structure (I covered this in C from the Top 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.

256 byte block (r1)

In all versions of RISC OS so far, the value returned in r1 after Wimp_Poll is the same as the value passed in.

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 this memory block up 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 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 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% contains.

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.

For example

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;

Which inside of 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 in

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 that having to decode the block by hand or setting

up the poll struct at the start of each application would have?

To save time, I have included on the cover disc (what do you mean, your subscription doesn't have the cover disc? Upgrade now!!!) a header file called Wimp_Block. Have a look at it and see how it works.

Reason codes (out r0)

The reason codes are the codes which the poll loop should react upon. These values are only

from Wimp_Poll and not from any other event an application will create.

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.

Reason Action 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
Priority : Highest : 17 - 19 Next : 1-6, 8, 9 Next : all other codes
Lowest : 0

The format of the wimp_poll routine is much the same as any other switch/case system.

r1 passes back as 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. The app 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.