TERMKEY_GETKEY(3)
πΈ TERMKEY_GETKEY πΈ
okay bestie, we're doing termkey_getkey and termkey_getkey_force today, and honestly? iconic. these two live in termkey(3) and their whole job is handing you the next key event. no cap. let's get into it π
β¨ SYNOPSIS β¨
#include <termkey.h>
TermKeyResult termkey_getkey(TermKey *tk, TermKeyKey *key);
TermKeyResult termkey_getkey_force(TermKey *tk, TermKeyKey *key);
Link with -ltermkey.
π DESCRIPTION π
so termkey_getkey() is the main character here π«Ά β it tries to pull one single keypress event out of the termkey(7) instance buffer and tuck it into the structure that key points at. cute, right?
and then it returns one of these lil guys, so listen up π:
TERMKEY_RES_KEYβ yesss, a complete keypress got yeeted out of the buffer and is now sitting in the key structure. we ate. π₯TERMKEY_RES_AGAINβ hmm, there's a partial keypress event in the buffer but it doesn't have all the bytes it needs yet π. and bestie, it also drops a lil preview of whattermkey_getkey_force()would return right into the key structure. foreshadowing, honestly.TERMKEY_RES_NONEβ the buffer is empty. nothing. zero. nada. ghost town πTERMKEY_RES_EOFβ no bytes are ready and the input stream is closed now. it's over. πTERMKEY_RES_ERRORβ you called this while terminal IO was stopped, because oftermkey_stop(3). and in that caseerrnogets set toEINVAL. so check it, bestie π«Ά
now termkey_getkey_force() is like termkey_getkey()'s chaotic older sister β it's similar, but it will NOT return TERMKEY_RES_AGAIN if it finds a partial match. instead it just forces an interpretation of the bytes π
. and yes, that means it might read the start of an Escape-prefixed multi-byte sequence as a literal Escape key followed by normal letters. that's the tradeoff. periodt.
π¨ neither of these functions will block or do any IO operations on the underlying filehandle. so don't come for them for that.
okay so what do you do instead, you ask? slay, glad you asked:
- wanna use the instance in an asynchronous program? see
termkey_advisereadable(3)β¨ - want a blocking call that's suitable for a synchronous program? use
termkey_waitkey(3)instead oftermkey_getkey()π - want to feed input in without a readable filehandle? that's
termkey_push_bytes(3)π¦
and before it returns, this function canonicalises the key structure according to the rules given for termkey_canonicalise(3). so it comes out all neat and pretty. the way that it just... tidies up. obsessed πΈ
π RETURN VALUE π
termkey_getkey() returns an enumeration of one of TERMKEY_RES_KEY, TEMRKEY_RES_AGAIN, TERMKEY_RES_NONE, TERMKEY_RES_EOF or TERMKEY_RES_ERROR.
termkey_getkey_force() returns one of the above too, except for TERMKEY_RES_AGAIN. she simply refuses. π
π EXAMPLE π
this lil program prints the deets of every keypress until you hit Ctrl-C. it's showing off how to use the termkey instance in a typical poll(2)-driven asynchronous program, which may also include mixed IO with other file handles. multi-tasking queen π
// <poll.h> might need this for sigset_t
#define _XOPEN_SOURCE 600
#include <poll.h>
#include <stdio.h>
#include "termkey.h"
static void on_key(TermKey *tk, TermKeyKey *key)
{
char buffer[50];
termkey_strfkey(tk, buffer, sizeof buffer, key, TERMKEY_FORMAT_VIM);
printf("%s\n", buffer);
}
int main(int argc, char *argv[])
{
TERMKEY_CHECK_VERSION;
TermKey *tk = termkey_new(0, 0);
if(!tk) {
fprintf(stderr, "Cannot allocate termkey instance\n");
exit(1);
}
struct pollfd fd;
fd.fd = 0; /* the file descriptor we passed to termkey_new() */
fd.events = POLLIN;
TermKeyResult ret;
TermKeyKey key;
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);
}
if(fd.revents & (POLLIN|POLLHUP|POLLERR))
termkey_advisereadable(tk);
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(ret == TERMKEY_RES_AGAIN)
nextwait = termkey_get_waittime(tk);
else
nextwait = -1;
}
termkey_destroy(tk);
}
π¦ SEE ALSO π¦
termkey_advisereadable(3), termkey_waitkey(3), termkey_get_waittime(3), termkey(7)
and that's the whole page bestie!! π this was TERMKEY_GETKEY(3), and yeah β that's literally the name stamped at the top and the bottom, she's consistent like that πβ¨ go forth and read them keys, iykyk ππ
π¦ where this page comes from
- alpine 3.24: libtermkey-doc 0.22-r4 Β· MIT
- debian trixie: libtermkey-dev 0.22-2+b1 Β· MIT
- epel 10: libtermkey-devel 0.22-2.el10_0 Β· MIT
- epel 9: libtermkey-devel 0.22-2.el9 Β· MIT
- fedora 43: libtermkey-devel 0.22-11.fc43 Β· MIT
- fedora 43: libtermkey-devel 0.22-11.fc43 Β· MIT
- fedora 44: libtermkey-devel 0.22-12.fc44 Β· MIT
- fedora 44: libtermkey-devel 0.22-12.fc44 Β· MIT
- nixos 26.05: libtermkey 0.22
- nixpkgs unstable: libtermkey 0.22
- opensuse-leap 16.0: libtermkey-devel 0.22-bp160.1.11 Β· MIT
- opensuse-leap 16.0: libtermkey-devel 0.22-bp160.1.11 Β· MIT
- opensuse-leap 16.0: libtermkey-devel 0.22-bp160.1.11 Β· MIT
- opensuse-leap 16.0: libtermkey-devel 0.22-bp160.1.11 Β· MIT
- ubuntu questing: libtermkey-dev 0.22-2
- ubuntu resolute: libtermkey-dev 0.22-2build1 Β· MIT
- ubuntu stonking: libtermkey-dev 0.22-3 Β· MIT
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms