X11: Remove support for the xf86vidmode extension

In practice, only the xrandr code path received any testing. Since Clonk
works fine without changing the resolution, this will not terribly
inconvenience anybody still stuck on old systems without xrandr.

Also only minimize the window when the resolution was changed.
The minimization is there to prevent accidental focus restoration
resulting in unwanted resolution switching.
Günther Brammer 2012-11-17 18:07:37 +01:00
parent 8a001972ab
commit 4dffefe8c9
7 changed files with 43 additions and 176 deletions

View File

@ -737,10 +737,8 @@ CHECK_INCLUDE_FILE_CXX(natupnp.h HAVE_NATUPNP_H)
# 'Bool' and 'Window' to be defined. Unfortunately, this doesn't exist
# as a CXX version (yet?).
include(CheckIncludeFiles)
CHECK_INCLUDE_FILES(X11/Xlib.h X11/extensions/xf86vmode.h HAVE_X11_EXTENSIONS_XF86VMODE_H)
CHECK_INCLUDE_FILES(X11/Xlib.h X11/extensions/Xrandr.h HAVE_X11_EXTENSIONS_XRANDR_H)
CHECK_INCLUDE_FILES(X11/Xlib.h X11/keysym.h HAVE_X11_KEYSYM_H)
CHECK_INCLUDE_FILES(X11/Xlib.h X11/xpm.h HAVE_X11_XPM_H)
CHECK_INCLUDE_FILE_CXX(iconv.h HAVE_ICONV)
if(HAVE_ICONV)
@ -1242,13 +1240,9 @@ if(USE_GTK)
endif()
if(USE_X11)
FINDLIB(X11_LIBRARIES X11)
FINDLIB(XPM_LIBRARIES Xpm)
FINDLIB(XXF86VM_LIBRARIES Xxf86vm)
FINDLIB(XRANDR_LIBRARIES Xrandr)
target_link_libraries(clonk
${X11_LIBRARIES}
${XPM_LIBRARIES}
${XXF86VM_LIBRARIES}
${XRANDR_LIBRARIES}
)
endif()

View File

@ -120,18 +120,12 @@
#cmakedefine HAVE_VFW32
/* Define to 1 if you have the <X11/extensions/xf86vmode.h> header file. */
#cmakedefine HAVE_X11_EXTENSIONS_XF86VMODE_H 1
/* Define to 1 if you have the <X11/extensions/Xrandr.h> header file. */
#cmakedefine HAVE_X11_EXTENSIONS_XRANDR_H 1
/* Define to 1 if you have the <X11/keysym.h> header file. */
#cmakedefine HAVE_X11_KEYSYM_H 1
/* Define to 1 if you have the <X11/xpm.h> header file. */
#cmakedefine HAVE_X11_XPM_H 1
/* Define as const if the declaration of iconv() needs const. */
#cmakedefine ICONV_CONST

View File

@ -135,18 +135,12 @@
/* */
#undef HAVE_VFW32
/* Define to 1 if you have the <X11/extensions/xf86vmode.h> header file. */
#undef HAVE_X11_EXTENSIONS_XF86VMODE_H
/* Define to 1 if you have the <X11/extensions/Xrandr.h> header file. */
#undef HAVE_X11_EXTENSIONS_XRANDR_H
/* Define to 1 if you have the <X11/keysym.h> header file. */
#undef HAVE_X11_KEYSYM_H
/* Define to 1 if you have the <X11/xpm.h> header file. */
#undef HAVE_X11_XPM_H
/* Define as const if the declaration of iconv() needs const. */
#undef ICONV_CONST

View File

@ -276,19 +276,15 @@ if test $enable_console = no; then
AC_DEFINE(HAVE_FREETYPE, 1, [Define to 1 if you have FreeType2.])
fi
# X11, Xpm, Xrandr
# X11, Xrandr
AC_PATH_XTRA
if test $have_x = yes; then
AC_DEFINE(USE_X11, 1, [Define to 1 if the X Window System is used])
CLONK_LIBS="$X_LIBS $CLONK_LIBS"
AC_CHECK_HEADERS([X11/keysym.h X11/extensions/xf86vmode.h X11/xpm.h X11/extensions/Xrandr.h], ,
AC_CHECK_HEADERS([X11/keysym.h X11/extensions/Xrandr.h], ,
[AC_MSG_ERROR([A required X11 header was not found.])], [[#include <X11/Xlib.h>]])
AC_CHECK_LIB(X11, XOpenDisplay, [CLONK_LIBS="-lX11 $CLONK_LIBS"],
[AC_MSG_ERROR([libX11 not found.])], [$X_LIBS])
AC_CHECK_LIB(Xpm, XpmCreatePixmapFromData, [CLONK_LIBS="-lXpm $CLONK_LIBS"],
[AC_MSG_ERROR([libXpm not found.])], [$X_LIBS])
AC_CHECK_LIB(Xxf86vm, XF86VidModeQueryVersion, [CLONK_LIBS="-lXxf86vm $CLONK_LIBS"],
[AC_MSG_ERROR([XF86VidMode not found.])], [$X_LIBS])
AC_CHECK_LIB(Xrandr, XRRQueryExtension, [CLONK_LIBS="-lXrandr $CLONK_LIBS"],
[AC_MSG_ERROR([libXrandr not found.])], [$X_LIBS])
fi

View File

@ -35,7 +35,6 @@
#ifdef USE_X11
#include <X11/Xlib.h>
#include <X11/extensions/xf86vmode.h>
#include <X11/extensions/Xrandr.h>
#include <gdk/gdkx.h>
#endif
@ -72,14 +71,6 @@ bool C4AbstractApp::Init(int argc, char * argv[])
// Try to figure out the location of the executable
Priv->argc=argc; Priv->argv=argv;
int xf86vmode_event_base, xf86vmode_error_base;
Display * const dpy = gdk_x11_display_get_xdisplay(gdk_display_get_default());
if (!XF86VidModeQueryExtension(dpy, &xf86vmode_event_base, &xf86vmode_error_base)
|| !XF86VidModeQueryVersion(dpy, &Priv->xf86vmode_major_version, &Priv->xf86vmode_minor_version))
{
Priv->xf86vmode_major_version = -1;
Priv->xf86vmode_minor_version = 0;
}
int xrandr_error_base;
if (!XRRQueryExtension(dpy, &Priv->xrandr_event, &xrandr_error_base)
|| !XRRQueryVersion(dpy, &Priv->xrandr_major_version, &Priv->xrandr_minor_version))
@ -87,21 +78,13 @@ bool C4AbstractApp::Init(int argc, char * argv[])
Priv->xrandr_major_version = -1;
Priv->xrandr_minor_version = 0;
}
XRRSelectInput(dpy, DefaultRootWindow(dpy), RRScreenChangeNotifyMask);
if (Priv->xrandr_major_version < 0 && Priv->xf86vmode_major_version < 0)
Log("Xrandr and xf86vmode extensions are missing. Resolution switching will not work.");
else if (Priv->xrandr_major_version >= 0)
LogF(" Using XRandR version %d.%d", Priv->xrandr_major_version, Priv->xrandr_minor_version);
if (Priv->xrandr_major_version >= 0)
{
LogF("Using XRandR version %d.%d", Priv->xrandr_major_version, Priv->xrandr_minor_version);
XRRSelectInput(dpy, DefaultRootWindow(dpy), RRScreenChangeNotifyMask);
}
else
LogF(" Using XF86VidMode version %d.%d", Priv->xf86vmode_major_version, Priv->xf86vmode_minor_version);
#if USE_CONSOLE && HAVE_LIBREADLINE
rl_callback_handler_install (">", readline_callback);
readline_callback_use_this_app = this;
Priv->stdin_channel = g_io_channel_unix_new(STDIN_FILENO);
g_io_add_watch(Priv->stdin_channel, G_IO_IN, &OnStdInInputStatic, this);
#endif
Log("The Xrandr extension is missing. Resolution switching will not work.");
// Custom initialization
return DoInit (argc, argv);
@ -157,69 +140,58 @@ bool C4AbstractApp::FlushMessages()
bool C4AbstractApp::SetVideoMode(unsigned int iXRes, unsigned int iYRes, unsigned int iColorDepth, unsigned int iRefreshRate, unsigned int iMonitor, bool fFullScreen)
{
Display * const dpy = gdk_x11_display_get_xdisplay(gdk_display_get_default());
if (Priv->tasked_out)
return false;
bool modefound = false;
if (fDspModeSet)
{
Priv->SwitchToDesktop(this, pWindow);
fDspModeSet = false;
}
if (!fFullScreen)
{
RestoreVideoMode();
if (iXRes != -1)
pWindow->SetSize(iXRes, iYRes);
return true;
}
if (Priv->xf86vmode_targetmode.hdisplay == iXRes && Priv->xf86vmode_targetmode.vdisplay == iYRes)
modefound = true;
// randr spec says to always get fresh info, so don't cache.
if (Priv->xrandr_major_version >= 0)
if (Priv->xrandr_major_version >= 0 && !(iXRes == -1 && iYRes == -1))
{
modefound = true;
Priv->wdt = iXRes; Priv->hgt = iYRes;
}
if (Priv->xf86vmode_major_version >= 0 && !modefound)
{
// save desktop-resolution before switching modes
// XF86VidMode has a really weird API.
XF86VidModeGetModeLine(dpy, DefaultScreen(dpy), (int*)&Priv->xf86vmode_oldmode.dotclock,
(XF86VidModeModeLine*)(((char *)&Priv->xf86vmode_oldmode) + sizeof(Priv->xf86vmode_oldmode.dotclock)));
if (iXRes == -1 && iYRes == -1)
// randr spec says to always get fresh info, so don't cache.
XRRScreenConfiguration * conf = XRRGetScreenInfo (dpy, pWindow->wnd);
if (Priv->xrandr_oldmode == -1)
Priv->xrandr_oldmode = XRRConfigCurrentConfiguration (conf, &Priv->xrandr_rot);
int n;
XRRScreenSize * sizes = XRRConfigSizes(conf, &n);
for (int i = 0; i < n; ++i)
{
Priv->xf86vmode_targetmode = Priv->xf86vmode_oldmode;
modefound = true;
}
}
if (Priv->xf86vmode_major_version >= 0 && !modefound)
{
// Change resolution
int mode_num;
XF86VidModeModeInfo **modes;
XF86VidModeGetAllModeLines(dpy, DefaultScreen(dpy), &mode_num, &modes);
// look for mode with requested resolution
for (int i = 0; i < mode_num; i++)
{
if ((modes[i]->hdisplay == iXRes) && (modes[i]->vdisplay == iYRes))
if (sizes[i].width == iXRes && sizes[i].height == iYRes)
{
if (!modefound) Priv->xf86vmode_targetmode = *modes[i];
modefound = true;
#ifdef _DEBUG
LogF("XRRSetScreenConfig %d", i);
#endif
fDspModeSet = XRRSetScreenConfig(dpy, conf, pWindow->wnd, i, Priv->xrandr_rot, CurrentTime) == RRSetConfigSuccess;
break;
}
}
XFree(modes);
XRRFreeScreenConfigInfo(conf);
}
if (!modefound) return false;
fDspModeSet = Priv->SwitchToFullscreen(this, pWindow);
if (fDspModeSet)
gtk_window_fullscreen(GTK_WINDOW(pWindow->window));
return fDspModeSet;
}
void C4AbstractApp::RestoreVideoMode()
{
if (fDspModeSet)
if (!fDspModeSet)
return;
// Restore resolution
Display * const dpy = gdk_x11_display_get_xdisplay(gdk_display_get_default());
if (Priv->xrandr_major_version >= 0 && Priv->xrandr_oldmode != -1)
{
Priv->SwitchToDesktop(this, pWindow);
fDspModeSet = false;
XRRScreenConfiguration * conf = XRRGetScreenInfo (dpy, pWindow->wnd);
#ifdef _DEBUG
LogF("XRRSetScreenConfig %d (back)", Priv->xrandr_oldmode);
#endif
XRRSetScreenConfig (dpy, conf, pWindow->wnd, Priv->xrandr_oldmode, Priv->xrandr_rot, CurrentTime);
Priv->xrandr_oldmode = -1;
XRRFreeScreenConfigInfo(conf);
}
gtk_window_unfullscreen(GTK_WINDOW(pWindow->window));
fDspModeSet = false;
}
bool C4AbstractApp::GetIndexedDisplayMode(int32_t iIndex, int32_t *piXRes, int32_t *piYRes, int32_t *piBitDepth, int32_t *piRefreshRate, uint32_t iMonitor)
@ -241,81 +213,6 @@ bool C4AbstractApp::GetIndexedDisplayMode(int32_t iIndex, int32_t *piXRes, int32
return r;
}
bool C4X11AppImpl::SwitchToFullscreen(C4AbstractApp * pApp, C4Window * pWindow)
{
Display * const dpy = gdk_x11_display_get_xdisplay(gdk_display_get_default());
if (xf86vmode_major_version >= 0 && xrandr_major_version < 0 &&
memcmp(&xf86vmode_targetmode, &xf86vmode_oldmode, sizeof(XF86VidModeModeInfo)))
{
XF86VidModeModeInfo & mode = xf86vmode_targetmode;
XResizeWindow(dpy, pWindow->wnd, mode.hdisplay, mode.vdisplay);
XSizeHints hints;
hints.flags = PMinSize | PMaxSize;
hints.min_width = mode.hdisplay;
hints.min_height = mode.vdisplay;
hints.max_width = mode.hdisplay;
hints.max_height = mode.vdisplay;
XSetWMNormalHints(dpy, pWindow->wnd, &hints);
XF86VidModeSwitchToMode(dpy, DefaultScreen(dpy), &mode);
// Move the viewport on the virtual screen
Window bla; int wnd_x = 0; int wnd_y = 0;
XTranslateCoordinates(dpy, pWindow->wnd, DefaultRootWindow(dpy), 0, 0, &wnd_x, &wnd_y, &bla);
XF86VidModeSetViewPort(dpy, DefaultScreen(dpy), wnd_x, wnd_y);
GdkWindow * wnd = gtk_widget_get_window(GTK_WIDGET(pWindow->window));
gdk_pointer_grab(wnd, true, GdkEventMask(0), wnd, NULL, gdk_x11_display_get_user_time(gdk_display_get_default()));
return true;
}
if (xrandr_major_version >= 0 && !(wdt == -1 && hgt == -1))
{
XRRScreenConfiguration * conf = XRRGetScreenInfo (dpy, pWindow->wnd);
xrandr_oldmode = XRRConfigCurrentConfiguration (conf, &xrandr_rot);
int n;
XRRScreenSize * sizes = XRRConfigSizes(conf, &n);
for (int i = 0; i < n; ++i)
{
if (sizes[i].width == wdt && sizes[i].height == hgt)
{
#ifdef _DEBUG
LogF("XRRSetScreenConfig %d", i);
#endif
XRRSetScreenConfig (dpy, conf, pWindow->wnd, i, xrandr_rot, CurrentTime);
break;
}
}
XRRFreeScreenConfigInfo(conf);
}
gtk_window_fullscreen(GTK_WINDOW(pWindow->window));
return true;
}
void C4X11AppImpl::SwitchToDesktop(C4AbstractApp * pApp, C4Window * pWindow)
{
Display * const dpy = gdk_x11_display_get_xdisplay(gdk_display_get_default());
if (xf86vmode_major_version >= 0 && xrandr_major_version < 0 &&
memcmp(&xf86vmode_targetmode, &xf86vmode_oldmode, sizeof(XF86VidModeModeInfo)))
{
XF86VidModeModeInfo & mode = xf86vmode_oldmode;
XF86VidModeSwitchToMode(dpy, DefaultScreen(dpy), &mode);
XF86VidModeSetViewPort(dpy, DefaultScreen(dpy), 0, 0);
XSizeHints hints;
hints.flags = 0;
XSetWMNormalHints(dpy, pWindow->wnd, &hints);
gdk_pointer_ungrab(gdk_x11_display_get_user_time(gdk_display_get_default()));
return;
}
gtk_window_unfullscreen(GTK_WINDOW(pWindow->window));
// Restore resolution
if (xrandr_major_version >= 0 && !(wdt == -1 && hgt == -1))
{
XRRScreenConfiguration * conf = XRRGetScreenInfo (dpy, pWindow->wnd);
#ifdef _DEBUG
LogF("XRRSetScreenConfig %d (back)", xrandr_oldmode);
#endif
XRRSetScreenConfig (dpy, conf, pWindow->wnd, xrandr_oldmode, xrandr_rot, CurrentTime);
XRRFreeScreenConfigInfo(conf);
}
}
bool C4AbstractApp::ApplyGammaRamp(_D3DGAMMARAMP& ramp, bool fForce)
{
if (!Active && !fForce) return false;

View File

@ -124,16 +124,11 @@ public:
C4GLibProc GLibProc;
C4X11AppImpl(C4AbstractApp *pApp):
GLibProc(g_main_context_default()),
tasked_out(false), pending_desktop(false),
xrandr_oldmode(-1),
argc(0), argv(0)
{
xf86vmode_targetmode.hdisplay = -1;
}
bool SwitchToFullscreen(C4AbstractApp * pApp, C4Window * );
void SwitchToDesktop(C4AbstractApp * pApp, C4Window * );
int xf86vmode_major_version, xf86vmode_minor_version;
XF86VidModeModeInfo xf86vmode_oldmode, xf86vmode_targetmode;
int gammasize; // Size of gamma ramps
int xrandr_major_version, xrandr_minor_version;
@ -141,8 +136,6 @@ public:
unsigned short xrandr_rot;
int xrandr_event;
bool tasked_out; int wdt; int hgt;
bool pending_desktop;
int argc; char ** argv;
};

View File

@ -47,7 +47,6 @@
#ifdef USE_X11
#include <gdk/gdkx.h>
#include <X11/Xlib.h>
#include <X11/extensions/xf86vmode.h>
#include <GL/glx.h>
#endif
@ -475,7 +474,7 @@ static gboolean OnFocusInFS(GtkWidget *widget, GdkEvent *event, gpointer user_d
static gboolean OnFocusOutFS(GtkWidget *widget, GdkEvent *event, gpointer user_data)
{
Application.Active = false;
if (Application.FullScreenMode())
if (Application.FullScreenMode() && Application.GetConfigWidth() != -1)
{
Application.RestoreVideoMode();
gtk_window_iconify(GTK_WINDOW(widget));