aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Hajnoczi <stefanha@redhat.com>2025-03-05 21:58:23 +0800
committerStefan Hajnoczi <stefanha@redhat.com>2025-03-05 21:58:23 +0800
commite8a01102936286e012ed0f00bd7f3b7474d415c9 (patch)
treee07ff376823b911bcb9191a2a5f75fb2dbcbc260
parentcf2f8cf3b7b2d4eadb4023eb18f4ae45b294fe82 (diff)
parent46f83c898a6658921fed57f98af6d505ab78a6e4 (diff)
downloadqemu-e8a01102936286e012ed0f00bd7f3b7474d415c9.zip
qemu-e8a01102936286e012ed0f00bd7f3b7474d415c9.tar.gz
qemu-e8a01102936286e012ed0f00bd7f3b7474d415c9.tar.bz2
Merge tag 'ui-pull-request' of https://gitlab.com/marcandre.lureau/qemu into staging
UI-related for 10.0 # -----BEGIN PGP SIGNATURE----- # # iQJQBAABCAA6FiEEh6m9kz+HxgbSdvYt2ujhCXWWnOUFAmfH8VIcHG1hcmNhbmRy # ZS5sdXJlYXVAcmVkaGF0LmNvbQAKCRDa6OEJdZac5fpaD/41MyK8mvNINCBh/zNs # BttToR+P2OKDdJcg+fiq8nSaBOqk8TnxWNdfKhd8bdPY3yD56zGzgYhZVLm+d0a6 # a54jkSYLxpM7LL9nKFjLSXDqhmrreU94YGIADzG5WPhndBBHg7ZtHoS5fhlCt4dq # 0YiPMdQqYf75lSk0w/q+KG+MNX/kA/2Yq2vmxMSRT+DniW7PfcO5MixYfaAs5zJz # JazcCZTDgbv/DrIsNeaEyMraE3GBnY1fU2obbwoQ2D+eFGA4SpUwjHKZnVkKuD0I # jYV53BQ+dQMGpN0kmQEyQOj25HvUR5WWlsvSYqHaWupUmg3P+Ne+RaGBUmymgwAU # FI8SVo9njl/4N8uaSDN76Ed6hpQh+LnnuR0pSDdxLLTef7JwC07009a1tYNeo3gq # xzTT0NlD8g8oTA/p/2HVAE2nKQME9qK3v3gqfVwZGlPnOBnL2S8+9qO5qK3xHUd0 # g3YwbaKl5aRDs2t2gzrUVEk6VO9TdpllzkskF26YuDmGgPHIU8y0P2TafPgtJ1cI # emlT06PiNwbJrpOLlLf8SaFXKWgDigt4mTUHg5ZNEDVOfs59qxcTPS1HdSKmA1nP # x5Zhq4AUFGAxJxziUznFvCYuqwiPqVkiqvrZF2PIAgkBCb0P8JtDbk+6DtTrrP+m # y2ODr8nH3Oo3hgDk7SOh577NKQ== # =KDTR # -----END PGP SIGNATURE----- # gpg: Signature made Wed 05 Mar 2025 14:38:10 HKT # gpg: using RSA key 87A9BD933F87C606D276F62DDAE8E10975969CE5 # gpg: issuer "marcandre.lureau@redhat.com" # gpg: Good signature from "Marc-André Lureau <marcandre.lureau@redhat.com>" [full] # gpg: aka "Marc-André Lureau <marcandre.lureau@gmail.com>" [full] # Primary key fingerprint: 87A9 BD93 3F87 C606 D276 F62D DAE8 E109 7596 9CE5 * tag 'ui-pull-request' of https://gitlab.com/marcandre.lureau/qemu: chardev: use remoteAddr if the chardev is client ui/console-vc: implement DCH (delete) and ICH (insert) commands ui/console-vc: add support for cursor DECSC and DECRC commands ui/console-vc: report cursor position in the screen not in the scroll buffer ui/console-vc: report to the application instead of screen rendering ui/console-vc: introduce parsing of the 'ESC ( <ch>' sequence Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
-rw-r--r--chardev/char-socket.c10
-rw-r--r--ui/console-vc.c154
2 files changed, 149 insertions, 15 deletions
diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index 91496ce..2f842f9 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -571,9 +571,13 @@ static char *qemu_chr_compute_filename(SocketChardev *s)
switch (ss->ss_family) {
case AF_UNIX:
- return g_strdup_printf("unix:%s%s",
- ((struct sockaddr_un *)(ss))->sun_path,
- s->is_listen ? ",server=on" : "");
+ if (s->is_listen) {
+ return g_strdup_printf("unix:%s,server=on",
+ ((struct sockaddr_un *)(ss))->sun_path);
+ } else {
+ return g_strdup_printf("unix:%s",
+ ((struct sockaddr_un *)(ps))->sun_path);
+ }
case AF_INET6:
left = "[";
right = "]";
diff --git a/ui/console-vc.c b/ui/console-vc.c
index fe20579..df13415 100644
--- a/ui/console-vc.c
+++ b/ui/console-vc.c
@@ -42,6 +42,8 @@ enum TTYState {
TTY_STATE_NORM,
TTY_STATE_ESC,
TTY_STATE_CSI,
+ TTY_STATE_G0,
+ TTY_STATE_G1,
};
typedef struct QemuTextConsole {
@@ -88,6 +90,7 @@ struct VCChardev {
int esc_params[MAX_ESC_PARAMS];
int nb_esc_params;
TextAttributes t_attrib; /* currently active text attributes */
+ TextAttributes t_attrib_saved;
int x_saved, y_saved;
};
typedef struct VCChardev VCChardev;
@@ -615,10 +618,9 @@ static void vc_put_one(VCChardev *vc, int ch)
static void vc_respond_str(VCChardev *vc, const char *buf)
{
- while (*buf) {
- vc_put_one(vc, *buf);
- buf++;
- }
+ QemuTextConsole *s = vc->console;
+
+ qemu_chr_be_write(s->chr, (const uint8_t *)buf, strlen(buf));
}
/* set cursor, checking bounds */
@@ -643,6 +645,113 @@ 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 default
+ * 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 blanks */
+ for (x1 = s->x; x1 < s->x + nr; x1++) {
+ vc_clear_xy(vc, x1, s->y);
+ }
+}
+
+/**
+ * vc_save_cursor() - saves cursor position and character attributes.
+ */
+static void vc_save_cursor(VCChardev *vc)
+{
+ QemuTextConsole *s = vc->console;
+
+ vc->x_saved = s->x;
+ vc->y_saved = s->y;
+ vc->t_attrib_saved = vc->t_attrib;
+}
+
+/**
+ * vc_restore_cursor() - restores cursor position and character
+ * attributes from saved state.
+ */
+static void vc_restore_cursor(VCChardev *vc)
+{
+ QemuTextConsole *s = vc->console;
+
+ s->x = vc->x_saved;
+ s->y = vc->y_saved;
+ vc->t_attrib = vc->t_attrib_saved;
+}
+
static void vc_putchar(VCChardev *vc, int ch)
{
QemuTextConsole *s = vc->console;
@@ -694,6 +803,16 @@ static void vc_putchar(VCChardev *vc, int ch)
vc->esc_params[i] = 0;
vc->nb_esc_params = 0;
vc->state = TTY_STATE_CSI;
+ } else if (ch == '(') {
+ vc->state = TTY_STATE_G0;
+ } else if (ch == ')') {
+ vc->state = TTY_STATE_G1;
+ } else if (ch == '7') {
+ vc_save_cursor(vc);
+ vc->state = TTY_STATE_NORM;
+ } else if (ch == '8') {
+ vc_restore_cursor(vc);
+ vc->state = TTY_STATE_NORM;
} else {
vc->state = TTY_STATE_NORM;
}
@@ -810,6 +929,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;
@@ -822,21 +944,19 @@ static void vc_putchar(VCChardev *vc, int ch)
case 6:
/* report cursor position */
response = g_strdup_printf("\033[%d;%dR",
- (s->y_base + s->y) % s->total_height + 1,
- s->x + 1);
+ s->y + 1, s->x + 1);
vc_respond_str(vc, response);
break;
}
break;
case 's':
- /* save cursor position */
- vc->x_saved = s->x;
- vc->y_saved = s->y;
+ vc_save_cursor(vc);
break;
case 'u':
- /* restore cursor position */
- s->x = vc->x_saved;
- s->y = vc->y_saved;
+ vc_restore_cursor(vc);
+ break;
+ case '@':
+ vc_csi_at(vc, vc->esc_params[0]);
break;
default:
trace_console_putchar_unhandled(ch);
@@ -844,6 +964,16 @@ static void vc_putchar(VCChardev *vc, int ch)
}
break;
}
+ break;
+ case TTY_STATE_G0: /* set character sets */
+ case TTY_STATE_G1: /* set character sets */
+ switch (ch) {
+ case 'B':
+ /* Latin-1 map */
+ break;
+ }
+ vc->state = TTY_STATE_NORM;
+ break;
}
}