---
name: "getch"
section: "3ncurses"
platform: "linux"
package: "ncurses-doc"
version: "6.5+20250216-2"
release: "Debian 13 (Trixie)"
platforms: ["linux"]
url: "https://new.carta.tech/getch/3ncurses"
---

# getch(3ncurses)

get (or push back) characters from curses terminal keyboard buffer

## NAME

**getch**, **wgetch**, **mvgetch**, **mvwgetch**, **ungetch**, **has\_key** - get (or push back) characters from *curses* terminal keyboard buffer

## SYNOPSIS

```
#include <curses.h>
```

**int getch(void);** **int wgetch(WINDOW \* *win*);** **int mvgetch(int *y*, int *x*);** **int mvwgetch(WINDOW \* *win*, int *y*, int *x*);**

**int ungetch(int *c*);**

*/\* extension \*/* **int has\_key(int *c*);**

## DESCRIPTION

### Reading Characters

**wgetch** gathers a key event from the terminal keyboard associated with a *curses* window *win*. **ncurses**(3NCURSES) describes the variants of this function.

When input is pending, **wgetch** returns an integer identifying the key event; for alphanumeric and punctuation keys, this value corresponds to the character encoding used by the terminal. Use of the control key as a modifier, by holding it down while pressing and releasing another key, often results in a distinct code. The behavior of other keys depends on whether *win* is in keypad mode; see subsection “Keypad Mode” below.

If no input is pending, then if the no-delay flag is set in the window (see **nodelay**(3NCURSES)), the function returns **ERR**; otherwise, *curses* waits until the terminal has input. If **cbreak**(3NCURSES) or **raw**(3NCURSES) has been called, this happens after one character is read. If **nocbreak**(3NCURSES) or **noraw**(3NCURSES) has been called, it occurs when the next newline is read. (Because the terminal's canonical or “cooked” mode is line-buffered, multiple **wgetch** calls may then be necessary to empty the input queue.) If **halfdelay**(3NCURSES) has been called, *curses* waits until input is available or the specified delay elapses.

If **echo**(3NCURSES) has been called, and the window is not a pad, *curses* writes the returned character *c* to the window (at the cursor position) per the following rules.

- •

  If *c* matches the terminal's erase character (see **erasechar**(3NCURSES)), the cursor moves leftward one position and the new position is erased as if **wmove**(3NCURSES) and then **wdelch**(3NCURSES) were called. When the window's keypad mode is enabled (see below), **KEY\_LEFT** and **KEY\_BACKSPACE** are handled the same way.

- •

  *curses* writes any other *c* to the window, as with **wechochar**(3NCURSES).

- •

  If the window *win* has been moved or modified since the last call to **wrefresh**(3NCURSES), *curses* calls **wrefresh** on it.

If *c* is a carriage return and **nl**(3NCURSES) has been called, **wgetch** returns the character code for line feed instead.

### Keypad Mode

To *curses*, key strokes not from the alphabetic section of the keyboard (those corresponding to the ECMA-6 character set—see [*ascii*(7)](/ascii/7.md)—optionally modified by either the control or shift keys) are treated as *function* keys. (In *curses*, the term “function key” includes but is not limited to keycaps engraved with “F1”, “PF1”, and so on.) If the window is in keypad mode, these produce a numeric code corresponding to the **KEY\_** symbols listed in subsection “Predefined Key Codes” below; otherwise, they transmit a sequence of codes typically starting with the escape character, and which must be collected with multiple **wgetch** calls.

- •

  The *curses.h* header file declares many *predefined function keys* whose names begin with **KEY\_**; these object-like macros have values outside the range of eight-bit character codes.

- •

  In *ncurses*, *user-defined function keys* are configured with **define\_key**(3NCURSES); they have no names, but are also expected to have values outside the range of eight-bit codes.

A variable intended to hold a function key code must thus be of type *short* or larger.

Most terminals one encounters follow the ECMA-48 standard insofar as their function keys produce character sequences prefixed with the escape character ESC. This fact implies that *curses* cannot distinguish a user's press of the escape key (assuming it sends ESC) from the beginning of a function key's character sequence without waiting to see if, and how soon, further input arrives. When *curses* reads such an ambiguous character, it sets a timer. If the remainder of the sequence does not arrive within the designated time, **wgetch** returns the prefix character; otherwise, it returns the function key code corresponding to the unique sequence defined by the terminal. Consequently, a user of a *curses* application may experience a delay after the escape key is pressed while *curses* disambiguates the input; see section “EXTENSIONS” below. If the window is in “no time-out” mode, the timer does not expire; it is an infinite (or very large) value. See **notimeout**(3NCURSES). Because function key sequences usually begin with ESC, the terminal may appear to hang in no time-out mode after the user presses the escape key. Generally, further typing “awakens” *curses*.

### Ungetting Characters

**ungetch** places *c* into the input queue to be returned by the next call to **wgetch**. A single input queue serves all windows associated with the screen.

### Predefined Key Codes

The header file *curses.h* defines the following function key codes.

- •

  Except for the special case of **KEY\_RESIZE**, a window's keypad mode must be enabled for **wgetch** to read these codes from it.

- •

  Not all of these are necessarily supported on any particular terminal.

- •

  The naming convention may seem obscure, with some apparent misspellings (such as “RSUME” for “resume”); the names correspond to the *terminfo* capability names for the keys, and were standardized before the IBM PC/AT keyboard layout achieved a dominant position in industry.

| | |
| --- | --- |
| **Symbol** | **Key name** |
| **KEY\_BREAK** | Break key |
| **KEY\_DOWN** | Arrow keys |
| **KEY\_UP** |  |
| **KEY\_LEFT** |  |
| **KEY\_RIGHT** |  |
| **KEY\_HOME** | Home key (upward+left arrow) |
| **KEY\_BACKSPACE** | Backspace |
| **KEY\_F0** | Function keys; space for 64 keys is reserved |
| **KEY\_F(*n*)** | Function key *n* where 0 ≤ *n* ≤ 63 |
| **KEY\_DL** | Delete line |
| **KEY\_IL** | Insert line |
| **KEY\_DC** | Delete character |
| **KEY\_IC** | Insert character/Enter insert mode |
| **KEY\_EIC** | Exit insert character mode |
| **KEY\_CLEAR** | Clear screen |
| **KEY\_EOS** | Clear to end of screen |
| **KEY\_EOL** | Clear to end of line |
| **KEY\_SF** | Scroll one line forward |
| **KEY\_SR** | Scroll one line backward (reverse) |
| **KEY\_NPAGE** | Next page/Page up |
| **KEY\_PPAGE** | Previous page/Page down |
| **KEY\_STAB** | Set tab |
| **KEY\_CTAB** | Clear tab |
| **KEY\_CATAB** | Clear all tabs |
| **KEY\_ENTER** | Enter/Send |
| **KEY\_SRESET** | Soft (partial) reset |
| **KEY\_RESET** | (Hard) reset |
| **KEY\_PRINT** | Print/Copy |
| **KEY\_LL** | Home down/Bottom (lower left) |
| **KEY\_A1** | Upper left of keypad |
| **KEY\_A3** | Upper right of keypad |
| **KEY\_B2** | Center of keypad |
| **KEY\_C1** | Lower left of keypad |
| **KEY\_C3** | Lower right of keypad |
| **KEY\_BTAB** | Back tab key |
| **KEY\_BEG** | Beg(inning) key |
| **KEY\_CANCEL** | Cancel key |
| **KEY\_CLOSE** | Close key |
| **KEY\_COMMAND** | Cmd (command) key |
| **KEY\_COPY** | Copy key |
| **KEY\_CREATE** | Create key |
| **KEY\_END** | End key |
| **KEY\_EXIT** | Exit key |
| **KEY\_FIND** | Find key |
| **KEY\_HELP** | Help key |
| **KEY\_MARK** | Mark key |
| **KEY\_MESSAGE** | Message key |
| **KEY\_MOUSE** | Mouse event occurred |
| **KEY\_MOVE** | Move key |
| **KEY\_NEXT** | Next object key |
| **KEY\_OPEN** | Open key |
| **KEY\_OPTIONS** | Options key |
| **KEY\_PREVIOUS** | Previous object key |
| **KEY\_REDO** | Redo key |
| **KEY\_REFERENCE** | Ref(erence) key |
| **KEY\_REFRESH** | Refresh key |
| **KEY\_REPLACE** | Replace key |
| **KEY\_RESIZE** | Screen resized |
| **KEY\_RESTART** | Restart key |
| **KEY\_RESUME** | Resume key |
| **KEY\_SAVE** | Save key |
| **KEY\_SELECT** | Select key |
| **KEY\_SUSPEND** | Suspend key |
| **KEY\_UNDO** | Undo key |
| **KEY\_SBEG** | Shifted beginning key |
| **KEY\_SCANCEL** | Shifted cancel key |
| **KEY\_SCOMMAND** | Shifted command key |
| **KEY\_SCOPY** | Shifted copy key |
| **KEY\_SCREATE** | Shifted create key |
| **KEY\_SDC** | Shifted delete character key |
| **KEY\_SDL** | Shifted delete line key |
| **KEY\_SEND** | Shifted end key |
| **KEY\_SEOL** | Shifted clear line key |
| **KEY\_SEXIT** | Shifted exit key |
| **KEY\_SFIND** | Shifted find key |
| **KEY\_SHELP** | Shifted help key |
| **KEY\_SHOME** | Shifted home key |
| **KEY\_SIC** | Shifted insert key |
| **KEY\_SLEFT** | Shifted left arrow key |
| **KEY\_SMESSAGE** | Shifted message key |
| **KEY\_SMOVE** | Shifted move key |
| **KEY\_SNEXT** | Shifted next object key |
| **KEY\_SOPTIONS** | Shifted options key |
| **KEY\_SPREVIOUS** | Shifted previous object key |
| **KEY\_SPRINT** | Shifted print key |
| **KEY\_SREDO** | Shifted redo key |
| **KEY\_SREPLACE** | Shifted replace key |
| **KEY\_SRIGHT** | Shifted right arrow key |
| **KEY\_SRSUME** | Shifted resume key |
| **KEY\_SSAVE** | Shifted save key |
| **KEY\_SSUSPEND** | Shifted suspend key |
| **KEY\_SUNDO** | Shifted undo key |

Many keyboards feature a nine-key directional pad.

| | | |
| --- | --- | --- |
| A1 | up | A3 |
| left | B2 | right |
| C1 | down | C3 |

Two of the symbols in the list above do *not* correspond to a physical key.

- •

  **wgetch** returns **KEY\_RESIZE**, even if the window's keypad mode is disabled, if *ncurses* has handled a **SIGWINCH** signal since **wgetch** was called; see **initscr**(3NCURSES) and **resizeterm**(3NCURSES).

- •

  **wgetch** returns **KEY\_MOUSE** to indicate that a mouse event is pending collection; see **mouse**(3NCURSES). Receipt of this code requires a window's keypad mode to be enabled, because to interpret mouse input (as with [*xterm*(1)](/xterm/1.md)'s mouse protocol), *ncurses* must read an escape sequence, as with a function key.

### Testing Key Codes

In *ncurses*, **has\_key** returns a Boolean value indicating whether the terminal type recognizes its parameter as a key code value. See also **define\_key**(3NCURSES) and **key\_defined**(3NCURSES).

## RETURN VALUE

**wgetch** returns a key code identifying the key event as described above, which may include **KEY\_RESIZE** or **KEY\_MOUSE** indicating non-key events, or **ERR** on failure. **wgetch** fails if

- •

  its timeout expires without any data arriving, or

- •

  execution was interrupted by a signal, in which case *errno* is set to *EINTR*.

**ungetch** returns **OK** on success and **ERR** on failure. **ungetch** fails if there is no more room in the input queue.

**has\_key** returns **TRUE** or **FALSE**.

Functions taking a *WINDOW* pointer argument fail if *win* is a null pointer.

Functions prefixed with “mv” first perform cursor movement and fail if the position (*y*, *x*) is outside the window boundaries.

## NOTES

**getch**, **mvgetch**, and **mvwgetch** may be implemented as macros.

*curses* discourages assignment of the ESC key to a discrete function by the programmer because the library requires a delay while it awaits the potential remainder of a terminal escape sequence.

Some key strokes are indistinguishable from control characters; for example, **KEY\_ENTER** may be the same as **^M**, and **KEY\_BACKSPACE** may be the same as **^H** or **^?**. Consult the *terminfo* entry for the terminal type to determine whether this is the case; see [**infocmp**(1)](/infocmp/1.md). Some *curses* implementations, including *ncurses*, honor the *terminfo* key definitions; others treat such control characters specially.

*curses* distinguishes the Enter keys in the alphabetic and numeric keypad sections of a keyboard because (most) terminals do. **KEY\_ENTER** refers to the key on the numeric keypad and, like other function keys, is reliably recognized only if the window's keypad mode is enabled.

- •

  The *terminfo* **key\_enter** (**kent**) capability describes the character (sequence) sent by the Enter key of a terminal's numeric (or similar) keypad.

- •

  “Enter or send” is X/Open Curses's description of this key.

*curses* treats the Enter or Return key in the *alphabetic* section of the keyboard differently.

- •

  It usually produces a control code for carriage return (**^M**) or line feed (**^J**).

- •

  Depending on the terminal mode (raw, cbreak, or canonical), and whether **nl**(3NCURSES) or **nonl**(3NCURSES) has been called, **wgetch** may return either a carriage return or line feed upon an Enter or Return key stroke.

Use of **wgetch** with **echo**(3NCURSES) and neither **cbreak**(3NCURSES) nor **raw**(3NCURSES) is not well-defined.

Historically, the list of key code macros above was influenced by the keyboard of the AT&T 7300 (also known variously as the “3B1”, “Safari 4”, and “UNIX PC”), a 1985 machine rich in function keys. Today's computer keyboards are based on that of the IBM PC/AT and tend to have fewer. A *curses* application can expect such a keyboard to transmit key codes **KEY\_UP**, **KEY\_DOWN**, **KEY\_LEFT**, **KEY\_RIGHT**, **KEY\_HOME**, **KEY\_END**, **KEY\_PPAGE** (Page Up), **KEY\_NPAGE** (Page Down), **KEY\_IC** (Insert), **KEY\_DC** (Delete), **KEY\_A1**, **KEY\_A3**, **KEY\_B2**, **KEY\_C1**, **KEY\_C3**, and **KEY\_F(***n***)** for 1 ≤ *n* ≤ 12.

## EXTENSIONS

In *ncurses*, when a window's “no time-out” mode is *not* set, the **ESCDELAY** variable configures the duration of the timer used to disambiguate a function key character sequence from a series of key strokes beginning with ESC typed by the user; see **curses\_variables**(3NCURSES).

**has\_key** is an *ncurses* extension, and is not found in SVr4 *curses*, 4.4BSD *curses*, or any other previous *curses* implementation.

## PORTABILITY

Applications employing *ncurses* extensions should condition their use on the visibility of the **NCURSES\_VERSION** preprocessor macro.

Except as noted in section “EXTENSIONS” above, X/Open Curses Issue 4 describes these functions. It specifies no error conditions for them.

SVr4 describes a successful return value only as “an integer value other than *ERR*”.

*wgetch* reads only single-byte characters.

The echo behavior of these functions on input of *KEY\_* or backspace characters is not documented in SVr4 *curses*.

The behavior of *wgetch* in the presence of signal handlers is not documented in SVr4 *curses* and is unspecified by X/Open Curses. In historical *curses* implementations, it varied depending on whether the operating system's dispatch of a signal to a handler interrupted a [*read*(2)](/read/2.md) call in progress, and also (in some implementations) whether an input timeout or non-blocking mode had been set. A portable *curses* application prepares for two cases: (a) signal receipt does not interrupt *wgetch*; or (b) signal receipt interrupts *wgetch* and causes it to return *ERR* with *errno* set to *EINTR*.

*KEY\_MOUSE* is mentioned in X/Open Curses, along with a few related *terminfo* capabilities, but no higher-level functions use the feature. The implementation in *ncurses* is an extension.

*KEY\_RESIZE* and *has\_key* are extensions first implemented for *ncurses*. By 2022, *PDCurses* and NetBSD *curses* had added them along with *KEY\_MOUSE*.

## SEE ALSO

ECMA-6 “7-bit coded Character Set” \<https://ecma-international.org/publications-and-standards/standards/ecma-6/\>

ECMA-48 “Control Functions for Coded Character Sets” \<https://ecma-international.org/publications-and-standards/standards/ecma-48/\>

**get\_wch**(3NCURSES) describes comparable functions of the *ncurses* library in its wide-character configuration (*ncursesw*).

**ncurses**(3NCURSES), **addch**(3NCURSES), **inopts**(3NCURSES), **mouse**(3NCURSES), **move**(3NCURSES), **outopts**(3NCURSES), **refresh**(3NCURSES), **curses\_variables**(3NCURSES), **resizeterm**(3NCURSES), [**ascii**(7)](/ascii/7.md)
