* 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; | ||||
|   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; | ||||
|  | @ -1214,6 +1208,25 @@ dev_console::console_attrs::set_cl_y (cltype y) | |||
|   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…
	
		Reference in New Issue