[ 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."