Hi Oleg, Dmitry, Yuri, all
Please find attached my first attempt at fixing bug 6636469 [0].
APPROACH
The fix is really simple it just checks to make sure RANDR's version is
1.2 or greater if usingXinerama is true, if this is all fine it proceeds
to load the libXrandr funcs.
For the moment I've completely ignored 6599351, and not touched any of
the Xinerama loading code at all.
BTW I note that with 6599351 the user has an old style X dual-head
config without using Xinerama - I found a note on the Debian Xrandr1.2
Howto wiki page [1] explaining that this configuration should crash
Xserver 1.3. Does it behave differently in Solaris X?
TESTING
The equipment I have here will allow me to test single monitor setups
with X servers 1.2 and 1.3. Java now behaves as expected in the
following cases:
1) Xserver 1.2 + 1 monitor + Xrandr
Expect: isFullScreenSupported: true
Result: PASS
2) Xserver 1.2 + 1 monitor + Xinerama enabled (Xinerama won't actually
load but Xrandr and DRI won't load either)
Expect: isFullScreenSupported: false
Result: PASS
3) Xserver 1.3 + 1 monitor + Xrandr + fake Xinerama
Expect: isFullScreenSupported: true
Result: PASS
4) Xserver 1.3 + 1 monitor + Xinerama enabled (Xinerama won't actually
load but Xrandr and DRI won't load either)
Expect: isFullScreenSupported: false
Result: PASS
TESTING TODO
I have an external LCD monitor at work which I can hook up to my laptop
next week. This should allow me to test out Xrandr 1.2 multi-monitor
setups. I'll post results as soon as complete.
However I don't think I can test out Xinerama dual head configs. I tried
to set this up once before but failed - I'm still not 100% certain if
Xinerama is actually compiled into my X server I will need to check this
out properly.
If anyone here has a multi monitor setup already and would be prepared
to help me test the following scenarios I'd be very grateful.
5) Xserver 1.2 + 2 monitor + Xinerama (Xrandr and DRI won't load)
Expect: isFullScreenSupported: false
6) Xserver 1.3 + 2 monitors + Xinerama
Expect: isFullScreenSupported: false
I am also still to run the jtreg tests against this. I will come back
with results.
Also, do I need to mail both awt-dev and 2d-dev or will just one do in
future?
Cheers
Dan
[0] http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6636469
[1] Section VI.3 of http://wiki.debian.org/XStrikeForce/HowToRandR12
------------------------------------------------------------------------
diff -r 99a06bc7fdb5 -r 7e529c4088cc
src/solaris/native/sun/awt/awt_GraphicsEnv.c
--- a/src/solaris/native/sun/awt/awt_GraphicsEnv.c Tue Dec 04 16:28:33
2007 -0800
+++ b/src/solaris/native/sun/awt/awt_GraphicsEnv.c Sat Dec 08 13:29:25
2007 +0000
@@ -1626,6 +1626,8 @@ Java_sun_awt_X11GraphicsEnvironment_getX
#define BIT_DEPTH_MULTI java_awt_DisplayMode_BIT_DEPTH_MULTI
+typedef Status
+ (*XRRQueryVersionType) (Display *dpy, int *major_versionp, int
*minor_versionp);
typedef XRRScreenConfiguration*
(*XRRGetScreenInfoType)(Display *dpy, Drawable root);
typedef void
@@ -1650,6 +1652,7 @@ typedef Status
short rate,
Time timestamp);
+static XRRQueryVersionType awt_XRRQueryVersion;
static XRRGetScreenInfoType awt_XRRGetScreenInfo;
static XRRFreeScreenConfigInfoType awt_XRRFreeScreenConfigInfo;
static XRRConfigRatesType awt_XRRConfigRates;
@@ -1672,11 +1675,37 @@ static jboolean
static jboolean
X11GD_InitXrandrFuncs(JNIEnv *env)
{
+ int rr_maj_ver = 0, rr_min_ver = 0;
+
void *pLibRandR = dlopen("libXrandr.so.2", RTLD_LAZY | RTLD_LOCAL);
if (pLibRandR == NULL) {
J2dRlsTraceLn(J2D_TRACE_ERROR,
"X11GD_InitXrandrFuncs: Could not open libXrandr.so.2");
return JNI_FALSE;
+ }
+
+ LOAD_XRANDR_FUNC(XRRQueryVersion);
+
+ if (!(*awt_XRRQueryVersion)(awt_display, &rr_maj_ver, &rr_min_ver)) {
+ J2dRlsTraceLn(J2D_TRACE_ERROR,
+ "X11GD_InitXrandrFuncs: XRRQueryVersion returned an error status");
+ dlclose(pLibRandR);
+ return JNI_FALSE;
+ }
+
+ if (usingXinerama) {
+ /*
+ * We can proceed as long as this is RANDR 1.2
+ * As of Xorg server 1.3 onwards the Xinerama backend may actually be
+ * a fake one provided by RANDR itself. See Java bug 6636469 for info.
+ */
+ if (!(rr_maj_ver >= 1 && rr_min_ver >= 2)) {
+ J2dRlsTraceLn2(J2D_TRACE_INFO, "X11GD_InitXrandrFuncs: Can't use Xrandr. "
+ "Xinerama is active and Xrandr version is %d.%d",
+ rr_maj_ver, rr_min_ver);
+ dlclose(pLibRandR);
+ return JNI_FALSE;
+ }
}
LOAD_XRANDR_FUNC(XRRGetScreenInfo);
@@ -1814,15 +1843,6 @@ Java_sun_awt_X11GraphicsDevice_initXrand
int opcode = 0, firstEvent = 0, firstError = 0;
jboolean ret;
- if (usingXinerama) {
- /*
- * REMIND: we'll just punt if Xinerama is enabled; we can remove this
- * restriction in the future if we find Xinerama and XRandR playing
- * well together...
- */
- return JNI_FALSE;
- }
-
AWT_LOCK();
ret = (jboolean)XQueryExtension(awt_display, "RANDR",
&opcode, &firstEvent, &firstError);