58
pixman_image_t *image;
59
void (*image_update)(QemuVT100 *vt, int x, int y, int width, int height);
60
61
+ ChardevVCEncoding encoding;
62
int width;
63
int height;
64
int total_height;
75
int update_x1;
76
int update_y1;
77
78
+ enum TTYState state;
79
+ int esc_params[MAX_ESC_PARAMS];
80
+ int nb_esc_params;
81
+ uint32_t utf8_state; /* UTF-8 DFA decoder state */
82
+ uint32_t utf8_codepoint; /* accumulated UTF-8 code point */
83
+ TextAttributes t_attrib; /* currently active text attributes */
84
+ TextAttributes t_attrib_saved;
85
+ int x_saved, y_saved;
86
+ /* fifo for key pressed */
87
+ Fifo8 out_fifo;
88
+ void (*out_flush)(QemuVT100 *vt);
89
+
90
QTAILQ_ENTRY(QemuVT100) list;
91
};
92
98
99
QemuVT100 vt;
100
Chardev *chr;
88
- /* fifo for key pressed */
89
- Fifo8 out_fifo;
101
} QemuTextConsole;
102
103
typedef QemuConsoleClass QemuTextConsoleClass;
114
115
struct VCChardev {
116
Chardev parent;
106
- QemuTextConsole *console;
117
108
- enum TTYState state;
109
- int esc_params[MAX_ESC_PARAMS];
110
- int nb_esc_params;
111
- uint32_t utf8_state; /* UTF-8 DFA decoder state */
112
- uint32_t utf8_codepoint; /* accumulated UTF-8 code point */
113
- TextAttributes t_attrib; /* currently active text attributes */
114
- TextAttributes t_attrib_saved;
115
- int x_saved, y_saved;
118
ChardevVCEncoding encoding;
119
+ QemuTextConsole *console;
120
};
121
typedef struct VCChardev VCChardev;
122
305
vt100_refresh(vt);
306
}
307
305
-static void qemu_text_console_flush(QemuTextConsole *s)
308
+static void qemu_text_console_out_flush(QemuTextConsole *s)
309
{
310
uint32_t len, avail;
311
312
len = qemu_chr_be_can_write(s->chr);
310
- avail = fifo8_num_used(&s->out_fifo);
313
+ avail = fifo8_num_used(&s->vt.out_fifo);
314
while (len > 0 && avail > 0) {
315
const uint8_t *buf;
316
uint32_t size;
317
315
- buf = fifo8_pop_bufptr(&s->out_fifo, MIN(len, avail), &size);
318
+ buf = fifo8_pop_bufptr(&s->vt.out_fifo, MIN(len, avail), &size);
319
qemu_chr_be_write(s->chr, buf, size);
320
len = qemu_chr_be_can_write(s->chr);
321
avail -= size;
322
}
323
}
324
322
-static void qemu_text_console_write(QemuTextConsole *s, const void *buf, size_t len)
325
+static void vt100_write(QemuVT100 *vt, const void *buf, size_t len)
326
{
327
uint32_t num_free;
328
326
- num_free = fifo8_num_free(&s->out_fifo);
327
- fifo8_push_all(&s->out_fifo, buf, MIN(num_free, len));
328
- qemu_text_console_flush(s);
329
+ num_free = fifo8_num_free(&vt->out_fifo);
330
+ fifo8_push_all(&vt->out_fifo, buf, MIN(num_free, len));
331
+ vt->out_flush(vt);
332
}
333
334
/* called when an ascii key is pressed */
335
void qemu_text_console_handle_keysym(QemuTextConsole *s, int keysym)
336
{
334
- QemuVT100 *vt = &s->vt;
337
uint8_t buf[16], *q;
338
int c;
339
365
*q++ = '\033';
366
*q++ = '[';
367
*q++ = keysym & 0xff;
366
- } else if (vt->echo && (keysym == '\r' || keysym == '\n')) {
368
+ } else if (s->vt.echo && (keysym == '\r' || keysym == '\n')) {
369
qemu_chr_write(s->chr, (uint8_t *)"\r", 1, true);
370
*q++ = '\n';
371
} else {
372
*q++ = keysym;
373
}
372
- if (vt->echo) {
374
+ if (s->vt.echo) {
375
qemu_chr_write(s->chr, buf, q - buf, true);
376
}
375
- qemu_text_console_write(s, buf, q - buf);
377
+ vt100_write(&s->vt, buf, q - buf);
378
break;
379
}
380
}
382
static void text_console_update(void *opaque, console_ch_t *chardata)
383
{
384
QemuTextConsole *s = QEMU_TEXT_CONSOLE(opaque);
383
- QemuVT100 *vt = &s->vt;
385
int i, j, src;
386
386
- if (vt->text_x[0] <= vt->text_x[1]) {
387
- src = (vt->y_base + vt->text_y[0]) * vt->width;
388
- chardata += vt->text_y[0] * vt->width;
389
- for (i = vt->text_y[0]; i <= vt->text_y[1]; i ++)
390
- for (j = 0; j < vt->width; j++, src++) {
387
+ if (s->vt.text_x[0] <= s->vt.text_x[1]) {
388
+ src = (s->vt.y_base + s->vt.text_y[0]) * s->vt.width;
389
+ chardata += s->vt.text_y[0] * s->vt.width;
390
+ for (i = s->vt.text_y[0]; i <= s->vt.text_y[1]; i ++)
391
+ for (j = 0; j < s->vt.width; j++, src++) {
392
console_write_ch(chardata ++,
392
- ATTR2CHTYPE(vt->cells[src].ch,
393
- vt->cells[src].t_attrib.fgcol,
394
- vt->cells[src].t_attrib.bgcol,
395
- vt->cells[src].t_attrib.bold));
393
+ ATTR2CHTYPE(s->vt.cells[src].ch,
394
+ s->vt.cells[src].t_attrib.fgcol,
395
+ s->vt.cells[src].t_attrib.bgcol,
396
+ s->vt.cells[src].t_attrib.bold));
397
}
397
- dpy_text_update(QEMU_CONSOLE(s), vt->text_x[0], vt->text_y[0],
398
- vt->text_x[1] - vt->text_x[0], i - vt->text_y[0]);
399
- vt->text_x[0] = vt->width;
400
- vt->text_y[0] = vt->height;
401
- vt->text_x[1] = 0;
402
- vt->text_y[1] = 0;
398
+ dpy_text_update(QEMU_CONSOLE(s), s->vt.text_x[0], s->vt.text_y[0],
399
+ s->vt.text_x[1] - s->vt.text_x[0], i - s->vt.text_y[0]);
400
+ s->vt.text_x[0] = s->vt.width;
401
+ s->vt.text_y[0] = s->vt.height;
402
+ s->vt.text_x[1] = 0;
403
+ s->vt.text_y[1] = 0;
404
}
404
- if (vt->cursor_invalidate) {
405
- dpy_text_cursor(QEMU_CONSOLE(s), vt->x, vt->y);
406
- vt->cursor_invalidate = 0;
405
+ if (s->vt.cursor_invalidate) {
406
+ dpy_text_cursor(QEMU_CONSOLE(s), s->vt.x, s->vt.y);
407
+ s->vt.cursor_invalidate = 0;
408
}
409
}
410
493
* NOTE: I know this code is not very efficient (checking every color for it
494
* self) but it is more readable and better maintainable.
495
*/
495
-static void vc_handle_escape(VCChardev *vc)
496
+static void vt100_handle_escape(QemuVT100 *vt)
497
{
498
int i;
499
499
- for (i = 0; i < vc->nb_esc_params; i++) {
500
- switch (vc->esc_params[i]) {
500
+ for (i = 0; i < vt->nb_esc_params; i++) {
501
+ switch (vt->esc_params[i]) {
502
case 0: /* reset all console attributes to default */
502
- vc->t_attrib = TEXT_ATTRIBUTES_DEFAULT;
503
+ vt->t_attrib = TEXT_ATTRIBUTES_DEFAULT;
504
break;
505
case 1:
505
- vc->t_attrib.bold = 1;
506
+ vt->t_attrib.bold = 1;
507
break;
508
case 4:
508
- vc->t_attrib.uline = 1;
509
+ vt->t_attrib.uline = 1;
510
break;
511
case 5:
511
- vc->t_attrib.blink = 1;
512
+ vt->t_attrib.blink = 1;
513
break;
514
case 7:
514
- vc->t_attrib.invers = 1;
515
+ vt->t_attrib.invers = 1;
516
break;
517
case 8:
517
- vc->t_attrib.unvisible = 1;
518
+ vt->t_attrib.unvisible = 1;
519
break;
520
case 22:
520
- vc->t_attrib.bold = 0;
521
+ vt->t_attrib.bold = 0;
522
break;
523
case 24:
523
- vc->t_attrib.uline = 0;
524
+ vt->t_attrib.uline = 0;
525
break;
526
case 25:
526
- vc->t_attrib.blink = 0;
527
+ vt->t_attrib.blink = 0;
528
break;
529
case 27:
529
- vc->t_attrib.invers = 0;
530
+ vt->t_attrib.invers = 0;
531
break;
532
case 28:
532
- vc->t_attrib.unvisible = 0;
533
+ vt->t_attrib.unvisible = 0;
534
break;
535
/* set foreground color */
536
case 30:
536
- vc->t_attrib.fgcol = QEMU_COLOR_BLACK;
537
+ vt->t_attrib.fgcol = QEMU_COLOR_BLACK;
538
break;
539
case 31:
539
- vc->t_attrib.fgcol = QEMU_COLOR_RED;
540
+ vt->t_attrib.fgcol = QEMU_COLOR_RED;
541
break;
542
case 32:
542
- vc->t_attrib.fgcol = QEMU_COLOR_GREEN;
543
+ vt->t_attrib.fgcol = QEMU_COLOR_GREEN;
544
break;
545
case 33:
545
- vc->t_attrib.fgcol = QEMU_COLOR_YELLOW;
546
+ vt->t_attrib.fgcol = QEMU_COLOR_YELLOW;
547
break;
548
case 34:
548
- vc->t_attrib.fgcol = QEMU_COLOR_BLUE;
549
+ vt->t_attrib.fgcol = QEMU_COLOR_BLUE;
550
break;
551
case 35:
551
- vc->t_attrib.fgcol = QEMU_COLOR_MAGENTA;
552
+ vt->t_attrib.fgcol = QEMU_COLOR_MAGENTA;
553
break;
554
case 36:
554
- vc->t_attrib.fgcol = QEMU_COLOR_CYAN;
555
+ vt->t_attrib.fgcol = QEMU_COLOR_CYAN;
556
break;
557
case 37:
557
- vc->t_attrib.fgcol = QEMU_COLOR_WHITE;
558
+ vt->t_attrib.fgcol = QEMU_COLOR_WHITE;
559
break;
560
/* set background color */
561
case 40:
561
- vc->t_attrib.bgcol = QEMU_COLOR_BLACK;
562
+ vt->t_attrib.bgcol = QEMU_COLOR_BLACK;
563
break;
564
case 41:
564
- vc->t_attrib.bgcol = QEMU_COLOR_RED;
565
+ vt->t_attrib.bgcol = QEMU_COLOR_RED;
566
break;
567
case 42:
567
- vc->t_attrib.bgcol = QEMU_COLOR_GREEN;
568
+ vt->t_attrib.bgcol = QEMU_COLOR_GREEN;
569
break;
570
case 43:
570
- vc->t_attrib.bgcol = QEMU_COLOR_YELLOW;
571
+ vt->t_attrib.bgcol = QEMU_COLOR_YELLOW;
572
break;
573
case 44:
573
- vc->t_attrib.bgcol = QEMU_COLOR_BLUE;
574
+ vt->t_attrib.bgcol = QEMU_COLOR_BLUE;
575
break;
576
case 45:
576
- vc->t_attrib.bgcol = QEMU_COLOR_MAGENTA;
577
+ vt->t_attrib.bgcol = QEMU_COLOR_MAGENTA;
578
break;
579
case 46:
579
- vc->t_attrib.bgcol = QEMU_COLOR_CYAN;
580
+ vt->t_attrib.bgcol = QEMU_COLOR_CYAN;
581
break;
582
case 47:
582
- vc->t_attrib.bgcol = QEMU_COLOR_WHITE;
583
+ vt->t_attrib.bgcol = QEMU_COLOR_WHITE;
584
break;
585
}
586
}
587
}
588
588
-static void vc_update_xy(VCChardev *vc, int x, int y)
589
+static void vt100_update_xy(QemuVT100 *vt, int x, int y)
590
{
590
- QemuTextConsole *s = vc->console;
591
- QemuVT100 *vt = &s->vt;
591
TextCell *c;
592
int y1, y2;
593
608
c = &vt->cells[y1 * vt->width + x];
609
vt100_putcharxy(vt, x, y2, c->ch,
610
&(c->t_attrib));
612
- vt100_invalidate_xy(&s->vt, x, y2);
611
+ vt100_invalidate_xy(vt, x, y2);
612
}
613
}
614
616
-static void vc_clear_xy(VCChardev *vc, int x, int y)
615
+static void vt100_clear_xy(QemuVT100 *vt, int x, int y)
616
{
618
- QemuTextConsole *s = vc->console;
619
- QemuVT100 *vt = &s->vt;
617
int y1 = (vt->y_base + y) % vt->total_height;
618
if (x >= vt->width) {
619
x = vt->width - 1;
621
TextCell *c = &vt->cells[y1 * vt->width + x];
622
c->ch = ' ';
623
c->t_attrib = TEXT_ATTRIBUTES_DEFAULT;
627
- vc_update_xy(vc, x, y);
624
+ vt100_update_xy(vt, x, y);
625
}
626
627
/*
664
return *state;
665
}
666
670
-static void vc_put_one(VCChardev *vc, int ch)
667
+static void vt100_put_one(QemuVT100 *vt, int ch)
668
{
672
- QemuTextConsole *s = vc->console;
673
- QemuVT100 *vt = &s->vt;
669
TextCell *c;
670
int y1;
671
if (vt->x >= vt->width) {
676
y1 = (vt->y_base + vt->y) % vt->total_height;
677
c = &vt->cells[y1 * vt->width + vt->x];
678
c->ch = ch;
684
- c->t_attrib = vc->t_attrib;
685
- vc_update_xy(vc, vt->x, vt->y);
679
+ c->t_attrib = vt->t_attrib;
680
+ vt100_update_xy(vt, vt->x, vt->y);
681
vt->x++;
682
}
683
684
/* set cursor, checking bounds */
690
-static void vc_set_cursor(VCChardev *vc, int x, int y)
685
+static void vt100_set_cursor(QemuVT100 *vt, int x, int y)
686
{
692
- QemuTextConsole *s = vc->console;
693
- QemuVT100 *vt = &s->vt;
694
-
687
if (x < 0) {
688
x = 0;
689
}
707
* characters between the cursor and right margin move to the
708
* left. Character attributes move with the characters.
709
*/
718
-static void vc_csi_P(struct VCChardev *vc, unsigned int nr)
710
+static void vt100_csi_P(QemuVT100 *vt, unsigned int nr)
711
{
720
- QemuTextConsole *s = vc->console;
721
- QemuVT100 *vt = &s->vt;
712
TextCell *c1, *c2;
713
unsigned int x1, x2, y;
714
unsigned int end, len;
732
c2 = &vt->cells[y * vt->width + x2];
733
memmove(c1, c2, len * sizeof(*c1));
734
for (end = x1 + len; x1 < end; x1++) {
745
- vc_update_xy(vc, x1, vt->y);
735
+ vt100_update_xy(vt, x1, vt->y);
736
}
737
}
738
/* Clear the rest */
739
for (; x1 < vt->width; x1++) {
750
- vc_clear_xy(vc, x1, vt->y);
740
+ vt100_clear_xy(vt, x1, vt->y);
741
}
742
}
743
747
* blank characters. Text between the cursor and right margin moves to
748
* the right. Characters scrolled past the right margin are lost.
749
*/
760
-static void vc_csi_at(struct VCChardev *vc, unsigned int nr)
750
+static void vt100_csi_at(QemuVT100 *vt, unsigned int nr)
751
{
762
- QemuTextConsole *s = vc->console;
763
- QemuVT100 *vt = &s->vt;
752
TextCell *c1, *c2;
753
unsigned int x1, x2, y;
754
unsigned int end, len;
772
c2 = &vt->cells[y * vt->width + x2];
773
memmove(c1, c2, len * sizeof(*c1));
774
for (end = x1 + len; x1 < end; x1++) {
787
- vc_update_xy(vc, x1, vt->y);
775
+ vt100_update_xy(vt, x1, vt->y);
776
}
777
}
778
/* Insert blanks */
779
for (x1 = vt->x; x1 < vt->x + nr; x1++) {
792
- vc_clear_xy(vc, x1, vt->y);
780
+ vt100_clear_xy(vt, x1, vt->y);
781
}
782
}
783
784
/**
797
- * vc_save_cursor() - saves cursor position and character attributes.
785
+ * vt100_save_cursor() - saves cursor position and character attributes.
786
*/
799
-static void vc_save_cursor(VCChardev *vc)
787
+static void vt100_save_cursor(QemuVT100 *vt)
788
{
801
- QemuTextConsole *s = vc->console;
802
- QemuVT100 *vt = &s->vt;
803
-
804
- vc->x_saved = vt->x;
805
- vc->y_saved = vt->y;
806
- vc->t_attrib_saved = vc->t_attrib;
789
+ vt->x_saved = vt->x;
790
+ vt->y_saved = vt->y;
791
+ vt->t_attrib_saved = vt->t_attrib;
792
}
793
794
/**
810
- * vc_restore_cursor() - restores cursor position and character
795
+ * vt100_restore_cursor() - restores cursor position and character
796
* attributes from saved state.
797
*/
813
-static void vc_restore_cursor(VCChardev *vc)
798
+static void vt100_restore_cursor(QemuVT100 *vt)
799
{
815
- QemuTextConsole *s = vc->console;
816
- QemuVT100 *vt = &s->vt;
817
-
818
- vt->x = vc->x_saved;
819
- vt->y = vc->y_saved;
820
- vc->t_attrib = vc->t_attrib_saved;
800
+ vt->x = vt->x_saved;
801
+ vt->y = vt->y_saved;
802
+ vt->t_attrib = vt->t_attrib_saved;
803
}
804
823
-static void vc_putchar(VCChardev *vc, int ch)
805
+static void vt100_putchar(QemuVT100 *vt, int ch)
806
{
825
- QemuTextConsole *s = vc->console;
826
- QemuVT100 *vt = &s->vt;
807
int i;
808
int x, y;
809
g_autofree char *response = NULL;
810
831
- switch(vc->state) {
811
+ switch (vt->state) {
812
case TTY_STATE_NORM:
833
- if (ch >= 0x80 && vc->encoding == CHARDEV_VC_ENCODING_UTF8) {
834
- switch (bh_utf8_decode(&vc->utf8_state, &vc->utf8_codepoint, ch)) {
813
+ if (ch >= 0x80 && vt->encoding == CHARDEV_VC_ENCODING_UTF8) {
814
+ switch (bh_utf8_decode(&vt->utf8_state, &vt->utf8_codepoint, ch)) {
815
case BH_UTF8_ACCEPT:
836
- vc_put_one(vc, unicode_to_cp437(vc->utf8_codepoint));
816
+ vt100_put_one(vt, unicode_to_cp437(vt->utf8_codepoint));
817
break;
818
case BH_UTF8_REJECT:
839
- vc->utf8_state = BH_UTF8_ACCEPT;
819
+ vt->utf8_state = BH_UTF8_ACCEPT;
820
break;
821
default:
822
/* Need more bytes */
824
}
825
break;
826
}
847
- /* ASCII byte: abort any pending UTF-8 sequence */
848
- vc->utf8_state = BH_UTF8_ACCEPT;
827
+ vt->utf8_state = BH_UTF8_ACCEPT;
828
switch(ch) {
829
case '\r': /* carriage return */
830
vt->x = 0;
831
break;
832
case '\n': /* newline */
854
- vt100_put_lf(&s->vt);
833
+ vt100_put_lf(vt);
834
break;
835
case '\b': /* backspace */
836
if (vt->x > 0)
854
/* SI (shift in), character set 0 (ignored) */
855
break;
856
case 27: /* esc (introducing an escape sequence) */
878
- vc->state = TTY_STATE_ESC;
857
+ vt->state = TTY_STATE_ESC;
858
break;
859
default:
881
- vc_put_one(vc, ch);
860
+ vt100_put_one(vt, ch);
861
break;
862
}
863
break;
864
case TTY_STATE_ESC: /* check if it is a terminal escape sequence */
865
if (ch == '[') {
866
for(i=0;i<MAX_ESC_PARAMS;i++)
888
- vc->esc_params[i] = 0;
889
- vc->nb_esc_params = 0;
890
- vc->state = TTY_STATE_CSI;
867
+ vt->esc_params[i] = 0;
868
+ vt->nb_esc_params = 0;
869
+ vt->state = TTY_STATE_CSI;
870
} else if (ch == '(') {
892
- vc->state = TTY_STATE_G0;
871
+ vt->state = TTY_STATE_G0;
872
} else if (ch == ')') {
894
- vc->state = TTY_STATE_G1;
873
+ vt->state = TTY_STATE_G1;
874
} else if (ch == ']' || ch == 'P' || ch == 'X'
875
|| ch == '^' || ch == '_') {
876
/* String sequences: OSC, DCS, SOS, PM, APC */
898
- vc->state = TTY_STATE_OSC;
877
+ vt->state = TTY_STATE_OSC;
878
} else if (ch == '7') {
900
- vc_save_cursor(vc);
901
- vc->state = TTY_STATE_NORM;
879
+ vt100_save_cursor(vt);
880
+ vt->state = TTY_STATE_NORM;
881
} else if (ch == '8') {
903
- vc_restore_cursor(vc);
904
- vc->state = TTY_STATE_NORM;
882
+ vt100_restore_cursor(vt);
883
+ vt->state = TTY_STATE_NORM;
884
} else {
906
- vc->state = TTY_STATE_NORM;
885
+ vt->state = TTY_STATE_NORM;
886
}
887
break;
888
case TTY_STATE_CSI: /* handle escape sequence parameters */
889
if (ch >= '0' && ch <= '9') {
911
- if (vc->nb_esc_params < MAX_ESC_PARAMS) {
912
- int *param = &vc->esc_params[vc->nb_esc_params];
890
+ if (vt->nb_esc_params < MAX_ESC_PARAMS) {
891
+ int *param = &vt->esc_params[vt->nb_esc_params];
892
int digit = (ch - '0');
893
894
*param = (*param <= (INT_MAX - digit) / 10) ?
895
*param * 10 + digit : INT_MAX;
896
}
897
} else {
919
- if (vc->nb_esc_params < MAX_ESC_PARAMS)
920
- vc->nb_esc_params++;
898
+ if (vt->nb_esc_params < MAX_ESC_PARAMS)
899
+ vt->nb_esc_params++;
900
if (ch == ';' || ch == '?') {
901
break;
902
}
924
- trace_console_putchar_csi(vc->esc_params[0], vc->esc_params[1],
925
- ch, vc->nb_esc_params);
926
- vc->state = TTY_STATE_NORM;
903
+ trace_console_putchar_csi(vt->esc_params[0], vt->esc_params[1],
904
+ ch, vt->nb_esc_params);
905
+ vt->state = TTY_STATE_NORM;
906
switch(ch) {
907
case 'A':
908
/* move cursor up */
930
- if (vc->esc_params[0] == 0) {
931
- vc->esc_params[0] = 1;
909
+ if (vt->esc_params[0] == 0) {
910
+ vt->esc_params[0] = 1;
911
}
933
- vc_set_cursor(vc, vt->x, vt->y - vc->esc_params[0]);
912
+ vt100_set_cursor(vt, vt->x, vt->y - vt->esc_params[0]);
913
break;
914
case 'B':
915
/* move cursor down */
937
- if (vc->esc_params[0] == 0) {
938
- vc->esc_params[0] = 1;
916
+ if (vt->esc_params[0] == 0) {
917
+ vt->esc_params[0] = 1;
918
}
940
- vc_set_cursor(vc, vt->x, vt->y + vc->esc_params[0]);
919
+ vt100_set_cursor(vt, vt->x, vt->y + vt->esc_params[0]);
920
break;
921
case 'C':
922
/* move cursor right */
944
- if (vc->esc_params[0] == 0) {
945
- vc->esc_params[0] = 1;
923
+ if (vt->esc_params[0] == 0) {
924
+ vt->esc_params[0] = 1;
925
}
947
- vc_set_cursor(vc, vt->x + vc->esc_params[0], vt->y);
926
+ vt100_set_cursor(vt, vt->x + vt->esc_params[0], vt->y);
927
break;
928
case 'D':
929
/* move cursor left */
951
- if (vc->esc_params[0] == 0) {
952
- vc->esc_params[0] = 1;
930
+ if (vt->esc_params[0] == 0) {
931
+ vt->esc_params[0] = 1;
932
}
954
- vc_set_cursor(vc, vt->x - vc->esc_params[0], vt->y);
933
+ vt100_set_cursor(vt, vt->x - vt->esc_params[0], vt->y);
934
break;
935
case 'G':
936
/* move cursor to column */
958
- vc_set_cursor(vc, vc->esc_params[0] - 1, vt->y);
937
+ vt100_set_cursor(vt, vt->esc_params[0] - 1, vt->y);
938
break;
939
case 'f':
940
case 'H':
941
/* move cursor to row, column */
963
- vc_set_cursor(vc, vc->esc_params[1] - 1, vc->esc_params[0] - 1);
942
+ vt100_set_cursor(vt, vt->esc_params[1] - 1, vt->esc_params[0] - 1);
943
break;
944
case 'J':
966
- switch (vc->esc_params[0]) {
945
+ switch (vt->esc_params[0]) {
946
case 0:
947
/* clear to end of screen */
948
for (y = vt->y; y < vt->height; y++) {
950
if (y == vt->y && x < vt->x) {
951
continue;
952
}
974
- vc_clear_xy(vc, x, y);
953
+ vt100_clear_xy(vt, x, y);
954
}
955
}
956
break;
961
if (y == vt->y && x > vt->x) {
962
break;
963
}
985
- vc_clear_xy(vc, x, y);
964
+ vt100_clear_xy(vt, x, y);
965
}
966
}
967
break;
969
/* clear entire screen */
970
for (y = 0; y < vt->height; y++) {
971
for (x = 0; x < vt->width; x++) {
993
- vc_clear_xy(vc, x, y);
972
+ vt100_clear_xy(vt, x, y);
973
}
974
}
975
break;
976
}
977
break;
978
case 'K':
1000
- switch (vc->esc_params[0]) {
979
+ switch (vt->esc_params[0]) {
980
case 0:
981
/* clear to eol */
982
for(x = vt->x; x < vt->width; x++) {
1004
- vc_clear_xy(vc, x, vt->y);
983
+ vt100_clear_xy(vt, x, vt->y);
984
}
985
break;
986
case 1:
987
/* clear from beginning of line */
988
for (x = 0; x <= vt->x && x < vt->width; x++) {
1010
- vc_clear_xy(vc, x, vt->y);
989
+ vt100_clear_xy(vt, x, vt->y);
990
}
991
break;
992
case 2:
993
/* clear entire line */
994
for(x = 0; x < vt->width; x++) {
1016
- vc_clear_xy(vc, x, vt->y);
995
+ vt100_clear_xy(vt, x, vt->y);
996
}
997
break;
998
}
999
break;
1000
case 'P':
1022
- vc_csi_P(vc, vc->esc_params[0]);
1001
+ vt100_csi_P(vt, vt->esc_params[0]);
1002
break;
1003
case 'm':
1025
- vc_handle_escape(vc);
1004
+ vt100_handle_escape(vt);
1005
break;
1006
case 'n':
1028
- switch (vc->esc_params[0]) {
1007
+ switch (vt->esc_params[0]) {
1008
case 5:
1009
/* report console status (always succeed)*/
1031
- qemu_text_console_write(s, "\033[0n", 4);
1010
+ vt100_write(vt, "\033[0n", 4);
1011
break;
1012
case 6:
1013
/* report cursor position */
1014
response = g_strdup_printf("\033[%d;%dR",
1015
vt->y + 1, vt->x + 1);
1037
- qemu_text_console_write(s, response, strlen(response));
1016
+ vt100_write(vt, response, strlen(response));
1017
break;
1018
}
1019
break;
1020
case 's':
1042
- vc_save_cursor(vc);
1021
+ vt100_save_cursor(vt);
1022
break;
1023
case 'u':
1045
- vc_restore_cursor(vc);
1024
+ vt100_restore_cursor(vt);
1025
break;
1026
case '@':
1048
- vc_csi_at(vc, vc->esc_params[0]);
1027
+ vt100_csi_at(vt, vt->esc_params[0]);
1028
break;
1029
default:
1030
trace_console_putchar_unhandled(ch);
1036
case TTY_STATE_OSC: /* Operating System Command: ESC ] ... BEL/ST */
1037
if (ch == '\a') {
1038
/* BEL terminates OSC */
1060
- vc->state = TTY_STATE_NORM;
1039
+ vt->state = TTY_STATE_NORM;
1040
} else if (ch == 27) {
1041
/* ESC might start ST (ESC \) */
1063
- vc->state = TTY_STATE_ESC;
1042
+ vt->state = TTY_STATE_ESC;
1043
}
1044
/* All other bytes are silently consumed */
1045
break;
1050
/* Latin-1 map */
1051
break;
1052
}
1074
- vc->state = TTY_STATE_NORM;
1053
+ vt->state = TTY_STATE_NORM;
1054
break;
1055
}
1056
}
1063
{
1064
VCChardev *drv = VC_CHARDEV(chr);
1065
QemuTextConsole *s = drv->console;
1087
- QemuVT100 *vt = &s->vt;
1066
int i;
1067
1090
- vt->update_x0 = vt->width * FONT_WIDTH;
1091
- vt->update_y0 = vt->height * FONT_HEIGHT;
1092
- vt->update_x1 = 0;
1093
- vt->update_y1 = 0;
1094
- vt100_show_cursor(vt, 0);
1068
+ s->vt.update_x0 = s->vt.width * FONT_WIDTH;
1069
+ s->vt.update_y0 = s->vt.height * FONT_HEIGHT;
1070
+ s->vt.update_x1 = 0;
1071
+ s->vt.update_y1 = 0;
1072
+ vt100_show_cursor(&s->vt, 0);
1073
for(i = 0; i < len; i++) {
1096
- vc_putchar(drv, buf[i]);
1074
+ vt100_putchar(&s->vt, buf[i]);
1075
}
1098
- vt100_show_cursor(vt, 1);
1099
- if (vt->update_x0 < vt->update_x1) {
1100
- vt100_image_update(vt, vt->update_x0, vt->update_y0,
1101
- vt->update_x1 - vt->update_x0,
1102
- vt->update_y1 - vt->update_y0);
1076
+ vt100_show_cursor(&s->vt, 1);
1077
+ if (s->vt.update_x0 < s->vt.update_x1) {
1078
+ vt100_image_update(&s->vt, s->vt.update_x0, s->vt.update_y0,
1079
+ s->vt.update_x1 - s->vt.update_x0,
1080
+ s->vt.update_y1 - s->vt.update_y0);
1081
}
1082
return len;
1083
}
1146
{
1147
QemuTextConsole *c = QEMU_TEXT_CONSOLE(obj);
1148
1171
- QTAILQ_INSERT_HEAD(&vt100s, &c->vt, list);
1172
- fifo8_create(&c->out_fifo, 16);
1173
- c->vt.total_height = DEFAULT_BACKSCROLL;
1149
QEMU_CONSOLE(c)->hw_ops = &text_console_ops;
1150
QEMU_CONSOLE(c)->hw = c;
1151
}
1169
{
1170
VCChardev *drv = VC_CHARDEV(chr);
1171
1197
- qemu_text_console_flush(drv->console);
1172
+ qemu_text_console_out_flush(drv->console);
1173
}
1174
1175
static void vc_chr_set_echo(Chardev *chr, bool echo)
1191
dpy_gfx_update(QEMU_CONSOLE(console), x, y, width, height);
1192
}
1193
1194
+static void text_console_out_flush(QemuVT100 *vt)
1195
+{
1196
+ QemuTextConsole *console = container_of(vt, QemuTextConsole, vt);
1197
+
1198
+ qemu_text_console_out_flush(console);
1199
+}
1200
+
1201
static bool vc_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp)
1202
{
1203
ChardevVC *vc = backend->u.vc.data;
1227
s = QEMU_TEXT_CONSOLE(object_new(TYPE_QEMU_FIXED_TEXT_CONSOLE));
1228
}
1229
1230
+ QTAILQ_INSERT_HEAD(&vt100s, &s->vt, list);
1231
+ fifo8_create(&s->vt.out_fifo, 16);
1232
+ s->vt.total_height = DEFAULT_BACKSCROLL;
1233
dpy_gfx_replace_surface(QEMU_CONSOLE(s), qemu_create_displaysurface(width, height));
1234
s->vt.image_update = text_console_image_update;
1235
+ s->vt.out_flush = text_console_out_flush;
1236
1237
s->chr = chr;
1238
drv->console = s;
1239
if (vc->has_encoding) {
1254
- drv->encoding = vc->encoding;
1240
+ drv->encoding = s->vt.encoding = vc->encoding;
1241
}
1242
1243
/* set current text attributes to default */
1258
- drv->t_attrib = TEXT_ATTRIBUTES_DEFAULT;
1244
+ s->vt.t_attrib = TEXT_ATTRIBUTES_DEFAULT;
1245
vt100_set_image(&s->vt, QEMU_CONSOLE(s)->surface->image);
1246
1247
if (chr->label) {
1248
char *msg;
1249
1264
- drv->t_attrib.bgcol = QEMU_COLOR_BLUE;
1250
+ s->vt.t_attrib.bgcol = QEMU_COLOR_BLUE;
1251
msg = g_strdup_printf("%s console\r\n", chr->label);
1252
qemu_chr_write(chr, (uint8_t *)msg, strlen(msg), true);
1253
g_free(msg);
1268
- drv->t_attrib = TEXT_ATTRIBUTES_DEFAULT;
1254
+ s->vt.t_attrib = TEXT_ATTRIBUTES_DEFAULT;
1255
}
1256
1257
qemu_chr_be_event(chr, CHR_EVENT_OPENED);