Re: [AD] Mistake?

[ Thread Index | Date Index | More lists.liballeg.org/allegro-developers Archives ]


Jason Wilkins <fenix@xxxxxxxxxx> writes:
> This is from keyboard.c, from _handle_keypress to be exact.
> 
> Is it correct?
[snip]
> The problem I have here is that it seems to be contradiction, but it works.

It's correct, just not very intuitive. The reason is that we have three 
different modes for keyboard input (or mouse input, which works the same 
way):

- Polling drivers, which provide a poll() function. Here, the user calls 
poll_keyboard(), which calls keyboard_driver->poll(), which checks for new 
input, and if there is any, calls _handle_key_press(). Hence if the 
keyboard_driver->poll() function exists, the right thing for this function 
to do is to put the input directly into the queue so it can be read by the 
application.

- Asynchronous drivers, which read their input in another thread or hardware 
interrupt. This is the best way to do it as long as your OS can support it, 
and is how all the current versions work. Here, _handle_key_press() may be 
called at any time. The keyboard_polled flag will be clear by default, so 
again the input will be processed straight away. This is how people expect 
things to behave.

- The third bit is the complicated part. When you write a program on a 
machine that has asynchronous input, you are likely to forget to call 
poll_keyboard() in some places where you really ought to, in which case your 
program won't work if you ever try it on a machine with a polling driver. To 
make it easy for people to test for these bugs, there is an emulation mode 
where asynchronous drivers are made to work like polling ones, so that you 
can easily tell if you've missed out any of the poll calls. The way this 
works is that the first time you call poll_keyboard(), your program switches 
into the poll emulation mode, and sets the keyboard_polled() flag. From then 
onwards, whenever the real asynchronous driver calls 
_handle_keyboard_input(), the data is cached in a temporary queue, and only 
when the user calls poll_keyboard() is it moved across to the real input 
queue. To the user, it looks exactly like a polling driver, but the driver 
itself can ignore this and just get on with being asynchronous.

So basically you can ignore all this stuff. Just write your driver to work 
in whichever of the first two modes you prefer, and the framework will do 
the emulation for you. The only thing to be careful of is that you must 
never update the user-visible data directly: put flags into _key_shifts, 
_mouse_b, etc, and let the framework code move it from there into the 
user-visible versions without the leading underscore.

> Do I get the 'Well Spotted' award?

I think this qualifies for "best runner up" :-)


--
Shawn Hargreaves - shawn@xxxxxxxxxx - http://www.talula.demon.co.uk/
"A binary is barely software: it's more like hardware on a floppy disk."



Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/