diff options
author | Mattias Andrée <m@maandree.se> | 2025-02-01 21:42:48 +0100 |
---|---|---|
committer | Mattias Andrée <m@maandree.se> | 2025-02-01 21:42:48 +0100 |
commit | 92e60862ad1c47530886682b30ea1d1c72526a28 (patch) | |
tree | f1eaed56bb43cd55a2b8807bfbd74d150bdf8ff5 /libterminput.h | |
parent | libterminput_read.3: add missing member in union libterminput_input (diff) | |
download | libterminput-92e60862ad1c47530886682b30ea1d1c72526a28.tar.gz libterminput-92e60862ad1c47530886682b30ea1d1c72526a28.tar.bz2 libterminput-92e60862ad1c47530886682b30ea1d1c72526a28.tar.xz |
m misc + add documentation to the header file
Signed-off-by: Mattias Andrée <m@maandree.se>
Diffstat (limited to '')
-rw-r--r-- | libterminput.h | 472 |
1 files changed, 446 insertions, 26 deletions
diff --git a/libterminput.h b/libterminput.h index d5c5439..7163140 100644 --- a/libterminput.h +++ b/libterminput.h @@ -9,13 +9,47 @@ * Flags for supporting incompatible input; the user must * set or clear his flag after setting or clearing it on * the terminal, and the user must make sure that the - * terminal support this flag if set. + * terminal support this flag if set */ enum libterminput_flags { + /** + * The sequence CSI M shall be parsed be parse as a DECSET 1005 + * sequence which is incompatible with legacy mouse tracking + * + * This flag shall only be set if DECSET 1005 has sent to the + * terminal and the user is sure it is supported by the terminal + */ LIBTERMINPUT_DECSET_1005 = 0x0001, + + /** + * Parse CSI M as Macro key presses rather rather than + * mouse tracking events + * + * This is incompatible with all mouse tracking modes except + * DECSET 1006 + */ LIBTERMINPUT_MACRO_ON_CSI_M = 0x0002, + + /** + * Parse CSI P as Pause key presses rather than F1 key presses + */ LIBTERMINPUT_PAUSE_ON_CSI_P = 0x0004, + + /** + * Parse CSI @ as Insert key presses rather than a number of + * possible special keys combined with the control and shift + * modifiers + */ LIBTERMINPUT_INS_ON_CSI_AT = 0x0008, + + /** + * Backtab shall be treated as a separate key, and not be + * reported as tab with the shift modifier. This flag is just + * a usability issue. Keyboards put backtab on shift+tab, + * which is why the tab keycap has both a backward arrow + * (backtab) and a forward arrow (tab); but most users are + * unfamiliar with backtab, and just see it as shift+tab. + */ LIBTERMINPUT_SEPARATE_BACKTAB = 0x0010, /** @@ -27,17 +61,62 @@ enum libterminput_flags { */ LIBTERMINPUT_ESC_ON_BLOCK = 0x0020, + /** + * This flag should be set, by the application, once + * the application sends an escape sequence requesting + * the terminal to report the cursor's position, and + * cleared once the position has been sent by the + * terminal and retreived by application + * + * This is required for distinguishing cursor position + * reports from F3 key presses + */ LIBTERMINPUT_AWAITING_CURSOR_POSITION = 0x0040 }; +/** + * Modifier keys + * + * These are the commonly reported modifiers, + * but additional modifiers are possible + */ enum libterminput_mod { + /** + * Shift modifier + */ LIBTERMINPUT_SHIFT = 0x01, + + /** + * Meta/Alternative modifier + */ LIBTERMINPUT_META = 0x02, + + /** + * Control modifier + */ LIBTERMINPUT_CTRL = 0x04 }; +/** + * Keyboard buttons + * + * Only listed values can be reported, however the value + * must be listed for the version the application is linked + * against, not compiled against, so other values can be + * reported the application is linked against a newer version + * of the library than it is compiled against + */ enum libterminput_key { + /** + * Non-special key + * + * Each code point that is generated as a keypress + * is reported separately, meaning that keypresses + * that generate multiple code points appear as + * multiple keypresses + */ LIBTERMINPUT_SYMBOL, + LIBTERMINPUT_UP, LIBTERMINPUT_DOWN, LIBTERMINPUT_RIGHT, @@ -85,88 +164,399 @@ enum libterminput_key { LIBTERMINPUT_KEYPAD_DECIMAL, LIBTERMINPUT_KEYPAD_COMMA, LIBTERMINPUT_KEYPAD_POINT, - LIBTERMINPUT_KEYPAD_ENTER, + LIBTERMINPUT_KEYPAD_ENTER }; +/** + * Mouse buttons + * + * It is possible that non-listed buttons are + * reported in events + */ enum libterminput_button { + /** + * No mouse button is held down + */ LIBTERMINPUT_NO_BUTTON, - LIBTERMINPUT_BUTTON1, /* left (assuming right-handed) */ - LIBTERMINPUT_BUTTON2, /* middle */ - LIBTERMINPUT_BUTTON3, /* right (assuming right-handed) */ - LIBTERMINPUT_SCROLL_UP, /* no corresponding release event shall be generated */ - LIBTERMINPUT_SCROLL_DOWN, /* no corresponding release event shall be generated */ - LIBTERMINPUT_SCROLL_LEFT, /* may or may not have a corresponding release event */ - LIBTERMINPUT_SCROLL_RIGHT, /* may or may not have a corresponding release event */ - LIBTERMINPUT_XBUTTON1, /* extended button 1, also known as backward */ - LIBTERMINPUT_XBUTTON2, /* extended button 2, also known as forward */ - LIBTERMINPUT_XBUTTON3, /* extended button 3, you probably don't have this button */ - LIBTERMINPUT_XBUTTON4 /* extended button 4, you probably don't have this button */ + + /** + * Primary button + * + * Left button if right-handed, + * right button if left-handed + */ + LIBTERMINPUT_BUTTON1, + + /** + * Middle button + */ + LIBTERMINPUT_BUTTON2, + + /** + * Secondary button + * + * Right button if right-handed, + * left button if left-handed + */ + LIBTERMINPUT_BUTTON3, + + /** + * Wheel scrolled up + * + * No corresponding release event shall be generated + */ + LIBTERMINPUT_SCROLL_UP, + + /** + * Wheel scrolled down + * + * No corresponding release event shall be generated + */ + LIBTERMINPUT_SCROLL_DOWN, + + /** + * Left-scroll button or wheel scrolled left + * + * May or may not have a corresponding release event + */ + LIBTERMINPUT_SCROLL_LEFT, + + /** + * Right-scroll button or wheel scrolled right + * + * May or may not have a corresponding release event + */ + LIBTERMINPUT_SCROLL_RIGHT, + + /** + * Extended button 1, also known as backward + */ + LIBTERMINPUT_XBUTTON1, + + /** + * Extended button 2, also known as farward + */ + LIBTERMINPUT_XBUTTON2, + + /** + * Extended button 3 + * + * You probably don't have this button + */ + LIBTERMINPUT_XBUTTON3, + + /** + * Extended button 4 + * + * You probably don't have this button + */ + LIBTERMINPUT_XBUTTON4 }; +/** + * Input event type + */ enum libterminput_type { + /** + * A special value to mark that the input was either + * discard or not yet completed + */ LIBTERMINPUT_NONE, + + /** + * Normal key press + */ LIBTERMINPUT_KEYPRESS, + + /** + * Pseudo-event that marks that beginning of a bracketed paste + */ LIBTERMINPUT_BRACKETED_PASTE_START, + + /** + * Pseudo-event that marks that end of a bracketed paste + */ LIBTERMINPUT_BRACKETED_PASTE_END, + + /** + * Bracketed paste + */ LIBTERMINPUT_TEXT, + + /** + * Mouse event + */ LIBTERMINPUT_MOUSEEVENT, + + /** + * OK response for a device status query + */ LIBTERMINPUT_TERMINAL_IS_OK, /* response to CSI 5 n */ + + /** + * Not-OK response for a device status query + */ LIBTERMINPUT_TERMINAL_IS_NOT_OK, /* response to CSI 5 n */ + + /** + * Cursor position report event as a response + * to a cursor position query + */ LIBTERMINPUT_CURSOR_POSITION /* response to CSI 6 n */ }; +/** + * Mouse event subtype + */ enum libterminput_event { + /** + * Mouse button pressed + */ LIBTERMINPUT_PRESS, + + /** + * Mouse button released + */ LIBTERMINPUT_RELEASE, + + /** + * Mouse moved, possibly with dragging + */ LIBTERMINPUT_MOTION, + + /** + * Highlight ended inside of selected region + */ LIBTERMINPUT_HIGHLIGHT_INSIDE, + + /** + * Highlight ended outside of selected region + */ LIBTERMINPUT_HIGHLIGHT_OUTSIDE }; +/** + * Keypress event + * + * Some key presses may actually be mouse events, + * particularly when mouse tracking is disabled. + * In particular, mouse scrolling may appear as + * repeated Up key or Down key pesses + */ struct libterminput_keypress { + /** + * Should be `LIBTERMINPUT_KEYPRESS` + */ enum libterminput_type type; + + /** + * Which key was pressed + */ enum libterminput_key key; - unsigned long long int times; /* if .times > 1, next will be the same, but will .times -= 1 */ + + /** + * This number of types the key was + * pressed + * + * Normally this would be 1, some mouse + * events generate arrow key presses that + * are reported, not multiple times, but + * as clicked multiple times + * + * For the next `.times - 1` reads (if + * this value is not modified by the user) + * will reported as the same event except + * that this value will be decreased by 1 + * each time + */ + unsigned long long int times; + + /** + * OR of active modifier keys + */ enum libterminput_mod mods; - char symbol[7]; /* use if .key == LIBTERMINPUT_SYMBOL */ + + /** + * The symbol generated by the pressed key + * + * Only set if `.key == LIBTERMINPUT_SYMBOL` + */ + char symbol[7]; }; +/** + * Text from a bracketed paste + */ struct libterminput_text { + /** + * Should be `LIBTERMINPUT_TEXT` + */ enum libterminput_type type; + + /** + * The number of bytes available in `.bytes` + */ size_t nbytes; + + /** + * The section of the paste included in this + * event report + * + * If the text is longer than this buffer, it + * is split into multiple events, however they + * will all be between the same + * `LIBTERMINPUT_BRACKETED_PASTE_START` and + * `LIBTERMINPUT_BRACKETED_PASTE_END`, so it is + * possible to determine which events are actually + * the same paste event + */ char bytes[512]; }; +/** + * Mouse event + */ struct libterminput_mouseevent { + /** + * Should be `LIBTERMINPUT_MOUSEEVENT` + */ enum libterminput_type type; - enum libterminput_mod mods; /* Set to 0 for LIBTERMINPUT_HIGHLIGHT_INSIDE and LIBTERMINPUT_HIGHLIGHT_OUTSIDE */ - enum libterminput_button button; /* Set to 1 for LIBTERMINPUT_HIGHLIGHT_INSIDE and LIBTERMINPUT_HIGHLIGHT_OUTSIDE */ + + /** + * Active modifier keys + * + * Set to 0 for `LIBTERMINPUT_HIGHLIGHT_INSIDE` + * and `LIBTERMINPUT_HIGHLIGHT_OUTSIDE` + */ + enum libterminput_mod mods; + + /** + * The mouse button used in the event + * + * Set to 1 (LIBTERMINPUT_BUTTON1) for + * `LIBTERMINPUT_HIGHLIGHT_INSIDE` and + * `LIBTERMINPUT_HIGHLIGHT_OUTSIDE` + */ + enum libterminput_button button; + + /** + * Mouse event sub type + */ enum libterminput_event event; + + /** + * Horizontal pointer position + * + * The number of cells offset right from the left edge, plus 1 + */ size_t x; + + /** + * Vertical pointer position + * + * The number of cells offset down from the top edge, plus 1 + */ size_t y; - size_t start_x; /* Only set for LIBTERMINPUT_HIGHLIGHT_OUTSIDE */ - size_t start_y; /* Only set for LIBTERMINPUT_HIGHLIGHT_OUTSIDE */ - size_t end_x; /* Only set for LIBTERMINPUT_HIGHLIGHT_OUTSIDE */ - size_t end_y; /* Only set for LIBTERMINPUT_HIGHLIGHT_OUTSIDE */ + + /** + * Horizontal beginning of the selection region + * + * Only set for `LIBTERMINPUT_HIGHLIGHT_OUTSIDE` + */ + size_t start_x; + + /** + * Vertical beginning of the selection region + * + * Only set for `LIBTERMINPUT_HIGHLIGHT_OUTSIDE` + */ + size_t start_y; + + /** + * Horizontal end of the selection region + * + * Only set for `LIBTERMINPUT_HIGHLIGHT_OUTSIDE` + */ + size_t end_x; + + /** + * Vertical end of the selection region + * + * Only set for `LIBTERMINPUT_HIGHLIGHT_OUTSIDE` + */ + size_t end_y; }; +/** + * Cursor position response + */ struct libterminput_position { + /** + * Should be `LIBTERMINPUT_CURSOR_POSITION` + */ enum libterminput_type type; + + /** + * Horizontal cursor position + * + * The number of cells offset right from the left edge, plus 1 + */ size_t x; + + /** + * Vertical cursor position + * + * The number of cells offset down from the top edge, plus 1 + */ size_t y; }; +/** + * Input event + */ union libterminput_input { + /** + * Input event type, used to determine which + * other member to read + * + * The following values have no corresponding + * member to read data from: + * `LIBTERMINPUT_NONE`, + * `LIBTERMINPUT_BRACKETED_PASTE_START`, + * `LIBTERMINPUT_BRACKETED_PASTE_END`, + * `LIBTERMINPUT_TERMINAL_IS_OK`, + * `LIBTERMINPUT_TERMINAL_IS_NOT_OK` + */ enum libterminput_type type; - struct libterminput_keypress keypress; /* use if .type == LIBTERMINPUT_KEYPRESS */ - struct libterminput_text text; /* use if .type == LIBTERMINPUT_TEXT */ - struct libterminput_mouseevent mouseevent; /* use if .type == LIBTERMINPUT_MOUSEEVENT */ - struct libterminput_position position; /* use if .type == LIBTERMINPUT_CURSOR_POSITION */ + + /** + * Use if `.type == LIBTERMINPUT_KEYPRESS` + */ + struct libterminput_keypress keypress; + + /** + * Use if `.type == LIBTERMINPUT_TEXT` + */ + struct libterminput_text text; + + /** + * Use if `.type == LIBTERMINPUT_MOUSEEVENT` + */ + struct libterminput_mouseevent mouseevent; + + /** + * Use if `.type == LIBTERMINPUT_CURSOR_POSITION` + */ + struct libterminput_position position; }; /** + * The current input state and configurations + * * This struct should be considered opaque + * + * Initialised with by setting all bytes to 0 */ struct libterminput_state { int inited; /* whether the input in initialised, not this struct */ @@ -193,11 +583,22 @@ struct libterminput_state { * @param input Output parameter for input * @param ctx State for the terminal, parts of the state may be stored in `input` * @return 1 normally, 0 on end of input, -1 on error + * + * @throws Any reason specified for read(3) */ int libterminput_read(int fd, union libterminput_input *input, struct libterminput_state *ctx); +/** + * Check if more input available that can be processed + * by `libterminput_read` without performing any additional + * read(3) operation + * + * @param input Input gathered by `libterminput_read` + * @param ctx State for the terminal + * @return 1 if there there is more input available, 0 otherwise + */ inline int -libterminput_is_ready(union libterminput_input *input, struct libterminput_state *ctx) +libterminput_is_ready(const union libterminput_input *input, const struct libterminput_state *ctx) { if (!ctx->inited || ctx->paused || ctx->mouse_tracking) return 0; @@ -206,7 +607,26 @@ libterminput_is_ready(union libterminput_input *input, struct libterminput_state return ctx->stored_head > ctx->stored_tail; } +/** + * Set a behavioural flags + * + * @param ctx Argument pasted as the last parameter to `libterminput_read` + * @param flags The OR of the flags to set + * @return 0 on success, -1 on failure + * + * The current version of this function cannot fail + */ int libterminput_set_flags(struct libterminput_state *ctx, enum libterminput_flags flags); + +/** + * Clear a behavioural flags + * + * @param ctx Argument pasted as the last parameter to `libterminput_read` + * @param flags The OR of the flags to clear + * @return 0 on success, -1 on failure + * + * The current version of this function cannot fail + */ int libterminput_clear_flags(struct libterminput_state *ctx, enum libterminput_flags flags); |