mirror of
https://github.com/Ryujinx/SDL.git
synced 2024-12-23 13:25:33 +00:00
[KMS/DRM] Patch for bug #5513. KMSDRM backend can now manage and use several displays.
This commit is contained in:
parent
a78bce9e38
commit
b17c49509b
|
@ -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);
|
(*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.
|
/* 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
|
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. */
|
in dispata) is destroyed and recreated when we recreate windows, etc. */
|
||||||
|
@ -176,17 +352,11 @@ KMSDRM_InitCursor()
|
||||||
SDL_Mouse *mouse = NULL;
|
SDL_Mouse *mouse = NULL;
|
||||||
mouse = SDL_GetMouse();
|
mouse = SDL_GetMouse();
|
||||||
|
|
||||||
if (!mouse) {
|
if (!mouse || !mouse->cur_cursor || !mouse->cursor_shown) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!(mouse->cur_cursor)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(mouse->cursor_shown)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Re-dump cursor buffer to the GBM BO of the focused window display. */
|
||||||
KMSDRM_ShowCursor(mouse->cur_cursor);
|
KMSDRM_ShowCursor(mouse->cur_cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,124 +364,60 @@ KMSDRM_InitCursor()
|
||||||
static int
|
static int
|
||||||
KMSDRM_ShowCursor(SDL_Cursor * cursor)
|
KMSDRM_ShowCursor(SDL_Cursor * cursor)
|
||||||
{
|
{
|
||||||
SDL_VideoDevice *video_device = SDL_GetVideoDevice();
|
SDL_VideoDisplay *display;
|
||||||
SDL_VideoData *viddata = ((SDL_VideoData *)video_device->driverdata);
|
SDL_Window *window;
|
||||||
SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0);
|
|
||||||
SDL_Mouse *mouse;
|
SDL_Mouse *mouse;
|
||||||
KMSDRM_CursorData *curdata;
|
|
||||||
|
|
||||||
uint32_t bo_handle;
|
int num_displays, i;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
size_t bo_stride;
|
/* Get the mouse focused window, if any. */
|
||||||
size_t bufsize;
|
|
||||||
uint32_t *ready_buffer = NULL;
|
|
||||||
uint32_t pixel;
|
|
||||||
|
|
||||||
int i,j;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
mouse = SDL_GetMouse();
|
mouse = SDL_GetMouse();
|
||||||
if (!mouse) {
|
if (!mouse) {
|
||||||
return SDL_SetError("No mouse.");
|
return SDL_SetError("No mouse.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************/
|
window = mouse->focus;
|
||||||
/* 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************************/
|
if (!window || !cursor) {
|
||||||
/* If cursor != NULL, DO show cursor on it's window. */
|
|
||||||
/*****************************************************/
|
|
||||||
curdata = (KMSDRM_CursorData *) cursor->driverdata;
|
|
||||||
|
|
||||||
if (!curdata || !dispdata->cursor_bo) {
|
/* If no window is focused by mouse or cursor is NULL,
|
||||||
return SDL_SetError("Cursor not initialized properly.");
|
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
|
num_displays = SDL_GetNumVideoDisplays();
|
||||||
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);
|
/* 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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 {
|
} 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);
|
display = SDL_GetDisplayForWindow(window);
|
||||||
|
|
||||||
|
if (display) {
|
||||||
|
|
||||||
|
if (cursor) {
|
||||||
|
/* Dump the cursor to the display DRM cursor BO so it becomes visible
|
||||||
|
on that display. */
|
||||||
|
ret = KMSDRM_DumpCursorToBO(display, cursor);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
/* Hide the cursor on that display. */
|
||||||
|
ret = KMSDRM_RemoveCursorFromBO(display);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret) {
|
|
||||||
ret = SDL_SetError("Failed to set DRM cursor.");
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
|
|
||||||
if (ready_buffer) {
|
|
||||||
SDL_free(ready_buffer);
|
|
||||||
}
|
|
||||||
return ret;
|
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) */
|
/* Warp the mouse to (x,y) */
|
||||||
static void
|
static void
|
||||||
KMSDRM_WarpMouse(SDL_Window * window, int x, int y)
|
KMSDRM_WarpMouse(SDL_Window * window, int x, int y)
|
||||||
|
@ -325,9 +431,12 @@ static int
|
||||||
KMSDRM_WarpMouseGlobal(int x, int y)
|
KMSDRM_WarpMouseGlobal(int x, int y)
|
||||||
{
|
{
|
||||||
SDL_Mouse *mouse = SDL_GetMouse();
|
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. */
|
/* Update internal mouse position. */
|
||||||
SDL_SendMouseMotion(mouse->focus, mouse->mouseID, 0, x, y);
|
SDL_SendMouseMotion(mouse->focus, mouse->mouseID, 0, x, y);
|
||||||
|
|
||||||
|
@ -354,28 +463,11 @@ KMSDRM_WarpMouseGlobal(int x, int y)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* UNDO WHAT WE DID IN KMSDRM_InitMouse(). */
|
|
||||||
void
|
void
|
||||||
KMSDRM_DeinitMouse(_THIS)
|
KMSDRM_InitMouse(_THIS, SDL_VideoDisplay *display)
|
||||||
{
|
{
|
||||||
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)
|
|
||||||
{
|
|
||||||
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_Mouse *mouse = SDL_GetMouse();
|
||||||
|
SDL_DisplayData *dispdata = (SDL_DisplayData *) display->driverdata;
|
||||||
|
|
||||||
mouse->CreateCursor = KMSDRM_CreateCursor;
|
mouse->CreateCursor = KMSDRM_CreateCursor;
|
||||||
mouse->ShowCursor = KMSDRM_ShowCursor;
|
mouse->ShowCursor = KMSDRM_ShowCursor;
|
||||||
|
@ -384,61 +476,17 @@ KMSDRM_InitMouse(_THIS)
|
||||||
mouse->WarpMouse = KMSDRM_WarpMouse;
|
mouse->WarpMouse = KMSDRM_WarpMouse;
|
||||||
mouse->WarpMouseGlobal = KMSDRM_WarpMouseGlobal;
|
mouse->WarpMouseGlobal = KMSDRM_WarpMouseGlobal;
|
||||||
|
|
||||||
/************************************************/
|
/* SDL expects to set the default cursor of the display when we init the mouse,
|
||||||
/* 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,
|
|
||||||
but since we have moved the KMSDRM_InitMouse() call to KMSDRM_CreateWindow(),
|
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
|
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.
|
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
|
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... */
|
would have to hide and delete them at quit, not to mention the memory leak... */
|
||||||
|
|
||||||
if(dispdata->set_default_cursor_pending) {
|
if(dispdata->set_default_cursor_pending) {
|
||||||
SDL_SetDefaultCursor(KMSDRM_CreateDefaultCursor());
|
SDL_SetDefaultCursor(KMSDRM_CreateDefaultCursor());
|
||||||
dispdata->set_default_cursor_pending = SDL_FALSE;
|
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
|
void
|
||||||
|
@ -452,23 +500,25 @@ static void
|
||||||
KMSDRM_MoveCursor(SDL_Cursor * cursor)
|
KMSDRM_MoveCursor(SDL_Cursor * cursor)
|
||||||
{
|
{
|
||||||
SDL_Mouse *mouse = SDL_GetMouse();
|
SDL_Mouse *mouse = SDL_GetMouse();
|
||||||
SDL_Window *window;
|
|
||||||
SDL_DisplayData *dispdata;
|
|
||||||
|
|
||||||
int drm_fd, ret, screen_y;
|
int drm_fd, ret, screen_y;
|
||||||
|
|
||||||
/* We must NOT call SDL_SendMouseMotion() here or we will enter recursivity!
|
/* We must NOT call SDL_SendMouseMotion() here or we will enter recursivity!
|
||||||
That's why we move the cursor graphic ONLY. */
|
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;
|
SDL_Window *window = mouse->focus;
|
||||||
dispdata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata;
|
SDL_DisplayData *dispdata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata;
|
||||||
|
|
||||||
|
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. */
|
/* Correct the Y coordinate, because DRM mouse coordinates start on screen top. */
|
||||||
screen_y = dispdata->mode.vdisplay - window->h + mouse->y;
|
screen_y = dispdata->mode.vdisplay - window->h + mouse->y;
|
||||||
|
|
||||||
drm_fd = KMSDRM_gbm_device_get_fd(KMSDRM_gbm_bo_get_device(dispdata->cursor_bo));
|
|
||||||
|
|
||||||
ret = KMSDRM_drmModeMoveCursor(drm_fd, dispdata->crtc->crtc_id, mouse->x, screen_y);
|
ret = KMSDRM_drmModeMoveCursor(drm_fd, dispdata->crtc->crtc_id, mouse->x, screen_y);
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
|
|
@ -43,10 +43,11 @@ typedef struct _KMSDRM_CursorData
|
||||||
|
|
||||||
} KMSDRM_CursorData;
|
} KMSDRM_CursorData;
|
||||||
|
|
||||||
extern void KMSDRM_InitMouse(_THIS);
|
extern void KMSDRM_InitMouse(_THIS, SDL_VideoDisplay *display);
|
||||||
extern void KMSDRM_DeinitMouse(_THIS);
|
|
||||||
extern void KMSDRM_QuitMouse(_THIS);
|
extern void KMSDRM_QuitMouse(_THIS);
|
||||||
|
|
||||||
|
extern void KMSDRM_CreateCursorBO(SDL_VideoDisplay *display);
|
||||||
|
extern void KMSDRM_DestroyCursorBO(_THIS, SDL_VideoDisplay *display);
|
||||||
extern void KMSDRM_InitCursor();
|
extern void KMSDRM_InitCursor();
|
||||||
|
|
||||||
#endif /* SDL_KMSDRM_mouse_h_ */
|
#endif /* SDL_KMSDRM_mouse_h_ */
|
||||||
|
|
|
@ -457,83 +457,64 @@ uint32_t width, uint32_t height, uint32_t refresh_rate){
|
||||||
/* _this is a SDL_VideoDevice * */
|
/* _this is a SDL_VideoDevice * */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
/* Deinitializes the dispdata members needed for KMSDRM operation that are
|
/* Deinitializes the driverdata of the SDL Displays in the SDL display list. */
|
||||||
inoffeensive for VK compatibility. */
|
void KMSDRM_DeinitDisplays (_THIS) {
|
||||||
void KMSDRM_DisplayDataDeinit (_THIS, SDL_DisplayData *dispdata) {
|
|
||||||
/* Free connector */
|
|
||||||
if (dispdata && dispdata->connector) {
|
|
||||||
KMSDRM_drmModeFreeConnector(dispdata->connector);
|
|
||||||
dispdata->connector = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Free CRTC */
|
SDL_DisplayData *dispdata;
|
||||||
if (dispdata && dispdata->crtc) {
|
int num_displays, i;
|
||||||
KMSDRM_drmModeFreeCrtc(dispdata->crtc);
|
|
||||||
dispdata->crtc = NULL;
|
num_displays = SDL_GetNumVideoDisplays();
|
||||||
|
|
||||||
|
/* Iterate on the SDL Display list. */
|
||||||
|
for (i = 0; i < num_displays; i++) {
|
||||||
|
|
||||||
|
/* Get the driverdata for this display */
|
||||||
|
dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(i);
|
||||||
|
|
||||||
|
/* Free connector */
|
||||||
|
if (dispdata && dispdata->connector) {
|
||||||
|
KMSDRM_drmModeFreeConnector(dispdata->connector);
|
||||||
|
dispdata->connector = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free CRTC */
|
||||||
|
if (dispdata && dispdata->crtc) {
|
||||||
|
KMSDRM_drmModeFreeCrtc(dispdata->crtc);
|
||||||
|
dispdata->crtc = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initializes the dispdata members needed for KMSDRM operation that are
|
/* Gets a DRM connector, builds an SDL_Display with it, and adds it to the
|
||||||
inoffeensive for VK compatibility, except we must leave the drm_fd
|
list of SDL Displays. */
|
||||||
closed when we get to the end of this function.
|
void KMSDRM_AddDisplay (_THIS, drmModeConnector *connector, drmModeRes *resources) {
|
||||||
This is to be called early, in VideoInit(), because it gets us
|
|
||||||
the videomode information, which SDL needs immediately after VideoInit(). */
|
|
||||||
int KMSDRM_DisplayDataInit (_THIS, SDL_DisplayData *dispdata) {
|
|
||||||
SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
|
SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
|
||||||
|
SDL_DisplayData *dispdata = NULL;
|
||||||
drmModeRes *resources = NULL;
|
SDL_VideoDisplay display = {0};
|
||||||
drmModeEncoder *encoder = NULL;
|
drmModeEncoder *encoder = NULL;
|
||||||
drmModeConnector *connector = NULL;
|
|
||||||
drmModeCrtc *crtc = NULL;
|
drmModeCrtc *crtc = NULL;
|
||||||
|
int i, j;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
unsigned i,j;
|
|
||||||
|
|
||||||
|
/* Reserve memory for the new display's driverdata. */
|
||||||
|
dispdata = (SDL_DisplayData *) SDL_calloc(1, sizeof(SDL_DisplayData));
|
||||||
|
if (!dispdata) {
|
||||||
|
ret = SDL_OutOfMemory();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize some of the members of the new display's driverdata
|
||||||
|
to sane values. */
|
||||||
dispdata->gbm_init = SDL_FALSE;
|
dispdata->gbm_init = SDL_FALSE;
|
||||||
dispdata->modeset_pending = SDL_FALSE;
|
dispdata->modeset_pending = SDL_FALSE;
|
||||||
dispdata->cursor_bo = NULL;
|
dispdata->cursor_bo = NULL;
|
||||||
|
|
||||||
/* Open /dev/dri/cardNN (/dev/drmN if on OpenBSD) */
|
/* Since we create and show the default cursor on KMSDRM_InitMouse() and
|
||||||
SDL_snprintf(viddata->devpath, sizeof(viddata->devpath), KMSDRM_DRI_CARDPATHFMT, viddata->devindex);
|
we call KMSDRM_InitMouse() everytime we create a new window, we have
|
||||||
|
to be sure to create and show the default cursor only the first time.
|
||||||
SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Opening device %s", viddata->devpath);
|
If we don't, new default cursors would stack up on mouse->cursors and SDL
|
||||||
viddata->drm_fd = open(viddata->devpath, O_RDWR | O_CLOEXEC);
|
would have to hide and delete them at quit, not to mention the memory leak... */
|
||||||
|
dispdata->set_default_cursor_pending = SDL_TRUE;
|
||||||
if (viddata->drm_fd < 0) {
|
|
||||||
ret = SDL_SetError("Could not open %s", viddata->devpath);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Opened DRM FD (%d)", viddata->drm_fd);
|
|
||||||
|
|
||||||
/* Get all of the available connectors / devices / crtcs */
|
|
||||||
resources = KMSDRM_drmModeGetResources(viddata->drm_fd);
|
|
||||||
if (!resources) {
|
|
||||||
ret = SDL_SetError("drmModeGetResources(%d) failed", viddata->drm_fd);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Iterate on the available connectors to find a connected connector. */
|
|
||||||
for (i = 0; i < resources->count_connectors; i++) {
|
|
||||||
drmModeConnector *conn = KMSDRM_drmModeGetConnector(viddata->drm_fd,
|
|
||||||
resources->connectors[i]);
|
|
||||||
|
|
||||||
if (!conn) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (conn->connection == DRM_MODE_CONNECTED && conn->count_modes) {
|
|
||||||
connector = conn;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
KMSDRM_drmModeFreeConnector(conn);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!connector) {
|
|
||||||
ret = SDL_SetError("No currently active connector found.");
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Try to find the connector's current encoder */
|
/* Try to find the connector's current encoder */
|
||||||
for (i = 0; i < resources->count_encoders; i++) {
|
for (i = 0; i < resources->count_encoders; i++) {
|
||||||
|
@ -558,7 +539,7 @@ int KMSDRM_DisplayDataInit (_THIS, SDL_DisplayData *dispdata) {
|
||||||
resources->encoders[i]);
|
resources->encoders[i]);
|
||||||
|
|
||||||
if (!encoder) {
|
if (!encoder) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (j = 0; j < connector->count_encoders; j++) {
|
for (j = 0; j < connector->count_encoders; j++) {
|
||||||
|
@ -568,7 +549,7 @@ int KMSDRM_DisplayDataInit (_THIS, SDL_DisplayData *dispdata) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (j != connector->count_encoders) {
|
if (j != connector->count_encoders) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
KMSDRM_drmModeFreeEncoder(encoder);
|
KMSDRM_drmModeFreeEncoder(encoder);
|
||||||
|
@ -577,7 +558,7 @@ int KMSDRM_DisplayDataInit (_THIS, SDL_DisplayData *dispdata) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!encoder) {
|
if (!encoder) {
|
||||||
ret = SDL_SetError("No connected encoder found.");
|
ret = SDL_SetError("No connected encoder found for connector.");
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -597,11 +578,21 @@ int KMSDRM_DisplayDataInit (_THIS, SDL_DisplayData *dispdata) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!crtc) {
|
if (!crtc) {
|
||||||
ret = SDL_SetError("No CRTC found.");
|
ret = SDL_SetError("No CRTC found for connector.");
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Figure out the default mode to be set. */
|
/*********************************************/
|
||||||
|
/* Create an SDL Display for this connector. */
|
||||||
|
/*********************************************/
|
||||||
|
|
||||||
|
/*********************************************/
|
||||||
|
/* Part 1: setup the SDL_Display driverdata. */
|
||||||
|
/*********************************************/
|
||||||
|
|
||||||
|
/* Get the mode currently setup for this display,
|
||||||
|
which is the mode currently setup on the CRTC
|
||||||
|
we found for the active connector. */
|
||||||
dispdata->mode = crtc->mode;
|
dispdata->mode = crtc->mode;
|
||||||
|
|
||||||
/* Save the original mode for restoration on quit. */
|
/* Save the original mode for restoration on quit. */
|
||||||
|
@ -612,11 +603,108 @@ int KMSDRM_DisplayDataInit (_THIS, SDL_DisplayData *dispdata) {
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Store the connector and crtc for future use. These are all we keep
|
/* Store the connector and crtc for this display. */
|
||||||
from this function, and these are just structs, inoffensive to VK. */
|
|
||||||
dispdata->connector = connector;
|
dispdata->connector = connector;
|
||||||
dispdata->crtc = crtc;
|
dispdata->crtc = crtc;
|
||||||
|
|
||||||
|
/*****************************************/
|
||||||
|
/* Part 2: setup the SDL_Display itself. */
|
||||||
|
/*****************************************/
|
||||||
|
|
||||||
|
/* Setup the display.
|
||||||
|
There's no problem with it being still incomplete. */
|
||||||
|
display.driverdata = dispdata;
|
||||||
|
display.desktop_mode.w = dispdata->mode.hdisplay;
|
||||||
|
display.desktop_mode.h = dispdata->mode.vdisplay;
|
||||||
|
display.desktop_mode.refresh_rate = dispdata->mode.vrefresh;
|
||||||
|
display.desktop_mode.format = SDL_PIXELFORMAT_ARGB8888;
|
||||||
|
display.current_mode = display.desktop_mode;
|
||||||
|
|
||||||
|
/* Add the display to the list of SDL displays. */
|
||||||
|
SDL_AddVideoDisplay(&display, SDL_FALSE);
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (encoder)
|
||||||
|
KMSDRM_drmModeFreeEncoder(encoder);
|
||||||
|
if (ret) {
|
||||||
|
/* Error (complete) cleanup */
|
||||||
|
if (dispdata->connector) {
|
||||||
|
KMSDRM_drmModeFreeConnector(dispdata->connector);
|
||||||
|
dispdata->connector = NULL;
|
||||||
|
}
|
||||||
|
if (dispdata->crtc) {
|
||||||
|
KMSDRM_drmModeFreeCrtc(dispdata->crtc);
|
||||||
|
dispdata->crtc = NULL;
|
||||||
|
}
|
||||||
|
if (dispdata) {
|
||||||
|
SDL_free(dispdata);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initializes the list of SDL displays: we build a new display for each
|
||||||
|
connecter connector we find.
|
||||||
|
Inoffeensive for VK compatibility, except we must leave the drm_fd
|
||||||
|
closed when we get to the end of this function.
|
||||||
|
This is to be called early, in VideoInit(), because it gets us
|
||||||
|
the videomode information, which SDL needs immediately after VideoInit(). */
|
||||||
|
int KMSDRM_InitDisplays (_THIS) {
|
||||||
|
|
||||||
|
SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
|
||||||
|
drmModeRes *resources = NULL;
|
||||||
|
|
||||||
|
int ret = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Open /dev/dri/cardNN (/dev/drmN if on OpenBSD) */
|
||||||
|
SDL_snprintf(viddata->devpath, sizeof(viddata->devpath), KMSDRM_DRI_CARDPATHFMT, viddata->devindex);
|
||||||
|
|
||||||
|
SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Opening device %s", viddata->devpath);
|
||||||
|
viddata->drm_fd = open(viddata->devpath, O_RDWR | O_CLOEXEC);
|
||||||
|
|
||||||
|
if (viddata->drm_fd < 0) {
|
||||||
|
ret = SDL_SetError("Could not open %s", viddata->devpath);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Opened DRM FD (%d)", viddata->drm_fd);
|
||||||
|
|
||||||
|
/* Get all of the available connectors / devices / crtcs */
|
||||||
|
resources = KMSDRM_drmModeGetResources(viddata->drm_fd);
|
||||||
|
if (!resources) {
|
||||||
|
ret = SDL_SetError("drmModeGetResources(%d) failed", viddata->drm_fd);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Iterate on the available connectors. For every connected connector,
|
||||||
|
we create an SDL_Display and add it to the list of SDL Displays. */
|
||||||
|
for (i = 0; i < resources->count_connectors; i++) {
|
||||||
|
drmModeConnector *connector = KMSDRM_drmModeGetConnector(viddata->drm_fd,
|
||||||
|
resources->connectors[i]);
|
||||||
|
|
||||||
|
if (!connector) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (connector->connection == DRM_MODE_CONNECTED && connector->count_modes) {
|
||||||
|
/* If it's a connected connector with available videomodes, try to add
|
||||||
|
an SDL Display representing it. KMSDRM_AddDisplay() is purposely void,
|
||||||
|
so if it fails (no encoder for connector, no valid video mode for
|
||||||
|
connector etc...) we can keep looking for connected connectors. */
|
||||||
|
KMSDRM_AddDisplay (_this, connector, resources);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* If it's not, free it now. */
|
||||||
|
KMSDRM_drmModeFreeConnector(connector);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Have we added any SDL displays? */
|
||||||
|
if (!SDL_GetNumVideoDisplays()) {
|
||||||
|
ret = SDL_SetError("No connected displays found.");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************/
|
/***********************************/
|
||||||
/* Block for Vulkan compatibility. */
|
/* Block for Vulkan compatibility. */
|
||||||
/***********************************/
|
/***********************************/
|
||||||
|
@ -627,26 +715,14 @@ int KMSDRM_DisplayDataInit (_THIS, SDL_DisplayData *dispdata) {
|
||||||
viddata->drm_fd = -1;
|
viddata->drm_fd = -1;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
if (encoder)
|
|
||||||
KMSDRM_drmModeFreeEncoder(encoder);
|
|
||||||
if (resources)
|
if (resources)
|
||||||
KMSDRM_drmModeFreeResources(resources);
|
KMSDRM_drmModeFreeResources(resources);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
/* Error (complete) cleanup */
|
|
||||||
if (dispdata->connector) {
|
|
||||||
KMSDRM_drmModeFreeConnector(dispdata->connector);
|
|
||||||
dispdata->connector = NULL;
|
|
||||||
}
|
|
||||||
if (dispdata->crtc) {
|
|
||||||
KMSDRM_drmModeFreeCrtc(dispdata->crtc);
|
|
||||||
dispdata->crtc = NULL;
|
|
||||||
}
|
|
||||||
if (viddata->drm_fd >= 0) {
|
if (viddata->drm_fd >= 0) {
|
||||||
close(viddata->drm_fd);
|
close(viddata->drm_fd);
|
||||||
viddata->drm_fd = -1;
|
viddata->drm_fd = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -838,68 +914,26 @@ KMSDRM_VideoInit(_THIS)
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
|
SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
|
||||||
SDL_DisplayData *dispdata = NULL;
|
|
||||||
SDL_VideoDisplay display = {0};
|
|
||||||
|
|
||||||
SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "KMSDRM_VideoInit()");
|
SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "KMSDRM_VideoInit()");
|
||||||
|
|
||||||
viddata->video_init = SDL_FALSE;
|
viddata->video_init = SDL_FALSE;
|
||||||
|
|
||||||
dispdata = (SDL_DisplayData *) SDL_calloc(1, sizeof(SDL_DisplayData));
|
|
||||||
if (!dispdata) {
|
|
||||||
return SDL_OutOfMemory();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get KMSDRM resources info and store what we need. Getting and storing
|
/* Get KMSDRM resources info and store what we need. Getting and storing
|
||||||
this info isn't a problem for VK compatibility.
|
this info isn't a problem for VK compatibility.
|
||||||
For VK-incompatible initializations we have KMSDRM_GBMInit(), which is
|
For VK-incompatible initializations we have KMSDRM_GBMInit(), which is
|
||||||
called on window creation, and only when we know it's not a VK window. */
|
called on window creation, and only when we know it's not a VK window. */
|
||||||
if (KMSDRM_DisplayDataInit(_this, dispdata)) {
|
if (KMSDRM_InitDisplays(_this)) {
|
||||||
ret = SDL_SetError("error getting KMS/DRM information");
|
ret = SDL_SetError("error getting KMS/DRM information");
|
||||||
goto cleanup;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Setup the single display that's available.
|
|
||||||
There's no problem with it being still incomplete. */
|
|
||||||
display.driverdata = dispdata;
|
|
||||||
display.desktop_mode.w = dispdata->mode.hdisplay;
|
|
||||||
display.desktop_mode.h = dispdata->mode.vdisplay;
|
|
||||||
display.desktop_mode.refresh_rate = dispdata->mode.vrefresh;
|
|
||||||
display.desktop_mode.format = SDL_PIXELFORMAT_ARGB8888;
|
|
||||||
display.current_mode = display.desktop_mode;
|
|
||||||
|
|
||||||
/* Add the display only when it's ready, */
|
|
||||||
SDL_AddVideoDisplay(&display, SDL_FALSE);
|
|
||||||
|
|
||||||
#ifdef SDL_INPUT_LINUXEV
|
#ifdef SDL_INPUT_LINUXEV
|
||||||
SDL_EVDEV_Init();
|
SDL_EVDEV_Init();
|
||||||
#elif defined(SDL_INPUT_WSCONS)
|
#elif defined(SDL_INPUT_WSCONS)
|
||||||
SDL_WSCONS_Init();
|
SDL_WSCONS_Init();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Since we create and show the default cursor on KMSDRM_InitMouse() and
|
|
||||||
we call KMSDRM_InitMouse() everytime we create a new window, we have
|
|
||||||
to be sure to create and show the default cursor only the first time.
|
|
||||||
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... */
|
|
||||||
dispdata->set_default_cursor_pending = SDL_TRUE;
|
|
||||||
|
|
||||||
viddata->video_init = SDL_TRUE;
|
viddata->video_init = SDL_TRUE;
|
||||||
|
|
||||||
cleanup:
|
|
||||||
|
|
||||||
if (ret) {
|
|
||||||
/* Error (complete) cleanup */
|
|
||||||
if (dispdata->crtc) {
|
|
||||||
SDL_free(dispdata->crtc);
|
|
||||||
}
|
|
||||||
if (dispdata->connector) {
|
|
||||||
SDL_free(dispdata->connector);
|
|
||||||
}
|
|
||||||
|
|
||||||
SDL_free(dispdata);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -909,9 +943,8 @@ void
|
||||||
KMSDRM_VideoQuit(_THIS)
|
KMSDRM_VideoQuit(_THIS)
|
||||||
{
|
{
|
||||||
SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
|
SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
|
||||||
SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0);
|
|
||||||
|
|
||||||
KMSDRM_DisplayDataDeinit(_this, dispdata);
|
KMSDRM_DeinitDisplays(_this);
|
||||||
|
|
||||||
#ifdef SDL_INPUT_LINUXEV
|
#ifdef SDL_INPUT_LINUXEV
|
||||||
SDL_EVDEV_Quit();
|
SDL_EVDEV_Quit();
|
||||||
|
@ -1010,8 +1043,8 @@ KMSDRM_DestroyWindow(_THIS, SDL_Window *window)
|
||||||
|
|
||||||
if ( !is_vulkan && dispdata->gbm_init ) {
|
if ( !is_vulkan && dispdata->gbm_init ) {
|
||||||
|
|
||||||
/* Destroy cursor GBM plane. */
|
/* Destroy the window display's cursor GBM BO. */
|
||||||
KMSDRM_DeinitMouse(_this);
|
KMSDRM_DestroyCursorBO(_this, SDL_GetDisplayForWindow(window));
|
||||||
|
|
||||||
/* Destroy GBM surface and buffers. */
|
/* Destroy GBM surface and buffers. */
|
||||||
KMSDRM_DestroySurfaces(_this, window);
|
KMSDRM_DestroySurfaces(_this, window);
|
||||||
|
@ -1126,15 +1159,20 @@ KMSDRM_CreateWindow(_THIS, SDL_Window * window)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Can't init mouse stuff sooner because cursor plane is not ready,
|
|
||||||
so we do it here. */
|
|
||||||
KMSDRM_InitMouse(_this);
|
|
||||||
|
|
||||||
/* Since we take cursor buffer way from the cursor plane and
|
/* Create the cursor BO for the display of this window,
|
||||||
destroy the cursor GBM BO when we destroy a window, we must
|
now that we know this is not a VK window. */
|
||||||
also manually re-show the cursor on screen, if necessary,
|
KMSDRM_CreateCursorBO(display);
|
||||||
when we create a window. */
|
|
||||||
|
/* Init mouse (=create and set the default cursor),
|
||||||
|
now that we know this is not a VK window. */
|
||||||
|
KMSDRM_InitMouse(_this, display);
|
||||||
|
|
||||||
|
/* When we destroy a window, we remove the cursor buffer from
|
||||||
|
the cursor plane and destroy the cursor GBM BO, but SDL expects
|
||||||
|
that we keep showing the visible cursors bewteen window
|
||||||
|
destruction/creation cycles. So we must manually re-show the
|
||||||
|
visible cursors, if necessary, when we create a window. */
|
||||||
KMSDRM_InitCursor();
|
KMSDRM_InitCursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1256,7 +1294,6 @@ KMSDRM_ReconfigureWindow( _THIS, SDL_Window * window) {
|
||||||
as pending so it's done on SwapWindow. */
|
as pending so it's done on SwapWindow. */
|
||||||
KMSDRM_CreateSurfaces(_this, window);
|
KMSDRM_CreateSurfaces(_this, window);
|
||||||
dispdata->modeset_pending = SDL_TRUE;
|
dispdata->modeset_pending = SDL_TRUE;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
|
@ -138,6 +138,7 @@ void KMSDRM_RaiseWindow(_THIS, SDL_Window * window);
|
||||||
void KMSDRM_MaximizeWindow(_THIS, SDL_Window * window);
|
void KMSDRM_MaximizeWindow(_THIS, SDL_Window * window);
|
||||||
void KMSDRM_MinimizeWindow(_THIS, SDL_Window * window);
|
void KMSDRM_MinimizeWindow(_THIS, SDL_Window * window);
|
||||||
void KMSDRM_RestoreWindow(_THIS, SDL_Window * window);
|
void KMSDRM_RestoreWindow(_THIS, SDL_Window * window);
|
||||||
|
void KMSDRM_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed);
|
||||||
void KMSDRM_DestroyWindow(_THIS, SDL_Window * window);
|
void KMSDRM_DestroyWindow(_THIS, SDL_Window * window);
|
||||||
|
|
||||||
/* Window manager function */
|
/* Window manager function */
|
||||||
|
|
Loading…
Reference in a new issue