mirror of
git://sourceware.org/git/newlib-cygwin.git
synced 2025-02-20 16:01:10 +08:00
* DevNotes: Add entry cgf-000024.
* fhandler.h (dev_console::state): Remove trailing underscore. (dev_console::args): Ditto. (dev_console::nargs): Ditto. (dev_console::info): Eliminate subclass. (dev_console::dwEnd): New field. (dev_console::scroll_window): New function. (dev_console::is_fullscreen): Ditto. (dev_console::fillin): Rename from fillin_info. (fhandler_console::scroll_buffer): Rename from scroll_screen. * fhandler_console.cc: Throughout s/dev_state\.info/dev_state/g. Accommodate other name changes. (dev_console::fillin): Accommodate rename. Notice max x/y written to. Forgo memset if GetConsoleScreenBufferInfo fails. (fhandler_console::scroll_buffer): Accommodate rename. Don't treat y coordinate of zero as top of screen. (dev_console::is_fullscreen): New function. (dev_console::scroll_window): Ditto. (fhandler_console::clear_screen): Just scroll the screen when clearing the screen in a state where the screen buffer is bigger than the screen. (fhandler_console::char_command): Try harder to get 'S' and 'T' working in the presence of a screen buffer. Use temporary 'n' variable rather than dev_state.args[0]. Use GNU ?: shortcut method.
This commit is contained in:
parent
f235534904
commit
df2764ef93
@ -1,3 +1,30 @@
|
||||
2014-02-15 Christopher Faylor <me.cygwin2014@cgf.cx>
|
||||
|
||||
* DevNotes: Add entry cgf-000024.
|
||||
* fhandler.h (dev_console::state): Remove trailing underscore.
|
||||
(dev_console::args): Ditto.
|
||||
(dev_console::nargs): Ditto.
|
||||
(dev_console::info): Eliminate subclass.
|
||||
(dev_console::dwEnd): New field.
|
||||
(dev_console::scroll_window): New function.
|
||||
(dev_console::is_fullscreen): Ditto.
|
||||
(dev_console::fillin): Rename from fillin_info.
|
||||
(fhandler_console::scroll_buffer): Rename from scroll_screen.
|
||||
* fhandler_console.cc: Throughout s/dev_state\.info/dev_state/g.
|
||||
Accommodate other name changes.
|
||||
(dev_console::fillin): Accommodate rename. Notice max x/y written to.
|
||||
Forgo memset if GetConsoleScreenBufferInfo fails.
|
||||
(fhandler_console::scroll_buffer): Accommodate rename. Don't treat y
|
||||
coordinate of zero as top of screen.
|
||||
(dev_console::is_fullscreen): New function.
|
||||
(dev_console::scroll_window): Ditto.
|
||||
(fhandler_console::clear_screen): Just scroll the screen when clearing
|
||||
the screen in a state where the screen buffer is bigger than the
|
||||
screen.
|
||||
(fhandler_console::char_command): Try harder to get 'S' and 'T' working
|
||||
in the presence of a screen buffer. Use temporary 'n' variable rather
|
||||
than dev_state.args[0]. Use GNU ?: shortcut method.
|
||||
|
||||
2014-02-14 Christopher Faylor <me.cygwin2014@cgf.cx>
|
||||
|
||||
* pinfo.cc (winpids::add): Always copy pinfo structure when winpid.
|
||||
|
@ -1,3 +1,11 @@
|
||||
2014-02-15 cgf-000024
|
||||
|
||||
Wow. It's hard getting the screen handling stuff working correctly when
|
||||
there is a screen buffer larger than screen size and vice versa. These
|
||||
changes attempt to use SetConsoleWindowInfo whenever possible so that
|
||||
the contents of the screen buffer are never wiped out. They also fix
|
||||
some previously misbehaving "scroll the screen" commands.
|
||||
|
||||
2013-06-07 cgf-000023
|
||||
|
||||
Given the fact that the signal thread never exits there is no need
|
||||
|
@ -1263,9 +1263,9 @@ class dev_console
|
||||
int meta_mask;
|
||||
|
||||
/* Output state */
|
||||
int state_;
|
||||
int args_[MAXARGS];
|
||||
int nargs_;
|
||||
int state;
|
||||
int args[MAXARGS];
|
||||
int nargs;
|
||||
unsigned rarg;
|
||||
bool saw_question_mark;
|
||||
bool saw_greater_than_sign;
|
||||
@ -1295,17 +1295,14 @@ class dev_console
|
||||
{
|
||||
short Top, Bottom;
|
||||
} scroll_region;
|
||||
struct console_attrs
|
||||
{
|
||||
SHORT winTop;
|
||||
SHORT winBottom;
|
||||
COORD dwWinSize;
|
||||
COORD dwBufferSize;
|
||||
COORD dwCursorPosition;
|
||||
WORD wAttributes;
|
||||
int set_cl_x (cltype);
|
||||
int set_cl_y (cltype);
|
||||
} info;
|
||||
|
||||
SHORT winTop;
|
||||
SHORT winBottom;
|
||||
COORD dwWinSize;
|
||||
COORD dwBufferSize;
|
||||
COORD dwCursorPosition;
|
||||
WORD wAttributes;
|
||||
COORD dwEnd;
|
||||
|
||||
COORD dwLastCursorPosition;
|
||||
COORD dwMousePosition; /* scroll-adjusted coord of mouse event */
|
||||
@ -1326,8 +1323,12 @@ class dev_console
|
||||
DWORD con_to_str (char *d, int dlen, WCHAR w);
|
||||
DWORD str_to_con (mbtowc_p, const char *, PWCHAR d, const char *s, DWORD sz);
|
||||
void set_color (HANDLE);
|
||||
bool fillin_info (HANDLE);
|
||||
void set_default_attr ();
|
||||
int set_cl_x (cltype);
|
||||
int set_cl_y (cltype);
|
||||
bool fillin (HANDLE);
|
||||
bool is_fullscreen (int, int, int, int);
|
||||
void scroll_window (HANDLE);
|
||||
|
||||
friend class fhandler_console;
|
||||
};
|
||||
@ -1358,7 +1359,7 @@ private:
|
||||
void set_default_attr ();
|
||||
|
||||
void clear_screen (cltype, cltype, cltype, cltype);
|
||||
void scroll_screen (int, int, int, int, int, int);
|
||||
void scroll_buffer (int, int, int, int, int, int);
|
||||
void cursor_set (bool, int, int);
|
||||
void cursor_get (int *, int *);
|
||||
void cursor_rel (int, int);
|
||||
|
@ -43,8 +43,8 @@ details. */
|
||||
#define CTRL_PRESSED (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)
|
||||
|
||||
#define dev_state (shared_console_info->dev_state)
|
||||
#define srTop (dev_state.info.winTop + dev_state.scroll_region.Top)
|
||||
#define srBottom ((dev_state.scroll_region.Bottom < 0) ? dev_state.info.winBottom : dev_state.info.winTop + dev_state.scroll_region.Bottom)
|
||||
#define srTop (dev_state.winTop + dev_state.scroll_region.Top)
|
||||
#define srBottom ((dev_state.scroll_region.Bottom < 0) ? dev_state.winBottom : dev_state.winTop + dev_state.scroll_region.Bottom)
|
||||
|
||||
const char *get_nonascii_key (INPUT_RECORD&, char *);
|
||||
|
||||
@ -172,7 +172,6 @@ fhandler_console::setup ()
|
||||
{
|
||||
if (set_unit ())
|
||||
{
|
||||
|
||||
dev_state.scroll_region.Bottom = -1;
|
||||
dev_state.dwLastCursorPosition.X = -1;
|
||||
dev_state.dwLastCursorPosition.Y = -1;
|
||||
@ -264,11 +263,11 @@ fhandler_console::set_cursor_maybe ()
|
||||
void
|
||||
fhandler_console::send_winch_maybe ()
|
||||
{
|
||||
SHORT y = dev_state.info.dwWinSize.Y;
|
||||
SHORT x = dev_state.info.dwWinSize.X;
|
||||
dev_state.fillin_info (get_output_handle ());
|
||||
SHORT y = dev_state.dwWinSize.Y;
|
||||
SHORT x = dev_state.dwWinSize.X;
|
||||
dev_state.fillin (get_output_handle ());
|
||||
|
||||
if (y != dev_state.info.dwWinSize.Y || x != dev_state.info.dwWinSize.X)
|
||||
if (y != dev_state.dwWinSize.Y || x != dev_state.dwWinSize.X)
|
||||
{
|
||||
dev_state.scroll_region.Top = 0;
|
||||
dev_state.scroll_region.Bottom = -1;
|
||||
@ -734,27 +733,31 @@ fhandler_console::set_input_state ()
|
||||
}
|
||||
|
||||
bool
|
||||
dev_console::fillin_info (HANDLE h)
|
||||
dev_console::fillin (HANDLE h)
|
||||
{
|
||||
bool ret;
|
||||
CONSOLE_SCREEN_BUFFER_INFO linfo;
|
||||
|
||||
if ((ret = GetConsoleScreenBufferInfo (h, &linfo)))
|
||||
{
|
||||
info.winTop = linfo.srWindow.Top;
|
||||
info.winBottom = linfo.srWindow.Bottom;
|
||||
info.dwWinSize.Y = 1 + linfo.srWindow.Bottom - linfo.srWindow.Top;
|
||||
info.dwWinSize.X = 1 + linfo.srWindow.Right - linfo.srWindow.Left;
|
||||
info.dwBufferSize = linfo.dwSize;
|
||||
info.dwCursorPosition = linfo.dwCursorPosition;
|
||||
info.wAttributes = linfo.wAttributes;
|
||||
winTop = linfo.srWindow.Top;
|
||||
winBottom = linfo.srWindow.Bottom;
|
||||
dwWinSize.Y = 1 + linfo.srWindow.Bottom - linfo.srWindow.Top;
|
||||
dwWinSize.X = 1 + linfo.srWindow.Right - linfo.srWindow.Left;
|
||||
if (dwBufferSize.Y != linfo.dwSize.Y || dwBufferSize.X != linfo.dwSize.X)
|
||||
dwEnd.X = dwEnd.Y = 0;
|
||||
dwBufferSize = linfo.dwSize;
|
||||
dwCursorPosition = linfo.dwCursorPosition;
|
||||
if (dwCursorPosition.Y > dwEnd.Y
|
||||
|| (dwCursorPosition.Y >= dwEnd.Y && dwCursorPosition.X > dwEnd.X))
|
||||
dwEnd = dwCursorPosition;
|
||||
wAttributes = linfo.wAttributes;
|
||||
}
|
||||
else
|
||||
{
|
||||
memset (&info, 0, sizeof info);
|
||||
info.dwWinSize.Y = 25;
|
||||
info.dwWinSize.X = 80;
|
||||
info.winBottom = 24;
|
||||
dwWinSize.Y = 25;
|
||||
dwWinSize.X = 80;
|
||||
winBottom = 24;
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -767,37 +770,28 @@ dev_console::fillin_info (HANDLE h)
|
||||
Negative values represents current screen dimensions
|
||||
*/
|
||||
void
|
||||
fhandler_console::scroll_screen (int x1, int y1, int x2, int y2, int xn, int yn)
|
||||
fhandler_console::scroll_buffer (int x1, int y1, int x2, int y2, int xn, int yn)
|
||||
{
|
||||
SMALL_RECT sr1, sr2;
|
||||
CHAR_INFO fill;
|
||||
COORD dest;
|
||||
fill.Char.AsciiChar = ' ';
|
||||
fill.Attributes = dev_state.current_win32_attr;
|
||||
|
||||
dev_state.fillin_info (get_output_handle ());
|
||||
sr1.Left = x1 >= 0 ? x1 : dev_state.info.dwWinSize.X - 1;
|
||||
if (y1 == 0)
|
||||
sr1.Top = dev_state.info.winTop;
|
||||
else
|
||||
sr1.Top = y1 > 0 ? y1 : dev_state.info.winBottom;
|
||||
sr1.Right = x2 >= 0 ? x2 : dev_state.info.dwWinSize.X - 1;
|
||||
if (y2 == 0)
|
||||
sr1.Bottom = dev_state.info.winTop;
|
||||
else
|
||||
sr1.Bottom = y2 > 0 ? y2 : dev_state.info.winBottom;
|
||||
dev_state.fillin (get_output_handle ());
|
||||
sr1.Left = x1 >= 0 ? x1 : dev_state.dwWinSize.X - 1;
|
||||
sr1.Top = y1 >= 0 ? y1 : dev_state.winBottom;
|
||||
sr1.Right = x2 >= 0 ? x2 : dev_state.dwWinSize.X - 1;
|
||||
sr1.Bottom = y2 >= 0 ? y2 : dev_state.winBottom;
|
||||
sr2.Top = srTop;
|
||||
sr2.Left = 0;
|
||||
sr2.Bottom = srBottom;
|
||||
sr2.Right = dev_state.info.dwWinSize.X - 1;
|
||||
sr2.Right = dev_state.dwWinSize.X - 1;
|
||||
if (sr1.Bottom > sr2.Bottom && sr1.Top <= sr2.Bottom)
|
||||
sr1.Bottom = sr2.Bottom;
|
||||
dest.X = xn >= 0 ? xn : dev_state.info.dwWinSize.X - 1;
|
||||
if (yn == 0)
|
||||
dest.Y = dev_state.info.winTop;
|
||||
else
|
||||
dest.Y = yn > 0 ? yn : dev_state.info.winBottom;
|
||||
fill.Char.AsciiChar = ' ';
|
||||
fill.Attributes = dev_state.current_win32_attr;
|
||||
ScrollConsoleScreenBuffer (get_output_handle (), &sr1, &sr2, dest, &fill);
|
||||
dest.X = xn >= 0 ? xn : dev_state.dwWinSize.X - 1;
|
||||
dest.Y = yn >= 0 ? yn : dev_state.winBottom;
|
||||
ScrollConsoleScreenBuffer (get_output_handle (), &sr1, NULL, dest, &fill);
|
||||
|
||||
#if 0 /* CGF: 2014-01-04 Assuming that we don't need this anymore */
|
||||
/* ScrollConsoleScreenBuffer on Windows 95 is buggy - when scroll distance
|
||||
@ -860,11 +854,11 @@ fhandler_console::open (int flags, mode_t)
|
||||
}
|
||||
set_output_handle (h);
|
||||
|
||||
if (dev_state.fillin_info (get_output_handle ()))
|
||||
if (dev_state.fillin (get_output_handle ()))
|
||||
{
|
||||
dev_state.current_win32_attr = dev_state.info.wAttributes;
|
||||
dev_state.current_win32_attr = dev_state.wAttributes;
|
||||
if (!dev_state.default_color)
|
||||
dev_state.default_color = dev_state.info.wAttributes;
|
||||
dev_state.default_color = dev_state.wAttributes;
|
||||
dev_state.set_default_attr ();
|
||||
}
|
||||
|
||||
@ -912,13 +906,13 @@ fhandler_console::ioctl (unsigned int cmd, void *arg)
|
||||
case TIOCGWINSZ:
|
||||
int st;
|
||||
|
||||
st = dev_state.fillin_info (get_output_handle ());
|
||||
st = dev_state.fillin (get_output_handle ());
|
||||
if (st)
|
||||
{
|
||||
/* *not* the buffer size, the actual screen size... */
|
||||
/* based on Left Top Right Bottom of srWindow */
|
||||
((struct winsize *) arg)->ws_row = dev_state.info.dwWinSize.Y;
|
||||
((struct winsize *) arg)->ws_col = dev_state.info.dwWinSize.X;
|
||||
((struct winsize *) arg)->ws_row = dev_state.dwWinSize.Y;
|
||||
((struct winsize *) arg)->ws_col = dev_state.dwWinSize.X;
|
||||
syscall_printf ("WINSZ: (row=%d,col=%d)",
|
||||
((struct winsize *) arg)->ws_row,
|
||||
((struct winsize *) arg)->ws_col);
|
||||
@ -1189,7 +1183,7 @@ dev_console::set_default_attr ()
|
||||
}
|
||||
|
||||
int
|
||||
dev_console::console_attrs::set_cl_x (cltype x)
|
||||
dev_console::set_cl_x (cltype x)
|
||||
{
|
||||
if (x == cl_disp_beg || x == cl_buf_beg)
|
||||
return 0;
|
||||
@ -1201,7 +1195,7 @@ dev_console::console_attrs::set_cl_x (cltype x)
|
||||
}
|
||||
|
||||
int
|
||||
dev_console::console_attrs::set_cl_y (cltype y)
|
||||
dev_console::set_cl_y (cltype y)
|
||||
{
|
||||
if (y == cl_buf_beg)
|
||||
return 0;
|
||||
@ -1213,7 +1207,26 @@ dev_console::console_attrs::set_cl_y (cltype y)
|
||||
return dwBufferSize.Y - 1;
|
||||
return dwCursorPosition.Y;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
dev_console::is_fullscreen (int x1, int y1, int x2, int y2)
|
||||
{
|
||||
return !savebuf
|
||||
&& x1 == 0 && x2 == dwWinSize.X - 1 && y1 == winTop && y2 == winBottom
|
||||
&& dwBufferSize.Y > dwWinSize.Y;
|
||||
}
|
||||
|
||||
void
|
||||
dev_console::scroll_window (HANDLE h)
|
||||
{
|
||||
SMALL_RECT sr;
|
||||
sr.Top = sr.Bottom = 1 + dwEnd.Y - winTop;
|
||||
sr.Left = sr.Right = 0;
|
||||
SetConsoleWindowInfo (h, FALSE, &sr);
|
||||
dwEnd.X = 0;
|
||||
SetConsoleCursorPosition (h, dwEnd);
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear the screen context from x1/y1 to x2/y2 cell.
|
||||
* Negative values represents current screen dimensions
|
||||
@ -1225,16 +1238,24 @@ fhandler_console::clear_screen (cltype xc1, cltype yc1, cltype xc2, cltype yc2)
|
||||
DWORD done;
|
||||
int num;
|
||||
|
||||
dev_state.fillin_info (get_output_handle ());
|
||||
dev_state.fillin (get_output_handle ());
|
||||
|
||||
int x1 = dev_state.info.set_cl_x (xc1);
|
||||
int y1 = dev_state.info.set_cl_y (yc1);
|
||||
int x2 = dev_state.info.set_cl_x (xc2);
|
||||
int y2 = dev_state.info.set_cl_y (yc2);
|
||||
int x1 = dev_state.set_cl_x (xc1);
|
||||
int y1 = dev_state.set_cl_y (yc1);
|
||||
int x2 = dev_state.set_cl_x (xc2);
|
||||
int y2 = dev_state.set_cl_y (yc2);
|
||||
|
||||
num = abs (y1 - y2) * dev_state.info.dwBufferSize.X + abs (x1 - x2) + 1;
|
||||
/* Detect special case - scroll the screen if we have a buffer to
|
||||
preserve the buffer. */
|
||||
if (dev_state.is_fullscreen (x1, y1, x2, y2))
|
||||
{
|
||||
dev_state.scroll_window (get_output_handle ());
|
||||
return;
|
||||
}
|
||||
|
||||
if ((y2 * dev_state.info.dwBufferSize.X + x2) > (y1 * dev_state.info.dwBufferSize.X + x1))
|
||||
num = abs (y1 - y2) * dev_state.dwBufferSize.X + abs (x1 - x2) + 1;
|
||||
|
||||
if ((y2 * dev_state.dwBufferSize.X + x2) > (y1 * dev_state.dwBufferSize.X + x1))
|
||||
{
|
||||
tlc.X = x1;
|
||||
tlc.Y = y1;
|
||||
@ -1260,7 +1281,7 @@ fhandler_console::cursor_set (bool rel_to_top, int x, int y)
|
||||
{
|
||||
COORD pos;
|
||||
|
||||
dev_state.fillin_info (get_output_handle ());
|
||||
dev_state.fillin (get_output_handle ());
|
||||
#if 0
|
||||
/* Setting y to the current winBottom here is the reason that the window
|
||||
isn't scrolled back to the current cursor position like it's done in
|
||||
@ -1269,17 +1290,17 @@ fhandler_console::cursor_set (bool rel_to_top, int x, int y)
|
||||
output is generated while the user had the window scrolled back. This
|
||||
behaviour is very old, it has no matching ChangeLog entry.
|
||||
Just disable for now but keep the code in for future reference. */
|
||||
if (y > dev_state.info.winBottom)
|
||||
y = dev_state.info.winBottom;
|
||||
if (y > dev_state.winBottom)
|
||||
y = dev_state.winBottom;
|
||||
else
|
||||
#endif
|
||||
if (y < 0)
|
||||
y = 0;
|
||||
else if (rel_to_top)
|
||||
y += dev_state.info.winTop;
|
||||
y += dev_state.winTop;
|
||||
|
||||
if (x > dev_state.info.dwWinSize.X)
|
||||
x = dev_state.info.dwWinSize.X - 1;
|
||||
if (x > dev_state.dwWinSize.X)
|
||||
x = dev_state.dwWinSize.X - 1;
|
||||
else if (x < 0)
|
||||
x = 0;
|
||||
|
||||
@ -1291,18 +1312,18 @@ fhandler_console::cursor_set (bool rel_to_top, int x, int y)
|
||||
void
|
||||
fhandler_console::cursor_rel (int x, int y)
|
||||
{
|
||||
dev_state.fillin_info (get_output_handle ());
|
||||
x += dev_state.info.dwCursorPosition.X;
|
||||
y += dev_state.info.dwCursorPosition.Y;
|
||||
dev_state.fillin (get_output_handle ());
|
||||
x += dev_state.dwCursorPosition.X;
|
||||
y += dev_state.dwCursorPosition.Y;
|
||||
cursor_set (false, x, y);
|
||||
}
|
||||
|
||||
void
|
||||
fhandler_console::cursor_get (int *x, int *y)
|
||||
{
|
||||
dev_state.fillin_info (get_output_handle ());
|
||||
*y = dev_state.info.dwCursorPosition.Y;
|
||||
*x = dev_state.info.dwCursorPosition.X;
|
||||
dev_state.fillin (get_output_handle ());
|
||||
*y = dev_state.dwCursorPosition.Y;
|
||||
*x = dev_state.dwCursorPosition.X;
|
||||
}
|
||||
|
||||
/* VT100 line drawing graphics mode maps `abcdefghijklmnopqrstuvwxyz{|}~ to
|
||||
@ -1474,14 +1495,14 @@ static const char base_chars[256] =
|
||||
void
|
||||
fhandler_console::char_command (char c)
|
||||
{
|
||||
int x, y;
|
||||
int x, y, n;
|
||||
char buf[40];
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case 'm': /* Set Graphics Rendition */
|
||||
for (int i = 0; i <= dev_state.nargs_; i++)
|
||||
switch (dev_state.args_[i])
|
||||
for (int i = 0; i <= dev_state.nargs; i++)
|
||||
switch (dev_state.args[i])
|
||||
{
|
||||
case 0: /* normal color */
|
||||
dev_state.set_default_attr ();
|
||||
@ -1585,7 +1606,7 @@ fhandler_console::char_command (char c)
|
||||
{
|
||||
CONSOLE_CURSOR_INFO console_cursor_info;
|
||||
GetConsoleCursorInfo (get_output_handle (), & console_cursor_info);
|
||||
switch (dev_state.args_[0])
|
||||
switch (dev_state.args[0])
|
||||
{
|
||||
case 0: /* blinking block */
|
||||
case 1: /* blinking block (default) */
|
||||
@ -1599,7 +1620,7 @@ fhandler_console::char_command (char c)
|
||||
SetConsoleCursorInfo (get_output_handle (), & console_cursor_info);
|
||||
break;
|
||||
default: /* use value as percentage */
|
||||
console_cursor_info.dwSize = dev_state.args_[0];
|
||||
console_cursor_info.dwSize = dev_state.args[0];
|
||||
SetConsoleCursorInfo (get_output_handle (), & console_cursor_info);
|
||||
break;
|
||||
}
|
||||
@ -1609,7 +1630,7 @@ fhandler_console::char_command (char c)
|
||||
case 'l':
|
||||
if (!dev_state.saw_question_mark)
|
||||
{
|
||||
switch (dev_state.args_[0])
|
||||
switch (dev_state.args[0])
|
||||
{
|
||||
case 4: /* Insert mode */
|
||||
dev_state.insert_mode = (c == 'h') ? true : false;
|
||||
@ -1618,7 +1639,7 @@ fhandler_console::char_command (char c)
|
||||
}
|
||||
break;
|
||||
}
|
||||
switch (dev_state.args_[0])
|
||||
switch (dev_state.args[0])
|
||||
{
|
||||
case 25: /* Show/Hide Cursor (DECTCEM) */
|
||||
{
|
||||
@ -1717,23 +1738,23 @@ fhandler_console::char_command (char c)
|
||||
break;
|
||||
|
||||
default: /* Ignore */
|
||||
syscall_printf ("unknown h/l command: %d", dev_state.args_[0]);
|
||||
syscall_printf ("unknown h/l command: %d", dev_state.args[0]);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'J':
|
||||
switch (dev_state.args_[0])
|
||||
switch (dev_state.args[0])
|
||||
{
|
||||
case 0: /* Clear to end of screen */
|
||||
clear_screen (cl_curr_pos, cl_curr_pos, cl_disp_end, cl_disp_end);
|
||||
break;
|
||||
case 1: /* Clear from beginning of screen to cursor */
|
||||
cursor_get (&x, &y);
|
||||
clear_screen (cl_disp_beg, cl_disp_beg, cl_curr_pos, cl_curr_pos);
|
||||
break;
|
||||
case 2: /* Clear screen */
|
||||
cursor_get (&x, &y);
|
||||
clear_screen (cl_disp_beg, cl_disp_beg, cl_disp_end, cl_disp_end);
|
||||
cursor_set (true, 0, 0);
|
||||
cursor_set (false, x, y);
|
||||
break;
|
||||
default:
|
||||
goto bad_escape;
|
||||
@ -1741,19 +1762,19 @@ fhandler_console::char_command (char c)
|
||||
break;
|
||||
|
||||
case 'A':
|
||||
cursor_rel (0, -(dev_state.args_[0] ? dev_state.args_[0] : 1));
|
||||
cursor_rel (0, -(dev_state.args[0] ?: 1));
|
||||
break;
|
||||
case 'B':
|
||||
cursor_rel (0, dev_state.args_[0] ? dev_state.args_[0] : 1);
|
||||
cursor_rel (0, dev_state.args[0] ?: 1);
|
||||
break;
|
||||
case 'C':
|
||||
cursor_rel (dev_state.args_[0] ? dev_state.args_[0] : 1, 0);
|
||||
cursor_rel (dev_state.args[0] ?: 1, 0);
|
||||
break;
|
||||
case 'D':
|
||||
cursor_rel (-(dev_state.args_[0] ? dev_state.args_[0] : 1),0);
|
||||
cursor_rel (-(dev_state.args[0] ?: 1),0);
|
||||
break;
|
||||
case 'K':
|
||||
switch (dev_state.args_[0])
|
||||
switch (dev_state.args[0])
|
||||
{
|
||||
case 0: /* Clear to end of line */
|
||||
clear_screen (cl_curr_pos, cl_curr_pos, cl_disp_end, cl_curr_pos);
|
||||
@ -1770,20 +1791,20 @@ fhandler_console::char_command (char c)
|
||||
break;
|
||||
case 'H':
|
||||
case 'f':
|
||||
cursor_set (true, (dev_state.args_[1] ? dev_state.args_[1] : 1) - 1,
|
||||
(dev_state.args_[0] ? dev_state.args_[0] : 1) - 1);
|
||||
cursor_set (true, (dev_state.args[1] ?: 1) - 1,
|
||||
(dev_state.args[0] ?: 1) - 1);
|
||||
break;
|
||||
case 'G': /* hpa - position cursor at column n - 1 */
|
||||
cursor_get (&x, &y);
|
||||
cursor_set (false, (dev_state.args_[0] ? dev_state.args_[0] - 1 : 0), y);
|
||||
cursor_set (false, (dev_state.args[0] ? dev_state.args[0] - 1 : 0), y);
|
||||
break;
|
||||
case 'd': /* vpa - position cursor at line n */
|
||||
cursor_get (&x, &y);
|
||||
cursor_set (true, x, (dev_state.args_[0] ? dev_state.args_[0] - 1 : 0));
|
||||
cursor_set (true, x, (dev_state.args[0] ? dev_state.args[0] - 1 : 0));
|
||||
break;
|
||||
case 's': /* Save cursor position */
|
||||
cursor_get (&dev_state.savex, &dev_state.savey);
|
||||
dev_state.savey -= dev_state.info.winTop;
|
||||
dev_state.savey -= dev_state.winTop;
|
||||
break;
|
||||
case 'u': /* Restore cursor position */
|
||||
cursor_set (true, dev_state.savex, dev_state.savey);
|
||||
@ -1793,39 +1814,39 @@ fhandler_console::char_command (char c)
|
||||
cursor_set (false, 8 * (x / 8 + 1), y);
|
||||
break;
|
||||
case 'L': /* AL - insert blank lines */
|
||||
dev_state.args_[0] = dev_state.args_[0] ? dev_state.args_[0] : 1;
|
||||
n = dev_state.args[0] ?: 1;
|
||||
cursor_get (&x, &y);
|
||||
scroll_screen (0, y, -1, -1, 0, y + dev_state.args_[0]);
|
||||
scroll_buffer (0, y, -1, -1, 0, y + n);
|
||||
break;
|
||||
case 'M': /* DL - delete lines */
|
||||
dev_state.args_[0] = dev_state.args_[0] ? dev_state.args_[0] : 1;
|
||||
n = dev_state.args[0] ?: 1;
|
||||
cursor_get (&x, &y);
|
||||
scroll_screen (0, y + dev_state.args_[0], -1, -1, 0, y);
|
||||
scroll_buffer (0, y + dev_state.args[0], -1, -1, 0, y);
|
||||
break;
|
||||
case '@': /* IC - insert chars */
|
||||
dev_state.args_[0] = dev_state.args_[0] ? dev_state.args_[0] : 1;
|
||||
n = dev_state.args[0] ?: 1;
|
||||
cursor_get (&x, &y);
|
||||
scroll_screen (x, y, -1, y, x + dev_state.args_[0], y);
|
||||
scroll_buffer (x, y, -1, y, x + n, y);
|
||||
break;
|
||||
case 'P': /* DC - delete chars */
|
||||
dev_state.args_[0] = dev_state.args_[0] ? dev_state.args_[0] : 1;
|
||||
n = dev_state.args[0] ?: 1;
|
||||
cursor_get (&x, &y);
|
||||
scroll_screen (x + dev_state.args_[0], y, -1, y, x, y);
|
||||
scroll_buffer (x + n, y, -1, y, x, y);
|
||||
break;
|
||||
case 'S': /* SF - Scroll forward */
|
||||
dev_state.args_[0] = dev_state.args_[0] ? dev_state.args_[0] : 1;
|
||||
scroll_screen (0, dev_state.args_[0], -1, -1, 0, 0);
|
||||
n = dev_state.args[0] ?: 1;
|
||||
scroll_buffer (0, n, -1, -1, 0, 0);
|
||||
break;
|
||||
case 'T': /* SR - Scroll down */
|
||||
dev_state.fillin_info (get_output_handle ());
|
||||
dev_state.args_[0] = dev_state.args_[0] ? dev_state.args_[0] : 1;
|
||||
scroll_screen (0, 0, -1, -1, 0, dev_state.info.winTop + dev_state.args_[0]);
|
||||
dev_state.fillin (get_output_handle ());
|
||||
n = dev_state.winTop + dev_state.args[0] ?: 1;
|
||||
scroll_buffer (0, dev_state.winTop, -1, -1, 0, n);
|
||||
break;
|
||||
case 'X': /* ec - erase chars */
|
||||
dev_state.args_[0] = dev_state.args_[0] ? dev_state.args_[0] : 1;
|
||||
n = dev_state.args[0] ?: 1;
|
||||
cursor_get (&x, &y);
|
||||
scroll_screen (x + dev_state.args_[0], y, -1, y, x, y);
|
||||
scroll_screen (x, y, -1, y, x + dev_state.args_[0], y);
|
||||
scroll_buffer (x + n, y, -1, y, x, y);
|
||||
scroll_buffer (x, y, -1, y, x + n, y);
|
||||
break;
|
||||
case 'Z': /* Back tab */
|
||||
cursor_get (&x, &y);
|
||||
@ -1835,10 +1856,10 @@ fhandler_console::char_command (char c)
|
||||
if (dev_state.insert_mode)
|
||||
{
|
||||
cursor_get (&x, &y);
|
||||
scroll_screen (x, y, -1, y, x + dev_state.args_[1], y);
|
||||
scroll_buffer (x, y, -1, y, x + dev_state.args[1], y);
|
||||
}
|
||||
while (dev_state.args_[1]--)
|
||||
WriteFile (get_output_handle (), &dev_state.args_[0], 1, (DWORD *) &x, 0);
|
||||
while (dev_state.args[1]--)
|
||||
WriteFile (get_output_handle (), &dev_state.args[0], 1, (DWORD *) &x, 0);
|
||||
break;
|
||||
case 'c': /* u9 - Terminal enquire string */
|
||||
if (dev_state.saw_greater_than_sign)
|
||||
@ -1854,12 +1875,12 @@ fhandler_console::char_command (char c)
|
||||
puts_readahead (buf);
|
||||
break;
|
||||
case 'n':
|
||||
switch (dev_state.args_[0])
|
||||
switch (dev_state.args[0])
|
||||
{
|
||||
case 6: /* u7 - Cursor position request */
|
||||
cursor_get (&x, &y);
|
||||
y -= dev_state.info.winTop;
|
||||
/* x -= dev_state.info.winLeft; // not available yet */
|
||||
y -= dev_state.winTop;
|
||||
/* x -= dev_state.winLeft; // not available yet */
|
||||
__small_sprintf (buf, "\033[%d;%dR", y + 1, x + 1);
|
||||
puts_readahead (buf);
|
||||
break;
|
||||
@ -1868,8 +1889,8 @@ fhandler_console::char_command (char c)
|
||||
}
|
||||
break;
|
||||
case 'r': /* Set Scroll region */
|
||||
dev_state.scroll_region.Top = dev_state.args_[0] ? dev_state.args_[0] - 1 : 0;
|
||||
dev_state.scroll_region.Bottom = dev_state.args_[1] ? dev_state.args_[1] - 1 : -1;
|
||||
dev_state.scroll_region.Top = dev_state.args[0] ? dev_state.args[0] - 1 : 0;
|
||||
dev_state.scroll_region.Bottom = dev_state.args[1] ? dev_state.args[1] - 1 : -1;
|
||||
cursor_set (true, 0, 0);
|
||||
break;
|
||||
case 'g': /* TAB set/clear */
|
||||
@ -2011,7 +2032,7 @@ do_print:
|
||||
{
|
||||
int x, y;
|
||||
cursor_get (&x, &y);
|
||||
scroll_screen (x, y, -1, y, x + buf_len, y);
|
||||
scroll_buffer (x, y, -1, y, x + buf_len, y);
|
||||
}
|
||||
|
||||
if (!write_console (write_buf, buf_len, done))
|
||||
@ -2041,17 +2062,17 @@ do_print:
|
||||
beep ();
|
||||
break;
|
||||
case ESC:
|
||||
dev_state.state_ = gotesc;
|
||||
dev_state.state = gotesc;
|
||||
break;
|
||||
case DWN:
|
||||
cursor_get (&x, &y);
|
||||
if (y >= srBottom)
|
||||
{
|
||||
if (y >= dev_state.info.winBottom && !dev_state.scroll_region.Top)
|
||||
if (y >= dev_state.winBottom && !dev_state.scroll_region.Top)
|
||||
WriteConsoleW (get_output_handle (), L"\n", 1, &done, 0);
|
||||
else
|
||||
{
|
||||
scroll_screen (0, srTop + 1, -1, srBottom, 0, srTop);
|
||||
scroll_buffer (0, srTop + 1, -1, srBottom, 0, srTop);
|
||||
y--;
|
||||
}
|
||||
}
|
||||
@ -2123,8 +2144,8 @@ fhandler_console::write (const void *vsrc, size_t len)
|
||||
|
||||
while (src < end)
|
||||
{
|
||||
paranoid_printf ("char %0c state is %d", *src, dev_state.state_);
|
||||
switch (dev_state.state_)
|
||||
paranoid_printf ("char %0c state is %d", *src, dev_state.state);
|
||||
switch (dev_state.state)
|
||||
{
|
||||
case normal:
|
||||
src = write_normal (src, end);
|
||||
@ -2134,33 +2155,33 @@ fhandler_console::write (const void *vsrc, size_t len)
|
||||
case gotesc:
|
||||
if (*src == '[') /* CSI Control Sequence Introducer */
|
||||
{
|
||||
dev_state.state_ = gotsquare;
|
||||
dev_state.state = gotsquare;
|
||||
dev_state.saw_question_mark = false;
|
||||
dev_state.saw_greater_than_sign = false;
|
||||
dev_state.saw_space = false;
|
||||
for (dev_state.nargs_ = 0; dev_state.nargs_ < MAXARGS; dev_state.nargs_++)
|
||||
dev_state.args_[dev_state.nargs_] = 0;
|
||||
dev_state.nargs_ = 0;
|
||||
for (dev_state.nargs = 0; dev_state.nargs < MAXARGS; dev_state.nargs++)
|
||||
dev_state.args[dev_state.nargs] = 0;
|
||||
dev_state.nargs = 0;
|
||||
}
|
||||
else if (*src == ']') /* OSC Operating System Command */
|
||||
{
|
||||
dev_state.rarg = 0;
|
||||
dev_state.my_title_buf[0] = '\0';
|
||||
dev_state.state_ = gotrsquare;
|
||||
dev_state.state = gotrsquare;
|
||||
}
|
||||
else if (*src == '(') /* Designate G0 character set */
|
||||
{
|
||||
dev_state.state_ = gotparen;
|
||||
dev_state.state = gotparen;
|
||||
}
|
||||
else if (*src == ')') /* Designate G1 character set */
|
||||
{
|
||||
dev_state.state_ = gotrparen;
|
||||
dev_state.state = gotrparen;
|
||||
}
|
||||
else if (*src == 'M') /* Reverse Index (scroll down) */
|
||||
{
|
||||
dev_state.fillin_info (get_output_handle ());
|
||||
scroll_screen (0, 0, -1, -1, 0, dev_state.info.winTop + 1);
|
||||
dev_state.state_ = normal;
|
||||
dev_state.fillin (get_output_handle ());
|
||||
scroll_buffer (0, 0, -1, -1, 0, dev_state.winTop + 1);
|
||||
dev_state.state = normal;
|
||||
}
|
||||
else if (*src == 'c') /* RIS Full Reset */
|
||||
{
|
||||
@ -2170,60 +2191,60 @@ fhandler_console::write (const void *vsrc, size_t len)
|
||||
dev_state.iso_2022_G1 = false;
|
||||
cursor_set (false, 0, 0);
|
||||
clear_screen (cl_buf_beg, cl_buf_beg, cl_buf_end, cl_buf_end);
|
||||
dev_state.state_ = normal;
|
||||
dev_state.state = normal;
|
||||
}
|
||||
else if (*src == '8') /* DECRC Restore cursor position */
|
||||
{
|
||||
cursor_set (true, dev_state.savex, dev_state.savey);
|
||||
dev_state.state_ = normal;
|
||||
dev_state.state = normal;
|
||||
}
|
||||
else if (*src == '7') /* DECSC Save cursor position */
|
||||
{
|
||||
cursor_get (&dev_state.savex, &dev_state.savey);
|
||||
dev_state.savey -= dev_state.info.winTop;
|
||||
dev_state.state_ = normal;
|
||||
dev_state.savey -= dev_state.winTop;
|
||||
dev_state.state = normal;
|
||||
}
|
||||
else if (*src == 'R') /* ? */
|
||||
dev_state.state_ = normal;
|
||||
dev_state.state = normal;
|
||||
else
|
||||
{
|
||||
dev_state.state_ = normal;
|
||||
dev_state.state = normal;
|
||||
}
|
||||
src++;
|
||||
break;
|
||||
case gotarg1:
|
||||
if (isdigit (*src))
|
||||
{
|
||||
dev_state.args_[dev_state.nargs_] = dev_state.args_[dev_state.nargs_] * 10 + *src - '0';
|
||||
dev_state.args[dev_state.nargs] = dev_state.args[dev_state.nargs] * 10 + *src - '0';
|
||||
src++;
|
||||
}
|
||||
else if (*src == ';')
|
||||
{
|
||||
src++;
|
||||
dev_state.nargs_++;
|
||||
if (dev_state.nargs_ >= MAXARGS)
|
||||
dev_state.nargs_--;
|
||||
dev_state.nargs++;
|
||||
if (dev_state.nargs >= MAXARGS)
|
||||
dev_state.nargs--;
|
||||
}
|
||||
else if (*src == ' ')
|
||||
{
|
||||
src++;
|
||||
dev_state.saw_space = true;
|
||||
dev_state.state_ = gotcommand;
|
||||
dev_state.state = gotcommand;
|
||||
}
|
||||
else
|
||||
dev_state.state_ = gotcommand;
|
||||
dev_state.state = gotcommand;
|
||||
break;
|
||||
case gotcommand:
|
||||
char_command (*src++);
|
||||
dev_state.state_ = normal;
|
||||
dev_state.state = normal;
|
||||
break;
|
||||
case gotrsquare:
|
||||
if (isdigit (*src))
|
||||
dev_state.rarg = dev_state.rarg * 10 + (*src - '0');
|
||||
else if (*src == ';' && (dev_state.rarg == 2 || dev_state.rarg == 0))
|
||||
dev_state.state_ = gettitle;
|
||||
dev_state.state = gettitle;
|
||||
else
|
||||
dev_state.state_ = eattitle;
|
||||
dev_state.state = eattitle;
|
||||
src++;
|
||||
break;
|
||||
case eattitle:
|
||||
@ -2232,9 +2253,9 @@ fhandler_console::write (const void *vsrc, size_t len)
|
||||
int n = strlen (dev_state.my_title_buf);
|
||||
if (*src < ' ')
|
||||
{
|
||||
if (*src == '\007' && dev_state.state_ == gettitle)
|
||||
if (*src == '\007' && dev_state.state == gettitle)
|
||||
set_console_title (dev_state.my_title_buf);
|
||||
dev_state.state_ = normal;
|
||||
dev_state.state = normal;
|
||||
}
|
||||
else if (n < TITLESIZE)
|
||||
{
|
||||
@ -2247,12 +2268,12 @@ fhandler_console::write (const void *vsrc, size_t len)
|
||||
case gotsquare:
|
||||
if (*src == ';')
|
||||
{
|
||||
dev_state.state_ = gotarg1;
|
||||
dev_state.nargs_++;
|
||||
dev_state.state = gotarg1;
|
||||
dev_state.nargs++;
|
||||
src++;
|
||||
}
|
||||
else if (isalpha (*src))
|
||||
dev_state.state_ = gotcommand;
|
||||
dev_state.state = gotcommand;
|
||||
else if (*src != '@' && !isalpha (*src) && !isdigit (*src))
|
||||
{
|
||||
if (*src == '?')
|
||||
@ -2263,14 +2284,14 @@ fhandler_console::write (const void *vsrc, size_t len)
|
||||
src++;
|
||||
}
|
||||
else
|
||||
dev_state.state_ = gotarg1;
|
||||
dev_state.state = gotarg1;
|
||||
break;
|
||||
case gotparen: /* Designate G0 Character Set (ISO 2022) */
|
||||
if (*src == '0')
|
||||
dev_state.vt100_graphics_mode_G0 = true;
|
||||
else
|
||||
dev_state.vt100_graphics_mode_G0 = false;
|
||||
dev_state.state_ = normal;
|
||||
dev_state.state = normal;
|
||||
src++;
|
||||
break;
|
||||
case gotrparen: /* Designate G1 Character Set (ISO 2022) */
|
||||
@ -2278,7 +2299,7 @@ fhandler_console::write (const void *vsrc, size_t len)
|
||||
dev_state.vt100_graphics_mode_G1 = true;
|
||||
else
|
||||
dev_state.vt100_graphics_mode_G1 = false;
|
||||
dev_state.state_ = normal;
|
||||
dev_state.state = normal;
|
||||
src++;
|
||||
break;
|
||||
}
|
||||
|
@ -16,3 +16,6 @@ What changed:
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- Try harder to do the right thing in the presence of console screen buffers,
|
||||
i.e., never clear the screen buffer unless the user asked for it. Also
|
||||
fix screen escape sequences which attempted to scroll the screen.
|
||||
|
Loading…
x
Reference in New Issue
Block a user