summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2014-09-16 14:30:28 -0400
committerJesse Luehrs <doy@tozt.net>2014-09-16 14:30:28 -0400
commit4203efb8c5b868c748ff939c9f85506bb01e6a5a (patch)
tree8c0fab1629a1f0197a2f0e7a625b8d12890ef6db
parentd469943454fc36add1ea6dd78d6fc4d963753761 (diff)
downloadlibvt100-4203efb8c5b868c748ff939c9f85506bb01e6a5a.tar.gz
libvt100-4203efb8c5b868c748ff939c9f85506bb01e6a5a.zip
split get_string into get_string_plaintext and get_string_formatted
-rw-r--r--src/screen.c235
-rw-r--r--src/screen.h5
2 files changed, 167 insertions, 73 deletions
diff --git a/src/screen.c b/src/screen.c
index c2acc43..1fc4edf 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -6,6 +6,12 @@
#include "vt100.h"
#include "parser.h"
+static void vt100_screen_get_string(
+ VT100Screen *vt, struct vt100_loc *start, struct vt100_loc *end,
+ char **strp, size_t *lenp, int formatted);
+static void vt100_screen_push_string(char **strp, size_t *lenp,
+ size_t *capacity, char *append,
+ size_t append_len);
static void vt100_screen_ensure_capacity(VT100Screen *vt, int size);
static struct vt100_row *vt100_screen_row_at(VT100Screen *vt, int row);
static void vt100_screen_scroll_down(VT100Screen *vt, int count);
@@ -107,82 +113,18 @@ int vt100_screen_process_string(VT100Screen *vt, char *buf, size_t len)
return len - remaining;
}
-void vt100_screen_get_string(
+void vt100_screen_get_string_formatted(
VT100Screen *vt, struct vt100_loc *start, struct vt100_loc *end,
char **strp, size_t *lenp)
{
- int row, col;
- size_t capacity = 8;
-
- *lenp = 0;
-
- if (end->row < start->row || (end->row == start->row && end->col <= start->col)) {
- return;
- }
-
- *strp = malloc(capacity);
-
- for (row = start->row; row <= end->row; ++row) {
- int start_col, end_col, max_col;
- struct vt100_row *grid_row = &vt->grid->rows[row];
-
- max_col = vt100_screen_row_max_col(vt, row);
-
- if (row == start->row) {
- if (start->col > max_col) {
- start_col = vt->grid->max.col;
- }
- else {
- start_col = start->col;
- }
- }
- else {
- start_col = 0;
- }
-
- if (row == end->row) {
- if (end->col > max_col) {
- end_col = vt->grid->max.col;
- }
- else {
- end_col = end->col;
- }
- }
- else {
- end_col = vt->grid->max.col;
- }
-
- if (end_col > max_col) {
- end_col = max_col;
- }
-
- for (col = start_col; col < end_col; ++col) {
- struct vt100_cell *cell = &grid_row->cells[col];
- char *contents = cell->contents;
- size_t len = cell->len;
-
- if (cell->len == 0) {
- contents = " ";
- len = 1;
- }
-
- if (*lenp + len > capacity) {
- capacity *= 1.5;
- *strp = realloc(*strp, capacity);
- }
- memcpy(*strp + *lenp, contents, len);
- *lenp += len;
- }
+ vt100_screen_get_string(vt, start, end, strp, lenp, 1);
+}
- if ((row != end->row || end->col > max_col) && !grid_row->wrapped) {
- if (*lenp + 1 > capacity) {
- capacity *= 1.5;
- *strp = realloc(*strp, capacity);
- }
- memcpy(*strp + *lenp, "\n", 1);
- *lenp += 1;
- }
- }
+void vt100_screen_get_string_plaintext(
+ VT100Screen *vt, struct vt100_loc *start, struct vt100_loc *end,
+ char **strp, size_t *lenp)
+{
+ vt100_screen_get_string(vt, start, end, strp, lenp, 0);
}
struct vt100_cell *vt100_screen_cell_at(VT100Screen *vt, int row, int col)
@@ -792,6 +734,155 @@ void vt100_screen_delete(VT100Screen *vt)
free(vt);
}
+static void vt100_screen_get_string(
+ VT100Screen *vt, struct vt100_loc *start, struct vt100_loc *end,
+ char **strp, size_t *lenp, int formatted)
+{
+ int row, col;
+ size_t capacity = 8;
+ struct vt100_cell_attrs attrs;
+
+ memset(&attrs, 0, sizeof(struct vt100_cell_attrs));
+
+ *lenp = 0;
+
+ if (end->row < start->row || (end->row == start->row && end->col <= start->col)) {
+ return;
+ }
+
+ *strp = malloc(capacity);
+
+ for (row = start->row; row <= end->row; ++row) {
+ int start_col, end_col, max_col;
+ struct vt100_row *grid_row = &vt->grid->rows[row];
+
+ max_col = vt100_screen_row_max_col(vt, row);
+
+ if (row == start->row) {
+ if (start->col > max_col) {
+ start_col = vt->grid->max.col;
+ }
+ else {
+ start_col = start->col;
+ }
+ }
+ else {
+ start_col = 0;
+ }
+
+ if (row == end->row) {
+ if (end->col > max_col) {
+ end_col = vt->grid->max.col;
+ }
+ else {
+ end_col = end->col;
+ }
+ }
+ else {
+ end_col = vt->grid->max.col;
+ }
+
+ if (end_col > max_col) {
+ end_col = max_col;
+ }
+
+ for (col = start_col; col < end_col; ++col) {
+ struct vt100_cell *cell = &grid_row->cells[col];
+ char *contents = cell->contents;
+ size_t len = cell->len;
+
+ if (formatted
+ && memcmp(&attrs, &cell->attrs,
+ sizeof(struct vt100_cell_attrs))) {
+ int attr_codes[6] = { 0 };
+ int first = 1;
+ size_t i;
+
+ if (attrs.fgcolor.id != cell->attrs.fgcolor.id) {
+ switch (cell->attrs.fgcolor.type) {
+ case VT100_COLOR_DEFAULT:
+ attr_codes[0] = 39;
+ break;
+ case VT100_COLOR_IDX:
+ attr_codes[0] = 30 + cell->attrs.fgcolor.idx;
+ break;
+ case VT100_COLOR_RGB:
+ // XXX
+ break;
+ }
+ }
+ if (attrs.bgcolor.id != cell->attrs.bgcolor.id) {
+ switch (cell->attrs.bgcolor.type) {
+ case VT100_COLOR_DEFAULT:
+ attr_codes[1] = 49;
+ break;
+ case VT100_COLOR_IDX:
+ attr_codes[1] = 40 + cell->attrs.bgcolor.idx;
+ break;
+ case VT100_COLOR_RGB:
+ // XXX
+ break;
+ }
+ }
+ if (attrs.bold != cell->attrs.bold) {
+ attr_codes[2] = cell->attrs.bold ? 1 : 21;
+ }
+ if (attrs.italic != cell->attrs.italic) {
+ attr_codes[3] = cell->attrs.italic ? 3 : 23;
+ }
+ if (attrs.underline != cell->attrs.underline) {
+ attr_codes[4] = cell->attrs.underline ? 4 : 24;
+ }
+ if (attrs.inverse != cell->attrs.inverse) {
+ attr_codes[5] = cell->attrs.inverse ? 7 : 27;
+ }
+ vt100_screen_push_string(strp, lenp, &capacity, "\e[", 2);
+ for (i = 0; i < sizeof(attr_codes) / sizeof(int); ++i) {
+ char buf[3];
+
+ if (!attr_codes[i]) {
+ continue;
+ }
+
+ if (!first) {
+ vt100_screen_push_string(strp, lenp, &capacity, ";", 1);
+ }
+ sprintf(buf, "%d", attr_codes[i]);
+ vt100_screen_push_string(strp, lenp, &capacity, buf,
+ strlen(buf));
+
+ first = 0;
+ }
+ vt100_screen_push_string(strp, lenp, &capacity, "m", 1);
+ memcpy(&attrs, &cell->attrs, sizeof(struct vt100_cell_attrs));
+ }
+
+ if (cell->len == 0) {
+ contents = " ";
+ len = 1;
+ }
+
+ vt100_screen_push_string(strp, lenp, &capacity, contents, len);
+ }
+
+ if ((row != end->row || end->col > max_col) && !grid_row->wrapped) {
+ vt100_screen_push_string(strp, lenp, &capacity, "\n", 1);
+ }
+ }
+}
+
+static void vt100_screen_push_string(char **strp, size_t *lenp,
+ size_t *capacity, char *append,
+ size_t append_len)
+{
+ if (*lenp + append_len > *capacity) {
+ *capacity *= 1.5;
+ *strp = realloc(*strp, *capacity);
+ }
+ memcpy(*strp + *lenp, append, append_len);
+ *lenp += append_len;
+}
+
static void vt100_screen_ensure_capacity(VT100Screen *vt, int size)
{
int old_capacity = vt->grid->row_capacity;
diff --git a/src/screen.h b/src/screen.h
index b6d1ab5..16cfc70 100644
--- a/src/screen.h
+++ b/src/screen.h
@@ -120,7 +120,10 @@ void vt100_screen_set_window_size(VT100Screen *vt, int rows, int cols);
void vt100_screen_set_scrollback_length(VT100Screen *vt, int rows);
int vt100_screen_process_string(VT100Screen *vt, char *buf, size_t len);
int vt100_screen_loc_is_selected(VT100Screen *vt, struct vt100_loc loc);
-void vt100_screen_get_string(
+void vt100_screen_get_string_plaintext(
+ VT100Screen *vt, struct vt100_loc *start, struct vt100_loc *end,
+ char **strp, size_t *lenp);
+void vt100_screen_get_string_formatted(
VT100Screen *vt, struct vt100_loc *start, struct vt100_loc *end,
char **strp, size_t *lenp);
struct vt100_cell *vt100_screen_cell_at(VT100Screen *vt, int row, int col);