|
@@ -83,6 +83,182 @@ void legacy_alpha_premultiply_ARGB8888 (uint32_t *pixel) {
|
|
|
(*pixel) = (((uint32_t)A << 24) | ((uint32_t)R << 16) | ((uint32_t)G << 8)) | ((uint32_t)B << 0);
|
|
|
}
|
|
|
|
|
|
+/* Given a display's driverdata, destroy the cursor BO for it.
|
|
|
+ To be called from KMSDRM_DestroyWindow(), as that's where we
|
|
|
+ destroy the driverdata for the window's display. */
|
|
|
+void
|
|
|
+KMSDRM_DestroyCursorBO (_THIS, SDL_VideoDisplay *display)
|
|
|
+{
|
|
|
+ SDL_DisplayData *dispdata = (SDL_DisplayData *) display->driverdata;
|
|
|
+
|
|
|
+ /* Destroy the curso GBM BO. */
|
|
|
+ if (dispdata->cursor_bo) {
|
|
|
+ KMSDRM_gbm_bo_destroy(dispdata->cursor_bo);
|
|
|
+ dispdata->cursor_bo = NULL;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/* Given a display's driverdata, create the cursor BO for it.
|
|
|
+ To be called from KMSDRM_CreateWindow(), as that's where we
|
|
|
+ build a window and assign a display to it. */
|
|
|
+void
|
|
|
+KMSDRM_CreateCursorBO (SDL_VideoDisplay *display) {
|
|
|
+
|
|
|
+ SDL_VideoDevice *dev = SDL_GetVideoDevice();
|
|
|
+ SDL_VideoData *viddata = ((SDL_VideoData *)dev->driverdata);
|
|
|
+ SDL_DisplayData *dispdata = (SDL_DisplayData *) display->driverdata;
|
|
|
+
|
|
|
+ if (!KMSDRM_gbm_device_is_format_supported(viddata->gbm_dev,
|
|
|
+ GBM_FORMAT_ARGB8888,
|
|
|
+ GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE))
|
|
|
+ {
|
|
|
+ SDL_SetError("Unsupported pixel format for cursor");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (KMSDRM_drmGetCap(viddata->drm_fd,
|
|
|
+ DRM_CAP_CURSOR_WIDTH, &dispdata->cursor_w) ||
|
|
|
+ KMSDRM_drmGetCap(viddata->drm_fd, DRM_CAP_CURSOR_HEIGHT,
|
|
|
+ &dispdata->cursor_h))
|
|
|
+ {
|
|
|
+ SDL_SetError("Could not get the recommended GBM cursor size");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (dispdata->cursor_w == 0 || dispdata->cursor_h == 0) {
|
|
|
+ SDL_SetError("Could not get an usable GBM cursor size");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ dispdata->cursor_bo = KMSDRM_gbm_bo_create(viddata->gbm_dev,
|
|
|
+ dispdata->cursor_w, dispdata->cursor_h,
|
|
|
+ GBM_FORMAT_ARGB8888, GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE | GBM_BO_USE_LINEAR);
|
|
|
+
|
|
|
+ if (!dispdata->cursor_bo) {
|
|
|
+ SDL_SetError("Could not create GBM cursor BO");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/* Remove a cursor buffer from a display's DRM cursor BO. */
|
|
|
+int
|
|
|
+KMSDRM_RemoveCursorFromBO(SDL_VideoDisplay *display)
|
|
|
+{
|
|
|
+ int ret = 0;
|
|
|
+ SDL_DisplayData *dispdata = (SDL_DisplayData *) display->driverdata;
|
|
|
+ SDL_VideoDevice *video_device = SDL_GetVideoDevice();
|
|
|
+ SDL_VideoData *viddata = ((SDL_VideoData *)video_device->driverdata);
|
|
|
+
|
|
|
+ ret = KMSDRM_drmModeSetCursor(viddata->drm_fd,
|
|
|
+ dispdata->crtc->crtc_id, 0, 0, 0);
|
|
|
+
|
|
|
+ if (ret) {
|
|
|
+ ret = SDL_SetError("Could not hide current cursor with drmModeSetCursor().");
|
|
|
+ }
|
|
|
+
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+/* Dump a cursor buffer to a display's DRM cursor BO. */
|
|
|
+int
|
|
|
+KMSDRM_DumpCursorToBO(SDL_VideoDisplay *display, SDL_Cursor *cursor)
|
|
|
+{
|
|
|
+ SDL_DisplayData *dispdata = (SDL_DisplayData *) display->driverdata;
|
|
|
+ KMSDRM_CursorData *curdata = (KMSDRM_CursorData *) cursor->driverdata;
|
|
|
+ SDL_VideoDevice *video_device = SDL_GetVideoDevice();
|
|
|
+ SDL_VideoData *viddata = ((SDL_VideoData *)video_device->driverdata);
|
|
|
+
|
|
|
+ uint32_t bo_handle;
|
|
|
+ size_t bo_stride;
|
|
|
+ size_t bufsize;
|
|
|
+ uint32_t *ready_buffer = NULL;
|
|
|
+ uint32_t pixel;
|
|
|
+
|
|
|
+ int i,j;
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ if (!curdata || !dispdata->cursor_bo) {
|
|
|
+ return SDL_SetError("Cursor or display not initialized properly.");
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Prepare a buffer we can dump to our GBM BO (different
|
|
|
+ size, alpha premultiplication...) */
|
|
|
+ bo_stride = KMSDRM_gbm_bo_get_stride(dispdata->cursor_bo);
|
|
|
+ bufsize = bo_stride * dispdata->cursor_h;
|
|
|
+
|
|
|
+ ready_buffer = (uint32_t*)SDL_calloc(1, bufsize);
|
|
|
+
|
|
|
+ if (!ready_buffer) {
|
|
|
+ ret = SDL_OutOfMemory();
|
|
|
+ goto cleanup;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Copy from the cursor buffer to a buffer that we can dump to the GBM BO,
|
|
|
+ pre-multiplying by alpha each pixel as we go. */
|
|
|
+ for (i = 0; i < curdata->h; i++) {
|
|
|
+ for (j = 0; j < curdata->w; j++) {
|
|
|
+ pixel = ((uint32_t*)curdata->buffer)[i * curdata->w + j];
|
|
|
+ legacy_alpha_premultiply_ARGB8888 (&pixel);
|
|
|
+ SDL_memcpy(ready_buffer + (i * dispdata->cursor_w) + j, &pixel, 4);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Dump the cursor buffer to our GBM BO. */
|
|
|
+ if (KMSDRM_gbm_bo_write(dispdata->cursor_bo, ready_buffer, bufsize)) {
|
|
|
+ ret = SDL_SetError("Could not write to GBM cursor BO");
|
|
|
+ goto cleanup;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Put the GBM BO buffer on screen using the DRM interface. */
|
|
|
+ bo_handle = KMSDRM_gbm_bo_get_handle(dispdata->cursor_bo).u32;
|
|
|
+ if (curdata->hot_x == 0 && curdata->hot_y == 0) {
|
|
|
+ ret = KMSDRM_drmModeSetCursor(viddata->drm_fd, dispdata->crtc->crtc_id,
|
|
|
+ bo_handle, dispdata->cursor_w, dispdata->cursor_h);
|
|
|
+ } else {
|
|
|
+ ret = KMSDRM_drmModeSetCursor2(viddata->drm_fd, dispdata->crtc->crtc_id,
|
|
|
+ bo_handle, dispdata->cursor_w, dispdata->cursor_h, curdata->hot_x, curdata->hot_y);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (ret) {
|
|
|
+ ret = SDL_SetError("Failed to set DRM cursor.");
|
|
|
+ goto cleanup;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (ret) {
|
|
|
+ ret = SDL_SetError("Failed to reset cursor position.");
|
|
|
+ goto cleanup;
|
|
|
+ }
|
|
|
+
|
|
|
+cleanup:
|
|
|
+
|
|
|
+ if (ready_buffer) {
|
|
|
+ SDL_free(ready_buffer);
|
|
|
+ }
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+/* This is only for freeing the SDL_cursor.*/
|
|
|
+static void
|
|
|
+KMSDRM_FreeCursor(SDL_Cursor * cursor)
|
|
|
+{
|
|
|
+ KMSDRM_CursorData *curdata;
|
|
|
+
|
|
|
+ /* Even if the cursor is not ours, free it. */
|
|
|
+ if (cursor) {
|
|
|
+ curdata = (KMSDRM_CursorData *) cursor->driverdata;
|
|
|
+ /* Free cursor buffer */
|
|
|
+ if (curdata->buffer) {
|
|
|
+ SDL_free(curdata->buffer);
|
|
|
+ curdata->buffer = NULL;
|
|
|
+ }
|
|
|
+ /* Free cursor itself */
|
|
|
+ if (cursor->driverdata) {
|
|
|
+ SDL_free(cursor->driverdata);
|
|
|
+ }
|
|
|
+ SDL_free(cursor);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
/* This simply gets the cursor soft-buffer ready.
|
|
|
We don't copy it to a GBO BO until ShowCursor() because the cusor GBM BO (living
|
|
|
in dispata) is destroyed and recreated when we recreate windows, etc. */
|
|
@@ -176,17 +352,11 @@ KMSDRM_InitCursor()
|
|
|
SDL_Mouse *mouse = NULL;
|
|
|
mouse = SDL_GetMouse();
|
|
|
|
|
|
- if (!mouse) {
|
|
|
- return;
|
|
|
- }
|
|
|
- if (!(mouse->cur_cursor)) {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- if (!(mouse->cursor_shown)) {
|
|
|
+ if (!mouse || !mouse->cur_cursor || !mouse->cursor_shown) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
+ /* Re-dump cursor buffer to the GBM BO of the focused window display. */
|
|
|
KMSDRM_ShowCursor(mouse->cur_cursor);
|
|
|
}
|
|
|
|
|
@@ -194,124 +364,60 @@ KMSDRM_InitCursor()
|
|
|
static int
|
|
|
KMSDRM_ShowCursor(SDL_Cursor * cursor)
|
|
|
{
|
|
|
- SDL_VideoDevice *video_device = SDL_GetVideoDevice();
|
|
|
- SDL_VideoData *viddata = ((SDL_VideoData *)video_device->driverdata);
|
|
|
- SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0);
|
|
|
+ SDL_VideoDisplay *display;
|
|
|
+ SDL_Window *window;
|
|
|
SDL_Mouse *mouse;
|
|
|
- KMSDRM_CursorData *curdata;
|
|
|
|
|
|
- uint32_t bo_handle;
|
|
|
+ int num_displays, i;
|
|
|
+ int ret = 0;
|
|
|
|
|
|
- size_t bo_stride;
|
|
|
- size_t bufsize;
|
|
|
- uint32_t *ready_buffer = NULL;
|
|
|
- uint32_t pixel;
|
|
|
-
|
|
|
- int i,j;
|
|
|
- int ret;
|
|
|
+ /* Get the mouse focused window, if any. */
|
|
|
|
|
|
mouse = SDL_GetMouse();
|
|
|
if (!mouse) {
|
|
|
return SDL_SetError("No mouse.");
|
|
|
}
|
|
|
|
|
|
- /*********************************************************/
|
|
|
- /* Hide cursor if it's NULL or it has no focus(=winwow). */
|
|
|
- /*********************************************************/
|
|
|
- if (!cursor || !mouse->focus) {
|
|
|
- /* Hide the drm cursor with no more considerations because
|
|
|
- SDL_VideoQuit() takes us here after disabling the mouse
|
|
|
- so there is no mouse->cur_cursor by now. */
|
|
|
- ret = KMSDRM_drmModeSetCursor(viddata->drm_fd,
|
|
|
- dispdata->crtc->crtc_id, 0, 0, 0);
|
|
|
- if (ret) {
|
|
|
- ret = SDL_SetError("Could not hide current cursor with drmModeSetCursor().");
|
|
|
- }
|
|
|
- return ret;
|
|
|
- }
|
|
|
+ window = mouse->focus;
|
|
|
|
|
|
- /*****************************************************/
|
|
|
- /* If cursor != NULL, DO show cursor on it's window. */
|
|
|
- /*****************************************************/
|
|
|
- curdata = (KMSDRM_CursorData *) cursor->driverdata;
|
|
|
+ if (!window || !cursor) {
|
|
|
|
|
|
- if (!curdata || !dispdata->cursor_bo) {
|
|
|
- return SDL_SetError("Cursor not initialized properly.");
|
|
|
- }
|
|
|
+ /* If no window is focused by mouse or cursor is NULL,
|
|
|
+ since we have no window (no mouse->focus) and hence
|
|
|
+ we have no display, we simply hide mouse on all displays.
|
|
|
+ This happens on video quit, where we get here after
|
|
|
+ the mouse focus has been unset, yet SDL wants to
|
|
|
+ restore the system default cursor (makes no sense here). */
|
|
|
|
|
|
- /* Prepare a buffer we can dump to our GBM BO (different
|
|
|
- size, alpha premultiplication...) */
|
|
|
- bo_stride = KMSDRM_gbm_bo_get_stride(dispdata->cursor_bo);
|
|
|
- bufsize = bo_stride * dispdata->cursor_h;
|
|
|
+ num_displays = SDL_GetNumVideoDisplays();
|
|
|
|
|
|
- ready_buffer = (uint32_t*)SDL_calloc(1, bufsize);
|
|
|
+ /* Iterate on the displays hidding the cursor. */
|
|
|
+ for (i = 0; i < num_displays; i++) {
|
|
|
+ display = SDL_GetDisplay(i);
|
|
|
+ ret = KMSDRM_RemoveCursorFromBO(display);
|
|
|
+ }
|
|
|
|
|
|
- if (!ready_buffer) {
|
|
|
- ret = SDL_OutOfMemory();
|
|
|
- goto cleanup;
|
|
|
- }
|
|
|
+ } else {
|
|
|
|
|
|
- /* Copy from the cursor buffer to a buffer that we can dump to the GBM BO,
|
|
|
- pre-multiplying by alpha each pixel as we go. */
|
|
|
- for (i = 0; i < curdata->h; i++) {
|
|
|
- for (j = 0; j < curdata->w; j++) {
|
|
|
- pixel = ((uint32_t*)curdata->buffer)[i * curdata->w + j];
|
|
|
- legacy_alpha_premultiply_ARGB8888 (&pixel);
|
|
|
- SDL_memcpy(ready_buffer + (i * dispdata->cursor_w) + j, &pixel, 4);
|
|
|
- }
|
|
|
- }
|
|
|
+ display = SDL_GetDisplayForWindow(window);
|
|
|
|
|
|
- /* Dump the cursor buffer to our GBM BO. */
|
|
|
- if (KMSDRM_gbm_bo_write(dispdata->cursor_bo, ready_buffer, bufsize)) {
|
|
|
- ret = SDL_SetError("Could not write to GBM cursor BO");
|
|
|
- goto cleanup;
|
|
|
- }
|
|
|
+ if (display) {
|
|
|
|
|
|
- /* Put the GBM BO buffer on screen using the DRM interface. */
|
|
|
- bo_handle = KMSDRM_gbm_bo_get_handle(dispdata->cursor_bo).u32;
|
|
|
- if (curdata->hot_x == 0 && curdata->hot_y == 0) {
|
|
|
- ret = KMSDRM_drmModeSetCursor(viddata->drm_fd, dispdata->crtc->crtc_id,
|
|
|
- bo_handle, dispdata->cursor_w, dispdata->cursor_h);
|
|
|
- } else {
|
|
|
- ret = KMSDRM_drmModeSetCursor2(viddata->drm_fd, dispdata->crtc->crtc_id,
|
|
|
- bo_handle, dispdata->cursor_w, dispdata->cursor_h, curdata->hot_x, curdata->hot_y);
|
|
|
- }
|
|
|
+ if (cursor) {
|
|
|
+ /* Dump the cursor to the display DRM cursor BO so it becomes visible
|
|
|
+ on that display. */
|
|
|
+ ret = KMSDRM_DumpCursorToBO(display, cursor);
|
|
|
|
|
|
- if (ret) {
|
|
|
- ret = SDL_SetError("Failed to set DRM cursor.");
|
|
|
- goto cleanup;
|
|
|
+ } else {
|
|
|
+ /* Hide the cursor on that display. */
|
|
|
+ ret = KMSDRM_RemoveCursorFromBO(display);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-cleanup:
|
|
|
-
|
|
|
- if (ready_buffer) {
|
|
|
- SDL_free(ready_buffer);
|
|
|
- }
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
-/* This is only for freeing the SDL_cursor.*/
|
|
|
-static void
|
|
|
-KMSDRM_FreeCursor(SDL_Cursor * cursor)
|
|
|
-{
|
|
|
- KMSDRM_CursorData *curdata;
|
|
|
-
|
|
|
- /* Even if the cursor is not ours, free it. */
|
|
|
- if (cursor) {
|
|
|
- curdata = (KMSDRM_CursorData *) cursor->driverdata;
|
|
|
- /* Free cursor buffer */
|
|
|
- if (curdata->buffer) {
|
|
|
- SDL_free(curdata->buffer);
|
|
|
- curdata->buffer = NULL;
|
|
|
- }
|
|
|
- /* Free cursor itself */
|
|
|
- if (cursor->driverdata) {
|
|
|
- SDL_free(cursor->driverdata);
|
|
|
- }
|
|
|
- SDL_free(cursor);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
/* Warp the mouse to (x,y) */
|
|
|
static void
|
|
|
KMSDRM_WarpMouse(SDL_Window * window, int x, int y)
|
|
@@ -325,9 +431,12 @@ static int
|
|
|
KMSDRM_WarpMouseGlobal(int x, int y)
|
|
|
{
|
|
|
SDL_Mouse *mouse = SDL_GetMouse();
|
|
|
- SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0);
|
|
|
|
|
|
- if (mouse && mouse->cur_cursor && mouse->cur_cursor->driverdata) {
|
|
|
+ if (mouse && mouse->cur_cursor && mouse->focus) {
|
|
|
+
|
|
|
+ SDL_Window *window = mouse->focus;
|
|
|
+ SDL_DisplayData *dispdata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata;
|
|
|
+
|
|
|
/* Update internal mouse position. */
|
|
|
SDL_SendMouseMotion(mouse->focus, mouse->mouseID, 0, x, y);
|
|
|
|
|
@@ -354,28 +463,11 @@ KMSDRM_WarpMouseGlobal(int x, int y)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-/* UNDO WHAT WE DID IN KMSDRM_InitMouse(). */
|
|
|
-void
|
|
|
-KMSDRM_DeinitMouse(_THIS)
|
|
|
-{
|
|
|
- SDL_VideoDevice *video_device = SDL_GetVideoDevice();
|
|
|
- SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0);
|
|
|
-
|
|
|
- /* Destroy the curso GBM BO. */
|
|
|
- if (video_device && dispdata->cursor_bo) {
|
|
|
- KMSDRM_gbm_bo_destroy(dispdata->cursor_bo);
|
|
|
- dispdata->cursor_bo = NULL;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-/* Create cursor BO. */
|
|
|
void
|
|
|
-KMSDRM_InitMouse(_THIS)
|
|
|
+KMSDRM_InitMouse(_THIS, SDL_VideoDisplay *display)
|
|
|
{
|
|
|
- SDL_VideoDevice *dev = SDL_GetVideoDevice();
|
|
|
- SDL_VideoData *viddata = ((SDL_VideoData *)dev->driverdata);
|
|
|
- SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0);
|
|
|
SDL_Mouse *mouse = SDL_GetMouse();
|
|
|
+ SDL_DisplayData *dispdata = (SDL_DisplayData *) display->driverdata;
|
|
|
|
|
|
mouse->CreateCursor = KMSDRM_CreateCursor;
|
|
|
mouse->ShowCursor = KMSDRM_ShowCursor;
|
|
@@ -384,61 +476,17 @@ KMSDRM_InitMouse(_THIS)
|
|
|
mouse->WarpMouse = KMSDRM_WarpMouse;
|
|
|
mouse->WarpMouseGlobal = KMSDRM_WarpMouseGlobal;
|
|
|
|
|
|
- /************************************************/
|
|
|
- /* Create the cursor GBM BO, if we haven't yet. */
|
|
|
- /************************************************/
|
|
|
- if (!dispdata->cursor_bo) {
|
|
|
-
|
|
|
- if (!KMSDRM_gbm_device_is_format_supported(viddata->gbm_dev,
|
|
|
- GBM_FORMAT_ARGB8888,
|
|
|
- GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE))
|
|
|
- {
|
|
|
- SDL_SetError("Unsupported pixel format for cursor");
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- if (KMSDRM_drmGetCap(viddata->drm_fd,
|
|
|
- DRM_CAP_CURSOR_WIDTH, &dispdata->cursor_w) ||
|
|
|
- KMSDRM_drmGetCap(viddata->drm_fd, DRM_CAP_CURSOR_HEIGHT,
|
|
|
- &dispdata->cursor_h))
|
|
|
- {
|
|
|
- SDL_SetError("Could not get the recommended GBM cursor size");
|
|
|
- goto cleanup;
|
|
|
- }
|
|
|
-
|
|
|
- if (dispdata->cursor_w == 0 || dispdata->cursor_h == 0) {
|
|
|
- SDL_SetError("Could not get an usable GBM cursor size");
|
|
|
- goto cleanup;
|
|
|
- }
|
|
|
-
|
|
|
- dispdata->cursor_bo = KMSDRM_gbm_bo_create(viddata->gbm_dev,
|
|
|
- dispdata->cursor_w, dispdata->cursor_h,
|
|
|
- GBM_FORMAT_ARGB8888, GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE | GBM_BO_USE_LINEAR);
|
|
|
-
|
|
|
- if (!dispdata->cursor_bo) {
|
|
|
- SDL_SetError("Could not create GBM cursor BO");
|
|
|
- goto cleanup;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /* SDL expects to set the default cursor on screen when we init the mouse,
|
|
|
+ /* SDL expects to set the default cursor of the display when we init the mouse,
|
|
|
but since we have moved the KMSDRM_InitMouse() call to KMSDRM_CreateWindow(),
|
|
|
we end up calling KMSDRM_InitMouse() every time we create a window, so we
|
|
|
have to prevent this from being done every time a new window is created.
|
|
|
If we don't, new default cursors would stack up on mouse->cursors and SDL
|
|
|
would have to hide and delete them at quit, not to mention the memory leak... */
|
|
|
+
|
|
|
if(dispdata->set_default_cursor_pending) {
|
|
|
SDL_SetDefaultCursor(KMSDRM_CreateDefaultCursor());
|
|
|
dispdata->set_default_cursor_pending = SDL_FALSE;
|
|
|
}
|
|
|
-
|
|
|
- return;
|
|
|
-
|
|
|
-cleanup:
|
|
|
- if (dispdata->cursor_bo) {
|
|
|
- KMSDRM_gbm_bo_destroy(dispdata->cursor_bo);
|
|
|
- dispdata->cursor_bo = NULL;
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
void
|
|
@@ -452,23 +500,25 @@ static void
|
|
|
KMSDRM_MoveCursor(SDL_Cursor * cursor)
|
|
|
{
|
|
|
SDL_Mouse *mouse = SDL_GetMouse();
|
|
|
- SDL_Window *window;
|
|
|
- SDL_DisplayData *dispdata;
|
|
|
-
|
|
|
int drm_fd, ret, screen_y;
|
|
|
|
|
|
/* We must NOT call SDL_SendMouseMotion() here or we will enter recursivity!
|
|
|
That's why we move the cursor graphic ONLY. */
|
|
|
- if (mouse && mouse->cur_cursor && mouse->cur_cursor->driverdata && mouse->focus) {
|
|
|
+ if (mouse && mouse->cur_cursor && mouse->focus) {
|
|
|
|
|
|
- window = mouse->focus;
|
|
|
- dispdata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata;
|
|
|
+ SDL_Window *window = mouse->focus;
|
|
|
+ SDL_DisplayData *dispdata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata;
|
|
|
|
|
|
- /* Correct the Y coordinate, because DRM mouse coordinates start on screen top. */
|
|
|
- screen_y = dispdata->mode.vdisplay - window->h + mouse->y;
|
|
|
+ if (!dispdata->cursor_bo) {
|
|
|
+ SDL_SetError("Cursor not initialized properly.");
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
drm_fd = KMSDRM_gbm_device_get_fd(KMSDRM_gbm_bo_get_device(dispdata->cursor_bo));
|
|
|
|
|
|
+ /* Correct the Y coordinate, because DRM mouse coordinates start on screen top. */
|
|
|
+ screen_y = dispdata->mode.vdisplay - window->h + mouse->y;
|
|
|
+
|
|
|
ret = KMSDRM_drmModeMoveCursor(drm_fd, dispdata->crtc->crtc_id, mouse->x, screen_y);
|
|
|
|
|
|
if (ret) {
|