return len1;
}
+typedef enum {
+ GRAPHIC_CONSOLE,
+ TEXT_CONSOLE,
+ TEXT_CONSOLE_FIXED_SIZE
+} console_type_t;
+
/* ??? This is mis-named.
It is used for both text and graphical consoles. */
struct TextConsole {
- int text_console; /* true if text console */
+ console_type_t console_type;
DisplayState *ds;
/* Graphic console state. */
vga_hw_update_ptr hw_update;
int esc_params[MAX_ESC_PARAMS];
int nb_esc_params;
- /* kbd read handler */
- IOCanRWHandler *fd_can_read;
- IOReadHandler *fd_read;
- void *fd_opaque;
+ CharDriverState *chr;
/* fifo for key pressed */
QEMUFIFO out_fifo;
uint8_t out_fifo_buf[16];
int y, y1;
if (s == active_console) {
+ int x = s->x;
+ if (x >= s->width) {
+ x = s->width - 1;
+ }
y1 = (s->y_base + s->y) % s->total_height;
y = y1 - s->y_displayed;
if (y < 0)
y += s->total_height;
if (y < s->height) {
- c = &s->cells[y1 * s->width + s->x];
+ c = &s->cells[y1 * s->width + x];
if (show) {
TextAttributes t_attrib = s->t_attrib_default;
t_attrib.invers = !(t_attrib.invers); /* invert fg and bg */
- vga_putcharxy(s->ds, s->x, y, c->ch, &t_attrib);
+ vga_putcharxy(s->ds, x, y, c->ch, &t_attrib);
} else {
- vga_putcharxy(s->ds, s->x, y, c->ch,
- &(c->t_attrib));
+ vga_putcharxy(s->ds, x, y, c->ch, &(c->t_attrib));
}
- dpy_update(s->ds, s->x * FONT_WIDTH, y * FONT_HEIGHT,
+ dpy_update(s->ds, x * FONT_WIDTH, y * FONT_HEIGHT,
FONT_WIDTH, FONT_HEIGHT);
}
}
int i, y1;
s = active_console;
- if (!s || !s->text_console)
+ if (!s || (s->console_type == GRAPHIC_CONSOLE))
return;
if (ydelta > 0) {
s->state = TTY_STATE_ESC;
break;
default:
- if (s->x >= s->width - 1) {
- break;
+ if (s->x >= s->width) {
+ /* line wrap */
+ s->x = 0;
+ console_put_lf(s);
}
y1 = (s->y_base + s->y) % s->total_height;
c = &s->cells[y1 * s->width + s->x];
c->t_attrib = s->t_attrib;
update_xy(s, s->x, s->y);
s->x++;
-#if 0 /* line wrap disabled */
- if (s->x >= s->width) {
- s->x = 0;
- console_put_lf(s);
- }
-#endif
break;
}
break;
s = consoles[index];
if (s) {
active_console = s;
- if (s->text_console) {
+ if (s->console_type != GRAPHIC_CONSOLE) {
if (s->g_width != s->ds->width ||
s->g_height != s->ds->height) {
+ if (s->console_type == TEXT_CONSOLE_FIXED_SIZE) {
+ dpy_resize(s->ds, s->g_width, s->g_height);
+ } else {
s->g_width = s->ds->width;
s->g_height = s->ds->height;
text_console_resize(s);
}
+ }
console_refresh(s);
} else {
vga_hw_invalidate();
return len;
}
-static void console_chr_add_read_handler(CharDriverState *chr,
- IOCanRWHandler *fd_can_read,
- IOReadHandler *fd_read, void *opaque)
-{
- TextConsole *s = chr->opaque;
- s->fd_can_read = fd_can_read;
- s->fd_read = fd_read;
- s->fd_opaque = opaque;
-}
-
static void console_send_event(CharDriverState *chr, int event)
{
TextConsole *s = chr->opaque;
int len;
uint8_t buf[16];
- len = s->fd_can_read(s->fd_opaque);
+ len = qemu_chr_can_read(s->chr);
if (len > s->out_fifo.count)
len = s->out_fifo.count;
if (len > 0) {
if (len > sizeof(buf))
len = sizeof(buf);
qemu_fifo_read(&s->out_fifo, buf, len);
- s->fd_read(s->fd_opaque, buf, len);
+ qemu_chr_read(s->chr, buf, len);
}
/* characters are pending: we send them a bit later (XXX:
horrible, should change char device API) */
int c;
s = active_console;
- if (!s || !s->text_console)
+ if (!s || (s->console_type == GRAPHIC_CONSOLE))
return;
switch(keysym) {
} else {
*q++ = keysym;
}
- if (s->fd_read) {
+ if (s->chr->chr_read) {
qemu_fifo_write(&s->out_fifo, buf, q - buf);
kbd_send_chars(s);
}
}
}
-static TextConsole *new_console(DisplayState *ds, int text)
+static TextConsole *new_console(DisplayState *ds, console_type_t console_type)
{
TextConsole *s;
int i;
if (!s) {
return NULL;
}
- if (!active_console || (active_console->text_console && !text))
+ if (!active_console || ((active_console->console_type != GRAPHIC_CONSOLE) &&
+ (console_type == GRAPHIC_CONSOLE))) {
active_console = s;
+ }
s->ds = ds;
- s->text_console = text;
- if (text) {
+ s->console_type = console_type;
+ if (console_type != GRAPHIC_CONSOLE) {
consoles[nb_consoles++] = s;
} else {
/* HACK: Put graphical consoles before text consoles. */
for (i = nb_consoles; i > 0; i--) {
- if (!consoles[i - 1]->text_console)
+ if (consoles[i - 1]->console_type == GRAPHIC_CONSOLE)
break;
consoles[i] = consoles[i - 1];
}
{
TextConsole *s;
- s = new_console(ds, 0);
+ s = new_console(ds, GRAPHIC_CONSOLE);
if (!s)
return NULL;
s->hw_update = update;
int is_graphic_console(void)
{
- return !active_console->text_console;
+ return active_console->console_type == GRAPHIC_CONSOLE;
}
-CharDriverState *text_console_init(DisplayState *ds)
+CharDriverState *text_console_init(DisplayState *ds, const char *p)
{
CharDriverState *chr;
TextConsole *s;
int i,j;
+ unsigned width;
+ unsigned height;
static int color_inited;
chr = qemu_mallocz(sizeof(CharDriverState));
if (!chr)
return NULL;
- s = new_console(ds, 1);
+ s = new_console(ds, (p == 0) ? TEXT_CONSOLE : TEXT_CONSOLE_FIXED_SIZE);
if (!s) {
free(chr);
return NULL;
}
chr->opaque = s;
chr->chr_write = console_puts;
- chr->chr_add_read_handler = console_chr_add_read_handler;
chr->chr_send_event = console_send_event;
+ s->chr = chr;
s->out_fifo.buf = s->out_fifo_buf;
s->out_fifo.buf_size = sizeof(s->out_fifo_buf);
s->kbd_timer = qemu_new_timer(rt_clock, kbd_send_chars, s);
s->total_height = DEFAULT_BACKSCROLL;
s->x = 0;
s->y = 0;
- s->g_width = s->ds->width;
- s->g_height = s->ds->height;
+ width = s->ds->width;
+ height = s->ds->height;
+ if (p != 0) {
+ width = strtoul(p, (char **)&p, 10);
+ if (*p == 'C') {
+ p++;
+ width *= FONT_WIDTH;
+ }
+ if (*p == 'x') {
+ p++;
+ height = strtoul(p, (char **)&p, 10);
+ if (*p == 'C') {
+ p++;
+ height *= FONT_HEIGHT;
+ }
+ }
+ }
+ s->g_width = width;
+ s->g_height = height;
/* Set text attribute defaults */
s->t_attrib_default.bold = 0;