6a29852ace
* The intent of having the length variable was to avoid sending trailing whitespace for each line, but the previous code never read the variable. Instead, every line it sent was the width of the terminal window. * There was a bug where running console.exe inside a TERM=cygwin terminal resulted in excessive line feeds. This change mitigates that bug, but doesn't fix it. The problem is that the agent assumes that after it writes to the last column of a line, the cursor is still on the same line, but this isn't true for the TERM=cygwin terminal.
220 lines
9.6 KiB
Plaintext
220 lines
9.6 KiB
Plaintext
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).
|