[Commits] SDL: Fixed bug 3974 - Fix SDL_WarpMouseInWindow on both KMSDRM a...

libsdl.org revision control commits-owner at libsdl.org
Mon Dec 4 20:37:07 PST 2017


details:   https://hg.libsdl.org/SDL/rev/73826bd39748
changeset: 11724:73826bd39748
user:      Sam Lantinga <slouken at libsdl.org>
date:      Mon Dec 04 20:37:01 2017 -0800
description:
Fixed bug 3974 - Fix SDL_WarpMouseInWindow on both KMSDRM and RaspberryPi drivers

Manuel Alfayate Corchete

This patch fixes SDL_WarpMouseInWindow() in both the KMSDRM and Raspberry Pi graphic backends.

diffstat:

 src/video/kmsdrm/SDL_kmsdrmmouse.c |  20 +++++++++++-
 src/video/raspberry/SDL_rpimouse.c |  63 +++++++++++++++++++++++++++++++++++++-
 2 files changed, 81 insertions(+), 2 deletions(-)

diffs (119 lines):

diff -r bc7ca7cfa6ca -r 73826bd39748 src/video/kmsdrm/SDL_kmsdrmmouse.c
--- a/src/video/kmsdrm/SDL_kmsdrmmouse.c	Mon Dec 04 20:35:01 2017 -0800
+++ b/src/video/kmsdrm/SDL_kmsdrmmouse.c	Mon Dec 04 20:37:01 2017 -0800
@@ -423,8 +423,13 @@
     SDL_Mouse *mouse = SDL_GetMouse();
 
     if (mouse != NULL && mouse->cur_cursor != NULL && mouse->cur_cursor->driverdata != NULL) {
+        /* Update internal mouse position. */
+        SDL_SendMouseMotion(mouse->focus, mouse->mouseID, 0, x, y);
+
+        /* And now update the cursor graphic position on screen. */
         curdata = (KMSDRM_CursorData *) mouse->cur_cursor->driverdata;
         if (curdata->bo != NULL) {
+
             if (curdata->crtc_id != 0) {
                 int ret, drm_fd;
                 drm_fd = KMSDRM_gbm_device_get_fd(KMSDRM_gbm_bo_get_device(curdata->bo));
@@ -475,7 +480,20 @@
 KMSDRM_MoveCursor(SDL_Cursor * cursor)
 {
     SDL_Mouse *mouse = SDL_GetMouse();
-    KMSDRM_WarpMouse(mouse->focus, mouse->x, mouse->y);
+    KMSDRM_CursorData *curdata;
+    int drm_fd, ret;
+
+    /* We must NOT call SDL_SendMouseMotion() here or we will enter recursivity!
+       That's why we move the cursor graphic ONLY. */
+    if (mouse != NULL && mouse->cur_cursor != NULL && mouse->cur_cursor->driverdata != NULL) {
+        curdata = (KMSDRM_CursorData *) mouse->cur_cursor->driverdata;
+	drm_fd = KMSDRM_gbm_device_get_fd(KMSDRM_gbm_bo_get_device(curdata->bo));
+	ret = KMSDRM_drmModeMoveCursor(drm_fd, curdata->crtc_id, mouse->x, mouse->y);
+
+	if (ret) {
+	    SDL_SetError("drmModeMoveCursor() failed.");
+	}
+    }
 }
 
 #endif /* SDL_VIDEO_DRIVER_KMSDRM */
diff -r bc7ca7cfa6ca -r 73826bd39748 src/video/raspberry/SDL_rpimouse.c
--- a/src/video/raspberry/SDL_rpimouse.c	Mon Dec 04 20:35:01 2017 -0800
+++ b/src/video/raspberry/SDL_rpimouse.c	Mon Dec 04 20:37:01 2017 -0800
@@ -247,6 +247,65 @@
         return 0;
     }
 
+    /* Update internal mouse position. */
+    SDL_SendMouseMotion(mouse->focus, mouse->mouseID, 0, x, y);
+
+    curdata = (RPI_CursorData *) mouse->cur_cursor->driverdata;
+    if (curdata->element == DISPMANX_NO_HANDLE) {
+        return 0;
+    }
+
+    update = vc_dispmanx_update_start(10);
+    if (!update) {
+        return 0;
+    }
+
+    src_rect.x = 0;
+    src_rect.y = 0;
+    src_rect.width  = curdata->w << 16;
+    src_rect.height = curdata->h << 16;
+    dst_rect.x = x;
+    dst_rect.y = y;
+    dst_rect.width  = curdata->w;
+    dst_rect.height = curdata->h;
+
+    ret = vc_dispmanx_element_change_attributes(
+        update,
+        curdata->element,
+        0,
+        0,
+        0,
+        &dst_rect,
+        &src_rect,
+        DISPMANX_NO_HANDLE,
+        DISPMANX_NO_ROTATE);
+    if (ret != DISPMANX_SUCCESS) {
+        return SDL_SetError("vc_dispmanx_element_change_attributes() failed");
+    }
+
+    /* Submit asynchronously, otherwise the peformance suffers a lot */
+    ret = vc_dispmanx_update_submit(update, 0, NULL);
+    if (ret != DISPMANX_SUCCESS) {
+        return SDL_SetError("vc_dispmanx_update_submit() failed");
+    }
+    return 0;
+}
+
+/* Warp the mouse to (x,y) */
+static int
+RPI_WarpMouseGlobalGraphicOnly(int x, int y)
+{
+    RPI_CursorData *curdata;
+    DISPMANX_UPDATE_HANDLE_T update;
+    int ret;
+    VC_RECT_T dst_rect;
+    VC_RECT_T src_rect;
+    SDL_Mouse *mouse = SDL_GetMouse();
+    
+    if (mouse == NULL || mouse->cur_cursor == NULL || mouse->cur_cursor->driverdata == NULL) {
+        return 0;
+    }
+
     curdata = (RPI_CursorData *) mouse->cur_cursor->driverdata;
     if (curdata->element == DISPMANX_NO_HANDLE) {
         return 0;
@@ -317,7 +376,9 @@
 RPI_MoveCursor(SDL_Cursor * cursor)
 {
     SDL_Mouse *mouse = SDL_GetMouse();
-    RPI_WarpMouse(mouse->focus, mouse->x, mouse->y);
+    /* We must NOT call SDL_SendMouseMotion() on the next call or we will enter recursivity, 
+     * so we create a version of WarpMouseGlobal without it. */
+    RPI_WarpMouseGlobalGraphicOnly(mouse->x, mouse->y);
 }
 
 #endif /* SDL_VIDEO_DRIVER_RPI */


More information about the commits mailing list