linux: use xrandr for all display mode changing
This commit is contained in:
parent
50c0c30499
commit
b83d29e265
|
@ -129,7 +129,6 @@ final class LinuxDisplay implements DisplayImplementation {
|
|||
private DisplayMode saved_mode;
|
||||
private DisplayMode current_mode;
|
||||
|
||||
private Screen[] savedXrandrConfig;
|
||||
|
||||
private boolean keyboard_grabbed;
|
||||
private boolean pointer_grabbed;
|
||||
|
@ -603,12 +602,17 @@ final class LinuxDisplay implements DisplayImplementation {
|
|||
}
|
||||
|
||||
private void switchDisplayModeOnTmpDisplay(DisplayMode mode) throws LWJGLException {
|
||||
incDisplay();
|
||||
try {
|
||||
nSwitchDisplayMode(getDisplay(), getDefaultScreen(), current_displaymode_extension, mode);
|
||||
} finally {
|
||||
decDisplay();
|
||||
}
|
||||
if (current_displaymode_extension == XRANDR) {
|
||||
// let Xrandr set the display mode
|
||||
XRandR.setConfiguration(XRandR.toScreen(mode));
|
||||
} else {
|
||||
incDisplay();
|
||||
try {
|
||||
nSwitchDisplayMode(getDisplay(), getDefaultScreen(), current_displaymode_extension, mode);
|
||||
} finally {
|
||||
decDisplay();
|
||||
}
|
||||
}
|
||||
}
|
||||
private static native void nSwitchDisplayMode(long display, int screen, int extension, DisplayMode mode) throws LWJGLException;
|
||||
|
||||
|
@ -625,11 +629,11 @@ final class LinuxDisplay implements DisplayImplementation {
|
|||
public void resetDisplayMode() {
|
||||
lockAWT();
|
||||
try {
|
||||
if( current_displaymode_extension == XRANDR && savedXrandrConfig.length > 0 )
|
||||
if( current_displaymode_extension == XRANDR )
|
||||
{
|
||||
AccessController.doPrivileged(new PrivilegedAction<Object>() {
|
||||
public Object run() {
|
||||
XRandR.setConfiguration( savedXrandrConfig );
|
||||
XRandR.restoreConfiguration();
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
@ -727,12 +731,12 @@ final class LinuxDisplay implements DisplayImplementation {
|
|||
throw new LWJGLException("No modes available");
|
||||
switch (current_displaymode_extension) {
|
||||
case XRANDR:
|
||||
savedXrandrConfig = AccessController.doPrivileged(new PrivilegedAction<Screen[]>() {
|
||||
public Screen[] run() {
|
||||
return XRandR.getConfiguration();
|
||||
saved_mode = AccessController.doPrivileged(new PrivilegedAction<DisplayMode>() {
|
||||
public DisplayMode run() {
|
||||
XRandR.saveConfiguration();
|
||||
return XRandR.toDisplayMode(XRandR.getConfiguration());
|
||||
}
|
||||
});
|
||||
saved_mode = getCurrentXRandrMode();
|
||||
break;
|
||||
case XF86VIDMODE:
|
||||
saved_mode = modes[0];
|
||||
|
@ -929,13 +933,24 @@ final class LinuxDisplay implements DisplayImplementation {
|
|||
public DisplayMode[] getAvailableDisplayModes() throws LWJGLException {
|
||||
lockAWT();
|
||||
try {
|
||||
incDisplay();
|
||||
try {
|
||||
DisplayMode[] modes = nGetAvailableDisplayModes(getDisplay(), getDefaultScreen(), current_displaymode_extension);
|
||||
return modes;
|
||||
} finally {
|
||||
decDisplay();
|
||||
}
|
||||
incDisplay();
|
||||
if (current_displaymode_extension == XRANDR) {
|
||||
// nGetAvailableDisplayModes cannot be trusted. Use xrandr
|
||||
Screen[] resolutions = XRandR.getResolutions(XRandR.getScreenNames()[0]);
|
||||
// quick hack, copy Screens to DisplayModes (todo: get bpp from somewhere, instead of using 24 as default)
|
||||
DisplayMode[] modes = new DisplayMode[resolutions.length];
|
||||
for (int i = 0; i < modes.length; i++) {
|
||||
modes[i] = new DisplayMode(resolutions[i].width, resolutions[i].height, 24, resolutions[i].freq);
|
||||
}
|
||||
return modes;
|
||||
} else {
|
||||
try {
|
||||
DisplayMode[] modes = nGetAvailableDisplayModes(getDisplay(), getDefaultScreen(), current_displaymode_extension);
|
||||
return modes;
|
||||
} finally {
|
||||
decDisplay();
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
unlockAWT();
|
||||
}
|
||||
|
@ -1101,11 +1116,11 @@ final class LinuxDisplay implements DisplayImplementation {
|
|||
if (current_window_mode == FULLSCREEN_NETWM) {
|
||||
nIconifyWindow(getDisplay(), getWindow(), getDefaultScreen());
|
||||
try {
|
||||
if( current_displaymode_extension == XRANDR && savedXrandrConfig.length > 0 )
|
||||
if( current_displaymode_extension == XRANDR )
|
||||
{
|
||||
AccessController.doPrivileged(new PrivilegedAction<Object>() {
|
||||
public Object run() {
|
||||
XRandR.setConfiguration( savedXrandrConfig );
|
||||
XRandR.restoreConfiguration();
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
|
|
@ -49,6 +49,18 @@ public class XRandR
|
|||
{
|
||||
private static Screen[] current;
|
||||
|
||||
/**
|
||||
* Either the screen marked as "primary" (if it is turned on)
|
||||
* or the one with the largest (current) resolution.
|
||||
*/
|
||||
private static String primaryScreenIdentifier;
|
||||
|
||||
/**
|
||||
* Used to save the configuration of all output devices to
|
||||
* restore it on exit or in case of crash.
|
||||
*/
|
||||
private static Screen[] savedConfiguration;
|
||||
|
||||
private static Map<String, Screen[]> screens;
|
||||
|
||||
private static void populate()
|
||||
|
@ -89,7 +101,13 @@ public class XRandR
|
|||
name = sa[ 0 ];
|
||||
|
||||
// save position of this screen, will be used later when current modeline is parsed
|
||||
parseScreenHeader(currentScreenPosition, "primary".equals(sa[ 2 ]) ? sa[ 3 ] : sa[ 2 ]);
|
||||
if ("primary".equals(sa[ 2 ])) {
|
||||
parseScreenHeader(currentScreenPosition, sa[ 3 ]);
|
||||
// save primary
|
||||
primaryScreenIdentifier = name;
|
||||
} else {
|
||||
parseScreenHeader(currentScreenPosition, sa[ 2 ]);
|
||||
}
|
||||
}
|
||||
else if( Pattern.matches( "\\d*x\\d*", sa[ 0 ] ) )
|
||||
{
|
||||
|
@ -106,6 +124,17 @@ public class XRandR
|
|||
screens.put( name, possibles.toArray( new Screen[ possibles.size() ] ) );
|
||||
|
||||
current = currentList.toArray(new Screen[currentList.size()]);
|
||||
|
||||
// set primary to largest screen if not set yet
|
||||
if (primaryScreenIdentifier == null) {
|
||||
long totalPixels = Long.MIN_VALUE;
|
||||
for (Screen screen : current) {
|
||||
if (1l * screen.width * screen.height > totalPixels) {
|
||||
primaryScreenIdentifier = screen.name;
|
||||
totalPixels = 1l * screen.width * screen.height;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch( Throwable e )
|
||||
{
|
||||
|
@ -117,13 +146,22 @@ public class XRandR
|
|||
}
|
||||
|
||||
/**
|
||||
* @return The current screen configuration, or an empty array if
|
||||
* xrandr is not supported
|
||||
* @return The current screen configuration of the primary device,
|
||||
* or an empty array if xrandr is not supported
|
||||
*/
|
||||
public static Screen[] getConfiguration()
|
||||
{
|
||||
populate();
|
||||
|
||||
// find and return primary
|
||||
for (Screen screen : current) {
|
||||
if (screen.name.equals(primaryScreenIdentifier)) {
|
||||
System.out.println("getConfiguration returned " + screen.width + "x" + screen.height + " @" + screen.freq);
|
||||
return new Screen[]{screen};
|
||||
}
|
||||
}
|
||||
|
||||
// problem with primary device, fall back to old behaviour
|
||||
return current.clone();
|
||||
}
|
||||
|
||||
|
@ -184,6 +222,25 @@ public class XRandR
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the current configuration for all connected display devices.
|
||||
* This configuration can be restored on exit/crash by calling
|
||||
* restoreConfiguration()
|
||||
*/
|
||||
public static void saveConfiguration() {
|
||||
savedConfiguration = current.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Restores the configuration for all connected display devices.
|
||||
* Used on exit or in case of a crash to reset all devices.
|
||||
*/
|
||||
public static void restoreConfiguration() {
|
||||
if (savedConfiguration != null) {
|
||||
setConfiguration(savedConfiguration);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the name of connected screens, or an empty array if
|
||||
* xrandr is not supported
|
||||
|
@ -275,6 +332,18 @@ public class XRandR
|
|||
screenPosition[1] = Integer.parseInt(m.group(4));
|
||||
}
|
||||
|
||||
static Screen toScreen(DisplayMode mode) {
|
||||
populate();
|
||||
// test: use first screen in list
|
||||
// TODO: replace with "primary"
|
||||
return new Screen(current[0].name, mode.getWidth(), mode.getHeight(), mode.getFrequency(), current[0].xPos, current[0].yPos);
|
||||
}
|
||||
|
||||
static DisplayMode toDisplayMode(Screen... screens) {
|
||||
// todo: use "primary" screen
|
||||
return new DisplayMode(screens[0].width, screens[0].height, 24, screens[0].freq);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encapsulates the configuration of a monitor.
|
||||
* Resolution and freq are fixed, position is mutable
|
||||
|
|
Loading…
Reference in New Issue