ICC colour management profiles with xiccd

It’s possible to apply colour management profiles (.icc files) on Linux/X11 desktops even if you don’t use Gnome or KDE, by using xiccd. Unfortunately the official documentation for xiccd is very terse.

Start by installing xiccd and ColorManager.

apt-get install xiccd colord

Start xiccd from early in ~/.xsession:

nohup /usr/bin/xiccd &

Note that xiccd takes some time to register with D-BUS.

Next I got the colord names of the display devices:

colormgr get-devices-by-kind display

The “Object Path” lines are the relevant ones here; they’ll be something like:

Object Path:   /org/freedesktop/ColorManager/devices/xrandr_xxx_me_1000

I renamed my .icc files according to the last component of the object path, e.g. “xrandr_xxx.icc” and copied my ICC files to ~/.local/share/icc. This can also be achieved with “colormgr import-profile”.

Get the Object Path of the profiles you’ve added:

colormgr get-profiles

Look for the lines like:

Object Path:   /org/freedesktop/ColorManager/profiles/icc_deadbeeff00dface0123456789abcdef_me_1000

Take the Object Paths for the device and profile to associate them together. This is persisted by colord so only needs to be done once.

colormgr device-add-profile /org/freedesktop/ColorManager/devices/xrandr_xxx_me_1000 /org/freedesktop/ColorManager/profiles/icc_deadbeeff00dface0123456789abcdef_me_1000

Additionally, the profile needs to be made default for each X session. This needs to run from ~/.xsession sometime after xiccd has had time to register devices with D-BUS. I just leave it at the end of my .xsession but you could also use a sleep or poll for the devices via colormgr get-devices.

/usr/bin/colormgr device-make-profile-default /org/freedesktop/ColorManager/devices/xrandr_xxx_me_1000 /org/freedesktop/ColorManager/profiles/icc_deadbeeff00dface0123456789abcdef_me_1000

See also: Pascal de Bruijn’s post on the subject. And if you use GNOME or KDE, use their colour management UIs instead.

Upgrading Raspbian to buster

I tried to apt-get dist-upgrade my Rasberry Pi 2 Model B to Raspbian Buster this weekend. Some things broke!

udev, journald and timesyncd crash

On startup this looks like systemd failures like “Failed to start udev Kernel Device Manager”, with errors like:

error while loading shared libraries: /usr/lib/arm-linux-gnueabihf/libarmmem.so: cannot restore segment prot after reloc: Operation not permitted

This was particularly nasty because the system fails to boot enough to start sshd, so physical access is needed to repair it.

This problem is described on stackexchange and on the Raspbian bug tracker.

libarmmem is an LD_PRELOADed library from the raspi-copies-and-fills package, containing ARM-optimized versions of memcpy, strlen, etc. The 0.11 package is incompatible with the other buster binaries, presumably due to the newer libc/toolchain.

The immediate solution is to apt-get purge raspi-copies-and-fills, but this presumably leaves you with some slow, ubiquitous libc routines. The solution to get optimized, working libraries was to build a new version of raspi-copies-and-fills with the buster toolchain. One extra layer of confusion was added because the Debian source (ala apt-get source) package corresponding to raspi-copies-and-fills_0.11 seems to be out of sync with Raspbian’s own repository, so I ended up forking my own raspi-copies-and-fills branch.

iptables is broken, nf_tables is disabled

Debian buster has deprecated iptables in favour of nftables, so /usr/sbin/iptables is by default an nftables wrapper. But the stable kernel from the raspberrypi-kernel_1.20190401-1 package doesn’t have the nf_tables kernel module, so all your iptables and nft commands will fail.

You can use /usr/sbin/iptables-legacy instead, or install a recent (4.19.50-v7+) kernel using rpi-update.

Building out-of-tree kernel modules after rpi-update

Unfortunately, rpi-update doesn’t install things in an idiomatic Debian way (there’s no .deb package, it just shoves binaries into /boot). In addition, rpi-update doesn’t install anything equivalent to raspberrypi-kernel-headers, which is required to build modules out-of-tree.

The separate rpi-source utility does automate grabbing the sources, navigating a couple of layers of indirection to find the right commits in various github repos. I ended up following this process manually to avoid inflicting 1GB of kernel sources on my Pi’s SD card just to get 25MB of headers. It involved grabbing Module7.symvers from the rpi-firmware repo, the tree from raspberrypi/linux, /proc/config.gz from the running kernel, and then finally running

make olddefconfig && make modules_prepare

Running a MacBook Pro and MacBook Air at native resolution

I wrote displaymode, a simple command line utility for changing the resolution of the main display of a macOS machine. It lets you run Retina displays at their native resolution. For a recent 15″ MacBook Pro this means 2880×1800 and for the 2018 MacBook Air Retina, 2560×1600

The repository is at https://github.com/p00ya/displaymode and you can download a binary in the releases section.

To get native resolution on the MacBook Air, run:

./displaymode t 2560 1600

and on the MacBook Pro:

./displaymode t 2880 1800

Continue reading “Running a MacBook Pro and MacBook Air at native resolution”

Making zsh history conditional on command success

So I thought it would be useful to exclude failed commands from my on-disk zsh history, while still having them available in the in-memory history until the current shell exits. This means that when you’re trying to find the one magic incantation that works of some esoteric command that you haven’t used for years, you can just search for it in your history without fear of repeating old mistakes.

From my .zshrc:


# called before a history line is saved.  See zshmisc(1).
function zshaddhistory() {
  # Prevent the command from being written to history before it's
  # executed; save it to LASTHIST instead.  Write it to history
  # in precmd.
  LASTHIST=$1
  # Return value 2: "... the history line will be saved on the internal
  # history list, but not written to the history file".
  return 2
}

# zsh hook called before the prompt is printed.  See zshmisc(1).
function precmd() {
  # Write the last command if successful, using the history buffered by
  # zshaddhistory().
  if [[ $? == 0 && -n $LASTHIST && -n $HISTFILE ]] ; then
    print -sr -- ${=${LASTHIST%%'\n'}}
  fi
}

Continue reading “Making zsh history conditional on command success”