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.
stable-5.3
Günther Brammer 2012-11-17 18:07:37 +01:00 committed by Nicolas Hake
parent 66c3c41d5d
commit 3c83efe426
7 changed files with 93 additions and 194 deletions

View File

@ -734,10 +734,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)
@ -1234,13 +1232,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

@ -111,18 +111,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

@ -120,18 +120,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

@ -256,19 +256,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,7 @@ 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 +79,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,196 +141,138 @@ 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)
{
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)
{
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 (!modefound) Priv->xf86vmode_targetmode = *modes[i];
modefound = true;
}
}
XFree(modes);
}
if (!modefound) return false;
fDspModeSet = Priv->SwitchToFullscreen(this, pWindow);
return fDspModeSet;
}
void C4AbstractApp::RestoreVideoMode()
{
if (fDspModeSet)
{
Priv->SwitchToDesktop(this, pWindow);
fDspModeSet = false;
}
}
bool C4AbstractApp::GetIndexedDisplayMode(int32_t iIndex, int32_t *piXRes, int32_t *piYRes, int32_t *piBitDepth, int32_t *piRefreshRate, uint32_t iMonitor)
{
if (Priv->xf86vmode_major_version < 0) return false;
bool r = false;
int mode_num;
XF86VidModeModeInfo **modes;
Display * const dpy = gdk_x11_display_get_xdisplay(gdk_display_get_default());
XF86VidModeGetAllModeLines(dpy, DefaultScreen(dpy), &mode_num, &modes);
if (iIndex < mode_num)
{
*piXRes = modes[iIndex]->hdisplay;
*piYRes = modes[iIndex]->vdisplay;
*piBitDepth = 32;
r = true;
}
XFree(modes);
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))
if (Priv->xrandr_major_version >= 0 && !(iXRes == -1 && iYRes == -1))
{
// randr spec says to always get fresh info, so don't cache.
XRRScreenConfiguration * conf = XRRGetScreenInfo (dpy, pWindow->wnd);
xrandr_oldmode = XRRConfigCurrentConfiguration (conf, &xrandr_rot);
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)
{
if (sizes[i].width == wdt && sizes[i].height == hgt)
if (sizes[i].width == iXRes && sizes[i].height == iYRes)
{
#ifdef _DEBUG
LogF("XRRSetScreenConfig %d", i);
#endif
XRRSetScreenConfig (dpy, conf, pWindow->wnd, i, xrandr_rot, CurrentTime);
fDspModeSet = XRRSetScreenConfig(dpy, conf, pWindow->wnd, i, Priv->xrandr_rot, CurrentTime) == RRSetConfigSuccess;
break;
}
}
XRRFreeScreenConfigInfo(conf);
}
gtk_window_fullscreen(GTK_WINDOW(pWindow->window));
return true;
if (fDspModeSet)
gtk_window_fullscreen(GTK_WINDOW(pWindow->window));
return fDspModeSet;
}
void C4X11AppImpl::SwitchToDesktop(C4AbstractApp * pApp, C4Window * pWindow)
void C4AbstractApp::RestoreVideoMode()
{
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()));
if (!fDspModeSet)
return;
}
gtk_window_unfullscreen(GTK_WINDOW(pWindow->window));
// Restore resolution
if (xrandr_major_version >= 0 && !(wdt == -1 && hgt == -1))
Display * const dpy = gdk_x11_display_get_xdisplay(gdk_display_get_default());
if (Priv->xrandr_major_version >= 0 && Priv->xrandr_oldmode != -1)
{
XRRScreenConfiguration * conf = XRRGetScreenInfo (dpy, pWindow->wnd);
#ifdef _DEBUG
LogF("XRRSetScreenConfig %d (back)", xrandr_oldmode);
LogF("XRRSetScreenConfig %d (back)", Priv->xrandr_oldmode);
#endif
XRRSetScreenConfig (dpy, conf, pWindow->wnd, xrandr_oldmode, xrandr_rot, CurrentTime);
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)
{
Display * const dpy = gdk_x11_display_get_xdisplay(gdk_display_get_default());
int n;
XRRScreenSize * sizes = XRRSizes(dpy, XDefaultScreen(dpy), &n);
if (iIndex < n && iIndex >= 0)
{
*piXRes = sizes[iIndex].width;
*piYRes = sizes[iIndex].height;
*piBitDepth = 32;
return true;
}
return false;
}
bool C4AbstractApp::ApplyGammaRamp(_D3DGAMMARAMP& ramp, bool fForce)
{
fprintf(stderr,"ApplyGammaRamp\n");
if (!Active && !fForce) return false;
if (Priv->xf86vmode_major_version < 2) return false;
if (Priv->xrandr_major_version < 1 || Priv->xrandr_minor_version < 3) return false;
if (Priv->gammasize != 256) return false;
Display * const dpy = gdk_x11_display_get_xdisplay(gdk_display_get_default());
return XF86VidModeSetGammaRamp(dpy, DefaultScreen(dpy), 256,
ramp.red, ramp.green, ramp.blue);
XRRCrtcGamma g = { Priv->gammasize, ramp.red, ramp.green, ramp.blue };
XRRScreenResources * r = XRRGetScreenResources(dpy, pWindow->wnd);
if (!r)
{
Log(" Error setting gamma ramp: XRRGetScreenResources");
return false;
}
XRROutputInfo * i = XRRGetOutputInfo(dpy, r, XRRGetOutputPrimary(dpy, pWindow->wnd));
XRRFreeScreenResources(r);
if (!i)
{
Log(" Error setting gamma ramp: XRRGetOutputInfo");
return false;
}
XRRSetCrtcGamma(dpy, i->crtc, &g);
XRRFreeOutputInfo(i);
return true;
}
bool C4AbstractApp::SaveDefaultGammaRamp(_D3DGAMMARAMP& ramp)
{
if (Priv->xf86vmode_major_version < 2) return false;
// Get the Display
fprintf(stderr,"SaveDefaultGammaRamp\n");
if (Priv->xrandr_major_version < 1 || Priv->xrandr_minor_version < 3) return false;
Display * const dpy = gdk_x11_display_get_xdisplay(gdk_display_get_default());
XF86VidModeGetGammaRampSize(dpy, DefaultScreen(dpy), &Priv->gammasize);
XRRScreenResources * r = XRRGetScreenResources(dpy, pWindow->wnd);
if (!r)
{
Log(" Error getting default gamma ramp: XRRGetScreenResources");
return false;
}
XRROutputInfo * i = XRRGetOutputInfo(dpy, r, XRRGetOutputPrimary(dpy, pWindow->wnd));
XRRFreeScreenResources(r);
if (!i)
{
Log(" Error getting default gamma ramp: XRRGetOutputInfo");
return false;
}
XRRCrtcGamma * g = XRRGetCrtcGamma(dpy, i->crtc);
XRRFreeOutputInfo(i);
if (!g)
{
Log(" Error getting default gamma ramp: XRRGetCrtcGamma");
return false;
}
Priv->gammasize = g->size;
if (Priv->gammasize != 256)
{
LogF(" Size of GammaRamp is %d, not 256", Priv->gammasize);
}
else
{
// store default gamma
if (!XF86VidModeGetGammaRamp(dpy, DefaultScreen(dpy), 256,
ramp.red, ramp.green, ramp.blue))
{
Log(" Error getting default gamma ramp; using standard");
return false;
}
memcpy(ramp.red, g->red, sizeof(ramp.red));
memcpy(ramp.green, g->green, sizeof(ramp.green));
memcpy(ramp.blue, g->blue, sizeof(ramp.blue));
}
return true;
XRRFreeGamma(g);
}
// Copy the text to the clipboard or the primary selection

View File

@ -124,13 +124,11 @@ public:
C4GLibProc GLibProc;
C4X11AppImpl(C4AbstractApp *pApp):
GLibProc(g_main_context_default()),
tasked_out(false), pending_desktop(false),
argc(0), argv(0) { }
bool SwitchToFullscreen(C4AbstractApp * pApp, C4Window * );
void SwitchToDesktop(C4AbstractApp * pApp, C4Window * );
xrandr_oldmode(-1),
argc(0), argv(0)
{
}
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;
@ -138,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));