The <kbd.h> header file
This header file contains the following functions:
GKeyDown GKeyFlush GKeyIn
kbhit ngetchx OSGetStatKeys
OSInitKeyInitDelay OSInitBetweenKeyDelay pushkey
_rowread
and the following constants and predefined types:
Arrows CommonKeys NULL
SCR_RECT StatKeys
Functions
Checks for currently-available 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.
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 ASCII representation (ESC, ENTER, function keys, etc.) and which are the same on
TI-89 and TI-92 Plus are defined in 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 reccommends
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 |
TI-92+:
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 |
It is interesting that ngetchx function is able to handle pressing to more than one arrow keys
at the same moment. The returned value is then simply logical OR of values for a particular key.
To increase compatibility between TI-89 and TI-92 Plus, a header file compat.h
is implemented. This file (among others) defines pseudo-constants (known from DoorsOS) like
KEY_LEFT, KEY_RIGHT,
KEY_UP and KEY_DOWN
which represents return values for arrow keys. These "pseudo-constants" have different values
on TI-89 and TI-92 Plus, so if you use testing like
if (key == KEY_LEFT) ...
such test will work fine on both 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
comparation with 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 effett, 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.
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 "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.
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.
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.
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 like 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). 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).
- If Flags is different than zero, some special behaviour happens.
Normally, Flags should be zero. It is collection of binary flags, where bits
b0, b1, b3 and b4 are used. They are not very useful, but their meaning is as follows:
- When b0=1, if the pressed key is a modal key (see QModeKey
for info what is a "modal" key for TIOS), GKeyIn will return KEY_ESC instead of
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.
- When b1=1, GKeyIn will not pick a 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.
- When b3=1, if the pressed key is a system key (see QSysKey
for info what is a "system" key for TIOS), GKeyIn will return KEY_ESC (code of ESC key) instead of
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.
- When b4=1, pressing on CATALOG key will be ignored.
Except in noted special cases, GKeyIn returns the same value as ngetchx.
Menus and dialog boxes usually set b0=1 and b3=1, so that if au user presses say VAR-LINK key in the dialog
box, the dialog box is closed and then the VAR-LINK key is acted on.
NOTE: Thomas Nussbaumer informed me that idle interfere with the
grayscale graphic. As GKeyIn calls idle function, usage of
GKeyIn while grayscale mode is active is not recommended.
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.
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 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
rate is 48. OSInitBetweenKeyDelay returns previous autorepeat rate.
Low-level keyboard reading.
_rowread is an inline function for low-level keyboard reading implemented using
GNU C smart macros. _rowread sends row to the I/O port 0x600018 (keyboard
row mask - setting a bit masks the corresponding row of the keyboard from being
read), waits a while to allow the I/O to recover, then returns inverted byte read
from 0x60001B. The byte is inverted for easier testing in C programs. So if a
bit in the result is set, one or more keys in the corresponding column are being held down
(keys in rows masked by row are ignored). This function 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). This function had some
problems with HW2 calculators; this is corrected in release 2.2 of the library.
Here is a table which describes how the keyboard matrix is organized on
both TI-89 and TI-92 Plus:
TI-89:
|
C o l u m n |
R o w |
| Bit 7 |
Bit 6 |
Bit 5 |
Bit 4 |
Bit 3 |
Bit 2 |
Bit 1 |
Bit 0 |
Bit 0 | alpha | Diamnd | Shift | 2nd | Right | Down | Left | Up |
Bit 1 | F5 | CLEAR | ^ | / | * | - | + | ENTER |
Bit 2 | F4 | BckSpc | T | , | 9 | 6 | 3 | (-) |
Bit 3 | F3 | CATLG | Z | ) | 8 | 5 | 2 | . |
Bit 4 | F2 | MODE | Y | ( | 7 | 4 | 1 | 0 |
Bit 5 | F1 | HOME | X | = | | | EE | STO | APPS |
Bit 6 | | | | | | | | ESC |
|
TI-92+:
|
C o l u m n |
R o w |
| Bit 7 |
Bit 6 |
Bit 5 |
Bit 4 |
Bit 3 |
Bit 2 |
Bit 1 |
Bit 0 |
Bit 0 | Down | Right | Up | Left | Hand | Shift | Diamnd | 2nd |
Bit 1 | 3 | 2 | 1 | F8 | W | S | Z | |
Bit 2 | 6 | 5 | 4 | F3 | E | D | X | |
Bit 3 | 9 | 8 | 7 | F7 | R | F | C | STO |
Bit 4 | , | ) | ( | F2 | T | G | V | Space |
Bit 5 | TAN | COS | SIN | F6 | Y | H | B | / |
Bit 6 | P | ENTER2 | LN | F1 | U | J | N | ^ |
Bit 7 | * | APPS | CLEAR | F5 | I | K | M | = |
Bit 8 | | ESC | MODE | + | O | L | Theta | BckSpc |
Bit 9 | (-) | . | 0 | F4 | Q | A | ENTER1 | - |
|
Note for TI-92+: ENTER1 is on the alphabetic and numeric keypads.
ENTER2 is next to the cursor pad.
Because of the way the TI89/TI92+ 's keyboard is wired, if you hold down three
keys that form the corners of a rectangle, the TI89/TI92+ will think you are
also holding down the key at the fourth corner. The [ON] key is special, and is
not part of the matrix.
NOTE: It is recommended to disable Auto-Int 1 (using OSSetSR)
while reading keyboard using _rowread, because keyboard reading routines implemented in Auto-Int 1
may interfere with _rowread if the interrupt occured just while _rowread is executing (although
the probability of such coincidence is small). However, you can not disable Auto-Int 1 in grayscale
programs, because they are based on interrupts: see FAQ list for an explanation
what to do in such cases.
Constants and predefined types
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.
This enum is currently defined as
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};
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.
Arrows is enumerated type for describing return values of function
OSGetStatKeys, which is used for reading arrow keys
(TI-89 only). This enum is defined as
enum Arrows {ARROW_UP = 1, ARROW_LEFT = 2, ARROW_DOWN = 3, ARROW_RIGHT = 4};
StatKeys is enumerated type for describing return values of function
OSGetStatKeys, which is used for reading
status keys (TI-92 Plus only). This enum is defined as
enum StatKeys {STAT_2ND = 1, STAT_DIAMOND = 2, STAT_SHIFT = 3, STAT_HAND = 4};
NULL is a null-pointer value, defined as (void *) 0.
SCR_RECT is a scructure (more precise, an union) for defining a rectangular area
using psysical screen coordinates. It is defined as
typedef union
{
struct
{
unsigned char x0, y0, x1, y1;
} xy;
unsigned long l;
} SCR_RECT;
Instead of giving four coordinates x0, y0, x1 and y1,
it is possible to give all together using a field l which is a packed long
number. See graph.h and wingraph.h
header files for more info about this structure.
NOTE: TIGCC is a GNU C, so it allows cast constructors.
That's why, constructions like
code = GKeyIn (&(SCR_RECT){{50, 20, 56, 26}}, 0);
are legal. See GKeyIn for info about this command.