diff options
author | Alex Fraser <alex@phatcore.com> | 2012-01-02 16:25:14 +0400 |
---|---|---|
committer | Alex Fraser <alex@phatcore.com> | 2012-01-02 16:25:14 +0400 |
commit | c2bb2857506a33ca12c4fbc08eee2ce5e2f73145 (patch) | |
tree | 8c362f824230919cb5abedd94f03a77ae4cd456a | |
parent | 7d19ff14979e47c6f91eac892b2a3cd5b7108cec (diff) |
Mode switching for GHOST under X11: adds the ability to change screen resolutions in the blenderplayer on GNU/Linux.
Code ported from Quake 2.
-rw-r--r-- | CMakeLists.txt | 13 | ||||
-rw-r--r-- | intern/ghost/CMakeLists.txt | 7 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_DisplayManagerX11.cpp | 76 |
3 files changed, 92 insertions, 4 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 24a117d6104..01d81eb7f00 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -156,6 +156,7 @@ endif() if(UNIX AND NOT APPLE) option(WITH_X11_XINPUT "Enable X11 Xinput (tablet support and unicode input)" ON) + option(WITH_X11_XF86VMODE "Enable X11 video mode switching" OFF) option(WITH_BUILTIN_GLEW "Use GLEW OpenGL wrapper library bundled with blender" ON) option(WITH_XDG_USER_DIRS "Build with XDG Base Directory Specification (only config and documents for now)" OFF) mark_as_advanced(WITH_XDG_USER_DIRS) @@ -584,6 +585,17 @@ if(UNIX AND NOT APPLE) if(WITH_X11_XINPUT) set(PLATFORM_LINKLIBS "${PLATFORM_LINKLIBS} ${X11_Xinput_LIB}") endif() + + if(WITH_X11_XF86VMODE) + # XXX, why dont cmake make this available? + FIND_LIBRARY(X11_Xxf86vmode_LIB Xxf86vm ${X11_LIB_SEARCH_PATH}) + mark_as_advanced(X11_Xxf86vmode_LIB) + if(X11_Xxf86vmode_LIB) + set(PLATFORM_LINKLIBS "${PLATFORM_LINKLIBS} ${X11_Xxf86vmode_LIB}") + else() + set(WITH_X11_XF86VMODE OFF) + endif() + endif() endif() if(CMAKE_SYSTEM_NAME MATCHES "Linux") @@ -1547,6 +1559,7 @@ if(FIRST_RUN) info_cfg_text("System Options:") info_cfg_option(WITH_INSTALL_PORTABLE) + info_cfg_option(WITH_X11_XF86VMODE) info_cfg_option(WITH_X11_XINPUT) info_cfg_option(WITH_BUILTIN_GLEW) diff --git a/intern/ghost/CMakeLists.txt b/intern/ghost/CMakeLists.txt index a84ff5825a9..35b617e5452 100644 --- a/intern/ghost/CMakeLists.txt +++ b/intern/ghost/CMakeLists.txt @@ -234,6 +234,13 @@ elseif(UNIX) ) endif() + if(WITH_X11_XF86VMODE) + add_definitions(-DWITH_X11_XF86VMODE) + list(APPEND INC_SYS + ${X11_xf86vmode_INCLUDE_PATH} + ) + endif() + if(WITH_INPUT_NDOF) list(APPEND SRC intern/GHOST_NDOFManagerX11.cpp diff --git a/intern/ghost/intern/GHOST_DisplayManagerX11.cpp b/intern/ghost/intern/GHOST_DisplayManagerX11.cpp index 34f5fda2a16..411203b6475 100644 --- a/intern/ghost/intern/GHOST_DisplayManagerX11.cpp +++ b/intern/ghost/intern/GHOST_DisplayManagerX11.cpp @@ -20,7 +20,9 @@ * * The Original Code is: all of this file. * - * Contributor(s): none yet. + * Video mode switching + * Copyright (C) 1997-2001 Id Software, Inc. + * Ported from Quake 2 by Alex Fraser <alex@phatcore.com> * * ***** END GPL LICENSE BLOCK ***** */ @@ -29,6 +31,10 @@ * \ingroup GHOST */ +#ifdef WITH_X11_XF86VMODE +# include <X11/Xlib.h> +# include <X11/extensions/xf86vmode.h> +#endif #include "GHOST_DisplayManagerX11.h" #include "GHOST_SystemX11.h" @@ -112,12 +118,74 @@ setCurrentDisplaySetting( GHOST_TUns8 display, const GHOST_DisplaySetting& setting ){ - // This is never going to work robustly in X - // but it's currently part of the full screen interface +#ifdef WITH_X11_XF86VMODE + // + // Mode switching code ported from Quake 2: + // ftp://ftp.idsoftware.com/idstuff/source/q2source-3.21.zip + // See linux/gl_glx.c:GLimp_SetMode + // + int majorVersion, minorVersion; + XF86VidModeModeInfo **vidmodes; + Display *dpy = m_system->getXDisplay(); + int scrnum, num_vidmodes; + int best_fit, best_dist, dist, x, y; + + scrnum = DefaultScreen(dpy); + + // Get video mode list + majorVersion = minorVersion = 0; + if (!XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion)) { + fprintf(stderr, "Error: XF86VidMode extension missing!\n"); + return GHOST_kFailure; + } +# ifdef _DEBUG + printf("Using XFree86-VidModeExtension Version %d.%d\n", + majorVersion, minorVersion); +# endif + + XF86VidModeGetAllModeLines(dpy, scrnum, &num_vidmodes, &vidmodes); + + best_dist = 9999999; + best_fit = -1; + + for (int i = 0; i < num_vidmodes; i++) { + if (setting.xPixels > vidmodes[i]->hdisplay || + setting.yPixels > vidmodes[i]->vdisplay) + continue; + + x = setting.xPixels - vidmodes[i]->hdisplay; + y = setting.yPixels - vidmodes[i]->vdisplay; + dist = (x * x) + (y * y); + if (dist < best_dist) { + best_dist = dist; + best_fit = i; + } + } - // we fudge it for now. + if (best_fit != -1) { +# ifdef _DEBUG + int actualWidth, actualHeight; + actualWidth = vidmodes[best_fit]->hdisplay; + actualHeight = vidmodes[best_fit]->vdisplay; + printf("Switching to video mode %dx%d\n", + actualWidth, actualHeight); +# endif + + // change to the mode + XF86VidModeSwitchToMode(dpy, scrnum, vidmodes[best_fit]); + + // Move the viewport to top left + XF86VidModeSetViewPort(dpy, scrnum, 0, 0); + } else + return GHOST_kFailure; + + XFlush(dpy); + return GHOST_kSuccess; +#else + // Just pretend the request was successful. return GHOST_kSuccess; +#endif } |