Playing with SVG filters on HTML content

Note: The technique described below only works in Firefox 3.5 and above (or products using the same rendering engine). It isn’t part of any formal spec (though it would be a great addition to one of them), and could potentially get removed with a future Firefox release.

Introduction

One of the lesser known tricks that you can do with Firefox 3.5 and above, is apply SVG clipping paths, masks and filters to HTML content. You can read more detail about the technique here:

http://weblogs.mozillazine.org/roc/archives/2008/06/applying_svg_ef.html

That’s all very nice and impressive in theory, but in practice actually creating an SVG filter to do the job you want is a less than intuitive process. For some common uses – such as drop shadows – you’re better off using the CSS3 native code, such as box-shadow and text-shadow. But other effects really do need the power of SVG filters.

Luckily there’s an easier method for creating filters than coding them by hand: Inkscape. This is an Open Source vector graphics editor which uses SVG as its native file format. It’s a powerful program – certainly powerful enough that I use it to create my webcomic, The Greys – and it not only has a user interface for creating filter chains but, more importantly, it has a lot of good filters pre-defined.

To be fair, the UI for creating and modifying filters leaves a lot to be desired and is only a little better than coding them by hand. It would be a lot better if it were possible to select one of the intermediate filter steps in order to see the effect of the filter up to that point, as that would make it easier to understand how some of the more involved filter chains work. As it stands it’s a functional but somewhat inelegant way to set up filter chains without having to remember which filter primitives take which parameters.

Thankfully version 0.47 of Inkscape introduced a Filters menu which contains dozens of pre-defined SVG filter chains. Applying one of these filters is as simple as selecting a target object in the main Inkscape window and choosing the filter that takes your fancy. Below you can see the results of duplicating a line of text a few times and applying a handful of filters straight from the menu.

Basic Code

So we’ve got a browser that can apply SVG filters to HTML content, a blog entry describing how to do it, and a whole load of ready-made filters, just ripe for the picking. How do we combine these into one fancy HTML page? First of all, let’s start with a basic bit of HTML using the simplest of SVG filters, “feBlur”:

<html xmlns="http://www.w3.org/1999/xhtml">
<body>

<svg xmlns="http://www.w3.org/2000/svg" height="0">
  <filter id="f1">
    <feGaussianBlur id="blur-filter1" stdDeviation="5"/>
  </filter>
</svg>

<style>
  .blur { filter:url(#f1); }
</style>

<h1 class="blur">This is an example of SVG filtered text</h1>

</body>
</html>

Save this with an “xhtml” extension (it needs to be XHTML, not just HTML, because we’re mixing XML languages using different namespaces – if you want to serve this online, you’ll need to make sure you use the correct XHTML mimetype). Then load it into Firefox >= 3.5 and you should see something like this:

Okay, let’s dissect the code so that it’s easier to work out what goes where as we move forward. First there’s the usual XML preamble and opening HTML tag. Next comes an SVG section which contains the filter itself. This is the most significant change from the original post linked above: rather than declaring the SVG namespace at the top of the page and then prefixing every SVG element, I’ve chosen to declare the default namespace on the SVG element itself. This means that the child elements don’t need to be prefixed – which will save us a lot of time when we start to introduce more complex filters. The filter is given an ID of “f1″ so that we can refer to it later. Not much later, as it happens…

The next section is a simple CSS style rule which attaches the filter with an ID of “f1″ to any element with a class name of blur.

Finally there’s the actual HTML – in this case an H1 tag to give us some big bold text to work on, as some of the filters don’t have much of an effect on thin small elements. To make extra certain you could, of course, add some additional styling to the .blur CSS declaration to ensure big bold fonts, but I’m trying to keep the markup clear of extraneous extras here.

Okay, that’s not too tricky. An SVG filter with an ID, a stylesheet to map that ID to a class, and some content that has that class. So what happens if we want to apply a more complex SVG filter to the text? Let’s start by creating an Inkscape file that uses it…

Getting Filters from Inkscape

Let’s fire up Inkscape and create a new SVG document containing our filter of choice. By default Inkscape starts with a blank canvas, so we just need to add some content and a filter to it. Because we’re aiming to style some HTML text, it makes sense to test Inkscape’s filters using a text object – but you can use any other Inkscape object, or even drag an image into the page, if you prefer:

0) I’m starting at zero because this is a non-essential pre-requisite step that will just make your filters a little easier to copy-and-paste later. In Inkscape select Inkscape Properties from the File menu, then find and select the SVG output section on the left. Make sure the Inline attributes option is checked, and set the Indent, spaces setting to something low (I use 2). These changes ensure that your filters don’t end up taking up dozens of lines in your text editor by putting each attribute on a separate line, and that any deeply-nested filter chains don’t go flying too far off the right of your screen.

1) Select the text tool from the toolbar on the left:

2) Using the toolbar at the top of the canvas, set some parameters for your text. Here I’ve chosen to use Arial as the font, with a size of 40px, left aligned, and emboldened. Setting the font size to something fairly large, and making it bold, both mean that there’s a larger drawn area for the filter to work on – some of the filters appear to have little or no effect if your target object is too small or thin.

3) Click on the canvas and type something.

4) Switch back to the selection tool (the arrow icon at the top of the toolbar on the left), and make sure your text is selected. If you’re not certain, click well away from it on the background of the canvas to de-select it, then click on the text to select it.

5) Pick a pre-defined filter from the Filters menu to try out. For our purposes we’ll use Leopard fur from the Materials sub-menu. You should see something like this:

6) Save the file, ensuring that you pick “Plain SVG” as the file format. If you inadvertently leave it as “Inkscape SVG” it won’t cause any problems, but you’ll have some unnecessary cruft in your file that you’ll have to work round or ignore later.

If you’ve been following along at home your file will look like this (it will be a bit different if you used another filter, and a lot longer if you skipped step 0):

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->

<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.1" width="744.09448" height="1052.3622" id="svg3528">
  <defs id="defs3530">
    <filter color-interpolation-filters="sRGB" id="filter4196">
      <feTurbulence baseFrequency="0.143" numOctaves="5" type="fractalNoise" id="feTurbulence4198" />
      <feColorMatrix result="result1" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5 -3.45" id="feColorMatrix4200" />
      <feComposite in2="SourceAlpha" operator="in" result="result3" id="feComposite4202" />
      <feColorMatrix values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 6 0" id="feColorMatrix4204" />
      <feMorphology result="result3" radius="1.8" operator="dilate" id="feMorphology4206" />
      <feGaussianBlur result="result3" stdDeviation="1" id="feGaussianBlur4208" />
      <feGaussianBlur result="result4" stdDeviation="2.7" id="feGaussianBlur4210" />
      <feComposite in2="result3" operator="out" result="result1" id="feComposite4212" />
      <feColorMatrix result="result3" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6 0" id="feColorMatrix4214" />
      <feFlood result="result2" flood-opacity="1" flood-color="rgb(209,151,45)" id="feFlood4216" />
      <feComposite in2="SourceGraphic" operator="in" in="result2" result="result91" id="feComposite4218" />
      <feComposite in2="result91" operator="atop" in="result3" result="result3" id="feComposite4220" />
      <feGaussianBlur stdDeviation="7.2" in="SourceAlpha" id="feGaussianBlur4222" />
      <feDiffuseLighting result="result92" diffuseConstant="1.91999996" surfaceScale="10.60000038" id="feDiffuseLighting4224">
        <feDistantLight azimuth="225" elevation="48" id="feDistantLight4226" />
      </feDiffuseLighting>
      <feBlend in2="result3" mode="multiply" result="result3" id="feBlend4228" />
      <feComposite in2="SourceAlpha" operator="in" result="result3" id="feComposite4230" />
      <feTurbulence result="result92" baseFrequency="0.106" numOctaves="3" id="feTurbulence4232" />
      <feDisplacementMap in2="result92" scale="4.5" xChannelSelector="R" yChannelSelector="G" in="result3" id="feDisplacementMap4234" />
    </filter>
  </defs>
  <g id="layer1">
    <text x="53.20932" y="308.90967" id="text3538" xml:space="preserve" style="font-size:40px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;filter:url(#filter4196);font-family:Arial;-inkscape-font-specification:AlArabiya Bold"><tspan x="53.20932" y="308.90967" id="tspan3540">Some Test Text In Inkscape</tspan></text>
  </g>
</svg>

Phew! There appears to be a lot going on in there – but that’s just because I’ve used a particularly complex filter. In practice we just want to copy the filter section into our HTML file, add a CSS rule to map it to our HTML and add some corresponding HTML. It doesn’t matter which filter you use in your Inkscape file, the basic steps are the same:

1) Start with the XHTML example file at the top of this page. We’ll add the new filter to it, but I’m sure you can work out how to completely replace the existing one if you want to
2) Copy the filter code from the SVG file. This is everything from the line that starts with <filter… to the line that ends with <filter/> – including the start and end lines themselves
3) Paste the filter code into the HTML document below the existing filter (i.e. just below the existing <filter/> line)
4) You can give the filter a shorter, snappier ID if you want – or stick with the Inkscape-generated one. In this case Inkscape has generated “filter4196″ (at the end of the <filter… line), so I’ll replace it with “f2″
5) Duplicate the CSS line which currently maps the “blur” class to the “f1″ filter. Edit the duplicate line with a new class name and the right ID for the new filter – in my case I’ve picked a class of “leopard” and changed the filter ID to “f2″
6) Add some HTML using the class you defined above
7) Save your XHTML file, and load it into Firefox

Here’s what my final file looks like:

<html xmlns="http://www.w3.org/1999/xhtml">

<body>

<svg xmlns="http://www.w3.org/2000/svg" height="0">
  <filter id="f1">
    <feGaussianBlur id="blur-filter1" stdDeviation="5"/>
  </filter>

  <filter color-interpolation-filters="sRGB" id="f2">
    <feTurbulence baseFrequency="0.143" numOctaves="5" type="fractalNoise" id="feTurbulence4198" />
    <feColorMatrix result="result1" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5 -3.45" id="feColorMatrix4200" />
    <feComposite in2="SourceAlpha" operator="in" result="result3" id="feComposite4202" />
    <feColorMatrix values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 6 0" id="feColorMatrix4204" />
    <feMorphology result="result3" radius="1.8" operator="dilate" id="feMorphology4206" />
    <feGaussianBlur result="result3" stdDeviation="1" id="feGaussianBlur4208" />
    <feGaussianBlur result="result4" stdDeviation="2.7" id="feGaussianBlur4210" />
    <feComposite in2="result3" operator="out" result="result1" id="feComposite4212" />
    <feColorMatrix result="result3" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6 0" id="feColorMatrix4214" />
    <feFlood result="result2" flood-opacity="1" flood-color="rgb(209,151,45)" id="feFlood4216" />
    <feComposite in2="SourceGraphic" operator="in" in="result2" result="result91" id="feComposite4218" />
    <feComposite in2="result91" operator="atop" in="result3" result="result3" id="feComposite4220" />
    <feGaussianBlur stdDeviation="7.2" in="SourceAlpha" id="feGaussianBlur4222" />
    <feDiffuseLighting result="result92" diffuseConstant="1.91999996" surfaceScale="10.60000038" id="feDiffuseLighting4224">
      <feDistantLight azimuth="225" elevation="48" id="feDistantLight4226" />
    </feDiffuseLighting>
    <feBlend in2="result3" mode="multiply" result="result3" id="feBlend4228" />
    <feComposite in2="SourceAlpha" operator="in" result="result3" id="feComposite4230" />
    <feTurbulence result="result92" baseFrequency="0.106" numOctaves="3" id="feTurbulence4232" />
    <feDisplacementMap in2="result92" scale="4.5" xChannelSelector="R" yChannelSelector="G" in="result3" id="feDisplacementMap4234" />
  </filter>
</svg>

<style>
  .blur { filter:url(#f1); }
  .leopard { filter:url(#f2); }
</style>

<h1 class="blur">This is an example of SVG filtered text</h1>
<h1 class="leopard">This is another example of SVG filtered text, now with leopard print!</h1>

</body>
</html>

And here’s what it looks like when I load it into Firefox:

You can rinse and repeat this process to add as many SVG filters as you like to your HTML content. Some work better than others, and some work better on images than text (yes, you can apply SVG filters to images in your HTML as well). The fact that inkscape provides an extensive library of pre-defined filters, and an opportunity to see them in action and even tweak them if you want to, means that producing the right filter for your needs is a lot easier than it would otherwise be.

Multiple Filters On One Object

It’s quite common to use multiple classes on a single element in HTML. The CSS rules cascade, with identical CSS properties overriding each other. Set the “font-size” in one selector, and it can be overridden by “font-size” in another. The same thing applies to the “filter” property that we’re using here. Initially you might think that you can add both leopard print and blur by using both classes:

<h1 class="leopard blur">This is an example of SVG filtered text</h1>

…but in practice one of the “filter” properties will override the other, so only a single filter gets applied (which one depends on how your CSS rules are written). The filter property can only take a single value, not a list of multiple values, so you can’t resolve the issue there, either.

If you want to use multiple filters on a single object, then unfortunately you have little choice but to construct an über-filter which combines all the filters you want to use into a single SVG filter element. It’s not as flexible as being able to apply multiple filters, but it’s also not as difficult as it sounds.

1) Create a document in Inkscape as above, adding your first filter
2) Add subsequent filters from the Filters menu – these will be appended to the first filter
3) Save the file and proceed as above, copying the über-filter from the Inkscape file into the XHTML file

In this way you can experiment with different combinations and ordering of filters within Inkscape before finally exporting your file. You can tweak each filter rule’s parameters in Inkscape’s filter editor and see the results applied immediately. This is a far more effective way to play with this capability than repeatedly changing the settings in the XHTML file and reloading the page in Firefox.

Conclusion

It’s common to see images used to replace text on websites, especially for headings. A good HTML coder will also add various tweaks and hacks to make the heading still work in text-only browsers or screen readers, not to mention making it visible to search engines. All this is a lot of extra work, which needs to be repeated every time a new heading is needed or an old one needs to be changed.

Many of these images are just text with a few stock Photoshop filters applied – exactly the sort of thing that could be achieved with SVG filters. By using SVG filters on HTML content the text remains as text – with all the accessibility and indexing advantages that implies. Unfortunately you have to weigh up these advantages against the enormous disadvantage of this technique only working in Firefox.

I can only hope that this functionality is made available in some (near) future versions of WebKit (Safari, Chrome, Konqueror) and Presto (Opera). I don’t hold out much hope for Internet Explorer, but as Microsoft has recently joined the SVG working group, there’s always a chance. In the meantime it’s an interesting application of technology but, like a lot of cutting-edge HTML, it’s not really practical for use on the web at large.

Posted in Tech, Web. No Comments »

Easy easing gets easier; hard easing stays hard

I’ve just been reading about CSS Transitions, which are part of the CSS3 draft specification, and which has been experimentally implemented in Opera, Webkit (Safari, Chrome and Konqueror amonst others) and in nightly builds of Firefox (with documentation on the ever useful devmo). CSS transitions provide a declarative way to animate CSS properties – in other words an easy way for a web page developer to say “this menu item should smoothly change from red to green, and get 3 pixels taller when the user puts their mouse over it”. As such they will be a great step forward in helping to make the web a prettier, more friendly place. Unfortunately it’s missing some of the most useful easing functions.

An easing function is essentially a curve which defines how the speed of the animation changes over time. Consider an element moving 100 pixels in 100 seconds. With a linear easing function, after 10 seconds the element will have moved 10 pixels, after 73 seconds it will have moved 73 pixels – it’s a simple 1:1 relationship between time and the value being animated (position, in this case):

In the CSS transitions spec, the easing function is always considered as starting from (0,0) and ending on (1.0,1.0), so the graph sticks to these figures. In practice you can think of the graph as showing time running from 0 to 100% of the transition period on the x-axis, and the relative value of the transition running from 0 to 100% on the y-axis. By changing the shape of the easing curve it’s possible to create animations which seem to accelerate or decelerate, which often gives a more pleasing result. In adddition to “Linear” the spec defines the following easing functions: ease, ease-in, ease-out, ease-in-out:

In addition to these basic easing functions, you can specify a custom function. In practice what you’re actually defining is the location of the two bezier control points that affect the easing function, but it does mean that you can go some way outside of the default curves if you really want to:

But here’s where the restriction comes in. Your custom function actually only specifies the location of two bezier control points – and they have to be within the range 0.0 to 1.0. You can’t have an easing function with extra intermediate points in it, and you can’t have an easing function whose value goes above 100% or below 0%. What that means, in practice, is that you can’t have an animation that appears to overshoot its destination before sliding back into place:

It also means that you can’t have an animation that overshoots its destination value, then undershoots, then overshoots, eventually rippling to a halt:

And you can’t create a bouncing ball animation:

You know that rebounding effect that you get when you scroll too far on an iPhone menu? You can’t re-create that. Perhaps you’d like to code your e-commerce site with a bounce effect as people drop things into their shopping baskets. Nope, you can’t do that either.

Yes, technically it’s possible to string several animations together by writing some script to catch the “transitioned” event and then trigger another animation. The devmo page even gives an example of doing exactly that to continuously animate a box with text in. But really that’s a crap workaround when the real solution is for the spec to allow more sophisticated easing curves.

It’s great that web developers will soon be able to trivially animate CSS values using simple easing functions. It’s not so great that they can’t trivially use more complex easing functions. We live in a world where mobile phones have user interfaces which pulse, bounce and ripple, providing visually stimulating feedback. Is it too much to ask for our browsers to easily allow the same?

Posted in Tech, Web. No Comments »

DVD Menu Overkill: Redux

They say a picture is worth a thousand words, but due to my tendency to waffle on a bit, my 1200 word epic about the extraneous crap they put on DVDs has been more succinctly covered by this picture (click for the full-sized original):

Posted in Miscellaneous. No Comments »

Why can’t we have a common on-demand TV service?

For the past couple of weeks my Freeview TV reception has been dreadful. The BBC channels are okay, but most other things have a signal strength that is too low to watch – especially during bad weather.

It appears that the problem is the Oxford transmitter, which has been replaced with a reserve transmitter while the main one is upgraded in preparation for the “digital switchover” next year (more details here). As I’m on the edge of the range for this transmitter I never got a great signal strength in the first place, so until this work is finished – which could take weeks yet – I’m left without the majority of channels.

“Just use the catch-up services over the web”, seems to be a common response from commenters on sites which mention this problem. They’re referring to the web-based apps which let viewers watch programmes they might have missed during the past week: BBC’s “iPlayer”, ITV’s “ITVPlayer”, Channel 4’s “4OD” and Five’s “Demand Five” – and that just covers the “traditional” five terrestrial broadcasters in the UK, not all the less well-known channels who probably have their own offerings. Watching programmes through these viewers is less-than-ideal for a number of reasons:

  • They’re web based, which means watching on a computer, or hooking a computer up to the TV and the audio system – possible, but a real pain
  • My computers are old or cheap machines running Linux – they’re fine for the normal day-to-day computing tasks I use them for, but full-screen Flash playback is a problem
  • If I don’t full-screen the player, I’m left with static web-page elements burning their marks into my plasma screen
  • Even if I get full-screen Flash going, the video quality isn’t exactly stellar due to the low bandwidth and small original image size

There’s one jewel in the crown of catch-up services, and that’s the BBC’s iPlayer. In all honesty their web-based version suffers from the same issues as any embedded Flash player (or similar technologies such as Silverlight). But the BBC have an ace up their sleeve in the form of iPlayer for the Nintendo Wii.

iPlayer for the Wii is wonderful. Yes, it’s still inferior quality to broadcast TV, but it has the distinct advantage of already being connected to the TV and audio system, and it’s operable from the sofa with the Wii remote. It’s not as good as a real TV signal, but it’s a damned sight better than any temporary hook-a-laptop-to-the-TV fix. Of course it also doesn’t help us much in this case as our BBC reception is still fine.

But I do have to question quite why we can get the BBC’s content via the Wii, but nobody else’s. Do we really still live in a world where each broadcaster has to code their own Wii channel independently? We don’t need a different set-top-box for each Freeview channel – they all conform to the same standards and can be decoded by any Freeview box. So why can’t they do the same for their catch-up content.

Please, TV companies, get together and sort this one out. I don’t want iPlayer for the Wii – I want “UK TV Player”, with the ability to watch any channel’s catch-up programmes. One application for the Wii would get me all the channels I watch, and then some. As would a single XBox360 program, or a PS3 application. Not to mention Windows, Macs, Linux and mobile phones.

If all the broadcasters clubbed together I’m sure they could make cost savings overall. They could focus their energies (and money) on a better user experience by making the “UK TV Player” available on as many operating systems and devices as possible. And people like me, stuck without a working Freeview signal, wouldn’t have to waste their time hooking a laptop up to the TV when there’s already a perfectly good games console more than capable of showing me their programmes.

Posted in Miscellaneous. No Comments »

XDMCP support in Ubuntu: make your voice heard

As I’ve pointed out previously, the XDMCP support has been severely crippled in Ubuntu 9.10, Karmic Koala. I suspect that XDMCP is something that isn’t considered a very high priority by the Ubuntu and upstream developers, as it’s an old protocol with security issues. Up until Karmic, however, it had the distinct advantage of being already installed (even on a Live CD) and easy to activate and access via the GUI.

It seems that I’m not the only one affected by this issue. In fact I’ve been quite surprised by the number of people who have flooded to this blog as a result of my articles on this. The most heavily visited page has received over 9,000 page views since I posted it. That’s NINE THOUSAND views, from over 6,000 unique visitors. Not bad for an old protocol with security issues. If I add together the hits for all the XDMCP pages on my blog, the total is over 23,000.

Clearly there are lots of people being affected by this issue, but most of them are suffering in silence or just getting on with it, perhaps by using one of the workarounds or alternatives I’ve talked about previously. Up to now I’ve avoided posting links to the relevant bugs on Ubuntu’s Launchpad site, as I didn’t want the bugs to get filled with a load of “me too” comments. But the other day I came across this blog post from the Launchpad developers about a new feature of Launchpad, “bug heat”. This extract from that post explains it better than I could:

…A bug’s heat is a calculated estimate of its importance, using factors such as how many people are subscribed, whether it’s a security issue, how many people have marked the bug as affecting them, and so on…

So I figured that if even a small proportion of those 6,000 visitors affected by this issue were to mark the relevant bug as affecting them, we can turn up the heat on this issue. So if you want to register yourself as a fellow sufferer, please do the following:

  1. Visit https://bugs.launchpad.net/gdm/+bug/408417 – the bug title is “No option to log in remotely via XDMCP”
  2. Read the bug description and have a look at the comments. Make sure that this really is the bug that’s affecting you, and that you’re happy to register yourself as being affected by it
  3. Log in to Launchpad (top right-hand corner), if necessary. If you don’t already have a Launchpad account you can create one there. Once you’re logged in you should be redirected back to bug #408417, but if not you can use the link above
  4. Find the line just below the bug title which says “This bug affects NN people. Does this bug affect you?” – where NN is the number of people who have already registered this bug as affecting them
  5. Having found that line, you should see a little exclamation mark to the right. I’ve subtly pointed it out on the screenshot below using a red arrow.
  6. Select the option for “Yes, This bug affects me” (or select “No” if you’ve changed your mind) and click on the “Change” button
  7. You should be returned to the bug page, and the text should have changed to read something like: “This bug affects you and NN other people”

That’s it. Job done. Another count for the tally, and hopefully a little increase in the bug heat. Please do not add any other comments or information to the bug unless you genuinely have something useful to contribute.

Please note that no matter how “hot” this bug becomes, it’s not likely to be addressed in time for Ubuntu 10.04. By raising awareness like this, however, it might stand more of a chance of being looked at for 10.10. Because it’s not likely to get fixed in the near future, you might also be interested in voting for bug #217798 which proposes adding Xephyr support to the terminal services client, given that the official party line from the Ubuntu devs seems to be that using tsclient is the recommended way of accessing XDMCP servers currently.

 
 
 

* tsclient+XNest is currently the recommended way to access an XDMCP server, since the removal of the remote login option in GDM, despite the fact that XDMCP support in tsclient requires XNest to be downloaded as it’s not shipped on the CD by default. This means that it’s no longer available to a Live CD user with no internet connection as a thin XDMCP client. These days I prefer to use Remmina over tsclient, as it does support Xephyr – but again that option is only practical if you can download and install applications to the client machine.

Posted in Linux, Tech. No Comments »

Another use for 3D TVs

It seems that just about every manufacturer is planning to launch 3D-capable TVs this year. Most of them use high frequency refresh rates, synchronised with LCD shutter specs, to present a different image to each eye: the screen is actually switching between two images extremely quickly, and each lens on the glasses switches between dark and clear so that the left eye only sees image 1, and the right eye only sees image 2. Let’s get that 100% clear: the left eye for all the viewers sees image 1 while the right eye is blanked out, then a fraction of a second later the left eye is blanked and the right eye sees image 2. Persistence of vision deals with the discontinuity in the images, just as it does with a regular TV.

That’s great… except that there isn’t a great deal of 3D content to watch at the moment. Most people will use their expensive new 3D TVs to watch predominantly 2D content for the time being. It seems a shame to waste all that image switching tech and LCD glasses… but perhaps there’s another use for technology: showing two different TV programmes at once.

Consider the following theoretical 3D TV: It has a single main remote control which has all the features you’ll never use, but comes with a second mini-remote which lets you change channels, select AV inputs, and adjust the volume of the second headphone socket. Second headphone socket? This imaginary TV has two separate headphone sockets, to go with the twin tuners that are built-in. The frames from one tuner or AV input are interlaced with the frames from the second, so that the TV is constantly switching between the two images at a high frequency.

The LCD glasses are also slightly modified with a 3-way switch to select between “3D”, “Programme 1″ and “Programme 2″. This just changes the way in which they synchronise with the TV. In 3D mode they operate as described above, alternating between which eye is clear and which is dark. In the other two modes both eyes operate synchronously, so that both eyes see image 1, but are blanked from image 2 (or vice versa).

This setup means that two people can watch different programmes on the same TV at the same time by setting one pair of glasses to “Programme 1″ and another to “Programme 2″, and donning a pair of headphones. It’s not hard to imagine a pair of kids playing a videogame, with the sound coming from the main speakers, while a parent or guardian watches a film using headphones. Want to check that the kids are playing something appropriate to their age? Just flick the switch on your glasses to see what they’re watching.

I have to admit that I haven’t used a pair of LCD shutter glasses, so I don’t know how much shadowing of the second image will be visible, but I would imagine it is likely to be acceptable for day-to-day use. It will probably also depend on the content – trying to watch a dark and moody horror film while the second programme is displaying a brightly coloured game will probably show more of a shadow than two images of similar brightness. But if it means being able to watch something different to your partner without having to become a social pariah, banished to “the spare room”, then it’s probably worth a little bit of ghosting.

Posted in Miscellaneous, Tech. No Comments »

Removing the mystery lines on a XUL checkbox

XUL has a checkbox widget, which you are expected to use like this:


<checkbox label="Account Locked" />

That will give you a perfectly functional checkbox with a label to the right of it (add dir=”rtl” if you want the label to the left of the checkbox). The image below shows how they appear on my Linux machine – the top part is an unselected checkbox, whereas the lower one has been clicked on, which has the effect of both checking the checkbox and focussing the widget:

Standard XUL checkboxes

It’s the focussing that’s the important bit here – notice how the label gets surrounded by a dotted border. A similar effect is used on a Windows machine, and is generally “a good thing” as it makes it clear which widget will be affected by keyboard presses (such as using the space bar to toggle the checkbox state).

Sometimes, however, the presence of this focus border is not “a good thing”, and can in fact become “a confusing thing”. Consider a user interface which has labels and widgets all neatly aligned using a XUL grid. In that case you might not want to have a label directly on the checkbox element at all, in which case you can find that a focussed checkbox takes on a most disconcerting appearance:

checkbox_no_label_1

The focus border is still being drawn around the non-existent label text. In this case it’s made worse by the checkbox being the second item in the row of a XUL grid with two columns. Because the field in the row below is much wider than the checkbox, the non-existent label flexes to fill the space, making an already odd looking widget seem even weirder. Incidentally, the field below is an XBL widget of my own devising, which is why it doesn’t look like a normal XUL textbox.

Putting the checkbox inside a XUL hbox element has the effect of curtailing its flexing habits, so that the focus border, while still present, is a little less offensive:

checkbox_no_label_2

But wouldn’t it be better to get rid of the focus border altogether? A little digging with the DOM inspector revealed that the checkbox label is being targetted with the following CSS selectors – the first on my Linux installation, and the second on Windows XP:


checkbox:focus > .checkbox-label-center-box > .checkbox-label-box

checkbox:focus > .checkbox-label-box

It’s possible to hit both of these by losing the immediate child selector (the “>”) and the “checkbox-label-center-box” class, so that the rule matches any descendent of a focussed checkbox which has a class of “checkbox-label-box”. A blunt approach would be to just disable the focus border altogether, by adding this to your CSS file:


checkbox:focus .checkbox-label-box
{
-moz-appearance: none;
border: none;
}

That does disable the focus border, but it disables it completely – even if the checkbox is used in a situation where it does have a label. Thankfully Firefox’s CSS engine is rich enough to let us use the [label] selector, to match elements which have the “label” attribute, as well as the :not() pseudo-class to negate the match. The result is this chunk of CSS, which will disable the focus border on checkboxes which don’t have a “label” attribute, but leave it untouched on those that do:


checkbox:focus:not([label]) .checkbox-label-box
{
-moz-appearance: none;
border: none;
}

Of course the proof of the pudding is in the slightly doctored screenshot (only doctored in that I pasted two together). In this you can see that the top row contains a checkbox with no label, and no focus border, and the bottom row contains a checkbox with a label which gets the default focus border that we all know and tolerate:

checkboxes_modified

Posted in Tech, XUL. 1 Comment »

What have they done to Bitzer?

I’m going to come out of the toy-chest here and reveal that I watch Shaun The Sheep. Yes it might nominally be a kids’ show, but if you think of it as “Wallace and Gromit Lite” then it’s not a bad way to spend a few minutes of downtime. Besides, you only have to look at the list of references to popular culture on Wikipedia to realise that it’s not aimed solely at children.

So I was quite pleased when I noticed that my MythTV box had recorded a couple of episodes that I hadn’t noticed in the schedules: it turns out that the second series has started. I settled down to watch it with my girlfriend (who is quite the Shaun fan) only to raise my eyebrows at what they’d done to the farmer.

The farmer used to look like this:
farmer_1024
[Original Source]

Now he looks like this:
farmer-1024x768
[Original Source - zip file of images]

The key difference isn’t easy to spot in those images, so I’ve combined and re-oriented them to make it a bit clearer:
farmer_diff

The key point is the line running around the farmer’s mouth. It’s a lot more pronounced on the show itself. It appears to me that Aardman have decided to speed up their work (or reduce costs, depending on how you look at it) by making the mouth section removable. This lets them animate the mouth movement independently of the rest of the body – and indeed the rest of the head. They did a similar trick on Chicken Run, where it was less noticeable due to the difference in colour and texture between the chickens’ beaks and faces. It stands out more on the farmer, but it’s not too bad, as it generally just makes it look like he’s got a five o’clock shadow.

So, a reasonably subtle change to the design of the farmer. He’s a secondary character anyway, so it wasn’t too distracting. But next to the eponymous Shaun, possibly the most prominent character is the farmer’s dog, Bitzer. Yes, you’ve guessed it, they’ve changed that character too. But unlike the relatively minor change to the farmer’s face, Bitzer has had a complete overhaul. And not in a good way.

Old Bitzer:
bitzer_1024
[Original Source]

New Bitzer:
bitzer-golf-1024x768
[Original Source - zip file of images]

The new Bitzer has acquired a furry texture… but not on his head. Maybe I missed the episode titled “Bitzer gets alopecia”. Perhaps the hair loss is a side effect of his efforts to dye his fur, as indicated by the colour change on his chest, throat and lower jaw. That’s the most egregious change and one which, in my opinion, really spoils the design of the character. It’s pretty obvious that, much like the farmer, they’ve decided to reduce costs by making the mouth into a removable section, independent of the rest of the head. But on the Bitzer model the distinction between the two parts – especially once animated – makes it look like Bitzer has been attacked by a bestial Hannibal Lecter, and his skin turned into a mask covering the top of the imposter’s face.

Watch out Shaun, I think there might be a serial killer on the farm. One who plans to destroy your very soul. I think his name is Aardman.

Enabling XDMCP on Karmic Koala (Pt. IV)

Other posts in this series:

  • Pt. I – Enabling GDM as an XDMCP server
  • Pt. II – Four XDMCP client options for Ubuntu 9.10
  • Pt. III – Three ways to use the host chooser
  • Pt. IV – Alternatives to XDMCP

If you’re affected by this issue, please also take a look at this post:
XDMCP support in Ubuntu: make your voice heard


Okay, that’s enough about how to get XDMCP working in Karmic. If you really, really, specifically, definitely want XDMCP support, then have a read of the previous posts. If, however, you just want a remote connection between two Ubuntu machines, then there are alternative solutions that you might want to consider.

Before abandoning XDMCP entirely, let’s just have a quick look at the pros and cons of the protocol – as it was implemented in Jaunty (i.e. back when it worked and everyone was happy). That will make it easier to compare with the other systems I’ll be describing below.

Pros

  • Already built into the X server – no need to install anything, even on a live CD
  • Easy to enable the server end via the GUI
  • Easy to connect from the client end, even without a local login on the client machine

Cons

  • High bandwidth required
  • Security is poor
  • Only cross-platform in one direction (Windows or MacOS can only be clients, not servers)

When it comes to remote access there are loads of alternatives available. I’m only going to consider a few of them. If none of these seem to suit your needs, please keep looking because there might be something else that does. With that, let’s start with that king of remote connections, OpenSSH.


OpenSSH

OpenSSH is a veritable toolkit of remote connectivity. In its simplest incarnation (ssh username@host) you get a command line running on the remote machine, and it can also be used to transfer files (scp and sftp). Those features alone can often be a viable replacement for a full remote desktop, if you know how to drive the command line. But it’s the transparent tunnelling of X data that interests us here.

Add the -X option to your ssh command and, assuming your server allows it, you can now run a graphical application from your ssh shell and have it displayed on your local machine. Note that it’s a capital X, a lower case x disables the option, and the default configuration of the OpenSSH server in Ubuntu will allow X forwarding. Ubuntu comes with the OpenSSH client by default, but you’ll need to install the server using your package manger of choice (it’s called “openssh-server”).

So, we’ve got our OpenSSH server installed on a machine called “karmic.localdomain”, and we want to run an application on that machine, but displaying on the local machine. If it’s just a one-shot command, you can do something like this:

ssh -X johndoe@karmic.localdomain xclock

As if by magic, Xclock appears on your local display, and when you close it your ssh connection is closed as well. I suppose Xclock might be handy if the server’s in a different timezone, but in practice you’re more likely to want something useful launched – perhaps Nautilus:

ssh -X johndoe@karmic.localdomain "nautilus --no-desktop"

It’s still some way from an XDMCP replacement though. It would be better if you could launch multiple applications, right? Well, just connect without specifying an application to run, then run it from the command line:

ssh -X johndoe@karmic.localdomain
karmic> nautilus --no-desktop &
karmic> xclock &
karmic>

Note the trailing ampersands – that’s standard command line usage from way back when, which causes the process to run in the background, so you get a prompt back and can launch something else. If you forget an ampersand (or want to see the console output during the application’s startup), you can press CTRL-Z to suspend the process, then run “bg” to resume it in the background. A basic grounding in Unix command-line job control is worthwhile if you use ssh a lot. I also recommend running “screen” as your first application, if it’s installed – a worthwhile addition to any command line junkie’s toolkit, but not something I will be going into any more detail about here.

The ability to launch individual GUI apps might make SSH a viable alternative to XDMCP in some situations, but often you just can’t get away from the fact that a full desktop is easier to use. You might be tempted to run “gnome-session” from your SSH command line, but that way madness lies. Trying to run a full desktop like that will work to a degree, but will also clash with your local desktop and can really screw it up when you log out of the remote session.

If you really need a full desktop connection, and really want to run it over SSH yourself, you can use OpenSSH’s ability to tunnel arbitrary TCP data to forward a VNC connection. You can’t do the same with an XDMCP connection, as that uses UDP not TCP, and OpenSSH can’t forward that in the same way. It is possible to set up a full VPN via SSH which will work, but is usually more hassle than it’s worth. A sneaky workaround is just to SSH into your remote machine, then run Xnest or Xephyr at the remote command line. Because these are both X clients, they will appear on your local desktop just like Xclock did. But they’re also X servers, so you can use them to make a connection to an XDMCP server that would otherwise be out of reach.


VNC

When talking about remote desktop connections, VNC is the first thing that will spring to the mind of many computer veterans. VNC was originally written to allow a user to make a remote connection to a Unix desktop. In that sense it is similar to XDMCP, but with one significant difference: disconnecting from an XDMCP session would kill the desktop and any applications running in it, whereas disconnecting from a VNC session would simply close the viewing application while leaving the desktop running “headless” on the server. This meant that it was possible to disconnect a VNC session on one machine then re-connect to it later, or from a different machine.

Some time later VNC was ported to Windows. Because most versions of Windows don’t support multiple users being logged-in and using a machine simultaneously, the Windows implementation of VNC shares the currently logged-in desktop with the viewer, rather than creating a new desktop. It quickly became clear that for some purposes this was actually better than the Unix approach – especially if you want to share someone’s desktop for support or training purposes.

Because of the advantages of being able to connect to a currently logged-in desktop, it wasn’t long before this same functionality was ported back across to Linux – in addition to the original Unix VNC server that could be used. Meanwhile extensions were made to the VNC protocol to support better compression algorithms or additional features, with the result that there are now a variety of different VNC servers and clients across all the major (and several minor) operating systems. I’m going to describe a few of them below, but there are many others, each with their own advantages and disadvantages, so if you don’t find one that suits you below try googling or searching in your package manager to see what other options are available.

Vino

If you want the Windows-style of VNC server, whereby the currently logged in desktop is shared over the network, then you’ll be pleased to know that it’s built into GNOME (and hence into a stock Ubuntu installation) by default. The server is called “Vino”, but in practice the name is irrelevant as you can just enable or disable it via System=>Preferences=>Remote Desktop.

There’s a counterpart to Vino, and that’s a VNC viewer called “Vinaigre” – though again, in practice, the name is irrelevant as you access it via Applications=>Internet=>Remote Desktop Viewer. Vinaigre isn’t tied specifically to Vino – it’s a general purpose VNC viewer which can be used with just about any VNC server, so it’s worth knowing about if you need to share a Windows or MacOS desktop and view it on a Ubuntu box. And it’s a whole lot more modern-looking than the old “vncviewer” application.

vnc4server

What if you don’t want to share a logged-in desktop, but want a completely different session to be available over VNC? That’s where “vnc4server” comes in. You’ll need to install it using the package manager of your choosing as a starting point. What you do with it next depends on your needs, but in any case it will involve running it on the remote machine as the user of your choice. For this example we’re going to pretend that there is a remote machine with an IP of 192.168.0.2, and your local machine with an IP of 192.168.0.3.

1) At the remote machine make sure you are not logged into the GNOME desktop. Press CTRL-ALT-F1 to get to a console, and log in. In practice you might find it easier to ssh into the remote machine instead, depending on how remote “remote” actually is.

2) At the console, run “vnc4server”. You will be prompted to create a password the first time you run it, which you can subsequently change using “vnc4passwd” if you need to.

3) You should get a few lines printed on the screen, amongst which is the address of the new VNC connection you’ve just started – in our case it will say something like “your-machine-name:1″, but I prefer to use IP addresses to avoid any name resolution issues, so we’ll access it as “192.168.0.2:1″.

4) On the local machine, launch a VNC viewer. Because it’s already installed on a stock Ubuntu system, I would use Vinaigre (Applications=>Internet=>Remote Desktop Viewer) as a starting point. Create a new connection, and put in the VNC server’s address (192.168.0.2:1 in our case). The :1 refers to the first VNC server running on the machine, which operates on port 5901 by default.

5) Enter your VNC password when prompted

6) Sigh with disappointment as you see this screen:

The default vnc4server desktop. Hmm...

The default vnc4server desktop. Hmm...

Not great, eh? Let’s try to improve matters by getting to an actual working GNOME desktop…

1) Close your local VNC viewer. On the remote machine we want to stop the vnc4server that’s running, so issue the following command

vnc4server -kill :1

2) The problem is that vnc4server starts the applications specified in the ~/.vnc/xstartup file – and because this file didn’t exist the first time you ran the server, it created it and populated it with some pretty useless defaults. Let’s take a look at this file:

#!/bin/sh

# Uncomment the following two lines for normal desktop:
# unset SESSION_MANAGER
# exec /etc/X11/xinit/xinitrc

[ -x /etc/vnc/xstartup ] && exec /etc/vnc/xstartup
[ -r $HOME/.Xresources ] && xrdb $HOME/.Xresources
xsetroot -solid grey
vncconfig -iconic &
xterm -geometry 80x24+10+10 -ls -title "$VNCDESKTOP Desktop" &
twm &

You might be tempted by the section that says “Uncomment the following two lines for normal desktop”… but you probably won’t end up with the “normal desktop” you were expecting:

This is not the desktop you were looking for...

This is not the desktop you were looking for...

Instead try editing the file to look like this (hint: as you’re at the command line, use “nano -w .vnc/xstartup” if you’re not already a vi or emacs fiend):

#!/bin/sh
unset SESSION_MANAGER
exec gnome-session &

3) Now start the VNC server again (“vnc4server”), and connect using your VNC client:

At last, a real desktop

At last, a real desktop

Okay, time for the bad news. First, this doesn’t play nicely with an already logged-in GNOME desktop, so whilst it’s good for headless servers or a machine on which you’re the sole user, it’s not so good for multiple users on a desktop machine which might have a user logged in directly on it. Second, don’t log out of your GNOME session if you want to come back to it later – just quit the VNC viewer. If you log out, it doesn’t respawn, and you’ll need to kill then restart the VNC server.

Now for the good news. You can run more than one VNC server on a machine – they’ll end up as screen :1, :2 and so on. Useful if you want to share a single server with multiple users. You can also run the server from a startup script if you don’t want to ssh in to start the server all the time – but I’ll leave that as an exercise for the reader (hint: this article is a good starting point).

Gitso

While I’m on the subject of VNC and its use, Windows-style, as a support tool it would be remiss of me not to mention Gitso (an awful recursive acronym for “Gitso Is To Support Others”!).

It’s a VNC server/viewer packaged up via a simple UI and preconfigured to make a reverse VNC connection from the server to the viewer. What this means, in practice, is that a non-techie user seeking support can run the application and type in an address given to them by the person offering support. The support person runs the application, and a VNC connection is set up such that they can see and control the user’s desktop.

There is some firewall configuration that will generally be needed, but by using a reverse VNC connection all of that is pushed off to the techie end of the line where, hopefully, the support person will know what they’re doing and be able to forward the necessary port.

Because it uses VNC it’s cross-platform, allowing you to support (and be supported) on Linux, Windows or MacOS. It’s not in the standard Ubuntu repositories, but you can download a suitable .deb package file from their website:

http://code.google.com/p/gitso/


Empathy. Or not. Or perhaps maybe.

One of the biggest issues with providing some sort of remote desktop access for support purposes is actually getting a safe connection from one machine to another. Typically most users are behind some sort of firewall or NAT, even if they don’t realise it, meaning that tunnelling a remote desktop connection becomes an exercise in port-forwarding and TCP/IP. There are numerous commercial operations who make a lot of money out of making remote desktop access easy without having to change firewall settings by having relay servers which are accessible to both ends of the connection.

As an example of this issue, Gitso (described above) requires the “techie” user to open port 5500 so that the supported user doesn’t have to. But what if there was already a near-instant communication channel between the two endpoints? Wouldn’t it be possible to use that as a tunnel for the data, with no need to go poking around in router settings? How about this Empathy instant-messaging software I’ve already got? Wouldn’t that do the trick?

The answer, in theory, is “yes”. Throughout a large period of the Karmic beta test the answer was, in practice, “yes”. Then Karmic was released… and the answer was “no”.

According to one of the comments in this bug report, the problem was a change in the terminology used to identify the remote desktop protocol, which put Empathy out of synch with Vinagre. That bug report also suggests that the problem is now solved… so I tried it, using a netbook running Karmic UNR and a desktop machine running a full version of Karmic. Both had all updates applied, and the two instances of Empathy were working fine when sending instant messages between the two GTalk accounts I was using for this test. But no matter what I tried, I couldn’t get the “Share my desktop” option to work.

Hence the title of this section. It apparently did work. Then it definitely stopped working. Then it apparently worked again, but not for me. If you need to provide remote support to another Ubuntu user, it might be worth a try – but if it’s important you should probably set up Gitso as well, just in case.


NX, and any others I’ve missed

This post is already way overdue, so I’m going to stop my experiments now and actually post the damned thing. One technology that I had planned to cover, and haven’t got round to trying, is “NX”, so I’ll give it a brief honourable mention in case you want to investigate it on your own, or have any experience with it that you want to share in the comments.

NX is a technology that takes the best bits of the X protocol, thins it out to reduce bandwidth, tunnels it over an SSH connection, and caches it heavily at the client end to reduce bandwidth even further. It’s not as cross-platform as VNC, nor as secure as SSH alone (due to its default use of well-known encryption keys), but as an alternative to XDMCP – especially over a slow internet connection – it’s well worth considering. You can find out more about it from the Wikipedia page about the technology itself, and from this Ubuntu Wiki page about installing it on Karmic.

There are other approaches and technologies that I haven’t even mentioned here, so if you’ve got any experience, good or bad, with any other remote desktop software please leave a comment for the benefit of everyone else. Personally I’m going to muddle along with XDMCP and Xephyr for intranet connections, and Gitso for remote support, whilst hoping that the built-in XDMCP support returns in Lucid, or that something comes along to fill its space that doesn’t need additional software installing on a Live CD.

Posted in Linux, Tech. 4 Comments »

Enabling XDMCP on Karmic Koala (Pt. III)

Other posts in this series:

  • Pt. I – Enabling GDM as an XDMCP server
  • Pt. II – Four XDMCP client options for Ubuntu 9.10
  • Pt. III – Three ways to use the host chooser
  • Pt. IV – Alternatives to XDMCP

If you’re affected by this issue, please also take a look at this post:
XDMCP support in Ubuntu: make your voice heard


Older versions of Ubuntu – or more specifically, older versions of GDM – had an option to remotely log into another server using XDMCP right from the main login screen. Selecting that option brought up a host chooser which scoured your local network for any XDMCP serving hosts, and then presented you with a list from which to choose a machine to log into. On a network with several serving hosts (such as the virtual machines we have running where I work) this was far more convenient than actually having to memorise the name or IP of the machine you want to connect to.

Of the four XDMCP client options I presented in my previous post, only one provided this host chooser functionality. Unfortunately that one was to replace GDM with KDM, which also implies adding a whole load of KDE libraries to your system.

This post will tell you a couple of ways to work around the loss of the host chooser from the login screen. Neither approach is perfect, but if you don’t want to replace your GDM login with KDM or something else, then they’re about the only choice you’ve got. They’re also useful if you want to make an XDMCP connection from within a running desktop environment, using Xnest or Xephyr, as described in the previous post.

Option 1: Run gdm-host-chooser and copy the IP

You may not be able to get to the host chooser from the GDM login screen, but that doesn’t mean it’s gone away altogether. It’s still hanging around in the depths of your machine, and you can launch it by typing the following line into a terminal or the ALT-F2 “Run Application” dialogue:

/usr/lib/gdm/gdm-host-chooser

(Note that on 9.04, Jaunty Jackalope, and earlier releases, it was “/usr/lib/gdmchooser”)

The first thing to note is that it’s not as easy on the eye as the old version. Previously it was possible to provide custom icons for each host by putting images into /usr/share/hosts/ with suitable names. If no host image was found, the image at /usr/share/pixmaps/nohost.png was used by default. With Karmic Koala this latter image still exists, but isn’t displayed in the chooser. Neither are any images in the hosts icon directory.

Host choosers: Jaunty and Karmic

Host choosers: Jaunty and Karmic

In the image above you can see the Jaunty chooser on the left, complete with several default host icons, and one quickly thrown together custom icon at the bottom. On the right is the icon-less Karmic chooser, which is also much larger than the Jaunty chooser, making it too tall for many netbook screens. The image shows the smallest size that each dialogue will scale to – they can be made larger if necessary.

What’s interesting is that the Jaunty chooser shows the host name of the Karmic box in a fairly readable way (“markc-desktop.local (192.168.49.1)”) whereas the Karmic chooser shows only its IPv6 address, with no host name. What you can discern from the chooser, however, is the IP address of each of the XDMCP serving hosts on your network. With that information you can use the “-query” option to xinit, Xnest or Xephyr in order to log into the machine of your choice. If you really, really want to log into a machine by selecting it from this list, rather than copying the IP, take a look at the other options below.

Option 2: Use -indirect, with an older server

Cast your mind back through the mists of time, way back to when XDMCP was invented and dumb X terminals were connecting to Unix mainframes in universities the world over. Particularly well funded universities might even have more than one Unix server – and hence the need for a host chooser – but if the dumb X terminals had to become intelligent enough to go scouring the network for willing servers and present their own local chooser… well, that would likely push their already exorbitant prices even further skyward. So “-indirect” was born.

This option is used in place of “-query” or “-broadcast” when starting an X server. In the case of Ubuntu you might specify it when using xinit, Xnest or Xephyr, as described in the previous post. It has one parameter, the IP of a server which will serve up a host chooser. So back in our university scenario, each dumb terminal could still remain dumb, provided it knew how to connect to a single specified server. That server then took on the responsibility of displaying a host chooser to the user. Once the user selected a host, the dumb terminal would reconnect to the selected machine, and everyone was happy.

Up until Jaunty you could also use this approach with Ubuntu. If you had a Ubuntu machine on your network with a known IP or name, you could use -indirect to bring up that machine’s chooser in order to see any other XDMCP servers on your network. In a complex environment with several such servers it meant that you could get away with only remembering the address of one of them.

This still works from the client end in Karmic, but not from the server end. The changes to GDM mean that it will no longer serve up a host chooser to any wandering clients that may request one. You can, however, still get a chooser up from another machine that’s not yet been upgraded to Karmic. So if you’ve got a lot of machines to connect to it might be worth leaving at least one of them running an older version of Ubuntu for the time being, so that you can use it as the source of a host chooser with the -indirect option.

Option 3: Use gdm-host-chooser in a subshell

If you tried running gdm-host-chooser using the command above from within a terminal, you may have noticed a load of text spewed out into your command line. If you subsequently selected an entry in the host chooser and clicked the “Connect” button, you may have noticed some more text being spewed out. If you were really observant you may have noticed that, amongst the text being spewed, was the word “hostname:” followed by a space, then the name (or more probably the IP) of the machine you selected. We can use this particular bit of textual spew to our advantage.

Instead of simply executing /usr/lib/gdm/gdm-host-chooser we can pipe its output through some other command line tools so that all we get out is the selected host IP. I’ve used “grep” to isolate the line in question, and “cut” to separate out the IP, but there are many other ways to do this (feel free to post if you’ve got a better approach):

/usr/lib/gdm/gdm-host-chooser | grep "hostname:" |cut -d' ' -f2

Now if you select a server in the chooser and click the “Connect” button, you should see the IP address appear on the command line without the “hostname: ” prefix. Using this mechanism it’s possible to insert the selected IP directly into the command line when using the “-query” option to xinit, Xnest or Xephyr by putting the whole of that line into a subshell:

xinit -- :1 -once -query $(/usr/lib/gdm/gdm-host-chooser | grep "hostname:" |cut -d' ' -f2)

Xnest :1 -once -query $(/usr/lib/gdm/gdm-host-chooser | grep "hostname:" |cut -d' ' -f2)

Xephyr :1 -once -query $(/usr/lib/gdm/gdm-host-chooser | grep "hostname:" |cut -d' ' -f2)

Pick one of those lines, depending on which type of X server you want to run. They’re all a little unwieldy for day-to-day use, so you might prefer to create a small shell script containing the appropriate line. That way you can launch your chooser and X server from a single command, or even assign it to a launcher on your panel.

I should note that the performance of the host chooser on my test machine was less than stellar, taking several seconds for clicks to register, so if you do use this approach you might need to be a bit patient.

Posted in Linux, Tech. No Comments »