aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES6
-rw-r--r--cmd-list-clients.c12
-rw-r--r--tmux.h3
-rw-r--r--tty.c89
4 files changed, 102 insertions, 8 deletions
diff --git a/CHANGES b/CHANGES
index 500fc30d..2c85331c 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,9 @@
19 May 2009
+* Try to guess if the window is UTF-8 by outputting a three-byte UTF-8 wide
+ character and seeing how much the cursor moves. Currently tries to figure out
+ if this works by some stupid checks on the terminal, these need to be
+ rethought. Also might be better using a width 1 character rather than width 2.
* If LANG contains "UTF-8", assume the terminal supports UTF-8, on the grounds
that anyone who configures it probably wants UTF-8. Not certain if this is
a perfect idea but let's see if it causes any problems.
@@ -1278,7 +1282,7 @@
(including mutt, emacs). No status bar yet and no key remapping or other
customisation.
-$Id: CHANGES,v 1.294 2009-05-19 16:03:18 nicm Exp $
+$Id: CHANGES,v 1.295 2009-05-19 16:08:35 nicm Exp $
LocalWords: showw utf UTF fulvio ciriaco joshe OSC APC gettime abc DEF OA clr
LocalWords: rivo nurges lscm Erdely eol smysession mysession ek dstname RB ms
diff --git a/cmd-list-clients.c b/cmd-list-clients.c
index 67a0cc5b..a38f90a6 100644
--- a/cmd-list-clients.c
+++ b/cmd-list-clients.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-list-clients.c,v 1.13 2009-02-11 17:50:32 nicm Exp $ */
+/* $Id: cmd-list-clients.c,v 1.14 2009-05-19 16:08:35 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -47,14 +47,20 @@ cmd_list_clients_exec(unused struct cmd *self, struct cmd_ctx *ctx)
{
struct client *c;
u_int i;
+ const char *s_utf8;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c == NULL || c->session == NULL)
continue;
- ctx->print(ctx, "%s: %s [%ux%u %s]", c->tty.path,
- c->session->name, c->tty.sx, c->tty.sy, c->tty.termname);
+ if (c->tty.flags & TTY_UTF8)
+ s_utf8 = " (utf8)";
+ else
+ s_utf8 = "";
+ ctx->print(ctx, "%s: %s [%ux%u %s]%s", c->tty.path,
+ c->session->name, c->tty.sx, c->tty.sy,
+ c->tty.termname, s_utf8);
}
return (0);
diff --git a/tmux.h b/tmux.h
index 6e1f7ef7..e12a9e47 100644
--- a/tmux.h
+++ b/tmux.h
@@ -1,4 +1,4 @@
-/* $Id: tmux.h,v 1.324 2009-05-19 13:32:55 tcunha Exp $ */
+/* $Id: tmux.h,v 1.325 2009-05-19 16:08:35 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -1117,6 +1117,7 @@ void tty_putc(struct tty *, u_char);
void tty_init(struct tty *, char *, char *);
void tty_start_tty(struct tty *);
void tty_stop_tty(struct tty *);
+void tty_detect_utf8(struct tty *);
void tty_set_title(struct tty *, const char *);
void tty_update_mode(struct tty *, int);
void tty_draw_line(
diff --git a/tty.c b/tty.c
index 72224039..9920b4a1 100644
--- a/tty.c
+++ b/tty.c
@@ -1,4 +1,4 @@
-/* $Id: tty.c,v 1.98 2009-05-14 16:21:55 nicm Exp $ */
+/* $Id: tty.c,v 1.99 2009-05-19 16:08:35 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -136,6 +136,8 @@ tty_start_tty(struct tty *tty)
int what;
#endif
+ tty_detect_utf8(tty);
+
if (tcgetattr(tty->fd, &tty->tio) != 0)
fatal("tcgetattr failed");
memcpy(&tio, &tty->tio, sizeof tio);
@@ -197,16 +199,97 @@ tty_stop_tty(struct tty *tty)
tty_raw(tty, tty_term_string2(tty->term, TTYC_CSR, 0, ws.ws_row - 1));
tty_raw(tty, tty_term_string(tty->term, TTYC_RMACS));
tty_raw(tty, tty_term_string(tty->term, TTYC_SGR0));
- tty_raw(tty, tty_term_string(tty->term, TTYC_CLEAR));
tty_raw(tty, tty_term_string(tty->term, TTYC_RMKX));
tty_raw(tty, tty_term_string(tty->term, TTYC_RMCUP));
-
+ tty_raw(tty, tty_term_string(tty->term, TTYC_CLEAR));
+
tty_raw(tty, tty_term_string(tty->term, TTYC_CNORM));
if (tty_term_has(tty->term, TTYC_KMOUS))
tty_raw(tty, "\033[?1000l");
}
void
+tty_detect_utf8(struct tty *tty)
+{
+ struct pollfd pfd;
+ char buf[7];
+ size_t len;
+ ssize_t n;
+ int nfds;
+ struct termios tio, old_tio;
+#ifdef TIOCFLUSH
+ int what;
+#endif
+
+ if (tty->flags & TTY_UTF8)
+ return;
+
+ /*
+ * If the terminal looks reasonably likely to support this, try to
+ * write a three-byte UTF-8 wide character to the terminal, then read
+ * the cursor position.
+ *
+ * XXX This entire function is a hack.
+ */
+
+ /* Check if the terminal looks sort of vt100. */
+ if (strstr(tty_term_string(tty->term, TTYC_CLEAR), "[2J") == NULL ||
+ strstr(tty_term_string(tty->term, TTYC_CUP), "H") == NULL)
+ return;
+
+ if (tcgetattr(tty->fd, &old_tio) != 0)
+ fatal("tcgetattr failed");
+ cfmakeraw(&tio);
+ if (tcsetattr(tty->fd, TCSANOW, &tio) != 0)
+ fatal("tcsetattr failed");
+
+#ifdef TIOCFLUSH
+ what = 0;
+ if (ioctl(tty->fd, TIOCFLUSH, &what) != 0)
+ fatal("ioctl(TIOCFLUSH)");
+#endif
+
+#define UTF8_TEST_DATA "\033[H\357\277\246\033[6n"
+ if (write(tty->fd, UTF8_TEST_DATA, (sizeof UTF8_TEST_DATA) - 1) == -1)
+ fatal("write failed");
+#undef UTF8_TEST_DATA
+
+ len = 0;
+ for (;;) {
+ pfd.fd = tty->fd;
+ pfd.events = POLLIN;
+
+ nfds = poll(&pfd, 1, 500);
+ if (nfds == -1) {
+ if (errno == EAGAIN || errno == EINTR)
+ continue;
+ fatal("poll failed");
+ }
+ if (nfds == 0)
+ break;
+#ifdef HAVE_POLL
+ if (pfd.revents & (POLLERR|POLLNVAL|POLLHUP))
+ break;
+#endif
+ if (!(pfd.revents & POLLIN))
+ continue;
+
+ if ((n = read(tty->fd, buf + len, 1)) != 1)
+ break;
+ buf[++len] = '\0';
+
+ if (len == (sizeof buf) - 1) {
+ if (strcmp(buf, "\033[1;3R") == 0)
+ tty->flags |= TTY_UTF8;
+ break;
+ }
+ }
+
+ if (tcsetattr(tty->fd, TCSANOW, &old_tio) != 0)
+ fatal("tcsetattr failed");
+}
+
+void
tty_fill_acs(struct tty *tty)
{
const char *ptr;