Fixed: #928 XRandR modesetting

This commit is contained in:
kervala 2010-07-12 21:52:35 +02:00
parent 9d2232c3d8
commit 3c40ce800a
5 changed files with 426 additions and 126 deletions

View file

@ -101,12 +101,13 @@ IF(WITH_3D)
IF(NOT WITH_COCOA) IF(NOT WITH_COCOA)
FIND_PACKAGE(X11) FIND_PACKAGE(X11)
FIND_PACKAGE(XF86VidMode) FIND_PACKAGE(XF86VidMode)
FIND_PACKAGE(XRandR)
ENDIF(NOT WITH_COCOA) ENDIF(NOT WITH_COCOA)
ENDIF(NOT WIN32) ENDIF(NOT WIN32)
ENDIF(WITH_DRIVER_OPENGL) ENDIF(WITH_DRIVER_OPENGL)
IF(WITH_CEGUI) IF(WITH_CEGUI)
FIND_PACKAGE(CEGUI) FIND_PACKAGE(CEGUI)
ENDIF(WITH_CEGUI) ENDIF(WITH_CEGUI)
ENDIF(WITH_3D) ENDIF(WITH_3D)
@ -119,7 +120,7 @@ IF(WITH_SOUND)
IF(WITH_DRIVER_FMOD) IF(WITH_DRIVER_FMOD)
FIND_PACKAGE(FMOD) FIND_PACKAGE(FMOD)
ENDIF(WITH_DRIVER_FMOD) ENDIF(WITH_DRIVER_FMOD)
IF(WITH_DRIVER_XAUDIO2) IF(WITH_DRIVER_XAUDIO2)
FIND_PACKAGE(Ogg) FIND_PACKAGE(Ogg)
FIND_PACKAGE(Vorbis) FIND_PACKAGE(Vorbis)
@ -143,8 +144,8 @@ IF(WITH_TESTS)
IF(BUILD_DASHBOARD) IF(BUILD_DASHBOARD)
INCLUDE(Dart) INCLUDE(Dart)
SET(SVNCOMMAND svn) SET(SVNCOMMAND svn)
SET(SVNSOURCEDIR http://dev.ryzom.com/svn/trunk/nel) SET(SVNSOURCEDIR http://dev.ryzom.com/svn/trunk/nel)
SET(GENERATELOGS svn2cl) SET(GENERATELOGS svn2cl)
ENDIF(BUILD_DASHBOARD) ENDIF(BUILD_DASHBOARD)
ENDIF(WITH_TESTS) 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_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY} NeL")
SET(CPACK_NSIS_HELP_LINK "http:\\\\\\\\dev.ryzom.com") 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_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 ## Source Packages
SET(CPACK_PACKAGE_FILE_NAME "nel-${NL_VERSION}") SET(CPACK_PACKAGE_FILE_NAME "nel-${NL_VERSION}")
SET(CPACK_SOURCE_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) SET(CMAKE_INSTALL_DEBUG_LIBRARIES TRUE)
IF(WITH_QT) IF(WITH_QT)
INCLUDE(${QT_USE_FILE}) INCLUDE(${QT_USE_FILE})
INSTALL(FILES INSTALL(FILES
"${QT_LIBRARY_DIR}/QtGuid4.dll" "${QT_LIBRARY_DIR}/QtGuid4.dll"
"${QT_LIBRARY_DIR}/QtXmld4.dll" "${QT_LIBRARY_DIR}/QtXmld4.dll"
"${QT_LIBRARY_DIR}/QtCored4.dll" "${QT_LIBRARY_DIR}/QtCored4.dll"
DESTINATION bin) DESTINATION bin)
@ -259,8 +260,8 @@ IF(WIN32)
ELSE(NOT CMAKE_BUILD_TYPE STREQUAL "Release") ELSE(NOT CMAKE_BUILD_TYPE STREQUAL "Release")
IF(WITH_QT) IF(WITH_QT)
INCLUDE(${QT_USE_FILE}) INCLUDE(${QT_USE_FILE})
INSTALL(FILES INSTALL(FILES
"${QT_LIBRARY_DIR}/QtGui4.dll" "${QT_LIBRARY_DIR}/QtGui4.dll"
"${QT_LIBRARY_DIR}/QtXml4.dll" "${QT_LIBRARY_DIR}/QtXml4.dll"
"${QT_LIBRARY_DIR}/QtCore4.dll" "${QT_LIBRARY_DIR}/QtCore4.dll"
DESTINATION bin) DESTINATION bin)
@ -276,7 +277,7 @@ IF(WIN32)
INSTALL(FILES "${CEGUI_LIB_DIR}/Devil.dll" DESTINATION bin) INSTALL(FILES "${CEGUI_LIB_DIR}/Devil.dll" DESTINATION bin)
INSTALL(FILES "${CEGUI_LIB_DIR}/ILU.dll" DESTINATION bin) INSTALL(FILES "${CEGUI_LIB_DIR}/ILU.dll" DESTINATION bin)
ENDIF(WITH_CEGUI) ENDIF(WITH_CEGUI)
# Only the tools require MFC. # Only the tools require MFC.
IF(WITH_TOOLS) IF(WITH_TOOLS)
SET(CMAKE_INSTALL_MFC_LIBRARIES TRUE) SET(CMAKE_INSTALL_MFC_LIBRARIES TRUE)

View file

@ -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)

View file

@ -14,7 +14,7 @@ ADD_LIBRARY(${NLDRV_OGL_LIB} SHARED ${SRC})
INCLUDE_DIRECTORIES(${LIBXML2_INCLUDE_DIR} ${OPENGL_INCLUDE_DIR}) INCLUDE_DIRECTORIES(${LIBXML2_INCLUDE_DIR} ${OPENGL_INCLUDE_DIR})
TARGET_LINK_LIBRARIES(${NLDRV_OGL_LIB} nel3d nelmisc ${OPENGL_LIBRARIES}) 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} VERSION ${NL_VERSION}
SOVERSION ${NL_VERSION_MAJOR} SOVERSION ${NL_VERSION_MAJOR}
PROJECT_LABEL "Driver, Video: OpenGL") PROJECT_LABEL "Driver, Video: OpenGL")
@ -22,7 +22,7 @@ SET_TARGET_PROPERTIES(${NLDRV_OGL_LIB} PROPERTIES
IF(WIN32) IF(WIN32)
INCLUDE_DIRECTORIES(${DXSDK_INCLUDE_DIR}) INCLUDE_DIRECTORIES(${DXSDK_INCLUDE_DIR})
TARGET_LINK_LIBRARIES(${NLDRV_OGL_LIB} ${DXSDK_DINPUT_LIBRARY} ${DXSDK_GUID_LIBRARY}) 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" DEBUG_POSTFIX "_d"
RELEASE_POSTFIX "_r" RELEASE_POSTFIX "_r"
LINK_FLAGS_DEBUG "${CMAKE_LINK_FLAGS_DEBUG}" LINK_FLAGS_DEBUG "${CMAKE_LINK_FLAGS_DEBUG}"
@ -34,10 +34,10 @@ ELSE(WIN32)
IF(WITH_COCOA) IF(WITH_COCOA)
TARGET_LINK_LIBRARIES(${NLDRV_OGL_LIB} ${COCOA}) TARGET_LINK_LIBRARIES(${NLDRV_OGL_LIB} ${COCOA})
ELSE(WITH_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. # simply does not look for X11's OpenGL, just for the native one.
INCLUDE_DIRECTORIES("/usr/X11/include") INCLUDE_DIRECTORIES("/usr/X11/include")
TARGET_LINK_LIBRARIES(${NLDRV_OGL_LIB} TARGET_LINK_LIBRARIES(${NLDRV_OGL_LIB}
"-L/usr/X11/lib" "-lGL" ${X11_LIBRARIES}) "-L/usr/X11/lib" "-lGL" ${X11_LIBRARIES})
ENDIF(WITH_COCOA) ENDIF(WITH_COCOA)
ELSE(APPLE) ELSE(APPLE)
@ -47,6 +47,11 @@ ELSE(WIN32)
ADD_DEFINITIONS(${XF86VidMode_DEFINITIONS}) ADD_DEFINITIONS(${XF86VidMode_DEFINITIONS})
TARGET_LINK_LIBRARIES(${NLDRV_OGL_LIB} ${XF86VidMode_LIBRARY}) TARGET_LINK_LIBRARIES(${NLDRV_OGL_LIB} ${XF86VidMode_LIBRARY})
ENDIF(XF86VidMode_FOUND) 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(APPLE)
ENDIF(WIN32) ENDIF(WIN32)

View file

@ -686,11 +686,17 @@ private:
Cursor _cursor; Cursor _cursor;
NLMISC::CUnixEventEmitter _EventEmitter; NLMISC::CUnixEventEmitter _EventEmitter;
XVisualInfo* _visual_info; XVisualInfo* _visual_info;
uint32 _xrandr_version;
uint32 _xvidmode_version;
#ifdef XRANDR
sint _OldSizeID;
#endif // XRANDR
#ifdef XF86VIDMODE #ifdef XF86VIDMODE
int _OldDotClock; // old dotclock sint _OldDotClock; // old dotclock
XF86VidModeModeLine _OldScreenMode; // old modeline XF86VidModeModeLine _OldScreenMode; // old modeline
int _OldX, _OldY; //Viewport settings sint _OldX, _OldY; //Viewport settings
#endif //XF86VIDMODE #endif //XF86VIDMODE
#endif // NL_OS_UNIX #endif // NL_OS_UNIX
@ -1252,10 +1258,8 @@ private:
// Monitor color parameters backup // Monitor color parameters backup
#ifdef WIN32
bool _NeedToRestaureGammaRamp; bool _NeedToRestaureGammaRamp;
uint16 _GammaRampBackuped[3*256]; uint16 _GammaRampBackuped[3*256];
#endif
/// \fragment shaders /// \fragment shaders

View file

@ -32,6 +32,9 @@
#elif defined (NL_OS_UNIX) #elif defined (NL_OS_UNIX)
# include <GL/gl.h> # include <GL/gl.h>
# include <GL/glx.h> # include <GL/glx.h>
# ifdef XRANDR
# include <X11/extensions/Xrandr.h>
# endif
#endif // NL_OS_UNIX #endif // NL_OS_UNIX
#include "nel/misc/mouse_device.h" #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")); 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 #endif
return true; return true;
} }
@ -756,12 +783,41 @@ bool CDriverGL::saveScreenMode()
#elif defined(NL_OS_UNIX) #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) #if defined(XF86VIDMODE)
// Store old mode in order to restore it when leaving fullscreen if (!res && _xvidmode_version > 0)
memset(&_OldScreenMode, 0, sizeof(XF86VidModeModeLine)); {
XF86VidModeGetModeLine(_dpy, DefaultScreen(_dpy), &_OldDotClock, &_OldScreenMode); // Store old mode in order to restore it when leaving fullscreen
res = XF86VidModeGetViewPort(_dpy, DefaultScreen(_dpy), &_OldX, &_OldY); memset(&_OldScreenMode, 0, sizeof(XF86VidModeModeLine));
XF86VidModeGetModeLine(_dpy, screen, &_OldDotClock, &_OldScreenMode);
res = XF86VidModeGetViewPort(_dpy, screen, &_OldX, &_OldY);
}
#endif // XF86VIDMODE #endif // XF86VIDMODE
@ -788,29 +844,62 @@ bool CDriverGL::restoreScreenMode()
#elif defined(NL_OS_UNIX) #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) #if defined(XF86VIDMODE)
XF86VidModeModeInfo info; if (!res && _xvidmode_version > 0)
nlinfo("3D: Switching back to original mode"); {
XF86VidModeModeInfo info;
nlinfo("3D: Switching back to original mode");
// This is UGLY // This is UGLY
info.dotclock = _OldDotClock; info.dotclock = _OldDotClock;
info.hdisplay = _OldScreenMode.hdisplay; info.hdisplay = _OldScreenMode.hdisplay;
info.hsyncstart = _OldScreenMode.hsyncstart; info.hsyncstart = _OldScreenMode.hsyncstart;
info.hsyncend = _OldScreenMode.hsyncend; info.hsyncend = _OldScreenMode.hsyncend;
info.htotal = _OldScreenMode.htotal; info.htotal = _OldScreenMode.htotal;
info.vdisplay = _OldScreenMode.vdisplay; info.vdisplay = _OldScreenMode.vdisplay;
info.vsyncstart = _OldScreenMode.vsyncstart; info.vsyncstart = _OldScreenMode.vsyncstart;
info.vsyncend = _OldScreenMode.vsyncend; info.vsyncend = _OldScreenMode.vsyncend;
info.vtotal = _OldScreenMode.vtotal; info.vtotal = _OldScreenMode.vtotal;
info.flags = _OldScreenMode.flags; info.flags = _OldScreenMode.flags;
info.privsize = _OldScreenMode.privsize; info.privsize = _OldScreenMode.privsize;
info.c_private = _OldScreenMode.c_private; info.c_private = _OldScreenMode.c_private;
nlinfo("3D: Switching back mode to %dx%d", info.hdisplay, info.vdisplay); nlinfo("3D: Switching back mode to %dx%d", info.hdisplay, info.vdisplay);
XF86VidModeSwitchToMode(_dpy, DefaultScreen(_dpy), &info); XF86VidModeSwitchToMode(_dpy, screen, &info);
nlinfo("3D: Switching back viewport to %d,%d",_OldX, _OldY); nlinfo("3D: Switching back viewport to %d,%d",_OldX, _OldY);
res = XF86VidModeSetViewPort(_dpy, DefaultScreen(_dpy), _OldX, _OldY); res = XF86VidModeSetViewPort(_dpy, screen, _OldX, _OldY);
}
#endif // XF86VIDMODE #endif // XF86VIDMODE
@ -819,6 +908,14 @@ bool CDriverGL::restoreScreenMode()
return res; 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) bool CDriverGL::setScreenMode(const GfxMode &mode)
{ {
@ -880,37 +977,89 @@ bool CDriverGL::setScreenMode(const GfxMode &mode)
#elif defined(NL_OS_UNIX) #elif defined(NL_OS_UNIX)
#if defined(XF86VIDMODE)
bool found = false; bool found = false;
// Find the requested mode and use it #ifdef XRANDR
XF86VidModeModeInfo **modes;
int nmodes; if (!found && _xrandr_version > 0)
if (XF86VidModeGetAllModeLines(_dpy, DefaultScreen(_dpy), &nmodes, &modes))
{ {
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); Rotation saved_rotation;
if (modes[i]->hdisplay == mode.Width && modes[i]->vdisplay == mode.Height) 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); size = i;
XF86VidModeSetViewPort(_dpy, DefaultScreen(_dpy), 0, 0); break;
found = true;
} }
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) if (!found)
return false; return false;
#endif // XF86VIDMODE
#endif // NL_OS_WINDOWS #endif // NL_OS_WINDOWS
return true; return true;
@ -1115,43 +1264,32 @@ bool CDriverGL::setWindowStyle(EWindowStyle windowStyle)
#elif defined(NL_OS_UNIX) #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 // x11 fullscreen is not working on mac os x
#if !defined(NL_OS_MAC) #if !defined(NL_OS_MAC)
// Toggle fullscreen // Toggle fullscreen
if (windowStyle != getWindowStyle()) if (windowStyle != getWindowStyle())
{ {
XEvent xev; XEvent xev;
memset(&xev, 0, sizeof(xev)); memset(&xev, 0, sizeof(xev));
xev.type = ClientMessage; xev.type = ClientMessage;
// xev.xclient.serial = 0;
// xev.xclient.send_event = True;
// xev.xclient.display = _dpy;
xev.xclient.window = _win; xev.xclient.window = _win;
xev.xclient.message_type = XInternAtom(_dpy, "_NET_WM_STATE", False); xev.xclient.message_type = XInternAtom(_dpy, "_NET_WM_STATE", False);
xev.xclient.format = 32; xev.xclient.format = 32;
xev.xclient.data.l[0] = windowStyle == EWSFullscreen ? 1:0; 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[1] = XInternAtom(_dpy, "_NET_WM_STATE_FULLSCREEN", False);
xev.xclient.data.l[2] = 0; 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 #endif
@ -1222,32 +1360,84 @@ bool CDriverGL::getModes(std::vector<GfxMode> &modes)
#elif defined (NL_OS_UNIX) #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; int nmodes;
XF86VidModeModeInfo **ms; XF86VidModeModeInfo **ms;
Bool ok = XF86VidModeGetAllModeLines(_dpy, DefaultScreen(_dpy), &nmodes, &ms); if (!found && XF86VidModeGetAllModeLines(_dpy, screen, &nmodes, &ms))
if(ok)
{ {
nldebug("3D: %d available modes:", nmodes); nlinfo("3D: %d available XF86VidMode modes:", nmodes);
for (int j = 0; j < nmodes; j++) for (int j = 0; j < nmodes; j++)
{ {
// Add this mode // Add this mode
GfxMode mode; GfxMode mode;
mode.Width = (uint16)ms[j]->hdisplay; mode.Width = (uint16)ms[j]->hdisplay;
mode.Height = (uint16)ms[j]->vdisplay; mode.Height = (uint16)ms[j]->vdisplay;
const uint16 pixelsCount = ms[j]->htotal * ms[j]->vtotal; mode.Frequency = modeInfoToFrequency(ms[j]);
mode.Frequency = pixelsCount ? 1000 * ms[j]->dotclock / pixelsCount:0; nlinfo("3D: Mode %d: %dx%d, %d Hz", j, mode.Width, mode.Height, mode.Frequency);
nldebug("3D: Mode %d: %dx%d, %d Hz", j, mode.Width, mode.Height, mode.Frequency);
modes.push_back (mode); modes.push_back (mode);
} }
XFree(ms); XFree(ms);
} }
else #endif // XF86VIDMODE
if (!found)
{ {
nlwarning("XF86VidModeGetAllModeLines returns 0, cannot get available video mode"); // Add current screen mode
return false; 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 #endif
return true; return true;
@ -1290,31 +1480,96 @@ bool CDriverGL::getCurrentScreenMode(GfxMode &mode)
#elif defined(NL_OS_UNIX) #elif defined(NL_OS_UNIX)
# ifdef XF86VIDMODE bool found = false;
sint pixelClock; int screen = DefaultScreen(_dpy);
XF86VidModeModeLine xmode;
if (!XF86VidModeGetModeLine(_dpy, DefaultScreen(_dpy), &pixelClock, &xmode))
{
nlwarning("XF86VidModeGetModeLine returns 0, cannot get current video mode");
return false;
}
// x11 fullscreen is not working on mac os x // x11 fullscreen is not working on mac os x
#if !defined(NL_OS_MAC) #if defined(NL_OS_MAC)
mode.Windowed = !_FullScreen;
#else
mode.Windowed = true; mode.Windowed = true;
found = true;
#endif #endif
mode.OffScreen = false; #ifdef XRANDR
mode.Depth = (uint) DefaultDepth(_dpy, DefaultScreen(_dpy));
mode.Frequency = 1000 * pixelClock / (xmode.htotal * xmode.vtotal) ;
mode.Width = xmode.hdisplay;
mode.Height = xmode.vdisplay;
nldebug("Current mode : %dx%d, %d Hz, %dbit", mode.Width, mode.Height, mode.Frequency, mode.Depth); if (!found && _xrandr_version > 0)
# endif {
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 #endif
return true; return true;
@ -1379,7 +1634,7 @@ void CDriverGL::showWindow(bool show)
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE) #elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
MAC::showWindow(show); MAC::showWindow(show);
#elif defined (NL_OS_UNIX) #elif defined (NL_OS_UNIX)
if (show) if (show)
@ -1649,19 +1904,8 @@ void CDriverGL::setWindowSize(uint32 width, uint32 height)
XSetWMNormalHints(_dpy, _win, &size_hints); XSetWMNormalHints(_dpy, _win, &size_hints);
// set position to (0, 0) if fullscreen // resize the window
if (_FullScreen) XResizeWindow(_dpy, _win, width, height);
{
// move and resize the window
XMoveResizeWindow(_dpy, _win, 0, 0, width, height);
}
else
{
// resize the window
XResizeWindow(_dpy, _win, width, height);
}
// XMapWindow(_dpy, _win);
_WindowWidth = width; _WindowWidth = width;
_WindowHeight = height; _WindowHeight = height;