From dd7cf89f5b61745f41356a40ec2c5737bb703e45 Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Wed, 18 Sep 2002 02:42:08 +0000 Subject: 2002-09-18 Marcus Brinkmann * hurd.ti: Change and to escape bracket right-angle sequences. Add , , and , disable . * display.c (handle_esc_bracket_m): Map \E[21m to normal intensity (as a way to switch off bright intensity). (handle_esc_bracket): Fix calculation of fill area for . (struct scrolling_region): New type. (struct display): New members INSERT_MODE and CSR. (display_output_one): For , also reset DISPLAY->insert_mode and DISPLAY->csr. (display_create): Initialize DISPLAY->csr.bottom. (display_output_one): If in insert mode, shift to the right before printing the character. (linefeed): Take scrolling region into account. (handle_esc_bracket): Switch the meaning of 'h' and 'l'. (handle_esc_bracket_question): Likewise. (handle_esc_bracket_question_hl): Switch the interpretation of FLAG. (handle_esc_bracket_hl): Likewise. Add support for insert mode and . (struct parse): New state STATE_ESC_BRACKET_RIGHT_ANGLE. (display_output_one): Handle STATE_ESC_BRACKET_RIGHT_ANGLE. (display_output_one): Move the bold attribute handling from here (, ) ... (handle_esc_bracket_right_angle_hl): ... to here. New function handling and . (handle_esc_bracket_right_angle): New function. (handle_esc_bracket): Implement . --- console/ChangeLog | 31 +++++++++ console/display.c | 200 +++++++++++++++++++++++++++++++++++++++++++----------- console/hurd.ti | 21 +++--- 3 files changed, 204 insertions(+), 48 deletions(-) diff --git a/console/ChangeLog b/console/ChangeLog index bb28d0d4..6d6a3b72 100644 --- a/console/ChangeLog +++ b/console/ChangeLog @@ -1,3 +1,34 @@ +2002-09-18 Marcus Brinkmann + + * hurd.ti: Change and to escape bracket + right-angle sequences. Add , , and , + disable . + * display.c (handle_esc_bracket_m): Map \E[21m to normal intensity + (as a way to switch off bright intensity). + (handle_esc_bracket): Fix calculation of fill area for . + (struct scrolling_region): New type. + (struct display): New members INSERT_MODE and CSR. + (display_output_one): For , also reset DISPLAY->insert_mode + and DISPLAY->csr. + (display_create): Initialize DISPLAY->csr.bottom. + (display_output_one): If in insert mode, shift to the right before + printing the character. + (linefeed): Take scrolling region into account. + (handle_esc_bracket): Switch the meaning of 'h' and 'l'. + (handle_esc_bracket_question): Likewise. + (handle_esc_bracket_question_hl): Switch the interpretation of + FLAG. + (handle_esc_bracket_hl): Likewise. Add support for insert mode + and . + (struct parse): New state STATE_ESC_BRACKET_RIGHT_ANGLE. + (display_output_one): Handle STATE_ESC_BRACKET_RIGHT_ANGLE. + (display_output_one): Move the bold attribute handling from here + (, ) ... + (handle_esc_bracket_right_angle_hl): ... to here. New function + handling and . + (handle_esc_bracket_right_angle): New function. + (handle_esc_bracket): Implement . + 2002-09-17 Marcus Brinkmann * input.c (input_enqueue): Initialize ERR. diff --git a/console/display.c b/console/display.c index 1001268c..566b9c3f 100644 --- a/console/display.c +++ b/console/display.c @@ -85,6 +85,12 @@ struct cursor }; typedef struct cursor *cursor_t; +struct scrolling_region +{ + uint32_t top; + uint32_t bottom; +}; + struct parse { /* The parsing state of output characters, needed to handle escape @@ -96,7 +102,8 @@ struct parse STATE_ESC, STATE_ESC_BRACKET_INIT, STATE_ESC_BRACKET, - STATE_ESC_BRACKET_QUESTION + STATE_ESC_BRACKET_QUESTION, + STATE_ESC_BRACKET_RIGHT_ANGLE } state; /* How many parameters an escape sequence may have. */ @@ -171,11 +178,21 @@ struct display signal for this virtual console. */ int owner_id; + /* The pending changes. */ struct changes changes; + /* The state of the virtual console. */ + /* The saved cursor position. */ struct cursor cursor; + /* The output queue and parser state. */ struct output output; + /* The current video attributes. */ struct attr attr; + /* Non-zero if we are in insert mode. */ + int insert_mode; + /* Scrolling region. */ + struct scrolling_region csr; + struct cons_display *user; struct user_pager_info *upi; @@ -971,12 +988,16 @@ handle_esc_bracket_hl (display_t display, int code, int flag) { switch (code) { + case 4: /* ECMA-48 , . */ + /* Insert mode: , . */ + display->insert_mode = flag ? 1 : 0; + break; case 34: /* Cursor standout: , . */ if (flag) - display->user->cursor.status = CONS_CURSOR_VERY_VISIBLE; - else display->user->cursor.status = CONS_CURSOR_NORMAL; + else + display->user->cursor.status = CONS_CURSOR_VERY_VISIBLE; /* XXX Flag cursor status change. */ break; } @@ -1028,8 +1049,12 @@ handle_esc_bracket_m (attr_t attr, int code) /* Alternate character set mode on: . */ attr->altchar = 1; break; + case 21: + /* Normal intensity (switch off bright). */ + attr->current.intensity = CONS_ATTR_INTENSITY_NORMAL; + break; case 22: - /* Normal intensity. */ + /* Normal intensity (switch off dim). */ attr->current.intensity = CONS_ATTR_INTENSITY_NORMAL; break; case 23: @@ -1095,24 +1120,44 @@ linefeed (display_t display) { struct cons_display *user = display->user; - if (user->cursor.row < user->screen.height - 1) + if (display->csr.top == 0 && display->csr.bottom >= user->screen.height - 1) { - user->cursor.row++; - /* XXX Flag cursor update. */ + /* No scrolling region active, do the normal scrolling activity. */ + if (user->cursor.row < user->screen.height - 1) + { + user->cursor.row++; + /* XXX Flag cursor update. */ + } + else + { + user->screen.cur_line++; + + screen_fill (display, 0, user->screen.height - 1, + user->screen.width - 1, user->screen.height - 1, + L' ', display->attr.current); + if (user->screen.scr_lines < + user->screen.lines - user->screen.height) + user->screen.scr_lines++; + /* XXX Flag current line change. */ + /* XXX Possibly flag change of length of scroll back buffer. */ + } } else { - user->screen.cur_line++; - - screen_fill (display, 0, user->screen.height - 1, - user->screen.width - 1, user->screen.height - 1, - L' ', display->attr.current); - if (user->screen.scr_lines < - user->screen.lines - user->screen.height) - user->screen.scr_lines++; - /* XXX Flag current line change. */ - /* XXX Possibly flag change of length of scroll back buffer. */ - } + /* With an active scrolling region, never actually scroll. Just + shift the scrolling region if necessary. */ + if (user->cursor.row != display->csr.bottom + && user->cursor.row < user->screen.height - 1) + { + user->cursor.row++; + /* XXX Flag cursor update. */ + } + else if (user->cursor.row == display->csr.bottom) + screen_shift_left (display, 0, display->csr.top, + user->screen.width - 1, display->csr.bottom, + user->screen.width, + L' ', display->attr.current); + } } static void @@ -1192,12 +1237,12 @@ handle_esc_bracket (display_t display, char op) user->cursor.col -= (parse->params[0] ?: 1); limit_cursor (display); break; - case 'h': + case 'l': /* Reset mode. */ for (i = 0; i < parse->nparams; i++) handle_esc_bracket_hl (display, parse->params[i], 0); break; - case 'l': + case 'h': /* Set mode. */ for (i = 0; i < parse->nparams; i++) handle_esc_bracket_hl (display, parse->params[i], 1); @@ -1280,6 +1325,25 @@ handle_esc_bracket (display_t display, char op) parse->params[0] ?: 1, L' ', display->attr.current); break; + case 'r': /* VT100: Set scrolling region. */ + if (!parse->params[1]) + { + display->csr.top = 0; + display->csr.bottom = user->screen.height - 1; + } + else + { + if (parse->params[1] <= user->screen.height + && parse->params[0] < parse->params[1]) + { + display->csr.top = parse->params[0] ? parse->params[0] - 1 : 0; + display->csr.bottom = parse->params[1] - 1; + user->cursor.col = 0; + user->cursor.row = 0; + /* XXX Flag cursor change. */ + } + } + break; case 'S': /* ECMA-48 . */ /* Scroll up: , . */ screen_shift_left (display, 0, 0, @@ -1296,10 +1360,16 @@ handle_esc_bracket (display_t display, char op) break; case 'X': /* ECMA-48 . */ /* Erase character(s): . */ - screen_fill (display, user->cursor.col, user->cursor.row, - /* XXX limit ? */user->cursor.col + (parse->params[0] ?: 1), - user->cursor.row, - L' ', display->attr.current); + { + int col = user->cursor.col; + if (parse->params[0] - 1 > 0) + col += parse->params[0] - 1; + if (col > user->screen.width - 1) + col = user->screen.width - 1; + + screen_fill (display, user->cursor.col, user->cursor.row, + col, user->cursor.row, L' ', display->attr.current); + } break; case 'I': /* ECMA-48 . */ /* Horizontal tab. */ @@ -1339,6 +1409,7 @@ handle_esc_bracket (display_t display, char op) } } + static void handle_esc_bracket_question_hl (display_t display, int code, int flag) { @@ -1347,9 +1418,9 @@ handle_esc_bracket_question_hl (display_t display, int code, int flag) case 25: /* Cursor invisibility: , . */ if (flag) - display->user->cursor.status = CONS_CURSOR_INVISIBLE; - else display->user->cursor.status = CONS_CURSOR_NORMAL; + else + display->user->cursor.status = CONS_CURSOR_INVISIBLE; /* XXX Flag cursor status change. */ break; } @@ -1364,12 +1435,12 @@ handle_esc_bracket_question (display_t display, char op) int i; switch (op) { - case 'h': + case 'l': /* Reset mode. */ for (i = 0; i < parse->nparams; ++i) handle_esc_bracket_question_hl (display, parse->params[i], 0); break; - case 'l': + case 'h': /* Set mode. */ for (i = 0; i < parse->nparams; ++i) handle_esc_bracket_question_hl (display, parse->params[i], 1); @@ -1377,6 +1448,45 @@ handle_esc_bracket_question (display_t display, char op) } } + +static void +handle_esc_bracket_right_angle_hl (display_t display, int code, int flag) +{ + switch (code) + { + case 1: + /* Bold: , . This is a GNU extension. */ + if (flag) + display->attr.current.bold = 1; + else + display->attr.current.bold = 0; + break; + } +} + + +static void +handle_esc_bracket_right_angle (display_t display, char op) +{ + parse_t parse = &display->output.parse; + + int i; + switch (op) + { + case 'l': + /* Reset mode. */ + for (i = 0; i < parse->nparams; ++i) + handle_esc_bracket_right_angle_hl (display, parse->params[i], 0); + break; + case 'h': + /* Set mode. */ + for (i = 0; i < parse->nparams; ++i) + handle_esc_bracket_right_angle_hl (display, parse->params[i], 1); + break; + } +} + + static wchar_t altchar_to_ucs4 (wchar_t chr) { @@ -1484,8 +1594,7 @@ display_output_one (display_t display, wchar_t chr) user->cursor.col--; else { - /* XXX This implements the functionality. - The alternative is to cut off and set col to 0. */ + /* This implements the functionality. */ user->cursor.col = user->screen.width - 1; user->cursor.row--; } @@ -1512,6 +1621,15 @@ display_output_one (display_t display, wchar_t chr) % user->screen.lines; int idx = line * user->screen.width + user->cursor.col; + if (display->insert_mode + && user->cursor.col != user->screen.width - 1) + { + /* If in insert mode, do the same as . */ + screen_shift_right (display, user->cursor.col, user->cursor.row, + user->screen.width - 1, user->cursor.row, 1, + L' ', display->attr.current); + } + user->_matrix[idx].chr = display->attr.altchar ? altchar_to_ucs4 (chr) : chr; user->_matrix[idx].attr = display->attr.current; @@ -1539,6 +1657,9 @@ display_output_one (display_t display, wchar_t chr) /* Reset: . */ display->attr.current = display->attr.attr_def; display->attr.altchar = 0; + display->insert_mode = 0; + display->csr.top = 0; + display->csr.bottom = user->screen.height - 1; user->cursor.status = CONS_CURSOR_NORMAL; /* Fall through. */ case L'c': @@ -1570,14 +1691,6 @@ display_output_one (display_t display, wchar_t chr) /* Visible bell. */ user->bell.visible++; break; - case L'Q': /* ECMA-48 . */ - /* Bold on: . This is a GNU extension. */ - display->attr.current.bold = 1; - break; - case L'R': /* ECMA-48 . */ - /* Bold off: . This is a GNU extension. */ - display->attr.current.bold = 0; - break; default: /* Unsupported escape sequence. */ break; @@ -1592,11 +1705,17 @@ display_output_one (display_t display, wchar_t chr) parse->state = STATE_ESC_BRACKET_QUESTION; break; /* Consume the question mark. */ } + else if (chr == '>') + { + parse->state = STATE_ESC_BRACKET_RIGHT_ANGLE; + break; /* Consume the right angle. */ + } else parse->state = STATE_ESC_BRACKET; /* Fall through. */ case STATE_ESC_BRACKET: case STATE_ESC_BRACKET_QUESTION: + case STATE_ESC_BRACKET_RIGHT_ANGLE: if (chr >= '0' && chr <= '9') parse->params[parse->nparams] = parse->params[parse->nparams]*10 + chr - '0'; @@ -1610,6 +1729,8 @@ display_output_one (display_t display, wchar_t chr) parse->nparams++; if (parse->state == STATE_ESC_BRACKET) handle_esc_bracket (display, chr); + else if (parse->state == STATE_ESC_BRACKET_RIGHT_ANGLE) + handle_esc_bracket_right_angle (display, chr); else handle_esc_bracket_question (display, chr); parse->state = STATE_NORMAL; @@ -1738,6 +1859,8 @@ display_create (display_t *r_display, const char *encoding, mutex_init (&display->lock); display->attr.attr_def = def_attr; display->attr.current = display->attr.attr_def; + display->csr.bottom = height - 1; + err = user_create (display, width, height, lines, L' ', display->attr.current); if (err) @@ -1919,7 +2042,6 @@ display_output (display_t display, int nonblock, char *data, size_t datalen) errno = err; return err; } - /* XXX What should be done with invalid characters etc? */ if (buffer_size) { /* If we used the caller's buffer DATA, the remaining bytes diff --git a/console/hurd.ti b/console/hurd.ti index ea95fcc4..18c86624 100644 --- a/console/hurd.ti +++ b/console/hurd.ti @@ -19,6 +19,8 @@ hurd|The GNU Hurd console server, # Moving the cursor. # We have automatic margins. am, +# We wrap around the left edge. + bw, # Carriage return and newline. cr=^M, nel=^M^J, # Move cursor to home position (to position P1, P2). @@ -35,9 +37,8 @@ hurd|The GNU Hurd console server, hpa=\E[%i%p1%dG, vpa=\E[%i%p1%dd, # Save (restore) cursor position. sc=\E7, rc=\E8, -# XXX When we support this. # Set the scrolling region to lines P1 to P2. -# csr=\E[%i%p1%d;%p2%dr, + csr=\E[%i%p1%d;%p2%dr, # Modifying cursor attributes. # Make cursor invisible, very visible or normal. @@ -66,13 +67,13 @@ hurd|The GNU Hurd console server, el=\E[K, el1=\E[1K, # Insert one character (P1 characters). -# XXX Don't give this when having insert mode. - ich1=\E[@, ich=\E[%p1%d@, -# XXX When we implement insert mode (smir and rmir) (but don't set ich1 then): +# not included because we have insert mode. +# ich1=\E[@, + ich=\E[%p1%d@, # Enter (leave) insert mode. -# smir=\E[4h, rmir=\E[4l, + smir=\E[4h, rmir=\E[4l, # It is save to move when in insert mode. -# mir, + mir, # Delete one character (P1 characters). dch1=\E[P, dch=\E[%p1%dP, # Erase the next N characters. @@ -95,6 +96,7 @@ hurd|The GNU Hurd console server, # Flash the screen (visible bell). flash=\Eg, + # Keycodes for special keys. # Backspace key. kbs=\177, @@ -136,7 +138,8 @@ hurd|The GNU Hurd console server, # Video attributes colliding with color. # ORed: A_STANDOUT 1, A_UNDERLINE 2, A_REVERSE 4, A_BLINK 8, A_DIM 16, # A_BOLD 32, A_INVIS 64 - ncv#18, +# We do our own display optimization, depending on the display driver. +# ncv#18, # Set background (foreground) color. setab=\E[4%p1%dm, setaf=\E[3%p1%dm, # Set default color pair to its original value. @@ -157,7 +160,7 @@ hurd|The GNU Hurd console server, sitm=\E[3m, ritm=\E[23m, # Enable (disable) real bold (not intensity bright) mode. This is a # GNU extension. - gsbom=\EQ, grbom=\ER, + gsbom=\E[>1h, grbom=\E[>1l, # XXX Linux has those also for rmpch and smpch. # Enable (disable) alternative character set. smacs=\E[11m, rmacs=\E[10m, -- cgit v1.2.3