From 1fefd62fee50d4455ef5ebf65e22b282d773ed7d Mon Sep 17 00:00:00 2001 From: Sven Schnelle Date: Mon, 28 Nov 2022 19:55:57 +0100 Subject: [PATCH] s390/tty3270: split up tty3270_convert_line() To make the code easier to read, split up tty3270_convertline() into several subfunctions: - tty3270_resize_line() to realloc the line if it doesn't have enough space left - tty3270_required_length() to calculate how much space we need - tty3270_add_attributes() to add the color and highlight attributes - tty3270_add_reset_attributes() to reset the attributes at the end of the line Signed-off-by: Sven Schnelle Acked-by: Heiko Carstens Tested-by: Niklas Schnelle Signed-off-by: Heiko Carstens --- drivers/s390/char/con3270.c | 169 +++++++++++++++++++++--------------- 1 file changed, 97 insertions(+), 72 deletions(-) diff --git a/drivers/s390/char/con3270.c b/drivers/s390/char/con3270.c index 61c73eb2471f..f4e7ac406511 100644 --- a/drivers/s390/char/con3270.c +++ b/drivers/s390/char/con3270.c @@ -1101,6 +1101,18 @@ static char tty3270_graphics_translate(struct tty3270 *tp, char ch) } } +static struct string *tty3270_resize_line(struct tty3270 *tp, struct string *s, int newlen) +{ + struct string *n = tty3270_alloc_string(tp, newlen); + + list_add(&n->list, &s->list); + list_del_init(&s->list); + if (!list_empty(&s->update)) + list_del_init(&s->update); + free_string(&tp->freemem, s); + return n; +} + /* * Insert character into the screen at the current position with the * current color and highlight. This function does NOT do cursor movement. @@ -1128,26 +1140,19 @@ static void tty3270_put_character(struct tty3270 *tp, char ch) cell->attributes = tp->attributes; } -/* - * Convert a tty3270_line to a 3270 data fragment usable for output. - */ -static void tty3270_convert_line(struct tty3270 *tp, int line_nr) +static int tty3270_required_length(struct tty3270 *tp, int line_nr) { + unsigned char f_color, b_color, highlight; struct tty3270_line *line; struct tty3270_cell *cell; - struct string *s, *n; - unsigned char highlight; - unsigned char f_color, b_color; - char *cp; - int flen, i; + int i, flen = 3; /* Prefix (TO_SBA). */ - /* Determine how long the fragment will be. */ - flen = 3; /* Prefix (TO_SBA). */ line = tp->screen + line_nr; flen += line->len; highlight = TAX_RESET; f_color = TAC_RESET; b_color = TAC_RESET; + for (i = 0, cell = line->cells; i < line->len; i++, cell++) { if (cell->attributes.highlight != highlight) { flen += 3; /* TO_SA to switch highlight. */ @@ -1173,69 +1178,23 @@ static void tty3270_convert_line(struct tty3270 *tp, int line_nr) if (line->len < tp->view.cols) flen += 4; /* Postfix (TO_RA). */ - /* Find the line in the list. */ - i = tp->view.rows - 2 - line_nr; - list_for_each_entry_reverse(s, &tp->lines, list) - if (--i <= 0) - break; - /* - * Check if the line needs to get reallocated. - */ - if (s->len != flen) { - /* Reallocate string. */ - n = tty3270_alloc_string(tp, flen); - list_add(&n->list, &s->list); - list_del_init(&s->list); - if (!list_empty(&s->update)) - list_del_init(&s->update); - free_string(&tp->freemem, s); - s = n; - } + return flen; +} - /* Write 3270 data fragment. */ - cp = s->string; - *cp++ = TO_SBA; - *cp++ = 0; - *cp++ = 0; - - highlight = TAX_RESET; - f_color = TAC_RESET; - b_color = TAC_RESET; - for (i = 0, cell = line->cells; i < line->len; i++, cell++) { - if (cell->attributes.highlight != highlight) { - *cp++ = TO_SA; - *cp++ = TAT_EXTHI; - *cp++ = cell->attributes.highlight; - highlight = cell->attributes.highlight; - } - if (cell->attributes.f_color != f_color) { - *cp++ = TO_SA; - *cp++ = TAT_FGCOLOR; - *cp++ = cell->attributes.f_color; - f_color = cell->attributes.f_color; - } - if (cell->attributes.b_color != b_color) { - *cp++ = TO_SA; - *cp++ = TAT_BGCOLOR; - *cp++ = cell->attributes.b_color; - b_color = cell->attributes.b_color; - } - if (cell->attributes.alternate_charset) - *cp++ = TO_GE; - - *cp++ = cell->character; - } - if (highlight != TAX_RESET) { +static char *tty3270_add_reset_attributes(struct tty3270 *tp, struct tty3270_line *line, + char *cp, struct tty3270_attribute *attr) +{ + if (attr->highlight != TAX_RESET) { *cp++ = TO_SA; *cp++ = TAT_EXTHI; *cp++ = TAX_RESET; } - if (f_color != TAC_RESET) { + if (attr->f_color != TAC_RESET) { *cp++ = TO_SA; *cp++ = TAT_FGCOLOR; *cp++ = TAC_RESET; } - if (b_color != TAC_RESET) { + if (attr->b_color != TAC_RESET) { *cp++ = TO_SA; *cp++ = TAT_BGCOLOR; *cp++ = TAC_RESET; @@ -1246,7 +1205,80 @@ static void tty3270_convert_line(struct tty3270 *tp, int line_nr) *cp++ = 0; *cp++ = 0; } + return cp; +} +static char *tty3270_add_attributes(struct tty3270_line *line, struct tty3270_attribute *attr, + char *cp) +{ + struct tty3270_cell *cell; + int i; + + *cp++ = TO_SBA; + *cp++ = 0; + *cp++ = 0; + + for (i = 0, cell = line->cells; i < line->len; i++, cell++) { + if (cell->attributes.highlight != attr->highlight) { + *cp++ = TO_SA; + *cp++ = TAT_EXTHI; + *cp++ = cell->attributes.highlight; + attr->highlight = cell->attributes.highlight; + } + if (cell->attributes.f_color != attr->f_color) { + *cp++ = TO_SA; + *cp++ = TAT_FGCOLOR; + *cp++ = cell->attributes.f_color; + attr->f_color = cell->attributes.f_color; + } + if (cell->attributes.b_color != attr->b_color) { + *cp++ = TO_SA; + *cp++ = TAT_BGCOLOR; + *cp++ = cell->attributes.b_color; + attr->b_color = cell->attributes.b_color; + } + if (cell->attributes.alternate_charset) + *cp++ = TO_GE; + *cp++ = cell->character; + } + return cp; +} + +static void tty3270_reset_attributes(struct tty3270_attribute *attr) +{ + attr->highlight = TAX_RESET; + attr->f_color = TAC_RESET; + attr->b_color = TAC_RESET; +} + +/* + * Convert a tty3270_line to a 3270 data fragment usable for output. + */ +static void tty3270_convert_line(struct tty3270 *tp, int line_nr) +{ + struct tty3270_line *line = tp->screen + line_nr; + struct tty3270_attribute attr; + struct string *s; + int flen, i; + char *cp; + + /* Determine how long the fragment will be. */ + flen = tty3270_required_length(tp, line_nr); + /* Find the line in the list. */ + i = tp->view.rows - 2 - line_nr; + list_for_each_entry_reverse(s, &tp->lines, list) + if (--i <= 0) + break; + /* + * Check if the line needs to get reallocated. + */ + if (s->len != flen) + s = tty3270_resize_line(tp, s, flen); + + /* Write 3270 data fragment. */ + tty3270_reset_attributes(&attr); + cp = tty3270_add_attributes(line, &attr, s->string); + cp = tty3270_add_reset_attributes(tp, line, cp, &attr); if (tp->nr_up + line_nr < tp->view.rows - 2) { /* Line is currently visible on screen. */ tty3270_update_string(tp, s, line_nr); @@ -1297,13 +1329,6 @@ static void tty3270_ri(struct tty3270 *tp) } } -static void tty3270_reset_attributes(struct tty3270_attribute *attr) -{ - attr->highlight = TAX_RESET; - attr->f_color = TAC_RESET; - attr->b_color = TAC_RESET; -} - static void tty3270_reset_cell(struct tty3270 *tp, struct tty3270_cell *cell) { cell->character = tp->view.ascebc[' '];