This is mostly so I can document this stuff in case I forget it —
-
Patch for the NVIDIA 1.0-6111 driver to get it working with recent 2.6 kernels
Recent 2.6.x kernels (from 2.6.8 onward) have rapidly-changing APIs for things such as PCI access, VMM symbols and so on, which completely broke the 1.0-6111 build under anything newer than 2.6.8. This actually kept me off 2.6 for quite a while, since newer driver releases that do build against newer kernels completely or mostly break on my hardware (NFORCE 220D) — 1.0-6629 through 1.0-7167 hard lock my machine, while 1.0-7174 onward make RENDER acceleration unusable in conjunction with Composite effects. NVIDIA has recognized that ‘legacy’ hardware such as mine has issues with newer drivers, so they’ve been promising a set of drivers meant expressly for legacy hardware. These haven’t been forthcoming, though.
Fortunately, I’m not alone in my woes. Lots of folks have run into the same issues, and I have to thank some Gentoo users for preparing and linking to various patches that got the 6111 drivers working for me. I have placed a consolidated patch against the glue here.
-
How to get a set of NVIDIA drivers ready while keeping xchat going
I’ve been promising various people on-and-off to write up how to build the NVIDIA drivers without having to exit out of X11. I’m going to write this assuming you’re building against a kernel different from your running kernel; however, the same procedure can be used if this is not the case.
The first thing to do is to extract the driver components out of the installer.
[ amitg @ athena | ~ ] ./NVIDIA-Linux-x86-1.0-6111-pkg1.run --extract-only
This will leave files in a new directory called NVIDIA-Linux-x86-1.0-6111-pkg1. (This procedure is not version-specific, by the way.)
The next thing to do is to build the kernel module. So first we apply patches if needed.
[ amitg @ athena | ~ ] cd NVIDIA-Linux-x86-1.0-6111-pkg1 [ amitg @ athena | ~/NVIDIA-Linux-x86-1.0-6111-pkg1 ] bzip2 -dc ~/nvidia-glue-6111-for-2.6.13.patch.bz2 | patch -p1 patching file usr/src/nv/agp_backend.h patching file usr/src/nv/conftest.sh patching file usr/src/nv/Makefile.kbuild patching file usr/src/nv/Makefile.nvidia patching file usr/src/nv/nv.c patching file usr/src/nv/nv-linux.h patching file usr/src/nv/os-agp.c patching file usr/src/nv/os-interface.c
Next, we enter the kernel module source directory. Here are two makefiles, one meant for 2.4 kernels and one using the 2.6 kernel’s integrated kbuild system. We need to create a symbolic link called Makefile that points to the appropriate makefile:
[ amitg @ athena | ~/NVIDIA-Linux-x86-1.0-6111-pkg1 ] cd usr/src/nv [ amitg @ athena | ~/NVIDIA-Linux-x86-1.0-6111-pkg1/usr/src/nv ] ln -s Makefile.kbuild Makefile
Now we’re ready to start building the module. This is done by running, as root, or a close approximation thereof using fakeroot, the make command, with the SYSSRC variable defined to be the path to the source to your target kernel. Keep in mind that you need to use the same version of gcc as used to build your kernel. My kernels are usually built with gcc-3.3, so I use that here:
[ amitg @ athena | ~/NVIDIA-Linux-x86-1.0-6111-pkg1/usr/src/nv ] fakeroot make -f Makefile.kbuild CC=gcc-3.3 SYSSRC=/home/amitg/linux-2.6.13
I’ve used fakeroot here; if you don’t have that (for instance, if you aren’t running Debian) you can replace this with sudo or an honest-to-$DEITY root shell. This will very likely end in an error if you aren’t running as root, to the effect that it will be unable to replace nvidia.{o,ko} in the running kernel’s module directory (it attempts to do this regardless of what kernel you’re building the module for, which is one advantage of using fakeroot — your current running kernel’s modules are unaffected):
NVIDIA: left KBUILD. install: cannot remove ‘/lib/modules/2.6.13/kernel/drivers/video/nvidia.ko’: Permission denied FATAL: Could not open /lib/modules/2.6.13/modules.dep.temp for writing: Permission denied make: *** [module-install] Error 1
This is eminently ignorable. If you ran the build as root, you’ll get a different error when the build system attempts to remove the running NVIDIA driver (and fails since it’s in use by X).
At this point you can install the module by copying it to the appropriate directory.
[ amitg @ athena | ~/NVIDIA-Linux-x86-1.0-6111-pkg1/usr/src/nv ] sudo cp nvidia.ko /lib/modules/2.6.13/kernel/drivers/video [ amitg @ athena | ~/NVIDIA-Linux-x86-1.0-6111-pkg1/usr/src/nv ] chmod 644 /lib/modules/2.6.13/kernel/drivers/video/nvidia.ko
If you’re installing a new version of the NVIDIA drivers, there’s also a quick way to install the libraries after this custom module building. Go up to the toplevel directory and edit the Makefile there:
[ amitg @ athena | ~/NVIDIA-Linux-x86-1.0-6111-pkg1/usr/src/nv ] cd ../../.. [ amitg @ athena | ~/NVIDIA-Linux-x86-1.0-6111-pkg1 ] $VISUAL Makefile
Search for the instance of install against the left edge. That’s the interesting target. You’ll see that it depends on the target kernel_module_install, which you’ve just done. Comment that out with a #. Then save the file and exit the editor.
Now you just run
[ amitg @ athena | ~/NVIDIA-Linux-x86-1.0-6111-pkg1 ] sudo make install Removing all old and conflicting files! rm -f /usr/lib/libGL.* rm -f /usr/lib/libGLcore.* rm -f /usr/lib/libGLwrapper.* rm -f /usr/lib/libnvidia-tls.* rm -f /usr/lib/tls/libGL.* rm -f /usr/lib/tls/libGLcore.* rm -f /usr/lib/tls/libGLwrapper.* rm -f /usr/lib/tls/libnvidia-tls.* rm -f /usr/X11R6/lib/libGL.* rm -f /usr/X11R6/lib/libGLcore.* rm -f /usr/X11R6/lib/libXvMCNVIDIA.* rm -f /usr/X11R6/lib/libGLwrapper.* rm -f /usr/X11R6/lib/tls/libGL.* rm -f /usr/X11R6/lib/tls/libGLcore.* rm -f /usr/X11R6/lib/tls/libXvMCNVIDIA.* rm -f /usr/X11R6/lib/tls/libGLwrapper.* rm -f /usr/X11R6/lib/modules/extensions/libGLcore.* rm -f /usr/X11R6/lib/modules/extensions/libglx.* rm -f /usr/X11R6/lib/modules/extensions/libGLwrapper.* Installing new drivers install usr/lib/libGL.so.1.0.6111 /usr/lib install usr/lib/libGLcore.so.1.0.6111 /usr/lib install usr/X11R6/lib/modules/drivers/nvidia_drv.o /usr/X11R6/lib/modules/drivers install usr/X11R6/lib/modules/extensions/libglx.so.1.0.6111 /usr/X11R6/lib/modules/extensions install usr/lib/libnvidia-tls.so.1.0.6111 /usr/lib install usr/lib/tls/libnvidia-tls.so.1.0.6111 /usr/lib/tls install usr/X11R6/lib/libXvMCNVIDIA.a /usr/X11R6/lib/libXvMCNVIDIA.a install usr/X11R6/lib/libXvMCNVIDIA.so.1.0.6111 /usr/X11R6/lib/libXvMCNVIDIA.so.1.0.6111 cd /usr/lib/; ln -fs libGL.so.1.0.6111 libGL.so cd /usr/X11R6/lib/modules/extensions; ln -fs libglx.so.1.0.6111 libglx.so Installing documentation in /usr/share/doc/NVIDIA_GLX-1.0 mkdir -p /usr/share/doc/NVIDIA_GLX-1.0/include cp -r usr/include/* /usr/share/doc/NVIDIA_GLX-1.0/include cp -r usr/share/doc/* /usr/share/doc/NVIDIA_GLX-1.0 /sbin/ldconfigand you’re done.
-
The canonical Quake Console
I’ve blogged before about getting Quake Consoles set up, with both Sawfish and KDE. Well, it’s time for an update.
Sawfish
First, due to a disk crash, the previous links won’t work. You can get the Sawfish script to enable a Quake Console at the Sawfish wiki. Setting it up in Sawfish is simple — drop the script in your ~/.sawfish/lisp directory, then edit ~/.sawfishrc and add
(require 'quake-console)
Then, start up sawfish-ui and add a binding for the setting “Quake console shade toggle”. Finally, you can run a good-looking terminal with either its WM_CLASS or title being uniquely matchable. You can do this with aterm or xterm using the -name option (which sets WM_CLASS to argument<NUL>XTerm) or with konsole by setting the profile title. Look at the script beyond the whole license/disclaimer thing to see the regular expressions used to match windows. Change that to taste and you’re done.
KDE
For KDE, I’ve made the Quake Konsole toggler script more robust:
#!/bin/sh [ -x "${HOME}/.quakeconsole" ] && . "${HOME}/.quakeconsole" if [ "$(dcop konsole-${QUAKECONSOLE} konsole-mainwindow\#1 width 2>&1 | grep -c 'call failed')" = "1" ]; then WINDOW=$(xlswins | grep -m1 'QuakeConsole') [ "${WINDOW}" = "" ] && exit 1 WINDOW=$(echo ${WINDOW} | cut -f1 -d" ") [ "${WINDOW}" = "" ] && exit 1 QUAKECONSOLE=`xprop -notype -id ${WINDOW} 32c _NET_WM_PID | cut -f3 -d" "` [ "${QUAKECONSOLE}" = "" ] && exit 1 echo QUAKECONSOLE=${QUAKECONSOLE} > "${HOME}/.quakeconsole" echo WINDOW=${WINDOW} >> "${HOME}/.quakeconsole" chmod a+x "${HOME}/.quakeconsole" fi HIDDEN=$(dcop konsole-${QUAKECONSOLE} 'konsole-mainwindow#1' hidden) if [ ${HIDDEN-x} = x ]; then exit; fi if [ ${HIDDEN} = true ]; then dcop konsole-${QUAKECONSOLE} 'konsole-mainwindow#1' show sleep 0.2 wmctrl -ia ${WINDOW} else exec dcop konsole-${QUAKECONSOLE} 'konsole-mainwindow#1' hide fi
This will make the script somewhat more robust — even if you close the konsole, when you restart it, the script will look for the new instance and manipulate that instead. You can see that it has quite a few dependencies — apart from dcop (which does the heavy lifting), you have xprop (to fetch the PID of the konsole window to manipulate), xlswins (to actually find the konsole window) and wmctrl (to focus and raise the Quake Console when it’s made available). Of these, xlswins is not usually readily found in the wild; it’s available in older distributions of the X11 source — for instance, off MIT’s X11R4 project directories. You can build it using something similar to
[ amitg @ athena | ~ ] gcc -I/usr/X11R6/include -L/usr/X11R6/lib -o xlswins xlswins.c -lX11
Apart from these things, the procedure to set up the Quake Konsole under KDE is the same as before.
GNOME et al
For GNOME, Xfce, etc. that don’t have decent window managers, the Quake Console can be hacked on using the Childers-Marrett method. This involves the use of alltray, a nifty tool that can minimize any window to the system tray^W^Wnotification area. It can also do things that MetaCity cannot, such as specify a window to be drawn undecorated. We also cook up a Perl script to manipulate alltray.
The way this works is that you define a profile in gnome-terminal, say one called QuakeConsole, that causes the phrase “Quake Console” to appear in the title.


Once you’ve saved the profile, you can launch a gnome-terminal through alltray using this profile:
[ amitg @ athena | ~ ] alltray --sticky --borderless --geometry +0+0 "gnome-terminal --window-with-profile=QuakeConsole"
Note that alltray sometimes will fail with an error if you haven’t fiddled with gconf much:
Failed to read gconf file /home/amitg/.gconf/apps/metacity/general/%gconf.xml: Failed to open file ‘/home/amitg/.gconf/apps/metacity/general/%gconf.xml’: No such file or directory
In such a case, it’s easiest just to “touch” the setting it’s looking for:
[ amitg @ athena | ~ ] gconftool-2 --type string --set /apps/metacity/general/theme Simple
Starting up alltray should make the Quake Console window appear without a frame and positioned in the top-left corner, then become minimized into its systray icon. Click the icon to make it appear and then remove the menubar. Now, when you click on the icon, it toggles the appearance of the window. In order to bind this to a keystroke, some trickery is needed. This is where the Perl script comes in. First, some setup — it relies on the CPAN modules X11::Protocol, X11::GUITest and Unix::Process. Debian users will find the first one already packaged:
[ amitg @ athene | ~ ] sudo apt-get -uf install libx11-protocol-perl
X11::GUITest — what actually sends the clicks, etc. — does not seem to be packaged, and nor does Unix::Process — used to figure out which alltray instance to activate — so we can install them using the CPAN shells. (Users of distributions that don’t package the other CPAN modules can use this method too.)
Invoke the CPAN shell:
[ amitg @ athene | ~ ] sudo perl -MCPAN -e shell
Issue the command reload index, followed by install X11::GUITest and install Unix::Process. The CPAN shell will automatically download, build, test and install the CPAN modules. Alternately, under Debian, you can use dh-make-perl --build --install --cpan Unix::Process to build an installable package; however, this didn’t seem to work for X11::GUITest in my case.
Now, for the script itself:
#!/usr/bin/perl -w use strict; use vars qw($id $wpid); use X11::Protocol; use X11::GUITest qw(ClickWindow FindWindowLike GetWindowName MoveMouseAbs GetMousePos); use Unix::Process; # Constants my $TRAY = "notification-area-applet"; my $ICON = "alltray"; my $CONSOLE = "--window-with-profile=QuakeConsole"; sub GetAlltrayId { my @ids = FindWindowLike $TRAY; my @filter; my $id; die "Systray not running.\n" if ($#ids < 0); foreach $id (@ids) { @filter = FindWindowLike $ICON, $id; last if ($#filter >= 0); } return \@filter; } sub GetWindowPid { my ($proto, $id) = @_; my @atoms = $proto -> ListProperties ($id); @atoms = grep ($proto -> GetAtomName ($_) eq '_NET_WM_PID', @atoms); if ($#atoms < 0) { return -1; } my ($pid) = $proto -> GetProperty ($id, $atoms [0], 'AnyPropertyType', 0, 1, 0); ($pid) = unpack ('L', $pid); return $pid; } sub ValidateTrayId { my ($id, $wpid) = @_; my $name; return (defined ($id) && defined ($wpid) && defined ($name = GetWindowName ($id)) && $name eq "alltray" && (rindex (Unix::Process -> cmd ($wpid), $CONSOLE)) >= 0); } $id = undef; $wpid = undef; if (-f $ENV{"HOME"} . "/.quakeconsole.pl") { require ($ENV{"HOME"} . '/.quakeconsole.pl'); } if (! ValidateTrayId ($id, $wpid)) { my $proto = X11::Protocol -> new (); my $trayids = &GetAlltrayId; my $cond = 0; while ($id = shift @{$trayids}) { $wpid = GetWindowPid ($proto, $id); if (rindex (Unix::Process -> cmd ($wpid), $CONSOLE) >= 0) { $cond = 1; last; } } if (! $cond) { exit 1; } open (IDFILE, ">" . $ENV{"HOME"} . "/.quakeconsole.pl") && print IDFILE '$id = ' . "$id;\n" . '$wpid = ' . "$wpid;\n"; close IDFILE; } my @pos = &GetMousePos; ClickWindow $id; MoveMouseAbs ($pos[0], $pos[1]);
It essentially finds the appropriate alltray instance to control and sends a click to it. You can bind this to a keystroke using the Registry^WGConf. Fire up gconf-editor, navigate to /apps/metacity/keybinding_commands and set the command_1 value to the location of the script above (and don’t forget to chmod the script executable). Then navigate to /apps/metacity/global_keybindings and set the value run_command_1 to the keystroke you want to use, e.g. 1 for Win-1. And that’s it.
Note that if you get a cryptic error such as
Can't read: at /usr/share/perl5/X11/Protocol.pm line 2303
it’s possible your ~/.Xauthority is corrupt; run xauth list to see if any “illegal addresses” show up. If they do, try renaming away the file, exiting X and starting it again. Thanks to Bill for encountering the issue and discovering the cause and fix.
Enlightenment
I haven’t tried this, but Kyle has a writeup on how to do this on Enlightenment using the eesh command/scripting tool.
In other news, I might be visiting the US on business for eight weeks starting sometime next month.
OK, time for bed.