4 * Really good keyboard handling
6 * © 1994-1998 Straylight
9 /*----- Licensing note ----------------------------------------------------*
11 * This file is part of Straylight's Steel library.
13 * Steel is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2, or (at your option)
18 * Steel is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with Steel. If not, write to the Free Software Foundation,
25 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
33 * BOOL akbd_checkInternalKey(int ikey)
36 * Checks whether a given key is being pressed at the moment.
39 * int ikey == the internal key number of the key to check, as shown on page
40 * 1-849 of the RISC OS 3 Programmer's Reference Manual.
43 BOOL akbd_checkInternalKey(int ikey)
45 return (bbc_inkey(0xFF00 | (ikey ^ 0xFF)));
49 * int akbd_translate(int chcode)
52 * Translates the given WIMP-type key number, as returned in a Key_Pressed
53 * (wimp_EKEY) event into a STEEL extended key number, which should
54 * distinguish almost every keypress available.
57 * int chcode == a WIMP-type keypress number
63 #define akbd__WEIRDCTRL 0x000003BB
65 #define akbd__modify(a,b,c,d) \
78 int akbd_translate(int chcode)
84 /* --- If it's a function key, the WIMP has translated it for us --- */
86 if ((chcode>=0x1CA) ||
87 (chcode>=0x180 && chcode<=0x1BF) ||
88 (chcode>='a' && chcode<='z') ||
89 (chcode>='A' && chcode<='Z') ||
90 (chcode>='[' && chcode<=']'))
93 /* --- Work out the modifier status --- */
96 if (akbd_checkInternalKey(0))
98 if (akbd_checkInternalKey(1))
101 /* --- How many ways can you press Delete? --- */
118 /* --- Check for variants of space --- */
121 akbd__modify(0x020,0x120,0x000,0x100);
123 /* --- The many faces of the Return key --- */
127 /* --- He pressed return (or maybe ^M, or even Enter...) --- */
129 if (akbd_checkInternalKey(60))
131 /* --- It was Enter, so return a variant of that --- */
133 akbd__modify(0x166,0x176,0x126,0x146);
135 else if (!akbd_checkInternalKey(101))
137 /* --- It *wasn't* ^M, so it must have been Return --- */
139 akbd__modify(0x01D,0x11D,0x13D,0x15D);
141 /* --- If it was ^M, the control key mashing will catch it --- */
144 /* --- Check for control keys --- */
148 if (akbd__WEIRDCTRL & (1<<chcode))
150 /* --- It's a control key, Jim, but not as we know it... --- */
152 static char intCodes[]={0,48,0,17,18,19,0,36,21,38};
156 /* --- It's backspace, though it may be ^H --- */
158 if (!akbd_checkInternalKey(84) &&
159 !akbd_checkInternalKey(21))
161 /* --- It really is backspace, or a variant thereof --- */
163 akbd__modify(0x01C,0x11C,0x13C,0x15C);
168 /* --- It's not a *really* weird key at least --- */
170 if (akbd_checkInternalKey(intCodes[chcode]))
172 /* --- It was a strange ^digit key press --- */
175 return (chcode+0x150);
177 return (chcode+0x130);
182 /* --- The many things that return 0 --- */
184 if (akbd_checkInternalKey(39))
195 /* --- Ok -- it's fairly sane then --- */
198 return (chcode+0x100);
203 /* --- Check for number key presses --- */
205 if (chcode>='0' && chcode<='9')
207 static char keypadTable[]={106,107,124,108,122,123,26,27,42,43};
209 if (akbd_checkInternalKey(keypadTable[chcode-'0']))
211 /* --- It was the keypad version, so we have to modify it --- */
213 return (chcode+(0x1C0-'0')+(modifiers<<4));
219 /* --- Test for the rest of the keypad --- */
223 case '/': icode=74; base=0x161; break;
224 case '*': icode=91; base=0x162; break;
225 case '#': icode=90; base=0x163; break;
226 case '-': icode=59; base=0x164; break;
227 case '+': icode=58; base=0x165; break;
228 case '.': icode=76; base=0x167; break;
232 /* --- It could be a keypad key here, so check --- */
234 if (akbd_checkInternalKey(icode))
236 /* --- It is one of the other keypad keys, so return it modified --- */
238 akbd__modify(base,base+16,base-64,base-32);
242 /* --- The revolting gross (US-ism -- yuk) keys that are left --- */
247 /* --- Home, or maybe ^6 :-/ --- */
249 if (akbd_checkInternalKey(24))
257 akbd__modify(0x01E,0x11E,0x13E,0x15E);
261 /* --- Escape, or maybe ^[ :-/ --- */
263 if (akbd_checkInternalKey(56))
271 akbd__modify(0x01B,0x11B,0x13B,0x15B);
278 return (chcode+0x130);
280 return (chcode+0x110);
284 /* --- Hmm -- it seems sensible after all --- */
290 * BOOL akbd_pollsh(void)
293 * Returns whether the Shift key is pressed
296 BOOL akbd_pollsh(void)
298 return (akbd_checkInternalKey(0));
302 * BOOL akbd_pollctl(void)
305 * Returns whether the Control key is pressed
308 BOOL akbd_pollctl(void)
310 return (akbd_checkInternalKey(1));
314 * BOOL akbd_pollkey(int *code)
317 * Reports whether the user has typed ahead, and if so what the keypress
318 * was. Note that the keypresses returned are WIMP-type, not STEEL extended
319 * ones so you will have to use akbd_translate if you need the extended
322 * This call could be used to allow buffering of keypresses: on a
323 * Key_Pressed event you would call this routine until it returns FALSE
324 * and store the codes it returns in a buffer along with the code from the
328 BOOL akbd_pollkey(int *code)
332 /* --- Find out if there is a key waiting --- */
338 /* --- Check for extended codes --- */
351 /* --- We found one --- */