winex11: Add support for XRandR 1.2.
This commit is contained in:
parent
ed331cb0a5
commit
cf6f8d2eb5
|
@ -8607,7 +8607,23 @@ cat >>confdefs.h <<_ACEOF
|
|||
#define SONAME_LIBXRANDR "$ac_cv_lib_soname_Xrandr"
|
||||
_ACEOF
|
||||
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
#include <X11/extensions/Xrandr.h>
|
||||
int
|
||||
main ()
|
||||
{
|
||||
static typeof(XRRGetScreenResources) *f; if (f) return 0;
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_compile "$LINENO"; then :
|
||||
|
||||
$as_echo "#define HAVE_XRRGETSCREENRESOURCES 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
fi
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
|
|
|
@ -1051,7 +1051,12 @@ then
|
|||
then
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <X11/Xlib.h>
|
||||
#include <X11/extensions/Xrandr.h>]], [[static typeof(XRRSetScreenConfigAndRate) * func; if (func) return 0;]])],
|
||||
[WINE_CHECK_SONAME(Xrandr,XRRQueryExtension,,,[$X_LIBS $XLIB $X_EXTRA_LIBS])])
|
||||
[WINE_CHECK_SONAME(Xrandr,XRRQueryExtension,
|
||||
[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <X11/extensions/Xrandr.h>]],
|
||||
[[static typeof(XRRGetScreenResources) *f; if (f) return 0;]])],
|
||||
[AC_DEFINE(HAVE_XRRGETSCREENRESOURCES, 1,
|
||||
[Define if Xrandr has the XRRGetScreenResources function])])],,
|
||||
[$X_LIBS $XLIB $X_EXTRA_LIBS])])
|
||||
fi
|
||||
WINE_NOTICE_WITH(xrandr,[test "x$ac_cv_lib_soname_Xrandr" = "x"],
|
||||
[libxrandr ${notice_platform}development files not found, XRandr won't be supported.])
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
* Wine X11drv Xrandr interface
|
||||
*
|
||||
* Copyright 2003 Alexander James Pasadyn
|
||||
* Copyright 2012 Henri Verbeet for CodeWeavers
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -45,12 +46,24 @@ MAKE_FUNCPTR(XRRRates)
|
|||
MAKE_FUNCPTR(XRRSetScreenConfig)
|
||||
MAKE_FUNCPTR(XRRSetScreenConfigAndRate)
|
||||
MAKE_FUNCPTR(XRRSizes)
|
||||
|
||||
#ifdef HAVE_XRRGETSCREENRESOURCES
|
||||
MAKE_FUNCPTR(XRRFreeCrtcInfo)
|
||||
MAKE_FUNCPTR(XRRFreeOutputInfo)
|
||||
MAKE_FUNCPTR(XRRFreeScreenResources)
|
||||
MAKE_FUNCPTR(XRRGetCrtcInfo)
|
||||
MAKE_FUNCPTR(XRRGetOutputInfo)
|
||||
MAKE_FUNCPTR(XRRGetScreenResources)
|
||||
MAKE_FUNCPTR(XRRSetCrtcConfig)
|
||||
static RRMode *xrandr12_modes;
|
||||
#endif
|
||||
|
||||
#undef MAKE_FUNCPTR
|
||||
|
||||
extern int usexrandr;
|
||||
|
||||
static struct x11drv_mode_info *dd_modes;
|
||||
static SizeID *xrandr_modes;
|
||||
static SizeID *xrandr10_modes;
|
||||
static unsigned int xrandr_mode_count;
|
||||
|
||||
static int load_xrandr(void)
|
||||
|
@ -75,11 +88,20 @@ static int load_xrandr(void)
|
|||
LOAD_FUNCPTR(XRRSetScreenConfig)
|
||||
LOAD_FUNCPTR(XRRSetScreenConfigAndRate)
|
||||
LOAD_FUNCPTR(XRRSizes)
|
||||
r = 1;
|
||||
|
||||
#ifdef HAVE_XRRGETSCREENRESOURCES
|
||||
LOAD_FUNCPTR(XRRFreeCrtcInfo)
|
||||
LOAD_FUNCPTR(XRRFreeOutputInfo)
|
||||
LOAD_FUNCPTR(XRRFreeScreenResources)
|
||||
LOAD_FUNCPTR(XRRGetCrtcInfo)
|
||||
LOAD_FUNCPTR(XRRGetOutputInfo)
|
||||
LOAD_FUNCPTR(XRRGetScreenResources)
|
||||
LOAD_FUNCPTR(XRRSetCrtcConfig)
|
||||
r = 2;
|
||||
#endif
|
||||
#undef LOAD_FUNCPTR
|
||||
|
||||
r = 1; /* success */
|
||||
|
||||
sym_not_found:
|
||||
if (!r) TRACE("Unable to load function ptrs from XRandR library\n");
|
||||
}
|
||||
|
@ -91,7 +113,7 @@ static int XRandRErrorHandler(Display *dpy, XErrorEvent *event, void *arg)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int X11DRV_XRandR_GetCurrentMode(void)
|
||||
static int xrandr10_get_current_mode(void)
|
||||
{
|
||||
SizeID size;
|
||||
Rotation rot;
|
||||
|
@ -110,7 +132,7 @@ static int X11DRV_XRandR_GetCurrentMode(void)
|
|||
wine_tsx11_unlock();
|
||||
for (i = 0; i < xrandr_mode_count; ++i)
|
||||
{
|
||||
if (xrandr_modes[i] == size && dd_modes[i].refresh_rate == rate)
|
||||
if (xrandr10_modes[i] == size && dd_modes[i].refresh_rate == rate)
|
||||
{
|
||||
res = i;
|
||||
break;
|
||||
|
@ -124,7 +146,7 @@ static int X11DRV_XRandR_GetCurrentMode(void)
|
|||
return res;
|
||||
}
|
||||
|
||||
static LONG X11DRV_XRandR_SetCurrentMode(int mode)
|
||||
static LONG xrandr10_set_current_mode( int mode )
|
||||
{
|
||||
SizeID size;
|
||||
Rotation rot;
|
||||
|
@ -144,7 +166,7 @@ static LONG X11DRV_XRandR_SetCurrentMode(int mode)
|
|||
dd_modes[mode].height,
|
||||
dd_modes[mode].refresh_rate);
|
||||
|
||||
size = xrandr_modes[mode];
|
||||
size = xrandr10_modes[mode];
|
||||
rate = dd_modes[mode].refresh_rate;
|
||||
|
||||
if (rate)
|
||||
|
@ -164,7 +186,7 @@ static LONG X11DRV_XRandR_SetCurrentMode(int mode)
|
|||
return DISP_CHANGE_FAILED;
|
||||
}
|
||||
|
||||
static void xrandr_init_modes(void)
|
||||
static void xrandr10_init_modes(void)
|
||||
{
|
||||
XRRScreenSize *sizes;
|
||||
int sizes_count;
|
||||
|
@ -201,15 +223,15 @@ static void xrandr_init_modes(void)
|
|||
|
||||
TRACE("XRandR modes: count=%d\n", nmodes);
|
||||
|
||||
if (!(xrandr_modes = HeapAlloc( GetProcessHeap(), 0, sizeof(*xrandr_modes) * nmodes )))
|
||||
if (!(xrandr10_modes = HeapAlloc( GetProcessHeap(), 0, sizeof(*xrandr10_modes) * nmodes )))
|
||||
{
|
||||
ERR("Failed to allocate xrandr mode info array.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
dd_modes = X11DRV_Settings_SetHandlers( "XRandR",
|
||||
X11DRV_XRandR_GetCurrentMode,
|
||||
X11DRV_XRandR_SetCurrentMode,
|
||||
dd_modes = X11DRV_Settings_SetHandlers( "XRandR 1.0",
|
||||
xrandr10_get_current_mode,
|
||||
xrandr10_set_current_mode,
|
||||
nmodes, 1 );
|
||||
|
||||
xrandr_mode_count = 0;
|
||||
|
@ -225,13 +247,13 @@ static void xrandr_init_modes(void)
|
|||
for (j = 0; j < rates_count; ++j)
|
||||
{
|
||||
X11DRV_Settings_AddOneMode( sizes[i].width, sizes[i].height, 0, rates[j] );
|
||||
xrandr_modes[xrandr_mode_count++] = i;
|
||||
xrandr10_modes[xrandr_mode_count++] = i;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
X11DRV_Settings_AddOneMode( sizes[i].width, sizes[i].height, 0, 0 );
|
||||
xrandr_modes[xrandr_mode_count++] = i;
|
||||
xrandr10_modes[xrandr_mode_count++] = i;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -242,16 +264,189 @@ static void xrandr_init_modes(void)
|
|||
TRACE("Enabling XRandR\n");
|
||||
}
|
||||
|
||||
#ifdef HAVE_XRRGETSCREENRESOURCES
|
||||
|
||||
static int xrandr12_get_current_mode(void)
|
||||
{
|
||||
XRRScreenResources *resources;
|
||||
XRRCrtcInfo *crtc_info;
|
||||
int i, ret = -1;
|
||||
|
||||
wine_tsx11_lock();
|
||||
if (!(resources = pXRRGetScreenResources( gdi_display, root_window )))
|
||||
{
|
||||
wine_tsx11_unlock();
|
||||
ERR("Failed to get screen resources.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!resources->ncrtc || !(crtc_info = pXRRGetCrtcInfo( gdi_display, resources, resources->crtcs[0] )))
|
||||
{
|
||||
pXRRFreeScreenResources( resources );
|
||||
wine_tsx11_unlock();
|
||||
ERR("Failed to get CRTC info.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
TRACE("CRTC 0: mode %#lx, %ux%u+%d+%d.\n", crtc_info->mode,
|
||||
crtc_info->width, crtc_info->height, crtc_info->x, crtc_info->y);
|
||||
|
||||
for (i = 0; i < xrandr_mode_count; ++i)
|
||||
{
|
||||
if (xrandr12_modes[i] == crtc_info->mode)
|
||||
{
|
||||
ret = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pXRRFreeCrtcInfo( crtc_info );
|
||||
pXRRFreeScreenResources( resources );
|
||||
wine_tsx11_unlock();
|
||||
|
||||
if (ret == -1)
|
||||
{
|
||||
ERR("Unknown mode, returning default.\n");
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static LONG xrandr12_set_current_mode( int mode )
|
||||
{
|
||||
Status status = RRSetConfigFailed;
|
||||
XRRScreenResources *resources;
|
||||
XRRCrtcInfo *crtc_info;
|
||||
|
||||
mode = mode % xrandr_mode_count;
|
||||
|
||||
wine_tsx11_lock();
|
||||
if (!(resources = pXRRGetScreenResources( gdi_display, root_window )))
|
||||
{
|
||||
wine_tsx11_unlock();
|
||||
ERR("Failed to get screen resources.\n");
|
||||
return DISP_CHANGE_FAILED;
|
||||
}
|
||||
|
||||
if (!resources->ncrtc || !(crtc_info = pXRRGetCrtcInfo( gdi_display, resources, resources->crtcs[0] )))
|
||||
{
|
||||
pXRRFreeScreenResources( resources );
|
||||
wine_tsx11_unlock();
|
||||
ERR("Failed to get CRTC info.\n");
|
||||
return DISP_CHANGE_FAILED;
|
||||
}
|
||||
|
||||
TRACE("CRTC 0: mode %#lx, %ux%u+%d+%d.\n", crtc_info->mode,
|
||||
crtc_info->width, crtc_info->height, crtc_info->x, crtc_info->y);
|
||||
|
||||
status = pXRRSetCrtcConfig( gdi_display, resources, resources->crtcs[0], CurrentTime, crtc_info->x,
|
||||
crtc_info->y, xrandr12_modes[mode], crtc_info->rotation, crtc_info->outputs, crtc_info->noutput );
|
||||
|
||||
pXRRFreeCrtcInfo( crtc_info );
|
||||
pXRRFreeScreenResources( resources );
|
||||
wine_tsx11_unlock();
|
||||
|
||||
if (status != RRSetConfigSuccess)
|
||||
{
|
||||
ERR("Resolution change not successful -- perhaps display has changed?\n");
|
||||
return DISP_CHANGE_FAILED;
|
||||
}
|
||||
|
||||
X11DRV_resize_desktop( dd_modes[mode].width, dd_modes[mode].height );
|
||||
return DISP_CHANGE_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static void xrandr12_init_modes(void)
|
||||
{
|
||||
XRRScreenResources *resources;
|
||||
XRROutputInfo *output_info;
|
||||
XRRCrtcInfo *crtc_info;
|
||||
int i, j;
|
||||
|
||||
if (!(resources = pXRRGetScreenResources( gdi_display, root_window )))
|
||||
{
|
||||
ERR("Failed to get screen resources.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!resources->ncrtc || !(crtc_info = pXRRGetCrtcInfo( gdi_display, resources, resources->crtcs[0] )))
|
||||
{
|
||||
pXRRFreeScreenResources( resources );
|
||||
ERR("Failed to get CRTC info.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
TRACE("CRTC 0: mode %#lx, %ux%u+%d+%d.\n", crtc_info->mode,
|
||||
crtc_info->width, crtc_info->height, crtc_info->x, crtc_info->y);
|
||||
|
||||
if (!crtc_info->noutput || !(output_info = pXRRGetOutputInfo( gdi_display, resources, crtc_info->outputs[0] )))
|
||||
{
|
||||
pXRRFreeCrtcInfo( crtc_info );
|
||||
pXRRFreeScreenResources( resources );
|
||||
ERR("Failed to get output info.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
TRACE("OUTPUT 0: name %s.\n", debugstr_a(output_info->name));
|
||||
|
||||
if (!output_info->nmode)
|
||||
{
|
||||
ERR("Output has no modes.\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!(xrandr12_modes = HeapAlloc( GetProcessHeap(), 0, sizeof(*xrandr12_modes) * output_info->nmode )))
|
||||
{
|
||||
ERR("Failed to allocate xrandr mode info array.\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
dd_modes = X11DRV_Settings_SetHandlers( "XRandR 1.2",
|
||||
xrandr12_get_current_mode,
|
||||
xrandr12_set_current_mode,
|
||||
output_info->nmode, 1 );
|
||||
|
||||
xrandr_mode_count = 0;
|
||||
for (i = 0; i < output_info->nmode; ++i)
|
||||
{
|
||||
for (j = 0; j < resources->nmode; ++j)
|
||||
{
|
||||
XRRModeInfo *mode = &resources->modes[j];
|
||||
|
||||
if (mode->id == output_info->modes[i])
|
||||
{
|
||||
unsigned int dots = mode->hTotal * mode->vTotal;
|
||||
unsigned int refresh = dots ? (mode->dotClock + dots / 2) / dots : 0;
|
||||
|
||||
TRACE("Adding mode %#lx: %ux%u@%u.\n", mode->id, mode->width, mode->height, refresh);
|
||||
X11DRV_Settings_AddOneMode( mode->width, mode->height, 0, refresh );
|
||||
xrandr12_modes[xrandr_mode_count++] = mode->id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
X11DRV_Settings_AddDepthModes();
|
||||
|
||||
done:
|
||||
pXRRFreeOutputInfo( output_info );
|
||||
pXRRFreeCrtcInfo( crtc_info );
|
||||
pXRRFreeScreenResources( resources );
|
||||
}
|
||||
|
||||
#endif /* HAVE_XRRGETSCREENRESOURCES */
|
||||
|
||||
void X11DRV_XRandR_Init(void)
|
||||
{
|
||||
int event_base, error_base, minor;
|
||||
int event_base, error_base, minor, ret;
|
||||
static int major;
|
||||
Bool ok;
|
||||
|
||||
if (major) return; /* already initialized? */
|
||||
if (!usexrandr) return; /* disabled in config */
|
||||
if (root_window != DefaultRootWindow( gdi_display )) return;
|
||||
if (!load_xrandr()) return; /* can't load the Xrandr library */
|
||||
if (!(ret = load_xrandr())) return; /* can't load the Xrandr library */
|
||||
|
||||
/* see if Xrandr is available */
|
||||
wine_tsx11_lock();
|
||||
|
@ -261,7 +456,13 @@ void X11DRV_XRandR_Init(void)
|
|||
if (X11DRV_check_error() || !ok) goto done;
|
||||
|
||||
TRACE("Found XRandR %d.%d.\n", major, minor);
|
||||
xrandr_init_modes();
|
||||
|
||||
#ifdef HAVE_XRRGETSCREENRESOURCES
|
||||
if (ret >= 2 && (major > 1 || (major == 1 && minor >= 2)))
|
||||
xrandr12_init_modes();
|
||||
else
|
||||
#endif
|
||||
xrandr10_init_modes();
|
||||
|
||||
done:
|
||||
wine_tsx11_unlock();
|
||||
|
|
|
@ -1145,6 +1145,9 @@
|
|||
/* Define if Xrender has the XRenderSetPictureTransform function */
|
||||
#undef HAVE_XRENDERSETPICTURETRANSFORM
|
||||
|
||||
/* Define if Xrandr has the XRRGetScreenResources function */
|
||||
#undef HAVE_XRRGETSCREENRESOURCES
|
||||
|
||||
/* Define to 1 if you have the `z' library (-lz). */
|
||||
#undef HAVE_ZLIB
|
||||
|
||||
|
|
Loading…
Reference in New Issue