| Test programs | |
| ------------- | |
| Cygwin | |
| emacs | |
| vim | |
| mc (Midnight Commander) | |
| lynx | |
| links | |
| less | |
| more | |
| wget | |
| Capturing the console output | |
| ---------------------------- | |
| Initial idea: | |
| In the agent, keep track of the remote terminal state for N lines of | |
| (window+history). Also keep track of the terminal size. Regularly poll for | |
| changes to the console screen buffer, then use some number of edits to bring | |
| the remote terminal into sync with the console. | |
| This idea seems to have trouble when a Unix terminal is resized. When the | |
| server receives a resize notification, it can have a hard time figuring out | |
| what the terminal did. Race conditions might also be a problem. | |
| The behavior of the terminal can be tricky: | |
| - When the window is expanded by one line, does the terminal add a blank line | |
| to the bottom or move a line from the history into the top? | |
| - When the window is shrunk by one line, does the terminal delete the topmost | |
| or the bottommost line? Can it delete the line with the cursor? | |
| Some popular behaviors for expanding: | |
| - [all] If there are no history lines, then add a line at the bottom. | |
| - [konsole] Always add a line at the bottom. | |
| - [putty,xterm,rxvt] Pull in a history line from the top. | |
| - [g-t] I can't tell. It seems to add a blank line, until the program writes | |
| to stdout or until I click the scroll bar, then the output "snaps" back down, | |
| pulling lines out of the history. I thought I saw different behavior | |
| between Ubuntu 10.10 and 11.10, so maybe GNOME 3 changed something. Avoid | |
| using "bash" to test this behavior because "bash" apparently always writes | |
| the prompt after terminal resize. | |
| Some popular behaviors for shrinking: | |
| - [konsole,putty,xterm,rxvt] If the line at the bottom is blank, then delete | |
| it. Otherwise, move the topmost line into history. | |
| - [g-t] If the line at the bottom has not been touched, then delete it. | |
| Otherwise, move the topmost line into history. | |
| (TODO: I need to test my theories about the terminal behavior better still. | |
| It's interesting to see how g-t handles clear differently than every other | |
| terminal.) | |
| There is an ANSI escape sequence (DSR) that sends the current cursor location | |
| to the terminal's input. One idea I had was to use this code to figure out how | |
| the terminal had handled a resize. I currently think this idea won't work due | |
| to race conditions. | |
| Newer idea: | |
| Keep track of the last N lines that have been sent to the remote terminal. | |
| Poll for changes to console output. When the output changes, send just the | |
| changed content to the terminal. In particular: | |
| - Don't send a cursor position (CUP) code. Instead, if the line that's 3 | |
| steps up from the latest line changes, send a relative cursor up (CUU) | |
| code. It's OK to send an absolute column number code (CHA). | |
| - At least in general, don't try to send complete screenshots of the current | |
| console window. | |
| The idea is that sending just the changes should have good behavior for streams | |
| of output, even when those streams modify the output (e.g. an archiver, or | |
| maybe a downloader/packager/wget). I need to think about whether this works | |
| for full-screen programs (e.g. emacs, less, lynx, the above list of programs). | |
| I noticed that console programs don't typically modify the window or buffer | |
| coordinates. edit.com is an exception. | |
| I tested the pager in native Python (more?), and I verified that ENTER and SPACE | |
| both paid no attention to the location of the console window within the screen | |
| buffer. This makes sense -- why would they care? The Cygwin less, on the other | |
| hand, does care. If I scroll the window up, then Cygwin less will write to a | |
| position within the window. I didn't really expect this behavior, but it | |
| doesn't seem to be a problem. | |
| Setting up a TestNetServer service | |
| ---------------------------------- | |
| First run the deploy.sh script to copy files into deploy. Make sure | |
| TestNetServer.exe will run in a bare environment (no MinGW or Qt in the path). | |
| Install the Windows Server 2003 Resource Kit. It will have two programs in it, | |
| instsrv and srvany. | |
| Run: | |
| InstSrv TestNetServer <path-to-srvany>\srvany.exe | |
| This creates a service named "TestNetServer" that uses the Microsoft service | |
| wrapper. To configure the new service to run TestNetServer, set a registry | |
| value: | |
| [HKLM\SYSTEM\CurrentControlSet\Services\TestNetServer\Parameters] | |
| Application=<full-path>\TestNetServer.exe | |
| Also see http://www.iopus.com/guides/srvany.htm. | |
| To remove the service, run: | |
| InstSrv TestNetServer REMOVE | |
| TODO | |
| ---- | |
| Agent: When resizing the console, consider whether to add lines to the top | |
| or bottom. I remember thinking the current behavior was wrong for some | |
| application, but I forgot which one. | |
| Make the font as small as possible. The console window dimensions are limited by | |
| the screen size, so making the font small reduces an unnecessary limitation on the | |
| PseudoConsole size. There's a documented Vista/Win7 API for this | |
| (SetCurrentConsoleFontEx), and apparently WinXP has an undocumented API | |
| (SetConsoleFont): | |
| http://blogs.microsoft.co.il/blogs/pavely/archive/2009/07/23/changing-console-fonts.aspx | |
| Make the agent work with DOS programs like edit and qbasic. | |
| - Detect that the terminal program has resized the window/buffer and enter a | |
| simple just-scrape-and-dont-resize mode. Track the client window size and | |
| send the intersection of the console and the agent's client. | |
| - I also need to generate keyboard scan codes. | |
| - Solve the NTVDM.EXE console shutdown problem, probably by ignoring NTVDM.EXE | |
| when it appears on the GetConsoleProcessList list. | |
| Rename the agent? Is the term "proxy" more accurate? | |
| Optimize the polling. e.g. Use a longer poll interval when the console is idle. | |
| Do a minimal poll that checks whether the sync marker or window has moved. | |
| Increase the console buffer size to ~9000 lines. Beware making it so big that | |
| reading the sync column exhausts the 32KB conhost<->agent heap. | |
| Reduce the memory overhead of the agent. The agent's m_bufferData array can | |
| be small (a few hundred lines?) relative to the console buffer size. | |
| Try to handle console background color better. | |
| Unix terminal emulators have a user-configurable foreground and background | |
| color, and for best results, the agent really needs to avoid changing the colors, | |
| especially the background color. It's undesirable/ugly to SSH into a machine | |
| and see the command prompt change the colors. It's especially ugly that the | |
| terminal retains its original colors and only drawn cells get the new colors. | |
| (e.g. Resizing the window to the right uses the local terminal colors rather | |
| than the remote colors.) It's especially ugly in gnome-terminal, which draws | |
| user-configurable black as black, but VT100 black as dark-gray. | |
| If there were a way to query the terminal emulator's colors, then I could | |
| match the console's colors to the terminal and everything would just work. As | |
| far as I know, that's not possible. | |
| I thought of a kludge that might work. Instead of translating console white | |
| and black to VT/100 white and black, I would translate them to "reset" and | |
| "invert". I'd translate other colors normally. This approach should produce | |
| ideal results for command-line work and tolerable results for full-screen | |
| programs without configuration. Configuring the agent for black-on-white or | |
| white-on-black would produce ideal results in all situations. | |
| This kludge only really applies to the SSH application. For a Win32 Konsole | |
| application, it should be easy to get the colors right all the time. | |
| Try using the screen reader API: | |
| - To eliminate polling. | |
| - To detect when a line wraps. When a line wraps, it'd be nice not to send a | |
| CRLF to the terminal emulator so copy-and-paste works better. | |
| - To detect hard tabs with Cygwin. | |
| Implement VT100/ANSI escape sequence recognition for input. Decide where this | |
| functionality belongs. PseudoConsole.dll? Disambiguating ESC from an escape | |
| sequence might be tricky. For the SSH server, I was thinking that when a small | |
| SSH payload ended with an ESC character, I could assume the character was really | |
| an ESC keypress, on the assumption that if it were an escape sequence, the | |
| payload would probably contain the whole sequence. I'm not sure this works, | |
| especially if there's a lot of other traffic multiplexed on the SSH socket. | |
| Support Unicode. | |
| - Some DOS programs draw using line/box characters. Can these characters be | |
| translated to the Unicode equivalents? | |
| Create automated tests. | |
| Experiment with the Terminator emulator, an emulator that doesn't wrap lines. | |
| How many columns does it report having? What column does it report the cursor | |
| in as it's writing past the right end of the window? Will Terminator be a | |
| problem if I implement line wrapping detection in the agent? | |
| BUG: After the unix-adapter/pconsole.exe program exits, the blinking cursor is | |
| replaced with a hidden cursor. | |
| Fix assert() in the agent. If it fails, the failure message needs to be | |
| reported somewhere. Pop up a dialog box? Maybe switch the active desktop, | |
| then show a dialog box? | |
| TODO: There's already a pconsole project on GitHub. Maybe rename this project | |
| to something else? winpty? | |
| TODO: Can the DebugServer system be replaced with OutputDebugString? How | |
| do we decide whose processes' output to collect? | |
| TODO: Three executables: | |
| build/winpty-agent.exe | |
| build/winpty.dll | |
| build/console.exe | |
| BUG: Run the pconsole.exe inside another console. As I type dir, I see this: | |
| D:\rprichard\pconsole> | |
| D:\rprichard\pconsole>d | |
| D:\rprichard\pconsole>di | |
| D:\rprichard\pconsole>dir | |
| In the output of "dir", every other line is blank. | |
| There was a bug in Terminal::sendLine that was causing this to happen | |
| frequently. Now that I fixed it, this bug should only manifest on lines | |
| whose last column is not a space (i.e. a full line). | |