Add support for the rectangular area operations #18574

Closed
opened 2026-01-31 06:18:10 +00:00 by claunia · 16 comments
Owner

Originally created by @j4james on GitHub (Oct 1, 2022).

Description of the new feature/enhancement

This is a set of functions that include DECFRA (fill rectangle), DECERA (erase rectangle), DECSERA (selective erase rectangle), DECCRA (copy rectangle), DECCARA (change attributes), DECRARA (reverse attributes), and DECSACE (this determines the affected area of the previous two operations - it can be a rectangle or a stream of characters).

Some of these should be helpful in improving our console API support for passthrough mode (#1173 / #10001). Most useful would probably be DECCRA, DECCARA, and possibly DECFRA. We've also discussed using DECCRA to support the layering concept in issue #10810, but that would require us supporting the paging functions as well (#13892).

Proposed technical implementation details (optional)

I've got a working POC, and some of these are fairly straightforward, but some require low level access to the buffer. That means my current implementation will probably require some refactoring to work with the ROW rewrite in PR #13626, so I'm happy to wait for that to merge first. And DECSERA depends on the new "protected" attribute added in PR #14046, so that definitely needs to merge first.

I should also note that I'm not positive about all of the implementation details, so if possible I'd like to get someone with a real terminal to confirm the correct behavior before I submit a PR.

Originally created by @j4james on GitHub (Oct 1, 2022). # Description of the new feature/enhancement This is a set of functions that include [`DECFRA`](https://vt100.net/docs/vt510-rm/DECFRA.html) (fill rectangle), [`DECERA`](https://vt100.net/docs/vt510-rm/DECERA.html) (erase rectangle), [`DECSERA`](https://vt100.net/docs/vt510-rm/DECSERA.html) (selective erase rectangle), [`DECCRA`](https://vt100.net/docs/vt510-rm/DECCRA.html) (copy rectangle), [`DECCARA`](https://vt100.net/docs/vt510-rm/DECCARA.html) (change attributes), [`DECRARA`](https://vt100.net/docs/vt510-rm/DECRARA.html) (reverse attributes), and [`DECSACE`](https://vt100.net/docs/vt510-rm/DECSACE.html) (this determines the affected area of the previous two operations - it can be a rectangle or a stream of characters). Some of these should be helpful in improving our console API support for passthrough mode (#1173 / #10001). Most useful would probably be `DECCRA`, `DECCARA`, and possibly `DECFRA`. We've also discussed using `DECCRA` to support the layering concept in issue #10810, but that would require us supporting the paging functions as well (#13892). # Proposed technical implementation details (optional) I've got a working POC, and some of these are fairly straightforward, but some require low level access to the buffer. That means my current implementation will probably require some refactoring to work with the `ROW` rewrite in PR #13626, so I'm happy to wait for that to merge first. And `DECSERA` depends on the new "protected" attribute added in PR #14046, so that definitely needs to merge first. I should also note that I'm not positive about all of the implementation details, so if possible I'd like to get someone with a real terminal to confirm the correct behavior before I submit a PR.
claunia added the Product-ConhostResolution-Fix-CommittedIssue-TaskArea-VT labels 2026-01-31 06:18:11 +00:00
Author
Owner

@j4james commented on GitHub (Oct 1, 2022):

@KalleOlaviNiemitalo and @jerch I believe you both have access to DEC terminals that should be capable of supporting these operations. So if you have the time, I'd be very grateful if you would be willing to run some tests which could help us figure out how exactly they are are supposed to work.

I've create a Python script with a series of test cases here:
https://gist.github.com/j4james/f8f3fb5ecd066dfc722dd98fec7a5742

For each test, it shows what I believe to be the expected output in the top of the screen, and the actual output in the bottom half. You just press enter to move on to the next test case until you've run through all of them (there are about 60 in total).

With any luck, most of them will be correct, but if anything doesn't match, just make a note of the test number, and we can figure out where to go from there.

If you want to go back and rerun an individual test, you can specify the test number as a command line parameter (e.g. python rectarea.py 3.4). You can also specify just the first part of the number if you want to run all the tests from a particular category (e.g. python rectarea.py 3).

@j4james commented on GitHub (Oct 1, 2022): @KalleOlaviNiemitalo and @jerch I believe you both have access to DEC terminals that should be capable of supporting these operations. So if you have the time, I'd be very grateful if you would be willing to run some tests which could help us figure out how exactly they are are supposed to work. I've create a Python script with a series of test cases here: https://gist.github.com/j4james/f8f3fb5ecd066dfc722dd98fec7a5742 For each test, it shows what I believe to be the expected output in the top of the screen, and the actual output in the bottom half. You just press enter to move on to the next test case until you've run through all of them (there are about 60 in total). With any luck, most of them will be correct, but if anything doesn't match, just make a note of the test number, and we can figure out where to go from there. If you want to go back and rerun an individual test, you can specify the test number as a command line parameter (e.g. `python rectarea.py 3.4`). You can also specify just the first part of the number if you want to run all the tests from a particular category (e.g. `python rectarea.py 3`).
Author
Owner

@KalleOlaviNiemitalo commented on GitHub (Oct 1, 2022):

@j4james, my current laptop lacks RS-232 ports. I may have a converter somewhere, though.

@KalleOlaviNiemitalo commented on GitHub (Oct 1, 2022): @j4james, my current laptop lacks RS-232 ports. I may have a converter somewhere, though.
Author
Owner

@jerch commented on GitHub (Oct 1, 2022):

@j4james Sure will see if I get down to it tomorrow. Also I kinda forgot about the other sequence you wanted to be checked several months ago. Can you give a pointer to that again? The reminder is kinda buried in tons of notifications now 😸

@jerch commented on GitHub (Oct 1, 2022): @j4james Sure will see if I get down to it tomorrow. Also I kinda forgot about the other sequence you wanted to be checked several months ago. Can you give a pointer to that again? The reminder is kinda buried in tons of notifications now :smile_cat:
Author
Owner

@j4james commented on GitHub (Oct 1, 2022):

@jerch The other one is here: https://github.com/microsoft/terminal/issues/13091#issuecomment-1126579485

But there's no rush for any of this, so I don't want to stress either of you if you don't have the time, or don't have the necessary equipment. I was just thinking it would be good to have some evidence for how these sequences are really meant to work, and then maybe we could start pushing TEs to improve their interoperability - right now everyone interprets the standards differently.

@j4james commented on GitHub (Oct 1, 2022): @jerch The other one is here: https://github.com/microsoft/terminal/issues/13091#issuecomment-1126579485 But there's no rush for any of this, so I don't want to stress either of you if you don't have the time, or don't have the necessary equipment. I was just thinking it would be good to have some evidence for how these sequences are really meant to work, and then maybe we could start pushing TEs to improve their interoperability - right now everyone interprets the standards differently.
Author
Owner

@lhecker commented on GitHub (Oct 3, 2022):

I'm hoping to get the ROW rewrite in soon, but we're currently a bit short-staffed so it might take a little to review that rather large PR. If you get your PR ready sooner than we can merge my PR, I'd say making your code work with my rewrite will be my problem and not yours. 😅 (But of course you can also wait for that PR if you want to.)

@lhecker commented on GitHub (Oct 3, 2022): I'm hoping to get the `ROW` rewrite in soon, but we're currently a bit short-staffed so it might take a little to review that rather large PR. If you get your PR ready sooner than we can merge my PR, I'd say making your code work with my rewrite will be my problem and not yours. 😅 (But of course you can also wait for that PR if you want to.)
Author
Owner

@carlos-zamora commented on GitHub (Oct 5, 2022):

@j4james thanks, this is a great idea. We'd love to have it! :)

@carlos-zamora commented on GitHub (Oct 5, 2022): @j4james thanks, this is a great idea. We'd love to have it! :)
Author
Owner

@KalleOlaviNiemitalo commented on GitHub (Oct 9, 2022):

VT420 powers up OK. The USB serial converter should arrive on Tuesday.

@KalleOlaviNiemitalo commented on GitHub (Oct 9, 2022): VT420 powers up OK. The USB serial converter should arrive on Tuesday.
Author
Owner

@KalleOlaviNiemitalo commented on GitHub (Oct 10, 2022):

I got the converter, but now there is a gender problem. 😖

@KalleOlaviNiemitalo commented on GitHub (Oct 10, 2022): I got the converter, but now there is a gender problem. 😖
Author
Owner

@j4james commented on GitHub (Oct 10, 2022):

@KalleOlaviNiemitalo No pressure, but I got a bit overexcited by the idea of your converter arriving, and I started working on some other VT420 operations which I was hoping you might also be able to test. 😊 Not the end of the world if you can't get it working though, and there's no hurry for any of this.

@j4james commented on GitHub (Oct 10, 2022): @KalleOlaviNiemitalo No pressure, but I got a bit overexcited by the idea of your converter arriving, and I started working on some other VT420 operations which I was hoping you might also be able to test. 😊 Not the end of the world if you can't get it working though, and there's no hurry for any of this.
Author
Owner

@DHowett commented on GitHub (Oct 10, 2022):

Our team's also recently come into possession of a VT420! We don't have nearly the right set of devices to interface with it yet, so I am more than happy to ask (beg!) @KalleOlaviNiemitalo to help out 😄

@DHowett commented on GitHub (Oct 10, 2022): Our team's also recently come into possession of a VT420! We don't have nearly the right set of devices to interface with it yet, so I am more than happy to ask (beg!) @KalleOlaviNiemitalo to help out :smile:
Author
Owner

@j4james commented on GitHub (Oct 11, 2022):

FYI, even if you can't get the terminal connected, you should still be able to do a certain amount of testing on it if you're desperate. Not the kind of test cases I linked above, but little one-off tests should be feasible.

What you do is switch the terminal from On Line to Local mode (use F3 to open the setup menu, and you'll find that option on the Global submenu). Then you can simply type escape sequences to see what effect they have. When you need an ESC character, just type Ctrl+[.

And note that you can use the arrow keys to move the cursor around the screen, because the escape sequences that those keys generate are exactly the same as the output sequences for cursor movement.

@j4james commented on GitHub (Oct 11, 2022): FYI, even if you can't get the terminal connected, you should still be able to do a certain amount of testing on it if you're desperate. Not the kind of test cases I linked above, but little one-off tests should be feasible. What you do is switch the terminal from _On Line_ to _Local_ mode (use <kbd>F3</kbd> to open the setup menu, and you'll find that option on the _Global_ submenu). Then you can simply type escape sequences to see what effect they have. When you need an `ESC` character, just type <kbd>Ctrl</kbd>+<kbd>[</kbd>. And note that you can use the arrow keys to move the cursor around the screen, because the escape sequences that those keys generate are exactly the same as the output sequences for cursor movement.
Author
Owner

@KalleOlaviNiemitalo commented on GitHub (Oct 13, 2022):

Serial I/O works. Now I just need the time.

@KalleOlaviNiemitalo commented on GitHub (Oct 13, 2022): Serial I/O works. Now I just need the time.
Author
Owner

@KalleOlaviNiemitalo commented on GitHub (Oct 13, 2022):

I attached all screen shots to https://gist.github.com/j4james/f8f3fb5ecd066dfc722dd98fec7a5742?permalink_comment_id=4334375#gistcomment-4334375.

@KalleOlaviNiemitalo commented on GitHub (Oct 13, 2022): I attached all screen shots to <https://gist.github.com/j4james/f8f3fb5ecd066dfc722dd98fec7a5742?permalink_comment_id=4334375#gistcomment-4334375>.
Author
Owner

@KalleOlaviNiemitalo commented on GitHub (Oct 14, 2022):

Is it possible to implement the rectangle stuff in such a way that it is compatible with the old terminals on ASCII characters, but also compatible with modern terminal emulators on Unicode grapheme clusters?

@KalleOlaviNiemitalo commented on GitHub (Oct 14, 2022): Is it possible to implement the rectangle stuff in such a way that it is compatible with the old terminals on ASCII characters, but also compatible with modern terminal emulators on Unicode grapheme clusters?
Author
Owner

@j4james commented on GitHub (Oct 15, 2022):

Is it possible to implement the rectangle stuff in such a way that it is compatible with the old terminals on ASCII characters, but also compatible with modern terminal emulators on Unicode grapheme clusters?

That's an interesting question. I hadn't thought of trying that before, but I've done a few tests now on the terminals I have that support both rectangular area operations as well as Unicode.

When you have a rectangular operation intersecting a glyph that spans two cells, that's much the same problem as when you output a single cell glyph on top of a two cell glyph. Most terminals just erase the whole glyph leaving a blank on one side or the other. Windows Terminal and conhost do things differently, and their exact behavior depends on the renderer in use, but I expect we'll fix that at some point in time.

A similar situation arises when using DECCRA to copy an area of the screen that intersects a two cell glyph. Most terminals will end up copying a blank if the source cell is only half of a two cell glyph. That's not particularly surprising either, although I think it might be better to leave the target cell unchanged in that case, similar to the way the VT420 handles a DECCRA of an area that is partially off screen.

The most interesting case though is the DECFRA operation when given a multi cell glyph as the fill character. Of the terminals I tested, MLTerm treated it as an invalid operation that did nothing, RLogin rendered the glyph compressed horizontally so it would fit in a single cell, Mintty just rendered half of the glyph, and XTerm rendered the full glyph width but the rectangle then took up twice as much space as expected.

XTerm's behavior doesn't seem intentional though, because if you do something to trigger a refresh, it rerenders the rectangle occupying the expected dimensions (still displaying the full width characters). For example, if you requested a rectangle 10 cells wide, it starts off as 10 glyphs occupying 20 cells, but refreshes as 5 glyphs occupying 10 cells. Personally I think the latter rendering is the nicest, so it's a pity XTerm doesn't get that right by default.

@j4james commented on GitHub (Oct 15, 2022): > Is it possible to implement the rectangle stuff in such a way that it is compatible with the old terminals on ASCII characters, but also compatible with modern terminal emulators on Unicode grapheme clusters? That's an interesting question. I hadn't thought of trying that before, but I've done a few tests now on the terminals I have that support both rectangular area operations as well as Unicode. When you have a rectangular operation intersecting a glyph that spans two cells, that's much the same problem as when you output a single cell glyph on top of a two cell glyph. Most terminals just erase the whole glyph leaving a blank on one side or the other. Windows Terminal and conhost do things differently, and their exact behavior depends on the renderer in use, but I expect we'll fix that at some point in time. A similar situation arises when using `DECCRA` to copy an area of the screen that intersects a two cell glyph. Most terminals will end up copying a blank if the source cell is only half of a two cell glyph. That's not particularly surprising either, although I think it might be better to leave the target cell unchanged in that case, similar to the way the VT420 handles a `DECCRA` of an area that is partially off screen. The most interesting case though is the `DECFRA` operation when given a multi cell glyph as the fill character. Of the terminals I tested, MLTerm treated it as an invalid operation that did nothing, RLogin rendered the glyph compressed horizontally so it would fit in a single cell, Mintty just rendered half of the glyph, and XTerm rendered the full glyph width but the rectangle then took up twice as much space as expected. XTerm's behavior doesn't seem intentional though, because if you do something to trigger a refresh, it rerenders the rectangle occupying the expected dimensions (still displaying the full width characters). For example, if you requested a rectangle 10 cells wide, it starts off as 10 glyphs occupying 20 cells, but refreshes as 5 glyphs occupying 10 cells. Personally I think the latter rendering is the nicest, so it's a pity XTerm doesn't get that right by default.
Author
Owner

@ghost commented on GitHub (Jan 24, 2023):

:tada:This issue was addressed in #14285, which has now been successfully released as Windows Terminal Preview v1.17.1023.🎉

Handy links:

@ghost commented on GitHub (Jan 24, 2023): :tada:This issue was addressed in #14285, which has now been successfully released as `Windows Terminal Preview v1.17.1023`.:tada: Handy links: * [Release Notes](https://github.com/microsoft/terminal/releases/tag/v1.17.1023) * [Store Download](https://www.microsoft.com/store/apps/9n8g5rfz9xk3?cid=storebadge&ocid=badge)
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#18574