summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicholas Marriott <nicm@openbsd.org>2013-01-18 02:16:21 +0000
committerNicholas Marriott <nicm@openbsd.org>2013-01-18 02:16:21 +0000
commitfdbfc7e3498e1cdd04e8df58aa1a937ee4d79caa (patch)
tree48c27a2125d75ac9c1ad6f21a089ae0642bb7bcc
parentc2e2107063f85c65c0153cb3f201c12e93599038 (diff)
Rather than having two grids for each pane, one for ASCII and one for
UTF-8, collapse the two together. Simplifies the code at the expense of more memory (which can probably be reduced again later).
-rw-r--r--Makefile2
-rw-r--r--cmd-server-info.c32
-rw-r--r--format.c1
-rw-r--r--grid-cell.c55
-rw-r--r--grid-utf8.c96
-rw-r--r--grid-view.c24
-rw-r--r--grid.c103
-rw-r--r--input.c9
-rw-r--r--screen-write.c108
-rw-r--r--tmux.h49
-rw-r--r--tty.c68
-rw-r--r--window-copy.c83
12 files changed, 192 insertions, 438 deletions
diff --git a/Makefile b/Makefile
index 7333f0f1..cebcac8e 100644
--- a/Makefile
+++ b/Makefile
@@ -85,7 +85,7 @@ SRCS= arguments.c \
control-notify.c \
environ.c \
format.c \
- grid-utf8.c \
+ grid-cell.c \
grid-view.c \
grid.c \
input-keys.c \
diff --git a/cmd-server-info.c b/cmd-server-info.c
index 0d09626a..f434f942 100644
--- a/cmd-server-info.c
+++ b/cmd-server-info.c
@@ -59,12 +59,11 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
struct job *job;
struct grid *gd;
struct grid_line *gl;
- u_int i, j, k;
+ u_int i, j, k, lines;
+ size_t size;
char out[80];
char *tim;
time_t t;
- u_int lines, ulines;
- size_t size, usize;
tim = ctime(&start_time);
*strchr(tim, '\n') = '\0';
@@ -97,8 +96,7 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
}
ctx->print(ctx, "%s", "");
- ctx->print(ctx, "Sessions: [%zu/%zu]",
- sizeof (struct grid_cell), sizeof (struct grid_utf8));
+ ctx->print(ctx, "Sessions: [%zu]", sizeof (struct grid_cell));
RB_FOREACH(s, sessions, &sessions) {
t = s->creation_time.tv_sec;
tim = ctime(&t);
@@ -115,26 +113,20 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
w->lastlayout);
j = 0;
TAILQ_FOREACH(wp, &w->panes, entry) {
- lines = ulines = size = usize = 0;
+ lines = size = 0;
gd = wp->base.grid;
for (k = 0; k < gd->hsize + gd->sy; k++) {
gl = &gd->linedata[k];
- if (gl->celldata != NULL) {
- lines++;
- size += gl->cellsize *
- sizeof *gl->celldata;
- }
- if (gl->utf8data != NULL) {
- ulines++;
- usize += gl->utf8size *
- sizeof *gl->utf8data;
- }
+ if (gl->celldata == NULL)
+ continue;
+ lines++;
+ size += gl->cellsize *
+ sizeof *gl->celldata;
}
- ctx->print(ctx, "%6u: %s %lu %d %u/%u, %zu "
- "bytes; UTF-8 %u/%u, %zu bytes", j,
+ ctx->print(ctx,
+ "%6u: %s %lu %d %u/%u, %zu bytes", j,
wp->tty, (u_long) wp->pid, wp->fd, lines,
- gd->hsize + gd->sy, size, ulines,
- gd->hsize + gd->sy, usize);
+ gd->hsize + gd->sy, size);
j++;
}
}
diff --git a/format.c b/format.c
index 0eeb622d..72c65c28 100644
--- a/format.c
+++ b/format.c
@@ -370,7 +370,6 @@ format_window_pane(struct format_tree *ft, struct window_pane *wp)
for (i = 0; i < gd->hsize; i++) {
gl = &gd->linedata[i];
size += gl->cellsize * sizeof *gl->celldata;
- size += gl->utf8size * sizeof *gl->utf8data;
}
size += gd->hsize * sizeof *gd->linedata;
diff --git a/grid-cell.c b/grid-cell.c
new file mode 100644
index 00000000..09643a9c
--- /dev/null
+++ b/grid-cell.c
@@ -0,0 +1,55 @@
+/* $OpenBSD$ */
+
+/*
+ * Copyright (c) 2012 Nicholas Marriott <nicm@users.sourceforge.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+
+#include <string.h>
+
+#include "tmux.h"
+
+/* Get cell width. */
+u_int
+grid_cell_width(const struct grid_cell *gc)
+{
+ return (gc->xstate >> 4);
+}
+
+/* Get cell data. */
+void
+grid_cell_get(const struct grid_cell *gc, struct utf8_data *ud)
+{
+ ud->size = gc->xstate & 0xf;
+ ud->width = gc->xstate >> 4;
+ memcpy(ud->data, gc->xdata, ud->size);
+}
+
+/* Set cell data. */
+void
+grid_cell_set(struct grid_cell *gc, const struct utf8_data *ud)
+{
+ memcpy(gc->xdata, ud->data, ud->size);
+ gc->xstate = (ud->width << 4) | ud->size;
+}
+
+/* Set a single character as cell data. */
+void
+grid_cell_one(struct grid_cell *gc, u_char ch)
+{
+ *gc->xdata = ch;
+ gc->xstate = (1 << 4) | 1;
+}
diff --git a/grid-utf8.c b/grid-utf8.c
deleted file mode 100644
index 0c829711..00000000
--- a/grid-utf8.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/* $OpenBSD$ */
-
-/*
- * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
- * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
- * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/types.h>
-
-#include <string.h>
-
-#include "tmux.h"
-
-/*
- * Grid UTF-8 utility functions.
- */
-
-/* Calculate UTF-8 grid cell size. Data is terminated by 0xff. */
-size_t
-grid_utf8_size(const struct grid_utf8 *gu)
-{
- size_t size;
-
- for (size = 0; size < sizeof gu->data; size++) {
- if (gu->data[size] == 0xff)
- break;
- }
- return (size);
-}
-
-/* Copy UTF-8 out into a buffer. */
-size_t
-grid_utf8_copy(const struct grid_utf8 *gu, char *buf, size_t len)
-{
- size_t size;
-
- size = grid_utf8_size(gu);
- if (size > len)
- fatalx("UTF-8 copy overflow");
- memcpy(buf, gu->data, size);
- return (size);
-}
-
-/* Set UTF-8 grid data from input UTF-8. */
-void
-grid_utf8_set(struct grid_utf8 *gu, const struct utf8_data *utf8data)
-{
- if (utf8data->size == 0)
- fatalx("UTF-8 data empty");
- if (utf8data->size > sizeof gu->data)
- fatalx("UTF-8 data too long");
- memcpy(gu->data, utf8data->data, utf8data->size);
- if (utf8data->size != sizeof gu->data)
- gu->data[utf8data->size] = 0xff;
- gu->width = utf8data->width;
-}
-
-/* Append UTF-8 character onto the cell data (for combined characters). */
-int
-grid_utf8_append(struct grid_utf8 *gu, const struct utf8_data *utf8data)
-{
- size_t old_size;
-
- old_size = grid_utf8_size(gu);
- if (old_size + utf8data->size > sizeof gu->data)
- return (-1);
- memcpy(gu->data + old_size, utf8data->data, utf8data->size);
- if (old_size + utf8data->size != sizeof gu->data)
- gu->data[old_size + utf8data->size] = 0xff;
- return (0);
-}
-
-/* Compare two UTF-8 cells. */
-int
-grid_utf8_compare(const struct grid_utf8 *gu1, const struct grid_utf8 *gu2)
-{
- size_t size;
-
- size = grid_utf8_size(gu1);
- if (size != grid_utf8_size(gu2))
- return (0);
- if (memcmp(gu1->data, gu2->data, size) != 0)
- return (0);
- return (1);
-}
diff --git a/grid-view.c b/grid-view.c
index e36144f0..bde624cc 100644
--- a/grid-view.c
+++ b/grid-view.c
@@ -52,28 +52,6 @@ grid_view_set_cell(
grid_set_cell(gd, grid_view_x(gd, px), grid_view_y(gd, py), gc);
}
-/* Get UTF-8 for reading. */
-const struct grid_utf8 *
-grid_view_peek_utf8(struct grid *gd, u_int px, u_int py)
-{
- return (grid_peek_utf8(gd, grid_view_x(gd, px), grid_view_y(gd, py)));
-}
-
-/* Get UTF-8 for writing. */
-struct grid_utf8 *
-grid_view_get_utf8(struct grid *gd, u_int px, u_int py)
-{
- return (grid_get_utf8(gd, grid_view_x(gd, px), grid_view_y(gd, py)));
-}
-
-/* Set UTF-8. */
-void
-grid_view_set_utf8(
- struct grid *gd, u_int px, u_int py, const struct grid_utf8 *gu)
-{
- grid_set_utf8(gd, grid_view_x(gd, px), grid_view_y(gd, py), gu);
-}
-
/* Clear into history. */
void
grid_view_clear_history(struct grid *gd)
@@ -87,7 +65,7 @@ grid_view_clear_history(struct grid *gd)
last = 0;
for (yy = 0; yy < gd->sy; yy++) {
gl = &gd->linedata[grid_view_y(gd, yy)];
- if (gl->cellsize != 0 || gl->utf8size != 0)
+ if (gl->cellsize != 0)
last = yy + 1;
}
if (last == 0)
diff --git a/grid.c b/grid.c
index 91ec7856..da769122 100644
--- a/grid.c
+++ b/grid.c
@@ -36,8 +36,8 @@
*/
/* Default grid cell data. */
-const struct grid_cell grid_default_cell = { 0, 0, 8, 8, ' ' };
-const struct grid_cell grid_marker_cell = { 0, 0, 8, 8, '_' };
+const struct grid_cell grid_default_cell = { 0, 0, 8, 8, (1 << 4) | 1, " " };
+const struct grid_cell grid_marker_cell = { 0, 0, 8, 8, (1 << 4) | 1, "_" };
#define grid_put_cell(gd, px, py, gc) do { \
memcpy(&gd->linedata[py].celldata[px], \
@@ -100,7 +100,6 @@ grid_destroy(struct grid *gd)
for (yy = 0; yy < gd->hsize + gd->sy; yy++) {
gl = &gd->linedata[yy];
free(gl->celldata);
- free(gl->utf8data);
}
free(gd->linedata);
@@ -114,7 +113,6 @@ grid_compare(struct grid *ga, struct grid *gb)
{
struct grid_line *gla, *glb;
struct grid_cell *gca, *gcb;
- struct grid_utf8 *gua, *gub;
u_int xx, yy;
if (ga->sx != gb->sx || ga->sy != ga->sy)
@@ -130,12 +128,6 @@ grid_compare(struct grid *ga, struct grid *gb)
gcb = &glb->celldata[xx];
if (memcmp(gca, gcb, sizeof (struct grid_cell)) != 0)
return (1);
- if (!(gca->flags & GRID_FLAG_UTF8))
- continue;
- gua = &gla->utf8data[xx];
- gub = &glb->utf8data[xx];
- if (memcmp(gua, gub, sizeof (struct grid_utf8)) != 0)
- return (1);
}
}
@@ -233,20 +225,6 @@ grid_expand_line(struct grid *gd, u_int py, u_int sx)
gl->cellsize = sx;
}
-/* Expand line to fit to cell for UTF-8. */
-void
-grid_expand_line_utf8(struct grid *gd, u_int py, u_int sx)
-{
- struct grid_line *gl;
-
- gl = &gd->linedata[py];
- if (sx <= gl->utf8size)
- return;
-
- gl->utf8data = xrealloc(gl->utf8data, sx, sizeof *gl->utf8data);
- gl->utf8size = sx;
-}
-
/* Get cell for reading. */
const struct grid_cell *
grid_peek_cell(struct grid *gd, u_int px, u_int py)
@@ -282,41 +260,6 @@ grid_set_cell(
grid_put_cell(gd, px, py, gc);
}
-/* Get UTF-8 for reading. */
-const struct grid_utf8 *
-grid_peek_utf8(struct grid *gd, u_int px, u_int py)
-{
- if (grid_check_y(gd, py) != 0)
- return (NULL);
-
- if (px >= gd->linedata[py].utf8size)
- return (NULL);
- return (&gd->linedata[py].utf8data[px]);
-}
-
-/* Get utf8 at relative position (for writing). */
-struct grid_utf8 *
-grid_get_utf8(struct grid *gd, u_int px, u_int py)
-{
- if (grid_check_y(gd, py) != 0)
- return (NULL);
-
- grid_expand_line_utf8(gd, py, px + 1);
- return (&gd->linedata[py].utf8data[px]);
-}
-
-/* Set utf8 at relative position. */
-void
-grid_set_utf8(
- struct grid *gd, u_int px, u_int py, const struct grid_utf8 *gc)
-{
- if (grid_check_y(gd, py) != 0)
- return;
-
- grid_expand_line_utf8(gd, py, px + 1);
- grid_put_utf8(gd, px, py, gc);
-}
-
/* Clear area. */
void
grid_clear(struct grid *gd, u_int px, u_int py, u_int nx, u_int ny)
@@ -373,7 +316,6 @@ grid_clear_lines(struct grid *gd, u_int py, u_int ny)
for (yy = py; yy < py + ny; yy++) {
gl = &gd->linedata[yy];
free(gl->celldata);
- free(gl->utf8data);
memset(gl, 0, sizeof *gl);
}
}
@@ -437,13 +379,6 @@ grid_move_cells(struct grid *gd, u_int dx, u_int px, u_int py, u_int nx)
memmove(
&gl->celldata[dx], &gl->celldata[px], nx * sizeof *gl->celldata);
- if (gl->utf8data != NULL) {
- grid_expand_line_utf8(gd, py, px + nx);
- grid_expand_line_utf8(gd, py, dx + nx);
- memmove(&gl->utf8data[dx],
- &gl->utf8data[px], nx * sizeof *gl->utf8data);
- }
-
/* Wipe any cells that have been moved. */
for (xx = px; xx < px + nx; xx++) {
if (xx >= dx && xx < dx + nx)
@@ -457,9 +392,9 @@ char *
grid_string_cells(struct grid *gd, u_int px, u_int py, u_int nx)
{
const struct grid_cell *gc;
- const struct grid_utf8 *gu;
+ struct utf8_data ud;
char *buf;
- size_t len, off, size;
+ size_t len, off;
u_int xx;
GRID_DEBUG(gd, "px=%u, py=%u, nx=%u", px, py, nx);
@@ -472,25 +407,15 @@ grid_string_cells(struct grid *gd, u_int px, u_int py, u_int nx)
gc = grid_peek_cell(gd, xx, py);
if (gc->flags & GRID_FLAG_PADDING)
continue;
+ grid_cell_get(gc, &ud);
- if (gc->flags & GRID_FLAG_UTF8) {
- gu = grid_peek_utf8(gd, xx, py);
-
- size = grid_utf8_size(gu);
- while (len < off + size + 1) {
- buf = xrealloc(buf, 2, len);
- len *= 2;
- }
-
- off += grid_utf8_copy(gu, buf + off, len - off);
- } else {
- while (len < off + 2) {
- buf = xrealloc(buf, 2, len);
- len *= 2;
- }
-
- buf[off++] = gc->data;
+ while (len < off + ud.size + 1) {
+ buf = xrealloc(buf, 2, len);
+ len *= 2;
}
+
+ memcpy(buf + off, ud.data, ud.size);
+ off += ud.size;
}
while (off > 0 && buf[off - 1] == ' ')
@@ -530,12 +455,6 @@ grid_duplicate_lines(
memcpy(dstl->celldata, srcl->celldata,
srcl->cellsize * sizeof *dstl->celldata);
}
- if (srcl->utf8size != 0) {
- dstl->utf8data = xcalloc(
- srcl->utf8size, sizeof *dstl->utf8data);
- memcpy(dstl->utf8data, srcl->utf8data,
- srcl->utf8size * sizeof *dstl->utf8data);
- }
sy++;
dy++;
diff --git a/input.c b/input.c
index e04ddc4f..20917fa1 100644
--- a/input.c
+++ b/input.c
@@ -879,8 +879,8 @@ input_clear(struct input_ctx *ictx)
int
input_print(struct input_ctx *ictx)
{
- ictx->cell.data = ictx->ch;
- screen_write_cell(&ictx->ctx, &ictx->cell, NULL);
+ grid_cell_one(&ictx->cell, ictx->ch);
+ screen_write_cell(&ictx->ctx, &ictx->cell);
return (0);
}
@@ -1657,9 +1657,8 @@ input_utf8_close(struct input_ctx *ictx)
utf8_append(&ictx->utf8data, ictx->ch);
- ictx->cell.flags |= GRID_FLAG_UTF8;
- screen_write_cell(&ictx->ctx, &ictx->cell, &ictx->utf8data);
- ictx->cell.flags &= ~GRID_FLAG_UTF8;
+ grid_cell_set(&ictx->cell, &ictx->utf8data);
+ screen_write_cell(&ictx->ctx, &ictx->cell);
return (0);
}
diff --git a/screen-write.c b/screen-write.c
index 4d147b5b..e68e498d 100644
--- a/screen-write.c
+++ b/screen-write.c
@@ -67,11 +67,10 @@ screen_write_reset(struct screen_write_ctx *ctx)
/* Write character. */
void
-screen_write_putc(
- struct screen_write_ctx *ctx, struct grid_cell *gc, u_char ch)
+screen_write_putc(struct screen_write_ctx *ctx, struct grid_cell *gc, u_char ch)
{
- gc->data = ch;
- screen_write_cell(ctx, gc, NULL);
+ grid_cell_one(gc, ch);
+ screen_write_cell(ctx, gc);
}
/* Calculate string length, with embedded formatting. */
@@ -203,9 +202,8 @@ screen_write_vnputs(struct screen_write_ctx *ctx, ssize_t maxlen,
}
size += utf8data.width;
- gc->flags |= GRID_FLAG_UTF8;
- screen_write_cell(ctx, gc, &utf8data);
- gc->flags &= ~GRID_FLAG_UTF8;
+ grid_cell_set(gc, &utf8data);
+ screen_write_cell(ctx, gc);
} else {
if (maxlen > 0 && size + 1 > (size_t) maxlen)
break;
@@ -277,9 +275,8 @@ screen_write_cnputs(struct screen_write_ctx *ctx,
}
size += utf8data.width;
- lgc.flags |= GRID_FLAG_UTF8;
- screen_write_cell(ctx, &lgc, &utf8data);
- lgc.flags &= ~GRID_FLAG_UTF8;
+ grid_cell_set(&lgc, &utf8data);
+ screen_write_cell(ctx, &lgc);
} else {
if (maxlen > 0 && size + 1 > (size_t) maxlen)
break;
@@ -385,8 +382,7 @@ screen_write_copy(struct screen_write_ctx *ctx,
struct grid *gd = src->grid;
struct grid_line *gl;
const struct grid_cell *gc;
- const struct grid_utf8 *gu;
- struct utf8_data utf8data;
+ struct utf8_data ud;
u_int xx, yy, cx, cy, ax, bx;
cx = s->cx;
@@ -414,16 +410,8 @@ screen_write_copy(struct screen_write_ctx *ctx,
gc = &grid_default_cell;
else
gc = &gl->celldata[xx];
- if (!(gc->flags & GRID_FLAG_UTF8)) {
- screen_write_cell(ctx, gc, NULL);
- continue;
- }
- /* Reinject the UTF-8 sequence. */
- gu = &gl->utf8data[xx];
- utf8data.size = grid_utf8_copy(
- gu, utf8data.data, sizeof utf8data.data);
- utf8data.width = gu->width;
- screen_write_cell(ctx, gc, &utf8data);
+ grid_cell_get(gc, &ud);
+ screen_write_cell(ctx, gc);
}
if (px + nx == gd->sx && px + nx > gl->cellsize)
screen_write_clearendofline(ctx);
@@ -442,7 +430,6 @@ screen_write_initctx(
struct screen *s = ctx->s;
struct grid *gd = s->grid;
const struct grid_cell *gc;
- const struct grid_utf8 *gu;
u_int xx;
ttyctx->wp = ctx->wp;
@@ -465,10 +452,6 @@ screen_write_initctx(
}
ttyctx->last_width = xx;
memcpy(&ttyctx->last_cell, gc, sizeof ttyctx->last_cell);
- if (gc->flags & GRID_FLAG_UTF8) {
- gu = grid_view_peek_utf8(gd, screen_size_x(s) - xx, s->cy);
- memcpy(&ttyctx->last_utf8, gu, sizeof ttyctx->last_utf8);
- }
}
/* Cursor up by ny. */
@@ -584,7 +567,7 @@ screen_write_alignmenttest(struct screen_write_ctx *ctx)
screen_write_initctx(ctx, &ttyctx, 0);
memcpy(&gc, &grid_default_cell, sizeof gc);
- gc.data = 'E';
+ grid_cell_one(&gc, 'E');
for (yy = 0; yy < screen_size_y(s); yy++) {
for (xx = 0; xx < screen_size_x(s); xx++)
@@ -1066,26 +1049,20 @@ screen_write_clearhistory(struct screen_write_ctx *ctx)
/* Write cell data. */
void
-screen_write_cell(struct screen_write_ctx *ctx,
- const struct grid_cell *gc, const struct utf8_data *utf8data)
+screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
{
struct screen *s = ctx->s;
struct grid *gd = s->grid;
struct tty_ctx ttyctx;
- struct grid_utf8 gu;
u_int width, xx;
struct grid_cell tmp_gc, *tmp_gcp;
+ struct utf8_data ud;
int insert = 0;
/* Ignore padding. */
if (gc->flags & GRID_FLAG_PADDING)
return;
-
- /* Find character width. */
- if (gc->flags & GRID_FLAG_UTF8)
- width = utf8data->width;
- else
- width = 1;
+ width = grid_cell_width(gc);
/*
* If this is a wide character and there is no room on the screen, for
@@ -1102,7 +1079,8 @@ screen_write_cell(struct screen_write_ctx *ctx,
* there is space.
*/
if (width == 0) {
- if (screen_write_combine(ctx, utf8data) == 0) {
+ grid_cell_get(gc, &ud);
+ if (screen_write_combine(ctx, &ud) == 0) {
screen_write_initctx(ctx, &ttyctx, 0);
tty_write(tty_cmd_utf8character, &ttyctx);
}
@@ -1145,11 +1123,6 @@ screen_write_cell(struct screen_write_ctx *ctx,
/* Set the cell. */
grid_view_set_cell(gd, s->cx, s->cy, gc);
- if (gc->flags & GRID_FLAG_UTF8) {
- /* Construct UTF-8 and write it. */
- grid_utf8_set(&gu, utf8data);
- grid_view_set_utf8(gd, s->cx, s->cy, &gu);
- }
/* Move the cursor. */
s->cx += width;
@@ -1159,12 +1132,11 @@ screen_write_cell(struct screen_write_ctx *ctx,
ttyctx.num = width;
tty_write(tty_cmd_insertcharacter, &ttyctx);
}
- ttyctx.utf8 = &gu;
if (screen_check_selection(s, s->cx - width, s->cy)) {
memcpy(&tmp_gc, &s->sel.cell, sizeof tmp_gc);
- tmp_gc.data = gc->data;
- tmp_gc.flags = gc->flags &
- ~(GRID_FLAG_FG256|GRID_FLAG_BG256);
+ grid_cell_get(gc, &ud);
+ grid_cell_set(&tmp_gc, &ud);
+ tmp_gc.flags = gc->flags & ~(GRID_FLAG_FG256|GRID_FLAG_BG256);
tmp_gc.flags |= s->sel.cell.flags &
(GRID_FLAG_FG256|GRID_FLAG_BG256);
ttyctx.cell = &tmp_gc;
@@ -1177,49 +1149,33 @@ screen_write_cell(struct screen_write_ctx *ctx,
/* Combine a UTF-8 zero-width character onto the previous. */
int
-screen_write_combine(
- struct screen_write_ctx *ctx, const struct utf8_data *utf8data)
+screen_write_combine(struct screen_write_ctx *ctx, const struct utf8_data *ud)
{
struct screen *s = ctx->s;
struct grid *gd = s->grid;
struct grid_cell *gc;
- struct grid_utf8 *gu, tmp_gu;
- u_int i;
+ struct utf8_data ud1;
/* Can't combine if at 0. */
if (s->cx == 0)
return (-1);
- /* Empty utf8data is out. */
- if (utf8data->size == 0)
+ /* Empty data is out. */
+ if (ud->size == 0)
fatalx("UTF-8 data empty");
- /* Retrieve the previous cell and convert to UTF-8 if not already. */
+ /* Retrieve the previous cell. */
gc = grid_view_get_cell(gd, s->cx - 1, s->cy);
- if (!(gc->flags & GRID_FLAG_UTF8)) {
- tmp_gu.data[0] = gc->data;
- tmp_gu.data[1] = 0xff;
- tmp_gu.width = 1;
+ grid_cell_get(gc, &ud1);
- grid_view_set_utf8(gd, s->cx - 1, s->cy, &tmp_gu);
- gc->flags |= GRID_FLAG_UTF8;
- }
+ /* Check there is enough space. */
+ if (ud1.size + ud->size > sizeof ud1.data)
+ return (-1);
- /* Append the current cell. */
- gu = grid_view_get_utf8(gd, s->cx - 1, s->cy);
- if (grid_utf8_append(gu, utf8data) != 0) {
- /* Failed: scrap this character and replace with underscores. */
- if (gu->width == 1) {
- gc->data = '_';
- gc->flags &= ~GRID_FLAG_UTF8;
- } else {
- for (i = 0; i < gu->width && i != sizeof gu->data; i++)
- gu->data[i] = '_';
- if (i != sizeof gu->data)
- gu->data[i] = 0xff;
- gu->width = i;
- }
- }
+ /* Append the data and set the cell. */
+ memcpy(ud1.data + ud1.size, ud->data, ud->size);
+ ud1.size += ud->size;
+ grid_cell_set(gc, &ud1);
return (0);
}
diff --git a/tmux.h b/tmux.h
index 9c062d65..9149f6b5 100644
--- a/tmux.h
+++ b/tmux.h
@@ -669,13 +669,7 @@ struct mode_key_table {
#define ALL_MOUSE_MODES (MODE_MOUSE_STANDARD|MODE_MOUSE_BUTTON|MODE_MOUSE_ANY)
-/*
- * A single UTF-8 character.
- *
- * The data member in this must be UTF8_SIZE to allow screen_write_copy to
- * reinject stored UTF-8 data back into screen_write_cell after combining (ugh
- * XXX XXX).
- */
+/* A single UTF-8 character. */
struct utf8_data {
u_char data[UTF8_SIZE];
@@ -709,7 +703,6 @@ struct utf8_data {
#define GRID_FLAG_FG256 0x1
#define GRID_FLAG_BG256 0x2
#define GRID_FLAG_PADDING 0x4
-#define GRID_FLAG_UTF8 0x8
/* Grid line flags. */
#define GRID_LINE_WRAPPED 0x1
@@ -720,13 +713,9 @@ struct grid_cell {
u_char flags;
u_char fg;
u_char bg;
- u_char data;
-} __packed;
-/* Grid cell UTF-8 data. Used instead of data in grid_cell for UTF-8 cells. */
-struct grid_utf8 {
- u_char width;
- u_char data[UTF8_SIZE];
+ u_char xstate; /* top 4 bits width, bottom 4 bits size */
+ u_char xdata[UTF8_SIZE];
} __packed;
/* Grid line. */
@@ -734,9 +723,6 @@ struct grid_line {
u_int cellsize;
struct grid_cell *celldata;
- u_int utf8size;
- struct grid_utf8 *utf8data;
-
int flags;
} __packed;
@@ -1233,7 +1219,6 @@ struct tty_ctx {
struct window_pane *wp;
const struct grid_cell *cell;
- const struct grid_utf8 *utf8;
u_int num;
void *ptr;
@@ -1254,7 +1239,6 @@ struct tty_ctx {
/* Saved last cell on line. */
struct grid_cell last_cell;
- struct grid_utf8 last_utf8;
u_int last_width;
};
@@ -1623,10 +1607,11 @@ void tty_putcode(struct tty *, enum tty_code_code);
void tty_putcode1(struct tty *, enum tty_code_code, int);
void tty_putcode2(struct tty *, enum tty_code_code, int, int);
void tty_putcode_ptr1(struct tty *, enum tty_code_code, const void *);
-void tty_putcode_ptr2(struct tty *, enum tty_code_code, const void *, const void *);
+void tty_putcode_ptr2(struct tty *, enum tty_code_code, const void *,
+ const void *);
void tty_puts(struct tty *, const char *);
void tty_putc(struct tty *, u_char);
-void tty_pututf8(struct tty *, const struct grid_utf8 *);
+void tty_putn(struct tty *, const void *, size_t, u_int);
void tty_init(struct tty *, struct client *, int, char *);
int tty_resize(struct tty *);
int tty_set_size(struct tty *, u_int, u_int);
@@ -1969,13 +1954,9 @@ void grid_collect_history(struct grid *);
void grid_scroll_history(struct grid *);
void grid_scroll_history_region(struct grid *, u_int, u_int);
void grid_expand_line(struct grid *, u_int, u_int);
-void grid_expand_line_utf8(struct grid *, u_int, u_int);
const struct grid_cell *grid_peek_cell(struct grid *, u_int, u_int);
struct grid_cell *grid_get_cell(struct grid *, u_int, u_int);
void grid_set_cell(struct grid *, u_int, u_int, const struct grid_cell *);
-const struct grid_utf8 *grid_peek_utf8(struct grid *, u_int, u_int);
-struct grid_utf8 *grid_get_utf8(struct grid *, u_int, u_int);
-void grid_set_utf8(struct grid *, u_int, u_int, const struct grid_utf8 *);
void grid_clear(struct grid *, u_int, u_int, u_int, u_int);
void grid_clear_lines(struct grid *, u_int, u_int);
void grid_move_lines(struct grid *, u_int, u_int, u_int);
@@ -1984,22 +1965,17 @@ char *grid_string_cells(struct grid *, u_int, u_int, u_int);
void grid_duplicate_lines(
struct grid *, u_int, struct grid *, u_int, u_int);
-/* grid-utf8.c */
-size_t grid_utf8_size(const struct grid_utf8 *);
-size_t grid_utf8_copy(const struct grid_utf8 *, char *, size_t);
-void grid_utf8_set(struct grid_utf8 *, const struct utf8_data *);
-int grid_utf8_append(struct grid_utf8 *, const struct utf8_data *);
-int grid_utf8_compare(const struct grid_utf8 *, const struct grid_utf8 *);
+/* grid-cell.c */
+u_int grid_cell_width(const struct grid_cell *);
+void grid_cell_get(const struct grid_cell *, struct utf8_data *);
+void grid_cell_set(struct grid_cell *, const struct utf8_data *);
+void grid_cell_one(struct grid_cell *, u_char);
/* grid-view.c */
const struct grid_cell *grid_view_peek_cell(struct grid *, u_int, u_int);
struct grid_cell *grid_view_get_cell(struct grid *, u_int, u_int);
void grid_view_set_cell(
struct grid *, u_int, u_int, const struct grid_cell *);
-const struct grid_utf8 *grid_view_peek_utf8(struct grid *, u_int, u_int);
-struct grid_utf8 *grid_view_get_utf8(struct grid *, u_int, u_int);
-void grid_view_set_utf8(
- struct grid *, u_int, u_int, const struct grid_utf8 *);
void grid_view_clear_history(struct grid *);
void grid_view_clear(struct grid *, u_int, u_int, u_int, u_int);
void grid_view_scroll_region_up(struct grid *, u_int, u_int);
@@ -2064,8 +2040,7 @@ void screen_write_clearendofscreen(struct screen_write_ctx *);
void screen_write_clearstartofscreen(struct screen_write_ctx *);
void screen_write_clearscreen(struct screen_write_ctx *);
void screen_write_clearhistory(struct screen_write_ctx *);
-void screen_write_cell(struct screen_write_ctx *,
- const struct grid_cell *, const struct utf8_data *);
+void screen_write_cell(struct screen_write_ctx *, const struct grid_cell *);
void screen_write_setselection(struct screen_write_ctx *, u_char *, u_int);
void screen_write_rawstring(struct screen_write_ctx *, u_char *, u_int);
void screen_write_bracketpaste(struct screen_write_ctx *, int);
diff --git a/tty.c b/tty.c
index a650c836..79cac5bb 100644
--- a/tty.c
+++ b/tty.c
@@ -48,8 +48,7 @@ void tty_redraw_region(struct tty *, const struct tty_ctx *);
void tty_emulate_repeat(
struct tty *, enum tty_code_code, enum tty_code_code, u_int);
void tty_repeat_space(struct tty *, u_int);
-void tty_cell(struct tty *,
- const struct grid_cell *, const struct grid_utf8 *);
+void tty_cell(struct tty *, const struct grid_cell *);
#define tty_use_acs(tty) \
(tty_term_has((tty)->term, TTYC_ACSC) && !((tty)->flags & TTY_UTF8))
@@ -416,15 +415,12 @@ tty_putc(struct tty *tty, u_char ch)
}
void
-tty_pututf8(struct tty *tty, const struct grid_utf8 *gu)
+tty_putn(struct tty *tty, const void *buf, size_t len, u_int width)
{
- size_t size;
-
- size = grid_utf8_size(gu);
- bufferevent_write(tty->event, gu->data, size);
+ bufferevent_write(tty->event, buf, len);
if (tty->log_fd != -1)
- write(tty->log_fd, gu->data, size);
- tty->cx += gu->width;
+ write(tty->log_fd, buf, len);
+ tty->cx += width;
}
void
@@ -582,7 +578,7 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy)
const struct grid_cell *gc;
struct grid_line *gl;
struct grid_cell tmpgc;
- const struct grid_utf8 *gu;
+ struct utf8_data ud;
u_int i, sx;
tty_update_mode(tty, tty->mode & ~MODE_CURSOR, s);
@@ -607,21 +603,17 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy)
for (i = 0; i < sx; i++) {
gc = grid_view_peek_cell(s->grid, i, py);
-
- gu = NULL;
- if (gc->flags & GRID_FLAG_UTF8)
- gu = grid_view_peek_utf8(s->grid, i, py);
-
if (screen_check_selection(s, i, py)) {
memcpy(&tmpgc, &s->sel.cell, sizeof tmpgc);
- tmpgc.data = gc->data;
+ grid_cell_get(gc, &ud);
+ grid_cell_set(&tmpgc, &ud);
tmpgc.flags = gc->flags &
~(GRID_FLAG_FG256|GRID_FLAG_BG256);
tmpgc.flags |= s->sel.cell.flags &
(GRID_FLAG_FG256|GRID_FLAG_BG256);
- tty_cell(tty, &tmpgc, gu);
+ tty_cell(tty, &tmpgc);
} else
- tty_cell(tty, gc, gu);
+ tty_cell(tty, gc);
}
if (sx >= tty->sx) {
@@ -984,17 +976,11 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx)
struct screen *s = wp->screen;
u_int cx;
u_int width;
- const struct grid_cell *gc = ctx->cell;
- const struct grid_utf8 *gu = ctx->utf8;
-
- if (gc->flags & GRID_FLAG_UTF8)
- width = gu->width;
- else
- width = 1;
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
/* Is the cursor in the very last position? */
+ width = grid_cell_width(ctx->cell);
if (ctx->ocx > wp->sx - width) {
if (ctx->xoff != 0 || wp->sx != tty->sx) {
/*
@@ -1011,17 +997,14 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx)
* move as far left as possible and redraw the last
* cell to move into the last position.
*/
- if (ctx->last_cell.flags & GRID_FLAG_UTF8)
- cx = screen_size_x(s) - ctx->last_utf8.width;
- else
- cx = screen_size_x(s) - 1;
+ cx = screen_size_x(s) - grid_cell_width(&ctx->last_cell);
tty_cursor_pane(tty, ctx, cx, ctx->ocy);
- tty_cell(tty, &ctx->last_cell, &ctx->last_utf8);
+ tty_cell(tty, &ctx->last_cell);
}
} else
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
- tty_cell(tty, ctx->cell, ctx->utf8);
+ tty_cell(tty, ctx->cell);
}
void
@@ -1071,10 +1054,10 @@ tty_cmd_rawstring(struct tty *tty, const struct tty_ctx *ctx)
}
void
-tty_cell(
- struct tty *tty, const struct grid_cell *gc, const struct grid_utf8 *gu)
+tty_cell(struct tty *tty, const struct grid_cell *gc)
{
- u_int i;
+ struct utf8_data ud;
+ u_int i;
/* Skip last character if terminal is stupid. */
if (tty->term->flags & TERM_EARLYWRAP &&
@@ -1088,23 +1071,24 @@ tty_cell(
/* Set the attributes. */
tty_attributes(tty, gc);
- /* If not UTF-8, write directly. */
- if (!(gc->flags & GRID_FLAG_UTF8)) {
- if (gc->data < 0x20 || gc->data == 0x7f)
+ /* Get the cell and if ASCII write with putc to do ACS tr