---
name: "termkey_getkey"
section: "3"
platform: "linux"
package: "libtermkey-dev"
version: "0.22-2+b1"
release: "Debian 13 (Trixie)"
platforms: ["linux"]
url: "https://new.carta.tech/termkey_getkey"
---

# termkey\_getkey(3)

retrieve the next key event

## NAME

termkey\_getkey, termkey\_getkey\_force - retrieve the next key event

## SYNOPSIS

```
#include <termkey.h>

TermKeyResult termkey_getkey(TermKey *tk, TermKeyKey *key);
TermKeyResult termkey_getkey_force(TermKey *tk, TermKeyKey *key);
```

Link with *-ltermkey*.

## DESCRIPTION

**termkey\_getkey**() attempts to retrieve a single keypress event from the [**termkey**(7)](/termkey/7.md) instance buffer, and put it in the structure referred to by *key*. It returns one of the following values:

- **TERMKEY\_RES\_KEY**

  a complete keypress was removed from the buffer, and has been placed in the *key* structure.

- **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 **termkey\_getkey\_force**() would return has been placed in the *key* structure.

- **TERMKEY\_RES\_NONE**

  no bytes are waiting in the buffer.

- **TERMKEY\_RES\_EOF**

   no bytes are ready and the input stream is now closed.

- **TERMKEY\_RES\_ERROR**

  called with terminal IO stopped, due to **termkey\_stop**(3). In this case *errno* will be set to **EINVAL**.

**termkey\_getkey\_force**() is similar to **termkey\_getkey**() but will not return **TERMKEY\_RES\_AGAIN** 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 *Escape* key followed by normal letters.

Neither of these functions will block or perform any IO operations on the underlying filehandle. To use the instance in an asynchronous program, see [**termkey\_advisereadable**(3)](/termkey_advisereadable/3.md). For a blocking call suitable for use in a synchronous program, use [**termkey\_waitkey**(3)](/termkey_waitkey/3.md) instead of **termkey\_getkey**(). For providing input without a readable filehandle, use [**termkey\_push\_bytes**(3)](/termkey_push_bytes/3.md).

Before returning, this function canonicalises the *key* structure according to the rules given for [**termkey\_canonicalise**(3)](/termkey_canonicalise/3.md).

## 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, except for **TERMKEY\_RES\_AGAIN**.

## EXAMPLE

The following example program prints details of every keypress until the user presses *Ctrl-C*. It demonstrates how to use the **termkey** instance in a typical [**poll**(2)](/poll/2.md)-driven asynchronous program, which may include mixed IO with other file handles.

```
// <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_advisereadable/3.md), [**termkey\_waitkey**(3)](/termkey_waitkey/3.md), **termkey\_get\_waittime**(3), [**termkey**(7)](/termkey/7.md)
