Xinerama protocol clashes on Solaris

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

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

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.
[] [] [] []

Post a Comment:
Comments are closed for this entry.

Engineer working on Oracle Solaris and with the X.Org open source community.


The views expressed on this blog are my own and do not necessarily reflect the views of Oracle, the X.Org Foundation, or anyone else.

See Also
Follow me on twitter


« April 2014