[PR #14285] [MERGED] Add support for the rectangular area operations #30045

Open
opened 2026-01-31 09:38:20 +00:00 by claunia · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/microsoft/terminal/pull/14285
Author: @j4james
Created: 10/23/2022
Status: Merged
Merged: 11/10/2022
Merged by: @undefined

Base: mainHead: feature-rect-area


📝 Commits (10+)

  • 33384aa Add support for the DECFRA sequence.
  • 89bb823 Add support for the DECERA sequence.
  • 6aa5045 Add support for the DECSERA sequence.
  • 24cd7d5 Add support for the DECCRA sequence.
  • 97f0e66 Add support for the DECSACE sequence.
  • b334d15 Add helper functions for manipulating buffer attributes.
  • 65ad810 Add support for the DECCARA sequence.
  • cd014dd Add support for the DECRARA sequence.
  • bc448a0 Make sure DECFRA works with full width glyphs.
  • add8022 Add some very basic screen buffer tests.

📊 Changes

14 files changed (+833 additions, -183 deletions)

View changed files

📝 src/buffer/out/TextAttribute.cpp (+1 -1)
📝 src/buffer/out/TextAttribute.hpp (+4 -0)
📝 src/host/ut_host/ScreenBufferTests.cpp (+126 -0)
📝 src/inc/conattrs.hpp (+4 -1)
📝 src/terminal/adapter/DispatchTypes.hpp (+7 -0)
📝 src/terminal/adapter/ITermDispatch.hpp (+8 -0)
📝 src/terminal/adapter/adaptDispatch.cpp (+397 -0)
📝 src/terminal/adapter/adaptDispatch.hpp (+24 -1)
📝 src/terminal/adapter/adaptDispatchGraphics.cpp (+205 -180)
📝 src/terminal/adapter/termDispatch.hpp (+8 -0)
📝 src/terminal/parser/OutputStateMachineEngine.cpp (+28 -0)
📝 src/terminal/parser/OutputStateMachineEngine.hpp (+7 -0)
📝 src/terminal/parser/telemetry.cpp (+7 -0)
📝 src/terminal/parser/telemetry.hpp (+7 -0)

📄 Description

Summary of the Pull Request

This PR adds support for the rectangular area escape sequences:
DECCRA, DECFRA, DECERA, DECSERA, DECCARA, DECRARA, and
DECSACE. They provide VT applications with an efficient way to copy,
fill, erase, or change the attributes in a rectangular area of the
screen.

PR Checklist

Detailed Description of the Pull Request / Additional comments

All of these operations take a rectangle, defined by four coordinates.
These need to have defaults applied, potentially need to be clipped
and/or clamped within the active margins, and finally converted to
absolute buffer coordinates. To avoid having to repeat that boilerplate
code everywhere, I've pulled that functionality out into a shared method
which they all use.

With that out of the way, operations like DECFRA (fill), DECERA
(erase), and DECSERA (selective erase) are fairly simple. They're just
filling the given rectangle using the existing methods _FillRect and
_SelectiveEraseRect. DECCRA (copy) is a little more work, because we
didn't have existing code for that in AdaptDispatch, but it's mostly
just cloned from the conhost _CopyRectangle function.

The DECCARA (change attributes) and DECRARA (reverse attributes)
operations are different though. Their coordinates can be interpreted as
either a rectangle, or a stream of character positions (determined by
the DECSACE escape sequence), and they both deal with attribute
manipulation of the target area. So again I've pulled out that common
functionality into some shared methods.

They both also take a list of SGR options which define the attribute
changes that they need to apply to the target area. To parse that data,
I've had to refactor the SGR decoder from the SetGraphicsRendition
method so it could be used with a given TextAttribute instance instead
of just modifying the active attributes.

The way that works in DECCARA, we apply the SGR options to two
TextAttribute instances - one with all rendition bits on, and one with
all off - producing a pair of bit masks. Then by ANDing the target
attributes with the first bit mask, and ORing them with the second, we
can efficiently achieve the same effect as if we'd applied each SGR
option to our target cells one by one.

In the case of DECRARA, we only need to create a single bit mask to
achieve the "reverse attribute" effect. That bit mask is applied to the
target cells with an XOR operation.

Validation Steps Performed

Thanks to @KalleOlaviNiemitalo, we've been able to run a series of tests
on a real VT420, so we have a good idea of how these ops are intended to
work. Our implementation does a reasonably good job of matching that
behavior, but we don't yet support paging, so we don't have the DECCRA
ability to copy between pages, and we also don't have the concept of
"unoccupied" cells, so we can't support that aspect of the streaming
operations.

It's also worth mentioning that the VT420 doesn't have colors, so we
can't be sure exactly how they are meant to interpreted. However, based
on the way the other attribute are handled, and what we know from the
DEC STD 070 documentation, I think it's fair to assume that our handling
of colors is also reasonable.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/microsoft/terminal/pull/14285 **Author:** [@j4james](https://github.com/j4james) **Created:** 10/23/2022 **Status:** ✅ Merged **Merged:** 11/10/2022 **Merged by:** [@undefined](undefined) **Base:** `main` ← **Head:** `feature-rect-area` --- ### 📝 Commits (10+) - [`33384aa`](https://github.com/microsoft/terminal/commit/33384aab1386924bb8f5ccb2b409fb385055cac3) Add support for the DECFRA sequence. - [`89bb823`](https://github.com/microsoft/terminal/commit/89bb8233ba6986a7a608c51d9c59330921e1f684) Add support for the DECERA sequence. - [`6aa5045`](https://github.com/microsoft/terminal/commit/6aa5045e1b191c5c9808e4bbae0e19192b6ee242) Add support for the DECSERA sequence. - [`24cd7d5`](https://github.com/microsoft/terminal/commit/24cd7d5c7669e78d76b66077f1dcb5c02d33bc0c) Add support for the DECCRA sequence. - [`97f0e66`](https://github.com/microsoft/terminal/commit/97f0e665d719697278f71ed6e8608477619619bb) Add support for the DECSACE sequence. - [`b334d15`](https://github.com/microsoft/terminal/commit/b334d15fb450fabc783c4fab40bb6b70508c7b29) Add helper functions for manipulating buffer attributes. - [`65ad810`](https://github.com/microsoft/terminal/commit/65ad81075274d19690fbe53f3008f9fe4ef6d5d2) Add support for the DECCARA sequence. - [`cd014dd`](https://github.com/microsoft/terminal/commit/cd014ddaeb61fc6f24a0b72ec0a51b5db2347944) Add support for the DECRARA sequence. - [`bc448a0`](https://github.com/microsoft/terminal/commit/bc448a0b4bb80457d772580de0161ba94a6518f5) Make sure DECFRA works with full width glyphs. - [`add8022`](https://github.com/microsoft/terminal/commit/add8022d3f85b46808b152a8a419a009154125ac) Add some very basic screen buffer tests. ### 📊 Changes **14 files changed** (+833 additions, -183 deletions) <details> <summary>View changed files</summary> 📝 `src/buffer/out/TextAttribute.cpp` (+1 -1) 📝 `src/buffer/out/TextAttribute.hpp` (+4 -0) 📝 `src/host/ut_host/ScreenBufferTests.cpp` (+126 -0) 📝 `src/inc/conattrs.hpp` (+4 -1) 📝 `src/terminal/adapter/DispatchTypes.hpp` (+7 -0) 📝 `src/terminal/adapter/ITermDispatch.hpp` (+8 -0) 📝 `src/terminal/adapter/adaptDispatch.cpp` (+397 -0) 📝 `src/terminal/adapter/adaptDispatch.hpp` (+24 -1) 📝 `src/terminal/adapter/adaptDispatchGraphics.cpp` (+205 -180) 📝 `src/terminal/adapter/termDispatch.hpp` (+8 -0) 📝 `src/terminal/parser/OutputStateMachineEngine.cpp` (+28 -0) 📝 `src/terminal/parser/OutputStateMachineEngine.hpp` (+7 -0) 📝 `src/terminal/parser/telemetry.cpp` (+7 -0) 📝 `src/terminal/parser/telemetry.hpp` (+7 -0) </details> ### 📄 Description ## Summary of the Pull Request This PR adds support for the rectangular area escape sequences: `DECCRA`, `DECFRA`, `DECERA`, `DECSERA`, `DECCARA`, `DECRARA`, and `DECSACE`. They provide VT applications with an efficient way to copy, fill, erase, or change the attributes in a rectangular area of the screen. ## PR Checklist * [x] Closes #14112 * [x] CLA signed. * [x] Tests added/passed * [ ] Documentation updated. * [ ] Schema updated. * [x] I've discussed this with core contributors already. Issue number where discussion took place: #14112 ## Detailed Description of the Pull Request / Additional comments All of these operations take a rectangle, defined by four coordinates. These need to have defaults applied, potentially need to be clipped and/or clamped within the active margins, and finally converted to absolute buffer coordinates. To avoid having to repeat that boilerplate code everywhere, I've pulled that functionality out into a shared method which they all use. With that out of the way, operations like `DECFRA` (fill), `DECERA` (erase), and `DECSERA` (selective erase) are fairly simple. They're just filling the given rectangle using the existing methods `_FillRect` and `_SelectiveEraseRect`. `DECCRA` (copy) is a little more work, because we didn't have existing code for that in `AdaptDispatch`, but it's mostly just cloned from the conhost `_CopyRectangle` function. The `DECCARA` (change attributes) and `DECRARA` (reverse attributes) operations are different though. Their coordinates can be interpreted as either a rectangle, or a stream of character positions (determined by the `DECSACE` escape sequence), and they both deal with attribute manipulation of the target area. So again I've pulled out that common functionality into some shared methods. They both also take a list of `SGR` options which define the attribute changes that they need to apply to the target area. To parse that data, I've had to refactor the `SGR` decoder from the `SetGraphicsRendition` method so it could be used with a given `TextAttribute` instance instead of just modifying the active attributes. The way that works in `DECCARA`, we apply the `SGR` options to two `TextAttribute` instances - one with all rendition bits on, and one with all off - producing a pair of bit masks. Then by `AND`ing the target attributes with the first bit mask, and `OR`ing them with the second, we can efficiently achieve the same effect as if we'd applied each `SGR` option to our target cells one by one. In the case of `DECRARA`, we only need to create a single bit mask to achieve the "reverse attribute" effect. That bit mask is applied to the target cells with an `XOR` operation. ## Validation Steps Performed Thanks to @KalleOlaviNiemitalo, we've been able to run a series of tests on a real VT420, so we have a good idea of how these ops are intended to work. Our implementation does a reasonably good job of matching that behavior, but we don't yet support paging, so we don't have the `DECCRA` ability to copy between pages, and we also don't have the concept of "unoccupied" cells, so we can't support that aspect of the streaming operations. It's also worth mentioning that the VT420 doesn't have colors, so we can't be sure exactly how they are meant to interpreted. However, based on the way the other attribute are handled, and what we know from the DEC STD 070 documentation, I think it's fair to assume that our handling of colors is also reasonable. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
claunia added the pull-request label 2026-01-31 09:38:20 +00:00
Sign in to join this conversation.
No Label pull-request
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#30045