/* Get cell for reading. */ void grid_get_cell(struct grid *gd, u_int px, u_int py, struct grid_cell *gc) { struct grid_line *gl; struct grid_cell_entry *gce; if (grid_check_y(gd, py) != 0 || px >= gd->linedata[py].cellsize) { memcpy(gc, &grid_default_cell, sizeof *gc); return; } gl = &gd->linedata[py]; gce = &gl->celldata[px]; if (gce->flags & GRID_FLAG_EXTENDED) { if (gce->offset >= gl->extdsize) memcpy(gc, &grid_default_cell, sizeof *gc); else memcpy(gc, &gl->extddata[gce->offset], sizeof *gc); return; } gc->flags = gce->flags & ~(GRID_FLAG_FG256|GRID_FLAG_BG256); gc->attr = gce->data.attr; gc->fg = gce->data.fg; if (gce->flags & GRID_FLAG_FG256) gc->fg |= COLOUR_FLAG_256; gc->bg = gce->data.bg; if (gce->flags & GRID_FLAG_BG256) gc->bg |= COLOUR_FLAG_256; utf8_set(&gc->data, gce->data.data); }
/* VT100 alignment test. */ void screen_write_alignmenttest(struct screen_write_ctx *ctx) { struct screen *s = ctx->s; struct tty_ctx ttyctx; struct grid_cell gc; u_int xx, yy; u_int sx = screen_size_x(s), sy = screen_size_y(s); screen_write_initctx(ctx, &ttyctx); screen_dirty_clear(s, 0, 0, sx - 1, sy - 1); memcpy(&gc, &grid_default_cell, sizeof gc); utf8_set(&gc.data, 'E'); for (yy = 0; yy < screen_size_y(s); yy++) { for (xx = 0; xx < screen_size_x(s); xx++) grid_view_set_cell(s->grid, xx, yy, &gc); } s->cx = 0; s->cy = 0; s->rupper = 0; s->rlower = screen_size_y(s) - 1; tty_write(tty_cmd_alignmenttest, &ttyctx); }
/* Set cells at relative position. */ void grid_set_cells(struct grid *gd, u_int px, u_int py, const struct grid_cell *gc, const char *s, size_t slen) { struct grid_line *gl; struct grid_cell_entry *gce; struct grid_cell *gcp; u_int i; if (grid_check_y(gd, __func__, py) != 0) return; grid_expand_line(gd, py, px + slen, 8); gl = &gd->linedata[py]; if (px + slen > gl->cellused) gl->cellused = px + slen; for (i = 0; i < slen; i++) { gce = &gl->celldata[px + i]; if (grid_need_extended_cell(gce, gc)) { gcp = grid_extended_cell(gl, gce, gc); utf8_set(&gcp->data, s[i]); } else grid_store_cell(gce, gc, s[i]); } }
/* * Convert a string into a buffer of UTF-8 characters. Terminated by size == 0. * Caller frees. */ struct utf8_data * utf8_fromcstr(const char *src) { struct utf8_data *dst; size_t n; enum utf8_state more; dst = NULL; n = 0; while (*src != '\0') { dst = xreallocarray(dst, n + 1, sizeof *dst); if ((more = utf8_open(&dst[n], *src)) == UTF8_MORE) { while (*++src != '\0' && more == UTF8_MORE) more = utf8_append(&dst[n], *src); if (more == UTF8_DONE) { n++; continue; } src -= dst[n].have; } utf8_set(&dst[n], *src); n++; src++; } dst = xreallocarray(dst, n + 1, sizeof *dst); dst[n].size = 0; return (dst); }
/* Write character. */ void screen_write_putc(struct screen_write_ctx *ctx, struct grid_cell *gc, u_char ch) { utf8_set(&gc->data, ch); screen_write_cell(ctx, gc); }
/* Write character. */ void screen_write_putc(struct screen_write_ctx *ctx, const struct grid_cell *gcp, u_char ch) { struct grid_cell gc; memcpy(&gc, gcp, sizeof gc); utf8_set(&gc.data, ch); screen_write_cell(ctx, &gc); }
/* Get cell from line. */ static void grid_get_cell1(struct grid_line *gl, u_int px, struct grid_cell *gc) { struct grid_cell_entry *gce = &gl->celldata[px]; if (gce->flags & GRID_FLAG_EXTENDED) { if (gce->offset >= gl->extdsize) memcpy(gc, &grid_default_cell, sizeof *gc); else memcpy(gc, &gl->extddata[gce->offset], sizeof *gc); return; } gc->flags = gce->flags & ~(GRID_FLAG_FG256|GRID_FLAG_BG256); gc->attr = gce->data.attr; gc->fg = gce->data.fg; if (gce->flags & GRID_FLAG_FG256) gc->fg |= COLOUR_FLAG_256; gc->bg = gce->data.bg; if (gce->flags & GRID_FLAG_BG256) gc->bg |= COLOUR_FLAG_256; utf8_set(&gc->data, gce->data.data); }