From: <sp...@us...> - 2010-07-09 18:44:37
|
Revision: 3368 http://java-game-lib.svn.sourceforge.net/java-game-lib/?rev=3368&view=rev Author: spasi Date: 2010-07-09 18:44:31 +0000 (Fri, 09 Jul 2010) Log Message: ----------- Compiz LFS improvements. Modified Paths: -------------- trunk/LWJGL/src/java/org/lwjgl/opengl/LinuxDisplay.java Modified: trunk/LWJGL/src/java/org/lwjgl/opengl/LinuxDisplay.java =================================================================== --- trunk/LWJGL/src/java/org/lwjgl/opengl/LinuxDisplay.java 2010-07-08 21:12:20 UTC (rev 3367) +++ trunk/LWJGL/src/java/org/lwjgl/opengl/LinuxDisplay.java 2010-07-09 18:44:31 UTC (rev 3368) @@ -53,6 +53,9 @@ import java.security.AccessController; import java.security.PrivilegedAction; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; final class LinuxDisplay implements DisplayImplementation { /* X11 constants */ @@ -455,7 +458,7 @@ private static native void mapRaised(long display, long window); private static native void reparentWindow(long display, long window, long parent, int x, int y); - private boolean isAncestorXEmbedded(long window) throws LWJGLException { + private static boolean isAncestorXEmbedded(long window) throws LWJGLException { long xembed_atom = internAtom("_XEMBED_INFO", true); if (xembed_atom != None) { long w = window; @@ -1249,16 +1252,19 @@ } /** - * Helper class for managing Compiz's workarounds. + * Helper class for managing Compiz's workarounds. We need this to enable Legacy + * Fullscreen Support in Compiz, else we'll have trouble with fullscreen windows + * when Compiz effects are enabled. + * + * Implementation Note: This code is probably too much for an inner class, but + * keeping it here until we're sure we cannot find a better solution. */ private static final class Compiz { - private static final String LEGACY_FULLSCREEN_SUPPORT = "/org/freedesktop/compiz/workarounds/allscreens/legacy_fullscreen"; + private static boolean applyFix; - private static boolean dbusAvailable; + private static Provider provider; - private static boolean legacyFullscreenSupport; - private Compiz() { } @@ -1269,24 +1275,110 @@ AccessController.doPrivileged(new PrivilegedAction() { public Object run() { try { - legacyFullscreenSupport = getBoolean(LEGACY_FULLSCREEN_SUPPORT); - dbusAvailable = true; + // Check if Compiz is active + if ( !isProcessActive("compiz") ) + return null; + + provider = null; + + String providerName = null; + + // Check if Dbus is available + if ( isProcessActive("dbus-daemon") ) { + providerName = "Dbus"; + provider = new Provider() { + + private static final String KEY = "/org/freedesktop/compiz/workarounds/allscreens/legacy_fullscreen"; + + public boolean hasLegacyFullscreenSupport() throws LWJGLException { + final List output = Compiz.run(new String[] { + "dbus-send", "--print-reply", "--type=method_call", "--dest=org.freedesktop.compiz", KEY, "org.freedesktop.compiz.get" + }); + + if ( output == null || output.size() < 2 ) + throw new LWJGLException("Invalid Dbus reply."); + + String line = (String)output.get(0); + + if ( !line.startsWith("method return") ) + throw new LWJGLException("Invalid Dbus reply."); + + line = ((String)output.get(1)).trim(); // value + if ( !line.startsWith("boolean") || line.length() < 12) + throw new LWJGLException("Invalid Dbus reply."); + + return "true".equalsIgnoreCase(line.substring("boolean".length() + 1)); + } + + public void setLegacyFullscreenSupport(final boolean state) throws LWJGLException { + if ( Compiz.run(new String[] { + "dbus-send", "--type=method_call", "--dest=org.freedesktop.compiz", KEY, "org.freedesktop.compiz.set", "boolean:" + Boolean.toString(state) + }) == null ) + throw new LWJGLException("Failed to apply Compiz LFS workaround."); + } + }; + } else { + try { + // Check if Gconf is available + Runtime.getRuntime().exec("gconftool"); + + providerName = "gconftool"; + provider = new Provider() { + + private static final String KEY = "/apps/compiz/plugins/workarounds/allscreens/options/legacy_fullscreen"; + + public boolean hasLegacyFullscreenSupport() throws LWJGLException { + final List output = Compiz.run(new String[] { + "gconftool", "-g", KEY + }); + + if ( output == null || output.size() == 0 ) + throw new LWJGLException("Invalid gconftool reply."); + + return Boolean.parseBoolean(((String)output.get(0)).trim()); + } + + public void setLegacyFullscreenSupport(final boolean state) throws LWJGLException { + if ( Compiz.run(new String[] { + "gconftool", "-s", KEY, "-s", Boolean.toString(state), "-t", "bool" + }) == null ) + throw new LWJGLException("Failed to apply Compiz LFS workaround."); + + try { + // gconftool will not apply the workaround immediately, sleep a bit + // to make sure it will be ok when we create the window. + Thread.sleep(200); // 100 is too low, 150 works, set to 200 to be safe. + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + }; + } catch (IOException e) { + // Ignore + } + } + + if ( provider != null && !provider.hasLegacyFullscreenSupport() ) { // No need to do anything is LFS is already enabled. + applyFix = true; + LWJGLUtil.log("Using " + providerName + " to apply Compiz LFS workaround."); + } } catch (LWJGLException e) { - LWJGLUtil.log("Compiz Dbus communication failed. Reason: " + e.getMessage()); + // Ignore + } finally { + return null; } - return null; } }); } static void setLegacyFullscreenSupport(final boolean enabled) { - if ( !dbusAvailable || legacyFullscreenSupport ) + if ( !applyFix ) return; AccessController.doPrivileged(new PrivilegedAction() { public Object run() { try { - setBoolean(LEGACY_FULLSCREEN_SUPPORT, enabled); + provider.setLegacyFullscreenSupport(enabled); } catch (LWJGLException e) { LWJGLUtil.log("Failed to change Compiz Legacy Fullscreen Support. Reason: " + e.getMessage()); } @@ -1295,48 +1387,54 @@ }); } - private static boolean getBoolean(final String option) throws LWJGLException { + private static List run(final String[] command) throws LWJGLException { + final List output = new ArrayList(); + try { - final Process p = Runtime.getRuntime().exec(new String[] { - "dbus-send", "--print-reply", "--type=method_call", "--dest=org.freedesktop.compiz", option, "org.freedesktop.compiz.get" - }); - final int exitValue = p.waitFor(); - if ( exitValue != 0 ) - throw new LWJGLException("Dbus error."); + final Process p = Runtime.getRuntime().exec(command); + try { + final int exitValue = p.waitFor(); + if ( exitValue != 0 ) + return null; + } catch (InterruptedException e) { + throw new LWJGLException("Process interrupted.", e); + } final BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream())); - String reply = br.readLine(); // header - if ( !reply.startsWith("method return") ) - throw new LWJGLException("Invalid Dbus reply."); + String line; + while ( (line = br.readLine()) != null ) + output.add(line); - reply = br.readLine().trim(); // value - if ( !reply.startsWith("boolean") ) - throw new LWJGLException("Invalid Dbus reply."); + br.close(); + } catch (final IOException e) { + throw new LWJGLException("Process failed.", e); + } - return "true".equalsIgnoreCase(reply.substring("boolean".length() + 1)); - } catch (IOException e) { - throw new LWJGLException("Dbus command failed.", e); - } catch (InterruptedException e) { - throw new LWJGLException("Dbus command failed.", e); - } + return output; } - private static void setBoolean(final String option, final boolean value) throws LWJGLException { - try { - final Process p = Runtime.getRuntime().exec(new String[] { - "dbus-send", "--type=method_call", "--dest=org.freedesktop.compiz", option, "org.freedesktop.compiz.set", "boolean:" + Boolean.toString(value) - }); - final int exitValue = p.waitFor(); - if ( exitValue != 0 ) - throw new LWJGLException("Dbus error."); - } catch (IOException e) { - throw new LWJGLException("Dbus command failed.", e); - } catch (InterruptedException e) { - throw new LWJGLException("Dbus command failed.", e); + private static boolean isProcessActive(final String processName) throws LWJGLException { + final List output = run(new String[] { "ps", "-C", processName }); + if ( output == null ) + return false; + + for ( Iterator iter = output.iterator(); iter.hasNext(); ) { + final String line = (String)iter.next(); + if ( line.contains(processName) ); + return true; } + + return false; } + private interface Provider { + + boolean hasLegacyFullscreenSupport() throws LWJGLException; + + void setLegacyFullscreenSupport(boolean state) throws LWJGLException; + + } } } \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |