From 3c40ce800a938bef2861b68cfb84502ccc31b17b Mon Sep 17 00:00:00 2001 From: kervala Date: Mon, 12 Jul 2010 21:52:35 +0200 Subject: [PATCH] Fixed: #928 XRandR modesetting --- code/nel/CMakeLists.txt | 23 +- code/nel/CMakeModules/FindXRandR.cmake | 46 ++ code/nel/src/3d/driver/opengl/CMakeLists.txt | 13 +- code/nel/src/3d/driver/opengl/driver_opengl.h | 12 +- .../3d/driver/opengl/driver_opengl_window.cpp | 458 ++++++++++++++---- 5 files changed, 426 insertions(+), 126 deletions(-) create mode 100644 code/nel/CMakeModules/FindXRandR.cmake diff --git a/code/nel/CMakeLists.txt b/code/nel/CMakeLists.txt index 801466119..29af3e2b6 100644 --- a/code/nel/CMakeLists.txt +++ b/code/nel/CMakeLists.txt @@ -101,12 +101,13 @@ IF(WITH_3D) IF(NOT WITH_COCOA) FIND_PACKAGE(X11) FIND_PACKAGE(XF86VidMode) + FIND_PACKAGE(XRandR) ENDIF(NOT WITH_COCOA) ENDIF(NOT WIN32) ENDIF(WITH_DRIVER_OPENGL) IF(WITH_CEGUI) - FIND_PACKAGE(CEGUI) + FIND_PACKAGE(CEGUI) ENDIF(WITH_CEGUI) ENDIF(WITH_3D) @@ -119,7 +120,7 @@ IF(WITH_SOUND) IF(WITH_DRIVER_FMOD) FIND_PACKAGE(FMOD) ENDIF(WITH_DRIVER_FMOD) - + IF(WITH_DRIVER_XAUDIO2) FIND_PACKAGE(Ogg) FIND_PACKAGE(Vorbis) @@ -143,8 +144,8 @@ IF(WITH_TESTS) IF(BUILD_DASHBOARD) INCLUDE(Dart) SET(SVNCOMMAND svn) - SET(SVNSOURCEDIR http://dev.ryzom.com/svn/trunk/nel) - SET(GENERATELOGS svn2cl) + SET(SVNSOURCEDIR http://dev.ryzom.com/svn/trunk/nel) + SET(GENERATELOGS svn2cl) ENDIF(BUILD_DASHBOARD) ENDIF(WITH_TESTS) @@ -225,8 +226,8 @@ SET(CPACK_PACKAGE_ICON ${CMAKE_SOURCE_DIR}/resources\\\\nel.bmp) SET(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY} NeL") SET(CPACK_NSIS_HELP_LINK "http:\\\\\\\\dev.ryzom.com") SET(CPACK_NSIS_URL_INFO_ABOUT "http:\\\\\\\\dev.ryzom.com\\\\projects\\\\nel\\\\wiki") -SET(CPACK_NSIS_CONTACT "matt.raykowski@gmail.com") - +SET(CPACK_NSIS_CONTACT "matt.raykowski@gmail.com") + ## Source Packages SET(CPACK_PACKAGE_FILE_NAME "nel-${NL_VERSION}") SET(CPACK_SOURCE_PACKAGE_FILE_NAME "nel-${NL_VERSION}") @@ -250,8 +251,8 @@ IF(WIN32) SET(CMAKE_INSTALL_DEBUG_LIBRARIES TRUE) IF(WITH_QT) INCLUDE(${QT_USE_FILE}) - INSTALL(FILES - "${QT_LIBRARY_DIR}/QtGuid4.dll" + INSTALL(FILES + "${QT_LIBRARY_DIR}/QtGuid4.dll" "${QT_LIBRARY_DIR}/QtXmld4.dll" "${QT_LIBRARY_DIR}/QtCored4.dll" DESTINATION bin) @@ -259,8 +260,8 @@ IF(WIN32) ELSE(NOT CMAKE_BUILD_TYPE STREQUAL "Release") IF(WITH_QT) INCLUDE(${QT_USE_FILE}) - INSTALL(FILES - "${QT_LIBRARY_DIR}/QtGui4.dll" + INSTALL(FILES + "${QT_LIBRARY_DIR}/QtGui4.dll" "${QT_LIBRARY_DIR}/QtXml4.dll" "${QT_LIBRARY_DIR}/QtCore4.dll" DESTINATION bin) @@ -276,7 +277,7 @@ IF(WIN32) INSTALL(FILES "${CEGUI_LIB_DIR}/Devil.dll" DESTINATION bin) INSTALL(FILES "${CEGUI_LIB_DIR}/ILU.dll" DESTINATION bin) ENDIF(WITH_CEGUI) - + # Only the tools require MFC. IF(WITH_TOOLS) SET(CMAKE_INSTALL_MFC_LIBRARIES TRUE) diff --git a/code/nel/CMakeModules/FindXRandR.cmake b/code/nel/CMakeModules/FindXRandR.cmake new file mode 100644 index 000000000..5867e65eb --- /dev/null +++ b/code/nel/CMakeModules/FindXRandR.cmake @@ -0,0 +1,46 @@ +# - Locate XRandR library +# This module defines +# XRandR_LIBRARY, the library to link against +# XRandR_FOUND, if false, do not try to link to XRandR +# XRandR_INCLUDE_DIR, where to find headers. + +IF(XRandR_LIBRARY AND XRandR_INCLUDE_DIR) + # in cache already + SET(XRandR_FIND_QUIETLY TRUE) +ENDIF(XRandR_LIBRARY AND XRandR_INCLUDE_DIR) + + +FIND_PATH(XRandR_INCLUDE_DIR + Xrandr.h + PATHS + $ENV{XRandR_DIR}/include + /usr/include/X11/ + /usr/X11R6/include/ + PATH_SUFFIXES extensions +) + +FIND_LIBRARY(XRandR_LIBRARY + Xrandr + PATHS + $ENV{XRandR_DIR}/lib + /usr/X11R6/lib + /usr/lib + /sw/lib + /opt/local/lib + /opt/csw/lib + /opt/lib + /usr/freeware/lib64 +) + +IF(XRandR_LIBRARY AND XRandR_INCLUDE_DIR) + SET(XRandR_FOUND "YES") + SET(XRandR_DEFINITIONS -DXRANDR) + IF(NOT XRandR_FIND_QUIETLY) + MESSAGE(STATUS "Found XRandR: ${XRandR_LIBRARY}") + ENDIF(NOT XRandR_FIND_QUIETLY) +ELSE(XRandR_LIBRARY AND XRandR_INCLUDE_DIR) + IF(NOT XRandR_FIND_QUIETLY) + MESSAGE(STATUS "Warning: Unable to find XRandR!") + ENDIF(NOT XRandR_FIND_QUIETLY) +ENDIF(XRandR_LIBRARY AND XRandR_INCLUDE_DIR) + diff --git a/code/nel/src/3d/driver/opengl/CMakeLists.txt b/code/nel/src/3d/driver/opengl/CMakeLists.txt index c7827d820..6789bfaa0 100644 --- a/code/nel/src/3d/driver/opengl/CMakeLists.txt +++ b/code/nel/src/3d/driver/opengl/CMakeLists.txt @@ -14,7 +14,7 @@ ADD_LIBRARY(${NLDRV_OGL_LIB} SHARED ${SRC}) INCLUDE_DIRECTORIES(${LIBXML2_INCLUDE_DIR} ${OPENGL_INCLUDE_DIR}) TARGET_LINK_LIBRARIES(${NLDRV_OGL_LIB} nel3d nelmisc ${OPENGL_LIBRARIES}) -SET_TARGET_PROPERTIES(${NLDRV_OGL_LIB} PROPERTIES +SET_TARGET_PROPERTIES(${NLDRV_OGL_LIB} PROPERTIES VERSION ${NL_VERSION} SOVERSION ${NL_VERSION_MAJOR} PROJECT_LABEL "Driver, Video: OpenGL") @@ -22,7 +22,7 @@ SET_TARGET_PROPERTIES(${NLDRV_OGL_LIB} PROPERTIES IF(WIN32) INCLUDE_DIRECTORIES(${DXSDK_INCLUDE_DIR}) TARGET_LINK_LIBRARIES(${NLDRV_OGL_LIB} ${DXSDK_DINPUT_LIBRARY} ${DXSDK_GUID_LIBRARY}) - SET_TARGET_PROPERTIES(${NLDRV_OGL_LIB} PROPERTIES + SET_TARGET_PROPERTIES(${NLDRV_OGL_LIB} PROPERTIES DEBUG_POSTFIX "_d" RELEASE_POSTFIX "_r" LINK_FLAGS_DEBUG "${CMAKE_LINK_FLAGS_DEBUG}" @@ -34,10 +34,10 @@ ELSE(WIN32) IF(WITH_COCOA) TARGET_LINK_LIBRARIES(${NLDRV_OGL_LIB} ${COCOA}) ELSE(WITH_COCOA) - # NOTE: I know, those hardcoded things are evil. But FindOpenGL on Mac + # NOTE: I know, those hardcoded things are evil. But FindOpenGL on Mac # simply does not look for X11's OpenGL, just for the native one. INCLUDE_DIRECTORIES("/usr/X11/include") - TARGET_LINK_LIBRARIES(${NLDRV_OGL_LIB} + TARGET_LINK_LIBRARIES(${NLDRV_OGL_LIB} "-L/usr/X11/lib" "-lGL" ${X11_LIBRARIES}) ENDIF(WITH_COCOA) ELSE(APPLE) @@ -47,6 +47,11 @@ ELSE(WIN32) ADD_DEFINITIONS(${XF86VidMode_DEFINITIONS}) TARGET_LINK_LIBRARIES(${NLDRV_OGL_LIB} ${XF86VidMode_LIBRARY}) ENDIF(XF86VidMode_FOUND) + IF(XRandR_FOUND) + INCLUDE_DIRECTORIES(${XRandR_INCLUDE_DIR}) + ADD_DEFINITIONS(${XRandR_DEFINITIONS}) + TARGET_LINK_LIBRARIES(${NLDRV_OGL_LIB} ${XRandR_LIBRARY}) + ENDIF(XRandR_FOUND) ENDIF(APPLE) ENDIF(WIN32) diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.h b/code/nel/src/3d/driver/opengl/driver_opengl.h index fa1685d5b..44ce39c2c 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.h +++ b/code/nel/src/3d/driver/opengl/driver_opengl.h @@ -686,11 +686,17 @@ private: Cursor _cursor; NLMISC::CUnixEventEmitter _EventEmitter; XVisualInfo* _visual_info; + uint32 _xrandr_version; + uint32 _xvidmode_version; + +#ifdef XRANDR + sint _OldSizeID; +#endif // XRANDR #ifdef XF86VIDMODE - int _OldDotClock; // old dotclock + sint _OldDotClock; // old dotclock XF86VidModeModeLine _OldScreenMode; // old modeline - int _OldX, _OldY; //Viewport settings + sint _OldX, _OldY; //Viewport settings #endif //XF86VIDMODE #endif // NL_OS_UNIX @@ -1252,10 +1258,8 @@ private: // Monitor color parameters backup -#ifdef WIN32 bool _NeedToRestaureGammaRamp; uint16 _GammaRampBackuped[3*256]; -#endif /// \fragment shaders diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp index 2024e26e6..a9e102dc1 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp @@ -32,6 +32,9 @@ #elif defined (NL_OS_UNIX) # include # include +# ifdef XRANDR +# include +# endif #endif // NL_OS_UNIX #include "nel/misc/mouse_device.h" @@ -201,6 +204,30 @@ bool CDriverGL::init (uint windowIcon, emptyProc exitFunc) nldebug("3D: XOpenDisplay on '%s' OK", getenv("DISPLAY")); } + _xrandr_version = 0; + +#ifdef XRANDR + _OldSizeID = 0; + sint xrandr_major, xrandr_minor; + if (XRRQueryVersion(_dpy, &xrandr_major, &xrandr_minor)) + { + _xrandr_version = xrandr_major * 100 + xrandr_minor; + nlinfo("3D: XRandR %d.%d found", xrandr_major, xrandr_minor); + } + +#endif + + _xvidmode_version = 0; + +#ifdef XF86VIDMODE + sint event = 0, error = -1, vm_major = 0, vm_minor = 0; + if (XF86VidModeQueryExtension(_dpy, &event, &error) && XF86VidModeQueryVersion(_dpy, &vm_major, &vm_minor)) + { + _xvidmode_version = vm_major * 100 + vm_minor; + nlinfo("3D: XF86VidMode %d.%d found", major, minor); + } +#endif + #endif return true; } @@ -756,12 +783,41 @@ bool CDriverGL::saveScreenMode() #elif defined(NL_OS_UNIX) + int screen = DefaultScreen(_dpy); + res = false; + +#ifdef XRANDR + + if (!res && _xrandr_version > 0) + { + XRRScreenConfiguration *screen_config = XRRGetScreenInfo(_dpy, RootWindow(_dpy, screen)); + + if (screen_config) + { + Rotation saved_rotation; + _OldSizeID = XRRConfigCurrentConfiguration(screen_config, &saved_rotation); + nlinfo("3D: current XRandR mode %d", _OldSizeID); + XRRFreeScreenConfigInfo(screen_config); + + res = true; + } + else + { + nlwarning("3D: XRRGetScreenInfo failed"); + } + } + +#endif // XRANDR + #if defined(XF86VIDMODE) - // Store old mode in order to restore it when leaving fullscreen - memset(&_OldScreenMode, 0, sizeof(XF86VidModeModeLine)); - XF86VidModeGetModeLine(_dpy, DefaultScreen(_dpy), &_OldDotClock, &_OldScreenMode); - res = XF86VidModeGetViewPort(_dpy, DefaultScreen(_dpy), &_OldX, &_OldY); + if (!res && _xvidmode_version > 0) + { + // Store old mode in order to restore it when leaving fullscreen + memset(&_OldScreenMode, 0, sizeof(XF86VidModeModeLine)); + XF86VidModeGetModeLine(_dpy, screen, &_OldDotClock, &_OldScreenMode); + res = XF86VidModeGetViewPort(_dpy, screen, &_OldX, &_OldY); + } #endif // XF86VIDMODE @@ -788,29 +844,62 @@ bool CDriverGL::restoreScreenMode() #elif defined(NL_OS_UNIX) + int screen = DefaultScreen(_dpy); + +#ifdef XRANDR + + if (!res && _xrandr_version > 0) + { + Window root = RootWindow(_dpy, screen); + + XRRScreenConfiguration *screen_config = XRRGetScreenInfo(_dpy, root); + + if (screen_config) + { + Rotation saved_rotation; + SizeID size = XRRConfigCurrentConfiguration(screen_config, &saved_rotation); + if (XRRSetScreenConfig(_dpy, screen_config, root, _OldSizeID, saved_rotation, CurrentTime) == RRSetConfigSuccess) + { + nlinfo("3D: Switching back to XRandR mode %d", _OldSizeID); + res = true; + } + + XRRFreeScreenConfigInfo(screen_config); + } + else + { + nlwarning("3D: XRRGetScreenInfo failed"); + } + } + +#endif // XRANDR + #if defined(XF86VIDMODE) - XF86VidModeModeInfo info; - nlinfo("3D: Switching back to original mode"); + if (!res && _xvidmode_version > 0) + { + XF86VidModeModeInfo info; + nlinfo("3D: Switching back to original mode"); - // This is UGLY - info.dotclock = _OldDotClock; - info.hdisplay = _OldScreenMode.hdisplay; - info.hsyncstart = _OldScreenMode.hsyncstart; - info.hsyncend = _OldScreenMode.hsyncend; - info.htotal = _OldScreenMode.htotal; - info.vdisplay = _OldScreenMode.vdisplay; - info.vsyncstart = _OldScreenMode.vsyncstart; - info.vsyncend = _OldScreenMode.vsyncend; - info.vtotal = _OldScreenMode.vtotal; - info.flags = _OldScreenMode.flags; - info.privsize = _OldScreenMode.privsize; - info.c_private = _OldScreenMode.c_private; + // This is UGLY + info.dotclock = _OldDotClock; + info.hdisplay = _OldScreenMode.hdisplay; + info.hsyncstart = _OldScreenMode.hsyncstart; + info.hsyncend = _OldScreenMode.hsyncend; + info.htotal = _OldScreenMode.htotal; + info.vdisplay = _OldScreenMode.vdisplay; + info.vsyncstart = _OldScreenMode.vsyncstart; + info.vsyncend = _OldScreenMode.vsyncend; + info.vtotal = _OldScreenMode.vtotal; + info.flags = _OldScreenMode.flags; + info.privsize = _OldScreenMode.privsize; + info.c_private = _OldScreenMode.c_private; - nlinfo("3D: Switching back mode to %dx%d", info.hdisplay, info.vdisplay); - XF86VidModeSwitchToMode(_dpy, DefaultScreen(_dpy), &info); - nlinfo("3D: Switching back viewport to %d,%d",_OldX, _OldY); - res = XF86VidModeSetViewPort(_dpy, DefaultScreen(_dpy), _OldX, _OldY); + nlinfo("3D: Switching back mode to %dx%d", info.hdisplay, info.vdisplay); + XF86VidModeSwitchToMode(_dpy, screen, &info); + nlinfo("3D: Switching back viewport to %d,%d",_OldX, _OldY); + res = XF86VidModeSetViewPort(_dpy, screen, _OldX, _OldY); + } #endif // XF86VIDMODE @@ -819,6 +908,14 @@ bool CDriverGL::restoreScreenMode() return res; } +// -------------------------------------------------- +#ifdef XF86VIDMODE +static sint modeInfoToFrequency(XF86VidModeModeInfo *info) +{ + return (info->htotal && info->vtotal) ? (1000 * info->dotclock / (info->htotal * info->vtotal)) : 0; +} +#endif // XF86VIDMODE + // -------------------------------------------------- bool CDriverGL::setScreenMode(const GfxMode &mode) { @@ -880,37 +977,89 @@ bool CDriverGL::setScreenMode(const GfxMode &mode) #elif defined(NL_OS_UNIX) -#if defined(XF86VIDMODE) - bool found = false; - // Find the requested mode and use it - XF86VidModeModeInfo **modes; - int nmodes; - if (XF86VidModeGetAllModeLines(_dpy, DefaultScreen(_dpy), &nmodes, &modes)) +#ifdef XRANDR + + if (!found && _xrandr_version > 0) { - for (int i = 0; i < nmodes; i++) + int screen = DefaultScreen(_dpy); + Window root = RootWindow(_dpy, screen); + + XRRScreenConfiguration *screen_config = XRRGetScreenInfo(_dpy, root); + + if (screen_config) { - nldebug("3D: Available mode - %dx%d", modes[i]->hdisplay, modes[i]->vdisplay); - if (modes[i]->hdisplay == mode.Width && modes[i]->vdisplay == mode.Height) + Rotation saved_rotation; + SizeID size = XRRConfigCurrentConfiguration(screen_config, &saved_rotation); + + sint nsizes; + XRRScreenSize *sizes = XRRConfigSizes(screen_config, &nsizes); + sint size = -1; + + for (sint i = 0; i < nsizes; ++i) { - if (XF86VidModeSwitchToMode(_dpy, DefaultScreen(_dpy), modes[i])) + if (sizes[i].width == mode.Width && sizes[i].height == mode.Height) { - nlinfo("3D: Switching to mode %dx%d", modes[i]->hdisplay, modes[i]->vdisplay); - XF86VidModeSetViewPort(_dpy, DefaultScreen(_dpy), 0, 0); - found = true; + size = i; + break; } - break; } + + if (size > -1 && XRRSetScreenConfig(_dpy, screen_config, root, size, saved_rotation, CurrentTime) == RRSetConfigSuccess) + { + nlinfo("3D: Switching to XRandR mode %d: %dx%d", size, sizes[size].width, sizes[size].height); + found = true; + } + else + { + nlwarning("3D: No corresponding screen mode or XRRSetScreenConfig failed"); + } + + XRRFreeScreenConfigInfo(screen_config); + } + else + { + nlwarning("3D: XRRGetScreenInfo failed"); } - XFree(modes); } +#endif + +#if defined(XF86VIDMODE) + + if (!found && _xvidmode_version > 0) + { + // Find the requested mode and use it + XF86VidModeModeInfo **modes; + int nmodes; + if (XF86VidModeGetAllModeLines(_dpy, DefaultScreen(_dpy), &nmodes, &modes)) + { + for (int i = 0; i < nmodes; i++) + { + const uint16 freq = modeInfoToFrequency(modes[i]); + + nldebug("3D: Available mode - %dx%d %d Hz", modes[i]->hdisplay, modes[i]->vdisplay, (int)freq); + if (modes[i]->hdisplay == mode.Width && modes[i]->vdisplay == mode.Height /* && freq == mode.Frequency */) + { + if (XF86VidModeSwitchToMode(_dpy, DefaultScreen(_dpy), modes[i])) + { + nlinfo("3D: XF86VidMode Switching to mode %dx%d", modes[i]->hdisplay, modes[i]->vdisplay); + XF86VidModeSetViewPort(_dpy, DefaultScreen(_dpy), 0, 0); + found = true; + } + break; + } + } + XFree(modes); + } + } + +#endif // XF86VIDMODE + if (!found) return false; -#endif // XF86VIDMODE - #endif // NL_OS_WINDOWS return true; @@ -1115,43 +1264,32 @@ bool CDriverGL::setWindowStyle(EWindowStyle windowStyle) #elif defined(NL_OS_UNIX) - XSetWindowAttributes attr; - -#ifdef XF86VIDMODE - // If we're going to attempt fullscreen, we need to set redirect to True, - // This basically places the window with no borders in the top left - // corner of the screen. - if (windowStyle == EWSWindowed) - { - attr.override_redirect = False; - } - else - { - attr.override_redirect = True; - } -#else - attr.override_redirect = False; -#endif - - int attr_flags = CWOverrideRedirect; - - XChangeWindowAttributes(_dpy, _win, attr_flags, &attr); - // x11 fullscreen is not working on mac os x + #if !defined(NL_OS_MAC) + // Toggle fullscreen if (windowStyle != getWindowStyle()) { XEvent xev; memset(&xev, 0, sizeof(xev)); xev.type = ClientMessage; +// xev.xclient.serial = 0; +// xev.xclient.send_event = True; +// xev.xclient.display = _dpy; xev.xclient.window = _win; xev.xclient.message_type = XInternAtom(_dpy, "_NET_WM_STATE", False); xev.xclient.format = 32; xev.xclient.data.l[0] = windowStyle == EWSFullscreen ? 1:0; xev.xclient.data.l[1] = XInternAtom(_dpy, "_NET_WM_STATE_FULLSCREEN", False); xev.xclient.data.l[2] = 0; - XSendEvent(_dpy, DefaultRootWindow(_dpy), False, SubstructureNotifyMask, &xev); + xev.xclient.data.l[3] = 0; + xev.xclient.data.l[4] = 0; + if (XSendEvent(_dpy, DefaultRootWindow(_dpy), False, SubstructureNotifyMask, &xev) != Success) + { + nlwarning("3D: Failed to toggle to fullscreen"); + return false; + } } #endif @@ -1222,32 +1360,84 @@ bool CDriverGL::getModes(std::vector &modes) #elif defined (NL_OS_UNIX) -# ifdef XF86VIDMODE + bool found = false; + int screen = DefaultScreen(_dpy); + +#if defined(XRANDR) + if (!found && _xrandr_version >= 100) + { + XRRScreenConfiguration *screen_config = XRRGetScreenInfo(_dpy, RootWindow(_dpy, screen)); + + if (screen_config) + { + // retrieve the list of resolutions + int nsizes = 0; + XRRScreenSize *sizes = XRRConfigSizes(screen_config, &nsizes); + + if (nsizes > 0) + { + nldebug("3D: %d available XRandR modes:", nsizes); + + for (sint i = 0; i < nsizes; ++i) + { + // Add this mode + GfxMode mode; + mode.Width = sizes[i].width; + mode.Height = sizes[i].height; + mode.Frequency = 0; + modes.push_back(mode); + + nldebug("3D: Mode %d: %dx%d", i, mode.Width, mode.Height); + } + + found = true; + } + else + { + nlwarning("3D: No XRandR modes available"); + } + + XRRFreeScreenConfigInfo(screen_config); + } + else + { + nlwarning("3D: XRRGetScreenInfo failed"); + } + } +#endif + +#ifdef XF86VIDMODE int nmodes; XF86VidModeModeInfo **ms; - Bool ok = XF86VidModeGetAllModeLines(_dpy, DefaultScreen(_dpy), &nmodes, &ms); - if(ok) + if (!found && XF86VidModeGetAllModeLines(_dpy, screen, &nmodes, &ms)) { - nldebug("3D: %d available modes:", nmodes); + nlinfo("3D: %d available XF86VidMode modes:", nmodes); for (int j = 0; j < nmodes; j++) { // Add this mode GfxMode mode; mode.Width = (uint16)ms[j]->hdisplay; mode.Height = (uint16)ms[j]->vdisplay; - const uint16 pixelsCount = ms[j]->htotal * ms[j]->vtotal; - mode.Frequency = pixelsCount ? 1000 * ms[j]->dotclock / pixelsCount:0; - nldebug("3D: Mode %d: %dx%d, %d Hz", j, mode.Width, mode.Height, mode.Frequency); + mode.Frequency = modeInfoToFrequency(ms[j]); + nlinfo("3D: Mode %d: %dx%d, %d Hz", j, mode.Width, mode.Height, mode.Frequency); modes.push_back (mode); } XFree(ms); } - else +#endif // XF86VIDMODE + + if (!found) { - nlwarning("XF86VidModeGetAllModeLines returns 0, cannot get available video mode"); - return false; + // Add current screen mode + GfxMode mode; + mode.Width = DisplayWidth(_dpy, screen); + mode.Height = DisplayHeight(_dpy, screen); + mode.Frequency = 0; + modes.push_back(mode); + + nldebug("3D: X11 available mode:"); + nldebug("3D: %dx%d", mode.Width, mode.Height); } -# endif #endif return true; @@ -1290,31 +1480,96 @@ bool CDriverGL::getCurrentScreenMode(GfxMode &mode) #elif defined(NL_OS_UNIX) -# ifdef XF86VIDMODE - sint pixelClock; - XF86VidModeModeLine xmode; - - if (!XF86VidModeGetModeLine(_dpy, DefaultScreen(_dpy), &pixelClock, &xmode)) - { - nlwarning("XF86VidModeGetModeLine returns 0, cannot get current video mode"); - return false; - } + bool found = false; + int screen = DefaultScreen(_dpy); // x11 fullscreen is not working on mac os x -#if !defined(NL_OS_MAC) - mode.Windowed = !_FullScreen; -#else +#if defined(NL_OS_MAC) mode.Windowed = true; + found = true; #endif - mode.OffScreen = false; - mode.Depth = (uint) DefaultDepth(_dpy, DefaultScreen(_dpy)); - mode.Frequency = 1000 * pixelClock / (xmode.htotal * xmode.vtotal) ; - mode.Width = xmode.hdisplay; - mode.Height = xmode.vdisplay; +#ifdef XRANDR - nldebug("Current mode : %dx%d, %d Hz, %dbit", mode.Width, mode.Height, mode.Frequency, mode.Depth); -# endif + if (!found && _xrandr_version > 0) + { + XRRScreenConfiguration *screen_config = XRRGetScreenInfo(_dpy, RootWindow(_dpy, screen)); + + if (screen_config) + { + int nsizes; + XRRScreenSize *sizes = XRRConfigSizes(screen_config, &nsizes); + if (nsizes > 0) + { + Rotation cur_rotation; + SizeID size = XRRConfigCurrentConfiguration(screen_config, &cur_rotation); + + mode.Windowed = !_FullScreen; + mode.OffScreen = false; + mode.Depth = (uint) DefaultDepth(_dpy, screen); + mode.Frequency = 0; + mode.Width = sizes[size].width; + mode.Height = sizes[size].height; + + found = true; + + nlinfo("3D: Current XRandR mode %d: %dx%d, %dbit", size, mode.Width, mode.Height, mode.Depth); + } + else + { + nlwarning("3D: No XRandR modes available"); + } + + XRRFreeScreenConfigInfo(screen_config); + } + else + { + nlwarning("3D: XRRGetScreenInfo failed"); + } + } + +#endif // XRANDR + +#ifdef XF86VIDMODE + + if (!found && _xvidmode_version > 0) + { + sint pixelClock; + XF86VidModeModeLine xmode; + + if (XF86VidModeGetModeLine(_dpy, screen, &pixelClock, &xmode)) + { + mode.Windowed = !_FullScreen; + mode.OffScreen = false; + mode.Depth = (uint) DefaultDepth(_dpy, screen); + mode.Frequency = 1000 * pixelClock / (xmode.htotal * xmode.vtotal) ; + mode.Width = xmode.hdisplay; + mode.Height = xmode.vdisplay; + nlinfo("3D: Current XF86VidMode mode: %dx%d, %d Hz, %dbit", mode.Width, mode.Height, mode.Frequency, mode.Depth); + + found = true; + } + else + { + nlwarning("3D: XF86VidModeGetModeLine failed, cannot get current video mode"); + } + } + +#endif + + if (!found) + { + mode.Windowed = !_FullScreen; + mode.OffScreen = _OffScreen; + mode.Depth = (uint) DefaultDepth(_dpy, screen); + mode.Frequency = 0; + mode.Width = DisplayWidth(_dpy, screen); + mode.Height = DisplayHeight(_dpy, screen); + + found = true; + + nldebug("Current mode: %dx%d, %d Hz, %dbit", mode.Width, mode.Height, mode.Frequency, mode.Depth); + } #endif return true; @@ -1379,7 +1634,7 @@ void CDriverGL::showWindow(bool show) #elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE) MAC::showWindow(show); - + #elif defined (NL_OS_UNIX) if (show) @@ -1649,19 +1904,8 @@ void CDriverGL::setWindowSize(uint32 width, uint32 height) XSetWMNormalHints(_dpy, _win, &size_hints); - // set position to (0, 0) if fullscreen - if (_FullScreen) - { - // move and resize the window - XMoveResizeWindow(_dpy, _win, 0, 0, width, height); - } - else - { - // resize the window - XResizeWindow(_dpy, _win, width, height); - } - -// XMapWindow(_dpy, _win); + // resize the window + XResizeWindow(_dpy, _win, width, height); _WindowWidth = width; _WindowHeight = height;