Hello all,
I ran into a problem using JOGL on Linux with multiple monitors. My setup requires that Xinerama be disabled, so my two monitors are configured as two screens (:0.0 and :0.1). In my program, I create a GLCanvas and add it to an existing java.awt.Frame like so:
GLCanvas canvas = new GLCanvas( null, null, null, frame.getGraphicsConfiguration().getDevice());
frame.add(canvas);
This worked fine on screen 0, but failed on screen 1 with the following exception:
java.lang.IllegalArgumentException: GLDrawableFactory.chooseGraphicsConfiguration() was not used when creating this Component.
I was able to trace through the source code in Eclipse, and found that that exception would be thrown when X11GLDrawableFactory was not able to get a GraphicsConfiguration. This was caused because the GLCanvasConstructor was not able to choose one, in chooseGraphicsConfiguration.
I traced the problem further to X11GLDrawableFactory.chooseGraphicsConfiguration, in which I found the following code:
int screen;
if( isXineramaEnabled() ) {
screen = 0;
} else {
screen = /* something else */;
}
Putting a breakpoint there, I was able to see that it thought Xinerama was enabled although I could verify from my xorg.conf file (and xdpyinfo) that it was not. The extension was present, but inactive.
Poking around a bit further, I found an XineramaHelper.c file which defined XineramaEnabled. It did an XQueryExtension to see if the “XINERAMA” extension was present, then an XineramaQueryScreens to get its setup. I couldn’t step into native code (or at least I don’t know how), so I created a simple program to test those routines. Sure enough, xorg reported that the Xinerama extension was present, and XineramaQueryScreens returned info for the first screen, even though it was not currently active. There is another function in the Xinerama extension library for xorg, named XineramaIsActive, which returned false in my case. I enabled Xinerama to test this further, and the XineramaIsActive call returned true, while the XineramaQueryScreens returned two heads instead of 1.
So I would argue that XineramaEnabled in XineramaHelper.c needs to be changed to use XineramaIsActive instead of XineramaQueryScreens. (At the very least, it needs to free the XineramaScreenInfo array returned by XineramaQueryScreens, as per the man page).
Something like this:
char* XinExtName = "XINERAMA";
int32_t major_opcode, first_event, first_error;
Bool gotXinExt = False;
gotXinExt = XQueryExtension(display, XinExtName, &major_opcode,
&first_event, &first_error);
if (gotXinExt) {
if (XineramaIsActive(display) ) {
return True;
}
}
return False;