Mode switching for GHOST under X11: adds the ability to change screen resolutions in the blenderplayer on GNU/Linux.

Code ported from Quake 2.
This commit is contained in:
Alex Fraser 2012-01-02 12:25:14 +00:00
parent 7d19ff1497
commit c2bb285750
3 changed files with 92 additions and 4 deletions

View File

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

View File

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

View File

@ -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;
// we fudge it for now.
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;
}
}
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
}