]> git.proxmox.com Git - qemu.git/blobdiff - console.c
Avoid asprintf() which is not available on mingw
[qemu.git] / console.c
index 223f8fd9a4563606c348c79c44887914a952e2c9..4525cc70b87bb287dd05c2a723d9a77b0612d20c 100644 (file)
--- a/console.c
+++ b/console.c
@@ -28,6 +28,7 @@
 //#define DEBUG_CONSOLE
 #define DEFAULT_BACKSCROLL 512
 #define MAX_CONSOLES 12
+#define CONSOLE_CURSOR_PERIOD 500
 
 #define QEMU_RGBA(r, g, b, a) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
 #define QEMU_RGB(r, g, b) QEMU_RGBA(r, g, b, 0xff)
@@ -139,6 +140,8 @@ struct TextConsole {
     TextCell *cells;
     int text_x[2], text_y[2], cursor_invalidate;
     int echo;
+    bool cursor_visible_phase;
+    QEMUTimer *cursor_timer;
 
     int update_x0;
     int update_y0;
@@ -176,17 +179,25 @@ void vga_hw_invalidate(void)
 void vga_hw_screen_dump(const char *filename)
 {
     TextConsole *previous_active_console;
+    bool cswitch;
 
     previous_active_console = active_console;
+    cswitch = previous_active_console && previous_active_console->index != 0;
 
     /* There is currently no way of specifying which screen we want to dump,
        so always dump the first one.  */
-    console_select(0);
+    if (cswitch) {
+        console_select(0);
+    }
     if (consoles[0] && consoles[0]->hw_screen_dump) {
-        consoles[0]->hw_screen_dump(consoles[0]->hw, filename);
+        consoles[0]->hw_screen_dump(consoles[0]->hw, filename, cswitch);
+    } else {
+        error_report("screen dump not implemented");
     }
 
-    console_select(previous_active_console->index);
+    if (cswitch) {
+        console_select(previous_active_console->index);
+    }
 }
 
 void vga_hw_text_update(console_ch_t *chardata)
@@ -607,7 +618,7 @@ static void console_show_cursor(TextConsole *s, int show)
             y += s->total_height;
         if (y < s->height) {
             c = &s->cells[y1 * s->width + x];
-            if (show) {
+            if (show && s->cursor_visible_phase) {
                 TextAttributes t_attrib = s->t_attrib_default;
                 t_attrib.invers = !(t_attrib.invers); /* invert fg and bg */
                 vga_putcharxy(s->ds, x, y, c->ch, &t_attrib);
@@ -1075,6 +1086,10 @@ void console_select(unsigned int index)
     s = consoles[index];
     if (s) {
         DisplayState *ds = s->ds;
+
+        if (active_console->cursor_timer) {
+            qemu_del_timer(active_console->cursor_timer);
+        }
         active_console = s;
         if (ds_get_bits_per_pixel(s->ds)) {
             ds->surface = qemu_resize_displaysurface(ds, s->g_width, s->g_height);
@@ -1082,6 +1097,10 @@ void console_select(unsigned int index)
             s->ds->surface->width = s->width;
             s->ds->surface->height = s->height;
         }
+        if (s->cursor_timer) {
+            qemu_mod_timer(s->cursor_timer,
+                   qemu_get_clock_ms(rt_clock) + CONSOLE_CURSOR_PERIOD / 2);
+        }
         dpy_resize(s->ds);
         vga_hw_invalidate();
     }
@@ -1439,9 +1458,6 @@ void console_color_init(DisplayState *ds)
     }
 }
 
-static int n_text_consoles;
-static CharDriverState *text_consoles[128];
-
 static void text_console_set_echo(CharDriverState *chr, bool echo)
 {
     TextConsole *s = chr->opaque;
@@ -1449,6 +1465,16 @@ static void text_console_set_echo(CharDriverState *chr, bool echo)
     s->echo = echo;
 }
 
+static void text_console_update_cursor(void *opaque)
+{
+    TextConsole *s = opaque;
+
+    s->cursor_visible_phase = !s->cursor_visible_phase;
+    vga_hw_invalidate();
+    qemu_mod_timer(s->cursor_timer,
+                   qemu_get_clock_ms(rt_clock) + CONSOLE_CURSOR_PERIOD / 2);
+}
+
 static void text_console_do_init(CharDriverState *chr, DisplayState *ds)
 {
     TextConsole *s;
@@ -1477,6 +1503,9 @@ static void text_console_do_init(CharDriverState *chr, DisplayState *ds)
         s->g_height = ds_get_height(s->ds);
     }
 
+    s->cursor_timer =
+        qemu_new_timer_ms(rt_clock, text_console_update_cursor, s);
+
     s->hw_invalidate = text_console_invalidate;
     s->hw_text_update = text_console_update;
     s->hw = s;
@@ -1508,7 +1537,7 @@ static void text_console_do_init(CharDriverState *chr, DisplayState *ds)
         chr->init(chr);
 }
 
-int text_console_init(QemuOpts *opts, CharDriverState **_chr)
+CharDriverState *text_console_init(QemuOpts *opts)
 {
     CharDriverState *chr;
     TextConsole *s;
@@ -1517,13 +1546,6 @@ int text_console_init(QemuOpts *opts, CharDriverState **_chr)
 
     chr = g_malloc0(sizeof(CharDriverState));
 
-    if (n_text_consoles == 128) {
-        fprintf(stderr, "Too many text consoles\n");
-        exit(1);
-    }
-    text_consoles[n_text_consoles] = chr;
-    n_text_consoles++;
-
     width = qemu_opt_get_number(opts, "width", 0);
     if (width == 0)
         width = qemu_opt_get_number(opts, "cols", 0) * FONT_WIDTH;
@@ -1540,7 +1562,7 @@ int text_console_init(QemuOpts *opts, CharDriverState **_chr)
 
     if (!s) {
         g_free(chr);
-        return -EBUSY;
+        return NULL;
     }
 
     s->chr = chr;
@@ -1548,20 +1570,18 @@ int text_console_init(QemuOpts *opts, CharDriverState **_chr)
     s->g_height = height;
     chr->opaque = s;
     chr->chr_set_echo = text_console_set_echo;
-
-    *_chr = chr;
-    return 0;
+    return chr;
 }
 
 void text_consoles_set_display(DisplayState *ds)
 {
     int i;
 
-    for (i = 0; i < n_text_consoles; i++) {
-        text_console_do_init(text_consoles[i], ds);
+    for (i = 0; i < nb_consoles; i++) {
+        if (consoles[i]->console_type != GRAPHIC_CONSOLE) {
+            text_console_do_init(consoles[i]->chr, ds);
+        }
     }
-
-    n_text_consoles = 0;
 }
 
 void qemu_console_resize(DisplayState *ds, int width, int height)