efi_loader: query serial console size reliably

Not all terminals understand CSI [18t for querying the console size.
We should adhere to escape sequences documented in the console_codes
manpage and the ECMA-48 standard.

So here we follow a different approach. We position the cursor to the
bottom right and query its position. Before leaving the function we
restore the original cursor position.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
This commit is contained in:
Heinrich Schuchardt 2018-09-15 23:52:07 +02:00 committed by Alexander Graf
parent 7b05667ce2
commit 6bb591f704

View file

@ -185,32 +185,56 @@ static bool cout_mode_matches(struct cout_mode *mode, int rows, int cols)
return (mode->rows == rows) && (mode->columns == cols); return (mode->rows == rows) && (mode->columns == cols);
} }
/**
* query_console_serial() - query console size
*
* @rows pointer to return number of rows
* @columns pointer to return number of columns
* Returns 0 on success
*/
static int query_console_serial(int *rows, int *cols) static int query_console_serial(int *rows, int *cols)
{ {
/* Ask the terminal about its size */ int ret = 0;
int n[3]; int n[2];
u64 timeout; u64 timeout;
/* Empty input buffer */ /* Empty input buffer */
while (tstc()) while (tstc())
getc(); getc();
printf(ESC"[18t"); /*
* Not all terminals understand CSI [18t for querying the console size.
* We should adhere to escape sequences documented in the console_codes
* manpage and the ECMA-48 standard.
*
* So here we follow a different approach. We position the cursor to the
* bottom right and query its position. Before leaving the function we
* restore the original cursor position.
*/
printf(ESC "7" /* Save cursor position */
ESC "[r" /* Set scrolling region to full window */
ESC "[999;999H" /* Move to bottom right corner */
ESC "[6n"); /* Query cursor position */
/* Check if we have a terminal that understands */ /* Allow up to one second for a response */
timeout = timer_get_us() + 1000000; timeout = timer_get_us() + 1000000;
while (!tstc()) while (!tstc())
if (timer_get_us() > timeout) if (timer_get_us() > timeout) {
return -1; ret = -1;
goto out;
}
/* Read {depth,rows,cols} */ /* Read {rows,cols} */
if (term_read_reply(n, 3, 't')) if (term_read_reply(n, 2, 'R')) {
return -1; ret = 1;
goto out;
}
*cols = n[2]; *cols = n[1];
*rows = n[1]; *rows = n[0];
out:
return 0; printf(ESC "8"); /* Restore cursor position */
return ret;
} }
/* /*