|
NAMEtermkey - terminal keypress reading libraryDESCRIPTIONtermkey is a library that allows programs to read and interpret keypress and other events from a terminal. It understands encoding schemes used by terminals to encode keypresses, and UTF-8 , allowing it to return events representing key events.termkey operates in a pseudo object-oriented fashion. It provides one function, termkey_new(3), that returns a pointer to a newly-allocated structure. All other functions take this pointer as their first argument. A typical use of this library would consist of a call to termkey_new() to construct a new instance to represent the stdin stream, then use the termkey_waitkey(3) function to wait for and interpret key press events. The termkey_destroy(3) function can be used to deallocate resources used by the instance if the program has finished using it. Reading EventsEach instance of a termkey structure may be used in one of three ways by the program. It may be used synchronously, blocking to wait for keypresses from a filehandle. It may be used asynchronously, returning keypresses if they are available, while co-operating with a non-blocking program. Or it may be used abstractly, interpreting key press bytes fed to it directly by the containing program.To obtain the next key event synchronously, a program may call termkey_waitkey(3). This will either return an event from its internal buffer, or block until a key is available, returning it when it is ready. It behaves similarly to getc(3), fgetc(3), or similar, except that it understands and returns entire key press events, rather than single bytes. To work with an asynchronous program, two other functions are used. termkey_advisereadable(3) informs a termkey instance that more bytes of input may be available from its file handle, so it should call read(2) to obtain them. The program can then call termkey_getkey(3) to extract key press events out of the internal buffer, in a way similar to termkey_waitkey(). Finally, bytes of input can be fed into the termkey instance directly, by calling termkey_push_bytes(3). This may be useful if the bytes have already been read from the terminal by the application, or even in situations that don't directly involve a terminal filehandle. Because of these situations, it is possible to construct a termkey instance not associated with a file handle, by passing -1 as the file descriptor. A termkey instance contains a buffer of pending bytes that have been read but not yet consumed by termkey_getkey(3). termkey_get_buffer_remaining(3) returns the number of bytes of buffer space currently free in the instance. termkey_set_buffer_size(3) and termkey_get_buffer_size(3) can be used to control and return the total size of this buffer. Key EventsKey events are stored in structures. Each structure holds details of one key event. This structure is defined as follows.
typedef struct { TermKeyType type; union { long codepoint; /* TERMKEY_TYPE_UNICODE */ int number; /* TERMKEY_TYPE_FUNCTION */ TermKeySym sym; /* TERMKEY_TYPE_KEYSYM */ } code; int modifiers; char utf8[7]; } TermKeyKey; The type field indicates the type of event, and determines which of the members of the code union is valid. It will be one of the following constants:
The modifiers bitmask is composed of a bitwise-or of the constants TERMKEY_KEYMOD_SHIFT, TERMKEY_KEYMOD_CTRL and TERMKEY_KEYMOD_ALT. The utf8 field is only set on events whose type is TERMKEY_TYPE_UNICODE. It should not be read for other events. Key events that represent special keys (type is TERMKEY_TYPE_KEYSYM) have with them as symbolic value that identifies the special key, in code.sym. termkey_get_keyname(3) may be used to turn this symbolic value into a string, and termkey_lookup_keyname(3) may be used to turn string names into symbolic values. A pair of functions are also provided to convert between key events and strings. termkey_strfkey(3) converts a key event into a string, and termkey_strpkey(3) parses a string turning it into a key event. Key events may be compared for equality or ordering by using termkey_keycmp(3). Control FlagsDetails of the behaviour of a termkey instance are controlled by two bitmasks of flags. termkey_set_flags(3) and termkey_get_flags(3) set or return the flags used to control the general behaviour, and termkey_set_canonflags(3) and termkey_get_canonflags(3) set or return the flags that control the key value canonicalisation behaviour performed by termkey_canonicalise(3).The following control flags are recognised.
The following canonicalisation flags are recognised.
Multi-byte EventsSpecial keys, mouse events, and UTF-8 encoded Unicode text, are all represented by more than one byte. If the start of a multi-byte sequence is seen by termkey_waitkey() it will wait a short time to see if the remainder of the sequence arrives. If the sequence remains unfinished after this timeout, it will be returned in its incomplete state. Partial escape sequences are returned as an Escape key (TERMKEY_SYM_ESCAPE) followed by the text contained in the sequence. Partial UTF-8 sequences are returned as the Unicode replacement character, U+FFFD.The amount of time that the termkey instance will wait is set by termkey_set_waittime(3), and is returned by termkey_get_waittime(3). Initially it will be set to 50 miliseconds. Mouse EventsThe TERMKEY_TYPE_MOUSE event type indicates a mouse event. The code field of the event structure should be considered opaque, though modifiers will be valid. In order to obtain the details of the mouse event, call termkey_interpret_mouse(3) passing the event structure and pointers to integers to store the result in.termkey recognises three mouse protocols: the original X10 protocol (CSI M followed by three bytes), SGR encoding (CSI < ... M, as requested by CSI ? 1006 h), and rxvt encoding (CSI ... M, as requested by CSI ? 1015 h). Which encoding is in use is inferred automatically by termkey, and does not need to be specified explicitly. Position EventsThe TERMKEY_TYPE_POSITION event type indicates a cursor position report. This is typically sent by a terminal in response to the Report Cursor Position command (CSI ? 6 n). The event bytes are opaque, but can be obtained by calling termkey_interpret_position(3) passing the event structure and pointers to integers to store the result in. Note that only a DEC CPR sequence (CSI ? R) is recognised, and not the non-DEC prefixed CSI R because the latter could be interpreted as the F3 function key instead.Mode ReportsThe TERMKEY_TYPE_MODEREPORT event type indicates an ANSI or DEC mode report. This is typically sent by a terminal in response to the Request Mode command (CSI $p or CSI ? $p). The event bytes are opaque, but can be obtained by calling termkey_interpret_modereport(3) passing the event structure and pointers to integers to store the result in.Control StringsThe TERMKEY_TYPE_DCS and TERMKEY_TYPE_OSC event types indicate a DCS or OSC control string. These are typically sent by the terminal in response of similar kinds of strings being sent as queries by the application. The event bytes are opaque, but the body of the string itself can be obtained by calling termkey_interpret_string(3) immediately after this event is received. The underlying termkey instance itself can only store one pending string, so the application should be sure to call this function in a timely manner soon after the event is received; at the very least, before calling any other functions that will insert bytes into or remove key events from the instance.Unrecognised CSIsThe TERMKEY_TYPE_UNKNOWN_CSI event type indicates a CSI sequence that the termkey does not recognise. It will have been extracted from the stream, but is available to the application to inspect by calling termkey_interpret_csi(3). It is important that if the application wishes to inspect this sequence it is done immediately, before any other IO operations on the termkey instance (specifically, before calling termkey_waitkey() or termkey_getkey() again), otherwise the buffer space consumed by the sequence will be overwritten. Other types of key event do not suffer this limitation as the TermKeyKey structure is sufficient to contain all the information required.SEE ALSOtermkey_new(3), termkey_waitkey(3), termkey_getkey(3) Visit the GSP FreeBSD Man Page Interface. |