Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/1.1/patches/2222091/?format=api
{ "id": 2222091, "url": "http://patchwork.ozlabs.org/api/1.1/patches/2222091/?format=api", "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20260410-qemu-vnc-v2-25-231416f76dc3@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": "<20260410-qemu-vnc-v2-25-231416f76dc3@redhat.com>", "date": "2026-04-10T19:18:47", "name": "[v2,25/67] ui/console-vc: move VT100 state machine and output FIFO into QemuVT100", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "d6012c1cfb43f0893a940d1cb0c81605c9da454a", "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/20260410-qemu-vnc-v2-25-231416f76dc3@redhat.com/mbox/", "series": [ { "id": 499494, "url": "http://patchwork.ozlabs.org/api/1.1/series/499494/?format=api", "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/list/?series=499494", "date": "2026-04-10T19:18:23", "name": "ui: add standalone VNC server over D-Bus", "version": 2, "mbox": "http://patchwork.ozlabs.org/series/499494/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2222091/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2222091/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=jSGZMHO3;\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=lists.gnu.org;\n envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n receiver=patchwork.ozlabs.org)" ], "Received": [ "from lists.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 4fsmrq4FZSz1y2d\n\tfor <incoming@patchwork.ozlabs.org>; Sat, 11 Apr 2026 05:22:03 +1000 (AEST)", "from localhost ([::1] helo=lists1p.gnu.org)\n\tby lists.gnu.org with esmtp (Exim 4.90_1)\n\t(envelope-from <qemu-devel-bounces@nongnu.org>)\n\tid 1wBHQH-0000MQ-LH; Fri, 10 Apr 2026 15:21:45 -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 1wBHQ3-0007s8-U8\n for qemu-devel@nongnu.org; Fri, 10 Apr 2026 15:21:31 -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 1wBHQ0-0001cS-JO\n for qemu-devel@nongnu.org; Fri, 10 Apr 2026 15:21:31 -0400", "from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com\n (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by\n relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3,\n cipher=TLS_AES_256_GCM_SHA384) id us-mta-687-DmQzhfBQNziv3cF7vOBDoQ-1; Fri,\n 10 Apr 2026 15:21:26 -0400", "from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com\n (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93])\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-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS\n id 6AF2119560B7\n for <qemu-devel@nongnu.org>; Fri, 10 Apr 2026 19:21:25 +0000 (UTC)", "from localhost (unknown [10.44.22.4])\n by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP\n id 1D747180057F; Fri, 10 Apr 2026 19:21:22 +0000 (UTC)" ], "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n s=mimecast20190719; t=1775848887;\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=eev7ZgDt7TuG9zqc7JFbqu+7TfwNceZf9Sx5cioSKfc=;\n b=jSGZMHO3WsMgtct5/YSdXpvnupM8zZBMRHTttw+9TCt7uZf9tGdaKOI4pWsKbNLnjbYzpI\n +Fa2NMOS6PAwkBjzfRJepxjBj/Zfv6QGDjxvNGMoHTHbJmnlok6Psaw95POW3sk0L/U3ug\n ucx8SSFML/QTy2YqB9vQLGo9C02povY=", "X-MC-Unique": "DmQzhfBQNziv3cF7vOBDoQ-1", "X-Mimecast-MFC-AGG-ID": "DmQzhfBQNziv3cF7vOBDoQ_1775848885", "From": "=?utf-8?q?Marc-Andr=C3=A9_Lureau?= <marcandre.lureau@redhat.com>", "Date": "Fri, 10 Apr 2026 23:18:47 +0400", "Subject": "[PATCH v2 25/67] 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": "<20260410-qemu-vnc-v2-25-231416f76dc3@redhat.com>", "References": "<20260410-qemu-vnc-v2-0-231416f76dc3@redhat.com>", "In-Reply-To": "<20260410-qemu-vnc-v2-0-231416f76dc3@redhat.com>", "To": "qemu-devel@nongnu.org", "Cc": "=?utf-8?q?Marc-Andr=C3=A9_Lureau?= <marcandre.lureau@redhat.com>", "X-Developer-Signature": "v=1; a=openpgp-sha256; l=32396;\n i=marcandre.lureau@redhat.com; h=from:subject:message-id;\n bh=PUHVzwpUuSJhv3fv9Q/KSd6OQTNQ0Wo8/FtWCxla3rc=;\n b=owEBbQKS/ZANAwAKAdro4Ql1lpzlAcsmYgBp2U0Uu5D6XB2ok14O8BvhaKHqEXFAu2YyAL0cT\n croY93vPcSJAjMEAAEKAB0WIQSHqb2TP4fGBtJ29i3a6OEJdZac5QUCadlNFAAKCRDa6OEJdZac\n 5eG+EACzXd7JZWoWXB5zpPyFdEg0MOD3ZubOdc4UQ7HQKHzLGlnzUKyqcQJQN08ORbXKn9SuiWL\n 42phqXNu2HLgwdl6X/CVmzMOi1D2XI4WWOpd4Gxs2A7BQKSN86HzewdcTVc3oYzocgTlaoAA0nQ\n vOk510uNaTfg4bv9N6QUZzSmRpzjCp9CtsTaPJzkqTq7RF83kWkG5uwC1JtTNZ3Z5FRLz0k9XAf\n 8Q6JLwVFAooz5OMZQA4ZVr2jjOLDg46FjAtfyRdmv0wy5g4ycIw2JPcu77MEauO+nAzrfl+esdH\n 23BKMTh0rJ/yMVyqZFjVSlh98MfU0axDH8Shv0GJgll/ENA41SchqNmyaqgPjzXg1UZT9xhhtZp\n P37IVNOWyyOydir5BRIrtK3ZHp/2++2vvUQrsF3pI298oIImN5xB5hlWRjMFYpGdxoC0Ovbf1pP\n mk7io1PKdxvRzP2pg263EvZBhIzwg0fqqWy0xLg38lsAy9Mxmf1OM4A0h8px1vmMEZWhUXy7k/f\n xiDLa8SC6hTiQuRKcEiL5Fmr07O4n9eiWpnLpjnf5YVVYjWfigw5SlELLMU830//34GdmOCehzq\n RUiO/mRJmzUYdhBz6dsM0emqWSpfynI2ckciuoL3Li9NTPu5U0WGefN+m7OGbsMtxsl2YSsnPNX\n lOiYWbhSeMFEJWA==", "X-Developer-Key": "i=marcandre.lureau@redhat.com; a=openpgp;\n fpr=87A9BD933F87C606D276F62DDAE8E10975969CE5", "X-Scanned-By": "MIMEDefang 3.4.1 on 10.30.177.93", "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": "7", "X-Spam_score": "0.7", "X-Spam_bar": "/", "X-Spam_report": "(0.7 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.54,\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 RCVD_IN_SBL_CSS=3.335, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001,\n RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001,\n SPF_PASS=-0.001 autolearn=no 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>\n---\n ui/console-vc.c | 375 +++++++++++++++++++++++++++-----------------------------\n 1 file changed, 180 insertions(+), 195 deletions(-)", "diff": "diff --git a/ui/console-vc.c b/ui/console-vc.c\nindex bba1fe614ef..5cfb3dfcf72 100644\n--- a/ui/console-vc.c\n+++ b/ui/console-vc.c\n@@ -72,6 +72,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@@ -83,8 +95,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@@ -102,15 +112,6 @@ OBJECT_DEFINE_TYPE(QemuFixedTextConsole, qemu_fixed_text_console, QEMU_FIXED_TEX\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 };\n typedef struct VCChardev VCChardev;\n \n@@ -299,36 +300,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@@ -360,16 +360,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@@ -377,30 +377,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@@ -489,103 +488,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@@ -606,14 +603,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@@ -621,7 +616,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@@ -664,10 +659,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@@ -678,17 +671,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@@ -712,10 +702,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@@ -739,12 +727,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@@ -754,10 +742,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@@ -781,61 +767,53 @@ 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 /* Feed byte through the UTF-8 DFA decoder */\n if (ch >= 0x80) {\n- switch (bh_utf8_decode(&vc->utf8_state, &vc->utf8_codepoint, ch)) {\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 /* Reset state so the decoder can resync */\n- vc->utf8_state = BH_UTF8_ACCEPT;\n+ vt->utf8_state = BH_UTF8_ACCEPT;\n break;\n default:\n /* Need more bytes */\n@@ -844,13 +822,13 @@ static void vc_putchar(VCChardev *vc, int ch)\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@@ -874,95 +852,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@@ -970,7 +948,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@@ -981,7 +959,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@@ -989,62 +967,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@@ -1056,10 +1034,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@@ -1070,7 +1048,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@@ -1083,22 +1061,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@@ -1167,9 +1144,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@@ -1193,7 +1167,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@@ -1215,6 +1189,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@@ -1244,24 +1225,28 @@ 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 \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": [ "v2", "25/67" ] }