Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/1.1/patches/2230541/?format=api
{ "id": 2230541, "url": "http://patchwork.ozlabs.org/api/1.1/patches/2230541/?format=api", "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20260430-qemu-vnc-v3-7-be96757428d0@redhat.com/", "project": { "id": 14, "url": "http://patchwork.ozlabs.org/api/1.1/projects/14/?format=api", "name": "QEMU Development", "link_name": "qemu-devel", "list_id": "qemu-devel.nongnu.org", "list_email": "qemu-devel@nongnu.org", "web_url": "", "scm_url": "", "webscm_url": "" }, "msgid": "<20260430-qemu-vnc-v3-7-be96757428d0@redhat.com>", "date": "2026-04-29T21:02:40", "name": "[v3,07/26] ui/console-vc: move VT100 state machine and output FIFO into QemuVT100", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "292ffd84956834dcc512f690835d6943a070cbbe", "submitter": { "id": 66774, "url": "http://patchwork.ozlabs.org/api/1.1/people/66774/?format=api", "name": "Marc-André Lureau", "email": "marcandre.lureau@redhat.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20260430-qemu-vnc-v3-7-be96757428d0@redhat.com/mbox/", "series": [ { "id": 502150, "url": "http://patchwork.ozlabs.org/api/1.1/series/502150/?format=api", "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/list/?series=502150", "date": "2026-04-29T21:02:34", "name": "ui: add standalone VNC server over D-Bus", "version": 3, "mbox": "http://patchwork.ozlabs.org/series/502150/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2230541/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2230541/checks/", "tags": {}, "headers": { "Return-Path": "<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>", "X-Original-To": "incoming@patchwork.ozlabs.org", "Delivered-To": "patchwork-incoming@legolas.ozlabs.org", "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=pass (1024-bit key;\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=CmyvELgG;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org\n (client-ip=209.51.188.17; helo=lists1p.gnu.org;\n envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n receiver=patchwork.ozlabs.org)" ], "Received": [ "from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17])\n\t(using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g5VDP4X24z1yGq\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 30 Apr 2026 07:04:36 +1000 (AEST)", "from localhost ([::1] helo=lists1p.gnu.org)\n\tby lists1p.gnu.org with esmtp (Exim 4.90_1)\n\t(envelope-from <qemu-devel-bounces@nongnu.org>)\n\tid 1wIC4h-0003kA-4h; Wed, 29 Apr 2026 17:04:03 -0400", "from eggs.gnu.org ([2001:470:142:3::10])\n by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <marcandre.lureau@redhat.com>)\n id 1wIC4f-0003fB-7S\n for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:04:01 -0400", "from us-smtp-delivery-124.mimecast.com ([170.10.129.124])\n by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <marcandre.lureau@redhat.com>)\n id 1wIC4c-0003JF-73\n for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:04:00 -0400", "from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com\n (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by\n relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3,\n cipher=TLS_AES_256_GCM_SHA384) id us-mta-141-0Dc5derAMsOJghMapa9ybg-1; Wed,\n 29 Apr 2026 17:03:56 -0400", "from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com\n (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest\n SHA256)\n (No client certificate requested)\n by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS\n id E57BE18003FC; Wed, 29 Apr 2026 21:03:54 +0000 (UTC)", "from localhost (unknown [10.44.22.2])\n by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP\n id 26CE630001BB; Wed, 29 Apr 2026 21:03:52 +0000 (UTC)" ], "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n s=mimecast20190719; t=1777496637;\n h=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n to:to:cc:cc:mime-version:mime-version:content-type:content-type:\n content-transfer-encoding:content-transfer-encoding:\n in-reply-to:in-reply-to:references:references;\n bh=hOiIw9bx+21x85nQF5knP0qQm5nnUYNoqlWGTUmBKLE=;\n b=CmyvELgGJ5xcaeDPps02lA/BU8xgAR4phTSs3gqSbDmMSRJVXdsrEAce6pURD7ht0g+c1V\n IACUVVb2wB1OMgiarJRaEb3b/UWtPHMbgDWFKrQPWurpOf53Nj2Bz97M0YCZQBt66PhyeF\n NKcHY1uqwB0+XMT39ytADKJsD5YYkj0=", "X-MC-Unique": "0Dc5derAMsOJghMapa9ybg-1", "X-Mimecast-MFC-AGG-ID": "0Dc5derAMsOJghMapa9ybg_1777496635", "From": "=?utf-8?q?Marc-Andr=C3=A9_Lureau?= <marcandre.lureau@redhat.com>", "Date": "Thu, 30 Apr 2026 01:02:40 +0400", "Subject": "[PATCH v3 07/26] ui/console-vc: move VT100 state machine and\n output FIFO into QemuVT100", "MIME-Version": "1.0", "Content-Type": "text/plain; charset=\"utf-8\"", "Content-Transfer-Encoding": "8bit", "Message-Id": "<20260430-qemu-vnc-v3-7-be96757428d0@redhat.com>", "References": "<20260430-qemu-vnc-v3-0-be96757428d0@redhat.com>", "In-Reply-To": "<20260430-qemu-vnc-v3-0-be96757428d0@redhat.com>", "To": "qemu-devel@nongnu.org", "Cc": "=?utf-8?q?Marc-Andr=C3=A9_Lureau?= <marcandre.lureau@redhat.com>,\n\t=?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= <philmd@linaro.org>", "X-Developer-Signature": "v=1; a=openpgp-sha256; l=32915;\n i=marcandre.lureau@redhat.com; h=from:subject:message-id;\n bh=UkwYMUsoliBfPHzYTf7cEwOOoeigeZPWYjncdjZ1IL0=;\n b=owEBbQKS/ZANAwAKAdro4Ql1lpzlAcsmYgBp8nILlAugwv64G1QI5k6aQ8+ZeHVVmWKQIILfP\n 9aAwP5Qes+JAjMEAAEKAB0WIQSHqb2TP4fGBtJ29i3a6OEJdZac5QUCafJyCwAKCRDa6OEJdZac\n 5SHiEACn4HNkFKnftewsrGO4HvXc9rtv4WJRVZXD3yS5Ike7ZoZzvPIqnjMIcs81UeAxf1VCyS+\n vyqb9MfNdypGLRcvl4qfPjXhH7Fb7RyicK2JqulJoLn6S6eJl0yu3NvM1d8+OcbBoUACYVtOdn5\n 73kTSzAkJ2BkM8kHEvAyJQH+jzD6rSBjSNT131yA/vNZWNwhjZc95iPFjhx7wSnH0ohI2P/ip2J\n dqinD138qpDWJh9tT/W1DBfxPkSVIfKxD2qQQWAo9QXrGMXCC8d79MNtsod9Bu586hvUIlKYgIq\n dLQ6K6QPxYe9I/4v6fhe7eVq7vLZQyvhRQlS7zuSRnAQ4GcPbLThZ255A2gx52aIonxGlHx6bpg\n WjurmBWtsOaX+RRSowFbiWPVZt2uLdyRzq/TNg3z9qWh//bcF8kN7XbtD1XqnsE5t7yw7GgqVe6\n eJuOKBe/LMx4jgO+PmHevs+gj5xv3JnS6AXo5j0xVUKDIdxXvzpIzurVMNzWy4NKbrbZNeZiRi4\n 2vy/oQl4z8RCD1i/Yiri9TrJ2BNMb9WmNceboVpw86vGCSwW/rxSvIvMkLvSC7IHO7GZi983f3d\n 1RaYt3D+7iaeSKuibgazU4+tbGD1qi5nyupKI8lEo7Dw9DVTj6/xRw+xEno/k6MAM3lXDrxSHrJ\n dKHoSvfCp3XbCLw==", "X-Developer-Key": "i=marcandre.lureau@redhat.com; a=openpgp;\n fpr=87A9BD933F87C606D276F62DDAE8E10975969CE5", "X-Scanned-By": "MIMEDefang 3.4.1 on 10.30.177.4", "Received-SPF": "pass client-ip=170.10.129.124;\n envelope-from=marcandre.lureau@redhat.com;\n helo=us-smtp-delivery-124.mimecast.com", "X-Spam_score_int": "-20", "X-Spam_score": "-2.1", "X-Spam_bar": "--", "X-Spam_report": "(-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001,\n DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1,\n RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001,\n SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no", "X-Spam_action": "no action", "X-BeenThere": "qemu-devel@nongnu.org", "X-Mailman-Version": "2.1.29", "Precedence": "list", "List-Id": "qemu development <qemu-devel.nongnu.org>", "List-Unsubscribe": "<https://lists.nongnu.org/mailman/options/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=unsubscribe>", "List-Archive": "<https://lists.nongnu.org/archive/html/qemu-devel>", "List-Post": "<mailto:qemu-devel@nongnu.org>", "List-Help": "<mailto:qemu-devel-request@nongnu.org?subject=help>", "List-Subscribe": "<https://lists.nongnu.org/mailman/listinfo/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=subscribe>", "Errors-To": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org", "Sender": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org" }, "content": "Move the terminal escape sequence parser state (TTYState, esc_params,\ntext attributes, saved cursor position) and the output FIFO from\nVCChardev/QemuTextConsole into QemuVT100. Rename the corresponding\nfunctions from vc_* to vt100_* to reflect they now operate on the VT100\nlayer directly, removing the indirection through vc->console->vt.\n\nAdd an out_flush callback to QemuVT100 so vt100_write() can flush\noutput without knowing about QemuTextConsole, and move FIFO/VT100\ninitialization from qemu_text_console_init() to vc_chr_open() where\nthe callback can be wired up.\n\nThis continues the decoupling of VT100 terminal emulation from the\nchardev layer, making QemuVT100 a self-contained terminal emulator.\n\nSigned-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>\nReviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>\n---\n ui/console-vc.c | 382 +++++++++++++++++++++++++++-----------------------------\n 1 file changed, 184 insertions(+), 198 deletions(-)", "diff": "diff --git a/ui/console-vc.c b/ui/console-vc.c\nindex 42d642afebb..cf1adfc3c71 100644\n--- a/ui/console-vc.c\n+++ b/ui/console-vc.c\n@@ -58,6 +58,7 @@ struct QemuVT100 {\n pixman_image_t *image;\n void (*image_update)(QemuVT100 *vt, int x, int y, int width, int height);\n \n+ ChardevVCEncoding encoding;\n int width;\n int height;\n int total_height;\n@@ -74,6 +75,18 @@ struct QemuVT100 {\n int update_x1;\n int update_y1;\n \n+ enum TTYState state;\n+ int esc_params[MAX_ESC_PARAMS];\n+ int nb_esc_params;\n+ uint32_t utf8_state; /* UTF-8 DFA decoder state */\n+ uint32_t utf8_codepoint; /* accumulated UTF-8 code point */\n+ TextAttributes t_attrib; /* currently active text attributes */\n+ TextAttributes t_attrib_saved;\n+ int x_saved, y_saved;\n+ /* fifo for key pressed */\n+ Fifo8 out_fifo;\n+ void (*out_flush)(QemuVT100 *vt);\n+\n QTAILQ_ENTRY(QemuVT100) list;\n };\n \n@@ -85,8 +98,6 @@ typedef struct QemuTextConsole {\n \n QemuVT100 vt;\n Chardev *chr;\n- /* fifo for key pressed */\n- Fifo8 out_fifo;\n } QemuTextConsole;\n \n typedef QemuConsoleClass QemuTextConsoleClass;\n@@ -103,17 +114,9 @@ OBJECT_DEFINE_TYPE(QemuFixedTextConsole, qemu_fixed_text_console, QEMU_FIXED_TEX\n \n struct VCChardev {\n Chardev parent;\n- QemuTextConsole *console;\n \n- enum TTYState state;\n- int esc_params[MAX_ESC_PARAMS];\n- int nb_esc_params;\n- uint32_t utf8_state; /* UTF-8 DFA decoder state */\n- uint32_t utf8_codepoint; /* accumulated UTF-8 code point */\n- TextAttributes t_attrib; /* currently active text attributes */\n- TextAttributes t_attrib_saved;\n- int x_saved, y_saved;\n ChardevVCEncoding encoding;\n+ QemuTextConsole *console;\n };\n typedef struct VCChardev VCChardev;\n \n@@ -302,36 +305,35 @@ static void vt100_scroll(QemuVT100 *vt, int ydelta)\n vt100_refresh(vt);\n }\n \n-static void qemu_text_console_flush(QemuTextConsole *s)\n+static void qemu_text_console_out_flush(QemuTextConsole *s)\n {\n uint32_t len, avail;\n \n len = qemu_chr_be_can_write(s->chr);\n- avail = fifo8_num_used(&s->out_fifo);\n+ avail = fifo8_num_used(&s->vt.out_fifo);\n while (len > 0 && avail > 0) {\n const uint8_t *buf;\n uint32_t size;\n \n- buf = fifo8_pop_bufptr(&s->out_fifo, MIN(len, avail), &size);\n+ buf = fifo8_pop_bufptr(&s->vt.out_fifo, MIN(len, avail), &size);\n qemu_chr_be_write(s->chr, buf, size);\n len = qemu_chr_be_can_write(s->chr);\n avail -= size;\n }\n }\n \n-static void qemu_text_console_write(QemuTextConsole *s, const void *buf, size_t len)\n+static void vt100_write(QemuVT100 *vt, const void *buf, size_t len)\n {\n uint32_t num_free;\n \n- num_free = fifo8_num_free(&s->out_fifo);\n- fifo8_push_all(&s->out_fifo, buf, MIN(num_free, len));\n- qemu_text_console_flush(s);\n+ num_free = fifo8_num_free(&vt->out_fifo);\n+ fifo8_push_all(&vt->out_fifo, buf, MIN(num_free, len));\n+ vt->out_flush(vt);\n }\n \n /* called when an ascii key is pressed */\n void qemu_text_console_handle_keysym(QemuTextConsole *s, int keysym)\n {\n- QemuVT100 *vt = &s->vt;\n uint8_t buf[16], *q;\n int c;\n \n@@ -363,16 +365,16 @@ void qemu_text_console_handle_keysym(QemuTextConsole *s, int keysym)\n *q++ = '\\033';\n *q++ = '[';\n *q++ = keysym & 0xff;\n- } else if (vt->echo && (keysym == '\\r' || keysym == '\\n')) {\n+ } else if (s->vt.echo && (keysym == '\\r' || keysym == '\\n')) {\n qemu_chr_write(s->chr, (uint8_t *)\"\\r\", 1, true);\n *q++ = '\\n';\n } else {\n *q++ = keysym;\n }\n- if (vt->echo) {\n+ if (s->vt.echo) {\n qemu_chr_write(s->chr, buf, q - buf, true);\n }\n- qemu_text_console_write(s, buf, q - buf);\n+ vt100_write(&s->vt, buf, q - buf);\n break;\n }\n }\n@@ -380,30 +382,29 @@ void qemu_text_console_handle_keysym(QemuTextConsole *s, int keysym)\n static void text_console_update(void *opaque, console_ch_t *chardata)\n {\n QemuTextConsole *s = QEMU_TEXT_CONSOLE(opaque);\n- QemuVT100 *vt = &s->vt;\n int i, j, src;\n \n- if (vt->text_x[0] <= vt->text_x[1]) {\n- src = (vt->y_base + vt->text_y[0]) * vt->width;\n- chardata += vt->text_y[0] * vt->width;\n- for (i = vt->text_y[0]; i <= vt->text_y[1]; i ++)\n- for (j = 0; j < vt->width; j++, src++) {\n+ if (s->vt.text_x[0] <= s->vt.text_x[1]) {\n+ src = (s->vt.y_base + s->vt.text_y[0]) * s->vt.width;\n+ chardata += s->vt.text_y[0] * s->vt.width;\n+ for (i = s->vt.text_y[0]; i <= s->vt.text_y[1]; i ++)\n+ for (j = 0; j < s->vt.width; j++, src++) {\n console_write_ch(chardata ++,\n- ATTR2CHTYPE(vt->cells[src].ch,\n- vt->cells[src].t_attrib.fgcol,\n- vt->cells[src].t_attrib.bgcol,\n- vt->cells[src].t_attrib.bold));\n+ ATTR2CHTYPE(s->vt.cells[src].ch,\n+ s->vt.cells[src].t_attrib.fgcol,\n+ s->vt.cells[src].t_attrib.bgcol,\n+ s->vt.cells[src].t_attrib.bold));\n }\n- dpy_text_update(QEMU_CONSOLE(s), vt->text_x[0], vt->text_y[0],\n- vt->text_x[1] - vt->text_x[0], i - vt->text_y[0]);\n- vt->text_x[0] = vt->width;\n- vt->text_y[0] = vt->height;\n- vt->text_x[1] = 0;\n- vt->text_y[1] = 0;\n+ dpy_text_update(QEMU_CONSOLE(s), s->vt.text_x[0], s->vt.text_y[0],\n+ s->vt.text_x[1] - s->vt.text_x[0], i - s->vt.text_y[0]);\n+ s->vt.text_x[0] = s->vt.width;\n+ s->vt.text_y[0] = s->vt.height;\n+ s->vt.text_x[1] = 0;\n+ s->vt.text_y[1] = 0;\n }\n- if (vt->cursor_invalidate) {\n- dpy_text_cursor(QEMU_CONSOLE(s), vt->x, vt->y);\n- vt->cursor_invalidate = 0;\n+ if (s->vt.cursor_invalidate) {\n+ dpy_text_cursor(QEMU_CONSOLE(s), s->vt.x, s->vt.y);\n+ s->vt.cursor_invalidate = 0;\n }\n }\n \n@@ -492,103 +493,101 @@ static void vt100_put_lf(QemuVT100 *vt)\n * NOTE: I know this code is not very efficient (checking every color for it\n * self) but it is more readable and better maintainable.\n */\n-static void vc_handle_escape(VCChardev *vc)\n+static void vt100_handle_escape(QemuVT100 *vt)\n {\n int i;\n \n- for (i = 0; i < vc->nb_esc_params; i++) {\n- switch (vc->esc_params[i]) {\n+ for (i = 0; i < vt->nb_esc_params; i++) {\n+ switch (vt->esc_params[i]) {\n case 0: /* reset all console attributes to default */\n- vc->t_attrib = TEXT_ATTRIBUTES_DEFAULT;\n+ vt->t_attrib = TEXT_ATTRIBUTES_DEFAULT;\n break;\n case 1:\n- vc->t_attrib.bold = 1;\n+ vt->t_attrib.bold = 1;\n break;\n case 4:\n- vc->t_attrib.uline = 1;\n+ vt->t_attrib.uline = 1;\n break;\n case 5:\n- vc->t_attrib.blink = 1;\n+ vt->t_attrib.blink = 1;\n break;\n case 7:\n- vc->t_attrib.invers = 1;\n+ vt->t_attrib.invers = 1;\n break;\n case 8:\n- vc->t_attrib.unvisible = 1;\n+ vt->t_attrib.unvisible = 1;\n break;\n case 22:\n- vc->t_attrib.bold = 0;\n+ vt->t_attrib.bold = 0;\n break;\n case 24:\n- vc->t_attrib.uline = 0;\n+ vt->t_attrib.uline = 0;\n break;\n case 25:\n- vc->t_attrib.blink = 0;\n+ vt->t_attrib.blink = 0;\n break;\n case 27:\n- vc->t_attrib.invers = 0;\n+ vt->t_attrib.invers = 0;\n break;\n case 28:\n- vc->t_attrib.unvisible = 0;\n+ vt->t_attrib.unvisible = 0;\n break;\n /* set foreground color */\n case 30:\n- vc->t_attrib.fgcol = QEMU_COLOR_BLACK;\n+ vt->t_attrib.fgcol = QEMU_COLOR_BLACK;\n break;\n case 31:\n- vc->t_attrib.fgcol = QEMU_COLOR_RED;\n+ vt->t_attrib.fgcol = QEMU_COLOR_RED;\n break;\n case 32:\n- vc->t_attrib.fgcol = QEMU_COLOR_GREEN;\n+ vt->t_attrib.fgcol = QEMU_COLOR_GREEN;\n break;\n case 33:\n- vc->t_attrib.fgcol = QEMU_COLOR_YELLOW;\n+ vt->t_attrib.fgcol = QEMU_COLOR_YELLOW;\n break;\n case 34:\n- vc->t_attrib.fgcol = QEMU_COLOR_BLUE;\n+ vt->t_attrib.fgcol = QEMU_COLOR_BLUE;\n break;\n case 35:\n- vc->t_attrib.fgcol = QEMU_COLOR_MAGENTA;\n+ vt->t_attrib.fgcol = QEMU_COLOR_MAGENTA;\n break;\n case 36:\n- vc->t_attrib.fgcol = QEMU_COLOR_CYAN;\n+ vt->t_attrib.fgcol = QEMU_COLOR_CYAN;\n break;\n case 37:\n- vc->t_attrib.fgcol = QEMU_COLOR_WHITE;\n+ vt->t_attrib.fgcol = QEMU_COLOR_WHITE;\n break;\n /* set background color */\n case 40:\n- vc->t_attrib.bgcol = QEMU_COLOR_BLACK;\n+ vt->t_attrib.bgcol = QEMU_COLOR_BLACK;\n break;\n case 41:\n- vc->t_attrib.bgcol = QEMU_COLOR_RED;\n+ vt->t_attrib.bgcol = QEMU_COLOR_RED;\n break;\n case 42:\n- vc->t_attrib.bgcol = QEMU_COLOR_GREEN;\n+ vt->t_attrib.bgcol = QEMU_COLOR_GREEN;\n break;\n case 43:\n- vc->t_attrib.bgcol = QEMU_COLOR_YELLOW;\n+ vt->t_attrib.bgcol = QEMU_COLOR_YELLOW;\n break;\n case 44:\n- vc->t_attrib.bgcol = QEMU_COLOR_BLUE;\n+ vt->t_attrib.bgcol = QEMU_COLOR_BLUE;\n break;\n case 45:\n- vc->t_attrib.bgcol = QEMU_COLOR_MAGENTA;\n+ vt->t_attrib.bgcol = QEMU_COLOR_MAGENTA;\n break;\n case 46:\n- vc->t_attrib.bgcol = QEMU_COLOR_CYAN;\n+ vt->t_attrib.bgcol = QEMU_COLOR_CYAN;\n break;\n case 47:\n- vc->t_attrib.bgcol = QEMU_COLOR_WHITE;\n+ vt->t_attrib.bgcol = QEMU_COLOR_WHITE;\n break;\n }\n }\n }\n \n-static void vc_update_xy(VCChardev *vc, int x, int y)\n+static void vt100_update_xy(QemuVT100 *vt, int x, int y)\n {\n- QemuTextConsole *s = vc->console;\n- QemuVT100 *vt = &s->vt;\n TextCell *c;\n int y1, y2;\n \n@@ -609,14 +608,12 @@ static void vc_update_xy(VCChardev *vc, int x, int y)\n c = &vt->cells[y1 * vt->width + x];\n vt100_putcharxy(vt, x, y2, c->ch,\n &(c->t_attrib));\n- vt100_invalidate_xy(&s->vt, x, y2);\n+ vt100_invalidate_xy(vt, x, y2);\n }\n }\n \n-static void vc_clear_xy(VCChardev *vc, int x, int y)\n+static void vt100_clear_xy(QemuVT100 *vt, int x, int y)\n {\n- QemuTextConsole *s = vc->console;\n- QemuVT100 *vt = &s->vt;\n int y1 = (vt->y_base + y) % vt->total_height;\n if (x >= vt->width) {\n x = vt->width - 1;\n@@ -624,7 +621,7 @@ static void vc_clear_xy(VCChardev *vc, int x, int y)\n TextCell *c = &vt->cells[y1 * vt->width + x];\n c->ch = ' ';\n c->t_attrib = TEXT_ATTRIBUTES_DEFAULT;\n- vc_update_xy(vc, x, y);\n+ vt100_update_xy(vt, x, y);\n }\n \n /*\n@@ -667,10 +664,8 @@ static uint32_t bh_utf8_decode(uint32_t *state, uint32_t *codep, uint32_t byte)\n return *state;\n }\n \n-static void vc_put_one(VCChardev *vc, int ch)\n+static void vt100_put_one(QemuVT100 *vt, int ch)\n {\n- QemuTextConsole *s = vc->console;\n- QemuVT100 *vt = &s->vt;\n TextCell *c;\n int y1;\n if (vt->x >= vt->width) {\n@@ -681,17 +676,14 @@ static void vc_put_one(VCChardev *vc, int ch)\n y1 = (vt->y_base + vt->y) % vt->total_height;\n c = &vt->cells[y1 * vt->width + vt->x];\n c->ch = ch;\n- c->t_attrib = vc->t_attrib;\n- vc_update_xy(vc, vt->x, vt->y);\n+ c->t_attrib = vt->t_attrib;\n+ vt100_update_xy(vt, vt->x, vt->y);\n vt->x++;\n }\n \n /* set cursor, checking bounds */\n-static void vc_set_cursor(VCChardev *vc, int x, int y)\n+static void vt100_set_cursor(QemuVT100 *vt, int x, int y)\n {\n- QemuTextConsole *s = vc->console;\n- QemuVT100 *vt = &s->vt;\n-\n if (x < 0) {\n x = 0;\n }\n@@ -715,10 +707,8 @@ static void vc_set_cursor(VCChardev *vc, int x, int y)\n * characters between the cursor and right margin move to the\n * left. Character attributes move with the characters.\n */\n-static void vc_csi_P(struct VCChardev *vc, unsigned int nr)\n+static void vt100_csi_P(QemuVT100 *vt, unsigned int nr)\n {\n- QemuTextConsole *s = vc->console;\n- QemuVT100 *vt = &s->vt;\n TextCell *c1, *c2;\n unsigned int x1, x2, y;\n unsigned int end, len;\n@@ -742,12 +732,12 @@ static void vc_csi_P(struct VCChardev *vc, unsigned int nr)\n c2 = &vt->cells[y * vt->width + x2];\n memmove(c1, c2, len * sizeof(*c1));\n for (end = x1 + len; x1 < end; x1++) {\n- vc_update_xy(vc, x1, vt->y);\n+ vt100_update_xy(vt, x1, vt->y);\n }\n }\n /* Clear the rest */\n for (; x1 < vt->width; x1++) {\n- vc_clear_xy(vc, x1, vt->y);\n+ vt100_clear_xy(vt, x1, vt->y);\n }\n }\n \n@@ -757,10 +747,8 @@ static void vc_csi_P(struct VCChardev *vc, unsigned int nr)\n * blank characters. Text between the cursor and right margin moves to\n * the right. Characters scrolled past the right margin are lost.\n */\n-static void vc_csi_at(struct VCChardev *vc, unsigned int nr)\n+static void vt100_csi_at(QemuVT100 *vt, unsigned int nr)\n {\n- QemuTextConsole *s = vc->console;\n- QemuVT100 *vt = &s->vt;\n TextCell *c1, *c2;\n unsigned int x1, x2, y;\n unsigned int end, len;\n@@ -784,59 +772,51 @@ static void vc_csi_at(struct VCChardev *vc, unsigned int nr)\n c2 = &vt->cells[y * vt->width + x2];\n memmove(c1, c2, len * sizeof(*c1));\n for (end = x1 + len; x1 < end; x1++) {\n- vc_update_xy(vc, x1, vt->y);\n+ vt100_update_xy(vt, x1, vt->y);\n }\n }\n /* Insert blanks */\n for (x1 = vt->x; x1 < vt->x + nr; x1++) {\n- vc_clear_xy(vc, x1, vt->y);\n+ vt100_clear_xy(vt, x1, vt->y);\n }\n }\n \n /**\n- * vc_save_cursor() - saves cursor position and character attributes.\n+ * vt100_save_cursor() - saves cursor position and character attributes.\n */\n-static void vc_save_cursor(VCChardev *vc)\n+static void vt100_save_cursor(QemuVT100 *vt)\n {\n- QemuTextConsole *s = vc->console;\n- QemuVT100 *vt = &s->vt;\n-\n- vc->x_saved = vt->x;\n- vc->y_saved = vt->y;\n- vc->t_attrib_saved = vc->t_attrib;\n+ vt->x_saved = vt->x;\n+ vt->y_saved = vt->y;\n+ vt->t_attrib_saved = vt->t_attrib;\n }\n \n /**\n- * vc_restore_cursor() - restores cursor position and character\n+ * vt100_restore_cursor() - restores cursor position and character\n * attributes from saved state.\n */\n-static void vc_restore_cursor(VCChardev *vc)\n+static void vt100_restore_cursor(QemuVT100 *vt)\n {\n- QemuTextConsole *s = vc->console;\n- QemuVT100 *vt = &s->vt;\n-\n- vt->x = vc->x_saved;\n- vt->y = vc->y_saved;\n- vc->t_attrib = vc->t_attrib_saved;\n+ vt->x = vt->x_saved;\n+ vt->y = vt->y_saved;\n+ vt->t_attrib = vt->t_attrib_saved;\n }\n \n-static void vc_putchar(VCChardev *vc, int ch)\n+static void vt100_putchar(QemuVT100 *vt, int ch)\n {\n- QemuTextConsole *s = vc->console;\n- QemuVT100 *vt = &s->vt;\n int i;\n int x, y;\n g_autofree char *response = NULL;\n \n- switch(vc->state) {\n+ switch (vt->state) {\n case TTY_STATE_NORM:\n- if (ch >= 0x80 && vc->encoding == CHARDEV_VC_ENCODING_UTF8) {\n- switch (bh_utf8_decode(&vc->utf8_state, &vc->utf8_codepoint, ch)) {\n+ if (ch >= 0x80 && vt->encoding == CHARDEV_VC_ENCODING_UTF8) {\n+ switch (bh_utf8_decode(&vt->utf8_state, &vt->utf8_codepoint, ch)) {\n case BH_UTF8_ACCEPT:\n- vc_put_one(vc, unicode_to_cp437(vc->utf8_codepoint));\n+ vt100_put_one(vt, unicode_to_cp437(vt->utf8_codepoint));\n break;\n case BH_UTF8_REJECT:\n- vc->utf8_state = BH_UTF8_ACCEPT;\n+ vt->utf8_state = BH_UTF8_ACCEPT;\n break;\n default:\n /* Need more bytes */\n@@ -844,14 +824,13 @@ static void vc_putchar(VCChardev *vc, int ch)\n }\n break;\n }\n- /* ASCII byte: abort any pending UTF-8 sequence */\n- vc->utf8_state = BH_UTF8_ACCEPT;\n+ vt->utf8_state = BH_UTF8_ACCEPT;\n switch(ch) {\n case '\\r': /* carriage return */\n vt->x = 0;\n break;\n case '\\n': /* newline */\n- vt100_put_lf(&s->vt);\n+ vt100_put_lf(vt);\n break;\n case '\\b': /* backspace */\n if (vt->x > 0)\n@@ -875,95 +854,95 @@ static void vc_putchar(VCChardev *vc, int ch)\n /* SI (shift in), character set 0 (ignored) */\n break;\n case 27: /* esc (introducing an escape sequence) */\n- vc->state = TTY_STATE_ESC;\n+ vt->state = TTY_STATE_ESC;\n break;\n default:\n- vc_put_one(vc, ch);\n+ vt100_put_one(vt, ch);\n break;\n }\n break;\n case TTY_STATE_ESC: /* check if it is a terminal escape sequence */\n if (ch == '[') {\n for(i=0;i<MAX_ESC_PARAMS;i++)\n- vc->esc_params[i] = 0;\n- vc->nb_esc_params = 0;\n- vc->state = TTY_STATE_CSI;\n+ vt->esc_params[i] = 0;\n+ vt->nb_esc_params = 0;\n+ vt->state = TTY_STATE_CSI;\n } else if (ch == '(') {\n- vc->state = TTY_STATE_G0;\n+ vt->state = TTY_STATE_G0;\n } else if (ch == ')') {\n- vc->state = TTY_STATE_G1;\n+ vt->state = TTY_STATE_G1;\n } else if (ch == ']' || ch == 'P' || ch == 'X'\n || ch == '^' || ch == '_') {\n /* String sequences: OSC, DCS, SOS, PM, APC */\n- vc->state = TTY_STATE_OSC;\n+ vt->state = TTY_STATE_OSC;\n } else if (ch == '7') {\n- vc_save_cursor(vc);\n- vc->state = TTY_STATE_NORM;\n+ vt100_save_cursor(vt);\n+ vt->state = TTY_STATE_NORM;\n } else if (ch == '8') {\n- vc_restore_cursor(vc);\n- vc->state = TTY_STATE_NORM;\n+ vt100_restore_cursor(vt);\n+ vt->state = TTY_STATE_NORM;\n } else {\n- vc->state = TTY_STATE_NORM;\n+ vt->state = TTY_STATE_NORM;\n }\n break;\n case TTY_STATE_CSI: /* handle escape sequence parameters */\n if (ch >= '0' && ch <= '9') {\n- if (vc->nb_esc_params < MAX_ESC_PARAMS) {\n- int *param = &vc->esc_params[vc->nb_esc_params];\n+ if (vt->nb_esc_params < MAX_ESC_PARAMS) {\n+ int *param = &vt->esc_params[vt->nb_esc_params];\n int digit = (ch - '0');\n \n *param = (*param <= (INT_MAX - digit) / 10) ?\n *param * 10 + digit : INT_MAX;\n }\n } else {\n- if (vc->nb_esc_params < MAX_ESC_PARAMS)\n- vc->nb_esc_params++;\n+ if (vt->nb_esc_params < MAX_ESC_PARAMS)\n+ vt->nb_esc_params++;\n if (ch == ';' || ch == '?') {\n break;\n }\n- trace_console_putchar_csi(vc->esc_params[0], vc->esc_params[1],\n- ch, vc->nb_esc_params);\n- vc->state = TTY_STATE_NORM;\n+ trace_console_putchar_csi(vt->esc_params[0], vt->esc_params[1],\n+ ch, vt->nb_esc_params);\n+ vt->state = TTY_STATE_NORM;\n switch(ch) {\n case 'A':\n /* move cursor up */\n- if (vc->esc_params[0] == 0) {\n- vc->esc_params[0] = 1;\n+ if (vt->esc_params[0] == 0) {\n+ vt->esc_params[0] = 1;\n }\n- vc_set_cursor(vc, vt->x, vt->y - vc->esc_params[0]);\n+ vt100_set_cursor(vt, vt->x, vt->y - vt->esc_params[0]);\n break;\n case 'B':\n /* move cursor down */\n- if (vc->esc_params[0] == 0) {\n- vc->esc_params[0] = 1;\n+ if (vt->esc_params[0] == 0) {\n+ vt->esc_params[0] = 1;\n }\n- vc_set_cursor(vc, vt->x, vt->y + vc->esc_params[0]);\n+ vt100_set_cursor(vt, vt->x, vt->y + vt->esc_params[0]);\n break;\n case 'C':\n /* move cursor right */\n- if (vc->esc_params[0] == 0) {\n- vc->esc_params[0] = 1;\n+ if (vt->esc_params[0] == 0) {\n+ vt->esc_params[0] = 1;\n }\n- vc_set_cursor(vc, vt->x + vc->esc_params[0], vt->y);\n+ vt100_set_cursor(vt, vt->x + vt->esc_params[0], vt->y);\n break;\n case 'D':\n /* move cursor left */\n- if (vc->esc_params[0] == 0) {\n- vc->esc_params[0] = 1;\n+ if (vt->esc_params[0] == 0) {\n+ vt->esc_params[0] = 1;\n }\n- vc_set_cursor(vc, vt->x - vc->esc_params[0], vt->y);\n+ vt100_set_cursor(vt, vt->x - vt->esc_params[0], vt->y);\n break;\n case 'G':\n /* move cursor to column */\n- vc_set_cursor(vc, vc->esc_params[0] - 1, vt->y);\n+ vt100_set_cursor(vt, vt->esc_params[0] - 1, vt->y);\n break;\n case 'f':\n case 'H':\n /* move cursor to row, column */\n- vc_set_cursor(vc, vc->esc_params[1] - 1, vc->esc_params[0] - 1);\n+ vt100_set_cursor(vt, vt->esc_params[1] - 1, vt->esc_params[0] - 1);\n break;\n case 'J':\n- switch (vc->esc_params[0]) {\n+ switch (vt->esc_params[0]) {\n case 0:\n /* clear to end of screen */\n for (y = vt->y; y < vt->height; y++) {\n@@ -971,7 +950,7 @@ static void vc_putchar(VCChardev *vc, int ch)\n if (y == vt->y && x < vt->x) {\n continue;\n }\n- vc_clear_xy(vc, x, y);\n+ vt100_clear_xy(vt, x, y);\n }\n }\n break;\n@@ -982,7 +961,7 @@ static void vc_putchar(VCChardev *vc, int ch)\n if (y == vt->y && x > vt->x) {\n break;\n }\n- vc_clear_xy(vc, x, y);\n+ vt100_clear_xy(vt, x, y);\n }\n }\n break;\n@@ -990,62 +969,62 @@ static void vc_putchar(VCChardev *vc, int ch)\n /* clear entire screen */\n for (y = 0; y < vt->height; y++) {\n for (x = 0; x < vt->width; x++) {\n- vc_clear_xy(vc, x, y);\n+ vt100_clear_xy(vt, x, y);\n }\n }\n break;\n }\n break;\n case 'K':\n- switch (vc->esc_params[0]) {\n+ switch (vt->esc_params[0]) {\n case 0:\n /* clear to eol */\n for(x = vt->x; x < vt->width; x++) {\n- vc_clear_xy(vc, x, vt->y);\n+ vt100_clear_xy(vt, x, vt->y);\n }\n break;\n case 1:\n /* clear from beginning of line */\n for (x = 0; x <= vt->x && x < vt->width; x++) {\n- vc_clear_xy(vc, x, vt->y);\n+ vt100_clear_xy(vt, x, vt->y);\n }\n break;\n case 2:\n /* clear entire line */\n for(x = 0; x < vt->width; x++) {\n- vc_clear_xy(vc, x, vt->y);\n+ vt100_clear_xy(vt, x, vt->y);\n }\n break;\n }\n break;\n case 'P':\n- vc_csi_P(vc, vc->esc_params[0]);\n+ vt100_csi_P(vt, vt->esc_params[0]);\n break;\n case 'm':\n- vc_handle_escape(vc);\n+ vt100_handle_escape(vt);\n break;\n case 'n':\n- switch (vc->esc_params[0]) {\n+ switch (vt->esc_params[0]) {\n case 5:\n /* report console status (always succeed)*/\n- qemu_text_console_write(s, \"\\033[0n\", 4);\n+ vt100_write(vt, \"\\033[0n\", 4);\n break;\n case 6:\n /* report cursor position */\n response = g_strdup_printf(\"\\033[%d;%dR\",\n vt->y + 1, vt->x + 1);\n- qemu_text_console_write(s, response, strlen(response));\n+ vt100_write(vt, response, strlen(response));\n break;\n }\n break;\n case 's':\n- vc_save_cursor(vc);\n+ vt100_save_cursor(vt);\n break;\n case 'u':\n- vc_restore_cursor(vc);\n+ vt100_restore_cursor(vt);\n break;\n case '@':\n- vc_csi_at(vc, vc->esc_params[0]);\n+ vt100_csi_at(vt, vt->esc_params[0]);\n break;\n default:\n trace_console_putchar_unhandled(ch);\n@@ -1057,10 +1036,10 @@ static void vc_putchar(VCChardev *vc, int ch)\n case TTY_STATE_OSC: /* Operating System Command: ESC ] ... BEL/ST */\n if (ch == '\\a') {\n /* BEL terminates OSC */\n- vc->state = TTY_STATE_NORM;\n+ vt->state = TTY_STATE_NORM;\n } else if (ch == 27) {\n /* ESC might start ST (ESC \\) */\n- vc->state = TTY_STATE_ESC;\n+ vt->state = TTY_STATE_ESC;\n }\n /* All other bytes are silently consumed */\n break;\n@@ -1071,7 +1050,7 @@ static void vc_putchar(VCChardev *vc, int ch)\n /* Latin-1 map */\n break;\n }\n- vc->state = TTY_STATE_NORM;\n+ vt->state = TTY_STATE_NORM;\n break;\n }\n }\n@@ -1084,22 +1063,21 @@ static int vc_chr_write(Chardev *chr, const uint8_t *buf, int len)\n {\n VCChardev *drv = VC_CHARDEV(chr);\n QemuTextConsole *s = drv->console;\n- QemuVT100 *vt = &s->vt;\n int i;\n \n- vt->update_x0 = vt->width * FONT_WIDTH;\n- vt->update_y0 = vt->height * FONT_HEIGHT;\n- vt->update_x1 = 0;\n- vt->update_y1 = 0;\n- vt100_show_cursor(vt, 0);\n+ s->vt.update_x0 = s->vt.width * FONT_WIDTH;\n+ s->vt.update_y0 = s->vt.height * FONT_HEIGHT;\n+ s->vt.update_x1 = 0;\n+ s->vt.update_y1 = 0;\n+ vt100_show_cursor(&s->vt, 0);\n for(i = 0; i < len; i++) {\n- vc_putchar(drv, buf[i]);\n+ vt100_putchar(&s->vt, buf[i]);\n }\n- vt100_show_cursor(vt, 1);\n- if (vt->update_x0 < vt->update_x1) {\n- vt100_image_update(vt, vt->update_x0, vt->update_y0,\n- vt->update_x1 - vt->update_x0,\n- vt->update_y1 - vt->update_y0);\n+ vt100_show_cursor(&s->vt, 1);\n+ if (s->vt.update_x0 < s->vt.update_x1) {\n+ vt100_image_update(&s->vt, s->vt.update_x0, s->vt.update_y0,\n+ s->vt.update_x1 - s->vt.update_x0,\n+ s->vt.update_y1 - s->vt.update_y0);\n }\n return len;\n }\n@@ -1168,9 +1146,6 @@ qemu_text_console_init(Object *obj)\n {\n QemuTextConsole *c = QEMU_TEXT_CONSOLE(obj);\n \n- QTAILQ_INSERT_HEAD(&vt100s, &c->vt, list);\n- fifo8_create(&c->out_fifo, 16);\n- c->vt.total_height = DEFAULT_BACKSCROLL;\n QEMU_CONSOLE(c)->hw_ops = &text_console_ops;\n QEMU_CONSOLE(c)->hw = c;\n }\n@@ -1194,7 +1169,7 @@ static void vc_chr_accept_input(Chardev *chr)\n {\n VCChardev *drv = VC_CHARDEV(chr);\n \n- qemu_text_console_flush(drv->console);\n+ qemu_text_console_out_flush(drv->console);\n }\n \n static void vc_chr_set_echo(Chardev *chr, bool echo)\n@@ -1216,6 +1191,13 @@ static void text_console_image_update(QemuVT100 *vt, int x, int y, int width, in\n dpy_gfx_update(QEMU_CONSOLE(console), x, y, width, height);\n }\n \n+static void text_console_out_flush(QemuVT100 *vt)\n+{\n+ QemuTextConsole *console = container_of(vt, QemuTextConsole, vt);\n+\n+ qemu_text_console_out_flush(console);\n+}\n+\n static bool vc_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)\n {\n ChardevVC *vc = backend->u.vc.data;\n@@ -1245,27 +1227,31 @@ static bool vc_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)\n s = QEMU_TEXT_CONSOLE(object_new(TYPE_QEMU_FIXED_TEXT_CONSOLE));\n }\n \n+ QTAILQ_INSERT_HEAD(&vt100s, &s->vt, list);\n+ fifo8_create(&s->vt.out_fifo, 16);\n+ s->vt.total_height = DEFAULT_BACKSCROLL;\n dpy_gfx_replace_surface(QEMU_CONSOLE(s), qemu_create_displaysurface(width, height));\n s->vt.image_update = text_console_image_update;\n+ s->vt.out_flush = text_console_out_flush;\n \n s->chr = chr;\n drv->console = s;\n if (vc->has_encoding) {\n- drv->encoding = vc->encoding;\n+ drv->encoding = s->vt.encoding = vc->encoding;\n }\n \n /* set current text attributes to default */\n- drv->t_attrib = TEXT_ATTRIBUTES_DEFAULT;\n+ s->vt.t_attrib = TEXT_ATTRIBUTES_DEFAULT;\n vt100_set_image(&s->vt, QEMU_CONSOLE(s)->surface->image);\n \n if (chr->label) {\n char *msg;\n \n- drv->t_attrib.bgcol = QEMU_COLOR_BLUE;\n+ s->vt.t_attrib.bgcol = QEMU_COLOR_BLUE;\n msg = g_strdup_printf(\"%s console\\r\\n\", chr->label);\n qemu_chr_write(chr, (uint8_t *)msg, strlen(msg), true);\n g_free(msg);\n- drv->t_attrib = TEXT_ATTRIBUTES_DEFAULT;\n+ s->vt.t_attrib = TEXT_ATTRIBUTES_DEFAULT;\n }\n \n qemu_chr_be_event(chr, CHR_EVENT_OPENED);\n", "prefixes": [ "v3", "07/26" ] }