good idea

Caveat: All this refers to CVS versions of HAL and pm-utils, and thus won't work for older versions.

When you suspend or hibernate, sometimes you have to do crazy things to the video adapter.
I'm lucky with my Toshiba, I don't need any extra options, but some people will need kernel options, vbe options or dpms commands.
In the past this used to be done via per-distro or manual hacks learned from obscure websites.
For instance, FC5 hard-codes different card vendors to do different things, and this over-simplified approach actually breaks resume for my Intel card.
What is needed is fine grained white-listing of certain laptop models and video-cards based on the vendor id and product id.
Now this is great in theory, but certain laptop vendors (as opposed to video card vendors) do funny things to the hardware on the cards.
Luckily we can use the sub vendor id and the sub product id, which should be set as the laptop vendor.
This is found to be just as accurate as the dmi data, as it's practically working at that level anyway.

Recently I added the video_adapter_pm namespace into Hal which lets us specify using FDI files what a computer actually needs to do the suspend and resume.
This means that once the laptop with the oddity has been added, then other laptops of the same type will start to “just work” without the user needing to poke around in config files.
This works in a similar way to how the USB quirk system works in the kernel — someone identifies the problem, and fixes it for everyone.

Now, the observant among you may notice the methods on org.freedesktop.Hal.Device.VideoAdapterPM: SuspendVideo and ResumeVideo.
When these are called, the the hal-system-video-* scripts are called, that actually do the hacks mentioned in the spec (like using the dpms and vbetool commands).
This means that any application that wishes to resume any connected video adapter just has to find a UDI with the capability video_adapter_pm and then execute SuspendVideo and ResumeVideo on it without worrying about any details.

It just so happens, that pm-utils does exactly this!
This means that HAL is used as an abstract layer, with pm-utils driving the video suspend and resume.
It's all a happy coincidence that pm-utils itself is called by HAL during the global Suspend() and Hibernate() methods, but there's no reason these methods can't be used by other software such as powersaved.

That was the good. Now for the bad.

In order to do the right thing for the right machine we have to know the videocard vid, pid, subvid and subpid, which I'm guessing most of you don't know off by heart.
HAL to the rescue. Using this prototype script we can search for video card devices and then generate the correct XML entry for you automatically.
You answer a few easy questions:

Section 1/3 : Kernel parameters
Use S3_BIOS (y|n): n
Use S3_MODE (y|n): n

Section 2/3 : Suspend actions
Use DPMS to force the screen off (y|n): y
Use vbestate restore (y|n): n
Use vbemode restore (y|n): n

Section 2/3 : Resume actions
Set VGA text mode to mode 3 (y|n): n
Use DPMS to force the screen on (y|n): y
Use VGA vbe post (y|n): n

Okay, maybe not so easy, but if you already know you need S3_MODE and S3_BIOS manually entered on the grub command line for resume to work then you just need to say yes to these and no to the others.

So the script does its thing, and you get a nice lump of XML in your home directory:

[hughsie@hughsie-laptop docs]$ cat /home/hughsie/autogenerated_video.fdi
<?xml version=”1.0″ encoding=”ISO-8859-1″?> <!– -*- SGML -*- –>
<deviceinfo version=”0.2″>
    system.manufacturer: TOSHIBA
    system.product:      Satellite Pro A10
    bios.release_date:   09/02/2003
    bios.version:        Version 1.30
    <match key=”pci.vendor_id” int=”0x8086″> <!– Intel Corporation –>
      <match key=”pci.product_id” int=”0x3582″> <!– 82852/855GM Integrated Graphics Device –>
        <match key=”pci.subsys_vendor_id” int=”0x1179″> <!– Toshiba America Info Systems –>
          <match key=”pci.subsys_product_id” int=”0x2″> <!– Unknown (0x0002) –>
            <merge key=”video_adapter_pm.dpms_suspend” type=”bool”>true</merge>
            <merge key=”video_adapter_pm.dpms_on” type=”bool”>true</merge>
            <append key=”info.capabilities” type=”strlist”>video_adapter_pm</append>
            <append key=”info.interfaces” type=”strlist”>org.freedesktop.Hal.Device.VideoAdapterPM</append>
            <append key=”org.freedesktop.Hal.Device.VideoAdapterPM.method_names” type=”strlist”>SuspendVideo</append>
            <append key=”org.freedesktop.Hal.Device.VideoAdapterPM.method_signatures” type=”strlist”></append>
            <append key=”org.freedesktop.Hal.Device.VideoAdapterPM.method_execpaths” type=”strlist”>hal-system-video-suspend</append>
            <append key=”org.freedesktop.Hal.Device.VideoAdapterPM.method_names” type=”strlist”>ResumeVideo</append>
            <append key=”org.freedesktop.Hal.Device.VideoAdapterPM.method_signatures” type=”strlist”></append>
            <append key=”org.freedesktop.Hal.Device.VideoAdapterPM.method_execpaths” type=”strlist”>hal-system-video-resume</append>

Now, copy this file into /usr/share/hal/fdi/policy/10osvendor/ or just take the <device>…</device> information and add to 10-video-power-policy.fdi
Restart HAL, and it all should “just work”. :-)
The idea is that as people get hardware working, we can get these lumps of XML into HAL cvs so that other people don't have the same problems.
The actual utopian possibility is that hardware manufacturers actually send this info from internal testing, but I'm not holding my breath on this one.

Now, please don't send me hundreds of emails saying “this works : here's my lump of XML” as the script is not finished yet.
I'll announce it on this blog as soon as it's been tested really well, but I would appreciate if you could leave a comment if it works for you, or if you think the script needs any bugfixing or other improvements.

gnome-power-manager Inhibit and UnInhibit methods in use

Further to my earlier posts, I've been improving the documentation for the Inhibit and UnInhibit methods, and really testing them hard. There's now a testing utility, gnome-power-inhibit-test in g-p-m CVS that allows you to play with multiple Inhibits and other issues. The testing utility shows how easy it is to add the DBUS methods into your program. The same methods can be used with GNOME Screensaver (but you'll have to change the service and interface names to ScreenSaver). Trying to suspend when we have an multiple Inhibit requests gives us this. And a single inhibit:

Utopia repo moved to p.fd.o

I've moved the FC5 utopia repo to because I shouldn't really be hosting a yum repo on SourceForge webserver, and because SourceForge is so slow and broken on a daily basis.

If you've been using the utopia experimental cvs daily builds for FC5 (i386 and ppc) then you need to switch you utopia.repo file to a new location.

Code that is being built daily in a semi-automated way is hal, PolicyKit, gnome-screensaver, pm-utils, icon-naming-utils, tango-icon-theme and of course gnome-power-manager.

I can't guarantee that any of this stuff actually works, as this stuff is more bleeding than rawhide, if you can get such a thing.

If stuff breaks, as always, you get to keep both pieces.

The Inhibit() method

Okay, my last post talked about the lowest layer of power-management. To keep people interested, I'll today talk about the highest layer of gnome-power-manager i.e. the DBUS interface.

GNOME Power Manager has a complete API, that has recently been changed to be more in line with DBUS specifications and to better please the XDG guys with the more general method names. Please review and give me feedback.

If you are a developer reading this, then the most important methods to know are Inhibit() and UnInhibit(), which also exist in gnome-screensaver.

Why two identical methods on different service names?

The reason is; If you Inhibit() on org.gnome.ScreenSaver, then the screensaver will not come on (i.e. the session will not become idle) when you are doing an activity. This is obviously most suitable for visual stuff that requires the screen like playing a DVD in totem or doing a presentation in OpenOffice.

If you do an Inhibit() on org.gnome.PowerManager then the session is marked as idle, so the screensaver can go on, but the computer does not auto-suspend or power down when the mouse has not been moved for the timeout period. This is suitable for applications like bittorrent, epiphany (when downloading a big file), and nautilus (when copying a big file from a network share).

Although this seems potentially like modifying lots of programs for little gain, this all makes the software “just work” without having to manually set power profiles (which is bad) or move the mouse to special hot-spots to prevent things happening. This also removes the need for a “blacklist” of applications that inhibit suspend, as this is inherently broken.

It also lets us inform the user if they try to do silly things, like if the user clicks hibernate, and k3b is about to finish writing a DVD, we can ask the user “are you really sure, as K3B is writing a DVD…”

Aaron Whitehouse has been compiling a list of applications that need bugs filed, or should use the Inhibit() interface which I hope you guys can add to.

If you read the spec files for gnome-power-manager and gnome-screensaver you can see that they are designed to be easy to use.

Comments, as usual, appreciated.

The lowest layer : pm-utils

As promised, here's the first of five posts about how all the power management will fit together.

Today I'll discuss the lowest layer, pm-utils.

Sometimes we may need to unload modules or sync hardware times on suspend or resume or do certain things to certain hardware (for instance turning on the suspend LED on IBM hardware) and also do vendor specific things. The problem domain seems vast, but the problems are all small and simple if broken down.

There are numerous different admin scripts and side-programs invented by modern distros (such as Redhat pm-utils, Ubuntu acpi-support and SuSe Powersave) but there has not been any standardization between distros or vendors.

This is where pm-utils steps in.

The idea of pm-utils is for really simple scripts to be installed, and then for software and hardware vendors to just install a simple script in a standard location to do something insane.

For instance, vmware could install the vmware suspend script (to suspend a vmware session before we hibernate) into a standard place without having to bodge each distro setup individually. In this way, the smallest distros get the same level of compatibility and integration as the big guys like SuSe and Redhat.

The hooks are placed in /etc/pm/hooks/ and are just simple shell scripts. Scripts are processed in alphabetical order for suspend and hibernate and reverse alphabetical order for resume or thaw. This means they are really very simple to write and most importantly very easy to install.

pm-utils in CVS now looks very different than the original Fedora-only package, and is now a standard module suitable for any distro with all the autotools goodness. It was chosen over the ubuntu scripts as we were familar with the Redhat scripts, they were better structured, and Peter Jones was happy to maintain it externally. pm-utils is changing rapidly, so CVS is the only sane way to review the latest scripts.

As a bonus, pm-utils also provides pm-powersave, allowing us to use the same principle of small manager script, with multiple hooks for powersaving actions. For instance, a vendor could install a led script into /etc/pm/power.d/ so that a light could turn green on a new laptop model when in low power mode. At the moment, only a laptop-mode script is installed, but other scripts will be added with time.

Soon, pm-utils will be a hard dependency of HAL, so we can get rid of all the compatibility scripts in HAL, making everything that little bit more sane.

Hopefully distros will converge to this common solution, converting their custom scripts into sane pm-utils rules.

Email me with questions, or comments.