-
Notifications
You must be signed in to change notification settings - Fork 8.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for horizontal margin sequences #14876
Comments
This is another one of those sequences which has lots of edge cases that aren't always clearly specified, and which everyone handles differently. So before I submit a PR for this, it would be ideal if we could get some of those aspects clarified by testing on a real DEC terminal. To that end I've created a Python script with a series of test cases here: @KalleOlaviNiemitalo and @jerch, I'd be very grateful if either of you would be willing to give that a run on your VT420 or VT525. It's setup as an automated test, so you shouldn't need to do anything other than run it, and the results will be logged in a file named Note that it could take a while, because it uses I should also mention that it highlights the results with reverse video if they've "failed", but that's just based on my best guess of how things should work. I wouldn't be surprised if the real terminals behave differently from my expectations. Also note that some of the operations were only supported on the VT510 and above, so you can definitely expect to see failures for those if testing on a VT420. I think that includes So @KalleOlaviNiemitalo, if the test is running really slowly, and you want to save some time, feel free to comment those ones out. You'll find all the test groups listed at the bottom of the script, so for example, you can comment out the |
@al20878: Thanks for giving it try. I probably should have explained that it switches to a second page for some of the tests, where it fills the screen with characters and then performs various operations on that content. When each test is finished, it switches back to the initial page to output the results. On a slow connection it's probably going to seem like you're on the second test page for most of the time, and you may not even notice the results page until the very end. Anyway, it's not important that you see the results, and you don't need to take a video, since it writes everything to a |
No problem, @j4james , I'll just leave it run on VT420 and then submit the logfile (the connection speed is 9600 baud, not too bad, but it'll take some time to finish). |
It finished in 7 and a half minutes |
VT520 finished the same script in 8:56 (same 9600 baud), the results are here: |
VT525 has done it in 5:56, but I noticed it wasn't getting any characters back from the terminal, unlike previously, as everything was coming in as asterisks ('*'). All three terminals are real H/W and were reset to factory (default) settings. |
Let me know if you need anything else! |
@al20878 This is brilliant! Thank you so much! There are quite a lot of operations where the results weren't what I expected, but that's exactly why I wanted to run these tests. It's great to have these details confirmed.
That's interesting. I'm using the DECRQCRA checksum operation to "read" the screen, but the details of the checksum algorithm aren't actually documented anywhere. I've been assuming it was one of two commonly used formats I've seen in other terminal emulators, one of which I know was derived from a real VT520. But I'm guessing the VT525 algorithm is different (possibly because it covers things like color attributes), so that would be an interesting subject for a future investigation. |
@al20878 Now that I've had a chance to look at all the results in detail, the only thing I'm unsure about is the handling of So when you have a chance, I've got another little script (linked here) that I'm hoping you'll test for me. All it does is write 4 digits to the screen, while altering the margins and saving and restoring the cursor position with On a VT100 and VT240 (tested on MAME), the output looks like this:
My theory is that the later DEC terminals do something different, though. My guess is the |
Sure, I'll run the script on the real terminals. So far I ran it in PuTTY, and I saw this:
|
Obviously, I would not be able to copy-paste the same from the terminals, but I can compare what would they show. I need to do a little cable reconf to reattach them in the proper order (now that I have the right cable adapter, it won't be a problem at all, and I'll do it shortly). Stay tuned |
@j4james as the saying goes, a picture is worth a thousand words, I'm attaching the "screenshots" of your script's output on 5 DEC terminals (VT320, VT330, VT420, VT520, and VT525, in order): |
@al20878 This is great, thanks! I'm so glad you tested on the VT320 and VT330 as well, so now we know exactly when the new behavior was introduced. I'm now inclined to update the Windows Terminal implementation to match the VT420/VT5xx devices by default, because that's seems to be the more "correct" behavior. In the long term we can always have an option for more strict compatibility with the lower level devices for edge cases like this.
There are a number of other operations I'd like to get a better understanding of, so if you don't mind doing this sort of thing, I'd love to ping you from time to time when I've got something ready to test. But feel free to ignore me if you're busy or if you lose interest. |
@j4james I'm happy to help!
Sure, reach out any time! |
This PR introduces two new escapes sequences: `DECLRMM` (Left Right Margin Mode), which enables the horizontal margin support, and `DECSLRM` (Set Left and Right Margins), which does exactly what the name suggests. A whole lot of existing operations have then been updated to take those horizontal margins into account. ## Detailed Description of the Pull Request / Additional comments The main complication was in figuring out in what way each operation is affected, since there's a fair amount of variation. * When writing text to the buffer, we need to wrap within the horizontal margins, but only when the cursor is also within the vertical margins, otherwise we just wrap within the boundaries of the screen. * Not all cursor movement operations are constrained by the margins, but for those that are, we clamp within both the vertical and horizontal margins. But if the cursor is already outside the margins, it is just clamped at the edges of the screen. * The `ICH` and `DCH` operations are constrained by the horizontal margins, but only when inside the vertical margins. And if the cursor is outside the horizontal margins, these operations have no effect at all. * The rectangular area operations are clamped within the horizontal margins when in the origin mode, the same way they're clamped within the vertical margins. * The scrolling operations only scroll the area inside both horizontal and vertical margins. This includes the `IL` and `DL` operations, but they also won't have any effect at all unless the cursor is already inside the margin area. * `CR` returns to the left margin rather than the start of the line, unless the cursor is already left of that margin, or outside the vertical margins. * `LF`, `VT`, `FF`, and `IND` only trigger a scroll at the bottom margin if the cursor is already inside both vertical and horizontal margins. The same rules apply to `RI` when triggering a scroll at the top margin. Another thing worth noting is the change to the `ANSISYSSC` operation. Since that shares the same escape sequence as `DECSLRM`, they can't both be active at the same time. However, the latter is only meant to be active when `DECLRMM` is set, so by default `ANSISYSC` will still work, but it'll no longer apply once the `DECLRMM` mode is enabled. ## Validation Steps Performed Thanks to @al20878, these operations have been extensively tested on a number of DEC terminals and I've manually confirmed our implementation matches their behavior. I've also extended some of our existing unit tests to cover at least the basic margin handling, although not all of the edge cases. Closes #14876
This PR introduces two new escapes sequences: `DECLRMM` (Left Right Margin Mode), which enables the horizontal margin support, and `DECSLRM` (Set Left and Right Margins), which does exactly what the name suggests. A whole lot of existing operations have then been updated to take those horizontal margins into account. ## Detailed Description of the Pull Request / Additional comments The main complication was in figuring out in what way each operation is affected, since there's a fair amount of variation. * When writing text to the buffer, we need to wrap within the horizontal margins, but only when the cursor is also within the vertical margins, otherwise we just wrap within the boundaries of the screen. * Not all cursor movement operations are constrained by the margins, but for those that are, we clamp within both the vertical and horizontal margins. But if the cursor is already outside the margins, it is just clamped at the edges of the screen. * The `ICH` and `DCH` operations are constrained by the horizontal margins, but only when inside the vertical margins. And if the cursor is outside the horizontal margins, these operations have no effect at all. * The rectangular area operations are clamped within the horizontal margins when in the origin mode, the same way they're clamped within the vertical margins. * The scrolling operations only scroll the area inside both horizontal and vertical margins. This includes the `IL` and `DL` operations, but they also won't have any effect at all unless the cursor is already inside the margin area. * `CR` returns to the left margin rather than the start of the line, unless the cursor is already left of that margin, or outside the vertical margins. * `LF`, `VT`, `FF`, and `IND` only trigger a scroll at the bottom margin if the cursor is already inside both vertical and horizontal margins. The same rules apply to `RI` when triggering a scroll at the top margin. Another thing worth noting is the change to the `ANSISYSSC` operation. Since that shares the same escape sequence as `DECSLRM`, they can't both be active at the same time. However, the latter is only meant to be active when `DECLRMM` is set, so by default `ANSISYSC` will still work, but it'll no longer apply once the `DECLRMM` mode is enabled. ## Validation Steps Performed Thanks to @al20878, these operations have been extensively tested on a number of DEC terminals and I've manually confirmed our implementation matches their behavior. I've also extended some of our existing unit tests to cover at least the basic margin handling, although not all of the edge cases. Closes #14876 (cherry picked from commit b00b77a) Service-Card-Id: 89180228 Service-Version: 1.18
Description of the new feature/enhancement
The
DECSLRM
escape sequence lets you set left and right margins, so you can wrap your output within a given horizontal range, and also limit the scrolling within those boundaries. This is useful for apps like multiplexers, where you can have two panes side by side, and you need to be able to scroll the one side independently of the other.Proposed technical implementation details (optional)
There are actually two sequences we need to implement for this. The first is
DECLRMM
(Left Right Margin Mode), without which the margin functionality won't be active. It's disabled by default because you can't use horizontal margins at the same time as double-width line attributes.The main sequence is
DECSLRM
(Set Left Right Margins), which works similarly to theDECSTBM
sequence (Set Top Bottom Margins) which we already support. But there a bunch of operations we then need to update to take those margins into account - cursor movement, insert and delete ops, text output, etc.I should also note that the
DECSLRM
sequence clashes with theANSISYSSC
sequence which we already support. But the way most modern terminals deal with that is to disableANSISYSSC
when theDECLRMM
mode is enabled. So by defaultCSI s
isANSISYSSC
(as we have it now), but withDECLRMM
enabled it's interpreted asDECSLRM
.The text was updated successfully, but these errors were encountered: