2010-02-20

How to try the GDM login screen in many resolutions

This blog post explains how to try the GDM login screen and make screen shots in any, user-specified screen resolution. This can be useful when designing GDM themes. The instructions were tried on Ubuntu Hardy (8.04), but they should work on Ubuntu Intrepid (8.10) and Ubuntu Jaunty (9.04). They won't work on Ubuntu Karmic or Ubuntu Lucid, because they contain GDM 2, which doesn't have the --xnest feature implemented (** (gdmflexiserver:18758): WARNING **: Not yet implemented). Installation instructions:

  1. (When asked to run a command, run it in a terminal window.)
  2. Make sure GDM is your display manager. Since GDM is the default, chances are that it is. To make sure, run sudo dpkg-reconfigure gdm, and select GDM if it asks you.
  3. Log in using GDM if you haven't already done so. To do that, run sudo /etc/init.d/gdm restart . (You will lose your X11 session doing so.)
  4. Install Xephyr, a modern nested (embedded) X server, similar to Xnest: sudo apt-get install xserver-xephyr
  5. Install ImageMagick for making screen shots in various image file formats: sudo apt-get install imagemagick
  6. Try Xephyr: Xephyr :9 -screen 800x600 -extension RANDR . A new window should appear with the usual a black-and-white diagonal background and a diagonal cross-shaped cursor. Abort Xephyr in the terminal window. Try with different -screen sizes.
  7. Find your GDM Xnest command line by running grep ^Xnest= /etc/gdm/gdm.conf . You should see something like Xnest=/usr/share/gdm/gdmXnestWrapper -br -audit 0.
  8. Create a new xnest wrapper script:
    echo '#!/bin/sh
    GEOMETRY="`cat /tmp/new-xnest-geometry`"
    GEOMETRY="${GEOMETRY:-800x600}"
    exec Xephyr "$@" -screen "$GEOMETRY" -extension RANDR' |
    sudo tee  /usr/local/sbin/gdm-xnest &&
    chmod 755 /usr/local/sbin/gdm-xnest
  9. Create the screenshot helper script:
    echo '#! /bin/bash --
    # by pts@fazekas.hu at Sat Feb 20 11:09:20 CET 2010
    GOT=($(ps x | perl -ne '\''if (/[ ]Xephyr :/) {
      $c++;
      print"$1 $2\n" if (/[ ]Xephyr :(\d+)(?= ).* -auth (\S+)/)}
      END{die"Xephyr not found\n"if!$c;die"multiple Xephyrs found\n"if$c>1}'\''))
    test "$?" = 0 || exit "$?"
    if test ${#GOT} != 2; then
      echo "Xephyr detection failed" >&2
      exit 90
    fi
    export DISPLAY=":${GOT[0]}" XAUTHORITY="${GOT[1]}"
    exec import -window root "$@"' |
    sudo tee -a    /usr/local/bin/xephyr-import &&
    sudo chmod 755 /usr/local/bin/xephyr-import 
  10. Change the Xrandr= setting in /etc/gdm/gdm.conf to use the new wrapper script: sudo perl -pi -0777 -e 's@^Xnest=.*@Xnest=/usr/local/sbin/gdm-xnest -br -audit 0@gm' /etc/gdm/gdm.conf
  11. Make sure the Xrandr= setting is changed: check that running grep ^Xnest= /etc/gdm/gdm.conf displays Xnest=/usr/local/sbin/gdm-xnest -br -audit 0
  12. Save your work in your X11 session, and restart GDM: sudo /etc/init.d/gdm restart . (You will lose your X11 session doing so.)
Usage instructions (how to show the GDM login dialog inside a window, and how to make a screen shot):
  1. If not already logged in, login in at the GDM login screen.
  2. Run gdmflexiserver --xnest to get the GDM login dialog inside a window of your regular session. You can specify the window size using e.g. echo 1024x768 >/tmp/new-xnest-geometry && gdmflexiserver --xnest
  3. To make a JPEG screen shot, run xephyr-import -quality 75 screenshot.jpg while the Xephyr window with the GDM login screen is still open.
  4. To make a PNG screen shot, run xephyr-import screenshot.png .

2010-02-19

How to create a Debian/Ubuntu package (.deb) manually

This blog post gives some hints how to create a .deb package file (to be used with Debian, Ubuntu and similar Linux distributions). The intended audience is programmers and system administrators, both with a strong Debian or Ubuntu Linux background and strong scripting skills. It is assumed that you know almost everything about your Linux system, you have installed .deb packages by hand (with dpkg. and apt-get), you understand the dependencies etc., and the only information you need how to create a .deb package from your software.

This blog post describes a low-level, hacky and quick approach with little automatic validation and instrumentation. This approach is useful for packages which don't require compilation or complicated runtime configuration. To start learning the more consistent, heavy-weight, validated approaches, fetch some source packages with apt-get source, and have a look at their debian subdirectories. The merit of our approach is simplicity (you have to understand only a few basic concepts to create your first package) and speed. Disadvantages are that it lets you create suboptimal, nonworking or nonstandard packages since there is only very little automatic validation, so you may sometimes recognize problems with your .deb packages too late, when it's too expensive to fix them; also this approach doesn't force you learn and follow the conventions and best practices of your Linux distribution.

First, have a look at the contents of .deb packages similar to your software. To get the .deb file, use apt-get install --reinstall ${PACKAGENAME}, abort the process once all files are downloaded, and fetch the file you are interested in from /var/cache/apt/sources. Once you have the .deb file, extract it with dpkg-deb:

$ dpkg-deb -x .../${MYFILE}.deb /tmp/${MYFILE}
$ dpkg-deb -e .../${MYFILE}.deb /tmp/${MYFILE}/DEBIAN

Important text files are:

  • /tmp/${MYFILE}/DEBIAN/control: all meta-information: package name, size, version number, dependencies, short description, long description
  • /tmp/${MYFILE}/DEBIAN/md5sums: md5sum values for all regular files in the package
  • /tmp/${MYFILE}/DEBIAN/postinst: executable script which will be run by dpkg -i after dependencies are installed, and files of this package are extracted
  • /tmp/${MYFILE}/DEBIAN/preinst: a similar executable script
  • /tmp/${MYFILE}/DEBIAN/prerm: another similar executable script
  • /tmp/${MYFILE}/DEBIAN/postrm: another similar executable script

Use Google to find out more about these (and possibly other) special files. To get examples, look at the special files of the packages installed to your system; those special files are in /var/lib/dpkg/info.

Google is your friend. Search for how to build a debian package. The first two results I've found seem to be useful, I strongly recommend you read them: http://tldp.org/HOWTO/html_single/Debian-Binary-Package-Building-HOWTO/; http://www.linuxfordevices.com/c/a/Linux-For-Devices-Articles/How-to-make-deb-packages/. However, be prepared that some of the information you find is outdated or obsoleted. Always compare the instructions found on the web to what the packages of your distribution contain. Also be prepared that you don't find any definitive, comprehensive, up-to-date or useful documentation on a particular subtopic: learn from examples then.

Follow the these steps to create your .deb package:

  1. Learn everything you possible need to know, as indicated above. Learn primarily from examples (by examining some relevant packages on your Linux distribution).
  2. Create a directory named ${PACKAGENAME}_${VERSION}_${ARCHITECTURE}. We'll call this the package directory.
  3. Create subdirectories and files in the package directory. For example, if you want to have your package contain /usr/bin/footool, then create usr, create usr/bin and copy your prebuilt footool binary to usr/bin.
  4. Make sure the owner, group and permission bits are right (as intended on the target system) for all files and directories.
  5. Create the DEBIAN subdirectory in the package directory.
  6. Create your DEBIAN/control file, possibly copying a similar one, and modifying some fields.
  7. If you need to run some code during installation after the package files are extracted to /, then create DEBIAN/postinst as a script (usually starting with #! /bin/sh), and make it executable. To prevent future troubles, make this script robust and idempotent, i.e. it should exit successfully even after a previous half-finished package installation. However, if there is something wrong in the system, the script should exit with a non-zero exit code. set -e can help here: it makes the shell running the script exit at the first nonsuccessful command (outside a subshell).
  8. Compute md5sums by running md5sum `find . -type f | grep -v '^[.]/DEBIAN/'` >DEBIAN/md5sums in the package directory.
  9. Set the Installed-Size: field of the DEBIAN/control file to last number in the total output of du run in the package directory.
  10. Make sure that the package name, version number and architecture in the package directory name are the same is what's indicated in DEBIAN/control.
  11. Make sure there are no backup files (*~, especially DEBIAN/*~) or temporary files lying around inside the package directory.
  12. Go one level above the package directory, and run dpkg-deb -b ${PACKAGENAME}_${VERSION}_${ARCHITECTURE} . This creates ${PACKAGENAME}_${VERSION}_${ARCHITECTURE}.deb.
  13. Your .deb package is ready. Try installing it to your system (sudo dpkg -i ${PACKAGENAME}_${VERSION}_${ARCHITECTURE}.deb . Play with it. Fix problems and rebuild it as many times as necessary. Increase the version number.

2010-02-18

How to create a screen shot of the GDM login screen on Ubuntu Hardy

This blog pts explains how to create a screen shot of the currently running X11 GDM login screen (the graphics login screen at system startup) on Ubuntu Hardy.

  1. Install ImageMagick for the image file format conversion below:
    $ sudo apt-get install imagemagick
  2. Create a helper script:
    $ echo 'DISPLAY=:0 XAUTHORITY=/var/lib/gdm/:0.Xauth xwd -root' >/tmp/shot.sh
  3. Make sure your login screen is active (log out or reboot the machine, and wait until you see the login screen).
  4. Log in in text mode (by pressing Ctrl-Alt-F1), or using SSH.
  5. Create the screen shot by running
    $ sudo bash /tmp/shot.sh >/tmp/shot.xwd
  6. You can log in now (by pressing Ctrl-AltF7 first to get back to the GDM login screen).
  7. Convert the screen shot to JPEG and/or PNG:
    $ convert -quality 50 /tmp/shot.xwd /tmp/shot.jpg
    $ convert /tmp/shot.xwd /tmp/shot.png
  8. View the screen shot in your favourite image viewer.

2010-02-11

How to run Firefox 3.6 on Debian Etch

This blog post explains how to run Firefox 3.6 32-bit on an old Linux system, such as Debian Etch.

First, here is some technical background. The most important problem with the stock Firefox 3.6 for Linux (especially with Flash Player 10) is that it needs newer versions of system libraries than what is available on some old Linux systems, such as Debian Etch. Copying those libraries from a newer system (such as Ubuntu Hardy) does the trick, except that some other data files (such as Pango's libpango1.0-0.modules file) also have to be copied, and Linux has to be persuaded that it should read libraries and data files from non-standard locations. For the latter, setting LD_LIBRARY_PATH and specifying the new lib/ld-linux.so.2 explicitly almost solves the problem, but it won't force the new directory for the config and data files. For that, we have to LD_PRELOAD our library overriding open(), fopen() etc.

Here is how to download and prepare it:

# Exit from the firefox.
# Make sure gcc, tar, bzip2, wget and an X11 system with the GTK libraries
# (no matter how old) are installed.
$ killall firefox-bin
$ killall -9 firefox-bin
$ cd /tmp
$ wget -O pts-etch-firefox3.6.tbz2 \
  http://pts-mini-gpl.googlecode.com/files/pts-etch-firefox3.6.tbz2
$ tar xjf pts-etch-firefox3.6.tbz2
$ (cd firefox3.6; ./fakeopen.c)

Here is how to use it:

$ firefox3.6/start.sh
... (prints a lot, but eventually opens a Firefox window)

Later the directory can be moved to /usr/local, properly chmodded, and a symlink can be created, like this:

sudo ln -sf /usr/local/firefox3.6/start.sh /usr/local/bin/firefox