diff --git a/lib/framework/wzapp.h b/lib/framework/wzapp.h index 3846201f4..0062ef6f9 100644 --- a/lib/framework/wzapp.h +++ b/lib/framework/wzapp.h @@ -45,8 +45,8 @@ bool wzActiveWindow(void); ///< Whether application currently has the mouse poin int wzGetTicks(void); ///< Milliseconds since start of game void wzFatalDialog(const char *text); ///< Throw up a modal warning dialog QList wzAvailableResolutions(); ///< Get list of available resolutions. -void wzSetSwapInterval(bool swap); -bool wzGetSwapInterval(); +void wzSetSwapInterval(int swap); +int wzGetSwapInterval(); QString wzGetSelection(); // Thread related diff --git a/lib/qtgame/main_qt.cpp b/lib/qtgame/main_qt.cpp index 22425aac4..d2cbe495f 100644 --- a/lib/qtgame/main_qt.cpp +++ b/lib/qtgame/main_qt.cpp @@ -104,12 +104,12 @@ QList wzAvailableResolutions() return WzMainWindow::instance()->availableResolutions(); } -void wzSetSwapInterval(bool swap) +void wzSetSwapInterval(int swap) { WzMainWindow::instance()->setSwapInterval(swap); } -bool wzGetSwapInterval() +int wzGetSwapInterval() { - return WzMainWindow::instance()->swapInterval() > 0; + return WzMainWindow::instance()->swapInterval(); } diff --git a/lib/sdl/main_sdl.cpp b/lib/sdl/main_sdl.cpp index bb7f47b74..a9b6bd0cc 100644 --- a/lib/sdl/main_sdl.cpp +++ b/lib/sdl/main_sdl.cpp @@ -108,16 +108,177 @@ QString wzGetSelection() return retval; } -void wzSetSwapInterval(bool swap) + +#if defined(WZ_WS_X11) + +#include // GLXDrawable +// X11 polution +#ifdef Status +#undef Status +#endif // Status +#ifdef CursorShape +#undef CursorShape +#endif // CursorShape +#ifdef Bool +#undef Bool +#endif // Bool + +#ifndef GLX_SWAP_INTERVAL_EXT +#define GLX_SWAP_INTERVAL_EXT 0x20F1 +#endif // GLX_SWAP_INTERVAL_EXT + +// Need this global for use case of only having glXSwapIntervalSGI +static int swapInterval = -1; + +void wzSetSwapInterval(int interval) { - // TBD + typedef void (* PFNGLXQUERYDRAWABLEPROC) (Display *, GLXDrawable, int, unsigned int *); + typedef void ( * PFNGLXSWAPINTERVALEXTPROC) (Display*, GLXDrawable, int); + typedef int (* PFNGLXGETSWAPINTERVALMESAPROC)(void); + typedef int (* PFNGLXSWAPINTERVALMESAPROC)(unsigned); + typedef int (* PFNGLXSWAPINTERVALSGIPROC) (int); + PFNGLXSWAPINTERVALEXTPROC glXSwapIntervalEXT; + PFNGLXQUERYDRAWABLEPROC glXQueryDrawable; + PFNGLXGETSWAPINTERVALMESAPROC glXGetSwapIntervalMESA; + PFNGLXSWAPINTERVALMESAPROC glXSwapIntervalMESA; + PFNGLXSWAPINTERVALSGIPROC glXSwapIntervalSGI; + + if (interval < 0) + interval = 0; + +#if GLX_VERSION_1_2 + // Hack-ish, but better than not supporting GLX_SWAP_INTERVAL_EXT? + GLXDrawable drawable = glXGetCurrentDrawable(); + Display * display = glXGetCurrentDisplay(); + glXSwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC) SDL_GL_GetProcAddress("glXSwapIntervalEXT"); + glXQueryDrawable = (PFNGLXQUERYDRAWABLEPROC) SDL_GL_GetProcAddress("glXQueryDrawable"); + + if (glXSwapIntervalEXT && glXQueryDrawable && drawable) + { + unsigned clampedInterval; + glXSwapIntervalEXT(display, drawable, interval); + glXQueryDrawable(display, drawable, GLX_SWAP_INTERVAL_EXT, &clampedInterval); + swapInterval = clampedInterval; + return; + } +#endif + + glXSwapIntervalMESA = (PFNGLXSWAPINTERVALMESAPROC) SDL_GL_GetProcAddress("glXSwapIntervalMESA"); + glXGetSwapIntervalMESA = (PFNGLXGETSWAPINTERVALMESAPROC) SDL_GL_GetProcAddress("glXGetSwapIntervalMESA"); + if (glXSwapIntervalMESA && glXGetSwapIntervalMESA) + { + glXSwapIntervalMESA(interval); + swapInterval = glXGetSwapIntervalMESA(); + return; + } + + glXSwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC) SDL_GL_GetProcAddress("glXSwapIntervalSGI"); + if (glXSwapIntervalSGI) + { + if (interval < 1) + interval = 1; + if (glXSwapIntervalSGI(interval)) + { + // Error, revert to default + swapInterval = 1; + glXSwapIntervalSGI(1); + } + else + { + swapInterval = interval; + } + return; + } + swapInterval = 0; } -bool wzGetSwapInterval() +int wzGetSwapInterval() { - return false; // TBD + if (swapInterval >= 0) + return swapInterval; + + typedef void (* PFNGLXQUERYDRAWABLEPROC) (Display *, GLXDrawable, int, unsigned int *); + typedef int (* PFNGLXGETSWAPINTERVALMESAPROC)(void); + typedef int (* PFNGLXSWAPINTERVALSGIPROC) (int); + PFNGLXQUERYDRAWABLEPROC glXQueryDrawable; + PFNGLXGETSWAPINTERVALMESAPROC glXGetSwapIntervalMESA; + PFNGLXSWAPINTERVALSGIPROC glXSwapIntervalSGI; + +#if GLX_VERSION_1_2 + // Hack-ish, but better than not supporting GLX_SWAP_INTERVAL_EXT? + GLXDrawable drawable = glXGetCurrentDrawable(); + Display * display = glXGetCurrentDisplay(); + glXQueryDrawable = (PFNGLXQUERYDRAWABLEPROC) SDL_GL_GetProcAddress("glXQueryDrawable"); + + if (glXQueryDrawable && drawable) + { + unsigned interval; + glXQueryDrawable(display, drawable, GLX_SWAP_INTERVAL_EXT, &interval); + swapInterval = interval; + return swapInterval; + } +#endif + + glXGetSwapIntervalMESA = (PFNGLXGETSWAPINTERVALMESAPROC) SDL_GL_GetProcAddress("glXGetSwapIntervalMESA"); + if (glXGetSwapIntervalMESA) + { + swapInterval = glXGetSwapIntervalMESA(); + return swapInterval; + } + + glXSwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC) SDL_GL_GetProcAddress("glXSwapIntervalSGI"); + if (glXSwapIntervalSGI) + { + swapInterval = 1; + } + else + { + swapInterval = 0; + } + return swapInterval; } +#elif defined(WZ_WS_WIN) + +void wzSetSwapInterval(int interval) +{ + typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int); + PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT; + + if (interval < 0) + interval = 0; + + wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC) SDL_GL_GetProcAddress("wglSwapIntervalEXT"); + + if (wglSwapIntervalEXT) + wglSwapIntervalEXT(interval); +} + +int wzGetSwapInterval() +{ + typedef int (WINAPI * PFNWGLGETSWAPINTERVALEXTPROC) (void); + PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT; + + wglGetSwapIntervalEXT = (PFNWGLGETSWAPINTERVALEXTPROC) SDL_GL_GetProcAddress("wglGetSwapIntervalEXT"); + if (wglGetSwapIntervalEXT) + return wglGetSwapIntervalEXT(); + return 0; +} + +#else + +void wzSetSwapInterval(int) +{ + return; +} + +int wzGetSwapInterval() +{ + return 0; +} + +#endif + QList wzAvailableResolutions() { QList list;