From: Roman Penyaev <r.peniaev@gmail.com>
Cc: "Roman Penyaev" <r.peniaev@gmail.com>,
"Marc-André Lureau" <marcandre.lureau@redhat.com>,
qemu-devel@nongnu.org
Subject: [PATCH 5/5] ui/console-vc: implement DCH (delete) and ICH (insert) commands
Date: Sun, 23 Feb 2025 15:54:02 +0100 [thread overview]
Message-ID: <20250223145407.259924-6-r.peniaev@gmail.com> (raw)
In-Reply-To: <20250223145407.259924-1-r.peniaev@gmail.com>
This patch implements DCH (delete character) and ICH (insert
character) commands.
DCH - Delete Character:
"As characters are deleted, the remaining characters between the
cursor and right margin move to the left. Character attributes move
with the characters. The terminal adds blank spaces with no visual
character attributes at the right margin. DCH has no effect outside
the scrolling margins" [1].
ICH - Insert Character:
"The ICH sequence inserts Pn blank characters with the normal
character attribute. The cursor remains at the beginning of the
blank characters. Text between the cursor and right margin moves to
the right. Characters scrolled past the right margin are lost. ICH
has no effect outside the scrolling margins" [2].
Without these commands console is barely usable.
[1] https://vt100.net/docs/vt510-rm/DCH.html
[1] https://vt100.net/docs/vt510-rm/ICH.html
Signed-off-by: Roman Penyaev <r.peniaev@gmail.com>
Cc: "Marc-André Lureau" <marcandre.lureau@redhat.com>
Cc: qemu-devel@nongnu.org
---
ui/console-vc.c | 108 +++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 102 insertions(+), 6 deletions(-)
diff --git a/ui/console-vc.c b/ui/console-vc.c
index 522adc2806c8..bc667897d1bc 100644
--- a/ui/console-vc.c
+++ b/ui/console-vc.c
@@ -598,21 +598,29 @@ static void vc_clear_xy(VCChardev *vc, int x, int y)
vc_update_xy(vc, x, y);
}
-static void vc_put_one(VCChardev *vc, int ch)
+static void vc_insert_xy(VCChardev *vc, int ch, int x, int y)
{
QemuTextConsole *s = vc->console;
TextCell *c;
int y1;
+
+ y1 = (s->y_base + y) % s->total_height;
+ c = &s->cells[y1 * s->width + x];
+ c->ch = ch;
+ c->t_attrib = vc->t_attrib;
+ vc_update_xy(vc, x, y);
+}
+
+static void vc_put_one(VCChardev *vc, int ch)
+{
+ QemuTextConsole *s = vc->console;
+
if (s->x >= s->width) {
/* line wrap */
s->x = 0;
vc_put_lf(vc);
}
- y1 = (s->y_base + s->y) % s->total_height;
- c = &s->cells[y1 * s->width + s->x];
- c->ch = ch;
- c->t_attrib = vc->t_attrib;
- vc_update_xy(vc, s->x, s->y);
+ vc_insert_xy(vc, ch, s->x, s->y);
s->x++;
}
@@ -645,6 +653,88 @@ static void vc_set_cursor(VCChardev *vc, int x, int y)
s->y = y;
}
+/**
+ * vc_csi_P() - (DCH) deletes one or more characters from the cursor
+ * position to the right. As characters are deleted, the remaining
+ * characters between the cursor and right margin move to the
+ * left. Character attributes move with the characters.
+ */
+static void vc_csi_P(struct VCChardev *vc, unsigned int nr)
+{
+ QemuTextConsole *s = vc->console;
+ TextCell *c1, *c2;
+ unsigned int x1, x2, y;
+ unsigned int end, len;
+
+ if (!nr) {
+ nr = 1;
+ }
+ if (nr > s->width - s->x) {
+ nr = s->width - s->x;
+ if (!nr) {
+ return;
+ }
+ }
+
+ x1 = s->x;
+ x2 = s->x + nr;
+ len = s->width - x2;
+ if (len) {
+ y = (s->y_base + s->y) % s->total_height;
+ c1 = &s->cells[y * s->width + x1];
+ c2 = &s->cells[y * s->width + x2];
+ memmove(c1, c2, len * sizeof(*c1));
+ for (end = x1 + len; x1 < end; x1++) {
+ vc_update_xy(vc, x1, s->y);
+ }
+ }
+ /* Clear the rest */
+ for (; x1 < s->width; x1++) {
+ vc_clear_xy(vc, x1, s->y);
+ }
+}
+
+/**
+ * vc_csi_at() - (ICH) inserts `nr` blank characters with the normal
+ * character attribute. The cursor remains at the beginning of the
+ * blank characters. Text between the cursor and right margin moves to
+ * the right. Characters scrolled past the right margin are lost.
+ */
+static void vc_csi_at(struct VCChardev *vc, unsigned int nr)
+{
+ QemuTextConsole *s = vc->console;
+ TextCell *c1, *c2;
+ unsigned int x1, x2, y;
+ unsigned int end, len;
+
+ if (!nr) {
+ nr = 1;
+ }
+ if (nr > s->width - s->x) {
+ nr = s->width - s->x;
+ if (!nr) {
+ return;
+ }
+ }
+
+ x1 = s->x + nr;
+ x2 = s->x;
+ len = s->width - x1;
+ if (len) {
+ y = (s->y_base + s->y) % s->total_height;
+ c1 = &s->cells[y * s->width + x1];
+ c2 = &s->cells[y * s->width + x2];
+ memmove(c1, c2, len * sizeof(*c1));
+ for (end = x1 + len; x1 < end; x1++) {
+ vc_update_xy(vc, x1, s->y);
+ }
+ }
+ /* Insert spaces */
+ for (x1 = s->x; x1 < s->x + nr; x1++) {
+ vc_insert_xy(vc, ' ', x1, s->y);
+ }
+}
+
/**
* vc_save_cursor() - saves cursor position and character attributes.
*/
@@ -847,6 +937,9 @@ static void vc_putchar(VCChardev *vc, int ch)
break;
}
break;
+ case 'P':
+ vc_csi_P(vc, vc->esc_params[0]);
+ break;
case 'm':
vc_handle_escape(vc);
break;
@@ -870,6 +963,9 @@ static void vc_putchar(VCChardev *vc, int ch)
case 'u':
vc_restore_cursor(vc);
break;
+ case '@':
+ vc_csi_at(vc, vc->esc_params[0]);
+ break;
default:
trace_console_putchar_unhandled(ch);
break;
--
2.43.0
next prev parent reply other threads:[~2025-02-23 14:55 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-02-23 14:53 [PATCH 0/5] ui/console-vc: various fixes and improvements Roman Penyaev
2025-02-23 14:53 ` [PATCH 1/5] ui/console-vc: introduce parsing of the 'ESC ( <ch>' sequence Roman Penyaev
2025-02-23 14:53 ` [PATCH 2/5] ui/console-vc: report to the application instead of screen rendering Roman Penyaev
2025-02-23 14:54 ` [PATCH 3/5] ui/console-vc: report cursor position in the screen not in the scroll buffer Roman Penyaev
2025-02-23 14:54 ` [PATCH 4/5] ui/console-vc: add support for cursor DECSC and DECRC commands Roman Penyaev
2025-02-23 14:54 ` Roman Penyaev [this message]
2025-02-24 7:25 ` [PATCH 5/5] ui/console-vc: implement DCH (delete) and ICH (insert) commands Marc-André Lureau
2025-02-25 9:59 ` Roman Penyaev
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250223145407.259924-6-r.peniaev@gmail.com \
--to=r.peniaev@gmail.com \
--cc=marcandre.lureau@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).