Monday Apr 16, 2007

X11 API's for querying multi-head screen layout

I should probably stick this in the X.Org wiki or OpenSolaris/GenUnix wiki, but I'm being lazy and just summarizing to here now from an e-mail thread last week on one of the Sun internal lists...

There are now 4 sets of API's to query the layout of display screens in a logical X screen when using a setup such as Xinerama, TwinView, or MergedFB:

  1. the original X11R6.4 XPanoramiX\* API
  2. Sun's Xinerama API
  3. XFree86's Xinerama API
  4. Xrandr 1.2

The first is pretty much universally available, but also universally deprecated. The functions for it are defined in libXinerama on Linux, libXext on Solaris, but I don't think we've ever shipped the header for it on Solaris, since it was deprecated long ago.

The second Sun created and proposed to the old X.Org industry consortium to become the standard, but they did not adopt it, crafted a replacement in committee that was universally incompatible with everything and never adopted that either. It's what the <X11/extensions/xinerama.h> header in Solaris represents, and was never documented, but you can find a description of the API in PSARC 2000/036. The functions from it are found in Solaris libXext, but nowhere else in the world that I know of.

The third, aka libXinerama, is available on most XFree86 & Xorg based systems, and finally came to Solaris in nv_62 and soon in Solaris 10 patches & the next update release. It uses the <X11/extensions/Xinerama.h> (note the capitalization compared to the other) header and is documented in the man page we created for the Solaris integration and contributed back to X.Org.

The fourth is a very recent development, having been released after X11R7.2's release in February. X.Org is currently in the process of releasing version 1.3 of the Xorg server package (release candidate 5 is out now) - this will be the first Xorg server feature release not tied to one of the whole X Window System releases. (X11R7.2 had Xorg server 1.2, X11R7.3 is expected to have Xorg server 1.4.) The xf86-video-intel driver 2.0 release candidate 4 is also out, it is the first driver to support the new Xrandr 1.2 additions, though work is in progress on other drivers, including the Radeon and nvidia drivers. We don't have a definite roadmap for including this in Solaris yet - we'll probably do it once the X.Org releases are finished and we're passed the upcoming milestone of the second Solaris Express Developer Edition release in May.

Thursday Jun 02, 2005

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

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


« July 2016