|
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). |
|
|