qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 5/8] sdl2: update for multihead support.


From: Dave Airlie
Subject: [Qemu-devel] [PATCH 5/8] sdl2: update for multihead support.
Date: Wed, 20 Nov 2013 15:52:38 +1000

From: Dave Airlie <address@hidden>

This reworks the complete SDL2 code to support multi-head,
by using DisplayChangeListeners wrapped inside a structure per-head,
containing the SDL2 information along with the console info.

This also adds a hack to allow Ctrl-Alt-n to toggle the first
console on/off.

Signed-off-by: Dave Airlie <address@hidden>
---
 ui/sdl2.c | 322 ++++++++++++++++++++++++++++++++++++++++----------------------
 1 file changed, 211 insertions(+), 111 deletions(-)

diff --git a/ui/sdl2.c b/ui/sdl2.c
index 4ad7ce3..6f3a919 100644
--- a/ui/sdl2.c
+++ b/ui/sdl2.c
@@ -39,11 +39,18 @@
 
 #include "sdl2_scancode_translate.h"
 
-static DisplayChangeListener *dcl;
-static DisplaySurface *surface;
-static SDL_Window *real_window;
-static SDL_Renderer *real_renderer;
-static SDL_Texture *guest_texture;
+#define SDL2_MAX_OUTPUT 4
+
+static struct sdl2_console_state {
+    DisplayChangeListener dcl;
+    DisplaySurface *surface;
+    SDL_Texture *texture;
+    SDL_Window *real_window;
+    SDL_Renderer *real_renderer;
+    int idx;
+    int last_vm_running; /* per console for caption reasons */
+    int x, y;
+} sdl2_console[SDL2_MAX_OUTPUT];
 
 static SDL_Surface *guest_sprite_surface;
 static int gui_grab; /* if true, all keyboard/mouse events are grabbed */
@@ -67,70 +74,112 @@ static SDL_Cursor *guest_sprite = NULL;
 static int scaling_active = 0;
 static Notifier mouse_mode_notifier;
 
-static void sdl_update_caption(void);
+static void sdl_update_caption(struct sdl2_console_state *scon);
+
+static struct sdl2_console_state *get_scon_from_window(uint32_t window_id)
+{
+    int i;
+    for (i = 0; i < SDL2_MAX_OUTPUT; i++) {
+        if (sdl2_console[i].real_window == SDL_GetWindowFromID(window_id))
+            return &sdl2_console[i];
+    }
+    return NULL;
+}
 
 static void sdl_update(DisplayChangeListener *dcl,
                        int x, int y, int w, int h)
 {
-    if (!surface)
+    struct sdl2_console_state *scon = container_of(dcl, struct 
sdl2_console_state, dcl);
+    SDL_Rect rect;
+    DisplaySurface *surf = qemu_console_surface(dcl->con);
+
+    if (!surf)
+        return;
+    if (!scon->texture)
         return;
 
-    SDL_UpdateTexture(guest_texture, NULL, surface_data(surface),
-                      surface_stride(surface));
-    SDL_RenderCopy(real_renderer, guest_texture, NULL, NULL);
-    SDL_RenderPresent(real_renderer);
+    rect.x = x;
+    rect.y = y;
+    rect.w = w;
+    rect.h = h;
+
+    SDL_UpdateTexture(scon->texture, NULL, surface_data(surf),
+                      surface_stride(surf));
+    SDL_RenderCopy(scon->real_renderer, scon->texture, &rect, &rect);
+    SDL_RenderPresent(scon->real_renderer);
 }
 
-static void do_sdl_resize(int width, int height, int bpp)
+static void do_sdl_resize(struct sdl2_console_state *scon, int width, int 
height, int bpp)
 {
     int flags;
 
-    if (real_window) {
-        SDL_SetWindowSize(real_window, width, height);
-        SDL_RenderSetLogicalSize(real_renderer, width, height);
+    if (scon->real_window && scon->real_renderer) {
+        if (width && height) {
+            SDL_RenderSetLogicalSize(scon->real_renderer, width, height);
+       
+            SDL_SetWindowSize(scon->real_window, width, height);
+        } else {
+            SDL_DestroyRenderer(scon->real_renderer);
+            SDL_DestroyWindow(scon->real_window);
+            scon->real_renderer = NULL;
+            scon->real_window = NULL;
+        }
     } else {
+        if (!width || !height) {
+            return;
+        }
         flags = 0;
         if (gui_fullscreen)
             flags |= SDL_WINDOW_FULLSCREEN;
         else
             flags |= SDL_WINDOW_RESIZABLE;
 
-        real_window = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED,
-                                       SDL_WINDOWPOS_UNDEFINED,
-                                       width, height, flags);
-        real_renderer = SDL_CreateRenderer(real_window, -1, 0);
-        sdl_update_caption();
+        scon->real_window = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED,
+                                             SDL_WINDOWPOS_UNDEFINED,
+                                             width, height, flags);
+        scon->real_renderer = SDL_CreateRenderer(scon->real_window, -1, 0);
+        sdl_update_caption(scon);
     }
 }
 
 static void sdl_switch(DisplayChangeListener *dcl,
                        DisplaySurface *new_surface)
 {
+    struct sdl2_console_state *scon = container_of(dcl, struct 
sdl2_console_state, dcl);
     int format = 0;
+    int idx = qemu_get_console_index(dcl->con);
+    DisplaySurface *old_surface = scon->surface;
+
     /* temporary hack: allows to call sdl_switch to handle scaling changes */
     if (new_surface) {
-        surface = new_surface;
+        scon->surface = new_surface;
     }
 
-    if (!scaling_active) {
-        do_sdl_resize(surface_width(surface), surface_height(surface), 0);
-    } else 
-        do_sdl_resize(surface_width(surface), surface_height(surface), 0);
+    if (!new_surface && idx > 0)
+        scon->surface = NULL;
 
-    if (guest_texture)
-        SDL_DestroyTexture(guest_texture);
+    if (new_surface == NULL)
+        do_sdl_resize(scon, 0, 0, 0);
+    else
+        do_sdl_resize(scon, surface_width(scon->surface), 
surface_height(scon->surface), 0);
 
-    if (surface_bits_per_pixel(surface) == 16)
-        format = SDL_PIXELFORMAT_RGB565;
-    else if (surface_bits_per_pixel(surface) == 32)
-        format = SDL_PIXELFORMAT_ARGB8888;
+    if (old_surface && scon->texture) {
+        SDL_DestroyTexture(scon->texture);
+        scon->texture = NULL;
+    }
 
-    if (!format)
-        exit(1);
-    guest_texture = SDL_CreateTexture(real_renderer, format,
-                                      SDL_TEXTUREACCESS_STREAMING,
-                                      surface_width(surface), 
surface_height(surface));
-    SDL_RenderSetLogicalSize(real_renderer, surface_width(surface), 
surface_height(surface));
+    if (new_surface) {
+        if (!scon->texture) {
+            if (surface_bits_per_pixel(scon->surface) == 16)
+                format = SDL_PIXELFORMAT_RGB565;
+            else if (surface_bits_per_pixel(scon->surface) == 32)
+                format = SDL_PIXELFORMAT_ARGB8888;
+
+            scon->texture = SDL_CreateTexture(scon->real_renderer, format,
+                                              SDL_TEXTUREACCESS_STREAMING,
+                                              surface_width(new_surface), 
surface_height(new_surface));
+        }
+    }
 }
 
 /* generic keyboard conversion */
@@ -250,7 +299,7 @@ static void sdl_process_key(SDL_KeyboardEvent *ev)
         kbd_put_keycode(keycode & SCANCODE_KEYCODEMASK);
 }
 
-static void sdl_update_caption(void)
+static void sdl_update_caption(struct sdl2_console_state *scon)
 {
     char win_title[1024];
     char icon_title[1024];
@@ -268,15 +317,15 @@ static void sdl_update_caption(void)
     }
 
     if (qemu_name) {
-        snprintf(win_title, sizeof(win_title), "QEMU (%s)%s", qemu_name, 
status);
+        snprintf(win_title, sizeof(win_title), "QEMU (%s-%d)%s", qemu_name, 
scon->idx, status);
         snprintf(icon_title, sizeof(icon_title), "QEMU (%s)", qemu_name);
     } else {
         snprintf(win_title, sizeof(win_title), "QEMU%s", status);
         snprintf(icon_title, sizeof(icon_title), "QEMU");
     }
 
-    if (real_window)
-      SDL_SetWindowTitle(real_window, win_title);
+    if (scon->real_window)
+        SDL_SetWindowTitle(scon->real_window, win_title);
 }
 
 static void sdl_hide_cursor(void)
@@ -300,52 +349,52 @@ static void sdl_show_cursor(void)
     if (!kbd_mouse_is_absolute() || !qemu_console_is_graphic(NULL)) {
         SDL_ShowCursor(1);
         if (guest_cursor &&
-                (gui_grab || kbd_mouse_is_absolute() || absolute_enabled))
+            (gui_grab || kbd_mouse_is_absolute() || absolute_enabled))
             SDL_SetCursor(guest_sprite);
         else
             SDL_SetCursor(sdl_cursor_normal);
     }
 }
 
-static void sdl_grab_start(void)
+static void sdl_grab_start(struct sdl2_console_state *scon)
 {
     /*
      * If the application is not active, do not try to enter grab state. This
      * prevents 'SDL_WM_GrabInput(SDL_GRAB_ON)' from blocking all the
      * application (SDL bug).
      */
-    if (!(SDL_GetWindowFlags(real_window) & SDL_WINDOW_INPUT_FOCUS)) {
+    if (!(SDL_GetWindowFlags(scon->real_window) & SDL_WINDOW_INPUT_FOCUS)) {
         return;
     }
     if (guest_cursor) {
         SDL_SetCursor(guest_sprite);
         if (!kbd_mouse_is_absolute() && !absolute_enabled) {
-            SDL_WarpMouseInWindow(real_window, guest_x, guest_y);
+            SDL_WarpMouseInWindow(scon->real_window, guest_x, guest_y);
         }
     } else
         sdl_hide_cursor();
-    SDL_SetWindowGrab(real_window, SDL_TRUE);
+    SDL_SetWindowGrab(scon->real_window, SDL_TRUE);
     gui_grab = 1;
-    sdl_update_caption();
+    sdl_update_caption(scon);
 }
 
-static void sdl_grab_end(void)
+static void sdl_grab_end(struct sdl2_console_state *scon)
 {
-    SDL_SetWindowGrab(real_window, SDL_FALSE);
+    SDL_SetWindowGrab(scon->real_window, SDL_FALSE);
     gui_grab = 0;
     sdl_show_cursor();
-    sdl_update_caption();
+    sdl_update_caption(scon);
 }
 
-static void absolute_mouse_grab(void)
+static void absolute_mouse_grab(struct sdl2_console_state *scon)
 {
     int mouse_x, mouse_y;
     int scr_w, scr_h;
     SDL_GetMouseState(&mouse_x, &mouse_y);
-    SDL_GetWindowSize(real_window, &scr_w, &scr_h);
+    SDL_GetWindowSize(scon->real_window, &scr_w, &scr_h);
     if (mouse_x > 0 && mouse_x < scr_w - 1 &&
         mouse_y > 0 && mouse_y < scr_h - 1) {
-        sdl_grab_start();
+        sdl_grab_start(scon);
     }
 }
 
@@ -355,18 +404,18 @@ static void sdl_mouse_mode_change(Notifier *notify, void 
*data)
         if (!absolute_enabled) {
             absolute_enabled = 1;
             if (qemu_console_is_graphic(NULL)) {
-                absolute_mouse_grab();
+                absolute_mouse_grab(&sdl2_console[0]);
             }
         }
     } else if (absolute_enabled) {
         if (!gui_fullscreen) {
-            sdl_grab_end();
+            sdl_grab_end(&sdl2_console[0]);
         }
         absolute_enabled = 0;
     }
 }
 
-static void sdl_send_mouse_event(int dx, int dy, int dz, int x, int y, int 
state)
+static void sdl_send_mouse_event(struct sdl2_console_state *scon, int dx, int 
dy, int dz, int x, int y, int state)
 {
     int buttons = 0;
 
@@ -382,9 +431,30 @@ static void sdl_send_mouse_event(int dx, int dy, int dz, 
int x, int y, int state
 
     if (kbd_mouse_is_absolute()) {
         int scr_w, scr_h;
-        SDL_GetWindowSize(real_window, &scr_w, &scr_h);
-        dx = x * 0x7FFF / (scr_w - 1);
-        dy = y * 0x7FFF / (scr_h - 1);
+        int max_w = 0, max_h = 0;
+        int off_x = 0, off_y = 0;
+        int cur_off_x = 0, cur_off_y = 0;
+        int i;
+
+        for (i = 0; i < SDL2_MAX_OUTPUT; i++) {
+            struct sdl2_console_state *thiscon = &sdl2_console[i];
+            if (thiscon->real_window && thiscon->surface) {
+                SDL_GetWindowSize(thiscon->real_window, &scr_w, &scr_h);
+                cur_off_x = thiscon->x;
+                cur_off_y = thiscon->y;
+                if (scr_w + cur_off_x > max_w)
+                    max_w = scr_w + cur_off_x;
+                if (scr_h + cur_off_y > max_h)
+                    max_h = scr_h + cur_off_y;
+                if (i == scon->idx) {
+                    off_x = cur_off_x;
+                    off_y = cur_off_y;
+                }
+            }
+        }
+
+        dx = (off_x + x) * 0x7FFF / (max_w - 1);
+        dy = (off_y + y) * 0x7FFF / (max_h - 1);
     } else if (guest_cursor) {
         x -= guest_x;
         y -= guest_y;
@@ -397,51 +467,52 @@ static void sdl_send_mouse_event(int dx, int dy, int dz, 
int x, int y, int state
     kbd_mouse_event(dx, dy, dz, buttons);
 }
 
-static void sdl_scale(int width, int height)
+static void sdl_scale(struct sdl2_console_state *scon, int width, int height)
 {
     int bpp = 0;
-    do_sdl_resize(width, height, bpp);
+    do_sdl_resize(scon, width, height, bpp);
     scaling_active = 1;
 }
 
-static void toggle_full_screen(void)
+static void toggle_full_screen(struct sdl2_console_state *scon)
 {
-    int width = surface_width(surface);
-    int height = surface_height(surface);
-    int bpp = surface_bits_per_pixel(surface);
+    int width = surface_width(scon->surface);
+    int height = surface_height(scon->surface);
+    int bpp = surface_bits_per_pixel(scon->surface);
 
     gui_fullscreen = !gui_fullscreen;
     if (gui_fullscreen) {
-        SDL_GetWindowSize(real_window, &gui_saved_width, &gui_saved_height);
+        SDL_GetWindowSize(scon->real_window, &gui_saved_width, 
&gui_saved_height);
         gui_saved_scaling = scaling_active;
 
-        do_sdl_resize(width, height, bpp);
+        do_sdl_resize(scon, width, height, bpp);
         scaling_active = 0;
 
         gui_saved_grab = gui_grab;
-        sdl_grab_start();
+        sdl_grab_start(scon);
     } else {
         if (gui_saved_scaling) {
-            sdl_scale(gui_saved_width, gui_saved_height);
+            sdl_scale(scon, gui_saved_width, gui_saved_height);
         } else {
-            do_sdl_resize(width, height, 0);
+            do_sdl_resize(scon, width, height, 0);
         }
         if (!gui_saved_grab || !qemu_console_is_graphic(NULL)) {
-            sdl_grab_end();
+            sdl_grab_end(scon);
         }
     }
-    graphic_hw_invalidate(NULL);
-    graphic_hw_update(NULL);
+    graphic_hw_invalidate(scon->dcl.con);
+    graphic_hw_update(scon->dcl.con);
 }
 
 static void handle_keydown(SDL_Event *ev)
 {
     int mod_state;
     int keycode;
+    struct sdl2_console_state *scon = get_scon_from_window(ev->key.windowID);
 
     if (alt_grab) {
         mod_state = (SDL_GetModState() & (gui_grab_code | KMOD_LSHIFT)) ==
-                    (gui_grab_code | KMOD_LSHIFT);
+            (gui_grab_code | KMOD_LSHIFT);
     } else if (ctrl_grab) {
         mod_state = (SDL_GetModState() & KMOD_RCTRL) == KMOD_RCTRL;
     } else {
@@ -452,16 +523,23 @@ static void handle_keydown(SDL_Event *ev)
     if (gui_key_modifier_pressed) {
         keycode = sdl_keyevent_to_keycode(&ev->key);
         switch (keycode) {
+        case 0x31:
+            /* spawn a new connected monitor if we have one */
+            if (sdl2_console[1].surface)
+                graphic_hw_notify_state(sdl2_console[1].dcl.con, 0, 0, 0, 0);
+            else
+                graphic_hw_notify_state(sdl2_console[1].dcl.con, 0, 0, 1024, 
768);
+            break;
         case 0x21: /* 'f' key on US keyboard */
-            toggle_full_screen();
+            toggle_full_screen(scon);
             gui_keysym = 1;
             break;
         case 0x16: /* 'u' key on US keyboard */
             if (scaling_active) {
                 scaling_active = 0;
-                sdl_switch(dcl, NULL);
-                graphic_hw_invalidate(NULL);
-                graphic_hw_update(NULL);
+                sdl_switch(&scon->dcl, NULL);
+                graphic_hw_invalidate(scon->dcl.con);
+                graphic_hw_update(scon->dcl.con);
             }
             gui_keysym = 1;
             break;
@@ -476,13 +554,13 @@ static void handle_keydown(SDL_Event *ev)
             if (!qemu_console_is_graphic(NULL)) {
                 /* release grab if going to a text console */
                 if (gui_grab) {
-                    sdl_grab_end();
+                    sdl_grab_end(scon);
                 } else if (absolute_enabled) {
                     sdl_show_cursor();
                 }
             } else if (absolute_enabled) {
                 sdl_hide_cursor();
-                absolute_mouse_grab();
+                absolute_mouse_grab(scon);
             }
             break;
         case 0x1b: /* '+' */
@@ -490,14 +568,14 @@ static void handle_keydown(SDL_Event *ev)
             if (!gui_fullscreen) {
                 int scr_w, scr_h;
                 int width, height;
-                SDL_GetWindowSize(real_window, &scr_w, &scr_h);
+                SDL_GetWindowSize(scon->real_window, &scr_w, &scr_h);
 
                 width = MAX(scr_w + (keycode == 0x1b ? 50 : -50),
-                                160);
-                height = (surface_height(surface) * width) /
-                    surface_width(surface);
+                            160);
+                height = (surface_height(scon->surface) * width) /
+                    surface_width(scon->surface);
 
-                sdl_scale(width, height);
+                sdl_scale(scon, width, height);
                 graphic_hw_invalidate(NULL);
                 graphic_hw_update(NULL);
                 gui_keysym = 1;
@@ -585,6 +663,7 @@ static void handle_keydown(SDL_Event *ev)
 static void handle_keyup(SDL_Event *ev)
 {
     int mod_state;
+    struct sdl2_console_state *scon = get_scon_from_window(ev->key.windowID);
 
     if (!alt_grab) {
         mod_state = (ev->key.keysym.mod & gui_grab_code);
@@ -597,10 +676,10 @@ static void handle_keyup(SDL_Event *ev)
             /* exit/enter grab if pressing Ctrl-Alt */
             if (!gui_grab) {
                 if (qemu_console_is_graphic(NULL)) {
-                    sdl_grab_start();
+                    sdl_grab_start(scon);
                 }
             } else if (!gui_fullscreen) {
-                sdl_grab_end();
+                sdl_grab_end(scon);
             }
             /* SDL does not send back all the modifiers key, so we must
              * correct it. */
@@ -617,25 +696,26 @@ static void handle_keyup(SDL_Event *ev)
 static void handle_mousemotion(SDL_Event *ev)
 {
     int max_x, max_y;
+    struct sdl2_console_state *scon = get_scon_from_window(ev->key.windowID);
 
     if (qemu_console_is_graphic(NULL) &&
         (kbd_mouse_is_absolute() || absolute_enabled)) {
         int scr_w, scr_h;
-        SDL_GetWindowSize(real_window, &scr_w, &scr_h);
+        SDL_GetWindowSize(scon->real_window, &scr_w, &scr_h);
         max_x = scr_w - 1;
         max_y = scr_h - 1;
         if (gui_grab && (ev->motion.x == 0 || ev->motion.y == 0 ||
-            ev->motion.x == max_x || ev->motion.y == max_y)) {
-            sdl_grab_end();
+                         ev->motion.x == max_x || ev->motion.y == max_y)) {
+            sdl_grab_end(scon);
         }
         if (!gui_grab &&
             (ev->motion.x > 0 && ev->motion.x < max_x &&
-            ev->motion.y > 0 && ev->motion.y < max_y)) {
-            sdl_grab_start();
+             ev->motion.y > 0 && ev->motion.y < max_y)) {
+            sdl_grab_start(scon);
         }
     }
     if (gui_grab || kbd_mouse_is_absolute() || absolute_enabled) {
-        sdl_send_mouse_event(ev->motion.xrel, ev->motion.yrel, 0,
+        sdl_send_mouse_event(scon, ev->motion.xrel, ev->motion.yrel, 0,
                              ev->motion.x, ev->motion.y, ev->motion.state);
     }
 }
@@ -644,6 +724,7 @@ static void handle_mousebutton(SDL_Event *ev)
 {
     int buttonstate = SDL_GetMouseState(NULL, NULL);
     SDL_MouseButtonEvent *bev;
+    struct sdl2_console_state *scon = get_scon_from_window(ev->key.windowID);
     int dz;
 
     if (!qemu_console_is_graphic(NULL)) {
@@ -654,7 +735,7 @@ static void handle_mousebutton(SDL_Event *ev)
     if (!gui_grab && !kbd_mouse_is_absolute()) {
         if (ev->type == SDL_MOUSEBUTTONUP && bev->button == SDL_BUTTON_LEFT) {
             /* start grabbing all events */
-            sdl_grab_start();
+            sdl_grab_start(scon);
         }
     } else {
         dz = 0;
@@ -672,19 +753,20 @@ static void handle_mousebutton(SDL_Event *ev)
             dz = 1;
         }
 #endif
-        sdl_send_mouse_event(0, 0, dz, bev->x, bev->y, buttonstate);
+        sdl_send_mouse_event(scon, 0, 0, dz, bev->x, bev->y, buttonstate);
     }
 }
 
 static void handle_windowevent(DisplayChangeListener *dcl, SDL_Event *ev)
 {
     int w, h;
+    struct sdl2_console_state *scon = get_scon_from_window(ev->key.windowID);
 
     switch (ev->window.event) {
     case SDL_WINDOWEVENT_RESIZED:
-        sdl_scale(ev->window.data1, ev->window.data2);
-        graphic_hw_invalidate(NULL);
-        graphic_hw_update(NULL);
+        sdl_scale(scon, ev->window.data1, ev->window.data2);
+        graphic_hw_invalidate(scon->dcl.con);
+        graphic_hw_update(scon->dcl.con);
         break;
     case SDL_WINDOWEVENT_EXPOSED:
         SDL_GetWindowSize(SDL_GetWindowFromID(ev->window.windowID), &w, &h);
@@ -694,12 +776,12 @@ static void handle_windowevent(DisplayChangeListener 
*dcl, SDL_Event *ev)
     case SDL_WINDOWEVENT_ENTER:
         if (!gui_grab && qemu_console_is_graphic(NULL) &&
             (kbd_mouse_is_absolute() || absolute_enabled)) {
-            absolute_mouse_grab();
+            absolute_mouse_grab(scon);
         }
         break;
     case SDL_WINDOWEVENT_FOCUS_LOST:
         if (gui_grab && !gui_fullscreen)
-            sdl_grab_end();
+            sdl_grab_end(scon);
         break;
     case SDL_WINDOWEVENT_RESTORED:
         update_displaychangelistener(dcl, GUI_REFRESH_INTERVAL_DEFAULT);
@@ -718,14 +800,15 @@ static void handle_windowevent(DisplayChangeListener 
*dcl, SDL_Event *ev)
 
 static void sdl_refresh(DisplayChangeListener *dcl)
 {
+    struct sdl2_console_state *scon = container_of(dcl, struct 
sdl2_console_state, dcl);
     SDL_Event ev1, *ev = &ev1;
 
-    if (last_vm_running != runstate_is_running()) {
-        last_vm_running = runstate_is_running();
-        sdl_update_caption();
+    if (scon->last_vm_running != runstate_is_running()) {
+        scon->last_vm_running = runstate_is_running();
+        sdl_update_caption(scon);
     }
 
-    graphic_hw_update(NULL);
+    graphic_hw_update(dcl->con);
 
     while (SDL_PollEvent(ev)) {
         switch (ev->type) {
@@ -760,13 +843,14 @@ static void sdl_refresh(DisplayChangeListener *dcl)
 static void sdl_mouse_warp(DisplayChangeListener *dcl,
                            int x, int y, int on)
 {
+    struct sdl2_console_state *scon = container_of(dcl, struct 
sdl2_console_state, dcl);
     if (on) {
         if (!guest_cursor)
             sdl_show_cursor();
         if (gui_grab || kbd_mouse_is_absolute() || absolute_enabled) {
             SDL_SetCursor(guest_sprite);
             if (!kbd_mouse_is_absolute() && !absolute_enabled) {
-                SDL_WarpMouseInWindow(real_window, x, y);
+                SDL_WarpMouseInWindow(scon->real_window, x, y);
             }
         }
     } else if (gui_grab)
@@ -804,6 +888,15 @@ static void sdl_mouse_define(DisplayChangeListener *dcl,
         SDL_SetCursor(guest_sprite);
 }
 
+static void sdl_notify_state(DisplayChangeListener *dcl,
+                             int x, int y, uint32_t width, uint32_t height)
+{
+    struct sdl2_console_state *scon = container_of(dcl, struct 
sdl2_console_state, dcl);
+
+    scon->x = x;
+    scon->y = y;
+}
+
 static void sdl_cleanup(void)
 {
     if (guest_sprite)
@@ -818,6 +911,7 @@ static const DisplayChangeListenerOps dcl_ops = {
     .dpy_refresh       = sdl_refresh,
     .dpy_mouse_set     = sdl_mouse_warp,
     .dpy_cursor_define = sdl_mouse_define,
+    .dpy_notify_state  = sdl_notify_state,
 };
 
 void sdl_display_init(DisplayState *ds, int full_screen, int no_frame)
@@ -825,7 +919,8 @@ void sdl_display_init(DisplayState *ds, int full_screen, 
int no_frame)
     int flags;
     uint8_t data = 0;
     char *filename;
-
+    int nconsoles;
+    int i;
 #if defined(__APPLE__)
     /* always use generic keymaps */
     if (!keyboard_layout)
@@ -866,19 +961,24 @@ void sdl_display_init(DisplayState *ds, int full_screen, 
int no_frame)
         if (image) {
             uint32_t colorkey = SDL_MapRGB(image->format, 255, 255, 255);
             SDL_SetColorKey(image, SDL_TRUE, colorkey);
-            SDL_SetWindowIcon(real_window, image);
+            SDL_SetWindowIcon(sdl2_console[0].real_window, image);
         }
         g_free(filename);
     }
 
     if (full_screen) {
         gui_fullscreen = 1;
-        sdl_grab_start();
+        sdl_grab_start(0);
     }
 
-    dcl = g_malloc0(sizeof(DisplayChangeListener));
-    dcl->ops = &dcl_ops;
-    register_displaychangelistener(dcl);
+    nconsoles = qemu_get_number_graphical_consoles();
+    
+    for (i = 0; i < nconsoles; i++) {
+        sdl2_console[i].dcl.ops = &dcl_ops;
+        sdl2_console[i].dcl.con = qemu_console_lookup_by_index(i);
+        register_displaychangelistener(&sdl2_console[i].dcl);
+        sdl2_console[i].idx = i;
+    }
 
     mouse_mode_notifier.notify = sdl_mouse_mode_change;
     qemu_add_mouse_mode_change_notifier(&mouse_mode_notifier);
-- 
1.8.3.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]