Xinerama protocol clashes on Solaris
By Alanc-Oracle on Jun 02, 2005
So now that nVidia has released their Solaris x86 drivers, a problem I've been working on recently will probably become more noticable. The Xinerama calls used by CDE & JDS on Solaris aren't compatible with the protocol used by the Xorg server. Back in the early days of Xinerama, a number of people noticed that the protocol originally delivered in X11R6.4 didn't meet all the needs of application and window manager developers, so proposals were made to extend it. Unfortunately, Xsun adopted an early draft of the proposed standard extensions, while XFree86 adopted a slightly different protocol extension, and meanwhile the standards committee version never got adopted by anyone. Since X11R6.7 and later pulled in the XFree86 version, it's effectively the defacto standard now, while we're working on fixing the standards committee version to be compatible with that so it can be adopted in a future X.Org release.
Unfortunately, this means CDE & JDS on Solaris will both exit on login to a session running on the Xorg server in Xinerama mode, and that now includes TwinView mode with a nVidia dual-head card. It will also cause Mozilla 1.7 on Solaris 10 to exit with an X error when you try to display to a XFree86 or Xorg machine running Xinerama, or to a MacOS X machine using the X server included there (which seems to always advertise the Xinerama extension, even when only a single screen is active).
For now, there are a couple of workarounds you can use:
- If using the nVidia drivers in TwinView mode, enable this option in xorg.conf,
as noted in the nVidia driver readme:
Option "NoTwinViewXineramaInfo" "1"
- Use the interposer library Steven Hahn posted in his blog to replace the calls in libXext that result in X errors
A real fix should appear in build 16 of “Nevada” (the current development branch of Solaris, which is released via the Solaris Express program, and soon via OpenSolaris as well), and then in patches for older releases of Solaris. This fix detects which version of the Xinerama protocol is used by the X server and then sends the correct requests for that protocol version.
Since this changes an interface our software uses to interact with other software (both from other groups in Sun and from groups outside Sun), I had to run the proposed change by our Architecture Review Committee (ARC) before putting it into Solaris. The change was simple and straightforward enough that it was easily approved, but since we're working to open up those review processes as part of the OpenSolaris process, I figured I'd post here what I sent to the committee for review, both to explain the fix better and to give a small bit of the flavor of our reviews to help future OpenSolaris developers start understanding how we work. As you can see, for small, simple changes, it's not really a lot of paperwork - this case was a “fast track” so it was mostly a free-form description of the changes, written in whatever way the developer thinks makes it most clear to the reviewers, followed by a simple table summarizing the interfaces.
(The references you'll see to “PSARC/2000/036” refer to the previous review when Sun added the draft standard changes. At the end, where the old protocol is listed as “Obsolete” that's probably closer to what most people think of as “deprecated” - still supported for now for backwards compatibility, but it may not be forever and nothing new should depend on it.)
PSARC/2000/036 introduced a Sun extension to the Xinerama protocol and API that came from X.Org in X11R6.4. The case made the prediction that these extensions would be part of the X.Org standard "in 6 to 8 months." Unfortunately, that was proven to be wildly optimistic as the standard got stalled (it has not yet been adopted today, 5 years after the original case), and the XFree86 open source community added their own requests to the protocol which used the same request numbers as Sun's addition. This results in applications receiving X Errors (for which most take the default error handling path of exiting) when using the functions in Solaris libXext to query an X server which implements the XFree86 version of the protocol (including Xorg on Solaris and virtually every X server on Linux, BSD, and MacOS X). For instance, dtwm & metacity will both exit on startup, making it impossible to login to either CDE or JDS on a Solaris 10 x86 system running Xorg in Xinerama mode. The two protocol definitions are: Xsun XFree86/Xorg ================================ ================================ Version: 1.0 Version: 1.1 Requests: Requests: --------- --------- From X11R6.4: From X11R6.4: 0 PanoramiXQueryVersion 0 PanoramiXQueryVersion 1 PanoramiXGetState 1 PanoramiXGetState 2 PanoramiXGetScreenCount 2 PanoramiXGetScreenCount 3 PanoramiXGetScreenSize 3 PanoramiXGetScreenSize Xsun additions: XFree86 additions: 4 XineramaInfo 4 XineramaIsActive 5 XineramaQueryScreens XineramaInfo request: XineramaIsActive request: (size 8 bytes) (size 4 bytes) CARD8 reqType; CARD8 reqType; CARD8 xXineramaReqType; CARD8 panoramiXReqType; CARD16 length B16; CARD16 length B16; CARD32 visual B32; A client can therefore determine which protocol is used by the X server by querying the Xinerama extension version, and using the XFree86/Xorg protocol if the server reports version 1.1 or higher of the Xinerama extension. Unfortunately, the server cannot query the client as to which version of the protocol they support, so in order to determine which protocol to use, it has to attempt to determine the version based on the requests. Fortunately, only a single request is in conflict, and the version of the protocol in use can be determined by the length field in the request - a 8-byte request is using the Xsun protocol, while a 4-byte is using the Xorg protocol. This project, therefore proposes the following steps to restore compatibility to the Xinerama implementations on Solaris, both with itself and with the many other OS'es that support the Xinerama 1.1 protocol: - The XineramaGetState() API in libXext will be modified to check the Xinerama extension version reported by the X server, and if it is >= 1.1, will use the XineramaIsActive request to determine the Xinerama state. If it is 1.0, it will continue to use the current method of reporting that Xinerama is active whenever the X server reports the extension is present. - The XineramaGetInfo() API in libXext will be modified to check the Xinerama extension version reported by the X server, and if it is >= 1.1, it will use the XineramaQueryScreens request to get the screen layout. If it is 1.0, it will continue to use the current method of using the XineramaInfo request to obtain this data. - The Xsun server will be modified to report that it supports Xinerama protocol 1.1 and handle Xinerama Request 5 requests appropriately. It will also be modified to check the length of Xinerama Request 4 calls, and dispatch appropriately to either the Xsun 1.0 or XFree86 1.1 protocol handlers. - The Xorg server will continue to support only the 1.1 protocol and return a BadLength error when it receives a Xsun XineramaInfo request. Once this project is implemented, those requests will only come from unpatched Solaris libXext versions, and customers will be instructed to install the libXext patch to resolve them. A future project is planned to deliver the libXinerama library which provides the Xinerama API in XFree86/Xorg, but that is not included in this project. Imported interfaces: ==================== Interface: Classification Defined in / Comments ---------- -------------- --------------------- XineramaGetInfo API & Protocol Evolving PSARC 2000/036 XineramaGetState API Evolving PSARC 2000/036 Exported interfaces: ==================== Interface: Classification Defined in / Comments ---------- -------------- --------------------- Xinerama 1.1 Protocol Standard (\*) X11R6.8 implementation XineramaInfo Request Obsolete (\*) Not yet formally adopted as a standard specification by the X.Org standards body, but in such widespread use in the open source implementation that incompatible change has been rejected by the community.[Technorati Tag: Solaris] [Technorati Tag: OpenSolaris] [Technorati Tag: Xorg] [Technorati Tag: Xinerama]