summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas Marriott <nicm@cvs.openbsd.org>2024-07-12 11:21:19 +0000
committerNicholas Marriott <nicm@cvs.openbsd.org>2024-07-12 11:21:19 +0000
commit895b8704d8966bc57e0253fa7fc5a22e1c8ab0f0 (patch)
tree4d2501f93271dbb49a86ff801a421397f00ab6e0
parent72ffdf9e883dfdde30796f49011351df1c90cc5d (diff)
UTF-8 keys now contain the internal representation and not the Unicode
codepoint, so convert extended keys properly. From Stanislav Kljuhhin.
-rw-r--r--usr.bin/tmux/tmux.h3
-rw-r--r--usr.bin/tmux/tty-keys.c13
-rw-r--r--usr.bin/tmux/utf8.c24
3 files changed, 37 insertions, 3 deletions
diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h
index fa84e9f6bfe..cc6c014b5a7 100644
--- a/usr.bin/tmux/tmux.h
+++ b/usr.bin/tmux/tmux.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tmux.h,v 1.1218 2024/06/24 08:30:50 nicm Exp $ */
+/* $OpenBSD: tmux.h,v 1.1219 2024/07/12 11:21:18 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -3267,6 +3267,7 @@ void session_renumber_windows(struct session *);
/* utf8.c */
enum utf8_state utf8_towc (const struct utf8_data *, wchar_t *);
+enum utf8_state utf8_fromwc(wchar_t wc, struct utf8_data *);
int utf8_in_table(wchar_t, const wchar_t *, u_int);
utf8_char utf8_build_one(u_char);
enum utf8_state utf8_from_data(const struct utf8_data *, utf8_char *);
diff --git a/usr.bin/tmux/tty-keys.c b/usr.bin/tmux/tty-keys.c
index 5027876bb3b..9b0a1d12096 100644
--- a/usr.bin/tmux/tty-keys.c
+++ b/usr.bin/tmux/tty-keys.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tty-keys.c,v 1.174 2024/06/24 08:30:50 nicm Exp $ */
+/* $OpenBSD: tty-keys.c,v 1.175 2024/07/12 11:21:18 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -911,6 +911,8 @@ tty_keys_extended_key(struct tty *tty, const char *buf, size_t len,
cc_t bspace;
key_code nkey;
key_code onlykey;
+ struct utf8_data ud;
+ utf8_char uc;
*size = 0;
@@ -960,6 +962,15 @@ tty_keys_extended_key(struct tty *tty, const char *buf, size_t len,
else
nkey = number;
+ /* Convert UTF-32 codepoint into internal representation. */
+ if (nkey & ~0x7f) {
+ if (utf8_fromwc(nkey, &ud) == UTF8_DONE &&
+ utf8_from_data(&ud, &uc) == UTF8_DONE)
+ nkey = uc;
+ else
+ return (-1);
+ }
+
/* Update the modifiers. */
if (modifiers > 0) {
modifiers--;
diff --git a/usr.bin/tmux/utf8.c b/usr.bin/tmux/utf8.c
index c5b775a53de..e6ad3440729 100644
--- a/usr.bin/tmux/utf8.c
+++ b/usr.bin/tmux/utf8.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: utf8.c,v 1.65 2024/05/24 12:41:24 nicm Exp $ */
+/* $OpenBSD: utf8.c,v 1.66 2024/07/12 11:21:18 nicm Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -441,6 +441,28 @@ utf8_towc(const struct utf8_data *ud, wchar_t *wc)
return (UTF8_DONE);
}
+/* Convert wide character to UTF-8 character. */
+enum utf8_state
+utf8_fromwc(wchar_t wc, struct utf8_data *ud)
+{
+ int size, width;
+
+ size = wctomb(ud->data, wc);
+ if (size < 0) {
+ log_debug("UTF-8 %d, wctomb() %d", wc, errno);
+ wctomb(NULL, 0);
+ return (UTF8_ERROR);
+ }
+ if (size == 0)
+ return (UTF8_ERROR);
+ ud->size = ud->have = size;
+ if (utf8_width(ud, &width) == UTF8_DONE) {
+ ud->width = width;
+ return (UTF8_DONE);
+ }
+ return (UTF8_ERROR);
+}
+
/*
* Open UTF-8 sequence.
*