LWJGL Forum

Programming => Lightweight Java Gaming Library => Topic started by: Matthias on May 20, 2010, 17:12:38

Title: Patch for XrandR.java
Post by: Matthias on May 20, 2010, 17:12:38
ok - next try (first try was killed by this great forum software!)

The following "xrandr -q" output causes a ArrayIndexOutOfBoundsException in XrandR.java: Screen 0: minimum 320 x 200, current 3360 x 1050, maximum 8192 x 8192
VGA-0 connected 1680x1050+0+0 (normal left inverted right x axis y axis) 434mm x 270mm
   1680x1050      60.0*+
   1280x1024      75.0     60.0 
   1152x864       75.0 
   1024x768       75.1     60.0 
   800x600        75.0     60.3 
   640x480        75.0     60.0 
   720x400        70.1 
LVDS connected (normal left inverted right x axis y axis)
   1680x1050      60.1 +
   1400x1050      60.0 
   1280x1024      59.9 
   1440x900       59.9 
   1280x960       59.9 
   1280x854       59.9 
   1280x800       59.8 
   1280x720       59.9 
   1152x768       59.8 
   1024x768       59.9 
   800x600        59.9 
   848x480        59.7 
   720x480        59.7 
   640x480        59.4 
S-video disconnected (normal left inverted right x axis y axis)
DVI-0 connected 1680x1050+1680+0 (normal left inverted right x axis y axis) 434mm x 270mm
   1680x1050      59.9*+
   1280x1024      75.0     60.0 
   1152x864       75.0 
   1024x768       75.1     60.0 
   800x600        75.0     60.3 
   640x480        75.0     60.0 
   720x400        70.1


The attached patch should fix that
Title: Re: Patch for XrandR.java
Post by: Matthias on May 20, 2010, 17:12:58
patch: Index: src/java/org/lwjgl/opengl/XRandR.java
===================================================================
--- src/java/org/lwjgl/opengl/XRandR.java (revision 3339)
+++ src/java/org/lwjgl/opengl/XRandR.java (working copy)
@@ -39,6 +39,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
@@ -82,10 +83,10 @@
name = sa[0];

// record the current config
- currentList.add(new Screen(name, sa[2]));
+ parseScreen(currentList, name, sa[2]);
} else if (Pattern.matches("\\d*x\\d*", sa[0])) {
// found a new mode line
- possibles.add(new Screen(name, sa[0]));
+ parseScreen(possibles, name, sa[0]);
}
}

@@ -179,7 +180,43 @@
// clone the array to prevent held copies being altered
return (Screen[]) ((Screen[]) screens.get(name)).clone();
}
+   
+    private static final Pattern SCREEN_PATTERN1 = Pattern.compile("^(\\d+)x(\\d+)\\+(\\d+)\\+(\\d+)$");
+    private static final Pattern SCREEN_PATTERN2 = Pattern.compile("^(\\d+)x(\\d+)$");

+    /**
+     * Parses a screen configuration and adds it to the list if it's valid.
+     *
+     * @param list
+     *           the list to add the Screen to if it's valid
+     * @param name
+     *           the name of this screen                         
+ * @param conf
+ *           config string, format either widthxheight or
+ *           widthxheight+xPos+yPos
+ */             
+    private static void parseScreen(List /* <Screen> */ list, String name, String what) {
+        Matcher m = SCREEN_PATTERN1.matcher(what);
+        if(!m.matches()) {
+            m = SCREEN_PATTERN2.matcher(what);
+            if(!m.matches()) {
+                System.out.println("Did not match: " + what);
+                return;
+            }
+        }
+        int width = Integer.parseInt(m.group(1));
+        int height = Integer.parseInt(m.group(2));
+        int xpos, ypos;
+        if(m.groupCount() > 3) {
+            xpos = Integer.parseInt(m.group(3));
+            ypos = Integer.parseInt(m.group(4));
+        } else {
+            xpos = 0;
+            ypos = 0;
+        }
+        list.add(new Screen(name, width, height, xpos, ypos));
+    }
+   
/**
* Encapsulates the configuration of a monitor. Resolution is
* fixed, position is mutable
@@ -213,24 +250,12 @@
*/
public int yPos = 0;

- /**
- * @param name
- *           name of the screen
- * @param conf
- *           config string, format either widthxheight or
- *           widthxheight+xPos+yPos
- */
- private Screen(String name, String conf) {
+ private Screen(String name, int width, int height, int xPos, int yPos) {
this.name = name;
-
- String[] sa = conf.split("\\D");
- width = Integer.parseInt(sa[0]);
- height = Integer.parseInt(sa[1]);
-
- if (sa.length > 2) {
- xPos = Integer.parseInt(sa[2]);
- yPos = Integer.parseInt(sa[3]);
- }
+ this.width = width;
+ this.height = height;
+ this.xPos = xPos;
+ this.yPos = yPos;
}

private void getArgs(List/* <String> */argList) {
Title: Re: Patch for XrandR.java
Post by: kappa on May 20, 2010, 19:06:17
committed.
Title: Re: Patch for XrandR.java
Post by: spasi on May 20, 2010, 23:09:27
I encountered this as well the other day (had my secondary monitor connected but disabled). But I fixed it by simply not adding connected & disabled screens to the currentList. Also, I don't think SCREEN_PATTERN2 will ever match anything, will it? And shouldn't we replace that System.out.println with LWJGLUtil.log?
Title: Re: Patch for XrandR.java
Post by: Matthias on May 21, 2010, 06:51:17
The code is also used to parse part of the mode list which only has widthxheight and the 2nd pattern will match this.
Title: Re: Patch for XrandR.java
Post by: princec on May 21, 2010, 08:58:00
(Just an aside: maybe I'm being a bit of a luddite but I wonder whether it might not be simpler to actually link to libxrandr and talk to it directly?)

Cas :)
Title: Re: Patch for XrandR.java
Post by: ryanm on May 21, 2010, 19:47:00
Yep, that would be the ideal solution. It just requires that someone actually do it. :P
The scope of XRandR.java is very limited - it only exists to properly restore the screen configuration on shutdown on linux systems with multiple monitors. All mode switching is already done through libxrandr.
Until LWJGL moves to support multiple displays, I reckon it'd be a lot of effort for little gain to do this stuff in native code.

Find attached a slightly different version of XRandR. My Eclipse has auto-formatted from the svn version, so a diff won't be terribly illuminating, but the changes are:
Title: Re: Patch for XrandR.java
Post by: kappa on May 21, 2010, 19:51:06
ryanm just downloaded your patch, seems like its incomplete and that the bottom part of the src code is missing.

could you re-upload please, also do you include matthiasm's fixes too?
Title: Re: Patch for XrandR.java
Post by: ryanm on May 21, 2010, 20:38:07
I downloaded from the svn and then made changes, so It does include Matthias's stuff. Don't know what happened with the attachment, try this one

edit: that one does the same thing. Very odd. Get it here (http://homepages.inf.ed.ac.uk/rmcnally/XRandR.java)
Title: Re: Patch for XrandR.java
Post by: kappa on May 21, 2010, 20:44:40
same problem, still 8.4kb big.

you could try embedded it in the actual post.

or hop on to #lwjgl on freenode.net (most dev's hang out there) and just pastebin it on irc.
Title: Re: Patch for XrandR.java
Post by: ryanm on May 21, 2010, 21:27:28
The linked version didn't work for you? ??? Is the internet allergic to this file or something? How about this (http://pastebin.com/WtrcupFu)?
Title: Re: Patch for XrandR.java
Post by: kappa on May 21, 2010, 22:14:40
Quote from: ryanm on May 21, 2010, 21:27:28
The linked version didn't work for you? ??? Is the internet allergic to this file or something? How about this (http://pastebin.com/WtrcupFu)?

sorry not sure how I missed the linked version, just saw another patch attached to the forum post. But the link version does work.

you missed some casting in the your code which was causing it to fail when compiling, anyhow changed that.

Patch committed.
Title: Re: Patch for XrandR.java
Post by: ryanm on May 21, 2010, 23:54:32
You must have caught me in the period between: