summaryrefslogtreecommitdiff
path: root/source/3rd-party/SDL2/src/video/kmsdrm
diff options
context:
space:
mode:
Diffstat (limited to 'source/3rd-party/SDL2/src/video/kmsdrm')
-rw-r--r--source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmdyn.c171
-rw-r--r--source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmdyn.h53
-rw-r--r--source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmevents.c42
-rw-r--r--source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmevents.h31
-rw-r--r--source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmmouse.c501
-rw-r--r--source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmmouse.h45
-rw-r--r--source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmopengles.c189
-rw-r--r--source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmopengles.h48
-rw-r--r--source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmsym.h99
-rw-r--r--source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmvideo.c739
-rw-r--r--source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmvideo.h125
11 files changed, 2043 insertions, 0 deletions
diff --git a/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmdyn.c b/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmdyn.c
new file mode 100644
index 0000000..c79f372
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmdyn.c
@@ -0,0 +1,171 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_KMSDRM
+
+#define DEBUG_DYNAMIC_KMSDRM 0
+
+#include "SDL_kmsdrmdyn.h"
+
+#if DEBUG_DYNAMIC_KMSDRM
+#include "SDL_log.h"
+#endif
+
+#ifdef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC
+
+#include "SDL_name.h"
+#include "SDL_loadso.h"
+
+typedef struct
+{
+ void *lib;
+ const char *libname;
+} kmsdrmdynlib;
+
+#ifndef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC
+#define SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC NULL
+#endif
+#ifndef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC_GBM
+#define SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC_GBM NULL
+#endif
+
+static kmsdrmdynlib kmsdrmlibs[] = {
+ {NULL, SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC},
+ {NULL, SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC_GBM}
+};
+
+static void *
+KMSDRM_GetSym(const char *fnname, int *pHasModule)
+{
+ int i;
+ void *fn = NULL;
+ for (i = 0; i < SDL_TABLESIZE(kmsdrmlibs); i++) {
+ if (kmsdrmlibs[i].lib != NULL) {
+ fn = SDL_LoadFunction(kmsdrmlibs[i].lib, fnname);
+ if (fn != NULL)
+ break;
+ }
+ }
+
+#if DEBUG_DYNAMIC_KMSDRM
+ if (fn != NULL)
+ SDL_Log("KMSDRM: Found '%s' in %s (%p)\n", fnname, kmsdrmlibs[i].libname, fn);
+ else
+ SDL_Log("KMSDRM: Symbol '%s' NOT FOUND!\n", fnname);
+#endif
+
+ if (fn == NULL)
+ *pHasModule = 0; /* kill this module. */
+
+ return fn;
+}
+
+#endif /* SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC */
+
+/* Define all the function pointers and wrappers... */
+#define SDL_KMSDRM_MODULE(modname) int SDL_KMSDRM_HAVE_##modname = 0;
+#define SDL_KMSDRM_SYM(rc,fn,params) SDL_DYNKMSDRMFN_##fn KMSDRM_##fn = NULL;
+#define SDL_KMSDRM_SYM_CONST(type,name) SDL_DYNKMSDRMCONST_##name KMSDRM_##name = NULL;
+#include "SDL_kmsdrmsym.h"
+
+static int kmsdrm_load_refcount = 0;
+
+void
+SDL_KMSDRM_UnloadSymbols(void)
+{
+ /* Don't actually unload if more than one module is using the libs... */
+ if (kmsdrm_load_refcount > 0) {
+ if (--kmsdrm_load_refcount == 0) {
+#ifdef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC
+ int i;
+#endif
+
+ /* set all the function pointers to NULL. */
+#define SDL_KMSDRM_MODULE(modname) SDL_KMSDRM_HAVE_##modname = 0;
+#define SDL_KMSDRM_SYM(rc,fn,params) KMSDRM_##fn = NULL;
+#define SDL_KMSDRM_SYM_CONST(type,name) KMSDRM_##name = NULL;
+#include "SDL_kmsdrmsym.h"
+
+
+#ifdef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC
+ for (i = 0; i < SDL_TABLESIZE(kmsdrmlibs); i++) {
+ if (kmsdrmlibs[i].lib != NULL) {
+ SDL_UnloadObject(kmsdrmlibs[i].lib);
+ kmsdrmlibs[i].lib = NULL;
+ }
+ }
+#endif
+ }
+ }
+}
+
+/* returns non-zero if all needed symbols were loaded. */
+int
+SDL_KMSDRM_LoadSymbols(void)
+{
+ int rc = 1; /* always succeed if not using Dynamic KMSDRM stuff. */
+
+ /* deal with multiple modules needing these symbols... */
+ if (kmsdrm_load_refcount++ == 0) {
+#ifdef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC
+ int i;
+ int *thismod = NULL;
+ for (i = 0; i < SDL_TABLESIZE(kmsdrmlibs); i++) {
+ if (kmsdrmlibs[i].libname != NULL) {
+ kmsdrmlibs[i].lib = SDL_LoadObject(kmsdrmlibs[i].libname);
+ }
+ }
+
+#define SDL_KMSDRM_MODULE(modname) SDL_KMSDRM_HAVE_##modname = 1; /* default yes */
+#include "SDL_kmsdrmsym.h"
+
+#define SDL_KMSDRM_MODULE(modname) thismod = &SDL_KMSDRM_HAVE_##modname;
+#define SDL_KMSDRM_SYM(rc,fn,params) KMSDRM_##fn = (SDL_DYNKMSDRMFN_##fn) KMSDRM_GetSym(#fn,thismod);
+#define SDL_KMSDRM_SYM_CONST(type,name) KMSDRM_##name = *(SDL_DYNKMSDRMCONST_##name*) KMSDRM_GetSym(#name,thismod);
+#include "SDL_kmsdrmsym.h"
+
+ if ((SDL_KMSDRM_HAVE_LIBDRM) && (SDL_KMSDRM_HAVE_GBM)) {
+ /* all required symbols loaded. */
+ SDL_ClearError();
+ } else {
+ /* in case something got loaded... */
+ SDL_KMSDRM_UnloadSymbols();
+ rc = 0;
+ }
+
+#else /* no dynamic KMSDRM */
+
+#define SDL_KMSDRM_MODULE(modname) SDL_KMSDRM_HAVE_##modname = 1; /* default yes */
+#define SDL_KMSDRM_SYM(rc,fn,params) KMSDRM_##fn = fn;
+#define SDL_KMSDRM_SYM_CONST(type,name) KMSDRM_##name = name;
+#include "SDL_kmsdrmsym.h"
+
+#endif
+ }
+
+ return rc;
+}
+
+#endif /* SDL_VIDEO_DRIVER_KMSDRM */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmdyn.h b/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmdyn.h
new file mode 100644
index 0000000..578b088
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmdyn.h
@@ -0,0 +1,53 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef SDL_kmsdrmdyn_h_
+#define SDL_kmsdrmdyn_h_
+
+#include "../../SDL_internal.h"
+
+#include <xf86drm.h>
+#include <xf86drmMode.h>
+#include <gbm.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int SDL_KMSDRM_LoadSymbols(void);
+void SDL_KMSDRM_UnloadSymbols(void);
+
+/* Declare all the function pointers and wrappers... */
+#define SDL_KMSDRM_SYM(rc,fn,params) \
+ typedef rc (*SDL_DYNKMSDRMFN_##fn) params; \
+ extern SDL_DYNKMSDRMFN_##fn KMSDRM_##fn;
+#define SDL_KMSDRM_SYM_CONST(type, name) \
+ typedef type SDL_DYNKMSDRMCONST_##name; \
+ extern SDL_DYNKMSDRMCONST_##name KMSDRM_##name;
+#include "SDL_kmsdrmsym.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SDL_kmsdrmdyn_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmevents.c b/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmevents.c
new file mode 100644
index 0000000..5a611f6
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmevents.c
@@ -0,0 +1,42 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_KMSDRM
+
+#include "SDL_kmsdrmvideo.h"
+#include "SDL_kmsdrmevents.h"
+
+#ifdef SDL_INPUT_LINUXEV
+#include "../../core/linux/SDL_evdev.h"
+#endif
+
+void KMSDRM_PumpEvents(_THIS)
+{
+#ifdef SDL_INPUT_LINUXEV
+ SDL_EVDEV_Poll();
+#endif
+
+}
+
+#endif /* SDL_VIDEO_DRIVER_KMSDRM */
+
diff --git a/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmevents.h b/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmevents.h
new file mode 100644
index 0000000..3b88c28
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmevents.h
@@ -0,0 +1,31 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "../../SDL_internal.h"
+
+#ifndef SDL_kmsdrmevents_h_
+#define SDL_kmsdrmevents_h_
+
+extern void KMSDRM_PumpEvents(_THIS);
+extern void KMSDRM_EventInit(_THIS);
+extern void KMSDRM_EventQuit(_THIS);
+
+#endif /* SDL_kmsdrmevents_h_ */
diff --git a/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmmouse.c b/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmmouse.c
new file mode 100644
index 0000000..0474089
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmmouse.c
@@ -0,0 +1,501 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_KMSDRM
+
+#include "SDL_kmsdrmvideo.h"
+#include "SDL_kmsdrmmouse.h"
+#include "SDL_kmsdrmdyn.h"
+
+#include "../../events/SDL_mouse_c.h"
+#include "../../events/default_cursor.h"
+
+static SDL_Cursor *KMSDRM_CreateDefaultCursor(void);
+static SDL_Cursor *KMSDRM_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y);
+static int KMSDRM_ShowCursor(SDL_Cursor * cursor);
+static void KMSDRM_MoveCursor(SDL_Cursor * cursor);
+static void KMSDRM_FreeCursor(SDL_Cursor * cursor);
+static void KMSDRM_WarpMouse(SDL_Window * window, int x, int y);
+static int KMSDRM_WarpMouseGlobal(int x, int y);
+
+static SDL_Cursor *
+KMSDRM_CreateDefaultCursor(void)
+{
+ return SDL_CreateCursor(default_cdata, default_cmask, DEFAULT_CWIDTH, DEFAULT_CHEIGHT, DEFAULT_CHOTX, DEFAULT_CHOTY);
+}
+
+/* Evaluate if a given cursor size is supported or not. Notably, current Intel gfx only support 64x64 and up. */
+static SDL_bool
+KMSDRM_IsCursorSizeSupported (int w, int h, uint32_t bo_format) {
+
+ SDL_VideoDevice *dev = SDL_GetVideoDevice();
+ SDL_VideoData *vdata = ((SDL_VideoData *)dev->driverdata);
+ int ret;
+ uint32_t bo_handle;
+ struct gbm_bo *bo = KMSDRM_gbm_bo_create(vdata->gbm, w, h, bo_format,
+ GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE);
+
+ if (bo == NULL) {
+ SDL_SetError("Could not create GBM cursor BO width size %dx%d for size testing", w, h);
+ goto cleanup;
+ }
+
+ bo_handle = KMSDRM_gbm_bo_get_handle(bo).u32;
+ ret = KMSDRM_drmModeSetCursor(vdata->drm_fd, vdata->crtc_id, bo_handle, w, h);
+
+ if (ret) {
+ goto cleanup;
+ }
+ else {
+ KMSDRM_gbm_bo_destroy(bo);
+ return SDL_TRUE;
+ }
+
+cleanup:
+ if (bo != NULL) {
+ KMSDRM_gbm_bo_destroy(bo);
+ }
+ return SDL_FALSE;
+}
+
+/* Create a cursor from a surface */
+static SDL_Cursor *
+KMSDRM_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
+{
+ SDL_VideoDevice *dev = SDL_GetVideoDevice();
+ SDL_VideoData *vdata = ((SDL_VideoData *)dev->driverdata);
+ SDL_PixelFormat *pixlfmt = surface->format;
+ KMSDRM_CursorData *curdata;
+ SDL_Cursor *cursor;
+ SDL_bool cursor_supported = SDL_FALSE;
+ int i, ret, usable_cursor_w, usable_cursor_h;
+ uint32_t bo_format, bo_stride;
+ char *buffer = NULL;
+ size_t bufsize;
+
+ switch(pixlfmt->format) {
+ case SDL_PIXELFORMAT_RGB332:
+ bo_format = GBM_FORMAT_RGB332;
+ break;
+ case SDL_PIXELFORMAT_ARGB4444:
+ bo_format = GBM_FORMAT_ARGB4444;
+ break;
+ case SDL_PIXELFORMAT_RGBA4444:
+ bo_format = GBM_FORMAT_RGBA4444;
+ break;
+ case SDL_PIXELFORMAT_ABGR4444:
+ bo_format = GBM_FORMAT_ABGR4444;
+ break;
+ case SDL_PIXELFORMAT_BGRA4444:
+ bo_format = GBM_FORMAT_BGRA4444;
+ break;
+ case SDL_PIXELFORMAT_ARGB1555:
+ bo_format = GBM_FORMAT_ARGB1555;
+ break;
+ case SDL_PIXELFORMAT_RGBA5551:
+ bo_format = GBM_FORMAT_RGBA5551;
+ break;
+ case SDL_PIXELFORMAT_ABGR1555:
+ bo_format = GBM_FORMAT_ABGR1555;
+ break;
+ case SDL_PIXELFORMAT_BGRA5551:
+ bo_format = GBM_FORMAT_BGRA5551;
+ break;
+ case SDL_PIXELFORMAT_RGB565:
+ bo_format = GBM_FORMAT_RGB565;
+ break;
+ case SDL_PIXELFORMAT_BGR565:
+ bo_format = GBM_FORMAT_BGR565;
+ break;
+ case SDL_PIXELFORMAT_RGB888:
+ case SDL_PIXELFORMAT_RGB24:
+ bo_format = GBM_FORMAT_RGB888;
+ break;
+ case SDL_PIXELFORMAT_BGR888:
+ case SDL_PIXELFORMAT_BGR24:
+ bo_format = GBM_FORMAT_BGR888;
+ break;
+ case SDL_PIXELFORMAT_RGBX8888:
+ bo_format = GBM_FORMAT_RGBX8888;
+ break;
+ case SDL_PIXELFORMAT_BGRX8888:
+ bo_format = GBM_FORMAT_BGRX8888;
+ break;
+ case SDL_PIXELFORMAT_ARGB8888:
+ bo_format = GBM_FORMAT_ARGB8888;
+ break;
+ case SDL_PIXELFORMAT_RGBA8888:
+ bo_format = GBM_FORMAT_RGBA8888;
+ break;
+ case SDL_PIXELFORMAT_ABGR8888:
+ bo_format = GBM_FORMAT_ABGR8888;
+ break;
+ case SDL_PIXELFORMAT_BGRA8888:
+ bo_format = GBM_FORMAT_BGRA8888;
+ break;
+ case SDL_PIXELFORMAT_ARGB2101010:
+ bo_format = GBM_FORMAT_ARGB2101010;
+ break;
+ default:
+ SDL_SetError("Unsupported pixel format for cursor");
+ return NULL;
+ }
+
+ if (!KMSDRM_gbm_device_is_format_supported(vdata->gbm, bo_format, GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE)) {
+ SDL_SetError("Unsupported pixel format for cursor");
+ return NULL;
+ }
+
+ cursor = (SDL_Cursor *) SDL_calloc(1, sizeof(*cursor));
+ if (cursor == NULL) {
+ SDL_OutOfMemory();
+ return NULL;
+ }
+ curdata = (KMSDRM_CursorData *) SDL_calloc(1, sizeof(*curdata));
+ if (curdata == NULL) {
+ SDL_OutOfMemory();
+ SDL_free(cursor);
+ return NULL;
+ }
+
+ /* We have to know beforehand if a cursor with the same size as the surface is supported.
+ * If it's not, we have to find an usable cursor size and use an intermediate and clean buffer.
+ * If we can't find a cursor size supported by the hardware, we won't go on trying to
+ * call SDL_SetCursor() later. */
+
+ usable_cursor_w = surface->w;
+ usable_cursor_h = surface->h;
+
+ while (usable_cursor_w <= MAX_CURSOR_W && usable_cursor_h <= MAX_CURSOR_H) {
+ if (KMSDRM_IsCursorSizeSupported(usable_cursor_w, usable_cursor_h, bo_format)) {
+ cursor_supported = SDL_TRUE;
+ break;
+ }
+ usable_cursor_w += usable_cursor_w;
+ usable_cursor_h += usable_cursor_h;
+ }
+
+ if (!cursor_supported) {
+ SDL_SetError("Could not find a cursor size supported by the kernel driver");
+ goto cleanup;
+ }
+
+ curdata->hot_x = hot_x;
+ curdata->hot_y = hot_y;
+ curdata->w = usable_cursor_w;
+ curdata->h = usable_cursor_h;
+
+ curdata->bo = KMSDRM_gbm_bo_create(vdata->gbm, usable_cursor_w, usable_cursor_h, bo_format,
+ GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE);
+
+ if (curdata->bo == NULL) {
+ SDL_SetError("Could not create GBM cursor BO");
+ goto cleanup;
+ }
+
+ bo_stride = KMSDRM_gbm_bo_get_stride(curdata->bo);
+ bufsize = bo_stride * curdata->h;
+
+ if (surface->pitch != bo_stride) {
+ /* pitch doesn't match stride, must be copied to temp buffer */
+ buffer = SDL_malloc(bufsize);
+ if (buffer == NULL) {
+ SDL_OutOfMemory();
+ goto cleanup;
+ }
+
+ if (SDL_MUSTLOCK(surface)) {
+ if (SDL_LockSurface(surface) < 0) {
+ /* Could not lock surface */
+ goto cleanup;
+ }
+ }
+
+ /* Clean the whole temporary buffer */
+ SDL_memset(buffer, 0x00, bo_stride * curdata->h);
+
+ /* Copy to temporary buffer */
+ for (i = 0; i < surface->h; i++) {
+ SDL_memcpy(buffer + (i * bo_stride),
+ ((char *)surface->pixels) + (i * surface->pitch),
+ surface->w * pixlfmt->BytesPerPixel);
+ }
+
+ if (SDL_MUSTLOCK(surface)) {
+ SDL_UnlockSurface(surface);
+ }
+
+ if (KMSDRM_gbm_bo_write(curdata->bo, buffer, bufsize)) {
+ SDL_SetError("Could not write to GBM cursor BO");
+ goto cleanup;
+ }
+
+ /* Free temporary buffer */
+ SDL_free(buffer);
+ buffer = NULL;
+ } else {
+ /* surface matches BO format */
+ if (SDL_MUSTLOCK(surface)) {
+ if (SDL_LockSurface(surface) < 0) {
+ /* Could not lock surface */
+ goto cleanup;
+ }
+ }
+
+ ret = KMSDRM_gbm_bo_write(curdata->bo, surface->pixels, bufsize);
+
+ if (SDL_MUSTLOCK(surface)) {
+ SDL_UnlockSurface(surface);
+ }
+
+ if (ret) {
+ SDL_SetError("Could not write to GBM cursor BO");
+ goto cleanup;
+ }
+ }
+
+ cursor->driverdata = curdata;
+
+ return cursor;
+
+cleanup:
+ if (buffer != NULL) {
+ SDL_free(buffer);
+ }
+ if (cursor != NULL) {
+ SDL_free(cursor);
+ }
+ if (curdata != NULL) {
+ if (curdata->bo != NULL) {
+ KMSDRM_gbm_bo_destroy(curdata->bo);
+ }
+ SDL_free(curdata);
+ }
+ return NULL;
+}
+
+/* Show the specified cursor, or hide if cursor is NULL */
+static int
+KMSDRM_ShowCursor(SDL_Cursor * cursor)
+{
+ SDL_VideoDevice *dev = SDL_GetVideoDevice();
+ SDL_VideoData *vdata = ((SDL_VideoData *)dev->driverdata);
+ SDL_Mouse *mouse;
+ KMSDRM_CursorData *curdata;
+ SDL_VideoDisplay *display = NULL;
+ SDL_DisplayData *ddata = NULL;
+ int ret;
+ uint32_t bo_handle;
+
+ mouse = SDL_GetMouse();
+ if (mouse == NULL) {
+ return SDL_SetError("No mouse.");
+ }
+
+ if (mouse->focus != NULL) {
+ display = SDL_GetDisplayForWindow(mouse->focus);
+ if (display != NULL) {
+ ddata = (SDL_DisplayData*) display->driverdata;
+ }
+ }
+
+ if (cursor == NULL) {
+ /* Hide current cursor */
+ if ( mouse->cur_cursor != NULL && mouse->cur_cursor->driverdata != NULL) {
+ curdata = (KMSDRM_CursorData *) mouse->cur_cursor->driverdata;
+
+ if (curdata->crtc_id != 0) {
+ ret = KMSDRM_drmModeSetCursor(vdata->drm_fd, curdata->crtc_id, 0, 0, 0);
+ if (ret) {
+ SDL_SetError("Could not hide current cursor with drmModeSetCursor().");
+ return ret;
+ }
+ /* Mark previous cursor as not-displayed */
+ curdata->crtc_id = 0;
+
+ return 0;
+ }
+ }
+ /* otherwise if possible, hide global cursor */
+ if (ddata != NULL && ddata->crtc_id != 0) {
+ ret = KMSDRM_drmModeSetCursor(vdata->drm_fd, ddata->crtc_id, 0, 0, 0);
+ if (ret) {
+ SDL_SetError("Could not hide display's cursor with drmModeSetCursor().");
+ return ret;
+ }
+ return 0;
+ }
+
+ return SDL_SetError("Couldn't find cursor to hide.");
+ }
+ /* If cursor != NULL, show new cursor on display */
+ if (display == NULL) {
+ return SDL_SetError("Could not get display for mouse.");
+ }
+ if (ddata == NULL) {
+ return SDL_SetError("Could not get display driverdata.");
+ }
+
+ curdata = (KMSDRM_CursorData *) cursor->driverdata;
+ if (curdata == NULL || curdata->bo == NULL) {
+ return SDL_SetError("Cursor not initialized properly.");
+ }
+
+ bo_handle = KMSDRM_gbm_bo_get_handle(curdata->bo).u32;
+ if (curdata->hot_x == 0 && curdata->hot_y == 0) {
+ ret = KMSDRM_drmModeSetCursor(vdata->drm_fd, ddata->crtc_id, bo_handle,
+ curdata->w, curdata->h);
+ } else {
+ ret = KMSDRM_drmModeSetCursor2(vdata->drm_fd, ddata->crtc_id, bo_handle,
+ curdata->w, curdata->h,
+ curdata->hot_x, curdata->hot_y);
+ }
+ if (ret) {
+ SDL_SetError("drmModeSetCursor failed.");
+ return ret;
+ }
+
+ curdata->crtc_id = ddata->crtc_id;
+
+ return 0;
+}
+
+/* Free a window manager cursor */
+static void
+KMSDRM_FreeCursor(SDL_Cursor * cursor)
+{
+ KMSDRM_CursorData *curdata;
+ int drm_fd;
+
+ if (cursor != NULL) {
+ curdata = (KMSDRM_CursorData *) cursor->driverdata;
+
+ if (curdata != NULL) {
+ if (curdata->bo != NULL) {
+ if (curdata->crtc_id != 0) {
+ drm_fd = KMSDRM_gbm_device_get_fd(KMSDRM_gbm_bo_get_device(curdata->bo));
+ /* Hide the cursor if previously shown on a CRTC */
+ KMSDRM_drmModeSetCursor(drm_fd, curdata->crtc_id, 0, 0, 0);
+ curdata->crtc_id = 0;
+ }
+ KMSDRM_gbm_bo_destroy(curdata->bo);
+ curdata->bo = NULL;
+ }
+ SDL_free(cursor->driverdata);
+ }
+ SDL_free(cursor);
+ }
+}
+
+/* Warp the mouse to (x,y) */
+static void
+KMSDRM_WarpMouse(SDL_Window * window, int x, int y)
+{
+ /* Only one global/fullscreen window is supported */
+ KMSDRM_WarpMouseGlobal(x, y);
+}
+
+/* Warp the mouse to (x,y) */
+static int
+KMSDRM_WarpMouseGlobal(int x, int y)
+{
+ KMSDRM_CursorData *curdata;
+ 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));
+ ret = KMSDRM_drmModeMoveCursor(drm_fd, curdata->crtc_id, x, y);
+
+ if (ret) {
+ SDL_SetError("drmModeMoveCursor() failed.");
+ }
+
+ return ret;
+ } else {
+ return SDL_SetError("Cursor is not currently shown.");
+ }
+ } else {
+ return SDL_SetError("Cursor not initialized properly.");
+ }
+ } else {
+ return SDL_SetError("No mouse or current cursor.");
+ }
+}
+
+void
+KMSDRM_InitMouse(_THIS)
+{
+ /* FIXME: Using UDEV it should be possible to scan all mice
+ * but there's no point in doing so as there's no multimice support...yet!
+ */
+ SDL_Mouse *mouse = SDL_GetMouse();
+
+ mouse->CreateCursor = KMSDRM_CreateCursor;
+ mouse->ShowCursor = KMSDRM_ShowCursor;
+ mouse->MoveCursor = KMSDRM_MoveCursor;
+ mouse->FreeCursor = KMSDRM_FreeCursor;
+ mouse->WarpMouse = KMSDRM_WarpMouse;
+ mouse->WarpMouseGlobal = KMSDRM_WarpMouseGlobal;
+
+ SDL_SetDefaultCursor(KMSDRM_CreateDefaultCursor());
+}
+
+void
+KMSDRM_QuitMouse(_THIS)
+{
+ /* TODO: ? */
+}
+
+/* This is called when a mouse motion event occurs */
+static void
+KMSDRM_MoveCursor(SDL_Cursor * cursor)
+{
+ SDL_Mouse *mouse = SDL_GetMouse();
+ 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 */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmmouse.h b/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmmouse.h
new file mode 100644
index 0000000..754417d
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmmouse.h
@@ -0,0 +1,45 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "../../SDL_internal.h"
+
+#ifndef SDL_KMSDRM_mouse_h_
+#define SDL_KMSDRM_mouse_h_
+
+#include <gbm.h>
+
+#define MAX_CURSOR_W 512
+#define MAX_CURSOR_H 512
+
+typedef struct _KMSDRM_CursorData
+{
+ struct gbm_bo *bo;
+ uint32_t crtc_id;
+ int hot_x, hot_y;
+ int w, h;
+} KMSDRM_CursorData;
+
+extern void KMSDRM_InitMouse(_THIS);
+extern void KMSDRM_QuitMouse(_THIS);
+
+#endif /* SDL_KMSDRM_mouse_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmopengles.c b/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmopengles.c
new file mode 100644
index 0000000..fc6304d
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmopengles.c
@@ -0,0 +1,189 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_KMSDRM && SDL_VIDEO_OPENGL_EGL
+
+#include "SDL_log.h"
+
+#include "SDL_kmsdrmvideo.h"
+#include "SDL_kmsdrmopengles.h"
+#include "SDL_kmsdrmdyn.h"
+
+#ifndef EGL_PLATFORM_GBM_MESA
+#define EGL_PLATFORM_GBM_MESA 0x31D7
+#endif
+
+/* EGL implementation of SDL OpenGL support */
+
+int
+KMSDRM_GLES_LoadLibrary(_THIS, const char *path) {
+ return SDL_EGL_LoadLibrary(_this, path, ((SDL_VideoData *)_this->driverdata)->gbm, EGL_PLATFORM_GBM_MESA);
+}
+
+SDL_EGL_CreateContext_impl(KMSDRM)
+
+SDL_bool
+KMSDRM_GLES_SetupCrtc(_THIS, SDL_Window * window) {
+ SDL_WindowData *wdata = ((SDL_WindowData *) window->driverdata);
+ SDL_DisplayData *displaydata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata;
+ SDL_VideoData *vdata = ((SDL_VideoData *)_this->driverdata);
+ KMSDRM_FBInfo *fb_info;
+
+ if (!(_this->egl_data->eglSwapBuffers(_this->egl_data->egl_display, wdata->egl_surface))) {
+ SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "eglSwapBuffers failed on CRTC setup");
+ return SDL_FALSE;
+ }
+
+ wdata->crtc_bo = KMSDRM_gbm_surface_lock_front_buffer(wdata->gs);
+ if (wdata->crtc_bo == NULL) {
+ SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not lock GBM surface front buffer on CRTC setup");
+ return SDL_FALSE;
+ }
+
+ fb_info = KMSDRM_FBFromBO(_this, wdata->crtc_bo);
+ if (fb_info == NULL) {
+ return SDL_FALSE;
+ }
+
+ if(KMSDRM_drmModeSetCrtc(vdata->drm_fd, displaydata->crtc_id, fb_info->fb_id,
+ 0, 0, &vdata->saved_conn_id, 1, &displaydata->cur_mode) != 0) {
+ SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "Could not set up CRTC to a GBM buffer");
+ return SDL_FALSE;
+
+ }
+
+ wdata->crtc_ready = SDL_TRUE;
+ return SDL_TRUE;
+}
+
+int KMSDRM_GLES_SetSwapInterval(_THIS, int interval) {
+ if (!_this->egl_data) {
+ return SDL_SetError("EGL not initialized");
+ }
+
+ if (interval == 0 || interval == 1) {
+ _this->egl_data->egl_swapinterval = interval;
+ } else {
+ return SDL_SetError("Only swap intervals of 0 or 1 are supported");
+ }
+
+ return 0;
+}
+
+int
+KMSDRM_GLES_SwapWindow(_THIS, SDL_Window * window) {
+ SDL_WindowData *wdata = ((SDL_WindowData *) window->driverdata);
+ SDL_DisplayData *displaydata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata;
+ SDL_VideoData *vdata = ((SDL_VideoData *)_this->driverdata);
+ KMSDRM_FBInfo *fb_info;
+ int ret;
+
+ /* Do we still need to wait for a flip? */
+ int timeout = 0;
+ if (_this->egl_data->egl_swapinterval == 1) {
+ timeout = -1;
+ }
+ if (!KMSDRM_WaitPageFlip(_this, wdata, timeout)) {
+ return 0;
+ }
+
+ /* Release previously displayed buffer (which is now the backbuffer) and lock a new one */
+ if (wdata->next_bo != NULL) {
+ KMSDRM_gbm_surface_release_buffer(wdata->gs, wdata->current_bo);
+ /* SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Released GBM surface %p", (void *)wdata->next_bo); */
+
+ wdata->current_bo = wdata->next_bo;
+ wdata->next_bo = NULL;
+ }
+
+ if (!(_this->egl_data->eglSwapBuffers(_this->egl_data->egl_display, wdata->egl_surface))) {
+ SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "eglSwapBuffers failed.");
+ return 0;
+ }
+
+ if (wdata->current_bo == NULL) {
+ wdata->current_bo = KMSDRM_gbm_surface_lock_front_buffer(wdata->gs);
+ if (wdata->current_bo == NULL) {
+ return 0;
+ }
+ }
+
+ wdata->next_bo = KMSDRM_gbm_surface_lock_front_buffer(wdata->gs);
+ if (wdata->next_bo == NULL) {
+ SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not lock GBM surface front buffer");
+ return 0;
+ /* } else {
+ SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Locked GBM surface %p", (void *)wdata->next_bo); */
+ }
+
+ fb_info = KMSDRM_FBFromBO(_this, wdata->next_bo);
+ if (fb_info == NULL) {
+ return 0;
+ }
+ if (_this->egl_data->egl_swapinterval == 0) {
+ /* Swap buffers instantly, possible tearing */
+ /* SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "drmModeSetCrtc(%d, %u, %u, 0, 0, &%u, 1, &%ux%u@%u)",
+ vdata->drm_fd, displaydata->crtc_id, fb_info->fb_id, vdata->saved_conn_id,
+ displaydata->cur_mode.hdisplay, displaydata->cur_mode.vdisplay, displaydata->cur_mode.vrefresh); */
+ ret = KMSDRM_drmModeSetCrtc(vdata->drm_fd, displaydata->crtc_id, fb_info->fb_id,
+ 0, 0, &vdata->saved_conn_id, 1, &displaydata->cur_mode);
+ if(ret != 0) {
+ SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not pageflip with drmModeSetCrtc: %d", ret);
+ }
+ } else {
+ /* Queue page flip at vsync */
+
+ /* Have we already setup the CRTC to one of the GBM buffers? Do so if we have not,
+ or FlipPage won't work in some cases. */
+ if (!wdata->crtc_ready) {
+ if(!KMSDRM_GLES_SetupCrtc(_this, window)) {
+ SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not set up CRTC for doing vsync-ed pageflips");
+ return 0;
+ }
+ }
+
+ /* SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "drmModePageFlip(%d, %u, %u, DRM_MODE_PAGE_FLIP_EVENT, &wdata->waiting_for_flip)",
+ vdata->drm_fd, displaydata->crtc_id, fb_info->fb_id); */
+ ret = KMSDRM_drmModePageFlip(vdata->drm_fd, displaydata->crtc_id, fb_info->fb_id,
+ DRM_MODE_PAGE_FLIP_EVENT, &wdata->waiting_for_flip);
+ if (ret == 0) {
+ wdata->waiting_for_flip = SDL_TRUE;
+ } else {
+ SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not queue pageflip: %d", ret);
+ }
+
+ /* Wait immediately for vsync (as if we only had two buffers), for low input-lag scenarios.
+ Run your SDL2 program with "SDL_KMSDRM_DOUBLE_BUFFER=1 <program_name>" to enable this. */
+ if (wdata->double_buffer) {
+ KMSDRM_WaitPageFlip(_this, wdata, -1);
+ }
+ }
+
+ return 0;
+}
+
+SDL_EGL_MakeCurrent_impl(KMSDRM)
+
+#endif /* SDL_VIDEO_DRIVER_KMSDRM && SDL_VIDEO_OPENGL_EGL */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmopengles.h b/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmopengles.h
new file mode 100644
index 0000000..d0a7bfa
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmopengles.h
@@ -0,0 +1,48 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_kmsdrmopengles_h_
+#define SDL_kmsdrmopengles_h_
+
+#if SDL_VIDEO_DRIVER_KMSDRM && SDL_VIDEO_OPENGL_EGL
+
+#include "../SDL_sysvideo.h"
+#include "../SDL_egl_c.h"
+
+/* OpenGLES functions */
+#define KMSDRM_GLES_GetAttribute SDL_EGL_GetAttribute
+#define KMSDRM_GLES_GetProcAddress SDL_EGL_GetProcAddress
+#define KMSDRM_GLES_UnloadLibrary SDL_EGL_UnloadLibrary
+#define KMSDRM_GLES_DeleteContext SDL_EGL_DeleteContext
+#define KMSDRM_GLES_GetSwapInterval SDL_EGL_GetSwapInterval
+
+extern int KMSDRM_GLES_SetSwapInterval(_THIS, int interval);
+extern int KMSDRM_GLES_LoadLibrary(_THIS, const char *path);
+extern SDL_GLContext KMSDRM_GLES_CreateContext(_THIS, SDL_Window * window);
+extern int KMSDRM_GLES_SwapWindow(_THIS, SDL_Window * window);
+extern int KMSDRM_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context);
+
+#endif /* SDL_VIDEO_DRIVER_KMSDRM && SDL_VIDEO_OPENGL_EGL */
+
+#endif /* SDL_kmsdrmopengles_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmsym.h b/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmsym.h
new file mode 100644
index 0000000..3ab2318
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmsym.h
@@ -0,0 +1,99 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/* *INDENT-OFF* */
+
+#ifndef SDL_KMSDRM_MODULE
+#define SDL_KMSDRM_MODULE(modname)
+#endif
+
+#ifndef SDL_KMSDRM_SYM
+#define SDL_KMSDRM_SYM(rc,fn,params)
+#endif
+
+#ifndef SDL_KMSDRM_SYM_CONST
+#define SDL_KMSDRM_SYM_CONST(type, name)
+#endif
+
+
+SDL_KMSDRM_MODULE(LIBDRM)
+SDL_KMSDRM_SYM(void,drmModeFreeResources,(drmModeResPtr ptr))
+SDL_KMSDRM_SYM(void,drmModeFreeFB,(drmModeFBPtr ptr))
+SDL_KMSDRM_SYM(void,drmModeFreeCrtc,(drmModeCrtcPtr ptr))
+SDL_KMSDRM_SYM(void,drmModeFreeConnector,(drmModeConnectorPtr ptr))
+SDL_KMSDRM_SYM(void,drmModeFreeEncoder,(drmModeEncoderPtr ptr))
+SDL_KMSDRM_SYM(drmModeResPtr,drmModeGetResources,(int fd))
+SDL_KMSDRM_SYM(int,drmModeAddFB,(int fd, uint32_t width, uint32_t height, uint8_t depth,
+ uint8_t bpp, uint32_t pitch, uint32_t bo_handle,
+ uint32_t *buf_id))
+SDL_KMSDRM_SYM(int,drmModeRmFB,(int fd, uint32_t bufferId))
+SDL_KMSDRM_SYM(drmModeFBPtr,drmModeGetFB,(int fd, uint32_t buf))
+SDL_KMSDRM_SYM(drmModeCrtcPtr,drmModeGetCrtc,(int fd, uint32_t crtcId))
+SDL_KMSDRM_SYM(int,drmModeSetCrtc,(int fd, uint32_t crtcId, uint32_t bufferId,
+ uint32_t x, uint32_t y, uint32_t *connectors, int count,
+ drmModeModeInfoPtr mode))
+SDL_KMSDRM_SYM(int,drmModeSetCursor,(int fd, uint32_t crtcId, uint32_t bo_handle,
+ uint32_t width, uint32_t height))
+SDL_KMSDRM_SYM(int,drmModeSetCursor2,(int fd, uint32_t crtcId, uint32_t bo_handle,
+ uint32_t width, uint32_t height,
+ int32_t hot_x, int32_t hot_y))
+SDL_KMSDRM_SYM(int,drmModeMoveCursor,(int fd, uint32_t crtcId, int x, int y))
+SDL_KMSDRM_SYM(drmModeEncoderPtr,drmModeGetEncoder,(int fd, uint32_t encoder_id))
+SDL_KMSDRM_SYM(drmModeConnectorPtr,drmModeGetConnector,(int fd, uint32_t connector_id))
+SDL_KMSDRM_SYM(int,drmHandleEvent,(int fd,drmEventContextPtr evctx))
+SDL_KMSDRM_SYM(int,drmModePageFlip,(int fd, uint32_t crtc_id, uint32_t fb_id,
+ uint32_t flags, void *user_data))
+
+
+SDL_KMSDRM_MODULE(GBM)
+SDL_KMSDRM_SYM(int,gbm_device_get_fd,(struct gbm_device *gbm))
+SDL_KMSDRM_SYM(int,gbm_device_is_format_supported,(struct gbm_device *gbm,
+ uint32_t format, uint32_t usage))
+SDL_KMSDRM_SYM(void,gbm_device_destroy,(struct gbm_device *gbm))
+SDL_KMSDRM_SYM(struct gbm_device *,gbm_create_device,(int fd))
+SDL_KMSDRM_SYM(unsigned int,gbm_bo_get_width,(struct gbm_bo *bo))
+SDL_KMSDRM_SYM(unsigned int,gbm_bo_get_height,(struct gbm_bo *bo))
+SDL_KMSDRM_SYM(uint32_t,gbm_bo_get_stride,(struct gbm_bo *bo))
+SDL_KMSDRM_SYM(union gbm_bo_handle,gbm_bo_get_handle,(struct gbm_bo *bo))
+SDL_KMSDRM_SYM(int,gbm_bo_write,(struct gbm_bo *bo, const void *buf, size_t count))
+SDL_KMSDRM_SYM(struct gbm_device *,gbm_bo_get_device,(struct gbm_bo *bo))
+SDL_KMSDRM_SYM(void,gbm_bo_set_user_data,(struct gbm_bo *bo, void *data,
+ void (*destroy_user_data)(struct gbm_bo *, void *)))
+SDL_KMSDRM_SYM(void *,gbm_bo_get_user_data,(struct gbm_bo *bo))
+SDL_KMSDRM_SYM(void,gbm_bo_destroy,(struct gbm_bo *bo))
+SDL_KMSDRM_SYM(struct gbm_bo *,gbm_bo_create,(struct gbm_device *gbm,
+ uint32_t width, uint32_t height,
+ uint32_t format, uint32_t usage))
+SDL_KMSDRM_SYM(struct gbm_surface *,gbm_surface_create,(struct gbm_device *gbm,
+ uint32_t width, uint32_t height,
+ uint32_t format, uint32_t flags))
+SDL_KMSDRM_SYM(void,gbm_surface_destroy,(struct gbm_surface *surf))
+SDL_KMSDRM_SYM(struct gbm_bo *,gbm_surface_lock_front_buffer,(struct gbm_surface *surf))
+SDL_KMSDRM_SYM(void,gbm_surface_release_buffer,(struct gbm_surface *surf, struct gbm_bo *bo))
+
+
+#undef SDL_KMSDRM_MODULE
+#undef SDL_KMSDRM_SYM
+#undef SDL_KMSDRM_SYM_CONST
+
+/* *INDENT-ON* */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmvideo.c b/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmvideo.c
new file mode 100644
index 0000000..bacbe0c
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmvideo.c
@@ -0,0 +1,739 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_KMSDRM
+
+/* SDL internals */
+#include "../SDL_sysvideo.h"
+#include "SDL_syswm.h"
+#include "SDL_log.h"
+#include "SDL_hints.h"
+#include "../../events/SDL_mouse_c.h"
+#include "../../events/SDL_keyboard_c.h"
+
+#ifdef SDL_INPUT_LINUXEV
+#include "../../core/linux/SDL_evdev.h"
+#endif
+
+/* KMS/DRM declarations */
+#include "SDL_kmsdrmvideo.h"
+#include "SDL_kmsdrmevents.h"
+#include "SDL_kmsdrmopengles.h"
+#include "SDL_kmsdrmmouse.h"
+#include "SDL_kmsdrmdyn.h"
+#include <sys/stat.h>
+#include <dirent.h>
+#include <errno.h>
+
+#define KMSDRM_DRI_PATH "/dev/dri/"
+
+static int
+check_modestting(int devindex)
+{
+ SDL_bool available = SDL_FALSE;
+ char device[512];
+ int drm_fd;
+
+ SDL_snprintf(device, sizeof (device), "%scard%d", KMSDRM_DRI_PATH, devindex);
+
+ drm_fd = open(device, O_RDWR | O_CLOEXEC);
+ if (drm_fd >= 0) {
+ if (SDL_KMSDRM_LoadSymbols()) {
+ drmModeRes *resources = KMSDRM_drmModeGetResources(drm_fd);
+ if (resources != NULL) {
+ available = SDL_TRUE;
+ KMSDRM_drmModeFreeResources(resources);
+ }
+ SDL_KMSDRM_UnloadSymbols();
+ }
+ close(drm_fd);
+ }
+
+ return available;
+}
+
+static int get_dricount(void)
+{
+ int devcount = 0;
+ struct dirent *res;
+ struct stat sb;
+ DIR *folder;
+
+ if (!(stat(KMSDRM_DRI_PATH, &sb) == 0
+ && S_ISDIR(sb.st_mode))) {
+ printf("The path %s cannot be opened or is not available\n",
+ KMSDRM_DRI_PATH);
+ return 0;
+ }
+
+ if (access(KMSDRM_DRI_PATH, F_OK) == -1) {
+ printf("The path %s cannot be opened\n",
+ KMSDRM_DRI_PATH);
+ return 0;
+ }
+
+ folder = opendir(KMSDRM_DRI_PATH);
+ if (folder) {
+ while ((res = readdir(folder))) {
+ if (res->d_type == DT_CHR) {
+ devcount++;
+ }
+ }
+ closedir(folder);
+ }
+
+ return devcount;
+}
+
+static int
+get_driindex(void)
+{
+ const int devcount = get_dricount();
+ int i;
+
+ for (i = 0; i < devcount; i++) {
+ if (check_modestting(i)) {
+ return i;
+ }
+ }
+
+ return -ENOENT;
+}
+
+static int
+KMSDRM_Available(void)
+{
+ int ret = -ENOENT;
+
+ ret = get_driindex();
+ if (ret >= 0)
+ return 1;
+
+ return ret;
+}
+
+static void
+KMSDRM_Destroy(SDL_VideoDevice * device)
+{
+ if (device->driverdata != NULL) {
+ SDL_free(device->driverdata);
+ device->driverdata = NULL;
+ }
+
+ SDL_free(device);
+ SDL_KMSDRM_UnloadSymbols();
+}
+
+static SDL_VideoDevice *
+KMSDRM_Create(int devindex)
+{
+ SDL_VideoDevice *device;
+ SDL_VideoData *vdata;
+
+ if (!devindex || (devindex > 99)) {
+ devindex = get_driindex();
+ }
+
+ if (devindex < 0) {
+ SDL_SetError("devindex (%d) must be between 0 and 99.\n", devindex);
+ return NULL;
+ }
+
+ if (!SDL_KMSDRM_LoadSymbols()) {
+ return NULL;
+ }
+
+ /* Initialize SDL_VideoDevice structure */
+ device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
+ if (device == NULL) {
+ SDL_OutOfMemory();
+ return NULL;
+ }
+
+ /* Initialize internal data */
+ vdata = (SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData));
+ if (vdata == NULL) {
+ SDL_OutOfMemory();
+ goto cleanup;
+ }
+ vdata->devindex = devindex;
+ vdata->drm_fd = -1;
+
+ device->driverdata = vdata;
+
+ /* Setup amount of available displays and current display */
+ device->num_displays = 0;
+
+ /* Set device free function */
+ device->free = KMSDRM_Destroy;
+
+ /* Setup all functions which we can handle */
+ device->VideoInit = KMSDRM_VideoInit;
+ device->VideoQuit = KMSDRM_VideoQuit;
+ device->GetDisplayModes = KMSDRM_GetDisplayModes;
+ device->SetDisplayMode = KMSDRM_SetDisplayMode;
+ device->CreateSDLWindow = KMSDRM_CreateWindow;
+ device->CreateSDLWindowFrom = KMSDRM_CreateWindowFrom;
+ device->SetWindowTitle = KMSDRM_SetWindowTitle;
+ device->SetWindowIcon = KMSDRM_SetWindowIcon;
+ device->SetWindowPosition = KMSDRM_SetWindowPosition;
+ device->SetWindowSize = KMSDRM_SetWindowSize;
+ device->ShowWindow = KMSDRM_ShowWindow;
+ device->HideWindow = KMSDRM_HideWindow;
+ device->RaiseWindow = KMSDRM_RaiseWindow;
+ device->MaximizeWindow = KMSDRM_MaximizeWindow;
+ device->MinimizeWindow = KMSDRM_MinimizeWindow;
+ device->RestoreWindow = KMSDRM_RestoreWindow;
+ device->SetWindowGrab = KMSDRM_SetWindowGrab;
+ device->DestroyWindow = KMSDRM_DestroyWindow;
+ device->GetWindowWMInfo = KMSDRM_GetWindowWMInfo;
+#if SDL_VIDEO_OPENGL_EGL
+ device->GL_LoadLibrary = KMSDRM_GLES_LoadLibrary;
+ device->GL_GetProcAddress = KMSDRM_GLES_GetProcAddress;
+ device->GL_UnloadLibrary = KMSDRM_GLES_UnloadLibrary;
+ device->GL_CreateContext = KMSDRM_GLES_CreateContext;
+ device->GL_MakeCurrent = KMSDRM_GLES_MakeCurrent;
+ device->GL_SetSwapInterval = KMSDRM_GLES_SetSwapInterval;
+ device->GL_GetSwapInterval = KMSDRM_GLES_GetSwapInterval;
+ device->GL_SwapWindow = KMSDRM_GLES_SwapWindow;
+ device->GL_DeleteContext = KMSDRM_GLES_DeleteContext;
+#endif
+
+ device->PumpEvents = KMSDRM_PumpEvents;
+
+ return device;
+
+cleanup:
+ if (device != NULL)
+ SDL_free(device);
+ if (vdata != NULL)
+ SDL_free(vdata);
+ return NULL;
+}
+
+VideoBootStrap KMSDRM_bootstrap = {
+ "KMSDRM",
+ "KMS/DRM Video Driver",
+ KMSDRM_Available,
+ KMSDRM_Create
+};
+
+
+static void
+KMSDRM_FBDestroyCallback(struct gbm_bo *bo, void *data)
+{
+ KMSDRM_FBInfo *fb_info = (KMSDRM_FBInfo *)data;
+
+ if (fb_info && fb_info->drm_fd > 0 && fb_info->fb_id != 0) {
+ KMSDRM_drmModeRmFB(fb_info->drm_fd, fb_info->fb_id);
+ SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Delete DRM FB %u", fb_info->fb_id);
+ }
+
+ free(fb_info);
+}
+
+KMSDRM_FBInfo *
+KMSDRM_FBFromBO(_THIS, struct gbm_bo *bo)
+{
+ uint32_t w, h, stride, handle;
+ int ret;
+ SDL_VideoData *vdata = ((SDL_VideoData *)_this->driverdata);
+ KMSDRM_FBInfo *fb_info;
+
+ fb_info = (KMSDRM_FBInfo *)KMSDRM_gbm_bo_get_user_data(bo);
+ if (fb_info != NULL) {
+ /* Have a previously used framebuffer, return it */
+ return fb_info;
+ }
+
+ /* Here a new DRM FB must be created */
+ fb_info = (KMSDRM_FBInfo *)SDL_calloc(1, sizeof(KMSDRM_FBInfo));
+ if (fb_info == NULL) {
+ SDL_OutOfMemory();
+ return NULL;
+ }
+ fb_info->drm_fd = vdata->drm_fd;
+
+ w = KMSDRM_gbm_bo_get_width(bo);
+ h = KMSDRM_gbm_bo_get_height(bo);
+ stride = KMSDRM_gbm_bo_get_stride(bo);
+ handle = KMSDRM_gbm_bo_get_handle(bo).u32;
+
+ ret = KMSDRM_drmModeAddFB(vdata->drm_fd, w, h, 24, 32, stride, handle, &fb_info->fb_id);
+ if (ret < 0) {
+ free(fb_info);
+ return NULL;
+ }
+ SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "New DRM FB (%u): %ux%u, stride %u from BO %p", fb_info->fb_id, w, h, stride, (void *)bo);
+
+ /* Associate our DRM framebuffer with this buffer object */
+ KMSDRM_gbm_bo_set_user_data(bo, fb_info, KMSDRM_FBDestroyCallback);
+ return fb_info;
+}
+
+SDL_bool
+KMSDRM_WaitPageFlip(_THIS, SDL_WindowData *wdata, int timeout) {
+ SDL_VideoData *vdata = ((SDL_VideoData *)_this->driverdata);
+
+ while (wdata->waiting_for_flip) {
+ vdata->drm_pollfd.revents = 0;
+ if (poll(&vdata->drm_pollfd, 1, timeout) < 0) {
+ SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "DRM poll error");
+ return SDL_FALSE;
+ }
+
+ if (vdata->drm_pollfd.revents & (POLLHUP | POLLERR)) {
+ SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "DRM poll hup or error");
+ return SDL_FALSE;
+ }
+
+ if (vdata->drm_pollfd.revents & POLLIN) {
+ /* Page flip? If so, drmHandleEvent will unset wdata->waiting_for_flip */
+ KMSDRM_drmHandleEvent(vdata->drm_fd, &vdata->drm_evctx);
+ } else {
+ /* Timed out and page flip didn't happen */
+ SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Dropping frame while waiting_for_flip");
+ return SDL_FALSE;
+ }
+ }
+ return SDL_TRUE;
+}
+
+static void
+KMSDRM_FlipHandler(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void *data)
+{
+ *((SDL_bool *) data) = SDL_FALSE;
+}
+
+
+/*****************************************************************************/
+/* SDL Video and Display initialization/handling functions */
+/* _this is a SDL_VideoDevice * */
+/*****************************************************************************/
+int
+KMSDRM_VideoInit(_THIS)
+{
+ int i;
+ int ret = 0;
+ char *devname;
+ SDL_VideoData *vdata = ((SDL_VideoData *)_this->driverdata);
+ drmModeRes *resources = NULL;
+ drmModeConnector *connector = NULL;
+ drmModeEncoder *encoder = NULL;
+ SDL_DisplayMode current_mode;
+ SDL_VideoDisplay display;
+
+ /* Allocate display internal data */
+ SDL_DisplayData *data = (SDL_DisplayData *) SDL_calloc(1, sizeof(SDL_DisplayData));
+ if (data == NULL) {
+ return SDL_OutOfMemory();
+ }
+
+ SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "KMSDRM_VideoInit()");
+
+ /* Open /dev/dri/cardNN */
+ devname = (char *) SDL_calloc(1, 16);
+ if (devname == NULL) {
+ ret = SDL_OutOfMemory();
+ goto cleanup;
+ }
+ SDL_snprintf(devname, 16, "/dev/dri/card%d", vdata->devindex);
+ vdata->drm_fd = open(devname, O_RDWR | O_CLOEXEC);
+ SDL_free(devname);
+
+ if (vdata->drm_fd < 0) {
+ ret = SDL_SetError("Could not open /dev/dri/card%d.", vdata->devindex);
+ goto cleanup;
+ }
+ SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Opened DRM FD (%d)", vdata->drm_fd);
+
+ vdata->gbm = KMSDRM_gbm_create_device(vdata->drm_fd);
+ if (vdata->gbm == NULL) {
+ ret = SDL_SetError("Couldn't create gbm device.");
+ goto cleanup;
+ }
+
+ /* Find the first available connector with modes */
+ resources = KMSDRM_drmModeGetResources(vdata->drm_fd);
+ if (!resources) {
+ ret = SDL_SetError("drmModeGetResources(%d) failed", vdata->drm_fd);
+ goto cleanup;
+ }
+
+ for (i = 0; i < resources->count_connectors; i++) {
+ connector = KMSDRM_drmModeGetConnector(vdata->drm_fd, resources->connectors[i]);
+ if (connector == NULL)
+ continue;
+
+ if (connector->connection == DRM_MODE_CONNECTED &&
+ connector->count_modes > 0) {
+ SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Found connector %d with %d modes.",
+ connector->connector_id, connector->count_modes);
+ vdata->saved_conn_id = connector->connector_id;
+ break;
+ }
+
+ KMSDRM_drmModeFreeConnector(connector);
+ connector = NULL;
+ }
+
+ if (i == resources->count_connectors) {
+ ret = SDL_SetError("No currently active connector found.");
+ goto cleanup;
+ }
+
+ for (i = 0; i < resources->count_encoders; i++) {
+ encoder = KMSDRM_drmModeGetEncoder(vdata->drm_fd, resources->encoders[i]);
+
+ if (encoder == NULL)
+ continue;
+
+ if (encoder->encoder_id == connector->encoder_id) {
+ SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Found encoder %d.", encoder->encoder_id);
+ data->encoder_id = encoder->encoder_id;
+ break;
+ }
+
+ KMSDRM_drmModeFreeEncoder(encoder);
+ encoder = NULL;
+ }
+
+ if (i == resources->count_encoders) {
+ ret = SDL_SetError("No connected encoder found.");
+ goto cleanup;
+ }
+
+ vdata->saved_crtc = KMSDRM_drmModeGetCrtc(vdata->drm_fd, encoder->crtc_id);
+ if (vdata->saved_crtc == NULL) {
+ ret = SDL_SetError("No CRTC found.");
+ goto cleanup;
+ }
+ SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Saved crtc_id %u, fb_id %u, (%u,%u), %ux%u",
+ vdata->saved_crtc->crtc_id, vdata->saved_crtc->buffer_id, vdata->saved_crtc->x,
+ vdata->saved_crtc->y, vdata->saved_crtc->width, vdata->saved_crtc->height);
+ data->crtc_id = encoder->crtc_id;
+ data->cur_mode = vdata->saved_crtc->mode;
+ vdata->crtc_id = encoder->crtc_id;
+
+ SDL_zero(current_mode);
+
+ current_mode.w = vdata->saved_crtc->mode.hdisplay;
+ current_mode.h = vdata->saved_crtc->mode.vdisplay;
+ current_mode.refresh_rate = vdata->saved_crtc->mode.vrefresh;
+
+ /* FIXME ?
+ drmModeFB *fb = drmModeGetFB(vdata->drm_fd, vdata->saved_crtc->buffer_id);
+ current_mode.format = drmToSDLPixelFormat(fb->bpp, fb->depth);
+ drmModeFreeFB(fb);
+ */
+ current_mode.format = SDL_PIXELFORMAT_ARGB8888;
+
+ current_mode.driverdata = NULL;
+
+ SDL_zero(display);
+ display.desktop_mode = current_mode;
+ display.current_mode = current_mode;
+
+ display.driverdata = data;
+ /* SDL_VideoQuit will later SDL_free(display.driverdata) */
+ SDL_AddVideoDisplay(&display);
+
+ /* Setup page flip handler */
+ vdata->drm_pollfd.fd = vdata->drm_fd;
+ vdata->drm_pollfd.events = POLLIN;
+ vdata->drm_evctx.version = DRM_EVENT_CONTEXT_VERSION;
+ vdata->drm_evctx.page_flip_handler = KMSDRM_FlipHandler;
+
+#ifdef SDL_INPUT_LINUXEV
+ SDL_EVDEV_Init();
+#endif
+
+ KMSDRM_InitMouse(_this);
+
+cleanup:
+ if (encoder != NULL)
+ KMSDRM_drmModeFreeEncoder(encoder);
+ if (connector != NULL)
+ KMSDRM_drmModeFreeConnector(connector);
+ if (resources != NULL)
+ KMSDRM_drmModeFreeResources(resources);
+
+ if (ret != 0) {
+ /* Error (complete) cleanup */
+ SDL_free(data);
+ if(vdata->saved_crtc != NULL) {
+ KMSDRM_drmModeFreeCrtc(vdata->saved_crtc);
+ vdata->saved_crtc = NULL;
+ }
+ if (vdata->gbm != NULL) {
+ KMSDRM_gbm_device_destroy(vdata->gbm);
+ vdata->gbm = NULL;
+ }
+ if (vdata->drm_fd >= 0) {
+ close(vdata->drm_fd);
+ vdata->drm_fd = -1;
+ }
+ }
+ return ret;
+}
+
+void
+KMSDRM_VideoQuit(_THIS)
+{
+ SDL_VideoData *vdata = ((SDL_VideoData *)_this->driverdata);
+
+ SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "KMSDRM_VideoQuit()");
+
+ if (_this->gl_config.driver_loaded) {
+ SDL_GL_UnloadLibrary();
+ }
+
+ if(vdata->saved_crtc != NULL) {
+ if(vdata->drm_fd > 0 && vdata->saved_conn_id > 0) {
+ /* Restore saved CRTC settings */
+ drmModeCrtc *crtc = vdata->saved_crtc;
+ if(KMSDRM_drmModeSetCrtc(vdata->drm_fd, crtc->crtc_id, crtc->buffer_id,
+ crtc->x, crtc->y, &vdata->saved_conn_id, 1,
+ &crtc->mode) != 0) {
+ SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "Could not restore original CRTC mode");
+ }
+ }
+ KMSDRM_drmModeFreeCrtc(vdata->saved_crtc);
+ vdata->saved_crtc = NULL;
+ }
+ if (vdata->gbm != NULL) {
+ KMSDRM_gbm_device_destroy(vdata->gbm);
+ vdata->gbm = NULL;
+ }
+ if (vdata->drm_fd >= 0) {
+ close(vdata->drm_fd);
+ SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Closed DRM FD %d", vdata->drm_fd);
+ vdata->drm_fd = -1;
+ }
+#ifdef SDL_INPUT_LINUXEV
+ SDL_EVDEV_Quit();
+#endif
+}
+
+void
+KMSDRM_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
+{
+ /* Only one display mode available, the current one */
+ SDL_AddDisplayMode(display, &display->current_mode);
+}
+
+int
+KMSDRM_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
+{
+ return 0;
+}
+
+int
+KMSDRM_CreateWindow(_THIS, SDL_Window * window)
+{
+ SDL_WindowData *wdata;
+ SDL_VideoDisplay *display;
+ SDL_VideoData *vdata = ((SDL_VideoData *)_this->driverdata);
+ Uint32 surface_fmt, surface_flags;
+
+ /* Allocate window internal data */
+ wdata = (SDL_WindowData *) SDL_calloc(1, sizeof(SDL_WindowData));
+ if (wdata == NULL) {
+ SDL_OutOfMemory();
+ goto error;
+ }
+
+ wdata->waiting_for_flip = SDL_FALSE;
+ display = SDL_GetDisplayForWindow(window);
+
+ /* Windows have one size for now */
+ window->w = display->desktop_mode.w;
+ window->h = display->desktop_mode.h;
+
+ /* Maybe you didn't ask for a fullscreen OpenGL window, but that's what you get */
+ window->flags |= (SDL_WINDOW_FULLSCREEN | SDL_WINDOW_OPENGL);
+
+ surface_fmt = GBM_FORMAT_XRGB8888;
+ surface_flags = GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING;
+
+ if (!KMSDRM_gbm_device_is_format_supported(vdata->gbm, surface_fmt, surface_flags)) {
+ SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "GBM surface format not supported. Trying anyway.");
+ }
+ wdata->gs = KMSDRM_gbm_surface_create(vdata->gbm, window->w, window->h, surface_fmt, surface_flags);
+
+#if SDL_VIDEO_OPENGL_EGL
+ if (!_this->egl_data) {
+ if (SDL_GL_LoadLibrary(NULL) < 0) {
+ goto error;
+ }
+ }
+ wdata->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) wdata->gs);
+
+ if (wdata->egl_surface == EGL_NO_SURFACE) {
+ SDL_SetError("Could not create EGL window surface");
+ goto error;
+ }
+#endif /* SDL_VIDEO_OPENGL_EGL */
+
+ /* In case we want low-latency, double-buffer video, we take note here */
+ wdata->double_buffer = SDL_FALSE;
+ if (SDL_GetHintBoolean(SDL_HINT_VIDEO_DOUBLE_BUFFER, SDL_FALSE)) {
+ wdata->double_buffer = SDL_TRUE;
+ }
+
+ /* Window is created, but we have yet to set up CRTC to one of the GBM buffers if we want
+ drmModePageFlip to work, and we can't do it until EGL is completely setup, because we
+ need to do eglSwapBuffers so we can get a valid GBM buffer object to call
+ drmModeSetCrtc on it. */
+ wdata->crtc_ready = SDL_FALSE;
+
+ /* Setup driver data for this window */
+ window->driverdata = wdata;
+
+ /* One window, it always has focus */
+ SDL_SetMouseFocus(window);
+ SDL_SetKeyboardFocus(window);
+
+ /* Window has been successfully created */
+ return 0;
+
+error:
+ if (wdata != NULL) {
+#if SDL_VIDEO_OPENGL_EGL
+ if (wdata->egl_surface != EGL_NO_SURFACE)
+ SDL_EGL_DestroySurface(_this, wdata->egl_surface);
+#endif /* SDL_VIDEO_OPENGL_EGL */
+ if (wdata->gs != NULL)
+ KMSDRM_gbm_surface_destroy(wdata->gs);
+ SDL_free(wdata);
+ }
+ return -1;
+}
+
+void
+KMSDRM_DestroyWindow(_THIS, SDL_Window * window)
+{
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ if(data) {
+ /* Wait for any pending page flips and unlock buffer */
+ KMSDRM_WaitPageFlip(_this, data, -1);
+ if (data->crtc_bo != NULL) {
+ KMSDRM_gbm_surface_release_buffer(data->gs, data->crtc_bo);
+ data->crtc_bo = NULL;
+ }
+ if (data->next_bo != NULL) {
+ KMSDRM_gbm_surface_release_buffer(data->gs, data->next_bo);
+ data->next_bo = NULL;
+ }
+ if (data->current_bo != NULL) {
+ KMSDRM_gbm_surface_release_buffer(data->gs, data->current_bo);
+ data->current_bo = NULL;
+ }
+#if SDL_VIDEO_OPENGL_EGL
+ SDL_EGL_MakeCurrent(_this, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ if (data->egl_surface != EGL_NO_SURFACE) {
+ SDL_EGL_DestroySurface(_this, data->egl_surface);
+ }
+#endif /* SDL_VIDEO_OPENGL_EGL */
+ if (data->gs != NULL) {
+ KMSDRM_gbm_surface_destroy(data->gs);
+ data->gs = NULL;
+ }
+ SDL_free(data);
+ window->driverdata = NULL;
+ }
+}
+
+int
+KMSDRM_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
+{
+ return -1;
+}
+
+void
+KMSDRM_SetWindowTitle(_THIS, SDL_Window * window)
+{
+}
+void
+KMSDRM_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon)
+{
+}
+void
+KMSDRM_SetWindowPosition(_THIS, SDL_Window * window)
+{
+}
+void
+KMSDRM_SetWindowSize(_THIS, SDL_Window * window)
+{
+}
+void
+KMSDRM_ShowWindow(_THIS, SDL_Window * window)
+{
+}
+void
+KMSDRM_HideWindow(_THIS, SDL_Window * window)
+{
+}
+void
+KMSDRM_RaiseWindow(_THIS, SDL_Window * window)
+{
+}
+void
+KMSDRM_MaximizeWindow(_THIS, SDL_Window * window)
+{
+}
+void
+KMSDRM_MinimizeWindow(_THIS, SDL_Window * window)
+{
+}
+void
+KMSDRM_RestoreWindow(_THIS, SDL_Window * window)
+{
+}
+void
+KMSDRM_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
+{
+
+}
+
+/*****************************************************************************/
+/* SDL Window Manager function */
+/*****************************************************************************/
+SDL_bool
+KMSDRM_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info)
+{
+ if (info->version.major <= SDL_MAJOR_VERSION) {
+ return SDL_TRUE;
+ } else {
+ SDL_SetError("application not compiled with SDL %d.%d\n",
+ SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
+ return SDL_FALSE;
+ }
+
+ /* Failed to get window manager information */
+ return SDL_FALSE;
+}
+
+#endif /* SDL_VIDEO_DRIVER_KMSDRM */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmvideo.h b/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmvideo.h
new file mode 100644
index 0000000..34f0b10
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/kmsdrm/SDL_kmsdrmvideo.h
@@ -0,0 +1,125 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "../../SDL_internal.h"
+
+#ifndef __SDL_KMSDRMVIDEO_H__
+#define __SDL_KMSDRMVIDEO_H__
+
+#include "../SDL_sysvideo.h"
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <poll.h>
+#include <xf86drm.h>
+#include <xf86drmMode.h>
+#include <gbm.h>
+#if SDL_VIDEO_OPENGL_EGL
+#include <EGL/egl.h>
+#endif
+
+typedef struct SDL_VideoData
+{
+ int devindex; /* device index that was passed on creation */
+ int drm_fd; /* DRM file desc */
+ struct gbm_device *gbm;
+ drmEventContext drm_evctx; /* DRM event context */
+ struct pollfd drm_pollfd; /* pollfd containing DRM file desc */
+ drmModeCrtc *saved_crtc; /* Saved CRTC to restore on quit */
+ uint32_t saved_conn_id; /* Saved DRM connector ID */
+ uint32_t crtc_id; /* CRTC in use */
+} SDL_VideoData;
+
+
+typedef struct SDL_DisplayData
+{
+ uint32_t encoder_id;
+ uint32_t crtc_id;
+ drmModeModeInfo cur_mode;
+} SDL_DisplayData;
+
+
+typedef struct SDL_WindowData
+{
+ struct gbm_surface *gs;
+ struct gbm_bo *current_bo;
+ struct gbm_bo *next_bo;
+ struct gbm_bo *crtc_bo;
+ SDL_bool waiting_for_flip;
+ SDL_bool crtc_ready;
+ SDL_bool double_buffer;
+#if SDL_VIDEO_OPENGL_EGL
+ EGLSurface egl_surface;
+#endif
+} SDL_WindowData;
+
+typedef struct KMSDRM_FBInfo
+{
+ int drm_fd; /* DRM file desc */
+ uint32_t fb_id; /* DRM framebuffer ID */
+} KMSDRM_FBInfo;
+
+/* Helper functions */
+KMSDRM_FBInfo *KMSDRM_FBFromBO(_THIS, struct gbm_bo *bo);
+SDL_bool KMSDRM_WaitPageFlip(_THIS, SDL_WindowData *wdata, int timeout);
+
+/****************************************************************************/
+/* SDL_VideoDevice functions declaration */
+/****************************************************************************/
+
+/* Display and window functions */
+int KMSDRM_VideoInit(_THIS);
+void KMSDRM_VideoQuit(_THIS);
+void KMSDRM_GetDisplayModes(_THIS, SDL_VideoDisplay * display);
+int KMSDRM_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode);
+int KMSDRM_CreateWindow(_THIS, SDL_Window * window);
+int KMSDRM_CreateWindowFrom(_THIS, SDL_Window * window, const void *data);
+void KMSDRM_SetWindowTitle(_THIS, SDL_Window * window);
+void KMSDRM_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon);
+void KMSDRM_SetWindowPosition(_THIS, SDL_Window * window);
+void KMSDRM_SetWindowSize(_THIS, SDL_Window * window);
+void KMSDRM_ShowWindow(_THIS, SDL_Window * window);
+void KMSDRM_HideWindow(_THIS, SDL_Window * window);
+void KMSDRM_RaiseWindow(_THIS, SDL_Window * window);
+void KMSDRM_MaximizeWindow(_THIS, SDL_Window * window);
+void KMSDRM_MinimizeWindow(_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);
+
+/* Window manager function */
+SDL_bool KMSDRM_GetWindowWMInfo(_THIS, SDL_Window * window,
+ struct SDL_SysWMinfo *info);
+
+/* OpenGL/OpenGL ES functions */
+int KMSDRM_GLES_LoadLibrary(_THIS, const char *path);
+void *KMSDRM_GLES_GetProcAddress(_THIS, const char *proc);
+void KMSDRM_GLES_UnloadLibrary(_THIS);
+SDL_GLContext KMSDRM_GLES_CreateContext(_THIS, SDL_Window * window);
+int KMSDRM_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context);
+int KMSDRM_GLES_SetSwapInterval(_THIS, int interval);
+int KMSDRM_GLES_GetSwapInterval(_THIS);
+int KMSDRM_GLES_SwapWindow(_THIS, SDL_Window * window);
+void KMSDRM_GLES_DeleteContext(_THIS, SDL_GLContext context);
+
+#endif /* __SDL_KMSDRMVIDEO_H__ */
+
+/* vi: set ts=4 sw=4 expandtab: */