[comp.lang.ada] Machine-Independent Keystroke Input

RCONN@WSMR-SIMTEL20.ARMY.MIL (Rick Conn) (05/26/89)

Re the recent discussion of this subject, the CAIS (Common
APSE Interface Set) proposes an interesting, altho somewhat involved, solution
to this problem.  Reference DoD-STD-1838 (9 Oct 86), 5.3.8.19 describes
a machine-independent keystroke reader:

	procedure GET (TERMINAL: in FILE_TYPE; ITEM : out CHARACTER;
		KEYS : in out FUNCTION_KEY_DESCRIPTOR);
	-- This procedure reads either a single character into ITEM or
	-- a single function key identification number into KEYS from
	-- the internal file identified by the input file handle TERMINAL.
	-- If no character is available at the time of the call the
	-- interface does not complete until a character becomes available.

This procedure is in package CAIS_SCROLL_TERMINAL_IO (and also in other
CAIS...TERMINAL packages).  Type FUNCTION_KEY_DESCRIPTOR is limited private,
and the package contains many routines to manipulate objects of this class.
In particular, after calling this GET, the procedure FUNCTION_KEY_COUNT
is to be called:

	procedure FUNCTION_KEY_COUNT (KEYS: in FUNCTION_KEY_DESCRIPTOR)
		return CAIS_NATURAL;
	-- Returns the number of function keys described in KEYS

FUNCTION_KEY_COUNT tells us if a character was returned in ITEM from
GET (returned value from FUNCTION_KEY_COUNT is 0) or if a function key
was returned (returned value is 1 since GET returns only one character or
one function key).

If FUNCTION_KEY_COUNT is 1, you can determine the function key's ID
by calling:

	procedure GET_FUNCTION_KEY (KEYS: in FUNCTION_KEY_DESCRIPTOR;
		INDEX : in CAIS_POSITIVE; KEY_IDENTIFIER: out CAIS_POSITIVE;
		POSITION: out CAIS_NATURAL);
	-- This procedure returns the identification number of a function key.
	-- Used with the single-character GET procedure, POSITION = 0.

You would call GET_FUNCTION_KEY with an INDEX value of 1 in order to
return the proper KEY_IDENTIFIER.

Finally, with the KEY_IDENTIFIER, this procedure can be used to get the key's
name:

	function FUNCTION_KEY_IDENTIFICATION (TERMINAL : in FILE_TYPE;
		KEY_IDENTIFIER: in CAIS_POSITIVE) return
		FUNCTION_KEY_NAME;
	-- FUNCTION_KEY_NAME is of subtype STRING and is
	-- implementation-dependent

The problem posed by Dik could be addressed by using a definition like this
and not allowing FUNCTION_KEY_NAME to be implementation-dependent.
In particular, I would like to see FUNCTION_KEY_NAME be an enumeration type
rather than a string (allowing, of course, for "other keys" not covered
by the "standard" enumeration values.  For instance:

	type FUNCTION_KEY_NAME is (PF1, PF2, -- others
		CLEAR_SCREEN, INSERT, DELETE, -- others
		UP_ARROW, DOWN_ARROW, -- others
		-- even more others
		SPECIAL);
	function FUNCTION_KEY_IDENTIFICATION (TERMINAL : in FILE_TYPE;
		KEY_IDENTIFIER: in CAIS_POSITIVE) return
		FUNCTION_KEY_NAME;
	-- FUNCTION_KEY_NAME is now an enumeration type
	function SPECIAL_KEY_IDENTIFICATION (TERMINAL : in FILE_TYPE;
		KEY_IDENTIFIER : in CAIS_POSITIVE) return STRING;
	-- to be called when FUNCTION_KEY_NAME object is SPECIAL

This CAIS definition may be a good starting point.  Part of the
reason for the complexity is that there is another GET which returns
a STRING or a group of FUNCTION KEYS (all keys pressed since the last call to a
GET).  Regardless, I think the CAIS is a good thing to look at when
discussing machine-independent problems like this one.

	Rick
-------