diff --git a/CMakeLists.txt b/CMakeLists.txt index 7524693683..d7bcfea28f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -310,7 +310,7 @@ set_option(SDL_RPATH "Use an rpath when linking SDL" ${SDL_RPATH_D set_option(SDL_CLOCK_GETTIME "Use clock_gettime() instead of gettimeofday()" ${SDL_CLOCK_GETTIME_DEFAULT}) dep_option(SDL_X11 "Use X11 video driver" ${UNIX_SYS} "SDL_VIDEO" OFF) dep_option(SDL_X11_SHARED "Dynamically load X11 support" ON "SDL_X11" OFF) -set(SDL_X11_OPTIONS Xcursor Xdbe XInput Xfixes Xrandr Xscrnsaver XShape) +set(SDL_X11_OPTIONS Xcursor Xdbe XInput Xfixes Xrandr Xscrnsaver XShape Xsync) foreach(_SUB ${SDL_X11_OPTIONS}) string(TOUPPER "SDL_X11_${_SUB}" _OPT) dep_option(${_OPT} "Enable ${_SUB} support" ON "SDL_X11" OFF) diff --git a/cmake/sdlchecks.cmake b/cmake/sdlchecks.cmake index 4efdf86ab9..c0bdabc400 100644 --- a/cmake/sdlchecks.cmake +++ b/cmake/sdlchecks.cmake @@ -307,6 +307,7 @@ macro(CheckX11) find_file(HAVE_XRANDR_H NAMES "X11/extensions/Xrandr.h" HINTS "${X11_INCLUDEDIR}") find_file(HAVE_XFIXES_H_ NAMES "X11/extensions/Xfixes.h" HINTS "${X11_INCLUDEDIR}") find_file(HAVE_XRENDER_H NAMES "X11/extensions/Xrender.h" HINTS "${X11_INCLUDEDIR}") + find_file(HAVE_XSYNC_H NAMES "X11/extensions/sync.h" HINTS "${X11_INCLUDEDIR}") find_file(HAVE_XSS_H NAMES "X11/extensions/scrnsaver.h" HINTS "${X11_INCLUDEDIR}") find_file(HAVE_XSHAPE_H NAMES "X11/extensions/shape.h" HINTS "${X11_INCLUDEDIR}") find_file(HAVE_XDBE_H NAMES "X11/extensions/Xdbe.h" HINTS "${X11_INCLUDEDIR}") @@ -445,6 +446,11 @@ macro(CheckX11) set(HAVE_X11_XFIXES TRUE) endif() + if(SDL_X11_XSYNC AND HAVE_XSYNC_H AND XEXT_LIB) + set(SDL_VIDEO_DRIVER_X11_XSYNC 1) + set(HAVE_X11_XSYNC TRUE) + endif() + if(SDL_X11_XRANDR AND HAVE_XRANDR_H AND XRANDR_LIB) if(HAVE_X11_SHARED) set(SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR "\"${XRANDR_LIB_SONAME}\"") diff --git a/include/build_config/SDL_build_config.h.cmake b/include/build_config/SDL_build_config.h.cmake index 044ef47123..2a5bdf1035 100644 --- a/include/build_config/SDL_build_config.h.cmake +++ b/include/build_config/SDL_build_config.h.cmake @@ -424,6 +424,7 @@ #cmakedefine SDL_VIDEO_DRIVER_X11_XRANDR @SDL_VIDEO_DRIVER_X11_XRANDR@ #cmakedefine SDL_VIDEO_DRIVER_X11_XSCRNSAVER @SDL_VIDEO_DRIVER_X11_XSCRNSAVER@ #cmakedefine SDL_VIDEO_DRIVER_X11_XSHAPE @SDL_VIDEO_DRIVER_X11_XSHAPE@ +#cmakedefine SDL_VIDEO_DRIVER_X11_XSYNC @SDL_VIDEO_DRIVER_X11_XSYNC@ #cmakedefine SDL_VIDEO_DRIVER_QNX @SDL_VIDEO_DRIVER_QNX@ #cmakedefine SDL_VIDEO_RENDER_D3D @SDL_VIDEO_RENDER_D3D@ diff --git a/src/video/x11/SDL_x11dyn.h b/src/video/x11/SDL_x11dyn.h index 8c9757be6b..9897b4f730 100644 --- a/src/video/x11/SDL_x11dyn.h +++ b/src/video/x11/SDL_x11dyn.h @@ -59,6 +59,9 @@ #ifdef SDL_VIDEO_DRIVER_X11_XFIXES #include #endif +#ifdef SDL_VIDEO_DRIVER_X11_XSYNC +#include +#endif #ifdef SDL_VIDEO_DRIVER_X11_XRANDR #include #endif diff --git a/src/video/x11/SDL_x11events.c b/src/video/x11/SDL_x11events.c index c6dee1d638..9b26bf092e 100644 --- a/src/video/x11/SDL_x11events.c +++ b/src/video/x11/SDL_x11events.c @@ -35,6 +35,7 @@ #include "SDL_x11xfixes.h" #include "SDL_x11settings.h" #include "../SDL_clipboard_c.h" +#include "SDL_x11xsync.h" #include "../../core/unix/SDL_poll.h" #include "../../events/SDL_events_c.h" #include "../../events/SDL_mouse_c.h" @@ -1376,6 +1377,11 @@ static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent) } } } + +#ifdef SDL_VIDEO_DRIVER_X11_XSYNC + X11_HandleConfigure(data->window, &xevent->xconfigure); +#endif /* SDL_VIDEO_DRIVER_X11_XSYNC */ + if (xevent->xconfigure.width != data->last_xconfigure.width || xevent->xconfigure.height != data->last_xconfigure.height) { if (!data->disable_size_position_events) { @@ -1501,6 +1507,17 @@ static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent) #endif SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_CLOSE_REQUESTED, 0, 0); break; + } else if ((xevent->xclient.message_type == videodata->atoms.WM_PROTOCOLS) && + (xevent->xclient.format == 32) && + (xevent->xclient.data.l[0] == videodata->atoms._NET_WM_SYNC_REQUEST)) { + +#ifdef DEBUG_XEVENTS + printf("window %p: _NET_WM_SYNC_REQUEST\n", data); +#endif +#ifdef SDL_VIDEO_DRIVER_X11_XSYNC + X11_HandleSyncRequest(data->window, &xevent->xclient); +#endif /* SDL_VIDEO_DRIVER_X11_XSYNC */ + break; } } break; diff --git a/src/video/x11/SDL_x11framebuffer.c b/src/video/x11/SDL_x11framebuffer.c index 948694af64..a586ba4a95 100644 --- a/src/video/x11/SDL_x11framebuffer.c +++ b/src/video/x11/SDL_x11framebuffer.c @@ -24,6 +24,7 @@ #include "SDL_x11video.h" #include "SDL_x11framebuffer.h" +#include "SDL_x11xsync.h" #ifndef NO_SHARED_MEMORY @@ -216,6 +217,10 @@ bool X11_UpdateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window, con } } +#ifdef SDL_VIDEO_DRIVER_X11_XSYNC + X11_HandlePresent(data->window); +#endif /* SDL_VIDEO_DRIVER_X11_XSYNC */ + X11_XSync(display, False); return true; diff --git a/src/video/x11/SDL_x11messagebox.c b/src/video/x11/SDL_x11messagebox.c index f2a5e59c33..2ecaa346e7 100644 --- a/src/video/x11/SDL_x11messagebox.c +++ b/src/video/x11/SDL_x11messagebox.c @@ -459,10 +459,11 @@ static bool X11_MessageBoxCreateWindow(SDL_MessageBoxDataX11 *data) (unsigned char *)&_NET_WM_WINDOW_TYPE_DIALOG, 1); // Allow the window to be deleted by the window manager - data->wm_protocols = X11_XInternAtom(display, "WM_PROTOCOLS", False); data->wm_delete_message = X11_XInternAtom(display, "WM_DELETE_WINDOW", False); X11_XSetWMProtocols(display, data->window, &data->wm_delete_message, 1); + data->wm_protocols = X11_XInternAtom(display, "WM_PROTOCOLS", False); + if (windowdata) { XWindowAttributes attrib; Window dummy; diff --git a/src/video/x11/SDL_x11opengl.c b/src/video/x11/SDL_x11opengl.c index 888c489242..e64d2f340d 100644 --- a/src/video/x11/SDL_x11opengl.c +++ b/src/video/x11/SDL_x11opengl.c @@ -24,6 +24,7 @@ #ifdef SDL_VIDEO_DRIVER_X11 #include "SDL_x11video.h" +#include "SDL_x11xsync.h" // GLX implementation of SDL OpenGL support @@ -1089,6 +1090,11 @@ bool X11_GL_SwapWindow(SDL_VideoDevice *_this, SDL_Window *window) Display *display = data->videodata->display; _this->gl_data->glXSwapBuffers(display, data->xwindow); + +#ifdef SDL_VIDEO_DRIVER_X11_XSYNC + X11_HandlePresent(data->window); +#endif /* SDL_VIDEO_DRIVER_X11_XSYNC */ + return true; } diff --git a/src/video/x11/SDL_x11opengles.c b/src/video/x11/SDL_x11opengles.c index caa2d0c4e4..56afa61575 100644 --- a/src/video/x11/SDL_x11opengles.c +++ b/src/video/x11/SDL_x11opengles.c @@ -25,6 +25,7 @@ #include "SDL_x11video.h" #include "SDL_x11opengles.h" #include "SDL_x11opengl.h" +#include "SDL_x11xsync.h" // EGL implementation of SDL OpenGL support @@ -134,7 +135,18 @@ SDL_EGLSurface X11_GLES_GetEGLSurface(SDL_VideoDevice *_this, SDL_Window *window return data->egl_surface; } -SDL_EGL_SwapWindow_impl(X11) +bool X11_GLES_SwapWindow(SDL_VideoDevice *_this, SDL_Window *window) +{ + const bool ret = SDL_EGL_SwapBuffers(_this, window->internal->egl_surface); \ + +#ifdef SDL_VIDEO_DRIVER_X11_XSYNC + X11_HandlePresent(window); +#endif /* SDL_VIDEO_DRIVER_X11_XSYNC */ + + return ret; +} + SDL_EGL_MakeCurrent_impl(X11) #endif // SDL_VIDEO_DRIVER_X11 && SDL_VIDEO_OPENGL_EGL + diff --git a/src/video/x11/SDL_x11sym.h b/src/video/x11/SDL_x11sym.h index b763d7dfb9..a84773db6d 100644 --- a/src/video/x11/SDL_x11sym.h +++ b/src/video/x11/SDL_x11sym.h @@ -173,6 +173,15 @@ SDL_X11_SYM(Status, XFixesQueryVersion,(Display* a, int* b, int* c), (a,b,c), re SDL_X11_SYM(Status, XFixesSelectSelectionInput, (Display* a, Window b, Atom c, unsigned long d), (a,b,c,d), return) #endif +#ifdef SDL_VIDEO_DRIVER_X11_XSYNC +SDL_X11_MODULE(XSYNC) +SDL_X11_SYM(Status, XSyncQueryExtension, (Display* a, int* b, int* c), (a, b, c), return) +SDL_X11_SYM(Status, XSyncInitialize, (Display* a, int* b, int* c), (a, b, c), return) +SDL_X11_SYM(XSyncCounter, XSyncCreateCounter, (Display* a, XSyncValue b), (a, b), return) +SDL_X11_SYM(Status, XSyncDestroyCounter, (Display* a, XSyncCounter b), (a, b), return) +SDL_X11_SYM(Status, XSyncSetCounter, (Display* a, XSyncCounter b, XSyncValue c), (a, b, c), return) +#endif + #ifdef SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS SDL_X11_SYM(Bool,XGetEventData,(Display* a,XGenericEventCookie* b),(a,b),return) SDL_X11_SYM(void,XFreeEventData,(Display* a,XGenericEventCookie* b),(a,b),) diff --git a/src/video/x11/SDL_x11video.c b/src/video/x11/SDL_x11video.c index 5e9774ee03..275bd4dbf6 100644 --- a/src/video/x11/SDL_x11video.c +++ b/src/video/x11/SDL_x11video.c @@ -38,6 +38,7 @@ #include "SDL_x11xinput2.h" #include "SDL_x11messagebox.h" #include "SDL_x11shape.h" +#include "SDL_x11xsync.h" #ifdef SDL_VIDEO_OPENGL_EGL #include "SDL_x11opengles.h" @@ -377,6 +378,8 @@ static bool X11_VideoInit(SDL_VideoDevice *_this) GET_ATOM(_NET_WM_ICON_NAME); GET_ATOM(_NET_WM_ICON); GET_ATOM(_NET_WM_PING); + GET_ATOM(_NET_WM_SYNC_REQUEST); + GET_ATOM(_NET_WM_SYNC_REQUEST_COUNTER); GET_ATOM(_NET_WM_WINDOW_OPACITY); GET_ATOM(_NET_WM_USER_TIME); GET_ATOM(_NET_ACTIVE_WINDOW); @@ -420,6 +423,10 @@ static bool X11_VideoInit(SDL_VideoDevice *_this) X11_InitXsettings(_this); +#ifdef SDL_VIDEO_DRIVER_X11_XSYNC + X11_InitXsync(_this); +#endif /* SDL_VIDEO_DRIVER_X11_XSYNC */ + #ifndef X_HAVE_UTF8_STRING #warning X server does not support UTF8_STRING, a feature introduced in 2000! This is likely to become a hard error in a future libSDL3. #endif diff --git a/src/video/x11/SDL_x11video.h b/src/video/x11/SDL_x11video.h index 09dfe854c7..cfb864a2f3 100644 --- a/src/video/x11/SDL_x11video.h +++ b/src/video/x11/SDL_x11video.h @@ -89,6 +89,8 @@ struct SDL_VideoData Atom _NET_WM_ICON_NAME; Atom _NET_WM_ICON; Atom _NET_WM_PING; + Atom _NET_WM_SYNC_REQUEST; + Atom _NET_WM_SYNC_REQUEST_COUNTER; Atom _NET_WM_WINDOW_OPACITY; Atom _NET_WM_USER_TIME; Atom _NET_ACTIVE_WINDOW; diff --git a/src/video/x11/SDL_x11window.c b/src/video/x11/SDL_x11window.c index 5802a2eaa9..130bda3135 100644 --- a/src/video/x11/SDL_x11window.c +++ b/src/video/x11/SDL_x11window.c @@ -38,6 +38,8 @@ #include "SDL_x11opengles.h" #endif +#include "SDL_x11xsync.h" + #define _NET_WM_STATE_REMOVE 0l #define _NET_WM_STATE_ADD 1l @@ -509,6 +511,7 @@ bool X11_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_Properties } const bool force_override_redirect = SDL_GetHintBoolean(SDL_HINT_X11_FORCE_OVERRIDE_REDIRECT, false); + const bool use_resize_sync = (window->flags & SDL_WINDOW_VULKAN); /* doesn't work well with Vulkan */ SDL_WindowData *windowdata; Display *display = data->display; int screen = displaydata->screen; @@ -770,7 +773,7 @@ bool X11_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_Properties } { - Atom protocols[3]; + Atom protocols[4]; int proto_count = 0; protocols[proto_count++] = data->atoms.WM_DELETE_WINDOW; // Allow window to be deleted by the WM @@ -781,6 +784,12 @@ bool X11_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_Properties protocols[proto_count++] = data->atoms._NET_WM_PING; // Respond so WM knows we're alive } +#ifdef SDL_VIDEO_DRIVER_X11_XSYNC + if (use_resize_sync) { + protocols[proto_count++] = data->atoms._NET_WM_SYNC_REQUEST; /* Respond after completing resize */ + } +#endif /* SDL_VIDEO_DRIVER_X11_XSYNC */ + SDL_assert(proto_count <= sizeof(protocols) / sizeof(protocols[0])); X11_XSetWMProtocols(display, w, protocols, proto_count); @@ -801,6 +810,12 @@ bool X11_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_Properties windowdata->fullscreen_borders_forced_on = !!(window->pending_flags & SDL_WINDOW_FULLSCREEN) && !!(window->flags & SDL_WINDOW_BORDERLESS); +#ifdef SDL_VIDEO_DRIVER_X11_XSYNC + if (use_resize_sync) { + X11_InitResizeSync(window); + } +#endif /* SDL_VIDEO_DRIVER_X11_XSYNC */ + #if defined(SDL_VIDEO_OPENGL_ES) || defined(SDL_VIDEO_OPENGL_ES2) || defined(SDL_VIDEO_OPENGL_EGL) if ((window->flags & SDL_WINDOW_OPENGL) && ((_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES) || @@ -1976,6 +1991,11 @@ void X11_DestroyWindow(SDL_VideoDevice *_this, SDL_Window *window) X11_XDestroyIC(data->ic); } #endif + +#ifdef SDL_VIDEO_DRIVER_X11_XSYNC + X11_TermResizeSync(window); +#endif /* SDL_VIDEO_DRIVER_X11_XSYNC */ + if (!(window->flags & SDL_WINDOW_EXTERNAL)) { X11_XDestroyWindow(display, data->xwindow); X11_XFlush(display); diff --git a/src/video/x11/SDL_x11window.h b/src/video/x11/SDL_x11window.h index d867255ba7..251ae677bc 100644 --- a/src/video/x11/SDL_x11window.h +++ b/src/video/x11/SDL_x11window.h @@ -83,6 +83,12 @@ struct SDL_WindowData PointerBarrier barrier[4]; SDL_Rect barrier_rect; #endif // SDL_VIDEO_DRIVER_X11_XFIXES +#ifdef SDL_VIDEO_DRIVER_X11_XSYNC + XSyncCounter resize_counter; + XSyncValue resize_id; + bool resize_in_progress; +#endif /* SDL_VIDEO_DRIVER_X11_XSYNC */ + SDL_Rect expected; SDL_DisplayMode requested_fullscreen_mode; diff --git a/src/video/x11/SDL_x11xsync.c b/src/video/x11/SDL_x11xsync.c new file mode 100644 index 0000000000..ada1ce39f0 --- /dev/null +++ b/src/video/x11/SDL_x11xsync.c @@ -0,0 +1,148 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2023 Sam Lantinga + + 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 defined(SDL_VIDEO_DRIVER_X11) && defined(SDL_VIDEO_DRIVER_X11_XSYNC) + +#include "SDL_x11video.h" +#include "SDL_x11xsync.h" + +static int xsync_initialized = 0; + +static int query_xsync_version(Display *display, int major, int minor) +{ + /* We don't care if this fails, so long as it sets major/minor on it's way out the door. */ + X11_XSyncInitialize(display, &major, &minor); + return (major * 1000) + minor; +} + +static bool xsync_version_atleast(const int version, const int wantmajor, const int wantminor) +{ + return version >= ((wantmajor * 1000) + wantminor); +} + +void X11_InitXsync(SDL_VideoDevice *_this) +{ + SDL_VideoData *data = (SDL_VideoData *) _this->internal; + + int version = 0; + int event, error; + int sync_opcode; + + if (!SDL_X11_HAVE_XSYNC || + !X11_XQueryExtension(data->display, "SYNC", &sync_opcode, &event, &error)) { + return; + } + + /* We need at least 5.0 for barriers. */ + version = query_xsync_version(data->display, 5, 0); + if (!xsync_version_atleast(version, 3, 0)) { + return; /* X server does not support the version we want at all. */ + } + + xsync_initialized = 1; +} + +int X11_XsyncIsInitialized(void) +{ + return xsync_initialized; +} + +int X11_InitResizeSync(SDL_Window *window) +{ + SDL_assert(window != NULL); + SDL_WindowData *data = (SDL_WindowData *) window->internal; + Display *display = data->videodata->display; + Atom counter_prop = data->videodata->atoms._NET_WM_SYNC_REQUEST_COUNTER; + XSyncCounter counter; + CARD32 counter_id; + + if (!X11_XsyncIsInitialized()){ + return SDL_Unsupported(); + } + + counter = X11_XSyncCreateCounter(display, (XSyncValue){0, 0}); + data->resize_counter = counter; + data->resize_id.lo = 0; + data->resize_id.hi = 0; + data->resize_in_progress = false; + + if (counter == None){ + return SDL_Unsupported(); + } + + counter_id = counter; + X11_XChangeProperty(display, data->xwindow, counter_prop, XA_CARDINAL, 32, + PropModeReplace, (unsigned char *)&counter_id, 1); + + return 0; +} + +void X11_TermResizeSync(SDL_Window *window) +{ + SDL_WindowData *data = (SDL_WindowData *) window->internal; + Display *display = data->videodata->display; + Atom counter_prop = data->videodata->atoms._NET_WM_SYNC_REQUEST_COUNTER; + XSyncCounter counter = data->resize_counter; + + X11_XDeleteProperty(display, data->xwindow, counter_prop); + if (counter != None) { + X11_XSyncDestroyCounter(display, counter); + } +} + +void X11_HandleSyncRequest(SDL_Window *window, XClientMessageEvent *event) +{ + SDL_WindowData *data = (SDL_WindowData *) window->internal; + + data->resize_id.lo = event->data.l[2]; + data->resize_id.hi = event->data.l[3]; + data->resize_in_progress = false; +} + +void X11_HandleConfigure(SDL_Window *window, XConfigureEvent *event) +{ + SDL_WindowData *data = (SDL_WindowData *) window->internal; + + if (data->resize_id.lo || data->resize_id.hi) { + data->resize_in_progress = true; + } +} + +void X11_HandlePresent(SDL_Window *window) +{ + SDL_WindowData *data = (SDL_WindowData *) window->internal; + Display *display = data->videodata->display; + XSyncCounter counter = data->resize_counter; + + if ((counter == None) || (!data->resize_in_progress)) { + return; + } + + X11_XSyncSetCounter(display, counter, data->resize_id); + + data->resize_id.lo = 0; + data->resize_id.hi = 0; + data->resize_in_progress = false; +} + +#endif /* SDL_VIDEO_DRIVER_X11 && SDL_VIDEO_DRIVER_X11_XSYNC */ diff --git a/src/video/x11/SDL_x11xsync.h b/src/video/x11/SDL_x11xsync.h new file mode 100644 index 0000000000..610e892e08 --- /dev/null +++ b/src/video/x11/SDL_x11xsync.h @@ -0,0 +1,39 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2023 Sam Lantinga + + 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_x11xsync_h_ +#define SDL_x11xsync_h_ + +#ifdef SDL_VIDEO_DRIVER_X11_XSYNC + +extern void X11_InitXsync(SDL_VideoDevice *_this); +extern int X11_XsyncIsInitialized(void); +int X11_InitResizeSync(SDL_Window *window); +void X11_TermResizeSync(SDL_Window *window); +void X11_HandleSyncRequest(SDL_Window *window, XClientMessageEvent *event); +void X11_HandleConfigure(SDL_Window *window, XConfigureEvent *event); +void X11_HandlePresent(SDL_Window *window); + +#endif /* SDL_VIDEO_DRIVER_X11_XSYNC */ + +#endif /* SDL_x11xsync_h_ */