From 0bfb13655c02c75b0e1cc864a81996e58cd5c7b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C5=99emysl=20Eric=20Janouch?= Date: Mon, 14 Sep 2020 15:38:49 +0200 Subject: [PATCH] Implement de/focus event parsing So far there is no way to set it up, I'm not sure how to go about it. --- CMakeLists.txt | 1 + LICENSE | 2 +- driver-csi.c | 30 ++++++++++++++++++++++++++++++ termo.c | 7 +++++++ termo.h | 2 ++ tests/33focus.c | 28 ++++++++++++++++++++++++++++ 6 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 tests/33focus.c diff --git a/CMakeLists.txt b/CMakeLists.txt index f60e7c8..d13c860 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -147,6 +147,7 @@ set (project_tests 30mouse 31position 32modereport + 33focus 39csi) if (BUILD_TESTING) diff --git a/LICENSE b/LICENSE index bcd79a8..25a4cdb 100644 --- a/LICENSE +++ b/LICENSE @@ -1,5 +1,5 @@ Copyright (c) 2007-2014 Paul Evans -Copyright (c) 2014 Přemysl Eric Janouch +Copyright (c) 2014-2020 Přemysl Eric Janouch Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/driver-csi.c b/driver-csi.c index 7f6b008..bb4b000 100644 --- a/driver-csi.c +++ b/driver-csi.c @@ -331,6 +331,33 @@ handle_csi_m (termo_t *tk, termo_key_t *key, int cmd, long *arg, int args) return TERMO_RES_NONE; } +// +// Handler for CSI I / CSI O focus events +// + +static termo_result_t +handle_csi_IO (termo_t *tk, termo_key_t *key, int cmd, long *arg, int args) +{ + (void) tk; + (void) arg; + (void) args; + + switch (cmd &= 0xff) + { + case 'I': + key->type = TERMO_TYPE_FOCUS; + key->code.focused = true; + return TERMO_RES_KEY; + case 'O': + key->type = TERMO_TYPE_FOCUS; + key->code.focused = false; + return TERMO_RES_KEY; + default: + return TERMO_RES_NONE; + } + return TERMO_RES_NONE; +} + termo_result_t termo_interpret_mouse (termo_t *tk, const termo_key_t *key, termo_mouse_event_t *event, int *button, int *line, int *col) @@ -671,6 +698,9 @@ register_keys (void) csi_handlers['M' - 0x20] = &handle_csi_m; csi_handlers['m' - 0x20] = &handle_csi_m; + csi_handlers['I' - 0x20] = &handle_csi_IO; + csi_handlers['O' - 0x20] = &handle_csi_IO; + csi_handlers['R' - 0x20] = &handle_csi_R; csi_handlers['y' - 0x20] = &handle_csi_y; diff --git a/termo.c b/termo.c index d72a4f5..b39fce6 100644 --- a/termo.c +++ b/termo.c @@ -156,6 +156,9 @@ print_key (termo_t *tk, termo_key_t *key) ev, button, line, col); break; } + case TERMO_TYPE_FOCUS: + fprintf (stderr, "%s\n", key->code.focused ? "Focused" : "Defocused"); + break; case TERMO_TYPE_POSITION: { int line, col; @@ -1572,6 +1575,8 @@ termo_strfkey_generic (termo_t *tk, char *buffer, size_t len, } break; } + case TERMO_TYPE_FOCUS: + l = snprintf (buffer + pos, len - pos, "Focus(%d)", key->code.focused); case TERMO_TYPE_POSITION: l = snprintf (buffer + pos, len - pos, "Position"); break; @@ -1826,6 +1831,8 @@ termo_keycmp (termo_t *tk, return cmp; break; } + case TERMO_TYPE_FOCUS: + return key1.code.focused - key2.code.focused; case TERMO_TYPE_POSITION: { int line1, col1, line2, col2; diff --git a/termo.h b/termo.h index 32eda4f..b435e9f 100644 --- a/termo.h +++ b/termo.h @@ -97,6 +97,7 @@ enum termo_type TERMO_TYPE_MOUSE, TERMO_TYPE_POSITION, TERMO_TYPE_MODEREPORT, + TERMO_TYPE_FOCUS, // add other recognised types here TERMO_TYPE_UNKNOWN_CSI = -1 @@ -159,6 +160,7 @@ struct termo_key uint32_t codepoint; // TERMO_TYPE_KEY int number; // TERMO_TYPE_FUNCTION termo_sym_t sym; // TERMO_TYPE_KEYSYM + int focused; // TERMO_TYPE_FOCUS // TERMO_TYPE_MODEREPORT // opaque, see termo_interpret_modereport() diff --git a/tests/33focus.c b/tests/33focus.c new file mode 100644 index 0000000..76f1d42 --- /dev/null +++ b/tests/33focus.c @@ -0,0 +1,28 @@ +#include "../termo.h" +#include "taplib.h" + +int +main (int argc, char *argv[]) +{ + termo_t *tk; + termo_key_t key; + + plan_tests (6); + + tk = termo_new_abstract ("vt100", NULL, 0); + + termo_push_bytes (tk, "\e[I", 3); + is_int (termo_getkey (tk, &key), TERMO_RES_KEY, + "getkey yields RES_KEY for focus in"); + is_int (key.type, TERMO_TYPE_FOCUS, "key.type for focus in"); + is_int (key.code.focused, 1, "focused indicator for focus in"); + + termo_push_bytes (tk, "\e[O", 3); + is_int (termo_getkey (tk, &key), TERMO_RES_KEY, + "getkey yields RES_KEY for focus out"); + is_int (key.type, TERMO_TYPE_FOCUS, "key.type for focus out"); + is_int (key.code.focused, 0, "focused indicator for focus out"); + + termo_destroy (tk); + return exit_status (); +}