Blog

Moving from XFree86 to X.Org

I moved a workstation from XFree86 to the X.Org server this week. The machine runs KDE all day and uses direct rendering, so my goal was not to celebrate a fork. It was to change the plumbing without making the desktop notice.

The reason for the move is now familiar. XFree86 4.4 adopted a licence clause that major free software distributors consider unacceptable or incompatible with how they combine software. X.Org X11R6.7 provides a continuation based on the earlier code and the broader development tree, under licences distributions are prepared to ship.

I let the distribution packages perform the replacement. This matters because the server is only one part of X: client libraries, fonts, loadable modules, drivers, and configuration paths must agree. Hand-installing a server over packaged files is an excellent way to create a system owned jointly by two package databases and nobody in particular.

Before upgrading, I saved the current X configuration and recorded the working video driver, horizontal and vertical monitor ranges, mouse protocol, keyboard layout, and enabled modules. I also made sure I could log in on a text console and knew how to stop the display manager.

The existing configuration required very little adjustment. Some installations use xorg.conf, while compatibility with an existing XF86Config may be provided. I prefer the new filename once the migration works; ambiguity is not a feature I need in emergency configuration.

The first test was a plain server start, followed by keyboard, mouse, resolution, and font checks. Then I tested KDE and direct rendering:

glxinfo | grep direct

That answer alone is not enough, but it quickly exposes a missing DRI module or mismatched userspace library. I also ran a 3D application and checked the X server log for modules that failed to load. A fast-looking spinning object is not a substitute for reading errors, though it is more festive.

Remote X clients and font paths deserve testing if the machine uses them. The wire protocol remains X11, but package changes can alter which font server or directories are configured. The migration should preserve capabilities, not just produce a local terminal window.

In normal use, KDE behaves exactly as it should: unexcited. Applications do not need to know whether the server came from XFree86 or X.Org. The visible result is deliberately boring.

The interesting change is organisational. Driver and extension work now has a development home tied more closely to the larger desktop community. That does not guarantee perfect engineering or rapid releases, but active collaboration is preferable to waiting behind a project boundary that many contributors had found difficult.

My advice remains to use distribution packages and retain a console escape route. This transition is technically conservative, but X sits underneath the entire graphical session. Even boring plumbing can flood the house when replaced casually.

Flicker-Free Custom Painting in Qt 3

I wrote a small Qt 3 widget that draws a graph, and it flickered whenever another window crossed it. The first version painted the background and graph directly onto the widget. The user could occasionally see the exciting interval between those operations.

The obvious cure is to draw a complete frame off-screen and copy it in one operation.

void Graph::paintEvent(QPaintEvent *event)
{
    QPixmap frame(size());
    frame.fill(colorGroup().base());

    QPainter p(&frame);
    drawGrid(&p);
    drawValues(&p);
    p.end();

    bitBlt(this, event->rect().topLeft(), &frame, event->rect());
}

The pixmap receives the background and every graph element before the screen changes, so the widget never displays a half-painted frame. For a frequently updated widget, I keep a cached pixmap and rebuild it only when the size, palette, or data changes.

Calling update() schedules a paint event and allows Qt to combine several dirty regions. Calling repaint() paints immediately. I use update() unless the application genuinely requires synchronous drawing; repeated immediate paints are an efficient way to make smooth animation less smooth.

Another option is the WNoAutoErase widget flag, which prevents Qt from erasing the background before paintEvent(). It can remove one source of flicker, but then the paint code must cover every exposed pixel. Missing one produces attractive garbage from whichever window was there before.

Double buffering costs memory proportional to the widget area, and redrawing an elaborate pixmap for every tiny exposure wastes time. Respect the event’s rectangle and cache expensive static parts.

The result is not clever: compose, then copy. That is precisely why I like it. Rendering bugs are much easier to diagnose when the screen sees only finished frames.

Letting udev Name the Devices

I have been trying udev on a Linux 2.6 test installation because I want removable devices to receive useful permissions without maintaining a giant static /dev. The project is still young, so this is an experiment rather than my new universal recipe.

The mechanism is pleasantly divided. The kernel discovers hardware and emits a hotplug event. Sysfs exposes the device and its attributes under /sys. A userspace helper uses that information and its rules to create or remove the appropriate node in /dev.

This means policy lives in userspace. The kernel does not need to decide which local group may open a scanner or what friendly name I prefer for a particular disk. It reports identity and major/minor numbers; udev applies the administrator’s rule.

For debugging, I start with sysfs rather than guessing a rule from the device node:

find /sys/class -name dev -print

The dev attribute contains the major and minor number for devices that have one. Following the device links reveals parent hardware and useful attributes. The exact early rule syntax and available helper programs are changing, so I keep rules small and check the documentation shipped with the installed version instead of copying an example for some other release.

My test sequence is equally small. I boot with a conventional device setup available as a fallback, start udev, attach one known USB device, and watch both the system log and /dev. I verify the node type, major/minor number, owner, group, and mode before opening it from an application.

Permissions are the easiest part to get subtly wrong. Creating the correct node with mode 0666 may make the test pass while giving every local user access to hardware that should be restricted. A group-based rule is usually a better policy. Convenience should not arrive disguised as an accidental security decision.

Persistent naming is the more interesting promise. Kernel names can depend on discovery order. Userspace can use stable attributes to select a consistent name for a known device. But choose attributes that are genuinely stable and unique; a generic product string shared by every unit is neither.

I like the architecture because it keeps detection in the kernel and local policy outside it. I remain cautious because early boot needs device nodes before much userspace is running, and distributions must integrate the pieces carefully. For now I am testing one class of device at a time. Dynamic /dev is useful, but a missing root disk remains impressively dynamic in the wrong direction.

Moving a Real Machine from Linux 2.4 to 2.6

I have now moved a machine I actually depend upon from Linux 2.4 to 2.6. Test boxes are excellent for discovering that a kernel boots. A working machine is better at discovering the scanner, firewall rule, and obscure filesystem one forgot to test.

The obvious approach is to install the new kernel and reboot. The correct approach begins with an inventory. I wrote down the storage controller, root filesystem, network devices, sound hardware, mounted filesystems, firewall setup, and every module not supplied by the kernel tree. If a component is required to boot or reach the network, I want its exact name before changing anything.

I then upgraded the required userspace while still running 2.4. module-init-tools understands 2.6 modules and supplies compatibility behaviour for a 2.4 boot. Recent procps tools understand newer /proc details and NPTL process presentation. Filesystem utilities must support the on-disk filesystems regardless of which kernel initiated the repair.

The important point is coexistence. I did not overwrite the old kernel image, old modules, or boot entry. My boot loader contains distinct choices, and I tested selecting 2.4 after installing the new tools. A rollback that has never been attempted is a comforting theory.

Building the first kernel

I used the 2.4 configuration as a reference, not scripture. make oldconfig carries choices forward and asks about new options, but subsystems changed between the series. I read the help for storage, input, sound, device filesystems, networking, and processor options instead of accepting every default at speed.

For the first build, the disk controller and root filesystem went directly into the kernel. This avoids depending on a new module loader and a new initial ramdisk during the same boot. Once the plain configuration worked, I made less essential drivers modular.

make oldconfig
make bzImage
make modules
make modules_install

The exact image installation is distribution and architecture dependent, so I copied it using the same procedure as the existing packaged kernel and created a separate boot-loader stanza. I also saved .config beside the image with a matching name.

Linux 2.6 uses sysfs for its device model. My startup scripts mount it at /sys:

mount -t sysfs none /sys

I kept the existing /dev arrangement for the first migration. Early udev is interesting and I intend to test it, but changing kernel, module format, device discovery, and device-node management in one reboot produces a beautiful failure with too many suspects.

The first boot is only the start

The machine reached a login prompt immediately, which proved almost nothing. I checked dmesg from beginning to end for timeouts, unknown options, and drivers claiming the wrong hardware. I mounted every local filesystem, activated swap, transferred data over each network interface, and exercised packet filtering.

Sound moved to ALSA, now part of the kernel tree. Applications using OSS interfaces can often use ALSA’s compatibility modules, but mixer state and device permissions still need checking. Silence may mean the channel is muted rather than the driver is broken, an ancient audio tradition maintained for compatibility with human suffering.

Threaded programs deserve a run under the new combination of kernel and C library. NPTL relies on facilities available in 2.6 and improves both performance and POSIX behaviour, but old monitoring scripts may interpret the changed process display incorrectly. I checked services by function rather than by expecting the old number of ps lines.

The firewall required careful review. The netfilter framework remains, but kernel configuration symbols and available matches can differ. Loading an old saved rule set is useful only if all required modules exist and the restore command reports success. A script that ignores errors can leave a machine less protected while printing reassuring startup messages.

Out-of-tree modules were the only serious obstacle. Internal kernel interfaces changed, and source written for 2.4 often needs a real port rather than a version-number adjustment. I found replacements in the 2.6 tree where possible. For the remaining hardware, I verified current source before making the migration permanent. Binary-only drivers put the schedule entirely in the vendor’s hands, which is one reason I avoid depending on them.

What changed in use

Under a compile and interactive desktop load, the machine is more responsive. The O(1) scheduler’s per-CPU run queues and priority arrays make task selection predictable as load grows. Kernel preemption, enabled on this workstation, reduces the delay before an awakened interactive task can run when another process is in preemptible kernel code.

This does not mean every benchmark is faster. Responsiveness concerns latency; throughput concerns completed work over time. I measured both and accepted a tiny difference in build time in exchange for fewer audio skips and shorter input pauses.

Sysfs is already useful for diagnosis. Following links from /sys/class to a device and its driver is clearer than assembling the relationship from several /proc files and boot messages. It also provides the structured device information that userspace managers such as udev need.

My migration rule is now simple: preserve 2.4, upgrade userspace first, boot a minimally clever 2.6 configuration, and add new mechanisms one at a time. Linux 2.6 is ready for this machine, but it did not become ready merely because uname -r printed the desired number. It became ready when every required workload passed and the old kernel remained one menu selection away.

Why XFree86 Is Being Replaced

X.Org released X11R6.7 this week, and several people have asked why distributions are considering it when XFree86 already drives their displays. The short answer is that a licensing dispute forced a technical fork to become an immediate practical choice.

XFree86 4.4 introduced a new licence clause requiring acknowledgement in advertising materials. Many free software projects and distributions consider that clause incompatible with the GNU General Public License or at least troublesome enough that they will not combine and ship the code as before. Debian and others had already objected; this is not a matter of one packager disliking a sentence’s punctuation.

The obvious response for a distribution is not to stop shipping X. X.Org’s release is based on the existing XFree86 code before the disputed licensing change, together with work from the freedesktop.org tree. It preserves the familiar X server and driver architecture while creating a place where development can continue under accepted licences.

For users, this is less dramatic than the project names suggest. KDE applications still speak X11. Existing XF86Config files are close to what the new server expects, although filenames and module paths may vary by package. Video, input, and font configuration remain recognisable.

I would test a replacement in this order:

console fallback works
server starts with the existing configuration
keyboard and mouse mappings are correct
native display resolution is available
direct rendering still works
KDE starts and restores a session

Direct rendering deserves special care because it joins the X server, a userspace library, a kernel module, and the video driver. Replacing one component can expose version mismatches that a basic desktop does not.

This split also reveals a governance problem. XFree86 had become difficult for outside developers to influence, and useful work was collecting elsewhere. A licence change was the trigger, but collaboration and release practice are part of why an alternative could form so quickly.

I dislike forks when they merely duplicate effort and rename directories. In this case the ecosystem needs a redistributable X implementation and a development home that distributions trust. X.Org is offering both while retaining the code and protocols users depend upon.

My advice is to follow the distribution rather than manually replacing a working server today. Packagers can coordinate drivers, libraries, paths, and upgrade scripts. The screen will still contain the same windows; the important change is who can maintain the machinery underneath them.