@samitouri / QOSamiQemu / commits / cd579196da

ui/console-vc: introduce QemuVT100

Start moving VT100 emulation specific code in a different structure. Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

Marc-André Lureau committed Feb 18, 2026 at 23:49 UTC cd579196dacf54e4b3ad120c54f6d86fea4aaef4
1 file changed +210 -189
ui/console-vc.c
+210 -189
@@ -47,9 +47,7 @@ enum TTYState {
47 TTY_STATE_OSC,
48 };
49
50 -typedef struct QemuTextConsole {
51 - QemuConsole parent;
52 -
50 +typedef struct QemuVT100 {
51 int width;
52 int height;
53 int total_height;
@@ -65,7 +63,12 @@ typedef struct QemuTextConsole {
63 int update_y0;
64 int update_x1;
65 int update_y1;
66 +} QemuVT100;
67
68 +typedef struct QemuTextConsole {
69 + QemuConsole parent;
70 +
71 + QemuVT100 vt;
72 Chardev *chr;
73 /* fifo for key pressed */
74 Fifo8 out_fifo;
@@ -180,37 +183,40 @@ static void vga_putcharxy(QemuConsole *s, int x, int y, int ch,
183
184 static void invalidate_xy(QemuTextConsole *s, int x, int y)
185 {
186 + QemuVT100 *vt = &s->vt;
187 +
188 if (!qemu_console_is_visible(QEMU_CONSOLE(s))) {
189 return;
190 }
186 - if (s->update_x0 > x * FONT_WIDTH)
187 - s->update_x0 = x * FONT_WIDTH;
188 - if (s->update_y0 > y * FONT_HEIGHT)
189 - s->update_y0 = y * FONT_HEIGHT;
190 - if (s->update_x1 < (x + 1) * FONT_WIDTH)
191 - s->update_x1 = (x + 1) * FONT_WIDTH;
192 - if (s->update_y1 < (y + 1) * FONT_HEIGHT)
193 - s->update_y1 = (y + 1) * FONT_HEIGHT;
191 + if (vt->update_x0 > x * FONT_WIDTH)
192 + vt->update_x0 = x * FONT_WIDTH;
193 + if (vt->update_y0 > y * FONT_HEIGHT)
194 + vt->update_y0 = y * FONT_HEIGHT;
195 + if (vt->update_x1 < (x + 1) * FONT_WIDTH)
196 + vt->update_x1 = (x + 1) * FONT_WIDTH;
197 + if (vt->update_y1 < (y + 1) * FONT_HEIGHT)
198 + vt->update_y1 = (y + 1) * FONT_HEIGHT;
199 }
200
201 static void console_show_cursor(QemuTextConsole *s, int show)
202 {
203 + QemuVT100 *vt = &s->vt;
204 TextCell *c;
205 int y, y1;
200 - int x = s->x;
206 + int x = vt->x;
207
202 - s->cursor_invalidate = 1;
208 + vt->cursor_invalidate = 1;
209
204 - if (x >= s->width) {
205 - x = s->width - 1;
210 + if (x >= vt->width) {
211 + x = vt->width - 1;
212 }
207 - y1 = (s->y_base + s->y) % s->total_height;
208 - y = y1 - s->y_displayed;
213 + y1 = (vt->y_base + vt->y) % vt->total_height;
214 + y = y1 - vt->y_displayed;
215 if (y < 0) {
210 - y += s->total_height;
216 + y += vt->total_height;
217 }
212 - if (y < s->height) {
213 - c = &s->cells[y1 * s->width + x];
218 + if (y < vt->height) {
219 + c = &vt->cells[y1 * vt->width + x];
220 if (show && cursor_visible_phase) {
221 TextAttributes t_attrib = TEXT_ATTRIBUTES_DEFAULT;
222 t_attrib.invers = !(t_attrib.invers); /* invert fg and bg */
@@ -225,27 +231,28 @@ static void console_show_cursor(QemuTextConsole *s, int show)
231 static void console_refresh(QemuTextConsole *s)
232 {
233 DisplaySurface *surface = qemu_console_surface(QEMU_CONSOLE(s));
234 + QemuVT100 *vt = &s->vt;
235 TextCell *c;
236 int x, y, y1;
237
238 assert(surface);
232 - s->text_x[0] = 0;
233 - s->text_y[0] = 0;
234 - s->text_x[1] = s->width - 1;
235 - s->text_y[1] = s->height - 1;
236 - s->cursor_invalidate = 1;
239 + vt->text_x[0] = 0;
240 + vt->text_y[0] = 0;
241 + vt->text_x[1] = vt->width - 1;
242 + vt->text_y[1] = vt->height - 1;
243 + vt->cursor_invalidate = 1;
244
245 qemu_console_fill_rect(QEMU_CONSOLE(s), 0, 0, surface_width(surface), surface_height(surface),
246 color_table_rgb[0][QEMU_COLOR_BLACK]);
240 - y1 = s->y_displayed;
241 - for (y = 0; y < s->height; y++) {
242 - c = s->cells + y1 * s->width;
243 - for (x = 0; x < s->width; x++) {
247 + y1 = vt->y_displayed;
248 + for (y = 0; y < vt->height; y++) {
249 + c = vt->cells + y1 * vt->width;
250 + for (x = 0; x < vt->width; x++) {
251 vga_putcharxy(QEMU_CONSOLE(s), x, y, c->ch,
252 &(c->t_attrib));
253 c++;
254 }
248 - if (++y1 == s->total_height) {
255 + if (++y1 == vt->total_height) {
256 y1 = 0;
257 }
258 }
@@ -256,28 +263,29 @@ static void console_refresh(QemuTextConsole *s)
263
264 static void console_scroll(QemuTextConsole *s, int ydelta)
265 {
266 + QemuVT100 *vt = &s->vt;
267 int i, y1;
268
269 if (ydelta > 0) {
270 for(i = 0; i < ydelta; i++) {
263 - if (s->y_displayed == s->y_base)
271 + if (vt->y_displayed == vt->y_base)
272 break;
265 - if (++s->y_displayed == s->total_height)
266 - s->y_displayed = 0;
273 + if (++vt->y_displayed == vt->total_height)
274 + vt->y_displayed = 0;
275 }
276 } else {
277 ydelta = -ydelta;
270 - i = s->backscroll_height;
271 - if (i > s->total_height - s->height)
272 - i = s->total_height - s->height;
273 - y1 = s->y_base - i;
278 + i = vt->backscroll_height;
279 + if (i > vt->total_height - vt->height)
280 + i = vt->total_height - vt->height;
281 + y1 = vt->y_base - i;
282 if (y1 < 0)
275 - y1 += s->total_height;
283 + y1 += vt->total_height;
284 for(i = 0; i < ydelta; i++) {
277 - if (s->y_displayed == y1)
285 + if (vt->y_displayed == y1)
286 break;
279 - if (--s->y_displayed < 0)
280 - s->y_displayed = s->total_height - 1;
287 + if (--vt->y_displayed < 0)
288 + vt->y_displayed = vt->total_height - 1;
289 }
290 }
291 console_refresh(s);
@@ -303,6 +311,7 @@ static void kbd_send_chars(QemuTextConsole *s)
311 /* called when an ascii key is pressed */
312 void qemu_text_console_handle_keysym(QemuTextConsole *s, int keysym)
313 {
314 + QemuVT100 *vt = &s->vt;
315 uint8_t buf[16], *q;
316 int c;
317 uint32_t num_free;
@@ -335,13 +344,13 @@ void qemu_text_console_handle_keysym(QemuTextConsole *s, int keysym)
344 *q++ = '\033';
345 *q++ = '[';
346 *q++ = keysym & 0xff;
338 - } else if (s->echo && (keysym == '\r' || keysym == '\n')) {
347 + } else if (vt->echo && (keysym == '\r' || keysym == '\n')) {
348 qemu_chr_write(s->chr, (uint8_t *)"\r", 1, true);
349 *q++ = '\n';
350 } else {
351 *q++ = keysym;
352 }
344 - if (s->echo) {
353 + if (vt->echo) {
354 qemu_chr_write(s->chr, buf, q - buf, true);
355 }
356 num_free = fifo8_num_free(&s->out_fifo);
@@ -354,29 +363,30 @@ void qemu_text_console_handle_keysym(QemuTextConsole *s, int keysym)
363 static void text_console_update(void *opaque, console_ch_t *chardata)
364 {
365 QemuTextConsole *s = QEMU_TEXT_CONSOLE(opaque);
366 + QemuVT100 *vt = &s->vt;
367 int i, j, src;
368
359 - if (s->text_x[0] <= s->text_x[1]) {
360 - src = (s->y_base + s->text_y[0]) * s->width;
361 - chardata += s->text_y[0] * s->width;
362 - for (i = s->text_y[0]; i <= s->text_y[1]; i ++)
363 - for (j = 0; j < s->width; j++, src++) {
369 + if (vt->text_x[0] <= vt->text_x[1]) {
370 + src = (vt->y_base + vt->text_y[0]) * vt->width;
371 + chardata += vt->text_y[0] * vt->width;
372 + for (i = vt->text_y[0]; i <= vt->text_y[1]; i ++)
373 + for (j = 0; j < vt->width; j++, src++) {
374 console_write_ch(chardata ++,
365 - ATTR2CHTYPE(s->cells[src].ch,
366 - s->cells[src].t_attrib.fgcol,
367 - s->cells[src].t_attrib.bgcol,
368 - s->cells[src].t_attrib.bold));
375 + ATTR2CHTYPE(vt->cells[src].ch,
376 + vt->cells[src].t_attrib.fgcol,
377 + vt->cells[src].t_attrib.bgcol,
378 + vt->cells[src].t_attrib.bold));
379 }
370 - dpy_text_update(QEMU_CONSOLE(s), s->text_x[0], s->text_y[0],
371 - s->text_x[1] - s->text_x[0], i - s->text_y[0]);
372 - s->text_x[0] = s->width;
373 - s->text_y[0] = s->height;
374 - s->text_x[1] = 0;
375 - s->text_y[1] = 0;
380 + dpy_text_update(QEMU_CONSOLE(s), vt->text_x[0], vt->text_y[0],
381 + vt->text_x[1] - vt->text_x[0], i - vt->text_y[0]);
382 + vt->text_x[0] = vt->width;
383 + vt->text_y[0] = vt->height;
384 + vt->text_x[1] = 0;
385 + vt->text_y[1] = 0;
386 }
377 - if (s->cursor_invalidate) {
378 - dpy_text_cursor(QEMU_CONSOLE(s), s->x, s->y);
379 - s->cursor_invalidate = 0;
387 + if (vt->cursor_invalidate) {
388 + dpy_text_cursor(QEMU_CONSOLE(s), vt->x, vt->y);
389 + vt->cursor_invalidate = 0;
390 }
391 }
392
@@ -390,76 +400,77 @@ static void text_console_resize(QemuTextConsole *t)
400
401 w = surface_width(s->surface) / FONT_WIDTH;
402 h = surface_height(s->surface) / FONT_HEIGHT;
393 - if (w == t->width && h == t->height) {
403 + if (w == t->vt.width && h == t->vt.height) {
404 return;
405 }
406
397 - last_width = t->width;
398 - t->width = w;
399 - t->height = h;
407 + last_width = t->vt.width;
408 + t->vt.width = w;
409 + t->vt.height = h;
410
401 - w1 = MIN(t->width, last_width);
411 + w1 = MIN(t->vt.width, last_width);
412
403 - cells = g_new(TextCell, t->width * t->total_height + 1);
404 - for (y = 0; y < t->total_height; y++) {
405 - c = &cells[y * t->width];
413 + cells = g_new(TextCell, t->vt.width * t->vt.total_height + 1);
414 + for (y = 0; y < t->vt.total_height; y++) {
415 + c = &cells[y * t->vt.width];
416 if (w1 > 0) {
407 - c1 = &t->cells[y * last_width];
417 + c1 = &t->vt.cells[y * last_width];
418 for (x = 0; x < w1; x++) {
419 *c++ = *c1++;
420 }
421 }
412 - for (x = w1; x < t->width; x++) {
422 + for (x = w1; x < t->vt.width; x++) {
423 c->ch = ' ';
424 c->t_attrib = TEXT_ATTRIBUTES_DEFAULT;
425 c++;
426 }
427 }
418 - g_free(t->cells);
419 - t->cells = cells;
428 + g_free(t->vt.cells);
429 + t->vt.cells = cells;
430 }
431
432 static void vc_put_lf(VCChardev *vc)
433 {
434 QemuTextConsole *s = vc->console;
435 + QemuVT100 *vt = &s->vt;
436 TextCell *c;
437 int x, y1;
438
428 - s->y++;
429 - if (s->y >= s->height) {
430 - s->y = s->height - 1;
439 + vt->y++;
440 + if (vt->y >= vt->height) {
441 + vt->y = vt->height - 1;
442
432 - if (s->y_displayed == s->y_base) {
433 - if (++s->y_displayed == s->total_height)
434 - s->y_displayed = 0;
443 + if (vt->y_displayed == vt->y_base) {
444 + if (++vt->y_displayed == vt->total_height)
445 + vt->y_displayed = 0;
446 }
436 - if (++s->y_base == s->total_height)
437 - s->y_base = 0;
438 - if (s->backscroll_height < s->total_height)
439 - s->backscroll_height++;
440 - y1 = (s->y_base + s->height - 1) % s->total_height;
441 - c = &s->cells[y1 * s->width];
442 - for(x = 0; x < s->width; x++) {
447 + if (++vt->y_base == vt->total_height)
448 + vt->y_base = 0;
449 + if (vt->backscroll_height < vt->total_height)
450 + vt->backscroll_height++;
451 + y1 = (vt->y_base + vt->height - 1) % vt->total_height;
452 + c = &vt->cells[y1 * vt->width];
453 + for(x = 0; x < vt->width; x++) {
454 c->ch = ' ';
455 c->t_attrib = TEXT_ATTRIBUTES_DEFAULT;
456 c++;
457 }
447 - if (s->y_displayed == s->y_base) {
448 - s->text_x[0] = 0;
449 - s->text_y[0] = 0;
450 - s->text_x[1] = s->width - 1;
451 - s->text_y[1] = s->height - 1;
458 + if (vt->y_displayed == vt->y_base) {
459 + vt->text_x[0] = 0;
460 + vt->text_y[0] = 0;
461 + vt->text_x[1] = vt->width - 1;
462 + vt->text_y[1] = vt->height - 1;
463
464 qemu_console_bitblt(QEMU_CONSOLE(s), 0, FONT_HEIGHT, 0, 0,
454 - s->width * FONT_WIDTH,
455 - (s->height - 1) * FONT_HEIGHT);
456 - qemu_console_fill_rect(QEMU_CONSOLE(s), 0, (s->height - 1) * FONT_HEIGHT,
457 - s->width * FONT_WIDTH, FONT_HEIGHT,
465 + vt->width * FONT_WIDTH,
466 + (vt->height - 1) * FONT_HEIGHT);
467 + qemu_console_fill_rect(QEMU_CONSOLE(s), 0, (vt->height - 1) * FONT_HEIGHT,
468 + vt->width * FONT_WIDTH, FONT_HEIGHT,
469 color_table_rgb[0][TEXT_ATTRIBUTES_DEFAULT.bgcol]);
459 - s->update_x0 = 0;
460 - s->update_y0 = 0;
461 - s->update_x1 = s->width * FONT_WIDTH;
462 - s->update_y1 = s->height * FONT_HEIGHT;
470 + vt->update_x0 = 0;
471 + vt->update_y0 = 0;
472 + vt->update_x1 = vt->width * FONT_WIDTH;
473 + vt->update_y1 = vt->height * FONT_HEIGHT;
474 }
475 }
476 }
@@ -564,24 +575,25 @@ static void vc_handle_escape(VCChardev *vc)
575 static void vc_update_xy(VCChardev *vc, int x, int y)
576 {
577 QemuTextConsole *s = vc->console;
578 + QemuVT100 *vt = &s->vt;
579 TextCell *c;
580 int y1, y2;
581
570 - s->text_x[0] = MIN(s->text_x[0], x);
571 - s->text_x[1] = MAX(s->text_x[1], x);
572 - s->text_y[0] = MIN(s->text_y[0], y);
573 - s->text_y[1] = MAX(s->text_y[1], y);
582 + vt->text_x[0] = MIN(vt->text_x[0], x);
583 + vt->text_x[1] = MAX(vt->text_x[1], x);
584 + vt->text_y[0] = MIN(vt->text_y[0], y);
585 + vt->text_y[1] = MAX(vt->text_y[1], y);
586
575 - y1 = (s->y_base + y) % s->total_height;
576 - y2 = y1 - s->y_displayed;
587 + y1 = (vt->y_base + y) % vt->total_height;
588 + y2 = y1 - vt->y_displayed;
589 if (y2 < 0) {
578 - y2 += s->total_height;
590 + y2 += vt->total_height;
591 }
580 - if (y2 < s->height) {
581 - if (x >= s->width) {
582 - x = s->width - 1;
592 + if (y2 < vt->height) {
593 + if (x >= vt->width) {
594 + x = vt->width - 1;
595 }
584 - c = &s->cells[y1 * s->width + x];
596 + c = &vt->cells[y1 * vt->width + x];
597 vga_putcharxy(QEMU_CONSOLE(s), x, y2, c->ch,
598 &(c->t_attrib));
599 invalidate_xy(s, x, y2);
@@ -591,11 +603,12 @@ static void vc_update_xy(VCChardev *vc, int x, int y)
603 static void vc_clear_xy(VCChardev *vc, int x, int y)
604 {
605 QemuTextConsole *s = vc->console;
594 - int y1 = (s->y_base + y) % s->total_height;
595 - if (x >= s->width) {
596 - x = s->width - 1;
606 + QemuVT100 *vt = &s->vt;
607 + int y1 = (vt->y_base + y) % vt->total_height;
608 + if (x >= vt->width) {
609 + x = vt->width - 1;
610 }
598 - TextCell *c = &s->cells[y1 * s->width + x];
611 + TextCell *c = &vt->cells[y1 * vt->width + x];
612 c->ch = ' ';
613 c->t_attrib = TEXT_ATTRIBUTES_DEFAULT;
614 vc_update_xy(vc, x, y);
@@ -604,19 +617,20 @@ static void vc_clear_xy(VCChardev *vc, int x, int y)
617 static void vc_put_one(VCChardev *vc, int ch)
618 {
619 QemuTextConsole *s = vc->console;
620 + QemuVT100 *vt = &s->vt;
621 TextCell *c;
622 int y1;
609 - if (s->x >= s->width) {
623 + if (vt->x >= vt->width) {
624 /* line wrap */
611 - s->x = 0;
625 + vt->x = 0;
626 vc_put_lf(vc);
627 }
614 - y1 = (s->y_base + s->y) % s->total_height;
615 - c = &s->cells[y1 * s->width + s->x];
628 + y1 = (vt->y_base + vt->y) % vt->total_height;
629 + c = &vt->cells[y1 * vt->width + vt->x];
630 c->ch = ch;
631 c->t_attrib = vc->t_attrib;
618 - vc_update_xy(vc, s->x, s->y);
619 - s->x++;
632 + vc_update_xy(vc, vt->x, vt->y);
633 + vt->x++;
634 }
635
636 static void vc_respond_str(VCChardev *vc, const char *buf)
@@ -630,6 +644,7 @@ static void vc_respond_str(VCChardev *vc, const char *buf)
644 static void vc_set_cursor(VCChardev *vc, int x, int y)
645 {
646 QemuTextConsole *s = vc->console;
647 + QemuVT100 *vt = &s->vt;
648
649 if (x < 0) {
650 x = 0;
@@ -637,15 +652,15 @@ static void vc_set_cursor(VCChardev *vc, int x, int y)
652 if (y < 0) {
653 y = 0;
654 }
640 - if (y >= s->height) {
641 - y = s->height - 1;
655 + if (y >= vt->height) {
656 + y = vt->height - 1;
657 }
643 - if (x >= s->width) {
644 - x = s->width - 1;
658 + if (x >= vt->width) {
659 + x = vt->width - 1;
660 }
661
647 - s->x = x;
648 - s->y = y;
662 + vt->x = x;
663 + vt->y = y;
664 }
665
666 /**
@@ -657,6 +672,7 @@ static void vc_set_cursor(VCChardev *vc, int x, int y)
672 static void vc_csi_P(struct VCChardev *vc, unsigned int nr)
673 {
674 QemuTextConsole *s = vc->console;
675 + QemuVT100 *vt = &s->vt;
676 TextCell *c1, *c2;
677 unsigned int x1, x2, y;
678 unsigned int end, len;
@@ -664,28 +680,28 @@ static void vc_csi_P(struct VCChardev *vc, unsigned int nr)
680 if (!nr) {
681 nr = 1;
682 }
667 - if (nr > s->width - s->x) {
668 - nr = s->width - s->x;
683 + if (nr > vt->width - vt->x) {
684 + nr = vt->width - vt->x;
685 if (!nr) {
686 return;
687 }
688 }
689
674 - x1 = s->x;
675 - x2 = s->x + nr;
676 - len = s->width - x2;
690 + x1 = vt->x;
691 + x2 = vt->x + nr;
692 + len = vt->width - x2;
693 if (len) {
678 - y = (s->y_base + s->y) % s->total_height;
679 - c1 = &s->cells[y * s->width + x1];
680 - c2 = &s->cells[y * s->width + x2];
694 + y = (vt->y_base + vt->y) % vt->total_height;
695 + c1 = &vt->cells[y * vt->width + x1];
696 + c2 = &vt->cells[y * vt->width + x2];
697 memmove(c1, c2, len * sizeof(*c1));
698 for (end = x1 + len; x1 < end; x1++) {
683 - vc_update_xy(vc, x1, s->y);
699 + vc_update_xy(vc, x1, vt->y);
700 }
701 }
702 /* Clear the rest */
687 - for (; x1 < s->width; x1++) {
688 - vc_clear_xy(vc, x1, s->y);
703 + for (; x1 < vt->width; x1++) {
704 + vc_clear_xy(vc, x1, vt->y);
705 }
706 }
707
@@ -698,6 +714,7 @@ static void vc_csi_P(struct VCChardev *vc, unsigned int nr)
714 static void vc_csi_at(struct VCChardev *vc, unsigned int nr)
715 {
716 QemuTextConsole *s = vc->console;
717 + QemuVT100 *vt = &s->vt;
718 TextCell *c1, *c2;
719 unsigned int x1, x2, y;
720 unsigned int end, len;
@@ -705,28 +722,28 @@ static void vc_csi_at(struct VCChardev *vc, unsigned int nr)
722 if (!nr) {
723 nr = 1;
724 }
708 - if (nr > s->width - s->x) {
709 - nr = s->width - s->x;
725 + if (nr > vt->width - vt->x) {
726 + nr = vt->width - vt->x;
727 if (!nr) {
728 return;
729 }
730 }
731
715 - x1 = s->x + nr;
716 - x2 = s->x;
717 - len = s->width - x1;
732 + x1 = vt->x + nr;
733 + x2 = vt->x;
734 + len = vt->width - x1;
735 if (len) {
719 - y = (s->y_base + s->y) % s->total_height;
720 - c1 = &s->cells[y * s->width + x1];
721 - c2 = &s->cells[y * s->width + x2];
736 + y = (vt->y_base + vt->y) % vt->total_height;
737 + c1 = &vt->cells[y * vt->width + x1];
738 + c2 = &vt->cells[y * vt->width + x2];
739 memmove(c1, c2, len * sizeof(*c1));
740 for (end = x1 + len; x1 < end; x1++) {
724 - vc_update_xy(vc, x1, s->y);
741 + vc_update_xy(vc, x1, vt->y);
742 }
743 }
744 /* Insert blanks */
728 - for (x1 = s->x; x1 < s->x + nr; x1++) {
729 - vc_clear_xy(vc, x1, s->y);
745 + for (x1 = vt->x; x1 < vt->x + nr; x1++) {
746 + vc_clear_xy(vc, x1, vt->y);
747 }
748 }
749
@@ -736,9 +753,10 @@ static void vc_csi_at(struct VCChardev *vc, unsigned int nr)
753 static void vc_save_cursor(VCChardev *vc)
754 {
755 QemuTextConsole *s = vc->console;
756 + QemuVT100 *vt = &s->vt;
757
740 - vc->x_saved = s->x;
741 - vc->y_saved = s->y;
758 + vc->x_saved = vt->x;
759 + vc->y_saved = vt->y;
760 vc->t_attrib_saved = vc->t_attrib;
761 }
762
@@ -749,15 +767,17 @@ static void vc_save_cursor(VCChardev *vc)
767 static void vc_restore_cursor(VCChardev *vc)
768 {
769 QemuTextConsole *s = vc->console;
770 + QemuVT100 *vt = &s->vt;
771
753 - s->x = vc->x_saved;
754 - s->y = vc->y_saved;
772 + vt->x = vc->x_saved;
773 + vt->y = vc->y_saved;
774 vc->t_attrib = vc->t_attrib_saved;
775 }
776
777 static void vc_putchar(VCChardev *vc, int ch)
778 {
779 QemuTextConsole *s = vc->console;
780 + QemuVT100 *vt = &s->vt;
781 int i;
782 int x, y;
783 g_autofree char *response = NULL;
@@ -766,21 +786,21 @@ static void vc_putchar(VCChardev *vc, int ch)
786 case TTY_STATE_NORM:
787 switch(ch) {
788 case '\r': /* carriage return */
769 - s->x = 0;
789 + vt->x = 0;
790 break;
791 case '\n': /* newline */
792 vc_put_lf(vc);
793 break;
794 case '\b': /* backspace */
775 - if (s->x > 0)
776 - s->x--;
795 + if (vt->x > 0)
796 + vt->x--;
797 break;
798 case '\t': /* tabspace */
779 - if (s->x + (8 - (s->x % 8)) > s->width) {
780 - s->x = 0;
799 + if (vt->x + (8 - (vt->x % 8)) > vt->width) {
800 + vt->x = 0;
801 vc_put_lf(vc);
802 } else {
783 - s->x = s->x + (8 - (s->x % 8));
803 + vt->x = vt->x + (8 - (vt->x % 8));
804 }
805 break;
806 case '\a': /* alert aka. bell */
@@ -848,32 +868,32 @@ static void vc_putchar(VCChardev *vc, int ch)
868 if (vc->esc_params[0] == 0) {
869 vc->esc_params[0] = 1;
870 }
851 - vc_set_cursor(vc, s->x, s->y - vc->esc_params[0]);
871 + vc_set_cursor(vc, vt->x, vt->y - vc->esc_params[0]);
872 break;
873 case 'B':
874 /* move cursor down */
875 if (vc->esc_params[0] == 0) {
876 vc->esc_params[0] = 1;
877 }
858 - vc_set_cursor(vc, s->x, s->y + vc->esc_params[0]);
878 + vc_set_cursor(vc, vt->x, vt->y + vc->esc_params[0]);
879 break;
880 case 'C':
881 /* move cursor right */
882 if (vc->esc_params[0] == 0) {
883 vc->esc_params[0] = 1;
884 }
865 - vc_set_cursor(vc, s->x + vc->esc_params[0], s->y);
885 + vc_set_cursor(vc, vt->x + vc->esc_params[0], vt->y);
886 break;
887 case 'D':
888 /* move cursor left */
889 if (vc->esc_params[0] == 0) {
890 vc->esc_params[0] = 1;
891 }
872 - vc_set_cursor(vc, s->x - vc->esc_params[0], s->y);
892 + vc_set_cursor(vc, vt->x - vc->esc_params[0], vt->y);
893 break;
894 case 'G':
895 /* move cursor to column */
876 - vc_set_cursor(vc, vc->esc_params[0] - 1, s->y);
896 + vc_set_cursor(vc, vc->esc_params[0] - 1, vt->y);
897 break;
898 case 'f':
899 case 'H':
@@ -884,9 +904,9 @@ static void vc_putchar(VCChardev *vc, int ch)
904 switch (vc->esc_params[0]) {
905 case 0:
906 /* clear to end of screen */
887 - for (y = s->y; y < s->height; y++) {
888 - for (x = 0; x < s->width; x++) {
889 - if (y == s->y && x < s->x) {
907 + for (y = vt->y; y < vt->height; y++) {
908 + for (x = 0; x < vt->width; x++) {
909 + if (y == vt->y && x < vt->x) {
910 continue;
911 }
912 vc_clear_xy(vc, x, y);
@@ -895,9 +915,9 @@ static void vc_putchar(VCChardev *vc, int ch)
915 break;
916 case 1:
917 /* clear from beginning of screen */
898 - for (y = 0; y <= s->y; y++) {
899 - for (x = 0; x < s->width; x++) {
900 - if (y == s->y && x > s->x) {
918 + for (y = 0; y <= vt->y; y++) {
919 + for (x = 0; x < vt->width; x++) {
920 + if (y == vt->y && x > vt->x) {
921 break;
922 }
923 vc_clear_xy(vc, x, y);
@@ -906,8 +926,8 @@ static void vc_putchar(VCChardev *vc, int ch)
926 break;
927 case 2:
928 /* clear entire screen */
909 - for (y = 0; y < s->height; y++) {
910 - for (x = 0; x < s->width; x++) {
929 + for (y = 0; y < vt->height; y++) {
930 + for (x = 0; x < vt->width; x++) {
931 vc_clear_xy(vc, x, y);
932 }
933 }
@@ -918,20 +938,20 @@ static void vc_putchar(VCChardev *vc, int ch)
938 switch (vc->esc_params[0]) {
939 case 0:
940 /* clear to eol */
921 - for(x = s->x; x < s->width; x++) {
922 - vc_clear_xy(vc, x, s->y);
941 + for(x = vt->x; x < vt->width; x++) {
942 + vc_clear_xy(vc, x, vt->y);
943 }
944 break;
945 case 1:
946 /* clear from beginning of line */
927 - for (x = 0; x <= s->x && x < s->width; x++) {
928 - vc_clear_xy(vc, x, s->y);
947 + for (x = 0; x <= vt->x && x < vt->width; x++) {
948 + vc_clear_xy(vc, x, vt->y);
949 }
950 break;
951 case 2:
952 /* clear entire line */
933 - for(x = 0; x < s->width; x++) {
934 - vc_clear_xy(vc, x, s->y);
953 + for(x = 0; x < vt->width; x++) {
954 + vc_clear_xy(vc, x, vt->y);
955 }
956 break;
957 }
@@ -951,7 +971,7 @@ static void vc_putchar(VCChardev *vc, int ch)
971 case 6:
972 /* report cursor position */
973 response = g_strdup_printf("\033[%d;%dR",
954 - s->y + 1, s->x + 1);
974 + vt->y + 1, vt->x + 1);
975 vc_respond_str(vc, response);
976 break;
977 }
@@ -1002,21 +1022,22 @@ static int vc_chr_write(Chardev *chr, const uint8_t *buf, int len)
1022 {
1023 VCChardev *drv = VC_CHARDEV(chr);
1024 QemuTextConsole *s = drv->console;
1025 + QemuVT100 *vt = &s->vt;
1026 int i;
1027
1007 - s->update_x0 = s->width * FONT_WIDTH;
1008 - s->update_y0 = s->height * FONT_HEIGHT;
1009 - s->update_x1 = 0;
1010 - s->update_y1 = 0;
1028 + vt->update_x0 = vt->width * FONT_WIDTH;
1029 + vt->update_y0 = vt->height * FONT_HEIGHT;
1030 + vt->update_x1 = 0;
1031 + vt->update_y1 = 0;
1032 console_show_cursor(s, 0);
1033 for(i = 0; i < len; i++) {
1034 vc_putchar(drv, buf[i]);
1035 }
1036 console_show_cursor(s, 1);
1016 - if (s->update_x0 < s->update_x1) {
1017 - dpy_gfx_update(QEMU_CONSOLE(s), s->update_x0, s->update_y0,
1018 - s->update_x1 - s->update_x0,
1019 - s->update_y1 - s->update_y0);
1037 + if (vt->update_x0 < vt->update_x1) {
1038 + dpy_gfx_update(QEMU_CONSOLE(s), vt->update_x0, vt->update_y0,
1039 + vt->update_x1 - vt->update_x0,
1040 + vt->update_y1 - vt->update_y0);
1041 }
1042 return len;
1043 }
@@ -1075,7 +1096,7 @@ qemu_text_console_init(Object *obj)
1096 QemuTextConsole *c = QEMU_TEXT_CONSOLE(obj);
1097
1098 fifo8_create(&c->out_fifo, 16);
1078 - c->total_height = DEFAULT_BACKSCROLL;
1099 + c->vt.total_height = DEFAULT_BACKSCROLL;
1100 QEMU_CONSOLE(c)->hw_ops = &text_console_ops;
1101 QEMU_CONSOLE(c)->hw = c;
1102 }
@@ -1106,12 +1127,12 @@ static void vc_chr_set_echo(Chardev *chr, bool echo)
1127 {
1128 VCChardev *drv = VC_CHARDEV(chr);
1129
1109 - drv->console->echo = echo;
1130 + drv->console->vt.echo = echo;
1131 }
1132
1133 void qemu_text_console_update_size(QemuTextConsole *c)
1134 {
1114 - dpy_text_resize(QEMU_CONSOLE(c), c->width, c->height);
1135 + dpy_text_resize(QEMU_CONSOLE(c), c->vt.width, c->vt.height);
1136 }
1137
1138 static bool vc_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)