xscreensaver 4.13

XScreenSaver 4.13 out now -- no new savers this time, but now on Xinerama systems, it will run one saver on each monitor (just like in "real" multi-head mode) instead of running one saver stretching across all the screens (which looked like ass.)

Sadly, to make this work, I had to add a kludge to the vroot.h file (which is the mechanism by which client programs find the root window to draw on.)

So this means that all the bundled screen savers will work fine, but any 3rd party screen savers will need to be recompiled with the latest vroot.h, or they will malfunction with Xinerama (they'll draw on the wrong window and compete with whatever is already running there.) For example, Xinerama users will be wanting to download the new version of XDaliClock if they use it with xscreensaver.

Extra super-sekrit bonus hack that works even with single-monitor systems: add the line "quad: true" to your ~/.xscreensaver file.

<LJ-CUT text=" 'What did I change,' I hear you asking... (30%) ">

What did I change? I hear you asking. Well, here's the deal. Back in the caveman days when I wrote xscreensaver, there were a bunch of programs floating around that could draw on the root window. I wanted to use those as screen savers, but didn't want to have to cut-and-paste the code to make that work.

It happened that, with some window managers, these programs had to include this silly vroot.h file in order to work, because those window managers had a "virtual" root window. So, eureka, xscreensaver could just impersonate the root window in the same way the window managers do, and everything would just magically work. Sweet.

Fast forward about ten years. Now it's common for people to have multiple monitors attached to their computers. X has always had a way of doing this; basically each screen is its own desktop. The mouse can move between them, but windows can't, so you have to launch windows on the screen you want them to stay on forever. This is kind of lame, so the popular thing to do is use the "Xinerama" extension, which makes it possible to move windows from one screen to another. In Xinerama mode, there's really only one X "screen", as far as programs can tell, it just happens to be really wide. It's possible to find out which parts of that one screen are covered by glass, but other than that, there's really no way to address each monitor independently. (You might expect that the way Xinerama is implemented is as a proxy on top of the underlying X screens, but it's not: all the monitors actually share one frame buffer.)

This is a problem for xscreensaver, because the way it runs different screen savers on each monitor depends on those programs drawing on the first root window they can find. This works great in normal multi-head mode, because each screen has exactly one virtual root window. In Xinerama-mode, we'd need multiple virtual root windows on the one X screen, and no way to tell the screen savers which one to use (since we want each of them to use different ones.)

So, I hacked vroot.h to first consult the environment variable $XSCREENSAVER_WINDOW, and if that's set, just draw there. This is somewhat evil, since it's the first change to vroot.h since 1991...

If I were starting over from scratch today, I'd just demand that all programs to be used as screen savers take a --window-id command-line option instead of doing this fake root window nonsense, but with the weight of history and the vast installed base, I think that the vroot.h change is probably the least hassle.

Also, this way the change only affects multi-screen Xinerama users, instead of affecting everybody.

Tags: , , ,
Current Music: Cubanate -- 9:59 ♬

6 Responses:

  1. chromal says:

    This sound excellent. I've been running xscreensaver in Xfree86 4.3.0 with the xinerama extension enabled, but my dual-head Matrox G450 card (or possibly the display driver the the mga X server?) would flake out badly when OpenGL-enabled screensavers attempted to write on a inter-framebuffer root window. I think the second output framebuffer on the matrox g450 lacks some of the 3d acceleration functionality.

    Whatever the cause, the end result would always be that xscreensaver would be randomly running screen savers and eventually call an OpenGL 'saver and then something inside the x server would rupture cause it to die horribly. It took my a while to realize what was happening, but I eventually disabled all the OpenGL savers and the problem went away.

    I'm not sure how many cards this affects, and I'm not sure who needs to fix it (Mesa team? Xfree86 team? Matrox?). It sounds like this change brings xscreensaver within easier hackability to work around this xinerama+G450 limitation.

    Er. Anyway, cool.

    • jwm says:

      The second output buffer does lack 3d acceleration, unfortunately.
      I found I was better off not using xinerama for that reason. Would
      have been nice to not have GL savers run on the second monitor at all,
      but I'm not running it at the moment, so I may never figure out how
      to hack that to work.

    • jwz says:

      I have a G450 and it's pretty flaky, so you may still experience lossage even with this hack. I found that "starwars" would cause X to lock hard pretty regularly, though since I'm not enough of a massochist to run a debugger on the X server, I have no idea why. This has been the case from RH7.0 through RH9.

      I'm running the G450 in Xinerama mode now (instead of real multi-head), and I find that it regularly gets in a mode where GL apps just won't show up on the secondary screen: they're black. Drag the window to the other screen, and it's there. Straddle the monitors, and half of it is there.

      Which is extra goofy, because I think Xinerama disables DRI, so all these GL programs ought to be running in unaccelerated software mode anyway, so how are the heads behaving differently?

      The "mgapdesk" stuff can enable a Matrox-specific Xinerama-like mode that supposedly gives you 3D accel on both heads -- but that doesn't actually give you the Xinerama info (there's no way for clients to know where the glass is) so it makes everything malfunction: GDM login boxes straddle the screens, the Gnome Panel goes all the way across the bottom of both screens, and, of course, xscreensaver runs one wide hack.

      Yow, is it time to get a Mac yet?

  2. boggyb says:

    So with X you can have either 1 desktop per monitor, with windows staying out on their own monitor, or you can have what nVidia calls span mode (in their nView system). Y'know, I think Microsoft actually got something right for a change. On my nVidia dualhead card, I can make it pretend to be two seperate cards, and that way Windows treats it as one big desktop while also treating it as two seperate monitors (which I think don't share framebuffers, since the mouse pointer cannot appear on both monitors at the same time and also since weired things happen when you have a DirectX app spread across both screens).

    Just my tuppence.

  3. kyzoku says:

    Ah very nice indeed. Finally I can run BSOD at work again and have it look right. It's just no the same when the blue screen is split across two screens with empty blackness on either side.