winex11.drv: Migrate XRandR 1.0 display settings handler to a new interface.
Signed-off-by: Zhiyi Zhang <zzhang@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
d13b61b738
commit
5491e939bc
|
@ -83,11 +83,6 @@ MAKE_FUNCPTR(XRRFreeProviderInfo)
|
||||||
|
|
||||||
#undef MAKE_FUNCPTR
|
#undef MAKE_FUNCPTR
|
||||||
|
|
||||||
static struct x11drv_mode_info *dd_modes;
|
|
||||||
static SizeID *xrandr10_modes;
|
|
||||||
static unsigned int xrandr_mode_count;
|
|
||||||
static int xrandr_current_mode = -1;
|
|
||||||
|
|
||||||
static int load_xrandr(void)
|
static int load_xrandr(void)
|
||||||
{
|
{
|
||||||
int r = 0;
|
int r = 0;
|
||||||
|
@ -144,157 +139,187 @@ static int XRandRErrorHandler(Display *dpy, XErrorEvent *event, void *arg)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int xrandr10_get_current_mode(void)
|
/* XRandR 1.0 display settings handler */
|
||||||
|
static BOOL xrandr10_get_id( const WCHAR *device_name, ULONG_PTR *id )
|
||||||
{
|
{
|
||||||
SizeID size;
|
WCHAR primary_adapter[CCHDEVICENAME];
|
||||||
Rotation rot;
|
|
||||||
XRRScreenConfiguration *sc;
|
|
||||||
short rate;
|
|
||||||
unsigned int i;
|
|
||||||
int res = -1;
|
|
||||||
|
|
||||||
if (xrandr_current_mode != -1)
|
if (!get_primary_adapter( primary_adapter ))
|
||||||
return xrandr_current_mode;
|
return FALSE;
|
||||||
|
|
||||||
sc = pXRRGetScreenInfo (gdi_display, DefaultRootWindow( gdi_display ));
|
/* RandR 1.0 only supports changing the primary adapter settings.
|
||||||
size = pXRRConfigCurrentConfiguration (sc, &rot);
|
* For non-primary adapters, an id is still provided but getting
|
||||||
rate = pXRRConfigCurrentRate (sc);
|
* and changing non-primary adapters' settings will be ignored. */
|
||||||
pXRRFreeScreenConfigInfo(sc);
|
*id = !lstrcmpiW( device_name, primary_adapter ) ? 1 : 0;
|
||||||
|
return TRUE;
|
||||||
for (i = 0; i < xrandr_mode_count; ++i)
|
|
||||||
{
|
|
||||||
if (xrandr10_modes[i] == size && dd_modes[i].refresh_rate == rate)
|
|
||||||
{
|
|
||||||
res = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (res == -1)
|
|
||||||
{
|
|
||||||
ERR("In unknown mode, returning default\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
xrandr_current_mode = res;
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static LONG xrandr10_set_current_mode( int mode )
|
static void add_xrandr10_mode( DEVMODEW *mode, DWORD depth, DWORD width, DWORD height,
|
||||||
|
DWORD frequency, SizeID size_id )
|
||||||
{
|
{
|
||||||
SizeID size;
|
mode->dmSize = sizeof(*mode);
|
||||||
Rotation rot;
|
mode->dmDriverExtra = sizeof(SizeID);
|
||||||
Window root;
|
mode->dmFields = DM_DISPLAYORIENTATION | DM_BITSPERPEL | DM_PELSWIDTH |
|
||||||
XRRScreenConfiguration *sc;
|
DM_PELSHEIGHT | DM_DISPLAYFLAGS;
|
||||||
Status stat;
|
if (frequency)
|
||||||
|
{
|
||||||
|
mode->dmFields |= DM_DISPLAYFREQUENCY;
|
||||||
|
mode->dmDisplayFrequency = frequency;
|
||||||
|
}
|
||||||
|
mode->u1.s2.dmDisplayOrientation = DMDO_DEFAULT;
|
||||||
|
mode->dmBitsPerPel = depth;
|
||||||
|
mode->dmPelsWidth = width;
|
||||||
|
mode->dmPelsHeight = height;
|
||||||
|
mode->u2.dmDisplayFlags = 0;
|
||||||
|
memcpy( (BYTE *)mode + sizeof(*mode), &size_id, sizeof(size_id) );
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL xrandr10_get_modes( ULONG_PTR id, DWORD flags, DEVMODEW **new_modes, UINT *new_mode_count )
|
||||||
|
{
|
||||||
|
INT size_idx, depth_idx, rate_idx, mode_idx = 0;
|
||||||
|
INT size_count, rate_count, mode_count = 0;
|
||||||
|
DEVMODEW *modes, *mode;
|
||||||
|
XRRScreenSize *sizes;
|
||||||
|
short *rates;
|
||||||
|
|
||||||
|
sizes = pXRRSizes( gdi_display, DefaultScreen( gdi_display ), &size_count );
|
||||||
|
if (size_count <= 0)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
for (size_idx = 0; size_idx < size_count; ++size_idx)
|
||||||
|
{
|
||||||
|
rates = pXRRRates( gdi_display, DefaultScreen( gdi_display ), size_idx, &rate_count );
|
||||||
|
if (rate_count)
|
||||||
|
mode_count += rate_count;
|
||||||
|
else
|
||||||
|
++mode_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate space for reported modes in three depths, and put an SizeID at the end of DEVMODEW as
|
||||||
|
* driver private data */
|
||||||
|
modes = heap_calloc( mode_count * DEPTH_COUNT, sizeof(*modes) + sizeof(SizeID) );
|
||||||
|
if (!modes)
|
||||||
|
{
|
||||||
|
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_idx = 0; size_idx < size_count; ++size_idx)
|
||||||
|
{
|
||||||
|
for (depth_idx = 0; depth_idx < DEPTH_COUNT; ++depth_idx)
|
||||||
|
{
|
||||||
|
rates = pXRRRates( gdi_display, DefaultScreen( gdi_display ), size_idx, &rate_count );
|
||||||
|
if (!rate_count)
|
||||||
|
{
|
||||||
|
mode = (DEVMODEW *)((BYTE *)modes + (sizeof(*mode) + sizeof(SizeID)) * mode_idx++);
|
||||||
|
add_xrandr10_mode( mode, depths[depth_idx], sizes[size_idx].width,
|
||||||
|
sizes[size_idx].height, 0, size_idx );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (rate_idx = 0; rate_idx < rate_count; ++rate_idx)
|
||||||
|
{
|
||||||
|
mode = (DEVMODEW *)((BYTE *)modes + (sizeof(*mode) + sizeof(SizeID)) * mode_idx++);
|
||||||
|
add_xrandr10_mode( mode, depths[depth_idx], sizes[size_idx].width,
|
||||||
|
sizes[size_idx].height, rates[rate_idx], size_idx );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*new_modes = modes;
|
||||||
|
*new_mode_count = mode_idx;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void xrandr10_free_modes( DEVMODEW *modes )
|
||||||
|
{
|
||||||
|
heap_free( modes );
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL xrandr10_get_current_mode( ULONG_PTR id, DEVMODEW *mode )
|
||||||
|
{
|
||||||
|
XRRScreenConfiguration *screen_config;
|
||||||
|
XRRScreenSize *sizes;
|
||||||
|
Rotation rotation;
|
||||||
|
SizeID size_id;
|
||||||
|
INT size_count;
|
||||||
short rate;
|
short rate;
|
||||||
|
|
||||||
root = DefaultRootWindow( gdi_display );
|
mode->dmFields = DM_DISPLAYORIENTATION | DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT |
|
||||||
sc = pXRRGetScreenInfo (gdi_display, root);
|
DM_DISPLAYFLAGS | DM_DISPLAYFREQUENCY | DM_POSITION;
|
||||||
pXRRConfigCurrentConfiguration (sc, &rot);
|
mode->u1.s2.dmDisplayOrientation = DMDO_DEFAULT;
|
||||||
mode = mode % xrandr_mode_count;
|
mode->u2.dmDisplayFlags = 0;
|
||||||
|
mode->u1.s2.dmPosition.x = 0;
|
||||||
|
mode->u1.s2.dmPosition.y = 0;
|
||||||
|
|
||||||
TRACE("Changing Resolution to %dx%d @%d Hz\n",
|
if (id != 1)
|
||||||
dd_modes[mode].width,
|
|
||||||
dd_modes[mode].height,
|
|
||||||
dd_modes[mode].refresh_rate);
|
|
||||||
|
|
||||||
size = xrandr10_modes[mode];
|
|
||||||
rate = dd_modes[mode].refresh_rate;
|
|
||||||
|
|
||||||
if (rate)
|
|
||||||
stat = pXRRSetScreenConfigAndRate( gdi_display, sc, root, size, rot, rate, CurrentTime );
|
|
||||||
else
|
|
||||||
stat = pXRRSetScreenConfig( gdi_display, sc, root, size, rot, CurrentTime );
|
|
||||||
|
|
||||||
pXRRFreeScreenConfigInfo(sc);
|
|
||||||
|
|
||||||
if (stat == RRSetConfigSuccess)
|
|
||||||
{
|
{
|
||||||
xrandr_current_mode = mode;
|
FIXME("Non-primary adapters are unsupported.\n");
|
||||||
X11DRV_DisplayDevices_Update( TRUE );
|
mode->dmBitsPerPel = 0;
|
||||||
|
mode->dmPelsWidth = 0;
|
||||||
|
mode->dmPelsHeight = 0;
|
||||||
|
mode->dmDisplayFrequency = 0;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
sizes = pXRRSizes( gdi_display, DefaultScreen( gdi_display ), &size_count );
|
||||||
|
if (size_count <= 0)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
screen_config = pXRRGetScreenInfo( gdi_display, DefaultRootWindow( gdi_display ) );
|
||||||
|
size_id = pXRRConfigCurrentConfiguration( screen_config, &rotation );
|
||||||
|
rate = pXRRConfigCurrentRate( screen_config );
|
||||||
|
pXRRFreeScreenConfigInfo( screen_config );
|
||||||
|
|
||||||
|
mode->dmBitsPerPel = screen_bpp;
|
||||||
|
mode->dmPelsWidth = sizes[size_id].width;
|
||||||
|
mode->dmPelsHeight = sizes[size_id].height;
|
||||||
|
mode->dmDisplayFrequency = rate;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static LONG xrandr10_set_current_mode( ULONG_PTR id, DEVMODEW *mode )
|
||||||
|
{
|
||||||
|
XRRScreenConfiguration *screen_config;
|
||||||
|
Rotation rotation;
|
||||||
|
SizeID size_id;
|
||||||
|
Window root;
|
||||||
|
Status stat;
|
||||||
|
|
||||||
|
if (id != 1)
|
||||||
|
{
|
||||||
|
FIXME("Non-primary adapters are unsupported.\n");
|
||||||
return DISP_CHANGE_SUCCESSFUL;
|
return DISP_CHANGE_SUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ERR("Resolution change not successful -- perhaps display has changed?\n");
|
if (is_detached_mode(mode))
|
||||||
return DISP_CHANGE_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void xrandr10_init_modes(void)
|
|
||||||
{
|
|
||||||
XRRScreenSize *sizes;
|
|
||||||
int sizes_count;
|
|
||||||
int i, j, nmodes = 0;
|
|
||||||
|
|
||||||
sizes = pXRRSizes( gdi_display, DefaultScreen(gdi_display), &sizes_count );
|
|
||||||
if (sizes_count <= 0) return;
|
|
||||||
|
|
||||||
TRACE("XRandR: found %d sizes.\n", sizes_count);
|
|
||||||
for (i = 0; i < sizes_count; ++i)
|
|
||||||
{
|
{
|
||||||
int rates_count;
|
FIXME("Detaching adapters is unsupported.\n");
|
||||||
short *rates;
|
return DISP_CHANGE_SUCCESSFUL;
|
||||||
|
|
||||||
rates = pXRRRates( gdi_display, DefaultScreen(gdi_display), i, &rates_count );
|
|
||||||
TRACE("- at %d: %dx%d (%d rates):", i, sizes[i].width, sizes[i].height, rates_count);
|
|
||||||
if (rates_count)
|
|
||||||
{
|
|
||||||
nmodes += rates_count;
|
|
||||||
for (j = 0; j < rates_count; ++j)
|
|
||||||
{
|
|
||||||
if (j > 0)
|
|
||||||
TRACE(",");
|
|
||||||
TRACE(" %d", rates[j]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
++nmodes;
|
|
||||||
TRACE(" <default>");
|
|
||||||
}
|
|
||||||
TRACE(" Hz\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("XRandR modes: count=%d\n", nmodes);
|
if (mode->dmFields & DM_BITSPERPEL && mode->dmBitsPerPel != screen_bpp)
|
||||||
|
WARN("Cannot change screen bit depth from %dbits to %dbits!\n", screen_bpp, mode->dmBitsPerPel);
|
||||||
|
|
||||||
if (!(xrandr10_modes = HeapAlloc( GetProcessHeap(), 0, sizeof(*xrandr10_modes) * nmodes )))
|
root = DefaultRootWindow( gdi_display );
|
||||||
{
|
screen_config = pXRRGetScreenInfo( gdi_display, root );
|
||||||
ERR("Failed to allocate xrandr mode info array.\n");
|
pXRRConfigCurrentConfiguration( screen_config, &rotation );
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
dd_modes = X11DRV_Settings_SetHandlers( "XRandR 1.0",
|
assert( mode->dmDriverExtra == sizeof(SizeID) );
|
||||||
xrandr10_get_current_mode,
|
memcpy( &size_id, (BYTE *)mode + sizeof(*mode), sizeof(size_id) );
|
||||||
xrandr10_set_current_mode,
|
|
||||||
nmodes, 1 );
|
|
||||||
|
|
||||||
xrandr_mode_count = 0;
|
if (mode->dmFields & DM_DISPLAYFREQUENCY && mode->dmDisplayFrequency)
|
||||||
for (i = 0; i < sizes_count; ++i)
|
stat = pXRRSetScreenConfigAndRate( gdi_display, screen_config, root, size_id, rotation,
|
||||||
{
|
mode->dmDisplayFrequency, CurrentTime );
|
||||||
int rates_count;
|
else
|
||||||
short *rates;
|
stat = pXRRSetScreenConfig( gdi_display, screen_config, root, size_id, rotation, CurrentTime );
|
||||||
|
pXRRFreeScreenConfigInfo( screen_config );
|
||||||
|
|
||||||
rates = pXRRRates( gdi_display, DefaultScreen(gdi_display), i, &rates_count );
|
if (stat != RRSetConfigSuccess)
|
||||||
|
return DISP_CHANGE_FAILED;
|
||||||
|
|
||||||
if (rates_count)
|
XFlush( gdi_display );
|
||||||
{
|
return DISP_CHANGE_SUCCESSFUL;
|
||||||
for (j = 0; j < rates_count; ++j)
|
|
||||||
{
|
|
||||||
X11DRV_Settings_AddOneMode( sizes[i].width, sizes[i].height, 0, rates[j] );
|
|
||||||
xrandr10_modes[xrandr_mode_count++] = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
X11DRV_Settings_AddOneMode( sizes[i].width, sizes[i].height, 0, 0 );
|
|
||||||
xrandr10_modes[xrandr_mode_count++] = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
X11DRV_Settings_AddDepthModes();
|
|
||||||
nmodes = X11DRV_Settings_GetModeCount();
|
|
||||||
|
|
||||||
TRACE("Available DD modes: count=%d\n", nmodes);
|
|
||||||
TRACE("Enabling XRandR\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_XRRGETPROVIDERRESOURCES
|
#ifdef HAVE_XRRGETPROVIDERRESOURCES
|
||||||
|
@ -1432,7 +1457,14 @@ void X11DRV_XRandR_Init(void)
|
||||||
|
|
||||||
TRACE("Found XRandR %d.%d.\n", major, minor);
|
TRACE("Found XRandR %d.%d.\n", major, minor);
|
||||||
|
|
||||||
xrandr10_init_modes();
|
settings_handler.name = "XRandR 1.0";
|
||||||
|
settings_handler.priority = 200;
|
||||||
|
settings_handler.get_id = xrandr10_get_id;
|
||||||
|
settings_handler.get_modes = xrandr10_get_modes;
|
||||||
|
settings_handler.free_modes = xrandr10_free_modes;
|
||||||
|
settings_handler.get_current_mode = xrandr10_get_current_mode;
|
||||||
|
settings_handler.set_current_mode = xrandr10_set_current_mode;
|
||||||
|
X11DRV_Settings_SetHandler( &settings_handler );
|
||||||
|
|
||||||
#ifdef HAVE_XRRGETPROVIDERRESOURCES
|
#ifdef HAVE_XRRGETPROVIDERRESOURCES
|
||||||
if (ret >= 4 && (major > 1 || (major == 1 && minor >= 4)))
|
if (ret >= 4 && (major > 1 || (major == 1 && minor >= 4)))
|
||||||
|
|
Loading…
Reference in New Issue