WIP: Is mine now (^3^)

Seriously though, I've got some issues with how this thing is designed,
as well as with its formatting, and when you add the fact that the
original author wants to merge this thing into his bigger library that
also handles terminal output, which I'll kindly leave to ncurses,
it kind of makes sense for me to do this.

Manpages have been removed as they are going to become obsolete and
they're rather difficult to maintain.  If anything, there will be
Doxygen-generated documentation.

The plan is to throw away any direct UTF-8 support and support all uni-
and multibyte character encodings.  However some unrelated refactoring
is about to come first.
This commit is contained in:
Přemysl Eric Janouch 2014-09-23 01:38:08 +02:00
parent 7909067ac0
commit b630bf7a5f
35 changed files with 2752 additions and 3352 deletions

View File

@ -1,10 +0,0 @@
termkey.h
demo
demo-async
demo-glib
termkey_getkey.3
termkey_waitkey.3
*.lo
*.la
.libs
t/*.t

View File

@ -1,8 +1,5 @@
The MIT License
Copyright (c) 2007-2011 Paul Evans <leonerd@leonerd.org.uk>
Copyright (c) 2007-2014 Paul Evans <leonerd@leonerd.org.uk>
Copyright (c) 2014 Přemysl Janouch <p.janouch@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -6,59 +6,62 @@
#include "termkey.h"
static void on_key(TermKey *tk, TermKeyKey *key)
static void
on_key (termkey_t *tk, termkey_key_t *key)
{
char buffer[50];
termkey_strfkey(tk, buffer, sizeof buffer, key, TERMKEY_FORMAT_VIM);
printf("%s\n", buffer);
char buffer[50];
termkey_strfkey (tk, buffer, sizeof buffer, key, TERMKEY_FORMAT_VIM);
printf ("%s\n", buffer);
}
int main(int argc, char *argv[])
int
main (int argc, char *argv[])
{
TERMKEY_CHECK_VERSION;
TERMKEY_CHECK_VERSION;
TermKey *tk = termkey_new(0, 0);
termkey_t *tk = termkey_new (0, 0);
if(!tk) {
fprintf(stderr, "Cannot allocate termkey instance\n");
exit(1);
}
if (!tk)
{
fprintf (stderr, "Cannot allocate termkey instance\n");
exit (1);
}
struct pollfd fd;
struct pollfd fd;
fd.fd = 0; /* the file descriptor we passed to termkey_new() */
fd.events = POLLIN;
fd.fd = 0; /* the file descriptor we passed to termkey_new() */
fd.events = POLLIN;
termkey_result_t ret;
termkey_key_t key;
TermKeyResult ret;
TermKeyKey key;
int running = 1;
int nextwait = -1;
int running = 1;
int nextwait = -1;
while (running)
{
if (poll (&fd, 1, nextwait) == 0)
// Timed out
if (termkey_getkey_force (tk, &key) == TERMKEY_RES_KEY)
on_key (tk, &key);
while(running) {
if(poll(&fd, 1, nextwait) == 0) {
// Timed out
if(termkey_getkey_force(tk, &key) == TERMKEY_RES_KEY)
on_key(tk, &key);
}
if (fd.revents & (POLLIN | POLLHUP | POLLERR))
termkey_advisereadable (tk);
if(fd.revents & (POLLIN|POLLHUP|POLLERR))
termkey_advisereadable(tk);
while ((ret = termkey_getkey (tk, &key)) == TERMKEY_RES_KEY)
{
on_key (tk, &key);
while((ret = termkey_getkey(tk, &key)) == TERMKEY_RES_KEY) {
on_key(tk, &key);
if (key.type == TERMKEY_TYPE_UNICODE
&& key.modifiers & TERMKEY_KEYMOD_CTRL
&& (key.code.codepoint == 'C' || key.code.codepoint == 'c'))
running = 0;
}
if(key.type == TERMKEY_TYPE_UNICODE &&
key.modifiers & TERMKEY_KEYMOD_CTRL &&
(key.code.codepoint == 'C' || key.code.codepoint == 'c'))
running = 0;
}
if (ret == TERMKEY_RES_AGAIN)
nextwait = termkey_get_waittime (tk);
else
nextwait = -1;
}
if(ret == TERMKEY_RES_AGAIN)
nextwait = termkey_get_waittime(tk);
else
nextwait = -1;
}
termkey_destroy(tk);
termkey_destroy (tk);
}

View File

@ -3,63 +3,63 @@
#include "termkey.h"
static TermKey *tk;
static termkey_t *tk;
static int timeout_id;
static void on_key(TermKey *tk, TermKeyKey *key)
static void
on_key (termkey_t *tk, termkey_key_t *key)
{
char buffer[50];
termkey_strfkey(tk, buffer, sizeof buffer, key, TERMKEY_FORMAT_VIM);
printf("%s\n", buffer);
char buffer[50];
termkey_strfkey (tk, buffer, sizeof buffer, key, TERMKEY_FORMAT_VIM);
printf ("%s\n", buffer);
}
static gboolean key_timer(gpointer data)
static gboolean
key_timer (gpointer data)
{
TermKeyKey key;
if(termkey_getkey_force(tk, &key) == TERMKEY_RES_KEY)
on_key(tk, &key);
return FALSE;
termkey_key_t key;
if (termkey_getkey_force (tk, &key) == TERMKEY_RES_KEY)
on_key (tk, &key);
return FALSE;
}
static gboolean stdin_io(GIOChannel *source, GIOCondition condition, gpointer data)
static gboolean
stdin_io (GIOChannel *source, GIOCondition condition, gpointer data)
{
if(condition && G_IO_IN) {
if(timeout_id)
g_source_remove(timeout_id);
if (condition && G_IO_IN)
{
if (timeout_id)
g_source_remove (timeout_id);
termkey_advisereadable(tk);
termkey_advisereadable (tk);
TermKeyResult ret;
TermKeyKey key;
while((ret = termkey_getkey(tk, &key)) == TERMKEY_RES_KEY) {
on_key(tk, &key);
}
termkey_result_t ret;
termkey_key_t key;
while ((ret = termkey_getkey (tk, &key)) == TERMKEY_RES_KEY)
on_key (tk, &key);
if(ret == TERMKEY_RES_AGAIN)
timeout_id = g_timeout_add(termkey_get_waittime(tk), key_timer, NULL);
}
if (ret == TERMKEY_RES_AGAIN)
timeout_id = g_timeout_add
(termkey_get_waittime (tk), key_timer, NULL);
}
return TRUE;
return TRUE;
}
int main(int argc, char *argv[])
int
main (int argc, char *argv[])
{
TERMKEY_CHECK_VERSION;
TERMKEY_CHECK_VERSION;
tk = termkey_new(0, 0);
tk = termkey_new (0, 0);
if (!tk)
{
fprintf (stderr, "Cannot allocate termkey instance\n");
exit (1);
}
if(!tk) {
fprintf(stderr, "Cannot allocate termkey instance\n");
exit(1);
}
GMainLoop *loop = g_main_loop_new(NULL, FALSE);
g_io_add_watch(g_io_channel_unix_new(0), G_IO_IN, stdin_io, NULL);
g_main_loop_run(loop);
termkey_destroy(tk);
GMainLoop *loop = g_main_loop_new (NULL, FALSE);
g_io_add_watch (g_io_channel_unix_new (0), G_IO_IN, stdin_io, NULL);
g_main_loop_run (loop);
termkey_destroy (tk);
}

201
demo.c
View File

@ -7,112 +7,129 @@
#include "termkey.h"
int main(int argc, char *argv[])
int
main(int argc, char *argv[])
{
TERMKEY_CHECK_VERSION;
TERMKEY_CHECK_VERSION;
int mouse = 0;
int mouse_proto = 0;
TermKeyFormat format = TERMKEY_FORMAT_VIM;
int mouse = 0;
int mouse_proto = 0;
termkey_format_t format = TERMKEY_FORMAT_VIM;
char buffer[50];
TermKey *tk;
char buffer[50];
termkey_t *tk;
int opt;
while((opt = getopt(argc, argv, "m::p:")) != -1) {
switch(opt) {
case 'm':
if(optarg)
mouse = atoi(optarg);
else
mouse = 1000;
int opt;
while ((opt = getopt (argc, argv, "m::p:")) != -1)
{
switch (opt)
{
case 'm':
if (optarg)
mouse = atoi (optarg);
else
mouse = 1000;
break;
break;
case 'p':
mouse_proto = atoi (optarg);
break;
case 'p':
mouse_proto = atoi(optarg);
break;
default:
fprintf (stderr, "Usage: %s [-m]\n", argv[0]);
return 1;
}
}
default:
fprintf(stderr, "Usage: %s [-m]\n", argv[0]);
return 1;
}
}
tk = termkey_new (0, TERMKEY_FLAG_SPACESYMBOL | TERMKEY_FLAG_CTRLC);
tk = termkey_new(0, TERMKEY_FLAG_SPACESYMBOL|TERMKEY_FLAG_CTRLC);
if (!tk)
{
fprintf (stderr, "Cannot allocate termkey instance\n");
exit (1);
}
if(!tk) {
fprintf(stderr, "Cannot allocate termkey instance\n");
exit(1);
}
if (termkey_get_flags (tk) & TERMKEY_FLAG_UTF8)
printf ("Termkey in UTF-8 mode\n");
else if (termkey_get_flags (tk) & TERMKEY_FLAG_RAW)
printf ("Termkey in RAW mode\n");
if(termkey_get_flags(tk) & TERMKEY_FLAG_UTF8)
printf("Termkey in UTF-8 mode\n");
else if(termkey_get_flags(tk) & TERMKEY_FLAG_RAW)
printf("Termkey in RAW mode\n");
termkey_result_t ret;
termkey_key_t key;
TermKeyResult ret;
TermKeyKey key;
if (mouse)
{
printf ("\033[?%dhMouse mode active\n", mouse);
if (mouse_proto)
printf ("\033[?%dh", mouse_proto);
}
if(mouse) {
printf("\033[?%dhMouse mode active\n", mouse);
if(mouse_proto)
printf("\033[?%dh", mouse_proto);
}
while ((ret = termkey_waitkey (tk, &key)) != TERMKEY_RES_EOF)
{
if (ret == TERMKEY_RES_KEY)
{
termkey_strfkey (tk, buffer, sizeof buffer, &key, format);
if (key.type == TERMKEY_TYPE_MOUSE)
{
int line, col;
termkey_interpret_mouse (tk, &key, NULL, NULL, &line, &col);
printf ("%s at line=%d, col=%d\n", buffer, line, col);
}
else if (key.type == TERMKEY_TYPE_POSITION)
{
int line, col;
termkey_interpret_position (tk, &key, &line, &col);
printf ("Cursor position report at line=%d, col=%d\n",
line, col);
}
else if (key.type == TERMKEY_TYPE_MODEREPORT)
{
int initial, mode, value;
termkey_interpret_modereport
(tk, &key, &initial, &mode, &value);
printf ("Mode report %s mode %d = %d\n",
initial ? "DEC" : "ANSI", mode, value);
}
else if (key.type == TERMKEY_TYPE_UNKNOWN_CSI)
{
long args[16];
size_t nargs = 16;
unsigned long command;
termkey_interpret_csi (tk, &key, args, &nargs, &command);
printf ("Unrecognised CSI %c %ld;%ld %c%c\n",
(char) (command >> 8), args[0], args[1],
(char) (command >> 16), (char) command);
}
else
printf ("Key %s\n", buffer);
while((ret = termkey_waitkey(tk, &key)) != TERMKEY_RES_EOF) {
if(ret == TERMKEY_RES_KEY) {
termkey_strfkey(tk, buffer, sizeof buffer, &key, format);
if(key.type == TERMKEY_TYPE_MOUSE) {
int line, col;
termkey_interpret_mouse(tk, &key, NULL, NULL, &line, &col);
printf("%s at line=%d, col=%d\n", buffer, line, col);
}
else if(key.type == TERMKEY_TYPE_POSITION) {
int line, col;
termkey_interpret_position(tk, &key, &line, &col);
printf("Cursor position report at line=%d, col=%d\n", line, col);
}
else if(key.type == TERMKEY_TYPE_MODEREPORT) {
int initial, mode, value;
termkey_interpret_modereport(tk, &key, &initial, &mode, &value);
printf("Mode report %s mode %d = %d\n", initial ? "DEC" : "ANSI", mode, value);
}
else if(key.type == TERMKEY_TYPE_UNKNOWN_CSI) {
long args[16];
size_t nargs = 16;
unsigned long command;
termkey_interpret_csi(tk, &key, args, &nargs, &command);
printf("Unrecognised CSI %c %ld;%ld %c%c\n", (char)(command >> 8), args[0], args[1], (char)(command >> 16), (char)command);
}
else {
printf("Key %s\n", buffer);
}
if (key.type == TERMKEY_TYPE_UNICODE
&& key.modifiers & TERMKEY_KEYMOD_CTRL
&& (key.code.codepoint == 'C' || key.code.codepoint == 'c'))
break;
if(key.type == TERMKEY_TYPE_UNICODE &&
key.modifiers & TERMKEY_KEYMOD_CTRL &&
(key.code.codepoint == 'C' || key.code.codepoint == 'c'))
break;
if (key.type == TERMKEY_TYPE_UNICODE
&& key.modifiers == 0
&& key.code.codepoint == '?')
{
// printf("\033[?6n"); // DECDSR 6 == request cursor position
printf ("\033[?1$p"); // DECRQM == request mode, DEC origin mode
fflush (stdout);
}
}
else if (ret == TERMKEY_RES_ERROR)
{
if (errno != EINTR)
{
perror("termkey_waitkey");
break;
}
printf ("Interrupted by signal\n");
}
}
if(key.type == TERMKEY_TYPE_UNICODE &&
key.modifiers == 0 &&
key.code.codepoint == '?') {
// printf("\033[?6n"); // DECDSR 6 == request cursor position
printf("\033[?1$p"); // DECRQM == request mode, DEC origin mode
fflush(stdout);
}
}
else if(ret == TERMKEY_RES_ERROR) {
if(errno != EINTR) {
perror("termkey_waitkey");
break;
}
printf("Interrupted by signal\n");
}
}
if (mouse)
printf ("\033[?%dlMouse mode deactivated\n", mouse);
if(mouse)
printf("\033[?%dlMouse mode deactivated\n", mouse);
termkey_destroy(tk);
termkey_destroy (tk);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +0,0 @@
termkey_destroy.3 = termkey_new.3
termkey_new_abstract.3 = termkey_new.3
termkey_get_flags.3 = termkey_set_flags.3
termkey_get_canonflags.3 = termkey_set_canonflags.3
termkey_get_buffer_size.3 = termkey_set_buffer_size.3
termkey_get_waittime.3 = termkey_set_waittime.3
termkey_getkey_force.3 = termkey_getkey.3
termkey_stop.3 = termkey_start.3
termkey_is_started.3 = termkey_start.3

View File

@ -1,145 +0,0 @@
.TH TERMKEY 7
.SH NAME
termkey \- terminal keypress reading library
.SH DESCRIPTION
\fBtermkey\fP 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
.SM UTF-8 ,
allowing it to return events representing key events.
.PP
\fBtermkey\fP operates in a pseudo object-oriented fashion. It provides one function, \fBtermkey_new\fP(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 \fBtermkey_new\fP() to construct a new instance to represent the \fIstdin\fP stream, then use the \fBtermkey_waitkey\fP(3) function to wait for and interpret key press events. The \fBtermkey_destroy\fP(3) function can be used to deallocate resources used by the instance if the program has finished using it.
.SS Reading Events
Each instance of a \fBtermkey\fP 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.
.PP
To obtain the next key event synchronously, a program may call \fBtermkey_waitkey\fP(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 \fBgetc\fP(3), \fBfgetc\fP(3), or similar, except that it understands and returns entire key press events, rather than single bytes.
.PP
To work with an asynchronous program, two other functions are used. \fBtermkey_advisereadable\fP(3) informs a \fBtermkey\fP instance that more bytes of input may be available from its file handle, so it should call \fBread\fP(2) to obtain them. The program can then call \fBtermkey_getkey\fP(3) to extract key press events out of the internal buffer, in a way similar to \fBtermkey_waitkey\fP().
.PP
Finally, bytes of input can be fed into the \fBtermkey\fP instance directly, by calling \fBtermkey_push_bytes\fP(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 \fBtermkey\fP instance not associated with a file handle, by passing -1 as the file descriptor.
.PP
A \fBtermkey\fP instance contains a buffer of pending bytes that have been read but not yet consumed by \fBtermkey_getkey\fP(3). \fBtermkey_get_buffer_remaining\fP(3) returns the number of bytes of buffer space currently free in the instance. \fBtermkey_set_buffer_size\fP(3) and \fBtermkey_get_buffer_size\fP(3) can be used to control and return the total size of this buffer.
.SS Key Events
Key events are stored in structures. Each structure holds details of one key event. This structure is defined as follows.
.PP
.in +4n
.nf
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;
.fi
.in
.PP
The \fItype\fP field indicates the type of event, and determines which of the members of the \fIcode\fP union is valid. It will be one of the following constants:
.TP
.B TERMKEY_TYPE_UNICODE
a Unicode codepoint. This value indicates that \fIcode.codepoint\fP is valid, and will contain the codepoint number of the keypress. In Unicode mode (if the \fBTERMKEY_FLAG_UTF8\fP bit is set) this will be its Unicode character number. In raw byte mode, this will contain a single 8-bit byte.
.TP
.B TERMKEY_TYPE_FUNCTION
a numbered function key. This value indicates that \fIcode.number\fP is valid, and contains the number of the numbered function key.
.TP
.B TERMKEY_TYPE_KEYSYM
a symbolic key. This value indicates that \fIcode.sym\fP is valid, and contains the symbolic key value.
.TP
.B TERMKEY_TYPE_MOUSE
a mouse button press, release, or movement. The \fIcode\fP structure should be considered opaque; \fBtermkey_interpret_mouse\fP(3) may be used to interpret it.
.TP
.B TERMKEY_TYPE_POSITION
a cursor position report. The \fIcode\fP structure should be considered opaque; \fBtermkey_interpret_position\fP(3) may be used to interpret it.
.TP
.B TERMKEY_TYPE_MODEREPORT
an ANSI or DEC mode value report. The \fIcode\fP structure should be considered opaque; \fBtermkey_interpret_modereport\fP(3) may be used to interpret it.
.TP
.B TERMKEY_TYPE_UNKNOWN_CSI
an unrecognised CSI sequence. The \fIcode\fP structure should be considered opaque; \fBtermkey_interpret_csi\fP(3) may be used to interpret it.
.PP
The \fImodifiers\fP bitmask is composed of a bitwise-or of the constants \fBTERMKEY_KEYMOD_SHIFT\fP, \fBTERMKEY_KEYMOD_CTRL\fP and \fBTERMKEY_KEYMOD_ALT\fP.
.PP
The \fIutf8\fP field is only set on events whose \fItype\fP is \fBTERMKEY_TYPE_UNICODE\fP. It should not be read for other events.
.PP
Key events that represent special keys (\fItype\fP is \fBTERMKEY_TYPE_KEYSYM\fP) have with them as symbolic value that identifies the special key, in \fIcode.sym\fP. \fBtermkey_get_keyname\fP(3) may be used to turn this symbolic value into a string, and \fBtermkey_lookup_keyname\fP(3) may be used to turn string names into symbolic values.
.PP
A pair of functions are also provided to convert between key events and strings. \fBtermkey_strfkey\fP(3) converts a key event into a string, and \fBtermkey_strpkey\fP(3) parses a string turning it into a key event.
.PP
Key events may be compared for equallity or ordering by using \fBtermkey_keycmp\fP(3).
.SS Control Flags
Details of the behaviour of a \fBtermkey\fP instance are controlled by two bitmasks of flags. \fBtermkey_set_flags\fP(3) and \fBtermkey_get_flags\fP(3) set or return the flags used to control the general behaviour, and \fBtermkey_set_canonflags\fP(3) and \fBtermkey_get_canonflags\fP(3) set or return the flags that control the key value canonicalisation behaviour performed by \fBtermkey_canonicalise\fP(3).
.PP
The following control flags are recognised.
.TP
.B TERMKEY_FLAG_NOINTERPRET
Do not attempt to interpret \fIC0\fP codes into keysyms. Instead report them as plain \fICtrl-letter\fP events.
.TP
.B TERMKEY_FLAG_CONVERTKP
Convert xterm's alternative keypad symbols into the plain
.SM ASCII
codes they would represent.
.TP
.B TERMKEY_FLAG_RAW
Ignore locale settings; do not attempt to recombine
.SM UTF-8
sequences. Instead report only raw values.
.TP
.B TERMKEY_FLAG_UTF8
Ignore locale settings; force
.SM UTF-8
recombining on. This flag overrides \fBTERMKEY_FLAG_RAW\fP.
.TP
.B TERMKEY_FLAG_NOTERMIOS
Even if the terminal file descriptor \fIfd\fP represents a
.SM TTY
device, do not call the \fBtcsetattr\fP(3) \fBtermios\fP function on it to set it to canonical input mode.
.TP
.B TERMKEY_FLAG_SPACESYMBOL
Report space as being a symbolic key rather than a Unicode codepoint. Setting or clearing this flag in fact sets or clears the \fBTERMKEY_CANON_SPACESYMBOL\fP canonicalisation flag.
.TP
.B TERMKEY_FLAG_CTRLC
Disable the \fBSIGINT\fP behaviour of \fICtrl-C\fP. If this flag is provided, then \fICtrl-C\fP will be available as a normal keypress, rather than sending the process group a \fBSIGINT\fP. This flag only takes effect without \fBTERMKEY_FLAG_NOTERMIOS\fP; with it, none of the signal keys are disabled anyway.
.TP
.B TERMKEY_FLAG_EINTR
Without this flag, IO operations are retried when interrupted by a signal (\fBEINTR\fP). With this flag the \fBTERMKEY_RES_ERROR\fP result is returned instead.
.PP
The following canonicalisation flags are recognised.
.TP
.B TERMKEY_CANON_SPACESYMBOL
If this flag is set then a Unicode space character is represented using the \fBTERMKEY_SYM_SPACE\fP symbol. If this flag is not set, it is represented by the \f(CWU+0020\fP Unicode codepoint.
.TP
.B TERMKEY_CANON_DELBS
If this flag is set then an
.SM ASCII
.SM DEL
character is represented by the \fBTERMKEY_SYM_BACKSPACE\fP symbol. If not, it is represented by \fBTERMKEY_SYM_DEL\fP. An
.SM ASCII
.SM BS
character is always represented by \fBTERMKEY_SYM_BACKSPACE\fP, regardless of this flag.
.SS Multi-byte Events
Special keys, mouse events, and
.SM UTF-8
encoded Unicode text, are all represented by more than one byte. If the start of a multi-byte sequence is seen by \fBtermkey_waitkey\fP() 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 (\fBTERMKEY_SYM_ESCAPE\fP) followed by the text contained in the sequence. Partial
.SM UTF-8
sequences are returned as the Unicode replacement character, \f(CWU+FFFD\fP.
.PP
The amount of time that the \fBtermkey\fP instance will wait is set by \fBtermkey_set_waittime\fP(3), and is returned by \fBtermkey_get_waittime\fP(3). Initially it will be set to 50 miliseconds.
.SS Mouse Events
The \fBTERMKEY_TYPE_MOUSE\fP event type indicates a mouse event. The \fIcode\fP field of the event structure should be considered opaque, though \fImodifiers\fP will be valid. In order to obtain the details of the mouse event, call \fBtermkey_interpret_mouse\fP(3) passing the event structure and pointers to integers to store the result in.
.PP
\fBtermkey\fP recognises three mouse protocols: the original
.SM X10
protocol (\f(CWCSI M\fP followed by three bytes),
.SM SGR
encoding (\f(CWCSI < ... M\fP, as requested by \f(CWCSI ? 1006 h\fP), and rxvt encoding (\f(CWCSI ... M\fP, as requested by \f(CWCSI ? 1015 h\fP). Which encoding is in use is inferred automatically by \fBtermkey\fP, and does not need to be specified explicitly.
.SS Position Events
The \fBTERMKEY_TYPE_POSITION\fP event type indicates a cursor position report. This is typically sent by a terminal in response to the Report Cursor Position command (\f(CWCSI ? 6 n\fP). The event bytes are opaque, but can be obtained by calling \fBtermkey_interpret_position\fP(3) passing the event structure and pointers to integers to store the result in. Note that only a DEC CPR sequence (\f(CWCSI ? R\fP) is recognised, and not the non-DEC prefixed \f(CWCSI R\fP because the latter could be interpreted as the \f(CWF3\fP function key instead.
.SS Mode Reports
The \fBTERMKEY_TYPE_MODEREPORT\fP event type indicates an ANSI or DEC mode report. This is typically sent by a terminal in response to the Request Mode command (\f(CWCSI $p\fP or \f(CWCSI ? $p\fP). The event bytes are opaque, but can be obtained by calling \fBtermkey_interpret_modereport\fP(3) passing the event structure and pointers to integers to store the result in.
.SS Unrecognised CSIs
The \fBTERMKEY_TYPE_UNKNOWN_CSI\fP event type indicates a CSI sequence that the \fBtermkey\fP does not recognise. It will have been extracted from the stream, but is available to the application to inspect by calling \fBtermkey_interpret_csi\fP(3). It is important that if the application wishes to inspect this sequence it is done immediately, before any other IO operations on the \fBtermkey\fP instance (specifically, before calling \fBtermkey_waitkey\fP() or \fBtermkey_getkey\fP() again), otherwise the buffer space consumed by the sequence will be overwritten. Other types of key event do not suffer this limitation as the \fBTermKeyKey\fP structure is sufficient to contain all the information required.
.SH "SEE ALSO"
.BR termkey_new (3),
.BR termkey_waitkey (3),
.BR termkey_getkey (3)

View File

@ -1,33 +0,0 @@
.TH TERMKEY_ADVISEREADABLE 3
.SH NAME
termkey_advisereadable \- read more bytes from the underlying terminal
.SH SYNOPSIS
.nf
.B #include <termkey.h>
.sp
.BI "TermKeyResult termkey_advisereadable(TermKey *" tk );
.fi
.sp
Link with \fI-ltermkey\fP.
.SH DESCRIPTION
\fBtermkey_advisereadable\fP() informs the \fBtermkey\fP(7) instance that new input may be available on the underlying file descriptor and so it should call \fBread\fP(2) to obtain it. If at least one more byte was read it will return \fBTERMKEY_RES_AGAIN\fP to indicate it may be useful to call \fBtermkey_getkey\fP(3) again. If no more input was read then \fBTERMKEY_RES_NONE\fP is returned. If there was no buffer space remaining, then \fBTERMKEY_RES_ERROR\fP is returned with \fIerrno\fP set to \fBENOMEM\fP. If no filehandle is associated with this instance, \fBTERMKEY_RES_ERROR\fP is returned with \fIerrno\fP set to \fBEBADF\fP.
.PP
This function, along with \fBtermkey_getkey\fP(3) make it possible to use the termkey instance in an asynchronous program. To provide bytes without using a readable file handle, use \fBtermkey_push_bytes\fP(3).
.PP
For synchronous usage, \fBtermkey_waitkey\fP(3) performs the input blocking task.
.SH "RETURN VALUE"
\fBtermkey_advisereadable\fP() returns one of the following constants:
.TP
.B TERMKEY_RES_AGAIN
At least one byte was read.
.TP
.B TERMKEY_RES_NONE
No nore bytes were read.
.TP
.B TERMKEY_RES_ERROR
An IO error occured. \fIerrno\fP will be preserved. If the error is \fBEINTR\fP then this will only be returned if \fBTERMKEY_FLAG_EINTR\fP flag is not set; if it is then the IO operation will be retried instead.
.SH "SEE ALSO"
.BR termkey_getkey (3),
.BR termkey_waitkey (3),
.BR termkey_set_waittime (3),
.BR termkey (7)

View File

@ -1,22 +0,0 @@
.TH TERMKEY_CANONICALISE 3
.SH NAME
termkey_canonicalise \- canonicalise a key event
.SH SYNOPSIS
.nf
.B #include <termkey.h>
.sp
.BI "void termkey_canonicalise(TermKey *" tk ", TermKeyKey *" key );
.fi
.sp
Link with \fI-ltermkey\fP.
.SH DESCRIPTION
\fBtermkey_canonicalise\fP(3) modifies the key event structure given by \fIkey\fP according to the canonicalisation flags set on the given \fBtermkey\fP instance. This operation is performed implicitly by \fBtermkey_getkey\fP(3), \fBtermkey_waitkey\fP(3) and \fBtermkey_strpkey\fP(3), and is also provided explicitly by this function.
.PP
See \fBtermkey\fP(7) for a list of canonicalisation flags.
.SH "RETURN VALUE"
\fBtermkey_canonicalise\fP() returns no value.
.SH "SEE ALSO"
.BR termkey_set_canonflags (3),
.BR termkey_waitkey (3),
.BR termkey_strpkey (3),
.BR termkey (7)

View File

@ -1,23 +0,0 @@
.TH TERMKEY_GET_BUFFER_REMAINING 3
.SH NAME
termkey_get_buffer_remaining \- returns the free buffer space
.SH SYNOPSIS
.nf
.B #include <termkey.h>
.sp
.BI "size_t termkey_get_buffer_remaining(TermKey *" tk ");
.fi
.sp
Link with \fI-ltermkey\fP.
.SH DESCRIPTION
\fBtermkey_get_buffer_remaining\fP() returns the number of bytes of buffer space currently free in the \fBtermkey\fP(7) instance. These bytes are free to use by \fBtermkey_push_bytes\fP(3), or may be filled by \fBtermkey_advisereadable\fP(3).
.PP
.SH "RETURN VALUE"
\fBtermkey_get_buffer_remaining\fP() returns a size in bytes.
.SH "SEE ALSO"
.BR termkey_push_bytes (3),
.BR termkey_advisereadable (3),
.BR termkey_set_buffer_size (3),
.BR termkey_get_buffer_size (3),
.BR termkey_getkey (3),
.BR termkey (7)

View File

@ -1,19 +0,0 @@
.TH TERMKEY_GET_FD 3
.SH NAME
termkey_get_fd \- obtain the file descriptor for the terminal
.SH SYNOPSIS
.nf
.B #include <termkey.h>
.sp
.BI "int termkey_get_fd(TermKey *" tk );
.fi
.sp
Link with \fI-ltermkey\fP.
.SH DESCRIPTION
\fBtermkey_get_fd\fP() returns the file descriptor that the \fBtermkey\fP(7) instance is using to read bytes from.
.SH "RETURN VALUE"
\fBtermkey_get_fd\fP() returns the current file descriptor, or -1 if no file descriptor is associated with this instance.
.SH "SEE ALSO"
.BR termkey_new (3),
.BR termkey_get_flags (3),
.BR termkey (7)

View File

@ -1,20 +0,0 @@
.TH TERMKEY_GET_KEYNAME 3
.SH NAME
termkey_get_keyname \- return a string name for a symbolic key
.SH SYNOPSIS
.nf
.B #include <termkey.h>
.sp
.BI "const char *termkey_get_keyname(TermKey *" tk ", TermKeySym " sym );
.fi
.sp
Link with \fI-ltermkey\fP.
.SH DESCRIPTION
\fBtermkey_get_keyname\fP() returns a human-readable string name for the symbolic key value given by \fIsym\fP. The returned string is owned by the \fBtermkey\fP(7) instance \fItk\fP so should not be modified or freed. The returned pointer is guaranteed to be valid until the instance is released using \fBtermkey_destroy\fP(3). This function is the inverse of \fBtermkey_keyname2sym\fP(3).
.SH "RETURN VALUE"
\fBtermkey_get_key\fP() returns a pointer to a string.
.SH "SEE ALSO"
.BR termkey_lookup_keyname (3),
.BR termkey_keyname2sym (3),
.BR termkey_strfkey (3),
.BR termkey (7)

View File

@ -1,56 +0,0 @@
# vim:ft=nroff
cat <<EOF
.TH TERMKEY_GETKEY 3
.SH NAME
termkey_getkey, termkey_getkey_force \- retrieve the next key event
.SH SYNOPSIS
.nf
.B #include <termkey.h>
.sp
.BI "TermKeyResult termkey_getkey(TermKey *" tk ", TermKeyKey *" key );
.BI "TermKeyResult termkey_getkey_force(TermKey *" tk ", TermKeyKey *" key );
.fi
.sp
Link with \fI-ltermkey\fP.
.SH DESCRIPTION
\fBtermkey_getkey\fP() attempts to retrieve a single keypress event from the \fBtermkey\fP(7) instance buffer, and put it in the structure referred to by \fIkey\fP. It returns one of the following values:
.in
.TP
.B TERMKEY_RES_KEY
a complete keypress was removed from the buffer, and has been placed in the \fIkey\fP structure.
.TP
.B TERMKEY_RES_AGAIN
a partial keypress event was found in the buffer, but it does not yet contain all the bytes required. An indication of what \fBtermkey_getkey_force\fP() would return has been placed in the \fIkey\fP structure.
.TP
.B TERMKEY_RES_NONE
no bytes are waiting in the buffer.
.TP
.B TERMKEY_RES_EOF
no bytes are ready and the input stream is now closed.
.TP
.B TERMKEY_RES_ERROR
called with terminal IO stopped, due to \fBtermkey_stop\fP(3). In this case \fIerrno\fP will be set to \fBEINVAL\fP.
.PP
\fBtermkey_getkey_force\fP() is similar to \fBtermkey_getkey\fP() but will not return \fBTERMKEY_RES_AGAIN\fP if a partial match is found. Instead, it will force an interpretation of the bytes, even if this means interpreting the start of an Escape-prefixed multi-byte sequence as a literal \fIEscape\fP key followed by normal letters.
.PP
Neither of these functions will block or perform any IO operations on the underlying filehandle. To use the instance in an asynchronous program, see \fBtermkey_advisereadable\fP(3). For a blocking call suitable for use in a synchronous program, use \fBtermkey_waitkey\fP(3) instead of \fBtermkey_getkey\fP(). For providing input without a readable filehandle, use \fBtermkey_push_bytes\fP(3).
.PP
Before returning, this function canonicalises the \fIkey\fP structure according to the rules given for \fBtermkey_canonicalise\fP(3).
.SH "RETURN VALUE"
\fBtermkey_getkey\fP() returns an enumeration of one of \fBTERMKEY_RES_KEY\fP, \fBTEMRKEY_RES_AGAIN\fP, \fBTERMKEY_RES_NONE\fP, \fBTERMKEY_RES_EOF\fP or \fBTERMKEY_RES_ERROR\fP. \fBtermkey_getkey_force\fP() returns one of the above, except for \fBTERMKEY_RES_AGAIN\fP.
.SH EXAMPLE
The following example program prints details of every keypress until the user presses \fICtrl-C\fP. It demonstrates how to use the \fBtermkey\fP instance in a typical \fBpoll\fP(2)-driven asynchronous program, which may include mixed IO with other file handles.
.PP
.in +4n
.nf
EOF
sed "s/\\\\/\\\\\\\\/g" demo-async.c
cat <<EOF
.in
.fi
.SH "SEE ALSO"
.BR termkey_advisereadable (3),
.BR termkey_waitkey (3),
.BR termkey_get_waittime (3),
.BR termkey (7)
EOF

View File

@ -1,28 +0,0 @@
.TH TERMKEY_INTERPRET_CSI 3
.SH NAME
termkey_interpret_csi \- interpret unrecognised CSI sequence
.SH SYNOPSIS
.nf
.B #include <termkey.h>
.sp
.BI "TermKeyResult termkey_interpret_csi(TermKey *" tk ", const TermKeyKey *" key ", "
.BI " long *" args "[], size_t *" nargs ", unsigned long *" cmd );
.fi
.sp
Link with \fI-ltermkey\fP.
.SH DESCRIPTION
\fBtermkey_interpret_csi\fP() fills in variables in the passed pointers according to the unrecognised CSI sequence event found in \fIkey\fP. It should be called if \fBtermkey_getkey\fP(3) or similar have returned a key event with the type of \fBTERMKEY_TYPE_UNKNOWN_CSI\fP. Note that it is important to call this function as soon as possible after obtaining a \fBTERMKEY_TYPE_CSI\fP key event; specifically, before calling \fBtermkey_getkey\fP() or \fBtermkey_waitkey\fP() again, as a subsequent call will overwrite the buffer space currently containing this sequence.
.PP
The \fIargs\fP array will be filled with the numerical arguments of the CSI sequence. The number of elements available in this array should be given as the initial value of the value pointed to by \fInargs\fP, which will be adjusted to give the number of arguments actually found when the function returns. The \fIcmd\fP variable will contain the CSI command value. If a leading byte was found (such as '\f(CW?\fP') then it will be bitwise-ored with the command value, shifted up by 8 bits. If an intermediate byte was found (such as '\f(CW$\fP') then it will be bitwise-ored with the command value, shifted up by 16 bits.
.nf
.sp
*cmd = command | (initial << 8) | (intermediate << 16);
.fi
.SH "RETURN VALUE"
If passed a \fIkey\fP event of the type \fBTERMKEY_TYPE_UNKNOWN_CSI\fP, this function will return \fBTERMKEY_RES_KEY\fP and will affect the variables whose pointers were passed in, as described above.
.PP
For other event types it will return \fBTERMKEY_RES_NONE\fP, and its effects on any variables whose pointers were passed in, are undefined.
.SH "SEE ALSO"
.BR termkey_waitkey (3),
.BR termkey_getkey (3),
.BR termkey (7)

View File

@ -1,26 +0,0 @@
.TH TERMKEY_INTERPRET_MODEREPORT 3
.SH NAME
termkey_interpret_modereport \- interpret opaque mode report data
.SH SYNOPSIS
.nf
.B #include <termkey.h>
.sp
.BI "TermKeyResult termkey_interpret_modereport(TermKey *" tk ", const TermKeyKey *" key ", "
.BI " int *" initial ", int *" mode ", int *" value );
.fi
.sp
Link with \fI-ltermkey\fP.
.SH DESCRIPTION
\fBtermkey_interpret_modereport\fP() fills in variables in the passed pointers according to the mode report event found in \fIkey\fP. It should be called if \fBtermkey_getkey\fP(3) or similar have returned a key event with the type of \fBTERMKEY_TYPE_MODEREPORT\fP.
.PP
Any pointer may instead be given as \fBNULL\fP to not return that value.
.PP
The \fIinitial\fP variable will be filled with 0 for an ANSI mode report, or \f(CW'?'\fP for a DEC mode report. The \fImode\fP variable will be filled with the number of the mode, and \fIvalue\fP will be filled with the value from the report.
.SH "RETURN VALUE"
If passed a \fIkey\fP event of the type \fBTERMKEY_TYPE_MODEREPORT\fP, this function will return \fBTERMKEY_RES_KEY\fP and will affect the variables whose pointers were passed in, as described above.
.PP
For other event types it will return \fBTERMKEY_RES_NONE\fP, and its effects on any variables whose pointers were passed in, are undefined.
.SH "SEE ALSO"
.BR termkey_waitkey (3),
.BR termkey_getkey (3),
.BR termkey (7)

View File

@ -1,41 +0,0 @@
.TH TERMKEY_INTERPRET_MOUSE 3
.SH NAME
termkey_interpret_mouse \- interpret opaque mouse event data
.SH SYNOPSIS
.nf
.B #include <termkey.h>
.sp
.BI "TermKeyResult termkey_interpret_mouse(TermKey *" tk ", const TermKeyKey *" key ", "
.BI " TermKeyMouseEvent *" ev ", int *" button ", int *" line ", int *" col );
.fi
.sp
Link with \fI-ltermkey\fP.
.SH DESCRIPTION
\fBtermkey_interpret_mouse\fP() fills in variables in the passed pointers according to the mouse event found in \fIkey\fP. It should be called if \fBtermkey_getkey\fP(3) or similar have returned a key event with the type of \fBTERMKEY_TYPE_MOUSE\fP.
.PP
Any pointer may instead be given as \fBNULL\fP to not return that value.
.PP
The \fIev\fP variable will take one of the following values:
.in
.TP
.B TERMKEY_MOUSE_UNKNOWN
an unknown mouse event.
.TP
.B TERMKEY_MOUSE_PRESS
a mouse button was pressed; \fIbutton\fP will contain its number.
.TP
.B TERMKEY_MOUSE_DRAG
the mouse was moved while holding a button; \fIbutton\fP will contain its number.
.TP
.B TERMKEY_MOUSE_RELEASE
a mouse button was released, or the mouse was moved while no button was pressed. If known, \fIbutton\fP will contain the number of the button released. Not all terminals can report this, so it may be 0 instead.
.PP
The \fIline\fP and \fIcol\fP variables will be filled in with the mouse position, indexed from 1. Note that due to the limited number of bytes in the \fBTermKeyKey\fP structure, the line and column numbers are limited to 2047 and 4095 respectively.
.SH "RETURN VALUE"
If passed a \fIkey\fP event of the type \fBTERMKEY_TYPE_MOUSE\fP, this function will return \fBTERMKEY_RES_KEY\fP and will affect the variables whose pointers were passed in, as described above.
.PP
For other event types it will return \fBTERMKEY_RES_NONE\fP, and its effects on any variables whose pointers were passed in, are undefined.
.SH "SEE ALSO"
.BR termkey_waitkey (3),
.BR termkey_getkey (3),
.BR termkey (7)

View File

@ -1,26 +0,0 @@
.TH TERMKEY_INTERPRET_POSITION 3
.SH NAME
termkey_interpret_position \- interpret opaque cursor position event data
.SH SYNOPSIS
.nf
.B #include <termkey.h>
.sp
.BI "TermKeyResult termkey_interpret_position(TermKey *" tk ", const TermKeyKey *" key ", "
.BI " int *" line ", int *" col );
.fi
.sp
Link with \fI-ltermkey\fP.
.SH DESCRIPTION
\fBtermkey_interpret_position\fP() fills in variables in the passed pointers according to the cursor position report event found in \fIkey\fP. It should be called if \fBtermkey_getkey\fP(3) or similar have returned a key event with the type of \fBTERMKEY_TYPE_POSITION\fP.
.PP
Any pointer may instead be given as \fBNULL\fP to not return that value.
.PP
The \fIline\fP and \fIcol\fP variables will be filled in with the cursor position, indexed from 1. Note that due to the limited number of bytes in the \fBTermKeyKey\fP structure, the line and column numbers are limited to 2047 and 4095 respectively.
.SH "RETURN VALUE"
If passed a \fIkey\fP event of the type \fBTERMKEY_TYPE_POSITION\fP, this function will return \fBTERMKEY_RES_KEY\fP and will affect the variables whose pointers were passed in, as described above.
.PP
For other event types it will return \fBTERMKEY_RES_NONE\fP, and its effects on any variables whose pointers were passed in, are undefined.
.SH "SEE ALSO"
.BR termkey_waitkey (3),
.BR termkey_getkey (3),
.BR termkey (7)

View File

@ -1,22 +0,0 @@
.TH TERMKEY_KEYCMP 3
.SH NAME
termkey_keycmp \- compare two key events
.SH SYNOPSIS
.nf
.B #include <termkey.h>
.sp
.BI "int termkey_keycmp(TermKey *" tk ", const TermKeyKey *" key1 ",
.BI " const TermKeyKey *" key2 );
.fi
.sp
Link with \fI-ltermkey\fP.
.SH DESCRIPTION
\fBtermkey_keycmp\fP() compares two key structures and applies a total ordering, returning a value that is negative, zero, or positive, to indicate if the given structures are increasing, identical, or decreasing. Before comparison, copies of both referenced structures are taken, and canonicalised according to the rules for \fBtermkey_canonicalise\fP(3).
.PP
Two structures of differing type are ordered \fBTERMKEY_TYPE_UNICODE\fP, \fBTERMKEY_TYPE_KEYSYM\fP, \fBTERMKEY_TYPE_FUNCTION\fP, \fBTERMKEY_TYPE_MOUSE\fP. Unicode structures are ordered by codepoint, keysym structures are ordered by keysym number, function structures are ordered by function key number, and mouse structures are ordered opaquely by an unspecified but consistent ordering. Within these values, keys different in modifier bits are ordered by the modifiers.
.SH "RETURN VALUE"
\fBtermkey_keycmp\fP() returns an integer greater than, equal to, or less than zero to indicate the relation between the two given key structures.
.SH "SEE ALSO"
.BR termkey_strpkey (3),
.BR termkey_canonicalise (3),
.BR termkey (7)

View File

@ -1,22 +0,0 @@
.TH TERMKEY_KEYNAME2SYM 3
.SH NAME
termkey_keyname2sym \- look up a symbolic key value for a string name
.SH SYNOPSIS
.nf
.B #include <termkey.h>
.sp
.BI "TermKeySym termkey_keyname2sym(TermKey *" tk ", const char *" keyname );
.fi
.sp
Link with \fI-ltermkey\fP.
.SH DESCRIPTION
\fBtermkey_keyname2sym\fP() looks up the symbolic key value represented by the given string name. This is a case-sensitive comparison. If the given name is not found, \fBTERMKEY_SYM_UNKNOWN\fP is returned instead. This function is the inverse of \fBtermkey_get_keyname\fP(3), and is a more specific form of \fBtermkey_lookup_keyname\fP(3) which only recognises names as complete strings.
.PP
Because the key names are stored in an array indexed by the symbol number, this function has to perform a linear search of the names. Use of this function should be restricted to converting key names into symbolic values during a program's initialisation, so that efficient comparisons can be done while it is running.
.SH "RETURN VALUE"
\fBtermkey_keyname2sym\fP() returns a symbolic key constant, or \fBTERMKEY_SYM_UNKNOWN\fP.
.SH "SEE ALSO"
.BR termkey_get_keyname (3),
.BR termkey_lookup_keyname (3),
.BR termkey_strpkey (3),
.BR termkey (7)

View File

@ -1,23 +0,0 @@
.TH TERMKEY_LOOKUP_KEYNAME 3
.SH NAME
termkey_lookup_keyname \- look up a symbolic key value for a string name
.SH SYNOPSIS
.nf
.B #include <termkey.h>
.sp
.BI "char *termkey_lookup_keyname(TermKey *" tk ", const char *" keyname ",
.BI " TermKeySym *" sym ");
.fi
.sp
Link with \fI-ltermkey\fP.
.SH DESCRIPTION
\fBtermkey_lookup_keyname\fP() looks up the symbolic key value represented by the given string name. This is a case-sensitive comparison. The symbolic value is written to the variable addressed by \fIsym\fP. This function is a more general form of \fBtermkey_keyname2sym\fP(3) because it can recognise a symbolic key name within a longer string, returning a pointer to the remainder of the input after the key name.
.PP
Because the key names are stored in an array indexed by the symbol number, this function has to perform a linear search of the names. Use of this function should be restricted to converting key names into symbolic values during a program's initialisation, so that efficient comparisons can be done while it is running.
.SH "RETURN VALUE"
\fBtermkey_lookup_keyname\fP() returns a pointer to the first character after a recognised name, or \fBNULL\fP if the string does not begin with the name of a recognised symbolic key.
.SH "SEE ALSO"
.BR termkey_get_keyname (3),
.BR termkey_keyname2sym (3),
.BR termkey_strpkey (3),
.BR termkey (7)

View File

@ -1,48 +0,0 @@
.TH TERMKEY_NEW 3
.SH NAME
termkey_new, termkey_destroy \- create or destroy new termkey instance
.SH SYNOPSIS
.nf
.B #include <termkey.h>
.sp
.BI "TERMKEY_CHECK_VERSION;"
.BI "TermKey *termkey_new(int " fd ", int " flags );
.BI "TermKey *termkey_new_abstract(const char *" term ", int " flags );
.BI "void termkey_destroy(TermKey *" tk );
.fi
.sp
Link with \fI\-ltermkey\fP.
.SH DESCRIPTION
\fBtermkey_new\fP() creates a new \fBtermkey\fP(7) instance connected to the file handle opened by \fIfd\fP using the \fIflags\fP. The \fITermKey\fP structure should be considered opaque; its contents are not intended for use outside of the library.
.PP
\fBtermkey_new_abstract\fP() creates a new \fBtermkey\fP() instance with no file handle associated. As this is usually done for handling other sources of terminal byte input, it also takes a string indicating the termtype to use.
.PP
\fBtermkey_destroy\fP() destroys the given instance and releases any resources controlled by it. It will not close the underlying filehandle given as the \fIfd\fP argument to \fBtermkey_new\fP().
.PP
The constructor attempts to detect if the current locale is
.SM UTF-8
aware or not, and sets either the \fBTERMKEY_FLAG_UTF8\fP or \fBTERMKEY_FLAG_RAW\fP flag. One of these two bits will always be in effect. The current flags in effect can be obtained by \fBtermkey_get_flags\fP(3).
.PP
If a file handle is provided, the terminfo driver may send a string to initialise or set the state of the terminal before \fBtermkey_new\fP() returns. This will not be done if no file handle is provided, or if the file handle is a pipe (\fBS_ISFIFO\fP()). In this case it will be the caller's responsibility to ensure the terminal is in the correct mode. Once initialised, the terminal can be stopped by \fBtermkey_stop\fP(3), and started again by \fBtermkey_start\fP(3).
.SH VERSION CHECK MACRO
Before calling any functions in the \fBtermkey\fP library, an application should use the \fBTERMKEY_CHECK_VERSION\fP macro to check that the loaded version of the library is compatible with the version it was compiled against. This should be done early on, ideally just after entering its \fBmain\fP() function.
.SH "RETURN VALUE"
If successful, \fBtermkey_new\fP() returns a pointer to the new instance. On failure, \fBNULL\fP is returned with \fIerrno\fP set to indicate the failure. \fBtermkey_destroy\fP() returns no value.
.SH ERRORS
.TP
.B ENOENT
No driver was able to recognise the given terminal type.
.TP
.B ENOMEM
A call to \fBmalloc\fP(3) failed to allocate memory.
.PP
Additionally, \fBtermkey_new\fP() may fail if \fBfstat\fP(2) or \fBwrite\fP(2) fails on the given file handle.
.SH "SEE ALSO"
.BR termkey_waitkey (3),
.BR termkey_advisereadable (3),
.BR termkey_getkey (3),
.BR termkey_get_flags (3),
.BR termkey_get_fd (3),
.BR termkey_get_buffer_remaining (3),
.BR termkey_get_buffer_size (3),
.BR termkey (7)

View File

@ -1,23 +0,0 @@
.TH TERMKEY_PUSH_BYTES 3
.SH NAME
termkey_push_bytes \- supply more bytes to the input buffer
.SH SYNOPSIS
.nf
.B #include <termkey.h>
.sp
.BI "size_t termkey_push_bytes(TermKey *" tk ", const char *" bytes ", size_t " len ");
.fi
.sp
Link with \fI-ltermkey\fP.
.SH DESCRIPTION
\fBtermkey_push_bytes\fP() allows more bytes of input to be supplied directly into the input buffer of the \fBtermkey\fP(7) instance. If there was no buffer space remaining then -1 is returned with \fIerrno\fP set to \fBENOMEM\fP.
.PP
This function, along with \fBtermkey_getkey\fP(3), makes it possible to use the \fBtermkey\fP instance with a source of bytes other than from reading a filehandle.
.PP
For synchronous usage, \fBtermkey_waitkey\fP(3) performs the input blocking task. For use against a regular stream filehandle that supports \fBread\fP(2), see \fBtermkey_advisereadable\fP(3).
.SH "RETURN VALUE"
\fBtermkey_push_bytes\fP() the number of bytes consumed from the input (which may be smaller than the length provided, if the buffer runs out of space) or -1 cast to \fBsize_t\fP if an error occurs, in which case \fIerrno\fP is set accordingly.
.SH "SEE ALSO"
.BR termkey_getkey (3),
.BR termkey_advisereadable (3),
.BR termkey (7)

View File

@ -1,22 +0,0 @@
.TH TERMKEY_SET_BUFFER_SIZE 3
.SH NAME
termkey_set_buffer_size, termkey_get_buffer_size \- control the buffer size
.SH SYNOPSIS
.nf
.B #include <termkey.h>
.sp
.BI "int termkey_set_buffer_size(TermKey *" tk ", size_t " size );
.BI "size_t termkey_get_buffer_size(TermKey *" tk );
.fi
.sp
Link with \fI-ltermkey\fP.
.SH DESCRIPTION
\fBtermkey_set_buffer_size\fP() changes the size of the buffer space in the \fBtermkey\fP(7) instance to that given by \fIsize\fP. Any bytes pending in the buffer will be preserved when resizing, though they will be truncated if the new size is smaller than the total number of bytes in the buffer.
.PP
\fBtermkey_get_buffer_size\fP() returns the size of the buffer set by the last call to \fBtermkey_set_buffer_size\fP(), or the default initial size of 256 bytes.
.SH "RETURN VALUE"
\fBtermkey_set_buffer_size\fP() returns a true value, or zero if an error occurs. \fBtermkey_get_buffer_size\fP() returns the current buffer size in bytes.
.SH "SEE ALSO"
.BR termkey_new (3),
.BR termkey_get_buffer_remaining (3),
.BR termkey (7)

View File

@ -1,21 +0,0 @@
.TH TERMKEY_SET_CANONFLAGS 3
.SH NAME
termkey_set_canonflags, termkey_get_canonflags \- control the canonicalisation flags
.SH SYNOPSIS
.nf
.B #include <termkey.h>
.sp
.BI "void termkey_set_canonflags(TermKey *" tk ", int " newflags );
.BI "int termkey_get_canonflags(TermKey *" tk );
.fi
.sp
Link with \fI-ltermkey\fP.
.SH DESCRIPTION
\fBtermkey_set_canonflags\fP() changes the set of canonicalisation flags in the \fBtermkey\fP(7) instance to those given by \fInewflags\fP. For detail on the available flags and their meaning, see the \fBtermkey\fP manpage.
.PP
\fBtermkey_get_canonflags\fP() returns the value set by the last call to \fBtermkey_set_canonflags\fP().
.SH "RETURN VALUE"
\fBtermkey_set_canonflags\fP() returns no value. \fBtermkey_get_canonflags\fP() returns the current canonicalisation flags.
.SH "SEE ALSO"
.BR termkey_canonicalise (3),
.BR termkey (7)

View File

@ -1,21 +0,0 @@
.TH TERMKEY_SET_FLAGS 3
.SH NAME
termkey_set_flags, termkey_get_flags \- control the operational flags
.SH SYNOPSIS
.nf
.B #include <termkey.h>
.sp
.BI "void termkey_set_flags(TermKey *" tk ", int " newflags );
.BI "int termkey_get_flags(TermKey *" tk );
.fi
.sp
Link with \fI-ltermkey\fP.
.SH DESCRIPTION
\fBtermkey_set_flags\fP() changes the set of operation flags in the \fBtermkey\fP(7) instance to those given by \fInewflags\fP.
.PP
\fBtermkey_get_flags\fP() returns the value set by the last call to \fBtermkey_set_flags\fP(), or the value given to the constructor.
.SH "RETURN VALUE"
\fBtermkey_set_flags\fP() returns no value. \fBtermkey_get_flags\fP() returns the current operational flags.
.SH "SEE ALSO"
.BR termkey_new (3),
.BR termkey (7)

View File

@ -1,22 +0,0 @@
.TH TERMKEY_SET_WAITTIME 3
.SH NAME
termkey_set_waittime, termkey_get_waittime \- control the wait time for multibyte sequences
.SH SYNOPSIS
.nf
.B #include <termkey.h>
.sp
.BI "void termkey_set_waittime(TermKey *" tk ", int " msec );
.BI "int termkey_get_waittime(TermKey *" tk );
.fi
.sp
Link with \fI-ltermkey\fP.
.SH DESCRIPTION
\fBtermkey_set_waittime\fP() sets the number of miliseconds that \fBtermkey_waitkey\fP(3) will wait for the remaining bytes of a multibyte sequence if it detects the start of a partially-complete one.
.PP
\fBtermkey_get_waittime\fP() returns the value set by the last call to \fBtermkey_set_waittime\fP(), or the default value if a different has not been set.
.SH "RETURN VALUE"
\fBtermkey_set_waittime\fP() returns no value. \fBtermkey_get_waittime\fP() returns the current wait time in miliseconds.
.SH "SEE ALSO"
.BR termkey_getkey (3),
.BR termkey_waitkey (3),
.BR termkey (7)

View File

@ -1,25 +0,0 @@
.TH TERMKEY_START 3
.SH NAME
termkey_start, termkey_stop, termkey_is_started \- enable or disable terminal operations
.SH SYNOPSIS
.nf
.B #include <termkey.h>
.sp
.BI "int termkey_start(TermKey *" tk );
.BI "int termkey_stop(TermKey *" tk );
.sp
.BI "int termkey_is_started(TermKey *" tk );
.fi
.sp
Link with \fI\-ltermkey\fP.
.SH DESCRIPTION
\fBtermkey_start\fP() enables the terminal IO operations of the given \fBtermkey\fP(7) instance, including sending a terminal control sequence and setting the \fBtermios\fP(3) modes required.
.PP
\fBtermkey_stop\fP() disables terminal IO operations, by reversing the steps taken by \fBtermkey_start\fP(). A newly-constructed \fBtermkey\fP instance will have terminal IO enabled already.
.PP
\fBtermkey_is_started\fP() enquires whether terminal IO is currently enabled.
.SH "RETURN VALUE"
If successful, \fBtermkey_start\fP() and \fBtermkey_stop\fP() return a true value. On failure, zero is returned with \fIerrno\fP set to indicate the failure. \fBtermkey_is_started\fP() returns true or false to indicate whether terminal IO is currently enabled.
.SH "SEE ALSO"
.BR termkey_new (3),
.BR termkey (7)

View File

@ -1,59 +0,0 @@
.TH TERMKEY_STRFKEY 3
.SH NAME
termkey_strfkey \- format a string representing a key event
.SH SYNOPSIS
.nf
.B #include <termkey.h>
.sp
.BI "size_t termkey_strfkey(TermKey *" tk ", char *" buffer ", size_t " len ",
.BI " TermKeyKey *" key ", TermKeyFormat " format );
.fi
.sp
Link with \fI-ltermkey\fP.
.SH DESCRIPTION
\fBtermkey_strfkey\fP() formats a string buffer to contain a human-readable representation of a key event. It fills the \fIbuffer\fP in a way analogous to the \fBsnprintf\fP(3) or \fBstrftime\fP(3) standard library functions. This function used to be called \fBtermkey_snprint_key\fP() but was renamed after version 0.6.
.PP
The \fIformat\fP argument specifies the format of the output, as a bitmask of the following constants:
.TP
.B TERMKEY_FORMAT_LONGMOD
Print full modifier names e.g. "\f(CWShift-\fP" instead of abbreviating to "\f(CWS-\fP".
.TP
.B TERMKEY_FORMAT_CARETCTRL
If the only modifier is \fBTERMKEY_MOD_CTRL\fP on a plain letter, render it as "\f(CW^X\fP" rather than "\f(CWCtrl-X\fP".
.TP
.B TERMKEY_FORMAT_ALTISMETA
Use the name "\f(CWMeta\fP" or the letter "\f(CWM\fP" instead of "\f(CWAlt\fP" or "\f(CWA\fP".
.TP
.B TERMKEY_FORMAT_WRAPBRACKET
If the key event is a special key instead of unmodified Unicode, wrap it in "\f(CW<brackets>\fP".
.TP
.B TERMKEY_FORMAT_SPACEMOD
Use spaces instead of hyphens to separate the modifier name(s) from the base key name.
.TP
.B TERMKEY_FORMAT_LOWERMOD
Use lowercase for the modifier name.
.TP
.B TERMKEY_FORMAT_LOWERSPACE
Use lowercase with spaces in for the key name instead of camelCase (for example "\f(CWpage down\fP" instead of "\f(CWPageDown\fP").
.TP
.B TERMKEY_FORMAT_MOUSE_POS
If the event is a mouse event, include the position rendered as "\f(CW@ (col,line)\fP".
.PP
The following shortcuts are provided for common combinations of format bits:
.TP
.B TERMKEY_FORMAT_VIM
Shortcut to set \fBALTISMETA\fP and \fBWRAPBRACKET\fP, to give an output close to the format the \fIvim\fP editor uses.
.TP
.B TERMKEY_FORMAT_URWID
Shortcut to set \fBALTISMETA\fP, \fBLONGMOD\fP, \fBLOWERMOD\fP, \fBSPACEMOD\fP and \fBLOWERSPACE\fP, to give an output close to the format the \fIurwid\fP python library uses.
.PP
When formatting a \fBTERMKEY_TYPE_UNICODE\fP key structure, this function uses the \fIutf8\fP member. If this member contains an empty string (i.e. its first character is 0) then this member will be prefilled by the function from the \fIcode.number\fP member. This can be convenient when the key structure is being constructed programatically by user code.
.SH "RETURN VALUE"
\fBtermkey_strfkey\fP() returns the number of characters written to \fIbuffer\fP.
.SH "SEE ALSO"
.BR termkey_new (3),
.BR termkey_getkey (3),
.BR termkey_waitkey (3),
.BR termkey_get_keyname (3),
.BR termkey_strpkey (3),
.BR termkey (7)

View File

@ -1,45 +0,0 @@
.TH TERMKEY_STRPKEY 3
.SH NAME
termkey_strpkey \- parse a string representing a key event
.SH SYNOPSIS
.nf
.B #include <termkey.h>
.sp
.BI "char *termkey_strpkey(TermKey *" tk ", const char *" str ",
.BI " TermKeyKey *" key ", TermKeyFormat " format );
.fi
.sp
Link with \fI-ltermkey\fP.
.SH DESCRIPTION
\fBtermkey_strpkey\fP(3) parses a string buffer containing a human-readable representation of a key event. It fills the \fIkey\fP structure from the results of this parsing, similar to the \fBstrptime\fP(3) standard library function.
.PP
The \fIformat\fP argument specifies the format expected in the string, as a bitmask of the following constants:
.TP
.B TERMKEY_FORMAT_LONGMOD
Expect full modifier names e.g. "\f(CWShift-\fP" instead of abbreviating to "\f(CWS-\fP".
.TP
.B TERMKEY_FORMAT_CARETCTRL
If the only modifier is \fBTERMKEY_MOD_CTRL\fP on a plain letter, accept it as "\f(CW^X\fP" rather than "\f(CWCtrl-X\fP".
.TP
.B TERMKEY_FORMAT_ALTISMETA
Expect the name "\f(CWMeta\fP" or the letter "\f(CWM\fP" instead of "\f(CWAlt\fP" or "\f(CWA\fP".
.TP
.B TERMKEY_FORMAT_SPACEMOD
Expect spaces instead of hyphens to separate the modifer name(s) from the base key name.
.TP
.B TERMKEY_FORMAT_LOWERMOD
Expect lowercase for the modifier name.
.TP
.B TERMKEY_FORMAT_LOWERSPACE
Expect lowercase with spaces in for the key name instead of camelCase (for example "\f(CWpage down\fP" instead of "\f(CWPageDown\fP").
.PP
Before returning, this function canonicalises the \fIkey\fP structure according to the rules given for \fBtermkey_canonicalise\fP(3).
.PP
The \fBTERMKEY_FORMAT_WRAPBRACKET\fP and \fBTERMKEY_FORMAT_MOUSE_POS\fP options are currently not supported by \fBtermkey_strpkey\fP(). When returning a \fBTERMKEY_TYPE_UNICODE\fP key structure, this function will fill in the \fIutf8\fP member.
.SH "RETURN VALUE"
After a successful parse, \fBtermkey_strpkey\fP() returns a pointer to the first character of the input it did not consume. If the input string contains more characters then this will point at the first character beyond. If the entire input string was consumed, then this will point at a null byte. If \fBtermkey_strpkey\fP() fails to parse, it returns \fBNULL\fP. After a failed parse, the \fIkey\fP structure may contain partial or invalid results. The structure will only be valid if the function returns a non-\fBNULL\fP result.
.SH "SEE ALSO"
.BR termkey_new (3),
.BR termkey_strfkey (3),
.BR termkey_keycmp (3),
.BR termkey (7)

View File

@ -1,45 +0,0 @@
# vim:ft=nroff
cat <<EOF
.TH TERMKEY_WAITKEY 3
.SH NAME
termkey_waitkey \- wait for and retrieve the next key event
.SH SYNOPSIS
.nf
.B #include <termkey.h>
.sp
.BI "TermKeyResult termkey_waitkey(TermKey *" tk ", TermKeyKey *" key );
.fi
.sp
Link with \fI-ltermkey\fP.
.SH DESCRIPTION
\fBtermkey_waitkey\fP() attempts to retrieve a single keypress event from the \fBtermkey\fP(7) instance buffer, and put it in the structure referred to by \fIkey\fP. If successful it will return \fBTERMKEY_RES_KEY\fP to indicate that the structure now contains a new keypress event. If nothing is in the buffer it will block until one is available. If no events are ready and the input stream is now closed, will return \fBTERMKEY_RES_EOF\fP. If no filehandle is associated with this instance, \fBTERMKEY_RES_ERROR\fP is returned with \fIerrno\fP set to \fBEBADF\fP.
.PP
Before returning, this function canonicalises the \fIkey\fP structure according to the rules given for \fBtermkey_canonicalise\fP(3).
.PP
Some keypresses generate multiple bytes from the terminal. Because there may be network or other delays between the terminal and an application using \fBtermkey\fP, \fBtermkey_waitkey\fP() will attempt to wait for the remaining bytes to arrive if it detects the start of a multibyte sequence. If no more bytes arrive within a certain time, then the bytes will be reported as they stand, even if this results in interpreting a partially-complete Escape sequence as a literal Escape key followed by some normal letters or other symbols. The amount of time to wait can be set by \fBtermkey_set_waittime\fP(3).
.SH "RETURN VALUE"
\fBtermkey_waitkey\fP() returns one of the following constants:
.TP
.B TERMKEY_RES_KEY
A key event as been provided.
.TP
.B TERMKEY_RES_EOF
No key events are ready and the terminal has been closed, so no more will arrive.
.TP
.B TERMKEY_RES_ERROR
An IO error occured. \fIerrno\fP will be preserved. If the error is \fBEINTR\fP then this will only be returned if \fBTERMKEY_FLAG_EINTR\fP flag is not set; if it is then the IO operation will be retried instead. If this is called with terminal IO stopped, due to \fBtermkey_stop\fP(3) then \fIerrno\fP will be set to \fBEINVAL\fP.
.SH EXAMPLE
The following example program prints details of every keypress until the user presses \fICtrl-C\fP.
.PP
.in +4n
.nf
EOF
sed "s/\\\\/\\\\\\\\/g" demo.c
cat <<EOF
.in
.fi
.SH "SEE ALSO"
.BR termkey_getkey (3),
.BR termkey_set_waittime (3),
.BR termkey (7)
EOF

View File

@ -1,94 +1,112 @@
#ifndef GUARD_TERMKEY_INTERNAL_H_
#define GUARD_TERMKEY_INTERNAL_H_
#ifndef TERMKEY_INTERNAL_H
#define TERMKEY_INTERNAL_H
#include "termkey.h"
#include <stdint.h>
#include <termios.h>
struct TermKeyDriver
typedef struct termkey_driver termkey_driver_t;
struct termkey_driver
{
const char *name;
void *(*new_driver)(TermKey *tk, const char *term);
void (*free_driver)(void *info);
int (*start_driver)(TermKey *tk, void *info);
int (*stop_driver)(TermKey *tk, void *info);
TermKeyResult (*peekkey)(TermKey *tk, void *info, TermKeyKey *key, int force, size_t *nbytes);
const char *name;
void *(*new_driver) (termkey_t *tk, const char *term);
void (*free_driver) (void *info);
int (*start_driver) (termkey_t *tk, void *info);
int (*stop_driver) (termkey_t *tk, void *info);
termkey_result_t (*peekkey) (termkey_t *tk,
void *info, termkey_key_t *key, int force, size_t *nbytes);
};
struct keyinfo {
TermKeyType type;
TermKeySym sym;
int modifier_mask;
int modifier_set;
};
struct TermKeyDriverNode;
struct TermKeyDriverNode {
struct TermKeyDriver *driver;
void *info;
struct TermKeyDriverNode *next;
};
struct TermKey {
int fd;
int flags;
int canonflags;
unsigned char *buffer;
size_t buffstart; // First offset in buffer
size_t buffcount; // NUMBER of entires valid in buffer
size_t buffsize; // Total malloc'ed size
size_t hightide; /* Position beyond buffstart at which peekkey() should next start
* normally 0, but see also termkey_interpret_csi */
struct termios restore_termios;
char restore_termios_valid;
int waittime; // msec
char is_closed;
char is_started;
int nkeynames;
const char **keynames;
// There are 32 C0 codes
struct keyinfo c0[32];
struct TermKeyDriverNode *drivers;
// Now some "protected" methods for the driver to call but which we don't
// want exported as real symbols in the library
struct {
void (*emit_codepoint)(TermKey *tk, long codepoint, TermKeyKey *key);
TermKeyResult (*peekkey_simple)(TermKey *tk, TermKeyKey *key, int force, size_t *nbytes);
TermKeyResult (*peekkey_mouse)(TermKey *tk, TermKeyKey *key, size_t *nbytes);
} method;
};
static inline void termkey_key_get_linecol(const TermKeyKey *key, int *line, int *col)
typedef struct keyinfo keyinfo_t;
struct keyinfo
{
if(col)
*col = (unsigned char)key->code.mouse[1] | ((unsigned char)key->code.mouse[3] & 0x0f) << 8;
termkey_type_t type;
termkey_sym_t sym;
int modifier_mask;
int modifier_set;
};
if(line)
*line = (unsigned char)key->code.mouse[2] | ((unsigned char)key->code.mouse[3] & 0x70) << 4;
typedef struct termkey_driver_node termkey_driver_node_t;
struct termkey_driver_node
{
termkey_driver_t *driver;
void *info;
termkey_driver_node_t *next;
};
struct termkey
{
int fd;
int flags;
int canonflags;
unsigned char *buffer;
size_t buffstart; // First offset in buffer
size_t buffcount; // NUMBER of entires valid in buffer
size_t buffsize; // Total malloc'ed size
// Position beyond buffstart at which peekkey() should next start
// normally 0, but see also termkey_interpret_csi().
size_t hightide;
struct termios restore_termios;
char restore_termios_valid;
int waittime; // msec
char is_closed;
char is_started;
int nkeynames;
const char **keynames;
// There are 32 C0 codes
keyinfo_t c0[32];
termkey_driver_node_t *drivers;
// Now some "protected" methods for the driver to call but which we don't
// want exported as real symbols in the library
struct
{
void (*emit_codepoint) (termkey_t *tk,
long codepoint, termkey_key_t *key);
termkey_result_t (*peekkey_simple) (termkey_t *tk,
termkey_key_t *key, int force, size_t *nbytes);
termkey_result_t (*peekkey_mouse) (termkey_t *tk,
termkey_key_t *key, size_t *nbytes);
}
method;
};
static inline void
termkey_key_get_linecol (const termkey_key_t *key, int *line, int *col)
{
if (col)
*col = (unsigned char) key->code.mouse[1]
| ((unsigned char) key->code.mouse[3] & 0x0f) << 8;
if (line)
*line = (unsigned char) key->code.mouse[2]
| ((unsigned char) key->code.mouse[3] & 0x70) << 4;
}
static inline void termkey_key_set_linecol(TermKeyKey *key, int line, int col)
static inline void
termkey_key_set_linecol (termkey_key_t *key, int line, int col)
{
if(line > 0xfff)
line = 0xfff;
if (line > 0xfff)
line = 0xfff;
if(col > 0x7ff)
col = 0x7ff;
if (col > 0x7ff)
col = 0x7ff;
key->code.mouse[1] = (line & 0x0ff);
key->code.mouse[2] = (col & 0x0ff);
key->code.mouse[3] = (line & 0xf00) >> 8 | (col & 0x300) >> 4;
key->code.mouse[1] = (line & 0x0ff);
key->code.mouse[2] = (col & 0x0ff);
key->code.mouse[3] = (line & 0xf00) >> 8 | (col & 0x300) >> 4;
}
extern struct TermKeyDriver termkey_driver_csi;
extern struct TermKeyDriver termkey_driver_ti;
extern termkey_driver_t termkey_driver_csi;
extern termkey_driver_t termkey_driver_ti;
#endif // ! TERMKEY_INTERNAL_H
#endif

2426
termkey.c

File diff suppressed because it is too large Load Diff

View File

@ -1,240 +1,258 @@
#ifdef __cplusplus
extern "C" {
#endif
#ifndef GUARD_TERMKEY_H_
#define GUARD_TERMKEY_H_
#ifndef TERMKEY_H
#define TERMKEY_H
#include <stdint.h>
#include <stdlib.h>
#include <limits.h>
#define TERMKEY_VERSION_MAJOR @@VERSION_MAJOR@@
#define TERMKEY_VERSION_MINOR @@VERSION_MINOR@@
#define TERMKEY_CHECK_VERSION \
termkey_check_version(TERMKEY_VERSION_MAJOR, TERMKEY_VERSION_MINOR)
termkey_check_version (TERMKEY_VERSION_MAJOR, TERMKEY_VERSION_MINOR)
typedef enum {
TERMKEY_SYM_UNKNOWN = -1,
TERMKEY_SYM_NONE = 0,
typedef enum termkey_sym termkey_sym_t;
enum termkey_sym
{
TERMKEY_SYM_UNKNOWN = -1,
TERMKEY_SYM_NONE = 0,
/* Special names in C0 */
TERMKEY_SYM_BACKSPACE,
TERMKEY_SYM_TAB,
TERMKEY_SYM_ENTER,
TERMKEY_SYM_ESCAPE,
/* Special names in C0 */
TERMKEY_SYM_BACKSPACE,
TERMKEY_SYM_TAB,
TERMKEY_SYM_ENTER,
TERMKEY_SYM_ESCAPE,
/* Special names in G0 */
TERMKEY_SYM_SPACE,
TERMKEY_SYM_DEL,
/* Special names in G0 */
TERMKEY_SYM_SPACE,
TERMKEY_SYM_DEL,
/* Special keys */
TERMKEY_SYM_UP,
TERMKEY_SYM_DOWN,
TERMKEY_SYM_LEFT,
TERMKEY_SYM_RIGHT,
TERMKEY_SYM_BEGIN,
TERMKEY_SYM_FIND,
TERMKEY_SYM_INSERT,
TERMKEY_SYM_DELETE,
TERMKEY_SYM_SELECT,
TERMKEY_SYM_PAGEUP,
TERMKEY_SYM_PAGEDOWN,
TERMKEY_SYM_HOME,
TERMKEY_SYM_END,
/* Special keys */
TERMKEY_SYM_UP,
TERMKEY_SYM_DOWN,
TERMKEY_SYM_LEFT,
TERMKEY_SYM_RIGHT,
TERMKEY_SYM_BEGIN,
TERMKEY_SYM_FIND,
TERMKEY_SYM_INSERT,
TERMKEY_SYM_DELETE,
TERMKEY_SYM_SELECT,
TERMKEY_SYM_PAGEUP,
TERMKEY_SYM_PAGEDOWN,
TERMKEY_SYM_HOME,
TERMKEY_SYM_END,
/* Special keys from terminfo */
TERMKEY_SYM_CANCEL,
TERMKEY_SYM_CLEAR,
TERMKEY_SYM_CLOSE,
TERMKEY_SYM_COMMAND,
TERMKEY_SYM_COPY,
TERMKEY_SYM_EXIT,
TERMKEY_SYM_HELP,
TERMKEY_SYM_MARK,
TERMKEY_SYM_MESSAGE,
TERMKEY_SYM_MOVE,
TERMKEY_SYM_OPEN,
TERMKEY_SYM_OPTIONS,
TERMKEY_SYM_PRINT,
TERMKEY_SYM_REDO,
TERMKEY_SYM_REFERENCE,
TERMKEY_SYM_REFRESH,
TERMKEY_SYM_REPLACE,
TERMKEY_SYM_RESTART,
TERMKEY_SYM_RESUME,
TERMKEY_SYM_SAVE,
TERMKEY_SYM_SUSPEND,
TERMKEY_SYM_UNDO,
/* Special keys from terminfo */
TERMKEY_SYM_CANCEL,
TERMKEY_SYM_CLEAR,
TERMKEY_SYM_CLOSE,
TERMKEY_SYM_COMMAND,
TERMKEY_SYM_COPY,
TERMKEY_SYM_EXIT,
TERMKEY_SYM_HELP,
TERMKEY_SYM_MARK,
TERMKEY_SYM_MESSAGE,
TERMKEY_SYM_MOVE,
TERMKEY_SYM_OPEN,
TERMKEY_SYM_OPTIONS,
TERMKEY_SYM_PRINT,
TERMKEY_SYM_REDO,
TERMKEY_SYM_REFERENCE,
TERMKEY_SYM_REFRESH,
TERMKEY_SYM_REPLACE,
TERMKEY_SYM_RESTART,
TERMKEY_SYM_RESUME,
TERMKEY_SYM_SAVE,
TERMKEY_SYM_SUSPEND,
TERMKEY_SYM_UNDO,
/* Numeric keypad special keys */
TERMKEY_SYM_KP0,
TERMKEY_SYM_KP1,
TERMKEY_SYM_KP2,
TERMKEY_SYM_KP3,
TERMKEY_SYM_KP4,
TERMKEY_SYM_KP5,
TERMKEY_SYM_KP6,
TERMKEY_SYM_KP7,
TERMKEY_SYM_KP8,
TERMKEY_SYM_KP9,
TERMKEY_SYM_KPENTER,
TERMKEY_SYM_KPPLUS,
TERMKEY_SYM_KPMINUS,
TERMKEY_SYM_KPMULT,
TERMKEY_SYM_KPDIV,
TERMKEY_SYM_KPCOMMA,
TERMKEY_SYM_KPPERIOD,
TERMKEY_SYM_KPEQUALS,
/* Numeric keypad special keys */
TERMKEY_SYM_KP0,
TERMKEY_SYM_KP1,
TERMKEY_SYM_KP2,
TERMKEY_SYM_KP3,
TERMKEY_SYM_KP4,
TERMKEY_SYM_KP5,
TERMKEY_SYM_KP6,
TERMKEY_SYM_KP7,
TERMKEY_SYM_KP8,
TERMKEY_SYM_KP9,
TERMKEY_SYM_KPENTER,
TERMKEY_SYM_KPPLUS,
TERMKEY_SYM_KPMINUS,
TERMKEY_SYM_KPMULT,
TERMKEY_SYM_KPDIV,
TERMKEY_SYM_KPCOMMA,
TERMKEY_SYM_KPPERIOD,
TERMKEY_SYM_KPEQUALS,
/* et cetera ad nauseum */
TERMKEY_N_SYMS
} TermKeySym;
typedef enum {
TERMKEY_TYPE_UNICODE,
TERMKEY_TYPE_FUNCTION,
TERMKEY_TYPE_KEYSYM,
TERMKEY_TYPE_MOUSE,
TERMKEY_TYPE_POSITION,
TERMKEY_TYPE_MODEREPORT,
/* add other recognised types here */
TERMKEY_TYPE_UNKNOWN_CSI = -1
} TermKeyType;
typedef enum {
TERMKEY_RES_NONE,
TERMKEY_RES_KEY,
TERMKEY_RES_EOF,
TERMKEY_RES_AGAIN,
TERMKEY_RES_ERROR
} TermKeyResult;
typedef enum {
TERMKEY_MOUSE_UNKNOWN,
TERMKEY_MOUSE_PRESS,
TERMKEY_MOUSE_DRAG,
TERMKEY_MOUSE_RELEASE
} TermKeyMouseEvent;
enum {
TERMKEY_KEYMOD_SHIFT = 1 << 0,
TERMKEY_KEYMOD_ALT = 1 << 1,
TERMKEY_KEYMOD_CTRL = 1 << 2
TERMKEY_N_SYMS
};
typedef struct {
TermKeyType type;
union {
long codepoint; /* TERMKEY_TYPE_UNICODE */
int number; /* TERMKEY_TYPE_FUNCTION */
TermKeySym sym; /* TERMKEY_TYPE_KEYSYM */
char mouse[4]; /* TERMKEY_TYPE_MOUSE */
/* opaque. see termkey_interpret_mouse */
} code;
typedef enum termkey_type termkey_type_t;
enum termkey_type
{
TERMKEY_TYPE_UNICODE,
TERMKEY_TYPE_FUNCTION,
TERMKEY_TYPE_KEYSYM,
TERMKEY_TYPE_MOUSE,
TERMKEY_TYPE_POSITION,
TERMKEY_TYPE_MODEREPORT,
/* add other recognised types here */
int modifiers;
/* Any Unicode character can be UTF-8 encoded in no more than 6 bytes, plus
* terminating NUL */
char utf8[7];
} TermKeyKey;
typedef struct TermKey TermKey;
enum {
TERMKEY_FLAG_NOINTERPRET = 1 << 0, /* Do not interpret C0//DEL codes if possible */
TERMKEY_FLAG_CONVERTKP = 1 << 1, /* Convert KP codes to regular keypresses */
TERMKEY_FLAG_RAW = 1 << 2, /* Input is raw bytes, not UTF-8 */
TERMKEY_FLAG_UTF8 = 1 << 3, /* Input is definitely UTF-8 */
TERMKEY_FLAG_NOTERMIOS = 1 << 4, /* Do not make initial termios calls on construction */
TERMKEY_FLAG_SPACESYMBOL = 1 << 5, /* Sets TERMKEY_CANON_SPACESYMBOL */
TERMKEY_FLAG_CTRLC = 1 << 6, /* Allow Ctrl-C to be read as normal, disabling SIGINT */
TERMKEY_FLAG_EINTR = 1 << 7 /* Return ERROR on signal (EINTR) rather than retry */
TERMKEY_TYPE_UNKNOWN_CSI = -1
};
enum {
TERMKEY_CANON_SPACESYMBOL = 1 << 0, /* Space is symbolic rather than Unicode */
TERMKEY_CANON_DELBS = 1 << 1 /* Del is converted to Backspace */
typedef enum termkey_result termkey_result_t;
enum termkey_result
{
TERMKEY_RES_NONE,
TERMKEY_RES_KEY,
TERMKEY_RES_EOF,
TERMKEY_RES_AGAIN,
TERMKEY_RES_ERROR
};
void termkey_check_version(int major, int minor);
typedef enum termkey_mouse_event termkey_mouse_event_t;
enum termkey_mouse_event
{
TERMKEY_MOUSE_UNKNOWN,
TERMKEY_MOUSE_PRESS,
TERMKEY_MOUSE_DRAG,
TERMKEY_MOUSE_RELEASE
};
TermKey *termkey_new(int fd, int flags);
TermKey *termkey_new_abstract(const char *term, int flags);
void termkey_free(TermKey *tk);
void termkey_destroy(TermKey *tk);
enum
{
TERMKEY_KEYMOD_SHIFT = 1 << 0,
TERMKEY_KEYMOD_ALT = 1 << 1,
TERMKEY_KEYMOD_CTRL = 1 << 2
};
int termkey_start(TermKey *tk);
int termkey_stop(TermKey *tk);
int termkey_is_started(TermKey *tk);
typedef struct termkey_key termkey_key_t;
struct termkey_key
{
termkey_type_t type;
union
{
long codepoint; /* TERMKEY_TYPE_UNICODE */
int number; /* TERMKEY_TYPE_FUNCTION */
termkey_sym_t sym; /* TERMKEY_TYPE_KEYSYM */
char mouse[4]; /* TERMKEY_TYPE_MOUSE */
/* opaque, see termkey_interpret_mouse() */
} code;
int termkey_get_fd(TermKey *tk);
int modifiers;
int termkey_get_flags(TermKey *tk);
void termkey_set_flags(TermKey *tk, int newflags);
/* The raw multibyte sequence for the key */
char utf8[MB_LEN_MAX + 1];
};
int termkey_get_waittime(TermKey *tk);
void termkey_set_waittime(TermKey *tk, int msec);
typedef struct termkey termkey_t;
int termkey_get_canonflags(TermKey *tk);
void termkey_set_canonflags(TermKey *tk, int);
enum
{
TERMKEY_FLAG_NOINTERPRET = 1 << 0, /* Do not interpret C0//DEL codes if possible */
TERMKEY_FLAG_CONVERTKP = 1 << 1, /* Convert KP codes to regular keypresses */
TERMKEY_FLAG_RAW = 1 << 2, /* Input is raw bytes, not UTF-8 */
TERMKEY_FLAG_UTF8 = 1 << 3, /* Input is definitely UTF-8 */
TERMKEY_FLAG_NOTERMIOS = 1 << 4, /* Do not make initial termios calls on construction */
TERMKEY_FLAG_SPACESYMBOL = 1 << 5, /* Sets TERMKEY_CANON_SPACESYMBOL */
TERMKEY_FLAG_CTRLC = 1 << 6, /* Allow Ctrl-C to be read as normal, disabling SIGINT */
TERMKEY_FLAG_EINTR = 1 << 7 /* Return ERROR on signal (EINTR) rather than retry */
};
size_t termkey_get_buffer_size(TermKey *tk);
int termkey_set_buffer_size(TermKey *tk, size_t size);
enum
{
TERMKEY_CANON_SPACESYMBOL = 1 << 0, /* Space is symbolic rather than Unicode */
TERMKEY_CANON_DELBS = 1 << 1 /* Del is converted to Backspace */
};
size_t termkey_get_buffer_remaining(TermKey *tk);
void termkey_check_version (int major, int minor);
void termkey_canonicalise(TermKey *tk, TermKeyKey *key);
termkey_t *termkey_new (int fd, int flags);
termkey_t *termkey_new_abstract (const char *term, int flags);
void termkey_free (termkey_t *tk);
void termkey_destroy (termkey_t *tk);
TermKeyResult termkey_getkey(TermKey *tk, TermKeyKey *key);
TermKeyResult termkey_getkey_force(TermKey *tk, TermKeyKey *key);
TermKeyResult termkey_waitkey(TermKey *tk, TermKeyKey *key);
int termkey_start (termkey_t *tk);
int termkey_stop (termkey_t *tk);
int termkey_is_started (termkey_t *tk);
TermKeyResult termkey_advisereadable(TermKey *tk);
int termkey_get_fd (termkey_t *tk);
size_t termkey_push_bytes(TermKey *tk, const char *bytes, size_t len);
int termkey_get_flags (termkey_t *tk);
void termkey_set_flags (termkey_t *tk, int newflags);
TermKeySym termkey_register_keyname(TermKey *tk, TermKeySym sym, const char *name);
const char *termkey_get_keyname(TermKey *tk, TermKeySym sym);
const char *termkey_lookup_keyname(TermKey *tk, const char *str, TermKeySym *sym);
int termkey_get_waittime (termkey_t *tk);
void termkey_set_waittime (termkey_t *tk, int msec);
TermKeySym termkey_keyname2sym(TermKey *tk, const char *keyname);
int termkey_get_canonflags (termkey_t *tk);
void termkey_set_canonflags (termkey_t *tk, int flags);
TermKeyResult termkey_interpret_mouse(TermKey *tk, const TermKeyKey *key, TermKeyMouseEvent *event, int *button, int *line, int *col);
size_t termkey_get_buffer_size (termkey_t *tk);
int termkey_set_buffer_size (termkey_t *tk, size_t size);
TermKeyResult termkey_interpret_position(TermKey *tk, const TermKeyKey *key, int *line, int *col);
size_t termkey_get_buffer_remaining (termkey_t *tk);
TermKeyResult termkey_interpret_modereport(TermKey *tk, const TermKeyKey *key, int *initial, int *mode, int *value);
void termkey_canonicalise (termkey_t *tk, termkey_key_t *key);
TermKeyResult termkey_interpret_csi(TermKey *tk, const TermKeyKey *key, long args[], size_t *nargs, unsigned long *cmd);
termkey_result_t termkey_getkey (termkey_t *tk, termkey_key_t *key);
termkey_result_t termkey_getkey_force (termkey_t *tk, termkey_key_t *key);
termkey_result_t termkey_waitkey (termkey_t *tk, termkey_key_t *key);
typedef enum {
TERMKEY_FORMAT_LONGMOD = 1 << 0, /* Shift-... instead of S-... */
TERMKEY_FORMAT_CARETCTRL = 1 << 1, /* ^X instead of C-X */
TERMKEY_FORMAT_ALTISMETA = 1 << 2, /* Meta- or M- instead of Alt- or A- */
TERMKEY_FORMAT_WRAPBRACKET = 1 << 3, /* Wrap special keys in brackets like <Escape> */
TERMKEY_FORMAT_SPACEMOD = 1 << 4, /* M Foo instead of M-Foo */
TERMKEY_FORMAT_LOWERMOD = 1 << 5, /* meta or m instead of Meta or M */
TERMKEY_FORMAT_LOWERSPACE = 1 << 6, /* page down instead of PageDown */
termkey_result_t termkey_advisereadable (termkey_t *tk);
TERMKEY_FORMAT_MOUSE_POS = 1 << 8 /* Include mouse position if relevant; @ col,line */
} TermKeyFormat;
size_t termkey_push_bytes (termkey_t *tk, const char *bytes, size_t len);
termkey_sym_t termkey_register_keyname (termkey_t *tk,
termkey_sym_t sym, const char *name);
const char *termkey_get_keyname (termkey_t *tk, termkey_sym_t sym);
const char *termkey_lookup_keyname (termkey_t *tk,
const char *str, termkey_sym_t *sym);
termkey_sym_t termkey_keyname2sym (termkey_t *tk, const char *keyname);
termkey_result_t termkey_interpret_mouse (termkey_t *tk,
const termkey_key_t *key, termkey_mouse_event_t *event,
int *button, int *line, int *col);
termkey_result_t termkey_interpret_position (termkey_t *tk,
const termkey_key_t *key, int *line, int *col);
termkey_result_t termkey_interpret_modereport (termkey_t *tk,
const termkey_key_t *key, int *initial, int *mode, int *value);
termkey_result_t termkey_interpret_csi (termkey_t *tk,
const termkey_key_t *key, long args[], size_t *nargs, unsigned long *cmd);
typedef enum termkey_format termkey_format_t;
enum termkey_format
{
TERMKEY_FORMAT_LONGMOD = 1 << 0, /* Shift-... instead of S-... */
TERMKEY_FORMAT_CARETCTRL = 1 << 1, /* ^X instead of C-X */
TERMKEY_FORMAT_ALTISMETA = 1 << 2, /* Meta- or M- instead of Alt- or A- */
TERMKEY_FORMAT_WRAPBRACKET = 1 << 3, /* Wrap special keys in brackets like <Escape> */
TERMKEY_FORMAT_SPACEMOD = 1 << 4, /* M Foo instead of M-Foo */
TERMKEY_FORMAT_LOWERMOD = 1 << 5, /* meta or m instead of Meta or M */
TERMKEY_FORMAT_LOWERSPACE = 1 << 6, /* page down instead of PageDown */
TERMKEY_FORMAT_MOUSE_POS = 1 << 8 /* Include mouse position if relevant; @ col,line */
};
/* Some useful combinations */
#define TERMKEY_FORMAT_VIM (TermKeyFormat)(TERMKEY_FORMAT_ALTISMETA|TERMKEY_FORMAT_WRAPBRACKET)
#define TERMKEY_FORMAT_URWID (TermKeyFormat)(TERMKEY_FORMAT_LONGMOD|TERMKEY_FORMAT_ALTISMETA| \
TERMKEY_FORMAT_LOWERMOD|TERMKEY_FORMAT_SPACEMOD|TERMKEY_FORMAT_LOWERSPACE)
#define TERMKEY_FORMAT_VIM (termkey_format_t) \
(TERMKEY_FORMAT_ALTISMETA | TERMKEY_FORMAT_WRAPBRACKET)
#define TERMKEY_FORMAT_URWID (termkey_format_t) \
(TERMKEY_FORMAT_LONGMOD | TERMKEY_FORMAT_ALTISMETA | \
TERMKEY_FORMAT_LOWERMOD | TERMKEY_FORMAT_SPACEMOD | \
TERMKEY_FORMAT_LOWERSPACE)
size_t termkey_strfkey(TermKey *tk, char *buffer, size_t len, TermKeyKey *key, TermKeyFormat format);
const char *termkey_strpkey(TermKey *tk, const char *str, TermKeyKey *key, TermKeyFormat format);
size_t termkey_strfkey (termkey_t *tk, char *buffer, size_t len,
termkey_key_t *key, termkey_format_t format);
const char *termkey_strpkey (termkey_t *tk, const char *str,
termkey_key_t *key, termkey_format_t format);
int termkey_keycmp(TermKey *tk, const TermKeyKey *key1, const TermKeyKey *key2);
int termkey_keycmp (termkey_t *tk,
const termkey_key_t *key1, const termkey_key_t *key2);
#endif
#endif // ! TERMKEY_H
#ifdef __cplusplus
}
#endif