Hi all
Happy new year.
Although I've been silent for a bit, I'm still working on this. I've
tested more widely now and have managed to configure multi-monitor
setups on both Xorg server's 1.2 and 1.3. I'm also now on the SCA
contributors list.
UPDATED PATCH
Please see the attached updated patch.
I needed to add code to prevent FSEM (Fullscreen Exclusive Mode) on Xorg
1.3 with 2 or more monitors. Although I suspect this is technically
possible now (as it is in Windows) running a full-screen app in a
multi-monitor setup currently disables all Graphics devices except the
default and requires an X restart to bring them back. So I guess it'll
need more work to support that.
Should I raise an RFE? Is this something worth doing?
FEEDBACK SO FAR
Guys, am I on the right lines?
Yuri, you were going to work on 6599351, does what I've done fit in or
were you planning more radical changes?
ADVICE ON JTREG APPROACH
Also I need some advice on how to approach a jtreg test for this. My
current plan is to use a shell script to query command line tools like
xdpyinfo and xrandr and then run a Java tool to check whether FSEM is or
isn't supported as expected. But I've no idea (yet) how portable this
would be across platforms and across versions of X.
I notice there aren't a great deal FSEM related tests in the source
other than one in jdk/test/java/awt/Fullscreen (which incidentally
appears to be missing a source file 'DisplayModeChanger.java').
I can see the benefit in providing a regression test for this but I'm
concerned that it's very dependent on the environment the tests are
being run on as to whether it'll get spotted at all.
Do you guys think it's a good idea to make a test for this or is it more
likely to be a pest to maintain?
Thanks
Dan Munckton
diff --git a/src/solaris/native/sun/awt/awt_GraphicsEnv.c b/src/solaris/native/sun/awt/awt_GraphicsEnv.c
--- a/src/solaris/native/sun/awt/awt_GraphicsEnv.c
+++ b/src/solaris/native/sun/awt/awt_GraphicsEnv.c
@@ -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;
@@ -1664,19 +1667,52 @@ static XRRSetScreenConfigAndRateType
if (awt_##f == NULL) { \
J2dRlsTraceLn1(J2D_TRACE_ERROR, \
"X11GD_InitXrandrFuncs: Could not load %s", #f); \
- dlclose(pLibRandR); \
- return JNI_FALSE; \
+ goto return_false; \
} \
} while (0)
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");
+ goto return_false;
+ }
+
+ /*
+ * REMIND: Fullscreen mode doesn't work quite right with multi-monitor setups
+ * so for now we also require a single screen.
+ */
+ if (awt_numScreens > 1 ) {
+ J2dRlsTraceLn(J2D_TRACE_INFO, "X11GD_InitXrandrFuncs: Can't use Xrandr. "
+ "Multiple screens in use");
+ goto return_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);
+ goto return_false;
+ }
}
LOAD_XRANDR_FUNC(XRRGetScreenInfo);
@@ -1688,6 +1724,10 @@ X11GD_InitXrandrFuncs(JNIEnv *env)
LOAD_XRANDR_FUNC(XRRSetScreenConfigAndRate);
return JNI_TRUE;
+
+return_false:
+ dlclose(pLibRandR);
+ return JNI_FALSE;
}
static jobject
@@ -1814,15 +1854,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);