Maemo hacking diary

August 31, 2010.
Heavy duty suckage
June 10, 2010.
Maemo hardware
November 7, 2009.
Conquering open source hacks
November 1, 2009.
Introduction, SDK
November 1, 2009
Introduction, SDK

I bought an iPAQ h3765 in 2002, which I ran Familiar Linux on. It used Matchbox 0.5, X11, gtk 1.2, etc. I wrote apps for it that used gtk and that used X11 directly. It tracks a personal database, and financial spreadsheet. It has limited media playback capabilities. It has a decent book reader and a painfully obnoxious alarm clock.

It has lasted well, and it still works. But its battery is old (like half an hour), it has no memory expansion (so is useless for media playback), and there is no incentive to carry it out of the house with me.

Since buying the iPAQ, I have begun carrying around a cellphone everywhere I go. I want a cellphone PDA now. I want OpenMoko, except that the project was an abysmal failure due to poor/non-existant leadership. I want an iPhone, except that I don't want to waste my time fighting with an intentionally-closed OS. Plus I want to just write for X11 without effort, so I can port my old applications over and not be tying myself to a single ridiculous platform. I want an Android phone except, you know, it's exactly the same as iPhone....for every time Google has said the word "open" in connection with Android, there has been an instance of Google telling a blatant lie [update 2012: I was just impatient].

So here comes Maemo! It is not dissimilar from Familiar (my old iPAQ distro) brought into the 21st century. It uses debian packages and X11 and Matchbox 1.2 and GTK 2.0, etc. All of the pie-in-the-sky design documents I saw for OpenMoko roughly describe fully-fleshed out systems that actually exist in Maemo. It is great. "Soon" there will be a cellphone (Nokia N900) running this OS. But while I'm waiting for the cost of the phone and the plan to decrease, I have purchased a Nokia N810. They're like an iPAQ, except they have more of everything, have this great Linux installed at the factory, wireless, GPS, memory expansion, keyboard, and webcam. But no cellular.

I am very impressed that this device remains running in its powered down state. When it is idle (battery life of like 4-8 days), it still maintains a WiFi connection (listening for voip calls, for example).

Anyways, now I am going to document my struggles with this device. I hope that this information may prove useful to someone else who wishes to develop for Maemo.

So my first struggle is setting up an SDK for this thing. I didn't really want to run a bunch of blind scripts from Nokia that were designed to set up an SDK with Scratchbox 1. I looked for a Scratchbox 2 setup and found "Maemo SDK+" but their repository appears to have experienced an epic fail.

So here's what I did:

But I do not really use Scratchbox2, except to deal with programs with broken autoconf.

So now I'm building my GTK applications for iPAQ. I can add them to the application launcher thingy menu by creating a file /usr/share/applications/myapp.desktop:

[Desktop Entry]
Comment=my app is mine

My apps do not respond to fullscreen requests. That is a problem.

November 7, 2009
Conquering open source hacks

I want page up/page down to work in xterm. There's a way to get at the functionality using a "toolbar" but that wastes screen real estate for keys. For every other key I need, I was able to use xmodmap (see this thread for details). That was so easy, I figured it had to be capable of taking this on. Indeed, I added the following definitions:

keycode 104 = Return Escape Escape Escape Escape
keycode 111 = Up Prior
keycode 113 = Left Home
keycode 114 = Right End
keycode 116 = Down Next

So I can do Fn+D-pad center and get escape, plus I have page up/page down/home/end by holding down shift with the d-pad directions.

However, this was totally useless, as the Maemo xterm gobbles these keys and turns them into scrollbar ops! I investigated some and this is not your typical overeager xterm configuration, this is a specialized app called osso_xterm. osso_xterm is advantageous for a variety of reasons, I'm sure, and the extensions (easy font control, use of the maemo menu system, good response to fullscreen) all work so easily that I do not want to give it up. But it uses something called "VTE", which is basically a GTK widget that provides a terminal. Very slick, and so on, but it has this flaw. It hardcodes certain _useful_ keys to useless functionality. The most moronic part is it contained remappings for both Prior and KP_Prior. It could have trapped just one of them and let us bypass it but nooOO!! Well, plus at least one of the guys to hack on it was kind of a moron, but I digress (and aren't we all, at moments, anyways?). Anyways, it's open source software sooooooo...

Now, I am not good at unraveling what to do when configure fails. It didn't want to build under scratchbox2 effortlessly because it wanted some more of a gnome environment than I had provided. So be it. I threw together a Makefile and config.h manually and was eventually able to compile it in the hackiest fashion possible. Then I modified it. I fixed what I perceive to be a bug applying shift to special keys (if the key says it doesn't care about modifiers, it shouldn't care about modifiers), and I also removed these hardcoded scrollbar operations. Problem solved, osso_xterm is now totally usable.

So this is a little lesson in open source. The things I am up against are unwieldy behemoths, just as in any closed platform (such as windows) or semi-closed platform (such as OS X). But unlike OS X, my enemy is autoconf/automake, which are very easy to bypass. My enemy is a short-sighted open source hacker, and I am his equal (he grants me this right, I love him for it). And so on. Result = victory. Anyways if anyone also wants page up to work in osso_xterm,

Oh, discovery! That useless key below the "home" key is escape!

I figured out fullscreen. Apps have to handle it independently. There is a key "HILDON_HARDKEY_FULLSCREEN" (GDK_F6) that you receive KeyPress events for, and on those you can call gtk_window_fullscreen()/gtk_window_unfullscreen(). Easy enough. The wm doesn't handle it (neither does HildonWindow) because so many apps have specialized fullscreen behavior. The gtk_window_*fullscreen() functions just (I think) generate the WM events to tell the WM to do it. So it should be easy to do outside of GTK as well.

It is exactly this easy to generate outside of GTK:

static void
toggle_fullscreen(Window win)
        XClientMessageEvent xclient;

        memset (&xclient, 0, sizeof (xclient));
        xclient.type = ClientMessage;
        xclient.window = win;
        xclient.message_type = XInternAtom(ggl_x_display, "_NET_WM_STATE", 0);
        xclient.format = 32;[0] = 2;                  /* _NET_WM_STATE_TOGGLE */[1] = XInternAtom(ggl_x_display, "_NET_WM_STATE_FULLSCREEN
", 0);[2] = 0;[3] = 0;[4] = 0;

        XSendEvent (ggl_x_display, x_root_win, False,
              SubstructureRedirectMask | SubstructureNotifyMask,
              (XEvent *)&xclient);
November 8, 2009
Sound programming

I can report that ESD is very easy to use but completely undocumented!!! Anyways, it is pretty limited, it has no good way to reduce the output buffer size, so it is not very good for anything that has any real-time requirements. But it turns into a select/write loop that you would be familiar with, and only takes a single function call to initialize.

ALSA is still an undocumented inconsistent pain in the ass. If you search for ALSA documentation you are still flooded with documentation for older versions. Every API call that is in ALSA has existed in several different forms with different arguments. ALSA is documented, but barely. To perform the same work as the one-line of ESD initialization, it requried 30 lines of fairly condensed code. ALSA sucks. But it runs on the n810 and once you figure out the initialization (man is it touchy!), it is well-behaved.

ALSA mixer didn't cut it, apparently the Maemo mixer is somewhat more hidden than that. Anyways, I eventually figured it out:

$ gconftool-2 -t int -s /apps/osso/sound/master_volume 100

Controls the volume. Calling it programmatically was almost as easy. GConf has a fairly decent API!

June 10, 2010
Maemo hardware

I know this is off-topic for Maemo, because Maemo is a piece of software. But the fact of the matter is that the only reason anyone gives a shit about cellphone operating systems is that they run on cellphone hardware. In fact, the OS is usually so customized that there is a roughly one-to-one correspondence between hardware and OS. That's why it's so important that it be open from the start -- because you won't have the opportunity to replace it with an open OS later. (yeah, I know, this isn't 100% true, but it's pretty close in practice)

So the quality of the hardware that runs Maemo is very important. I have a Nokia n810. The n900 -- the modern cellphone variant of the n810 -- looks about the same and likely has similar characteristics.

The biggest problem is durability. I've dropped my n810 twice in the 8 months that I've owned it, which is far fewer times than I've dropped my cellphone in that time span. This sucker only leaves the house about once a month, it really doesn't see much abuse. Yet one of the corners of its cheap plastic casing is demolished. The slide mechanism for the keyboard is failing. The keyboard no longer slides smoothly in and out and needs to be futzed with each time to get it past a catch. It never 100% closes anymore. The keyboard-open sensor is constantly sending false alarms. In addition, the keyboard just isn't that great. The control key is nearly impossible to use for some reason. I suspect that the action of pressing the second key causes a momentary and nearly unavoidable loss of contact on the control key.

Another big problem is the lock implementation. To unlock the device requires a herculean effort focused on a small obnoxious spring-loaded switch. But sliding the keyboard out also unlocks it. Even before I dropped it, the keyboard would slide out enough in my pocket to unlock it from time to time. So here we have the worst combination: it is difficult to intentionally unlock it and easy to accidentally unlock it. Top it off with the fact that it relocks after a timeout even when the keyboard is out, a physical configuration in which it is even harder to toggle the little unlock switch.

Plus the GPS barely works (though this may be because gpsd crashes easily), it gets hot when you use the CPU (which is kind of neat just because it doesn't get hot if you don't use the CPU, but I think better could be done), and it is bigger and heavier than most of its competitors. And the battery is a little subpar when the device is in actual use (even light usage).

I cringed when I was shopping for this device because I did not want to buy a shitty piece of hardware that would fall apart in less than a year (such as one with a hinge or sliding keyboard), but I said to myself "Nokia makes millions of cellphones that survive millions of hours in millions of pockets, surely have overcome the limitations of hinges and sliders." Maybe they did, but they didn't bother with this one. It's a piece of crap unworthy of sitting in your pocket no matter how great the software may be.

Keep in mind, their chief competition in reality is the iPhone, which started out at least 10x better than the n900, and has been improving dramatically ever since.

And while I'm dishing on Nokia, let me say that Maemo is overall a disappointment too. It is awesome for me because it uses X11, and because I do not hate its UI (in fact, it is based on Matchbox which is my favorite palmtop window manager). However, the custom parts of their code (such as their task manager) are very fragile, poorly documented, and unsourced. Their source distribution is actively frustrating, as they will provide source for most of the process you are inspecting, but not all of it. And the crucial part that you need to work around or conform to -- the part you are interested in -- is always missing. In other words, it's basically the same experience as Apple's OS X. I know this road too well: I could own this thing for five years and it will still have the nuissance failings that I discovered in the first week of owning it. Major bummer! If I use a true open source system for five years then I always overcome the vast majority of its software shortcomings over time (for example my newish Lenovo IdeaPad has already had most of its kinks worked out after only 4 months).

Honestly, I find myself wishing they'd written their crap in Java simply because there are a number of decent Java decompilers out there. I can't wait until Android makes me eat those words!

August 31, 2010
Heavy duty suckage

I didn't buy this device with the intention of using it as a web browser, but I remember reading several reviews which said the user was surprised that it is the first handheld web browser they've used that is of any value.

I'm shocked by the lowness of their standards. They must be impressed that it is a semi-thorough nearly-Firefox browser which can talk Javascript and I think flash. It can (reluctantly) play youtube videos, and it can (reluctantly) view Facebook in regular (non-mobile) mode.

However, it is constantly going AWOL for seconds at a time to display even trivial content. Any browser session lasting more than a few minutes ultimately results in a crashed browser. To really kick things off, most browser crashes are unrecoverable and require you to killall -9 browserd, which is one of the few programs which will not restart cleanly without a reboot!

But the thing that really gets me is going AWOL. I recently used an Archos 5 Android tablet and was blown away that it would go AWOL for several seconds for even trivial browser interactions (I decided as a test I would get the store display model to play a youtube video and see how unpalatable it was -- but in five minutes of interaction I did not even successfully get that far!). I decided then and there I wouldn't buy a budget Android tablet, that they were mere garbage.

So I shouldn't be too surprised that Maemo is merely "no better than Android." But it's still crap.

See, the experience that pushed me over the line was using _really_ trivial web content. I have a directory of about 1000 small (1-10kB) plain text HTML files with absolutely no sophisticated aspect whatsoever (i.e., no Javascript). I remember there was a browser called "Dillo" that I ran on my old iPAQ back in 2002 that was too braindead for "real" websites but would really do a slick job on plain HTML like this. It was fast and responsive and the touch interface was actually convenient.

The first challenge comes at opening the file. It shows me the generalized Maemo file-open widget which provides you Windows-like choices of where to get the file from, but denies me access to the root directory. So I must click "Removable MMC" instead of "/media/mmc1". Even MacOS file-open dialog lets you see the root! Anyways, once I click "Removable MMC" every interaction has a two second lag, even really basic ones (like clicking something to highlight it). After a moment, the sub-heading for the directory with the 1000 small HTML files in it changes from "(0 files)" to "(1 file)". But after that, everything freezes. The little X in the corner won't kill the browser, and neither will the CANCEL button. I have to kill it from an xterm! I'm pretty sure it is doing some sort of braindead processing on each of my 1000 small HTML files for no reason except to make itself ungodly slow. Gah!

Anyways, I eventually bypass the file-open widget by typing file:/// in the URL bar. Then I discover what slow really means. When I click on a link within these files (all on the local MMC, mind you), it takes about half a second just to display the new page, even though it is a local file. Then the real shock comes in -- I try to scroll this text-only web page. It is SLOOOOOW! I mean, Windows 3.1 Netscape 4.5 slow. On a 286. As you scroll the text up and down, it is too slow to even remotely keep up so it fragments the text and doesn't finish updating all of the fragments (to present a consistent view) until a full half second after you finish dragging. It is completely unusable, and this is the most trivial text-only content I can imagine.

That was the built-in browser. So I tried Midori. Same problems! Same crappy crashing file-open dialog, same unusable scroll performance. The crapulence seems to be hardcoded in the GTK-derived widget set which is the standard GUI for this device.

So I tried lynx under the builtin X terminal. It is fast, it is snappy, it never provides a perceptible delay for any interaction within these local files. It never crashes. The only downside is it forces you to use a rather awkward keyboard interface instead of the touchscreen interface.

Someday maybe I'll get to use an iPad and I'll know if this sort of crapulence is endemic to the modern portable web or something just reserved for non-Applers.

I guess I have to figure out how to build dillo for it.