Ipad, Screenshots and Linux

It’s become increasingly clear over the past few months that many recent, fun-sounding films from countries with smaller film industries will never get a physical DVD release. The only way to see these films is via Amazon Prime, and since Amazon Prime isn’t conveniently available on Linux machines, I’m having to use an Ipad to watch these films.

Which is fine.

But I have to take screenshots. (I mean. I have to!) That leaves a lot of images on the Ipad, and I need a convenient way to get those from the Ipad to my Linux laptop.

Now, there’s Dropbox, and… stuff, but all those things require some manual work at the Ipad end or the Linux end. I hate manual work.

So wouldn’t it be nice if there was some way to just “do something” and then all the screenshots from the Ipad would magically appear in my Emacs on the Linux laptop?

There is!

It’s a bit fiddly, though, so let’s just get started.  (“A bit fiddly” is code for “seven pages of text is to follow”.  This is the year of Linux on the Desktop.)

My Laptop runs Ubuntu Linux, and it comes with an ifuse distribution that’s built with GnuTLS and not OpenSSL. This doesn’t work with IOS 10, so you need to build it yourself.

I’ve streamlined the build instructions a bit. The utilities and libraries needed to talk to Idevices is spread over four repositories, but the following should pull them all down, build them, and install them under /usr/local.

sudo apt-get build-dep ifuse 
for elem in libusbmuxd libimobiledevice usbmuxd ifuse; do 
  git clone https://github.com/libimobiledevice/${elem}.git 
  (cd $elem; sh ./autogen.sh; make; sudo make install) 

Check that your path is picking up the correct version by saying

$ type ifuse 
ifuse is /usr/local/bin/ifuse

Then plug in the Ipad via USB, and test that you can talk to the device. You may have to press “Trust this device” on the Ipad while connecting.

$ sudo mkdir /media/ipad 
$ sudo chown larsi.users /media/ipad 
$ idevicepair pair SUCCESS: Paired with device 37b633350ab83dc815a6a97dcd6d327b12c41968 
$ ifuse /media/ipad

You should now have the Ipad mounted, and the screenshots are under /media/ipad/DCIM.

Now for the fun part: Make the laptop copy over the files automatically whenever you plug in the Ipad.  I’m using the general setup from the usb-automount setup I did a few months ago.

The main difference is this udev.rules file:

ATTR{idVendor}="05ac", ATTR{idProduct}="12ab", PROGRAM="/bin/systemd-escape -p --template=usb-automount@.service $env{DEVNAME}", ENV{SYSTEMD_WANTS}+="%c"

And then I use the following script to actually copy over the contents to the current “viewing directory”.



if [ "$command" = "remove" ]; then
    umount /media/ipad

# Mount the Ipad.
ifuse /media/ipad

if [ -d "/media/ipad/DCIM/100APPLE" ]; then
    cd /media/ipad/DCIM/100APPLE
    for pic in IMG*; do
        if [ ! -f "$to/$pic" ]; then
            cp -av "$pic" "$to/$pic"
            chown larsi.users "$to/$pic"
            if echo "$pic" | grep PNG > /dev/null; then
                shot=`echo "$pic" | sed 's/IMG_/shot/' | sed 's/PNG/png/'`
                if [ ! -f "/home/larsi/.movie-current/$shot" ]; then
                    ln "$to/$pic" "/home/larsi/.movie-current/$shot"

cd /
umount /media/ipad

Or something like that.  You obviously have to adjust the script to your needs if you want to do something like this, but the general idea should be sound, I think…

Look!  The images appeared in Emacs!  As if by magic!

It seems to work reliably, also after rebooting the laptop.  Apparently the “idevicepair pair” think only has to be done once?  Or something?

The only minor annoyance is that Ubuntu pops up an icon in the right-hand menu every time I plug in the Ipad.  Is there any way to say to Ubuntu “ignore this device in the UI”?  There is a way to make Ubuntu ignore all auto-mounted devices, but that’s not what I want, and there is a way to make Linux ignore a specific USB device completely (echo 0 > /sys/bus/usb/devices/2-1/authorized), but that’s not what I want, either.  I just want the UI to ignore this specific device…

Oh, never mind.

[Edit: I’ve now put the scripts on github.  That should make it easier to customize if anybody wants to use this setup…]

One Thing Leads To Another

In the previous installment, I got a new monitor for my stereo computer.

I thought everything was fine, but then I started noticing stuttering on flac playback. After some investigation, it seems as if X is on (and displaying stuff on this new, bigger monitor), and there’s network traffic, then the flac123 process is starved for time slices, even if the flac123 process is running with realtime priority.


Now, my stereo machine is very, very old. As far as I can tell, it’s from 2005, and is basically a laptop mainboard strapped into a nice case:

(It’s the black thing in the middle.) But even if it’s old, its requirements hadn’t really changed since I got it: It plays music and samples music and routes music to various rooms via an RME Multiface box. So I was going to use it until it stopped working, but I obviously can’t live with stuttering music and I didn’t want to spend more time on this, so I bought a new machine from QuietPC.

There’s not a lot inside, so I put the external 12V pad into the case. Tee hee. Well, thermally that’s probably not recommended, but it doesn’t seem to be a problem.

Nice heat pipes!

Look how different the new machine is! Instead of the round, blue LED power lamp, it’s now a… while LED power lamp. And it’s about 2mm wider than the old machine, but you can’t tell unless you know and then it annoys the fuck out of you.


Anyway, installation notes: Things basically work, but Debian still haven’t fixed their installation CDs to work on machines with NVMe disks. When it fails to install grub, you have to say:

mount --bind /dev /target/dev 
mount --bind /dev/pts /target/dev/pts 
mount --bind /proc /target/proc 
mount --bind /sys /target/sys 
cp /etc/resolv.conf /target/etc 
chroot /target /bin/bash 
aptitude update a
ptitude install grub-efi-amd64 
grub-install --target=x86_64-efi /dev/nvme0n1

Fixing this should have been kinda trivial and warranted fixing, wouldn’t you think? But they haven’t, and it’s been that way for a year…

Let’s see… anything else? Oh, yeah, I had to install a kernel and X from jessie backports, because the built-in Intel graphics are too new for Debian Stale. I mean Stable. Put

deb http://ftp.uio.no/debian/ jessie-backports main contrib

into /etc/apt/sources.list and say

apt -t jessie-backports install linux-image-amd64 xserver-xorg-video-intel

although that may fail according to the phase of the moon, and I had to install linux-image-4.9.0-0.bpo.2-amd64 instead…

And the RME Multiface PCIe card said:

snd_hdsp 0000:03:00.0: Direct firmware load for multiface_firmware_rev11.bin failed with error -2

I got that to work by downloading the ALSA firmware package, compiling and installing the result as /lib/firmware/multiface_firmware_rev11.bin.

Oh, and the old machine was a 32 bit machine, so my C programs written in the late 90s had hilarious code like

(char*)((unsigned int)buf + max (write_start - block_start, 0)

that no longer happened to work (by accident) on a 64 bit machine. And these programs (used for splitting vinyl albums into individual songs and the like) are ridiculously fast now. The first time I ran it I thought there must have been a mistake, because it had split the album by the time I had released the key ordering the album to be split.

That’s the difference between a brand new NVMe disk and a first generation SSD. Man, those things were slow…

And the 3.5GHz Kaby Lake CPU probably doesn’t make things worse, either.

Vroom vroom. Now I can listen to music 10x faster than before. With the new machine, the flac files play with a more agile bassline and well-proportioned vocals, with plenty of details in a surefooted rhythmic structure: Nicely layered and fairly large in scale, but not too much authority or fascism.

Also: Gold interconnects.


I’m extremely lazy, so using a remote control to switch the TV on or off is just out of the question. The remote is just languishing in a cupboard somewhere, and the TV is always on. Which seems like a waste, since I only use it (like) a couple of days a week or something.

Most of the time it just functions as an xscreensaver-enabled display to show the sleeve of whatever album’s playing on the stereo.

But then! The other week a friend told me about something magical called “CEC”, which is apparently short for Consumer Electronics Control. It allows sending commands via HDMI (High-Definition Multimedia Interface) from your VIDEO (Visual Ideas Directed Except Oldskool) card to the TV (Television).

However, virtually no video cards support this natively. The notable exception is the graphics card in the Raspberry Pi (RPI).

Fortunately, Pulse-Eight sells CEC injectors. It a tiny thing you put in between your computer and your TV. And today it arrived:

Very small and cute.

It’s a bit more extensive with the wiring. The product page said that you can’t use it reliably if you have a very long HDMI cable to your TV, but mine is seven meters, and it seems to work fine…  Oh, perhaps I should try playing something that takes a lot of bandwidth…  Let’s see…  Captain America: Civil War Bluray…  Yup, there’s the captain.  No extra latency or anything that as far as I can tell.

There’s a USB port that you communicate over. The device shows up as a serial device in Linux, and you talk to it via a program called cec-client.

This excellent blog posts details how you use cec-client from Linux, but basically you just say

$ echo 'standby 0' | cec-client -s /dev/ttyACM0

and the TV goes to standby mode.


Mine didn’t, and it’s a five year old Samsung TV. After googling a bit more, it turns out that you have to enable this stuff under the “Anynet+” setting in the menus. Let’s just walk through this quickly, if anybody has problems finding the menu (which is something I had):

It’s way down in the main menu. Enter the “Content View” thing…

… and then choose “Anynet+”…

… and setup..

… and the thing you’re looking for is “Auto Turn Off”. If that’s on, then you can put the TV into standby mode via CEC. Makes sense, huh? HUH?!

So now all the bits are in place, and I can use this stuff. I chose to have xscreensaver wake the screen up with a -watch script modeled after this one.

So when I hit something on the TV machine keyboard, it unblanks xscreensaver and turns the TV on. (This takes an annoyingly long time, though… like 10 seconds? What’s up with TV makers and the incredible slowness involved with anything?)

To switch the TV off, I just hooked it up into my general go out/switch off everything before going to sleep actions.

Emacs is for automation.

There you go.

Obelisk: A Monitor Review

I’ve had the same monitor in my stereo control system for many years. It’s a 20″ Dell that’s OK.

It’s got an appropriate size for the living room. But lately it’s started having a high-pitched whine. If I play only punk music I can’t hear it at all, but otherwise it’s slightly annoying.

So I went looking for a new monitor. I thought it might be nice to have a rotated monitor this time: Higher than wide so that I can display the name of the currently playing artist un-sideways.

Practical as always.

So my specs here were: No logos, and no bezels wider on any sides, and as small as possible. The logo/bezel thing because inevitably that looks weird when rotated, and this is in the living room. Looking pretty is nice.

Behold! After searching for hours, there was one (1) monitor that fit the specs, and it’s this 24″ NEC EX241UN. It’s got very narrow bezels and no logos and nothing ugly. So it’s just like a matte obelisk.

But my stereo computer machine is oooold. It’s based on a 2GHz Pentium M 32-bit CPU. I think I bought it in 2005, possibly? You can see it underneath the cassette player up there… It’s in a Hush enclosure.

And it managed to connect to the screen! I wasn’t quite sure whether it was going to be able to do that, because it’s also a Pentium M motherboard and the video routing is not very well supported by Linux by default. But I managed to route the DVI signal out instead of the LVDS and VGA, and there’s … the Matrix?

Er. X isn’t quite sure….

OK, “Option rotate left” in xorg.conf instead.

Now I have to rearrange all the display data… Hm… Does that look nice?

The monitor itself is pretty nice.  Quite wide viewing angle, but when I standing there at the screen looking for something to play, I do get a slight sheen at the bottom of the screen, so it’s not perfect.  But it’s completely silent, as far as I can tell over my tinnitus.

Perhaps I should have a clock and a load monitor there. Just so that not 100% of the screen is Emacs. I don’t want to appear fanatical or anything.

Or perhaps the sleeve on top?

Hm… Perhaps I should make that font smaller. I’m nearsighted, but not actually blind.

The un-nerdiness of this setup cannot be misunderstimated.

Of course not.  Not.

Automatically Mount exfat File Systems in Linux

I do quite a bit of video on my camera, and the easiest way to transfer these rather large files to my computer is to insert the SD card into an SD card connected to my computer.

impossibleI wanted this to be as painless as possible, so I want the computer to auto mount anything inserted, without any distracting GUI stuff popping up.

The usbmount package was suggested, and it almost works. After inserting a card into the reader, it mounts it… but then three seconds later the mount point goes AWOL. If I df, I get this message:

# df
 df: ‘/media/usb1’: Transport endpoint is not connected

And it turns out that this is more complicated than you’d think, because udev and systemd.

The file system on the cards I use is exfat. exfat is a fuse (userland) file system, so usbmount ends up starting a userland process to handle the file system.

And you can’t do that from udev. It does not allow “long lived processes”: It’ll kill off everything started by an udev rule, and that includes the fuse process.

So now what?

It turns out that there is no easy way to do something as trivial as automatically mount an exfat SD card. But there’s a fiddly and yucky way, involving systemd units and other stuff that no sane person should feel necessary to know about, so I’ve created a little package for you with some files that you can just copy to the correct locations, and it’ll Just Work.

gladFor the next two weeks, until the udev/systemd brain trust fucks us all over again.

I’ve tested these files on Debian Jessie in mid July 2016, and it worked then.  Your mileage will vary.  I’ve cobbled this together by Googling for hours and mashing up various recipies that almost work.  Neither udev nor systemd are very good at reporting errors, so it’s all trial and error…

Down the Rabbit Hole


I was going to do a simple switcharoo.  The tiny firewall machine at home had shown itself to be slightly unstable.  Not egregiously, but it seems like it’ll die every four months or so.  That’s kinda annoying.

Fitlet X-Lan all wired up

So I got a new, spiffier tiny machine.  Copying over the setup from the old machine should take five minutes.  At most.  But then I started thinking.


This is what I thought: “This machine has a better CPU and graphics card than the machine I’m currently using as the music RAID/music ripping/charging headphones/scanning machine.  Perhaps I should just make this a firewall/RAID/music/charging/scanning machine and have one fewer machines at home?”

The old RAID machine

You can see where this is going.

Three six hour days later, things are kinda starting to work.

I think the base problem is that I’ve got a mixed setup of newer stuff and older, not very well supported stuff that was unusual even back then.

Here’s the lsusb output:

root@potato:~# lsusb
Bus 004 Device 004: ID 1781:0c30 Multiple Vendors Telldus TellStick
Bus 004 Device 003: ID 041e:30c4 Creative Technology, Ltd 
Bus 004 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
Bus 004 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 003 Device 004: ID 0409:005a NEC Corp. HighSpeed Hub
Bus 003 Device 003: ID 0bda:8723 Realtek Semiconductor Corp. 
Bus 003 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 005: ID 0bc2:3320 Seagate RSS LLC SRD00F2 [Expansion Desktop Drive]
Bus 002 Device 004: ID 0bc2:ab31 Seagate RSS LLC 
Bus 002 Device 003: ID 059f:106e LaCie, Ltd 
Bus 002 Device 002: ID 05e3:0612 Genesys Logic, Inc. 
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 008: ID 0eef:0001 D-WAV Scientific Co., Ltd eGalax TouchScreen
Bus 001 Device 007: ID 17e9:0288 DisplayLink 
Bus 001 Device 006: ID 0a81:0205 Chesen Electronics Corp. PS/2 Keyboard+Mouse Adapter
Bus 001 Device 005: ID 0409:005a NEC Corp. HighSpeed Hub
Bus 001 Device 004: ID 080c:0300 Datalogic S.p.A. Gryphon D120 Barcode Scanner
Bus 001 Device 003: ID 05e3:0610 Genesys Logic, Inc. 4-port hub
Bus 001 Device 002: ID 04b8:0129 Seiko Epson Corp. ES-10000G [Expression 10000XL]
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

Yeah, I know.  In addition there’s two eSATA CD-ROMs and the internal SSD.

First of all, this machine is quite picky about what USB hubs it’ll accept.  I’ve got three USB3 hard disks (that make up the /music RAID) connected via a USB3 hub, because there’s only two USB3 connectors on this machine.  With the first hub I tried, Linux was unable to detect the disks.  Unless I plugged them in one at a time.  My guess would be a power management problem.  With a different, cheap powered USB3 hub, everything works fine.

For the non-USB3 things I had a different powered hub, and when that was plugged in, the BIOS wouldn’t boot.  Fortunately there’s six USB2 sockets, so I was able to connect most of the things directly, and it seems to accept having the headphones etc connected via a cheap unpowered small hub, as seen here:

New spiffy machine

After getting all the USB power situation figured out (which took a while), I started checking the individual devices.  Most things just worked (like the USB speaker, the Epson USB scanner, the eSATA CD-ROMs, Tellstick, the Datalogic barcode scanner…), but the USB monitor (Mimo Monztor 10″) refused to switch to monitor mode.

It comes up in CD-ROM mode (with some installation software), and you’re supposed to run usb_modeswitch on it to switch it to the udlfb mode.

USB description data (for identification)
Manufacturer: DisplayLink
 Product: Monztor S10
 Serial No.: 10270020
Change configuration to 1 ...
 Device is busy, try to detach kernel driver
Looking for active driver ...
 OK, driver detached
 Device is busy, try to detach kernel driver
Looking for active driver ...
 No active driver found. Detached before or never attached
 Device is busy, try to detach kernel driver
Looking for active driver ...
 No active driver found. Detached before or never attached
 Device is busy, try to detach kernel driver

Hm.  Busy?  I guess, because the usb-storage driver claims it.  So then I thought: Could I make usb-storage not do that?  I can’t disable usb-storage, since I need that for the /music RAID, but can I make usb-storage hand it over?  Indeed I can.  This is my solution:

First, make Linux identify the “disk” by giving it a name:

root@potato:~# cat /etc/udev/rules.d/20-monztor.rules
SUBSYSTEM=="block", ATTRS{idVendor}=="17e9", ATTRS{idProduct}=="0288",
   MODE="0666", SYMLINK+="monztor"

Then I use the following script:


device=$(basename $(realpath /dev/monztor))

for file in /dev/disk/by-path/*; do
    candidate=$(basename $(realpath "$file"))
    if [ "$candidate" == "$device" ]; then
	id=$(echo "$file" | sed 's/.*usb-[^:]*://' | sed 's/-.*//')
	for uid in /sys/bus/usb/drivers/usb-storage/*; do
	    suid=$(basename $uid | sed 's/^..//')
	    if [ "$suid" == "$id" ]; then
		result=$(basename $uid)

echo $result

Then I start X this way:

root@potato:~# cat /etc/init.d/xinit

case "$1" in
start)  echo -n "Starting display"
        if true; then
	    rmmod udlfb
	    sleep 10
	    /root/find-monztor > /sys/bus/usb/drivers/usb-storage/unbind
	    sleep 2
            modprobe udlfb fb_defio=1 console=1
            sleep 5
            usb_modeswitch -v 0x17e9 -p 0x0288 -u 1
            sleep 1
            /usr/bin/X :1 -depth 16 -xf86config /etc/X11/xorg.conf.mimo -sharevts -noreset -s 0  &
        su - larsi -c "xinit -- /usr/bin/X :0 -depth 24 &"
        echo "." 

Yeah, look at all them sleeps…  This is all kinda timing sensitive, but with these very generous pauses between each action, the boot is 100% reproducible.  But it should be done in a less hacky way, of course, but whatevs.

Now, you’d think, everything is hunky dory?

What’s going on with the mouse pointer?  It just stands there, shaking…

And then it occurred to me that the Monztor monitor is a touch monitor, and perhaps it doesn’t…  really work with a modern version of Linux?  This is what xinput –list says:

⎡ Virtual core pointer                    	id=2	[master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer              	id=4	[slave  pointer  (2)]
⎜   ↳ CHESEN PS2 to USB Converter             	id=11	[slave  pointer  (2)]
⎜   ↳ eGalax Inc. USB TouchController         	id=13	[slave  pointer  (2)]
⎜   ↳ eGalax Inc. USB TouchController         	id=12	[slave  pointer  (2)]
⎣ Virtual core keyboard                   	id=3	[master keyboard (2)]
    ↳ Virtual core XTEST keyboard             	id=5	[slave  keyboard (3)]
    ↳ Power Button                            	id=6	[slave  keyboard (3)]
    ↳ Video Bus                               	id=7	[slave  keyboard (3)]
    ↳ Power Button                            	id=8	[slave  keyboard (3)]
    ↳ CHESEN PS2 to USB Converter             	id=10	[slave  keyboard (3)]
    ↳ Creative Technology Sound BlasterAxx SBX 8	id=14	[slave  keyboard (3)]
    ↳ AT Translated Set 2 keyboard            	id=15	[slave  keyboard (3)]
∼ © Datalogic 2002 Datalogic Bar Code Scanner	id=9	[floating slave]

Yup, there it is.  The eGalax thing has to be the Monztor.  So how to disable that?  The xinput command can do all sorts of things, but it’s not very user friendly.  I made the following little command that’ll output device IDs based on regexp matches:



if [ "$match" = "" ]; then
    echo "Usage: $0 "

xinput --list | grep "$match" | sed 's/.*id=\([0-9]*\).*/\1/'

And then I can say things like

# Disable input from the Mimo monitor touch screen, because it's
# buggy and shivering.
for id in `xlist eGalax.*pointer`; do
    xinput set-int-prop $id "Device Enabled" 8 0

Presto! No shaking! But then I noticed that whenever I did something on the main screen, the events were also passed to the second X server running an mplayer showing random youtube clips.
And xinput doesn’t take a –display parameter. This is how I disable that:

# Disable all pointers and keyboards on the other screen
xterm -display :1 -e \
 'for id in `xlist .`; do xinput set-int-prop $id "Device Enabled" 8 0; done'

See? SIMPLE!!!

But now the little monitor is showing the temperature and a youtube clip vaguely of the same thing that my stereo is playing.  Back to normal.

So does Linux suck?  Of course.  But I’m making it do some pretty weird stuff, and I’m kinda surprised this all works at all.  My guess is that on any other OS using this range of obscure hardware, this would have been just as awful.  Although perhaps I wouldn’t even have attempted it.

And I just had to rebuild the RAID two or three times during this process.  I mean, c’mon.

Touchy Emacs

I use Emacs as a music playing interface, and I thought it would be nice try to create a pure touch screen interface, just … because.

The only OS that would install on my old Surface Pro 2 was the prerelease version of Ubuntu 16.04, Xenial Xerus.  Apparently kernels between 2013 and a couple of weeks ago dropped support for the wifi card in the Pro 2, so, but Xerus has it.

And everything works fine.  Except the multitouch.  Apparently Unity only has support for four-digit gestures, and it’s apparently impossible to remap these gestures.  (This is what hours of googling told me.)

To make Unity stop doing this crap, you have to build your own version.  This page explains how, but I’m just going to reiterate what it says, because some things have changed slightly.

sudo apt-get build-dep unity
cd /tmp
mkdir unity
cd unity
apt-get source unity

Then edit this file:

unity-7.4.0+16.04.20151218/plugins/unityshell/src/unityshell.cpp.  Comment out this line


And then build.

cd /tmp/unity/unity-6.8.0
dpkg-buildpackage -us -uc -nc
cd ..
sudo dpkg -i *.deb
apt-get remove unity-autopilo

Then install touchegg.  You need to create mappings between gestures and the events that Emacs will respond to.

 <property name="composed_gestures_time">0</property>
 <application name="Emacs">

 <gesture type="TAP" fingers="2" direction="">
 <action type="SEND_KEYS">space</action>
 <gesture type="TAP" fingers="3" direction="">
 <action type="SEND_KEYS">p</action>
 <gesture type="DRAG" fingers="2" direction="UP">
 <action type="SEND_KEYS">Control+v</action>

 <gesture type="DRAG" fingers="2" direction="DOWN">
 <action type="SEND_KEYS">Alt+v</action>


Etc etc.  And here’s the result: A Surface Pro 2 playing in the kitchen while I’m programming on the patio:

I kinda really wanted to delve into creating a proper touch interface for Emacs, where you could define gestures as you want with a simple (local-set-key [(swipe up three-fingers]) ‘do-something), but this stuff seems like it’s way immature.  Still.  After all these years.  Or perhaps I’ve just not found the right documentation on dar webs.