aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2021-04-10 00:22:45 +0200
committerMattias Andrée <maandree@kth.se>2021-04-10 00:22:45 +0200
commita7be1b1dc5648999167321df657d5490caef6883 (patch)
treebbdca1f9205dc735350cbda9d16318d9b0171dd8
parentAdd libterminput_is_ready (diff)
downloadlibterminput-a7be1b1dc5648999167321df657d5490caef6883.tar.gz
libterminput-a7be1b1dc5648999167321df657d5490caef6883.tar.bz2
libterminput-a7be1b1dc5648999167321df657d5490caef6883.tar.xz
Add support for cursor position and device status reports
Signed-off-by: Mattias Andrée <maandree@kth.se>
-rw-r--r--TODO1
-rw-r--r--libterminput.c21
-rw-r--r--libterminput.h32
-rw-r--r--libterminput_read.340
-rw-r--r--libterminput_set_flags.335
5 files changed, 99 insertions, 30 deletions
diff --git a/TODO b/TODO
index 50b03d9..057febf 100644
--- a/TODO
+++ b/TODO
@@ -1,2 +1 @@
-Add cursor position report support
Add test
diff --git a/libterminput.c b/libterminput.c
index 147e756..5d6f401 100644
--- a/libterminput.c
+++ b/libterminput.c
@@ -398,9 +398,15 @@ parse_sequence(union libterminput_input *input, struct libterminput_state *ctx)
}
break;
case 'P':
- input->keypress.key = LIBTERMINPUT_F1;
- if (ctx->flags & LIBTERMINPUT_PAUSE_ON_CSI_P)
- input->keypress.key = LIBTERMINPUT_PAUSE;
+ if ((ctx->flags & LIBTERMINPUT_AWAITING_CURSOR_POSITION) && nnums == 2) {
+ input->position.type = LIBTERMINPUT_CURSOR_POSITION;
+ input->position.y = (size_t)nums[0] + (size_t)!nums[0];
+ input->position.x = (size_t)nums[1] + (size_t)!nums[1];
+ } else {
+ input->keypress.key = LIBTERMINPUT_F1;
+ if (ctx->flags & LIBTERMINPUT_PAUSE_ON_CSI_P)
+ input->keypress.key = LIBTERMINPUT_PAUSE;
+ }
break;
case 'Q': input->keypress.key = LIBTERMINPUT_F2; break;
case 'R': input->keypress.key = LIBTERMINPUT_F3; break;
@@ -460,6 +466,15 @@ parse_sequence(union libterminput_input *input, struct libterminput_state *ctx)
input->keypress.key = LIBTERMINPUT_LEFT;
input->keypress.mods |= LIBTERMINPUT_SHIFT;
break;
+ case 'n':
+ if (nnums == 1 && nums[0] == '0') {
+ input->type = LIBTERMINPUT_TERMINAL_IS_OK;
+ } else if (nnums == 1 && nums[0] == '3') {
+ input->type = LIBTERMINPUT_TERMINAL_IS_NOT_OK;
+ } else {
+ goto suppress;
+ }
+ break;
case 't':
/* Parsing output for legacy mouse highlight tracking output (\e[?1001h). */
ctx->mouse_tracking = 0;
diff --git a/libterminput.h b/libterminput.h
index 0182a54..95eea11 100644
--- a/libterminput.h
+++ b/libterminput.h
@@ -12,11 +12,11 @@
* terminal support this flag if set.
*/
enum libterminput_flags {
- LIBTERMINPUT_DECSET_1005 = 0x0001,
- LIBTERMINPUT_MACRO_ON_CSI_M = 0x0002,
- LIBTERMINPUT_PAUSE_ON_CSI_P = 0x0004,
- LIBTERMINPUT_INS_ON_CSI_AT = 0x0008,
- LIBTERMINPUT_SEPARATE_BACKTAB = 0x0010,
+ LIBTERMINPUT_DECSET_1005 = 0x0001,
+ LIBTERMINPUT_MACRO_ON_CSI_M = 0x0002,
+ LIBTERMINPUT_PAUSE_ON_CSI_P = 0x0004,
+ LIBTERMINPUT_INS_ON_CSI_AT = 0x0008,
+ LIBTERMINPUT_SEPARATE_BACKTAB = 0x0010,
/**
* If an ESC is received without anything after it,
@@ -25,7 +25,9 @@ enum libterminput_flags {
* simulate a keypress that terminal does not support
* (yes, this is a real world issue).
*/
- LIBTERMINPUT_ESC_ON_BLOCK = 0x0020
+ LIBTERMINPUT_ESC_ON_BLOCK = 0x0020,
+
+ LIBTERMINPUT_AWAITING_CURSOR_POSITION = 0x0040
};
enum libterminput_mod {
@@ -107,7 +109,10 @@ enum libterminput_type {
LIBTERMINPUT_BRACKETED_PASTE_START,
LIBTERMINPUT_BRACKETED_PASTE_END,
LIBTERMINPUT_TEXT,
- LIBTERMINPUT_MOUSEEVENT
+ LIBTERMINPUT_MOUSEEVENT,
+ LIBTERMINPUT_TERMINAL_IS_OK, /* response to CSI 5 n */
+ LIBTERMINPUT_TERMINAL_IS_NOT_OK, /* response to CSI 5 n */
+ LIBTERMINPUT_CURSOR_POSITION /* response to CSI 6 n */
};
enum libterminput_event {
@@ -126,6 +131,12 @@ struct libterminput_keypress {
char symbol[7]; /* use if .key == LIBTERMINPUT_SYMBOL */
};
+struct libterminput_text {
+ enum libterminput_type type;
+ size_t nbytes;
+ char bytes[512];
+};
+
struct libterminput_mouseevent {
enum libterminput_type type;
enum libterminput_mod mods; /* Set to 0 for LIBTERMINPUT_HIGHLIGHT_INSIDE and LIBTERMINPUT_HIGHLIGHT_OUTSIDE */
@@ -139,10 +150,10 @@ struct libterminput_mouseevent {
size_t end_y; /* Only set for LIBTERMINPUT_HIGHLIGHT_OUTSIDE */
};
-struct libterminput_text {
+struct libterminput_position {
enum libterminput_type type;
- size_t nbytes;
- char bytes[512];
+ size_t x;
+ size_t y;
};
union libterminput_input {
@@ -150,6 +161,7 @@ union libterminput_input {
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 */
};
diff --git a/libterminput_read.3 b/libterminput_read.3
index 2cf401b..09f0212 100644
--- a/libterminput_read.3
+++ b/libterminput_read.3
@@ -85,7 +85,10 @@ enum libterminput_type {
LIBTERMINPUT_BRACKETED_PASTE_START,
LIBTERMINPUT_BRACKETED_PASTE_END,
LIBTERMINPUT_TEXT,
- LIBTERMINPUT_MOUSEEVENT
+ LIBTERMINPUT_MOUSEEVENT,
+ LIBTERMINPUT_TERMINAL_IS_OK,
+ LIBTERMINPUT_TERMINAL_IS_NOT_OK,
+ LIBTERMINPUT_CURSOR_POSITION
};
enum libterminput_event {
@@ -104,6 +107,12 @@ struct libterminput_keypress {
char symbol[7];
};
+struct libterminput_text {
+ enum libterminput_type type;
+ size_t nbytes;
+ char bytes[512];
+};
+
struct libterminput_mouseevent {
enum libterminput_type type;
enum libterminput_mod mods;
@@ -117,10 +126,10 @@ struct libterminput_mouseevent {
size_t end_y;
};
-struct libterminput_text {
+struct libterminput_position {
enum libterminput_type type;
- size_t nbytes;
- char bytes[512];
+ size_t x;
+ size_t y;
};
union libterminput_input {
@@ -393,6 +402,29 @@ and
will also be set to indicate the region selected by
the application.
.RE
+.TP
+.B LIBTERMINPUT_TERMINAL_IS_OK
+OK response for a device status query.
+.TP
+.B LIBTERMINPUT_TERMINAL_IS_NOT_OK
+Not-OK response for a device status query.
+.TP
+.B LIBTERMINPUT_CURSOR_POSITION
+Cursor position report even as a response to a
+cursor position query. The line (indexed starting
+with 1 at the top) the cursor is on will be
+stored in
+.I input->position.y
+and the column (indexed starting with 1 at the
+left edge) will be stored in
+.I input->position.x
+
+This event can conflict with both F1 and pause
+key processes, therefore the
+.B LIBTERMINPUT_AWAITING_CURSOR_POSITION
+flag must be set with the
+.BR libterminput_set_flags (3)
+function.
.SH RETURN VALUE
The
.BR libterminput_read ()
diff --git a/libterminput_set_flags.3 b/libterminput_set_flags.3
index 6b79998..4560971 100644
--- a/libterminput_set_flags.3
+++ b/libterminput_set_flags.3
@@ -34,15 +34,17 @@ The available flags are
.B LIBTERMINPUT_DECSET_1005
The sequence
.B 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.
+shall be parsed be parse as a
+.I DECSET 1005
+sequence which is incompatible with legacy mouse
+tracking. This flag shall only be set if
+.I DECSET 1005
+has sent to the terminal and the user is sure it
+is supported by the terminal.
.TP
.B LIBTERMINPUT_MACRO_ON_CSI_M
The sequence
-.B CSI Pm M
+.BI "CSI " Pm " M"
shall be parsed as a key press of the macro key.
This is incompatible with all mouse tracking modes
except
@@ -54,13 +56,13 @@ and therefore uses it, can safely use this flag.
.TP
.B LIBTERMINPUT_PAUSE_ON_CSI_P
The sequence
-.B CSI Pm M
+.BI "CSI " Pm " M"
shall be parsed as a key press of the pause key
instead of the F1 key.
.TP
.B LIBTERMINPUT_INS_ON_CSI_AT
The sequence
-.B CSI Pm @
+.BI "CSI " Pm " @"
shall be parsed as a key press of the insert key
instead of a number of possible special keys
combined with the control and shift modifiers.
@@ -75,11 +77,20 @@ a forward arrow (tab); but most users are unfamiliar
with backtab, and just see it as shift+tab.
.TP
.B LIBTERMINPUT_ESC_ON_BLOCK
-If an ESC is received without anything after it,
-it shall be parsed as an ESC keypress. This is not
+If an ESC is received without anything after it, it
+shall be parsed as an escape keypress. This is not
always desirable behaviour as the user may manually
-press ESC to simulate a keypress that terminal does
-not support (yes, this is a real world issue).
+press escape to simulate a keypress that terminal
+does not support (yes, this is a real world issue).
+.TP
+.B LIBTERMINPUT_AWAITING_CURSOR_POSITION
+The sequence
+.BI "CSI " Ps " ; " Rs " R"
+shall be parsed as a cursor position report rather
+than as an F1 or pause key press. This flag takes
+precedence over the
+.B LIBTERMINPUT_PAUSE_ON_CSI_P
+flag.
.PP
.I ctx
must have been zero-initialised, e.g. with