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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
diff --git a/src/video/kmsdrm/SDL_kmsdrmmouse.c b/src/video/kmsdrm/SDL_kmsdrmmouse.c
index f834339..80fa89f 100644
--- a/src/video/kmsdrm/SDL_kmsdrmmouse.c
+++ b/src/video/kmsdrm/SDL_kmsdrmmouse.c
@@ -423,8 +423,13 @@ KMSDRM_WarpMouseGlobal(int x, int y)
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 @@ static void
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 --git a/src/video/raspberry/SDL_rpimouse.c b/src/video/raspberry/SDL_rpimouse.c
index 026fbd2..4ab9c77 100644
--- a/src/video/raspberry/SDL_rpimouse.c
+++ b/src/video/raspberry/SDL_rpimouse.c
@@ -247,6 +247,65 @@ RPI_WarpMouseGlobal(int x, int y)
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 @@ static void
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 */