All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dave Airlie <airlied@gmail.com>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH 5/8] sdl2: update for multihead support.
Date: Wed, 20 Nov 2013 15:52:38 +1000	[thread overview]
Message-ID: <1384926761-9962-6-git-send-email-airlied@gmail.com> (raw)
In-Reply-To: <1384926761-9962-1-git-send-email-airlied@gmail.com>

From: Dave Airlie <airlied@redhat.com>

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 <airlied@redhat.com>
---
 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

  parent reply	other threads:[~2013-11-20  5:53 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-11-20  5:52 [Qemu-devel] [RFC] virtio-gpu and sdl2 so far Dave Airlie
2013-11-20  5:52 ` [Qemu-devel] [PATCH 1/8] ui/sdl2 : initial port to SDL 2.0 (v1.2) Dave Airlie
2013-11-20 10:52   ` Gerd Hoffmann
2013-11-20  5:52 ` [Qemu-devel] [PATCH 2/8] console: add state notifiers for ui<->display Dave Airlie
2013-11-20 11:04   ` Gerd Hoffmann
2013-11-20  5:52 ` [Qemu-devel] [PATCH 3/8] console: add information retrival wrappers Dave Airlie
2013-11-20 11:12   ` Gerd Hoffmann
2013-11-20  5:52 ` [Qemu-devel] [PATCH 4/8] console: add ability to wrap a console Dave Airlie
2013-11-20  5:52 ` Dave Airlie [this message]
2013-11-20  5:52 ` [Qemu-devel] [PATCH 6/8] virtio-gpu: v0.1 of the virtio based GPU code Dave Airlie
2013-11-20 11:26   ` Gerd Hoffmann
2013-11-20  5:52 ` [Qemu-devel] [PATCH 7/8] virtio-vga: v1 Dave Airlie
2013-11-20 12:02   ` Gerd Hoffmann
2013-11-21  3:12     ` Dave Airlie
2013-11-21  6:17       ` Paolo Bonzini
2013-11-21 11:06       ` Gerd Hoffmann
2013-12-06  5:24         ` Dave Airlie
2013-12-06  8:24           ` Gerd Hoffmann
2013-12-06  8:58             ` Dave Airlie
2014-01-07 23:35               ` Dave Airlie
2014-01-13  8:01                 ` Gerd Hoffmann
2013-11-20  5:52 ` [Qemu-devel] [PATCH 8/8] HACK: just to make things start easier with libvirt Dave Airlie

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1384926761-9962-6-git-send-email-airlied@gmail.com \
    --to=airlied@gmail.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.