mirror of
https://github.com/tmate-io/tmate.git
synced 2024-11-23 08:33:17 +01:00
Step 2 of the Grand Plan To Make UTF-8 Better.
Split grid into two arrays, one containing grid attributes/flags/colours (keeps the name grid_cell for now) and a separate with the character data (called text). The text is stored as a u_short but is treated as a uint64_t elsewhere; eventually the grid will have two arrays. I'm not happy with the naming so that might change. Still need to decide where to go from here. I'm not sure whether to combine the peek/set functions together, and also whether to continue to treat the text as a uint64_t (and convert to/from Unicode) or make it a char array (of size one when UTF-8 disabled, eight when enabled) and keep everything as UTF-8. Also since UTF-8 will eventually become an attribute of the grid itself it might be nice to move all the padding crap into grid.c.
This commit is contained in:
parent
5872633aef
commit
6c0728fe07
@ -1,4 +1,4 @@
|
||||
/* $Id: cmd-find-window.c,v 1.3 2009-01-19 18:23:40 nicm Exp $ */
|
||||
/* $Id: cmd-find-window.c,v 1.4 2009-03-28 16:30:05 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@ -163,19 +163,19 @@ cmd_find_window_callback(void *data, int idx)
|
||||
char *
|
||||
cmd_find_window_search(struct window_pane *wp, const char *searchstr)
|
||||
{
|
||||
char *buf, *s;
|
||||
size_t off;
|
||||
const struct grid_cell *gc;
|
||||
u_int i, j, k;
|
||||
u_char data[4];
|
||||
char *buf, *s;
|
||||
size_t off;
|
||||
uint64_t text;
|
||||
u_int i, j, k;
|
||||
u_char data[4];
|
||||
|
||||
buf = xmalloc(1);
|
||||
|
||||
for (j = 0; j < screen_size_y(&wp->base); j++) {
|
||||
off = 0;
|
||||
for (i = 0; i < screen_size_x(&wp->base); i++) {
|
||||
gc = grid_view_peek_cell(wp->base.grid, i, j);
|
||||
utf8_split(gc->data, data);
|
||||
text = grid_view_peek_text(wp->base.grid, i, j);
|
||||
utf8_split(text, data);
|
||||
|
||||
buf = xrealloc(buf, 1, off + 4);
|
||||
for (k = 0; k < sizeof data; k++) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: cmd-list-windows.c,v 1.31 2009-03-28 15:43:41 nicm Exp $ */
|
||||
/* $Id: cmd-list-windows.c,v 1.32 2009-03-28 16:30:05 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@ -66,8 +66,10 @@ cmd_list_windows_exec(struct cmd *self, struct cmd_ctx *ctx)
|
||||
gd = wp->base.grid;
|
||||
|
||||
size = 0;
|
||||
for (i = 0; i < gd->hsize; i++)
|
||||
for (i = 0; i < gd->hsize; i++) {
|
||||
size += gd->size[i] * sizeof **gd->data;
|
||||
size += gd->size[i] * sizeof (u_short);
|
||||
}
|
||||
size += gd->hsize * (sizeof *gd->data);
|
||||
size += gd->hsize * (sizeof *gd->size);
|
||||
|
||||
|
16
grid-view.c
16
grid-view.c
@ -1,4 +1,4 @@
|
||||
/* $Id: grid-view.c,v 1.7 2009-03-28 15:43:41 nicm Exp $ */
|
||||
/* $Id: grid-view.c,v 1.8 2009-03-28 16:30:05 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@ -37,6 +37,13 @@ grid_view_peek_cell(struct grid *gd, u_int px, u_int py)
|
||||
return (grid_peek_cell(gd, grid_view_x(gd, px), grid_view_y(gd, py)));
|
||||
}
|
||||
|
||||
/* Get cell text. */
|
||||
uint64_t
|
||||
grid_view_peek_text(struct grid *gd, u_int px, u_int py)
|
||||
{
|
||||
return (grid_peek_text(gd, grid_view_x(gd, px), grid_view_y(gd, py)));
|
||||
}
|
||||
|
||||
/* Get cell for writing. */
|
||||
struct grid_cell *
|
||||
grid_view_get_cell(struct grid *gd, u_int px, u_int py)
|
||||
@ -52,6 +59,13 @@ grid_view_set_cell(
|
||||
grid_set_cell(gd, grid_view_x(gd, px), grid_view_y(gd, py), gc);
|
||||
}
|
||||
|
||||
/* Set text. */
|
||||
void
|
||||
grid_view_set_text(struct grid *gd, u_int px, u_int py, uint64_t text)
|
||||
{
|
||||
grid_set_text(gd, grid_view_x(gd, px), grid_view_y(gd, py), text);
|
||||
}
|
||||
|
||||
/* Clear area. */
|
||||
void
|
||||
grid_view_clear(struct grid *gd, u_int px, u_int py, u_int nx, u_int ny)
|
||||
|
62
grid.c
62
grid.c
@ -1,4 +1,4 @@
|
||||
/* $Id: grid.c,v 1.10 2009-03-28 15:43:41 nicm Exp $ */
|
||||
/* $Id: grid.c,v 1.11 2009-03-28 16:30:05 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@ -35,11 +35,14 @@
|
||||
*/
|
||||
|
||||
/* Default grid cell data. */
|
||||
const struct grid_cell grid_default_cell = { ' ', 0, 0, 8, 8 };
|
||||
const struct grid_cell grid_default_cell = { 0, 0, 8, 8 };
|
||||
|
||||
#define grid_put_cell(gd, px, py, gc) do { \
|
||||
memcpy(&gd->data[py][px], gc, sizeof gd->data[py][px]); \
|
||||
} while (0)
|
||||
#define grid_put_text(gd, px, py, xtext) do { \
|
||||
gd->text[py][px] = xtext; \
|
||||
} while (0)
|
||||
|
||||
int grid_check_x(struct grid *, u_int);
|
||||
int grid_check_y(struct grid *, u_int);
|
||||
@ -97,6 +100,7 @@ grid_create(u_int sx, u_int sy, u_int hlimit)
|
||||
|
||||
gd->size = xcalloc(gd->sy, sizeof *gd->size);
|
||||
gd->data = xcalloc(gd->sy, sizeof *gd->data);
|
||||
gd->text = xcalloc(gd->sy, sizeof *gd->text);
|
||||
|
||||
return (gd);
|
||||
}
|
||||
@ -108,10 +112,14 @@ grid_destroy(struct grid *gd)
|
||||
u_int yy;
|
||||
|
||||
for (yy = 0; yy < gd->hsize + gd->sy; yy++) {
|
||||
if (gd->text[yy] != NULL)
|
||||
xfree(gd->text[yy]);
|
||||
if (gd->data[yy] != NULL)
|
||||
xfree(gd->data[yy]);
|
||||
}
|
||||
|
||||
if (gd->text != NULL)
|
||||
xfree(gd->text);
|
||||
if (gd->data != NULL)
|
||||
xfree(gd->data);
|
||||
if (gd->size != NULL)
|
||||
@ -164,8 +172,10 @@ grid_scroll_line(struct grid *gd)
|
||||
yy = gd->hsize + gd->sy;
|
||||
gd->size = xrealloc(gd->size, yy + 1, sizeof *gd->size);
|
||||
gd->data = xrealloc(gd->data, yy + 1, sizeof *gd->data);
|
||||
gd->text = xrealloc(gd->text, yy + 1, sizeof *gd->text);
|
||||
|
||||
gd->data[yy] = NULL;
|
||||
gd->text[yy] = NULL;
|
||||
gd->size[yy] = 0;
|
||||
|
||||
gd->hsize++;
|
||||
@ -179,6 +189,7 @@ grid_reduce_line(struct grid *gd, u_int py, u_int sx)
|
||||
return;
|
||||
|
||||
gd->data[py] = xrealloc(gd->data[py], sx, sizeof **gd->data);
|
||||
gd->text[py] = xrealloc(gd->text[py], sx, sizeof **gd->text);
|
||||
gd->size[py] = sx;
|
||||
}
|
||||
|
||||
@ -192,8 +203,11 @@ grid_expand_line(struct grid *gd, u_int py, u_int sx)
|
||||
return;
|
||||
|
||||
gd->data[py] = xrealloc(gd->data[py], sx, sizeof **gd->data);
|
||||
for (xx = gd->size[py]; xx < sx; xx++)
|
||||
gd->text[py] = xrealloc(gd->text[py], sx, sizeof **gd->text);
|
||||
for (xx = gd->size[py]; xx < sx; xx++) {
|
||||
grid_put_cell(gd, xx, py, &grid_default_cell);
|
||||
grid_put_text(gd, xx, py, ' ');
|
||||
}
|
||||
gd->size[py] = sx;
|
||||
}
|
||||
|
||||
@ -211,6 +225,20 @@ grid_peek_cell(struct grid *gd, u_int px, u_int py)
|
||||
return (&gd->data[py][px]);
|
||||
}
|
||||
|
||||
/* Get text for reading. */
|
||||
uint64_t
|
||||
grid_peek_text(struct grid *gd, u_int px, u_int py)
|
||||
{
|
||||
if (grid_check_x(gd, px) != 0)
|
||||
return (' ');
|
||||
if (grid_check_y(gd, py) != 0)
|
||||
return (' ');
|
||||
|
||||
if (px >= gd->size[py])
|
||||
return (' ');
|
||||
return (gd->text[py][px]);
|
||||
}
|
||||
|
||||
/* Get cell at relative position (for writing). */
|
||||
struct grid_cell *
|
||||
grid_get_cell(struct grid *gd, u_int px, u_int py)
|
||||
@ -238,6 +266,19 @@ grid_set_cell(
|
||||
grid_put_cell(gd, px, py, gc);
|
||||
}
|
||||
|
||||
/* Set text at relative position. */
|
||||
void
|
||||
grid_set_text(struct grid *gd, u_int px, u_int py, uint64_t text)
|
||||
{
|
||||
if (grid_check_x(gd, px) != 0)
|
||||
return;
|
||||
if (grid_check_y(gd, py) != 0)
|
||||
return;
|
||||
|
||||
grid_expand_line(gd, py, px + 1);
|
||||
grid_put_text(gd, px, py, text);
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear area. Note this is different from a fill as it just omits unallocated
|
||||
* cells.
|
||||
@ -321,9 +362,11 @@ grid_clear_lines(struct grid *gd, u_int py, u_int ny)
|
||||
return;
|
||||
|
||||
for (yy = py; yy < py + ny; yy++) {
|
||||
if (gd->data[yy] != NULL) {
|
||||
if (gd->data[yy] != NULL || gd->text[yy] != NULL) {
|
||||
xfree(gd->data[yy]);
|
||||
gd->data[yy] = NULL;
|
||||
xfree(gd->text[yy]);
|
||||
gd->data[yy] = NULL;
|
||||
gd->text[yy] = NULL;
|
||||
gd->size[yy] = 0;
|
||||
}
|
||||
}
|
||||
@ -364,7 +407,8 @@ grid_move_lines(struct grid *gd, u_int dy, u_int py, u_int ny)
|
||||
grid_clear_lines(gd, yy, 1);
|
||||
}
|
||||
|
||||
memmove(&gd->data[dy], &gd->data[py], ny * (sizeof *gd->data));
|
||||
memmove(&gd->data[dy], &gd->data[py], ny * (sizeof *gd->data));
|
||||
memmove(&gd->text[dy], &gd->text[py], ny * (sizeof *gd->text));
|
||||
memmove(&gd->size[dy], &gd->size[py], ny * (sizeof *gd->size));
|
||||
|
||||
/* Wipe any lines that have been moved (without freeing them). */
|
||||
@ -372,6 +416,7 @@ grid_move_lines(struct grid *gd, u_int dy, u_int py, u_int ny)
|
||||
if (yy >= dy && yy < dy + ny)
|
||||
continue;
|
||||
gd->data[yy] = NULL;
|
||||
gd->text[yy] = NULL;
|
||||
gd->size[yy] = 0;
|
||||
}
|
||||
}
|
||||
@ -424,13 +469,14 @@ grid_move_cells(struct grid *gd, u_int dx, u_int px, u_int py, u_int nx)
|
||||
grid_expand_line(gd, py, px + nx);
|
||||
grid_expand_line(gd, py, dx + nx);
|
||||
memmove(&gd->data[py][dx], &gd->data[py][px], nx * (sizeof **gd->data));
|
||||
memmove(&gd->text[py][dx], &gd->text[py][px], nx * (sizeof **gd->text));
|
||||
|
||||
/* Wipe any cells that have been moved. */
|
||||
for (xx = px; xx < px + nx; xx++) {
|
||||
if (xx >= dx && xx < dx + nx)
|
||||
continue;
|
||||
memcpy(
|
||||
&gd->data[py][xx], &grid_default_cell, sizeof **gd->data);
|
||||
grid_put_cell(gd, xx, py, &grid_default_cell);
|
||||
grid_put_text(gd, xx, py, ' ' );
|
||||
}
|
||||
}
|
||||
|
||||
|
10
input.c
10
input.c
@ -1,4 +1,4 @@
|
||||
/* $Id: input.c,v 1.74 2009-01-18 21:46:30 nicm Exp $ */
|
||||
/* $Id: input.c,v 1.75 2009-03-28 16:30:05 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@ -541,9 +541,9 @@ input_state_utf8(u_char ch, struct input_ctx *ictx)
|
||||
if (value > 0xffff) /* non-BMP not supported */
|
||||
value = '_';
|
||||
|
||||
ictx->cell.data = value;
|
||||
ictx->text = value;
|
||||
ictx->cell.flags |= GRID_FLAG_UTF8;
|
||||
screen_write_cell(&ictx->ctx, &ictx->cell);
|
||||
screen_write_cell(&ictx->ctx, &ictx->cell, ictx->text);
|
||||
ictx->cell.flags &= ~GRID_FLAG_UTF8;
|
||||
}
|
||||
|
||||
@ -585,8 +585,8 @@ input_handle_character(u_char ch, struct input_ctx *ictx)
|
||||
}
|
||||
log_debug2("-- ch %zu: %hhu (%c)", ictx->off, ch, ch);
|
||||
|
||||
ictx->cell.data = ch;
|
||||
screen_write_cell(&ictx->ctx, &ictx->cell);
|
||||
ictx->text = ch;
|
||||
screen_write_cell(&ictx->ctx, &ictx->cell, ictx->text);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: screen-write.c,v 1.38 2009-03-28 15:43:41 nicm Exp $ */
|
||||
/* $Id: screen-write.c,v 1.39 2009-03-28 16:30:05 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@ -47,8 +47,7 @@ void
|
||||
screen_write_putc(
|
||||
struct screen_write_ctx *ctx, struct grid_cell *gc, u_char ch)
|
||||
{
|
||||
gc->data = ch;
|
||||
screen_write_cell(ctx, gc);
|
||||
screen_write_cell(ctx, gc, ch);
|
||||
}
|
||||
|
||||
/* Write string. */
|
||||
@ -77,17 +76,21 @@ screen_write_copy(struct screen_write_ctx *ctx,
|
||||
struct screen *s = ctx->s;
|
||||
struct grid *gd = src->grid;
|
||||
const struct grid_cell *gc;
|
||||
uint64_t text;
|
||||
u_int xx, yy, cx, cy;
|
||||
|
||||
cx = s->cx;
|
||||
cy = s->cy;
|
||||
for (yy = py; yy < py + ny; yy++) {
|
||||
for (xx = px; xx < px + nx; xx++) {
|
||||
if (xx >= gd->sx || yy >= gd->hsize + gd->sy)
|
||||
if (xx >= gd->sx || yy >= gd->hsize + gd->sy) {
|
||||
gc = &grid_default_cell;
|
||||
else
|
||||
text = ' ';
|
||||
} else {
|
||||
gc = grid_peek_cell(gd, xx, yy);
|
||||
screen_write_cell(ctx, gc);
|
||||
text = grid_peek_text(gd, xx, yy);
|
||||
}
|
||||
screen_write_cell(ctx, gc, text);
|
||||
}
|
||||
cy++;
|
||||
screen_write_cursormove(ctx, cx, cy);
|
||||
@ -513,17 +516,19 @@ screen_write_clearscreen(struct screen_write_ctx *ctx)
|
||||
|
||||
/* Write cell data. */
|
||||
void
|
||||
screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
|
||||
screen_write_cell(
|
||||
struct screen_write_ctx *ctx, const struct grid_cell *gc, uint64_t text)
|
||||
{
|
||||
struct screen *s = ctx->s;
|
||||
struct grid *gd = s->grid;
|
||||
u_int width, xx;
|
||||
const struct grid_cell *hc;
|
||||
uint64_t htext;
|
||||
struct grid_cell *ic, tc;
|
||||
|
||||
/* Find character width. */
|
||||
if (gc->flags & GRID_FLAG_UTF8)
|
||||
width = utf8_width(gc->data);
|
||||
width = utf8_width(text);
|
||||
else
|
||||
width = 1;
|
||||
|
||||
@ -534,8 +539,7 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
|
||||
/* If the character is wider than the screen, don't print it. */
|
||||
if (width > screen_size_x(s)) {
|
||||
memcpy(&tc, gc, sizeof tc);
|
||||
tc.data = '_';
|
||||
|
||||
text = '_';
|
||||
width = 1;
|
||||
gc = &tc;
|
||||
}
|
||||
@ -560,6 +564,7 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
|
||||
* which covered by the same character.
|
||||
*/
|
||||
hc = grid_view_peek_cell(gd, s->cx, s->cy);
|
||||
htext = grid_view_peek_text(gd, s->cx, s->cy);
|
||||
if (hc->flags & GRID_FLAG_PADDING) {
|
||||
/*
|
||||
* A padding cell, so clear any following and leading padding
|
||||
@ -585,7 +590,7 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
|
||||
break;
|
||||
grid_view_set_cell(gd, xx, s->cy, &grid_default_cell);
|
||||
}
|
||||
} else if (hc->flags & GRID_FLAG_UTF8 && utf8_width(hc->data) > 1) {
|
||||
} else if (hc->flags & GRID_FLAG_UTF8 && utf8_width(htext) > 1) {
|
||||
/*
|
||||
* An UTF-8 wide cell; overwrite following padding cells only.
|
||||
*/
|
||||
@ -610,16 +615,15 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
|
||||
|
||||
/* Set the cell. */
|
||||
grid_view_set_cell(gd, s->cx, s->cy, gc);
|
||||
grid_view_set_text(gd, s->cx, s->cy, text);
|
||||
|
||||
/* Move the cursor. */
|
||||
screen_write_save(ctx);
|
||||
s->cx += width;
|
||||
|
||||
/* Draw to the screen if necessary. */
|
||||
if (screen_check_selection(s, s->cx - width, s->cy)) {
|
||||
memcpy(&tc, &s->sel.cell, sizeof tc);
|
||||
tc.data = gc->data;
|
||||
tty_write_cmd(ctx->wp, TTY_CELL, &tc);
|
||||
} else
|
||||
tty_write_cmd(ctx->wp, TTY_CELL, gc);
|
||||
if (screen_check_selection(s, s->cx - width, s->cy))
|
||||
tty_write_cmd(ctx->wp, TTY_CELL, &s->sel.cell, text);
|
||||
else
|
||||
tty_write_cmd(ctx->wp, TTY_CELL, gc, text);
|
||||
}
|
||||
|
10
screen.c
10
screen.c
@ -1,4 +1,4 @@
|
||||
/* $Id: screen.c,v 1.79 2009-03-28 15:43:41 nicm Exp $ */
|
||||
/* $Id: screen.c,v 1.80 2009-03-28 16:30:05 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@ -89,6 +89,7 @@ screen_resize_x(struct screen *s, u_int sx)
|
||||
{
|
||||
struct grid *gd = s->grid;
|
||||
const struct grid_cell *gc;
|
||||
uint64_t text;
|
||||
u_int xx, yy;
|
||||
|
||||
if (sx == 0)
|
||||
@ -106,14 +107,15 @@ screen_resize_x(struct screen *s, u_int sx)
|
||||
* If the character after the last is wide or padding, remove
|
||||
* it and any leading padding.
|
||||
*/
|
||||
gc = &grid_default_cell;
|
||||
text = ' ';
|
||||
for (xx = sx; xx > 0; xx--) {
|
||||
gc = grid_peek_cell(gd, xx - 1, yy);
|
||||
text = grid_peek_text(gd, xx - 1, yy);
|
||||
if (!(gc->flags & GRID_FLAG_PADDING))
|
||||
break;
|
||||
grid_set_cell(gd, xx - 1, yy, &grid_default_cell);
|
||||
}
|
||||
if (xx > 0 && xx != sx && utf8_width(gc->data) != 1)
|
||||
if (xx > 0 && xx != sx && utf8_width(text) != 1)
|
||||
grid_set_cell(gd, xx - 1, yy, &grid_default_cell);
|
||||
|
||||
/* Reduce the line size. */
|
||||
@ -165,6 +167,7 @@ screen_resize_y(struct screen *s, u_int sy)
|
||||
/* Resize line arrays. */
|
||||
gd->size = xrealloc(gd->size, gd->hsize + sy, sizeof *gd->size);
|
||||
gd->data = xrealloc(gd->data, gd->hsize + sy, sizeof *gd->data);
|
||||
gd->text = xrealloc(gd->text, gd->hsize + sy, sizeof *gd->text);
|
||||
|
||||
/* Size increasing. */
|
||||
if (sy > screen_size_y(s)) {
|
||||
@ -172,6 +175,7 @@ screen_resize_y(struct screen *s, u_int sy)
|
||||
for (yy = gd->hsize + oy; yy < gd->hsize + sy; yy++) {
|
||||
gd->size[yy] = 0;
|
||||
gd->data[yy] = NULL;
|
||||
gd->text[yy] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
29
tmux.h
29
tmux.h
@ -1,4 +1,4 @@
|
||||
/* $Id: tmux.h,v 1.287 2009-03-28 15:43:41 nicm Exp $ */
|
||||
/* $Id: tmux.h,v 1.288 2009-03-28 16:30:05 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@ -482,16 +482,15 @@ struct mode_key_data {
|
||||
#define GRID_FLAG_PADDING 0x4
|
||||
#define GRID_FLAG_UTF8 0x8
|
||||
|
||||
/* Grid cell. */
|
||||
/* Grid cell attributes. */
|
||||
struct grid_cell {
|
||||
u_short data;
|
||||
u_char attr;
|
||||
u_char flags;
|
||||
u_char fg;
|
||||
u_char bg;
|
||||
} __packed;
|
||||
|
||||
/* Grid data. */
|
||||
/* Entire grid of cells. */
|
||||
struct grid {
|
||||
u_int sx;
|
||||
u_int sy;
|
||||
@ -499,8 +498,10 @@ struct grid {
|
||||
u_int hsize;
|
||||
u_int hlimit;
|
||||
|
||||
u_int *size;
|
||||
u_int *size; /* row size */
|
||||
|
||||
struct grid_cell **data;
|
||||
uint16_t **text;
|
||||
};
|
||||
|
||||
/* Option data structures. */
|
||||
@ -589,7 +590,8 @@ struct input_ctx {
|
||||
size_t len;
|
||||
size_t off;
|
||||
|
||||
struct grid_cell cell; /* current cell data */
|
||||
struct grid_cell cell;
|
||||
uint64_t text;
|
||||
|
||||
struct grid_cell saved_cell;
|
||||
u_int saved_cx;
|
||||
@ -1054,7 +1056,7 @@ long long options_get_number(struct options *, const char *);
|
||||
void tty_reset(struct tty *);
|
||||
void tty_region(struct tty *, u_int, u_int, u_int);
|
||||
void tty_cursor(struct tty *, u_int, u_int, u_int);
|
||||
void tty_cell(struct tty *, const struct grid_cell *);
|
||||
void tty_cell(struct tty *, const struct grid_cell *, uint64_t);
|
||||
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);
|
||||
@ -1373,8 +1375,9 @@ void grid_expand_line(struct grid *, u_int, u_int);
|
||||
void grid_scroll_line(struct grid *);
|
||||
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 *);
|
||||
void grid_set_cell(struct grid *, u_int, u_int, const struct grid_cell *);
|
||||
uint64_t grid_peek_text(struct grid *, u_int, u_int);
|
||||
void grid_set_text(struct grid *, u_int, u_int, uint64_t);
|
||||
void grid_clear(struct grid *, u_int, u_int, u_int, u_int);
|
||||
void grid_fill(struct grid *,
|
||||
const struct grid_cell *, u_int, u_int, u_int, u_int);
|
||||
@ -1387,9 +1390,12 @@ void grid_move_cells(struct grid *, u_int, u_int, u_int, u_int);
|
||||
|
||||
/* grid-view.c */
|
||||
const struct grid_cell *grid_view_peek_cell(struct grid *, u_int, u_int);
|
||||
uint64_t grid_view_peek_text(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 *);
|
||||
struct grid *, u_int, u_int, const struct grid_cell *);
|
||||
uint64_t grid_view_peek_text(struct grid *, u_int, u_int);
|
||||
void grid_view_set_text(struct grid *, u_int, u_int, uint64_t);
|
||||
void grid_view_clear(struct grid *, u_int, u_int, u_int, u_int);
|
||||
void grid_view_fill(struct grid *,
|
||||
const struct grid_cell *, u_int, u_int, u_int, u_int);
|
||||
@ -1438,7 +1444,8 @@ void screen_write_kkeypadmode(struct screen_write_ctx *, int);
|
||||
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_cell(struct screen_write_ctx *, const struct grid_cell *);
|
||||
void screen_write_cell(
|
||||
struct screen_write_ctx *, const struct grid_cell *, uint64_t);
|
||||
|
||||
/* screen-redraw.c */
|
||||
void screen_redraw_screen(struct client *, struct screen *);
|
||||
|
41
tty.c
41
tty.c
@ -1,4 +1,4 @@
|
||||
/* $Id: tty.c,v 1.83 2009-03-28 10:15:01 nicm Exp $ */
|
||||
/* $Id: tty.c,v 1.84 2009-03-28 16:30:05 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@ -381,8 +381,8 @@ tty_emulate_repeat(
|
||||
void
|
||||
tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int oy)
|
||||
{
|
||||
const struct grid_cell *gc;
|
||||
struct grid_cell tc;
|
||||
const struct grid_cell *gc;
|
||||
uint64_t text;
|
||||
u_int i, sx;
|
||||
|
||||
sx = screen_size_x(s);
|
||||
@ -393,15 +393,13 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int oy)
|
||||
|
||||
for (i = 0; i < sx; i++) {
|
||||
gc = grid_view_peek_cell(s->grid, i, py);
|
||||
text = grid_view_peek_text(s->grid, i, py);
|
||||
|
||||
if (screen_check_selection(s, i, py)) {
|
||||
memcpy(&tc, &s->sel.cell, sizeof tc);
|
||||
tc.data = gc->data;
|
||||
gc = &tc;
|
||||
}
|
||||
|
||||
tty_cursor(tty, i, py, oy);
|
||||
tty_cell(tty, gc);
|
||||
if (screen_check_selection(s, i, py))
|
||||
tty_cell(tty, &s->sel.cell, text);
|
||||
else
|
||||
tty_cell(tty, gc, text);
|
||||
}
|
||||
|
||||
if (sx >= tty->sx)
|
||||
@ -739,16 +737,18 @@ tty_cmd_cell(struct tty *tty, struct window_pane *wp, va_list ap)
|
||||
{
|
||||
struct screen *s = wp->screen;
|
||||
struct grid_cell *gc;
|
||||
uint64_t text;
|
||||
|
||||
gc = va_arg(ap, struct grid_cell *);
|
||||
text = va_arg(ap, uint64_t);
|
||||
|
||||
tty_cursor(tty, s->old_cx, s->old_cy, wp->yoff);
|
||||
|
||||
tty_cell(tty, gc);
|
||||
tty_cell(tty, gc, text);
|
||||
}
|
||||
|
||||
void
|
||||
tty_cell(struct tty *tty, const struct grid_cell *gc)
|
||||
tty_cell(struct tty *tty, const struct grid_cell *gc, uint64_t text)
|
||||
{
|
||||
u_int i, width;
|
||||
u_char out[4];
|
||||
@ -767,22 +767,22 @@ tty_cell(struct tty *tty, const struct grid_cell *gc)
|
||||
|
||||
/* If not UTF-8, write directly. */
|
||||
if (!(gc->flags & GRID_FLAG_UTF8)) {
|
||||
if (gc->data > 0xff || gc->data < 0x20 || gc->data == 0x7f)
|
||||
if (text > 0xff || text < 0x20 || text == 0x7f)
|
||||
return;
|
||||
tty_putc(tty, gc->data);
|
||||
tty_putc(tty, text);
|
||||
return;
|
||||
}
|
||||
|
||||
/* If the terminal doesn't support UTF-8, write underscores. */
|
||||
if (!(tty->flags & TTY_UTF8)) {
|
||||
width = utf8_width(gc->data);
|
||||
width = utf8_width(text);
|
||||
while (width-- > 0)
|
||||
tty_putc(tty, '_');
|
||||
return;
|
||||
}
|
||||
|
||||
/* Otherwise, unpack UTF-8 and write it. */
|
||||
utf8_split(gc->data, out);
|
||||
utf8_split(text, out);
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (out[i] == 0xff)
|
||||
break;
|
||||
@ -793,16 +793,15 @@ tty_cell(struct tty *tty, const struct grid_cell *gc)
|
||||
void
|
||||
tty_reset(struct tty *tty)
|
||||
{
|
||||
struct grid_cell *tc = &tty->cell;
|
||||
struct grid_cell *gc = &tty->cell;
|
||||
|
||||
tc->data = grid_default_cell.data;
|
||||
if (memcmp(tc, &grid_default_cell, sizeof *tc) == 0)
|
||||
if (memcmp(gc, &grid_default_cell, sizeof *gc) == 0)
|
||||
return;
|
||||
|
||||
if (tty_term_has(tty->term, TTYC_RMACS) && tc->attr & GRID_ATTR_CHARSET)
|
||||
if (tty_term_has(tty->term, TTYC_RMACS) && gc->attr & GRID_ATTR_CHARSET)
|
||||
tty_putcode(tty, TTYC_RMACS);
|
||||
tty_putcode(tty, TTYC_SGR0);
|
||||
memcpy(tc, &grid_default_cell, sizeof *tc);
|
||||
memcpy(gc, &grid_default_cell, sizeof *gc);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: window-copy.c,v 1.50 2009-02-13 21:39:45 nicm Exp $ */
|
||||
/* $Id: window-copy.c,v 1.51 2009-03-28 16:30:05 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
@ -465,9 +465,9 @@ void
|
||||
window_copy_copy_line(
|
||||
struct window_pane *wp, char **buf, size_t *off, u_int sy, u_int sx, u_int ex)
|
||||
{
|
||||
const struct grid_cell *gc;
|
||||
u_int i, j, xx;
|
||||
u_char data[4];
|
||||
u_int i, j, xx;
|
||||
uint64_t text;
|
||||
u_char data[4];
|
||||
|
||||
if (sx > ex)
|
||||
return;
|
||||
@ -480,8 +480,8 @@ window_copy_copy_line(
|
||||
|
||||
if (sx < ex) {
|
||||
for (i = sx; i < ex; i++) {
|
||||
gc = grid_peek_cell(wp->base.grid, i, sy);
|
||||
utf8_split(gc->data, data);
|
||||
text = grid_peek_text(wp->base.grid, i, sy);
|
||||
utf8_split(text, data);
|
||||
|
||||
*buf = xrealloc(*buf, 1, (*off) + 4);
|
||||
for (j = 0; j < sizeof data; j++) {
|
||||
@ -501,26 +501,28 @@ int
|
||||
window_copy_is_space(struct window_pane *wp, u_int px, u_int py)
|
||||
{
|
||||
const struct grid_cell *gc;
|
||||
const char *spaces = " -_@";
|
||||
uint64_t text;
|
||||
const char *spaces = " -_@";
|
||||
|
||||
gc = grid_peek_cell(wp->base.grid, px, py);
|
||||
if (gc->flags & GRID_FLAG_PADDING)
|
||||
return (0);
|
||||
if (gc->data == 0x00 || gc->data > 0xff)
|
||||
text = grid_peek_text(wp->base.grid, px, py);
|
||||
if (text == 0x00 || text == 0x7f || text > 0xff)
|
||||
return (0);
|
||||
return (strchr(spaces, gc->data) != NULL);
|
||||
return (strchr(spaces, text) != NULL);
|
||||
}
|
||||
|
||||
u_int
|
||||
window_copy_find_length(struct window_pane *wp, u_int py)
|
||||
{
|
||||
const struct grid_cell *gc;
|
||||
u_int px;
|
||||
uint64_t text;
|
||||
u_int px;
|
||||
|
||||
px = wp->base.grid->size[py];
|
||||
while (px > 0) {
|
||||
gc = grid_peek_cell(wp->base.grid, px - 1, py);
|
||||
if (gc->data != 0x20)
|
||||
text = grid_peek_text(wp->base.grid, px - 1, py);
|
||||
if (text != 0x20)
|
||||
break;
|
||||
px--;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user