alanc @ sun.com

Alan Coopersmith’s blog

Random thoughts of a disorganized mind...
(and though it should be obvious, while Sun pays me to think about things, they disclaim any responsibility for these thoughts, nor do I claim what I say matches in any way what Sun thinks)

Loading...
http://blogs.sun.com/alanc/date/20050623 Thursday June 23, 2005

dtracing down an X server "memory leak"

A bug came into our group today complaining of a memory leak in X. The customer and the support engineer they'd worked with had actually done a good job of narrowing down a simple repeatable test case:

#!/bin/sh

while : ; do
        /usr/openwin/bin/xterm &
        sleep 1
        kill -KILL `pgrep xterm`
done
They had also run Xsun with libumem preloaded and had captured the stack trace that was making repeated allocations and not freeing them:
After 7 minutes:

> ::umausers
1040384 bytes for 254 allocations with data size 4096:
        libumem.so.1`umem_cache_alloc+0x13c
        libumem.so.1`umem_alloc+0x44
        libumem.so.1`malloc+0x2c
        Xalloc+0x18
        MapAlloc+0x14
        libcfb.so.1`cfbCreatePixmap+0x74
        ProcCreatePixmap+0x118
        Dispatch+0x17c
        main+0x788
        _start+0x108

After 11 minutes:

> ::umausers
3506176 bytes for 856 allocations with data size 4096:
        libumem.so.1`umem_cache_alloc+0x13c
        libumem.so.1`umem_alloc+0x44
        libumem.so.1`malloc+0x2c
        Xalloc+0x18
        MapAlloc+0x14
        libcfb.so.1`cfbCreatePixmap+0x74
        ProcCreatePixmap+0x118
        Dispatch+0x17c
        main+0x788
        _start+0x108

One of the other support engineers noticed the bug was reproducible only under CDE and not in the GNOME desktop. At that point they sent the bug to our group to investigate further.

I just happened to be working on a new toy at the time the bug came in: an Xserver provider for dtrace. (I've actually been working on this for a while, and am getting it ready to release for people to experiment with - watch this blog for news on that soon.) This seemed the perfect bug to put it to the test with.

Since it had already been narrowed down to CreatePixmap, the next question was who was calling CreatePixmap and which ones were freed afterwards. Unfortunately, there's about a half dozen different ways in the X server to free a resource like a pixmap, and not all of them involve X requests - for instance, when an X client connection is closed, the X server garbage collects the resources that were specific to that client. So what I really wanted was to trace pixmap allocations and frees and match those to the clients calling CreatePixmap. This actually ended up using a good cross section of the initial set of dtrace probes I'd created in the X server.

First, to record who was making calls, I used the client-connect, client-authenticate, and client-disconnect probes. You can probably guess what each of those probes do. For connect & disconnect I simply printed that the event happened and which client id was involved. (In the X server all clients are tracked by a simple integer id, which is usually the position of the entry in the array of client information pointers that has the details for that client.) At client authenticate time, when we actually figure out what client is connecting, I also printed the string representing the address of the client and the pid of the client for local clients. This looks like:

Xserver$1:::client-connect
{
	printf("** Client Connect: id %d\n", arg0);
}

Xserver$1:::client-auth
{
	printf("** Client auth'ed: id %d => %s pid %d\n",
		arg0, copyinstr(arg1), arg2);
}

Xserver$1:::client-disconnect
{
	printf("** Client Disconnect: id %d\n", arg0);
}
(The $1 refers to the first argument to the dtrace script when it's run, which I was using for the process id of the Xserver I wanted to trace. Unfortunately, since the X server provider is a User-Defined Dtrace Provider, the available data for each probe gets generic names, hence the arg0, arg1, etc. I'll provide a chart of what those really mean when I get the provider released.)

Next I needed to record when pixmaps were created and freed, so I used the resource-alloc and resource-free probes, and printed the XID for each alloc & free of a resource of type PIXMAP:

Xserver$1:::resource-alloc
/Xrestype[arg3] == "PIXMAP"/
{
	printf("** Pixmap alloc: %08x\n", arg0);
}


Xserver$1:::resource-free
/Xrestype[arg3] == "PIXMAP"/
{
	printf("** Pixmap free:  %08x\n", arg0);
}

Then I added probes for the requests coming in to the Xserver from clients, and whenever one came in for CreatePixmap, print when it started and finished, and which client it was from, so you could see which pixmap allocs came from those requests:

Xserver$1:::request-start
/Xrequest[arg0] == "X_CreatePixmap"/
{
    	printf("-> %s: client %d\n", Xrequest[arg0], arg3);
}

Xserver$1:::request-done
/Xrequest[arg0] == "X_CreatePixmap"/
{
    	printf("<- %s: client %d\n", Xrequest[arg0], arg3);
}

Put it all together, with a little bit of extra glue to cache the strings being copied through the kernel for better performance and reduced overhead, and the final script looks like this:

#!/usr/sbin/dtrace -qs

string Xrequest[uintptr_t];
string Xrestype[uintptr_t];

Xserver$1:::request-start
/Xrequest[arg0] == ""/
{
	Xrequest[arg0] = copyinstr(arg0);
}

Xserver$1:::resource-alloc
/arg3 != 0 && Xrestype[arg3] == ""/
{
	Xrestype[arg3] = copyinstr(arg3);
}


Xserver$1:::request-start
/Xrequest[arg0] == "X_CreatePixmap"/
{
    	printf("-> %s: client %d\n", Xrequest[arg0], arg3);
}

Xserver$1:::request-done
/Xrequest[arg0] == "X_CreatePixmap"/
{
    	printf("<- %s: client %d\n", Xrequest[arg0], arg3);
}

Xserver$1:::resource-alloc
/Xrestype[arg3] == "PIXMAP"/
{
	printf("** Pixmap alloc: %08x\n", arg0);
}


Xserver$1:::resource-free
/Xrestype[arg3] == "PIXMAP"/
{
	printf("** Pixmap free:  %08x\n", arg0);
}

Xserver$1:::client-connect
{
	printf("** Client Connect: id %d\n", arg0);
}

Xserver$1:::client-auth
{
	printf("** Client auth'ed: id %d => %s pid %d\n",
		arg0, copyinstr(arg1), arg2);
}

Xserver$1:::client-disconnect
{
	printf("** Client Disconnect: id %d\n", arg0);
}

So I sent my test machine back to the dtlogin screen, started the script with the pid of the running X server and logged into CDE. I ran a few iterations of the xterm loop and found this pattern repeated for each iteration:

** Client Connect: id 17
** Client auth'ed: id 17 => local host pid 20273
-> X_CreatePixmap: client 17
** Pixmap alloc: 02200009
<- X_CreatePixmap: client 17
-> X_CreatePixmap: client 15
** Pixmap alloc: 01e00180
<- X_CreatePixmap: client 15
-> X_CreatePixmap: client 15
** Pixmap alloc: 01e00181
<- X_CreatePixmap: client 15
-> X_CreatePixmap: client 14
** Pixmap alloc: 01c004c8
<- X_CreatePixmap: client 14
** Pixmap free:  02200009
** Client Disconnect: id 17
** Pixmap free:  01e00180
** Pixmap free:  01e00181

As you can see, the xterm was assigned client id 17 - it created a single pixmap itself which was freed, client id 15 created and freed two more, but for every xterm started, client id 14 created one that wasn't freed. Looking back at the beginning of the log to see who client id 14 and 15 were revealed they were two connections from the same process:

** Client auth'ed: id 14 => local host pid 20089
** Client auth'ed: id 15 => local host pid 20089

Not surprisingly, ps showed that pid 20089 was the CDE window manager, dtwm. At this point I could have just punted the bug to our CDE team, but since I had this all set up, I decided to go one level further. So far, nothing I'd done with dtrace couldn't have been done by rebuilding the Xserver with some carefully selected printf()'s added - of course, being able to do it without having to rebuild the X server is very nice for those who aren't X server engineers and don't rebuild the X server several thousand times a year. But the true power of dtrace is that it's a whole system tracing tool, so I can see what's going on in the Xserver & dtwm processes at the same time.

My first attempt was to simply use the dtrace system() call to call pstack on the dtwm pid every time we got a CreatePixmap call from it - unfortunately, XCreatePixmap() is an asynchronous call, and gets buffered up and sent later, so all that showed is that by the time the X server got the CreatePixmap call is that dtwm had finished sending requests and was waiting in the X event loop for new events to come in.

So I cheated. Since I knew the function in libX11 dtwm would be calling was XCreatePixmap, I simply traced calls to it from the process id (which I made a command line argument to the script):

pid$4::XCreatePixmap:entry
{
	ustack();
}
I also changed the script to only print the CreatePixmap requests from the two client ids representing dtwm:
Xserver$1:::request-start
/(arg3 == $2 || arg3 == $3) && Xrequest[arg0] == "X_CreatePixmap"/
{
    	printf("-> %s: client %d\n", Xrequest[arg0], arg3);
}

This expanded the detail in the output to show where dtwm was creating the pixmaps:

** Client Connect: id 19
** Client auth'ed: id 19 => local host pid 20497
** Pixmap alloc: 02600009

              libX11.so.4`XCreatePixmap
              libXm.so.4`_XmGetScaledPixmap+0x2fc
              libXm.so.4`Xm21GetPixmapByDepth+0x6b
              libXm.so.4`Xm21GetPixmap+0x31
              dtwm`MakeNamedIconPixmap+0xc4
              dtwm`ProcessWmHints+0x310
              dtwm`GetClientInfo+0x299
              dtwm`ManageWindow+0x18
              dtwm`WmDispatchWsEvent+0x6e
              dtwm`main+0x1f1
              dtwm`0x809772a

              libX11.so.4`XCreatePixmap
              libXm.so.4`_XmGetScaledPixmap+0x2fc
              libXm.so.4`Xm21GetPixmapByDepth+0x6b
              libXm.so.4`Xme21GetMask+0x43
              libXm.so.4`XmeGetMask+0x1b
              libDtSvc.so.1`_DtGetMask+0x45
              dtwm`MakeNamedIconPixmap+0xf2
              dtwm`ProcessWmHints+0x310
              dtwm`GetClientInfo+0x299
              dtwm`ManageWindow+0x18
              dtwm`WmDispatchWsEvent+0x6e
              dtwm`main+0x1f1
              dtwm`0x809772a
-> X_CreatePixmap: client 15
** Pixmap alloc: 01e001d0
-> X_CreatePixmap: client 15
** Pixmap alloc: 01e001d1

              libX11.so.4`XCreatePixmap
              dtwm`MakeIconPixmap+0x10c
              dtwm`MakeNamedIconPixmap+0x14a
              dtwm`ProcessWmHints+0x310
              dtwm`GetClientInfo+0x299
              dtwm`ManageWindow+0x18
              dtwm`WmDispatchWsEvent+0x6e
              dtwm`main+0x1f1
              dtwm`0x809772a
-> X_CreatePixmap: client 14
** Pixmap alloc: 01c006f8
** Pixmap free:  01e001d0
** Pixmap free:  01e001d1
** Pixmap free:  02600009
** Client Disconnect: id 19
** Client Connect: id 19

So now that I could point the CDE team to the exact function to look at, MakeIconPixmap in dtwm, I passed the bug on to them. (Since Sun's CDE team is overseas, they were asleep while all this happened, and should be getting to work soon, so I don't have an ending yet to this story, but since this is a blog, I can just post that later.)

[] [] [] []

http://blogs.sun.com/alanc/date/20050614 Tuesday June 14, 2005

Solaris Express changes for desktop users

Along with the rest of the OpenSolaris downloads made available today, was a new Solaris Express: Community Edition, which like the current Solaris Express is based on the "Nevada" development branch of Solaris. While the bits released are the same, the community edition comes out more often, and with less testing first, to allow building, testing and debugging OpenSolaris with the same bits the engineers have internally. Once testing is done, one out of every two or three releases should be promoted to the main Solaris Express program, for those who like living near the cutting edge, but not right on it.

So the first community edition release today is build 16 of the "Nevada" branch of Solaris. The latest Solaris Express release was Solaris Express 4/05, which was build 10 of the "Nevada" branch. I imagine Dan or the Alan from Down Under will put together their usual lists soon covering the entire feature set, but I've already got a list gathered of changes you'll see in the Solaris desktop software consolidations (X, CDE, JDS, etc.) when you move from build 10 to build 16, so I figured I'd go ahead and post it. Some, but not all, of these changes should also be in Solaris Express 6/05, with the rest coming in the Solaris Express release after that.

Unfortunately, since these desktop components are not yet part of OpenSolaris, their bugs aren't yet available on the bugs.opensolaris.org portal yet either, so I can't link to the bug database for more info on them yet.

  • Once again, new login screen graphics. (The "squiggles" didn't compress well for remote display or low-bandwidth Sun Ray, like the people in Sun's Sun-Ray-at-home internal pilot program.) Also, a 1400x1050 graphic size is added for all the laptop users.
  • Java Desktop System theme changes to match the upcoming JDS3 for Linux release. The Java coffee cup is back in the default background and the curved lines in the background don't clash with the icons as much. The Launch menu button is changed to look like a single button instead of a Java button next to a launch button.
  • Sun Update Connection icon in the JDS toolbar.
  • Updated versions of Xorg's nv (open source nVidia) & i810 (Intel 8xx & 9xx series chipsets) drivers to support newer hardware. [These are both updated to the X.Org CVS versions from around March 2005.]
  • Added libraries and clients for extensions created by XFree86:
    • programs (in /usr/X11/bin): xgamma, xrandr, xvidtune, xvinfo
    • libraries (in /usr/X11/lib): libXxf86misc.so.1, libXxf86vm.so.1
  • SPARC OpenGL upgraded to Sun's OpenGL 1.5 alpha release
  • Mesa open-source OpenGL-workalike for Xorg included on Solaris x86/x64.
  • Xscreensaver OpenGL modules now shipped on Solaris x86/x64 too. (Were previously SPARC-only since we had no x86 OpenGL support.)
  • agpgart kernel driver and Xorg server support (only used by the Xorg driver for Intel 8xx & 9xx series chipsets though) [See the OpenSolaris X Window System community announcements page for links to the sources integrated into X.Org CVS for this.]
  • Virtual mouse and keyboard drivers in the kernel make all USB & PS/2 keyboards and mice available via /dev/mouse and /dev/kbd, so you no longer need to manually configure your X config files to support multiple devices, and hotplugging additional devices simply works. If you open one of the other mouse or keyboard device files directly, it splits it out of the coalesced virtual devices and lets you access directly, if you need special configuration for specific devices.
  • Bugs in 3-button mouse emulation in both Xsun & Xorg have been fixed.
  • xorgcfg GUI tool provided for configuring xorg.conf files for Xorg.
  • libXext is now compatible with the XFree86/Xorg flavor of Xinerama. (See my June 2nd blog post for details. )
  • gdm2 better configured to work on Solaris (reboot & shutdown commands properly set, etc.)
  • JDS no longer locks up the keyboard when displayed to foriegn X servers like Xvnc or Exceed.

Though as I mentioned, these bits are from a development release, not fully debugged yet, so there's a couple of things to watch out for as well:

  • If you've installed the nVidia accelerated driver and upgrade to build 16, you need to reinstall that driver after upgrading since it clashes with the Mesa OpenGL in this build. That will be fixed in the future as we work on integrating the nVidia driver directly into Solaris.
  • If you're using an Xorg configuration file with multiple mouse devices, make sure the /dev/mouse device comes before the /dev/kdmouse or your system may hang on Xorg startup if you don't have a USB mouse plugged in. (Alternatively, delete the kdmouse device and just use the virtual mouse via /dev/mouse.) This is bug 6275666, fixed in Nevada build 17.

[] [] []

Opening Day

access(2) OpenSolaris As you may have noticed, the release of the first big batch of code from OpenSolaris project today is being accompanied by blogs from many of the Solaris engineers. When you read these blogs you'll see most of the engineers are writing about the parts of the code they know best. Unfortunately, for me, that's the parts not yet released. (There are a couple of lines of code here and there from me that I submitted as suggested fixes in bugs I filed, but I've never checked in any code directly to the source tree the released code comes from.)

Why is that? Because of the way Solaris is built - it's not one single monolithic source tree, but instead organized into chunks called "consolidations." Today's first phase is a single consolidation, called "OS/Networking" or ON for short, which contains most of the Solaris kernel, drivers and core utilities. The consolidation most of my work goes into is simply called "X", and includes both the Xsun & Xorg source trees for Solaris, but not the Xsun device modules. Other consolidations include CDE/Motif, JDS, Graphics and Networking drivers, Developer Tools, Administration/Installation, and so on. Each consolidation manages it's own source trees and builds, and delivers the built packages to a central dock where all the consolidations are combined into the Solaris WOS ("Wad of Stuff") which is the CD or DVD set delivered to the users.

Since Solaris is huge, instead of waiting until everything was ready for release, a staged plan was developed for OpenSolaris, starting with the consolidation at the core of the OS and then working out to the higher layers. Now that ON is out and the infrastructure used is set up, we're starting to work out how to release code from other consolidations. Once everything is in place for additional consolidations to be added to OpenSolaris, the next phase will probably be the source trees that come from open source releases and are thus not needing as much work to separate out the bits that can be released from those that can't, and that is expected to include our Xorg server source tree.

Of course, if you want to build Xorg for Solaris, you don't need our changes - there's not actually much you need that's not currently in the X.Org CVS repository on freedesktop.org. There's even stuff there that's not yet in our builds, like the experimental support for building 64-bit Xorg servers for AMD64 machines. Our Solaris builds are based on the Xorg 6.8.2 source tree, with various changes backported from the CVS head, such as the newer ATI, nVidia, and i810 drivers, and a few small customizations. Some of those can be enabled in the open source builds by using the BuildLikeSun Imake option recently added to CVS to document some of our customizations. The rest we'll be working on getting out there later this year.

We've also set up a "X Window System" community on the new OpenSolaris.org website where you can find out more information about the status of our X source releases, and talk to the engineering teams and other users. Come join us over there if this part of OpenSolaris interests you!

[] [] []

http://blogs.sun.com/alanc/date/20050612 Sunday June 12, 2005

Acceptance speech

I've had this post sitting in my draft folder for a little over a month now, trying to figure out what to say, so I guess I might as well finish it up or delete it.

A few weeks ago, I was surprised to be called up on stage by John Loiacono in front of a room full of the leaders of Sun's Software division and presented me with the quarterly award for Collaboration for the January-March quarter. That's the quarter Solaris 10 shipped, and I was recognized for work that went into that release, primarily the integration of the Xorg server into Solaris. All I got to say at the time was "Thanks", which is probably best, since as an award for collaboration, I couldn't have earned it without help from my many collaborators, and it would have taken a long time to thank all of them. I'm going to try here, but even still will probably forget someone, and if so I apologize in advance.

The Xorg server project never could have been done without the hard work of the entire X engineering team, our colleagues in the x86 Platform team in LA, the Desktop and x86 Video QA teams in Beijing, and our tireless program manager Ray. And of course, without all the groundwork laid by the contributors to the original X Consortium, the XFree86 Project, and the X.Org Foundation to create the software, we'd have nothing to integrate.

Besides the Xorg server project, the announcement called out several other projects for Solaris: Implementing Solaris Service Management Facility (SMF) support for the xserver, PAM authentication and auditing in xlock, other security support in X, and updating and modernizing the Solaris xserver keyboard and mouse code. The internal Greenline community provided valuable help and suggestions in designing and implementing our SMF services. The xlock work couldn't have been done without the help and advice from Gary and Darren - especially the auditing support which Gary wrote for us. Casper's work on getpeerucred() made the localuser and localgroup X authentication methods possible on Solaris. As for the keyboard and mouse drivers, in large part they built on work done by the USB & PS/2 driver teams to add support for wheel mice, mice that report absolute coordinates, and the "virtual" mouse/keyboard project that's coming soon to handle multiple mice and keyboards seamlessly.

The award itself is an interesting bit of work, described as "Scrapyard Art", which was created by San Jose artist Noreen Rubay. I've posted a photo of it on flickr.

So given all this, what's next? Different types of collaborations, with different groups. I'm one of about a dozen people working on X.Org's Modularization Project. I'm working with the OpenSolaris team to set up the X Window System community on opensolaris.org for the upcoming launch. And in my spare time (yeah, right, like I have any), I've even been working on setting up a clone of del.icio.us inside Sun's firewall, to allow people to share their links to all the useful sites inside the Sun network. But it's getting late, and we've got new episodes of The 4400, The Dead Zone, and McBride on our TiVo, so I'll save the details on those until later.


[] [] []

http://blogs.sun.com/alanc/date/20050602 Thursday June 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
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.
[] [] [] []