Keyboard handling routines
Starts a _keytest_optimized block.
BEGIN_KEYTEST is used to start a block of key reading using _keytest_optimized.
See also: END_KEYTEST, _keytest_optimized
Ends a _keytest_optimized block.
END_KEYTEST is used to end a block of key reading using _keytest_optimized.
See also: BEGIN_KEYTEST
short _keytest_optimized (short row, short col); |
Optimized low-level keyboard reading for single keys.
_keytest_optimized behaves like _keytest, but
it produces better code if keys from the same row are read sequentially.
You have to use it together with BEGIN_KEYTEST and END_KEYTEST.
An example probably best explains the usage of this function. The following
piece of code waits until an arrow key is pressed. Since all arrows
are in the same row, only one call to _rowread
is necessary.
for (;;) { BEGIN_KEYTEST if (_keytest_optimized (RR_LEFT) || _keytest_optimized (RR_RIGHT) || _keytest_optimized (RR_UP) || _keytest_optimized (RR_DOWN)) break; END_KEYTEST }
short _keytest (short row, short col); |
Low-level keyboard reading for single keys.
_keytest uses _rowread to read the key in a
specific row and column. If the parameters are constants, the argument for
_rowread and the return mask are optimized
into single values.
_keytest returns TRUE if the key is being
held down, and FALSE otherwise.
Be sure to read the notes about _rowread.
compat.h defines constant pairs for all keys.
Using these constant pairs, you can use _keytest in this way:
if (_keytest (RR_ESC)) ...
See also: _keytest_optimized
#define _rowread_internal(row) (~(_rowread (row))) |
Low-level keyboard reading without inverting.
_rowread_internal is a function which was previously used internally by _rowread. Unlike _rowread, it does not invert the return value.
#define _rowread_inverted(row) (_rowread (~((short)(row)))) |
Low-level keyboard reading with inverting.
_rowread_inverted is similar to _rowread, but it also inverts the row passed to it.
unsigned short _rowread (unsigned short row); |
Low-level keyboard reading.
_rowread is a function for low-level keyboard reading.
It is implemented for simultaneous reading of more than one key (useful in games), or for reading
keys when interrupts are disabled (useful if you want to avoid displaying status
line indicators, which are displayed from Auto-Int 1).
Setting a bit in row masks the corresponding row of the keyboard from being
read, so if row is zero, all rows are read at the same time. Take a look
at _rowread_inverted as well.
In the result, all bits (cols) corresponding to keys which are being held down
are set.
See below for some examples.
Here is a table which describes how the keyboard matrix is organized on
both the TI-89 and TI-92 Plus:
TI-89:
C o l u m n | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
R o w |
|
C o l u m n | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
R o w |
|
_rowread(~((short)(1<<2))) & (1<<3) _rowread(~0b100) & 0b1000 _rowread(~0x4) & 0x8 _rowread(0xFFFB) & 0x8
But generally it is much easier to use the _keytest macro instead.
Because of the way the TI-89 and TI-92+'s keyboard is wired, if you hold down three
keys that form the corners of a rectangle, the calculator will think you are
also holding down the key at the fourth corner. The ON key is special. It is not
part of the keyboard matrix and therefore cannot be read with _rowread. It
triggers a special interrupt instead.
Note: It is recommended to redirect Auto-Int 1 and 5 while reading the keyboard using _rowread,
because keyboard reading routines implemented in these two interrupts may interfere with _rowread if
an interrupt occurs just while _rowread is executing.
See DUMMY_HANDLER from intr.h
for information on how to do this.
About the internal implementation: _rowread sends row to the I/O port
0x600018 (keyboard row mask), waits a while to allow the I/O to recover, then
returns the byte read from 0x60001B (inverted for easier testing in C programs).
See also: _rowread_internal, _rowread_inverted, _keytest
void alphaLockOff (unsigned char *Status); |
Turns the alpha-lock off on the TI-89.
alphaLockOff first returns the current alpha-lock keyboard status in Status. Then it turns the alpha-lock off. This routine exists on both the TI-89 and TI-92+, but as there is no alpha-lock on the TI-92+, this function does nothing on the TI-92+.
See also: alphaLockOn, restoreAlphaLock, SetAlphaStatus, GetAlphaStatus
void alphaLockOn (unsigned char *Status); |
Turns the alpha-lock on on the TI-89.
alphaLockOn first returns the current alpha-lock keyboard status in Status. Then it turns the alpha-lock on. This routine exists on both the TI-89 and TI-92+, but as there is no alpha-lock on the TI-92+, this function does nothing on the TI-92+.
See also: alphaLockOff, restoreAlphaLock, SetAlphaStatus, GetAlphaStatus
unsigned char GetAlphaStatus (void); |
Returns the current alpha-lock status.
GetAlphaStatus returns TRUE if the alpha-lock is on, and FALSE otherwise.
On the TI-92+, the function will always return FALSE.
See also: SetAlphaStatus
short GKeyDown (void); |
Checks for currently-available keystrokes.
Although GKeyDown is different entry in the TIOS jump table than kbhit, there is no difference between these two functions. GKeyDown just calls kbhit and does nothing more.
void GKeyFlush (void); |
Flushes the keyboard queue.
GKeyFlush flushes the keyboard queue by repeatedly calling GKeyIn until the queue is empty.
short GKeyIn (SCR_RECT *cursor_shape, unsigned short Flags); |
Gets character from the keyboard, with additional possibilities.
GKeyIn acts similarly to ngetchx, with following differences:
During waiting for a keypress, a flashing cursor may optionally be displayed. Parameter cursor_shape is a pointer to SCR_RECT structure which defines location and shape of the cursor (it is, in fact, a flashing rectangular area which is obtained by XORing a rectangle while waiting on a key). If cursor_shape is NULL, no cursor will be displayed.
The activity in the status line during waiting for a keypress is set to IDLE (in opposite to ngetchx which sets activity to BUSY). After a keystroke is ready, the activity will be switched to BUSY. See ST_busy for more info about status line activity indicator.
During waiting for a keypress, if the user waits too long, the calculator will be switched off (APD feature - Automatic Power Down). This will not happen with ngetchx. See system.h header file for more info about APD.
During waiting for a keypress, the calculator enters into "idle" state (see idle for more info).
GKeyIn bypasses the event manager’s handling of keys so this routine should be used with caution.
If Flags is different than zero, some special behaviour happens.
The parameter Flags can be a combination of the following, defined in the GKeyFlags enumeration:
GKF_NORMAL | No special key processing.
This is the usual value to set.
Note: GKF_NORMAL is actually 0 (i.e. no flags are set). |
GKF_MODAL | If the pressed key is a modal
key (see QModeKey for information on
what is a "modal" key for the TIOS), GKeyIn will return
KEY_ESC instead of the real keystroke code,
and the keystroke will not be picked from the keyboard queue. If the pressed
key is not a mode key, GKeyIn behaves as usual.
Note that DIALOG boxes usually set GKF_MODAL and GKF_SYS so that if the user presses [VAR-LINK] in the dialog box, the dialog box is closed and then the [VAR-LINK] key is acted on (though there is a flag to allow [VAR-LINK] to be activated from inside a dialog box). |
GKF_REPUSH_KEY | GKeyIn will not pick the keystroke from the keyboard queue, so the "keypress" flag will remain set. You must explicitely pick it using ngetchx or flush the queue using GKeyFlush. |
GKF_ACCEPT | The purpose of this flag is unknown for the moment. |
GKF_SYS | If the pressed key is a system key (see QSysKey for information on what is a "system" key for the TIOS), GKeyIn will return KEY_ESC instead of the real keystroke code, and the keystroke will not be picked from the keyboard queue. If the pressed key is not a system key, GKeyIn behaves as usual. |
GKF_NO_EVS | Pressing the [CATALOG] key will be ignored. |
See also: ngetchx, kbhit, kbd_queue, OSFastArrows
short kbhit (void); |
Checks for unread keystrokes.
kbhit checks to see if a keystroke is currently available. Any available keystrokes can be
retrieved with ngetchx. If a keystroke is available, kbhit returns a
nonzero integer (in fact, it returns the exactly same value as
ngetchx); if not, it returns 0. Note that kbhit does not pick a
keystroke from the keyboard queue. So, kbhit will continue to return non-zero value until
"keypress" flag is reset by calling ngetchx,
GKeyFlush or GKeyIn.
Note: kbhit function is slow, because it also handles receiving eventual bytes from the
link port (used mainly internally in TIOS when the calculator is in the Home screen). See kbd_queue
for much faster way to check the keyboard state.
See also: ngetchx, GKeyIn, kbd_queue, OSFastArrows
short KeyYesOrNo (unsigned short key); |
Checks if a key value represents a 'yes' or 'no' key.
KeyYesOrNo returns:
1, if key is ENTER, or the first letter of 'yes' in the current language;
0, if key is ESC, or the first letter of 'no' in the current language;
-1, if key is neither.
Here is an example (called "Key Yes or No"):
// Check whether typed keys represent "Yes" or "No" // in current language #define USE_TI89 // Compile for TI-89 #define USE_TI92PLUS // Compile for TI-92 Plus #define USE_V200 // Compile for V200 #define OPTIMIZE_ROM_CALLS // Use ROM Call Optimization #define MIN_AMS 200 // Compile for AMS 2.00 or higher #define SAVE_SCREEN // Save/Restore LCD Contents #include <tigcclib.h> // Include All Header Files // Main Function void _main(void) { short k, a; ClrScr (); while ((k = GKeyIn (NULL, 0)) != 32) // While the user doesn't type SPACE { a = KeyYesOrNo(k); if (a == 0) DrawStr (0, 0, "FALSE ", A_REPLACE); else if (a == 1) DrawStr (0, 0, "TRUE ", A_REPLACE); else DrawStr (0, 0, "NEITHER", A_REPLACE); } DrawStr (0, 0, "SPACE ", A_REPLACE); GKeyIn (NULL, 0); }
short ngetchx (void); |
Gets character from the keyboard, without echoing to the screen.
ngetchx reads a single character directly from the keyboard, without echoing
to the screen. If the keyboard queue is empty, ngetchx will wait for the keypress,
else the character will be picked from the keyboard queue.
ngetchx returns the code of the character read from the keyboard. This code is mainly
the same as TI-Basic function GetKey returns. All keypresses which correspond to the
ASCII character will return the ASCII code of it, for example pressing on '+' key will
return the ASCII code of '+' (which is 43 in decimal), so you can write
if (ngetchx () == '+') ...
Codes for some other common keypresses which do not
have an ASCII representation (ESC, ENTER, function keys, etc.) and which are the same on the
TI-89 and TI-92 Plus are defined in the enum CommonKeys (for
example, KEY_ESC, KEY_ENTER etc.).
Be aware that codes assigned to arrow keys is shuffled in
comparation with TI-Basic. These codes are also different on TI-89 and TI-92 Plus.
Note that the documentation of releases of TIGCCLIB prior to 2.0 has an error: it recommends
usage of OSGetStatKeys as a calculator-independent
method for reading arrow keys. This is simply not true. Here is a table of return codes for
pressing arrow keys on TI-89 and TI-92 Plus:
TI-89:
Key | Normal | +Shift | +2nd | +Diamond | +alpha |
Up | 337 | 8529 | 4433 | 16721 | 33105 |
Right | 344 | 8536 | 4440 | 16728 | 33112 |
Down | 340 | 8532 | 4436 | 16724 | 33108 |
Left | 338 | 8530 | 4434 | 16722 | 33106 |
Key | Normal | +Shift | +2nd | +Diamond | +alpha |
Up | 338 | 16722 | 4434 | 8530 | 33106 |
Right | 340 | 16724 | 4436 | 8532 | 33108 |
Down | 344 | 16728 | 4440 | 8536 | 33112 |
Left | 337 | 16721 | 4433 | 8529 | 33105 |
if (key == KEY_LEFT) ...
such test will work fine on both the TI-89 and TI-92 Plus. These pseudo-constants works in both
"nostub" and "DoorsOS" mode. Pseudo-constants KEY_UPRIGHT
and KEY_DOWNLEFT are also defined, with obvious meaning.
Codes of keystrokes like <Diamond> + <key> are also different in
comparison with the TI-Basic GetKey function. I will not give a complete table here, because such
keystrokes are rarely used in programs. If you are interested for a code of the concrete keystroke, you
can easily find it by yourself. Principally, the code for a keystroke like
<Diamond> + <key> is mainly equal to the code for <key> increased by
KEY_DIAMOND. This is also a pseudo-constant with value 16384 on TI-89
and 8192 on TI-92 Plus. The same is true for keystrokes like
<Shift> + <key>, and the appropriate pseudo-constant which need to be added
is called KEY_SHIFT (8192 on TI-89 and 16384 on TI-92 Plus).
As a side effect, ngetchx also sets the activity in the status bar to BUSY, so the
"BUSY" indicator will appear in the status bar. If you want later to remove the "BUSY"
indicator, you must call ST_busy function to do this.
Note: ngetchx function is slow, because it also handles receiving eventual bytes from the
link port. This is used in TIOS mainly when the calculator is in the Home screen, but principally,
if the program is waiting for a keypress using ngetchx function, any valid data which come to the
link port will be received and processed accordingly (for example, the program waiting for a
keypress can accept another program via the link port during waiting).
See kbd_queue for much faster way to gets characters from
the keyboard.
See also: GKeyIn, kbhit, kbd_queue, OSFastArrows
short OSGetStatKeys (void); |
Checks whether an arrow key (TI-89) or status key (TI-92+) is pressed.
OSGetStatKeys is a strange function: it behaves differently on TI-89
and on TI-92 Plus. On TI-89 it returns ARROW_LEFT, ARROW_RIGHT, ARROW_UP
or ARROW_DOWN if one of the corresponding arrow keys is pressed (these
constants are defined in enum Arrows). On
TI-92 Plus it returns STAT_2ND, STAT_DIAMOND, STAT_SHIFT of STAT_HAND
if one of the corresponding status key is pressed (these constants are
defined in enum StatKeys). If no arrow keys is
pressed (TI-89) or if no status keys is pressed (TI-92 Plus), this function
returns zero. OSGetStatKeys does not wait for a keypress. If more than
one arrow/status key is pressed, OSGetStatKeys returns a garbage value.
Note: The information about this functions in releases of TIGCCLIB
prior to 2.0 were incomplete: I didn't notice different behaviour on
TI-89 and TI-92 Plus. So, avoid this function in portable programs.
short OSInitBetweenKeyDelay (short rate); |
Sets the rate at which a key autorepeats.
OSInitBetweenKeyDelay sets the rate at which a key autorepeats to rate
(note that only few keys have an autorepeat feature, namely arrow keys and backspace).
The measuring unit for this function is 1/395 s (because
Auto-Int 1 is triggered 395 times per second), and the default value for
rate is 48. OSInitBetweenKeyDelay returns the previous autorepeat rate.
Greg Dietsche pointed out that on HW2 (precisely, if the gateArray
field of the structure returned by
FL_getHardwareParmBlock
exists and is 2 or higher), TIOS immediately multiplies the value passed to
it by 3/4.
This is probably a bug, as this implies that there is no way to restore the
rate to the value previously returned by OSInitBetweenKeyDelay. To work
around this problem, OSInitBetweenKeyDelay is defined as a macro which
detects this modification in a smart way, and tries to revert it for the
return value.
short OSInitKeyInitDelay (short delay); |
Sets the initial autorepeat key delay.
OSInitKeyInitDelay sets the time that a key has to be held down before it starts to repeat to delay (note that only few keys have autorepeat feature, like arrow keys and backspace). Measuring unit for this function is 1/395 s (because Auto-Int 1 is triggered 395 times per second), and the default value for delay is 336 (slightly shorter than 1 second). OSInitKeyInitDelay returns previous autorepeat key delay.
void pushkey (short code); |
Replaces the keystroke in the keyboard queue with the given code.
If the keyboard queue is empty, pushkey pushes code in the keyboard queue, then sets the "keypressed" flag. If the keyboard queue is not empty, pushkey replaces the keystroke on the top of the keyboard queue with code. In each case, the next call of ngetchx will return code.
void restoreAlphaLock (unsigned char *Status); |
Restores the alpha-lock status.
restoreAlphaLock restores the alpha-lock status to the value saved in Flags,
which is obtained through a call to alphaLockOn or alphaLockOff.
It seems that these are the valid values for *Status:
0 | Alpha-lock is turned off. |
1 | Alpha-lock is turned on. |
2 | Uppercase alpha-lock is turned on. However, GetAlphaStatus will then return FALSE. This is the value which is used if the user presses SHIFT and then ALPHA. |
3 | Uppercase alpha-lock is turned on. GetAlphaStatus will return TRUE. |
See also: alphaLockOn, alphaLockOff, SetAlphaStatus
void SetAlphaStatus (unsigned char Status); |
Sets the alpha-lock status on the TI-89.
There are two valid values for Status: TRUE turns the alpha-lock on; FALSE turns it off.
On the TI-92+, the function does nothing.
See also: GetAlphaStatus
unsigned char OSFastArrows; |
A variable determining whether arrow keys are repeated slowly or quickly.
OSFastArrows tells ngetchx,
GKeyIn, and
OSdequeue how to handle the arrow
keys.
Once a key value is pushed onto the key queue, the same key value is not
pushed again until the key is released, unless that key is one of the
following: any of the arrow keys, the contrast keys, delete, or backspace.
These keys are allowed to "auto-repeat". If one of these keys is pressed
and held, after an initial delay, the same key value will be pushed again. If
the keypress continues to be active, the key value will continue to be
pushed at a rate set by a delay which is slightly shorter than the initial
delay. If a key is pushed as a result of this auto-repeat feature, the value
KB_AUTOREPEAT is OR’d with the key value
prior to pushing the key value onto the key queue.
It seems that the following values are allowed:
0 | Keys are repeated at normal speed. This is the default. In this case, ngetchx will clear the KB_AUTOREPEAT bit from the key value. |
1 | Same as 0 for ngetchx, but in text editors like the home screen entry line, keys are not repeated at all. |
2 | The key delay is ignored; ngetchx returns immediately if an arrow key is pressed. In text editors, the busy indicator is visible, but keys do not seem to be repeated. |
See also: ngetchx, OSInitBetweenKeyDelay, OSInitKeyInitDelay
#define KB_AUTOREPEAT (1<<11) |
A constant defining the "auto-repeat" bit.
KB_AUTOREPEAT is a constant defining the "auto-repeat" bit in key values, please see OSFastArrows for more informations.
See also: OSFastArrows
enum Arrows {ARROW_UP = 1, ARROW_LEFT = 2, ARROW_DOWN = 3, ARROW_RIGHT = 4}; |
An enumeration for describing the four arrow keys.
Arrows is an enumeration for describing the return values of the function OSGetStatKeys, which is used for reading arrow keys (TI-89 only).
enum CommonKeys {KEY_F1 = 268, KEY_F2 = 269, KEY_F3 = 270, KEY_F4 = 271, KEY_F5 = 272, KEY_F6 = 273, KEY_F7 = 274, KEY_F8 = 275, KEY_ESC = 264, KEY_QUIT = 4360, KEY_APPS = 265, KEY_SWITCH = 4361, KEY_MODE = 266, KEY_BACKSPACE = 257, KEY_INS = 4353, KEY_CLEAR = 263, KEY_VARLNK = 4141, KEY_CHAR = 4139, KEY_ENTER = 13, KEY_ENTRY = 4109, KEY_STO = 258, KEY_RCL = 4354, KEY_SIGN = 173, KEY_MATH = 4149, KEY_MEM = 4150, KEY_ON = 267, KEY_OFF = 4363}; |
An enumeration for describing common key codes.
CommonKeys is enumerated type for decribing codes of various common keypresses, which usually does not ASCII representation, and which are the same on TI-89 and TI-92 Plus. Note that codes of keypresses like HOME, CATALOG etc. are not defined here, because they are not the same on TI-89 and TI-92 Plus. See compat.h for more info how to detect the calculator version.
enum GKeyFlags {GKF_NORMAL=0, GKF_MODAL=1, GKF_REPUSH_KEY=2, GKF_ACCEPT=4, GKF_SYS=8, GKF_NO_EVS=16}; |
Enumerates different key options flags for the GKeyIn routine.
Enumerates different key options flags. The meanings of these flags are given in GKeyIn.
See also: GKeyIn
enum StatKeys {STAT_2ND = 1, STAT_DIAMOND = 2, STAT_SHIFT = 3, STAT_HAND = 4}; |
An enumeration for describing modifier key values.
StatKeys is an enumerated type for describing the return values of the function OSGetStatKeys, which is used for reading the status keys (TI-92 Plus only).