version 1.76, 2015/11/12 22:04:37 |
version 1.77, 2015/11/13 08:09:28 |
|
|
screen_write_putc(struct screen_write_ctx *ctx, struct grid_cell *gc, |
screen_write_putc(struct screen_write_ctx *ctx, struct grid_cell *gc, |
u_char ch) |
u_char ch) |
{ |
{ |
grid_cell_one(gc, ch); |
utf8_set(&gc->data, ch); |
screen_write_cell(ctx, gc); |
screen_write_cell(ctx, gc); |
} |
} |
|
|
|
|
ptr++; |
ptr++; |
|
|
left = strlen(ptr); |
left = strlen(ptr); |
if (left < ud.size - 1) |
if (left < (size_t)ud.size - 1) |
break; |
break; |
while (utf8_append(&ud, *ptr)) |
while (utf8_append(&ud, *ptr)) |
ptr++; |
ptr++; |
|
|
ptr++; |
ptr++; |
|
|
left = strlen(ptr); |
left = strlen(ptr); |
if (left < ud.size - 1) |
if (left < (size_t)ud.size - 1) |
break; |
break; |
while (utf8_append(&ud, *ptr)) |
while (utf8_append(&ud, *ptr)) |
ptr++; |
ptr++; |
|
|
} |
} |
size += ud.width; |
size += ud.width; |
|
|
grid_cell_set(gc, &ud); |
utf8_copy(&gc->data, &ud); |
screen_write_cell(ctx, gc); |
screen_write_cell(ctx, gc); |
} else { |
} else { |
if (maxlen > 0 && size + 1 > (size_t) maxlen) |
if (maxlen > 0 && size + 1 > (size_t) maxlen) |
|
|
ptr++; |
ptr++; |
|
|
left = strlen(ptr); |
left = strlen(ptr); |
if (left < ud.size - 1) |
if (left < (size_t)ud.size - 1) |
break; |
break; |
while (utf8_append(&ud, *ptr)) |
while (utf8_append(&ud, *ptr)) |
ptr++; |
ptr++; |
|
|
} |
} |
size += ud.width; |
size += ud.width; |
|
|
grid_cell_set(&lgc, &ud); |
utf8_copy(&lgc.data, &ud); |
screen_write_cell(ctx, &lgc); |
screen_write_cell(ctx, &lgc); |
} else { |
} else { |
if (maxlen > 0 && size + 1 > (size_t) maxlen) |
if (maxlen > 0 && size + 1 > (size_t) maxlen) |
|
|
struct screen *s = ctx->s; |
struct screen *s = ctx->s; |
struct grid *gd = src->grid; |
struct grid *gd = src->grid; |
struct grid_line *gl; |
struct grid_line *gl; |
const struct grid_cell *gc; |
struct grid_cell gc; |
struct utf8_data ud; |
|
u_int xx, yy, cx, cy, ax, bx; |
u_int xx, yy, cx, cy, ax, bx; |
|
|
cx = s->cx; |
cx = s->cx; |
|
|
bx = px + nx; |
bx = px + nx; |
|
|
for (xx = ax; xx < bx; xx++) { |
for (xx = ax; xx < bx; xx++) { |
if (xx >= gl->cellsize) |
grid_get_cell(gd, xx, yy, &gc); |
gc = &grid_default_cell; |
screen_write_cell(ctx, &gc); |
else |
|
gc = &gl->celldata[xx]; |
|
grid_cell_get(gc, &ud); |
|
screen_write_cell(ctx, gc); |
|
} |
} |
if (px + nx == gd->sx && px + nx > gl->cellsize) |
if (px + nx == gd->sx && px + nx > gl->cellsize) |
screen_write_clearendofline(ctx); |
screen_write_clearendofline(ctx); |
|
|
|
|
/* Set up context for TTY command. */ |
/* Set up context for TTY command. */ |
void |
void |
screen_write_initctx( |
screen_write_initctx(struct screen_write_ctx *ctx, struct tty_ctx *ttyctx, |
struct screen_write_ctx *ctx, struct tty_ctx *ttyctx, int save_last) |
int save_last) |
{ |
{ |
struct screen *s = ctx->s; |
struct screen *s = ctx->s; |
struct grid *gd = s->grid; |
struct grid *gd = s->grid; |
const struct grid_cell *gc; |
struct grid_cell gc; |
u_int xx; |
u_int xx; |
|
|
ttyctx->wp = ctx->wp; |
ttyctx->wp = ctx->wp; |
|
|
return; |
return; |
|
|
/* Save the last cell on the screen. */ |
/* Save the last cell on the screen. */ |
gc = &grid_default_cell; |
memcpy(&gc, &grid_default_cell, sizeof gc); |
for (xx = 1; xx <= screen_size_x(s); xx++) { |
for (xx = 1; xx <= screen_size_x(s); xx++) { |
gc = grid_view_peek_cell(gd, screen_size_x(s) - xx, s->cy); |
grid_view_get_cell(gd, screen_size_x(s) - xx, s->cy, &gc); |
if (!(gc->flags & GRID_FLAG_PADDING)) |
if (~gc.flags & GRID_FLAG_PADDING) |
break; |
break; |
} |
} |
ttyctx->last_width = xx; |
ttyctx->last_width = xx; |
memcpy(&ttyctx->last_cell, gc, sizeof ttyctx->last_cell); |
memcpy(&ttyctx->last_cell, &gc, sizeof ttyctx->last_cell); |
} |
} |
|
|
/* Set a mode. */ |
/* Set a mode. */ |
|
|
screen_write_initctx(ctx, &ttyctx, 0); |
screen_write_initctx(ctx, &ttyctx, 0); |
|
|
memcpy(&gc, &grid_default_cell, sizeof gc); |
memcpy(&gc, &grid_default_cell, sizeof gc); |
grid_cell_one(&gc, 'E'); |
utf8_set(&gc.data, 'E'); |
|
|
for (yy = 0; yy < screen_size_y(s); yy++) { |
for (yy = 0; yy < screen_size_y(s); yy++) { |
for (xx = 0; xx < screen_size_x(s); xx++) |
for (xx = 0; xx < screen_size_x(s); xx++) |
|
|
struct grid *gd = s->grid; |
struct grid *gd = s->grid; |
struct tty_ctx ttyctx; |
struct tty_ctx ttyctx; |
u_int width, xx, last; |
u_int width, xx, last; |
struct grid_cell tmp_gc, *tmp_gcp; |
struct grid_cell tmp_gc; |
struct utf8_data ud; |
|
int insert; |
int insert; |
|
|
/* Ignore padding. */ |
/* Ignore padding. */ |
if (gc->flags & GRID_FLAG_PADDING) |
if (gc->flags & GRID_FLAG_PADDING) |
return; |
return; |
width = grid_cell_width(gc); |
width = gc->data.width; |
|
|
/* |
/* |
* If this is a wide character and there is no room on the screen, for |
* If this is a wide character and there is no room on the screen, for |
|
|
* there is space. |
* there is space. |
*/ |
*/ |
if (width == 0) { |
if (width == 0) { |
grid_cell_get(gc, &ud); |
if (screen_write_combine(ctx, &gc->data) == 0) { |
if (screen_write_combine(ctx, &ud) == 0) { |
|
screen_write_initctx(ctx, &ttyctx, 0); |
screen_write_initctx(ctx, &ttyctx, 0); |
tty_write(tty_cmd_utf8character, &ttyctx); |
tty_write(tty_cmd_utf8character, &ttyctx); |
} |
} |
|
|
* If the new character is UTF-8 wide, fill in padding cells. Have |
* If the new character is UTF-8 wide, fill in padding cells. Have |
* already ensured there is enough room. |
* already ensured there is enough room. |
*/ |
*/ |
for (xx = s->cx + 1; xx < s->cx + width; xx++) { |
memcpy(&tmp_gc, &grid_default_cell, sizeof tmp_gc); |
tmp_gcp = grid_view_get_cell(gd, xx, s->cy); |
tmp_gc.flags |= GRID_FLAG_PADDING; |
if (tmp_gcp != NULL) |
tmp_gc.data.width = 0; |
tmp_gcp->flags |= GRID_FLAG_PADDING; |
for (xx = s->cx + 1; xx < s->cx + width; xx++) |
} |
grid_view_set_cell(gd, xx, s->cy, &tmp_gc); |
|
|
/* Set the cell. */ |
/* Set the cell. */ |
grid_view_set_cell(gd, s->cx, s->cy, gc); |
grid_view_set_cell(gd, s->cx, s->cy, gc); |
|
|
} |
} |
if (screen_check_selection(s, s->cx - width, s->cy)) { |
if (screen_check_selection(s, s->cx - width, s->cy)) { |
memcpy(&tmp_gc, &s->sel.cell, sizeof tmp_gc); |
memcpy(&tmp_gc, &s->sel.cell, sizeof tmp_gc); |
grid_cell_get(gc, &ud); |
utf8_copy(&tmp_gc.data, &gc->data); |
grid_cell_set(&tmp_gc, &ud); |
|
tmp_gc.attr = tmp_gc.attr & ~GRID_ATTR_CHARSET; |
tmp_gc.attr = tmp_gc.attr & ~GRID_ATTR_CHARSET; |
tmp_gc.attr |= gc->attr & GRID_ATTR_CHARSET; |
tmp_gc.attr |= gc->attr & GRID_ATTR_CHARSET; |
tmp_gc.flags = gc->flags & ~(GRID_FLAG_FG256|GRID_FLAG_BG256); |
tmp_gc.flags = gc->flags & ~(GRID_FLAG_FG256|GRID_FLAG_BG256); |
|
|
{ |
{ |
struct screen *s = ctx->s; |
struct screen *s = ctx->s; |
struct grid *gd = s->grid; |
struct grid *gd = s->grid; |
struct grid_cell *gc; |
struct grid_cell gc; |
struct utf8_data ud1; |
|
|
|
/* Can't combine if at 0. */ |
/* Can't combine if at 0. */ |
if (s->cx == 0) |
if (s->cx == 0) |
|
|
fatalx("UTF-8 data empty"); |
fatalx("UTF-8 data empty"); |
|
|
/* Retrieve the previous cell. */ |
/* Retrieve the previous cell. */ |
gc = grid_view_get_cell(gd, s->cx - 1, s->cy); |
grid_view_get_cell(gd, s->cx - 1, s->cy, &gc); |
grid_cell_get(gc, &ud1); |
|
|
|
/* Check there is enough space. */ |
/* Check there is enough space. */ |
if (ud1.size + ud->size > sizeof ud1.data) |
if (gc.data.size + ud->size > sizeof gc.data.data) |
return (-1); |
return (-1); |
|
|
/* Append the data and set the cell. */ |
/* Append the data. */ |
memcpy(ud1.data + ud1.size, ud->data, ud->size); |
memcpy(gc.data.data + gc.data.size, ud->data, ud->size); |
ud1.size += ud->size; |
gc.data.size += ud->size; |
grid_cell_set(gc, &ud1); |
|
|
|
|
/* Set the new cell. */ |
|
grid_view_set_cell(gd, s->cx - 1, s->cy, &gc); |
|
|
return (0); |
return (0); |
} |
} |
|
|
|
|
{ |
{ |
struct screen *s = ctx->s; |
struct screen *s = ctx->s; |
struct grid *gd = s->grid; |
struct grid *gd = s->grid; |
const struct grid_cell *gc; |
struct grid_cell gc; |
u_int xx; |
u_int xx; |
|
|
gc = grid_view_peek_cell(gd, s->cx, s->cy); |
grid_view_get_cell(gd, s->cx, s->cy, &gc); |
if (gc->flags & GRID_FLAG_PADDING) { |
if (gc.flags & GRID_FLAG_PADDING) { |
/* |
/* |
* A padding cell, so clear any following and leading padding |
* A padding cell, so clear any following and leading padding |
* cells back to the character. Don't overwrite the current |
* cells back to the character. Don't overwrite the current |
|
|
*/ |
*/ |
xx = s->cx + 1; |
xx = s->cx + 1; |
while (--xx > 0) { |
while (--xx > 0) { |
gc = grid_view_peek_cell(gd, xx, s->cy); |
grid_view_get_cell(gd, xx, s->cy, &gc); |
if (!(gc->flags & GRID_FLAG_PADDING)) |
if (~gc.flags & GRID_FLAG_PADDING) |
break; |
break; |
grid_view_set_cell(gd, xx, s->cy, &grid_default_cell); |
grid_view_set_cell(gd, xx, s->cy, &grid_default_cell); |
} |
} |
|
|
*/ |
*/ |
xx = s->cx + width - 1; |
xx = s->cx + width - 1; |
while (++xx < screen_size_x(s)) { |
while (++xx < screen_size_x(s)) { |
gc = grid_view_peek_cell(gd, xx, s->cy); |
grid_view_get_cell(gd, xx, s->cy, &gc); |
if (!(gc->flags & GRID_FLAG_PADDING)) |
if (~gc.flags & GRID_FLAG_PADDING) |
break; |
break; |
grid_view_set_cell(gd, xx, s->cy, &grid_default_cell); |
grid_view_set_cell(gd, xx, s->cy, &grid_default_cell); |
} |
} |