Patchwork [16/48] sdl: multitouch and window close suppport

login
register
mail settings
Submitter Riku Voipio
Date March 26, 2010, 4:06 p.m.
Message ID <6986507e48450820c1ffc84bcc96908cc14d7d46.1269617186.git.riku.voipio@nokia.com>
Download mbox | patch
Permalink /patch/48661/
State New
Headers show

Comments

Riku Voipio - March 26, 2010, 4:06 p.m.
From: Juha Riihimäki <juha.riihimaki@nokia.com>

- show shutting down status in window caption
- add display close handler support
- add support for disabling input grabbing
- add ability to disable window grab:

currently if the qemu window is inactive and you click inside the
qemu window the input will be grabbed. with touchscreen devices
this might not be very feasible as there is no visible guest
cursor so this patch adds a global variable that can be used to
control the grabbing behavior. default behavior is not modified
but for n8x0, n900 and n00 devices the grabbing is disabled.
note that with sdl rendering you can still toggle grabbing by
pressing ctrl+alt when the qemu window is active.

Signed-Off-By: Riku Voipio <riku.voipio@nokia.com>
Signed-Off-By: Juha Riihimäki <juha.riihimaki@nokia.com>

---
 sdl.c |   66 +++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 54 insertions(+), 12 deletions(-)

Patch

diff --git a/sdl.c b/sdl.c
index 16a48e9..40e2ad1 100644
--- a/sdl.c
+++ b/sdl.c
@@ -57,6 +57,8 @@  static SDL_Cursor *guest_sprite = NULL;
 static uint8_t allocator;
 static SDL_PixelFormat host_format;
 static int scaling_active = 0;
+static int mouseX = 0, mouseY = 0;
+static int shutting_down_guest = 0;
 static Notifier mouse_mode_notifier;
 
 static void sdl_update(DisplayState *ds, int x, int y, int w, int h)
@@ -78,6 +80,30 @@  static void sdl_update(DisplayState *ds, int x, int y, int w, int h)
             }
         }
     } 
+    if (multitouch_enabled && !cursor_hide && !gui_grab &&
+        modifiers_state[56] && real_screen && real_screen->pixels) {
+        unsigned char *p = (unsigned char *)real_screen->pixels;
+        int altX = real_screen->w - mouseX;
+        int altY = real_screen->h - mouseY;
+        int x, y;
+        int bytesperpixel = real_screen->format->BytesPerPixel;
+        p += altY * real_screen->pitch;
+        for (y = 0; y < 8; y++) {
+            if (y + altY > 0 && y + altY < real_screen->h) {
+                unsigned char *q = p + altX * bytesperpixel;
+                for (x = 0; x < 8; x++) {
+                    if (x + altX > 0 && x + altX < real_screen->w) {
+                        int i;
+                        for (i = 0; i < bytesperpixel; i++) {
+                            q[i] ^= 0xff;
+                        }
+                    }
+                    q += bytesperpixel;
+                }
+            }
+            p += real_screen->pitch;
+        }
+    }
     SDL_UpdateRect(real_screen, rec.x, rec.y, rec.w, rec.h);
 }
 
@@ -413,15 +439,19 @@  static void sdl_update_caption(void)
     char icon_title[1024];
     const char *status = "";
 
-    if (!vm_running)
-        status = " [Stopped]";
-    else if (gui_grab) {
-        if (alt_grab)
-            status = " - Press Ctrl-Alt-Shift to exit mouse grab";
-        else if (ctrl_grab)
-            status = " - Press Right-Ctrl to exit mouse grab";
-        else
-            status = " - Press Ctrl-Alt to exit mouse grab";
+    if (shutting_down_guest) {
+        status = " [Shutting down]";
+    } else {
+        if (!vm_running)
+            status = " [Stopped]";
+        else if (gui_grab) {
+            if (alt_grab)
+                status = " - Press Ctrl-Alt-Shift to exit mouse grab";
+            else if (ctrl_grab)
+                status = " - Press Right-Ctrl to exit mouse grab";
+            else
+                status = " - Press Ctrl-Alt to exit mouse grab";
+        }
     }
 
     if (qemu_name) {
@@ -513,6 +543,9 @@  static void sdl_send_mouse_event(int dx, int dy, int dz, int x, int y, int state
         buttons |= MOUSE_EVENT_RBUTTON;
     if (state & SDL_BUTTON(SDL_BUTTON_MIDDLE))
         buttons |= MOUSE_EVENT_MBUTTON;
+    if (modifiers_state[56] &&
+        (buttons & (MOUSE_EVENT_LBUTTON | MOUSE_EVENT_RBUTTON)))
+        buttons |= MOUSE_EVENT_MBUTTON << 1;
 
     if (kbd_mouse_is_absolute()) {
        dx = x * 0x7FFF / (width - 1);
@@ -526,6 +559,9 @@  static void sdl_send_mouse_event(int dx, int dy, int dz, int x, int y, int state
         dy = y;
     }
 
+    mouseX = x;
+    mouseY = y;
+
     kbd_mouse_event(dx, dy, dz, buttons);
 }
 
@@ -678,8 +714,14 @@  static void sdl_refresh(DisplayState *ds)
                 sdl_process_key(&ev->key);
             break;
         case SDL_QUIT:
-            if (!no_quit)
-                qemu_system_shutdown_request();
+            if (!no_quit) {
+                if (qemu_run_display_close_handler()) {
+                    qemu_system_shutdown_request();
+                } else {
+                    shutting_down_guest = 1;
+                    sdl_update_caption();
+                }
+            }
             break;
         case SDL_MOUSEMOTION:
             if (gui_grab || kbd_mouse_is_absolute() ||
@@ -696,7 +738,7 @@  static void sdl_refresh(DisplayState *ds)
                     if (ev->type == SDL_MOUSEBUTTONDOWN &&
                         (bev->button == SDL_BUTTON_LEFT)) {
                         /* start grabbing all events */
-                        sdl_grab_start();
+                        if (cursor_allow_grab) sdl_grab_start();
                     }
                 } else {
                     int dz;