Ever since the N900 was announced, I’ve had people ask me whether it’s difficult, or in some cases even possible, to write apps for it. Well, it is possible, and it’s pretty easy: let’s write a simple app together and you’ll see. We’ll make a basic client for the social bookmarking site reddit, and I’ll call it ræddit, because I have no imagination.
First, a bit of handwaving. I’m not here to teach you C, or Glib programming, or GTK programming. There are plenty of good tutorials about those already, and I’ll assume you know a bit about them. In keeping with this, we won’t be writing the client’s back end; we’ll just assume that there’s a Glib-friendly client library for reddit already in existence. Oh, look, a handy Glib-friendly client library just conveniently sprang into existence for us: source, headers.
Learn to love Scratchbox. If you’re doing any development for the N900, you’ll run into a cross-compiler toolkit called scratchbox. It’s packaged in most major distros, so install it before you go any further. There are two reasons you’d use scratchbox:
- In case you don’t have an N900 handy, you can run an entire Maemo environment inside scratchbox. But we’ll assume you have an N900 lying around, because otherwise we’d have to explain how to set up the desktop environment inside scratchbox, and that would be a bit of a diversion. (On the other hand, this would be a good subject for a future post in this series.)
- You can also use scratchbox just for running a compiler, in order to make binaries. This is what we’ll do.
My First Compile. So first of all, let’s not bother with any of the graphical stuff, or with packaging. Let’s just write a program that dumps the contents of reddit’s front page out to standard output, and then let’s run it on your phone. Here’s a pretty minimal program to do that: raeddit-01.c. Put that in your scratchbox, along with the reddit client library linked to above, and at the scratchbox prompt type:
apt-get install libcurl3-dev libjson-glib-dev
gcc `pkg-config --cflags --libs glib-2.0 hildon-1 json-glib-1.0 libcurl dbus-glib-1` raeddit-01.c greddit.c -o raeddit-01
There are some extra libraries listed in the pkg-config statement which we’ll be needing later.
Caveat: You may currently find a difficulty getting the correct packages installed to compile against json-glib; as of the time of writing there was a version dependency problem in the Maemo repository between libjson-glib-dev and libjson-glib-1.0-0. I solved it in a rather ugly way by downloading the package directly and doing dpkg -i --force-depends libjson-glib-dev_0.6.2-5_armel.deb. Your mileage may vary. I hope they’ve fixed this by the time you read this. If not, you know what to do.
So anyway, you should now have a binary called raeddit-01.
Now, either find out your trusty N900’s wifi IP address, or hook it up via USB, in which case its IP address is 192.168.2.15. Give the command
scp raeddit-01 root@192.168.2.15:
(The default root password is well-known.) Your binary is now on the phone in the directory /root. Make sure the phone is connected to the Internet, fire up a terminal on the device, and type
/root/raeddit-01
If you see the current contents of reddit’s front page printed out on the terminal, you’re doing fine:
First steps into Hildon. So, now we have a very basic reddit client. Let’s think about making it pretty.
What we want is a series of buttons going down the page that look something like this:
Eventually we’ll need to make a custom widget for that, but fortunately there’s a standard Maemo widget called a HildonButton which holds two labels, a title and an optional subtitle, which is close enough to what we want for a basic tutorial. It looks like this:
We can just stick a bunch of these into a GtkVBox. But we also want the user to be able to flick through them with her finger, and there’s a specialised Maemo container widget to allow that: it’s called HildonPannableArea. So the GtkVBox will live inside one of those.
So here’s raeddit-02.c (diff to raeddit-01.c), which knows how to put up a window and fill it with buttons. The buttons don’t go anywhere, but at least we’re getting somewhere! Compile it, transfer it to the phone, and run it again:
Making the buttons into links. So next we need to make the buttons go to the various sites. Now, there’s two important things you have to consider when porting or building an app on the N900. One of them, which we’ve just mentioned, is that sometimes there are widgets which don’t exist on the desktop, because they work in ways which are better adapted to life on a phone. The other is that there’s a whole ecosystem of programs on the device with which we must play nicely. One such program is the web browser, and right now that’s exactly the program we need to talk to.
The polite way to ask the browser to show a particular page is by using a DBus call. Here’s raeddit-03.c (diff to raeddit-02.c), which knows how to do that. Compile it, transfer it to the phone, and run it again. I would show you a screenshot, but it looks just the same as the last version. And it works.
And now we have a first approximation to the program we wanted, which is at least good enough to call version 0.01!
Where can this go next?
- The program needs to live in a package, so that it can be installed easily, so that it can have a little icon in the launch menu, and so that it can be uploaded to maemo-extras and perhaps one day to Maemo Select. We’ll be looking at that next time.
- There are lots of things you might want to do with a post on reddit, beyond just viewing the site it links to. So rather than the buttons going directly to the sites, it would be better if they popped up one of those rather stylish menus saying things like “Go to site”, “Go to comments page”, “Vote up”, “Vote down”, and so on. (That kind of menu is called a HildonTouchSelector). We’ll do that the time after next.
- Clearly the page should refresh every so often.
- The download should really be done asynchronously.
- The buttons should really be custom widgets that look more like our mockup.
- Many posts on reddit consist only of a picture, and launching the browser for these is probably overkill. We could do these in-process with a GdkPixbuf. This should be another option on the popup menu, “View image”, so that people still had the option of using the browser.
- Also for picture posts, we could display them inline in the custom widgets, as is done on the website.
- Of course, it would be lovely if you could use the client to log in, and vote posts up or down.
- Also, the ability to post links would be pretty useful.
- There should be an app menu with some useful buttons on it.
- The client should support subreddits.
- It would be extra fun to have this as a home applet rather than an app.
- There should be a way to sort posts by newness, hotness, and so on. (Yes, I noticed after I wrote it that the current version sorts posts backwards.)
- It should be possible to hide posts you’ve already seen.
- There should be a “share” button, to share posts you like with other people by email or twitter/identica, and so on.
- It would be a nice touch if there were gestures to access the most common options on the popup menu (slide your finger from left to right across a post to open the associated link, and so on.)
- I can imagine adding a new addressbook field called “reddit username”, and being able to single-tap open a contact’s reddit user page from their contact information.
- The iPhone app has a thing where it goes to a random page if you shake it. We could do that…
- …your idea here…
Let me know where you’d like this series to go in future. I’m speaking only as a fascinated individual here, and I’d also welcome any corrections you have, as well as any questions about things I left unclear. If this whets your appetite, you can find out a lot more detail in the official developer guide, or the official porting guide.
thanks for using json-glib :-)
btw, some of the complexity of getting the node/getting the value has been reduced in the 0.7 development cycle. and I’d love to add GIO stream support to the parser…
Hey, thank for your post !!!. It will be great more of this on the future :)
Great Stuff! I just installed scratchbox yesterday and started playing with it. I can’t wait until the n900 is released in the US!
“The default password is well-known”? wtf?
Connect to WiFi and you get root’ed? Surely it can’t be /that/ easy?
But will you not end up throwing out the code for the next Qt-based Maemo?
Faidon: previous Nokia Internet Tablets came without an SSH server preinstalled, so remote rooting is not possible. And when you install the openssh-server package, the installer asks you to change the root password to something only you’ll know. I’m pretty sure this will continue to be the case with the N900 as well.
Thank you. I’m using an osso_rpc_run() statement from Diablo to launch the browser and I have no idea if it still works because the SDK lacks the browser. Thanks to your diff for adding the load-link-in-browser functionality, I can correct this.
@anon: No, the next Maemo will still support GTK apps just fine. (They’re switching to Qt as the primary toolkit going forward, but they’re not going to break all the existing apps.)
What about other programing languages? How will PyGTK work on the device for example? Is it in the default install or would you have to include that with your app?
I uploaded a new version of json-glib some days ago. Seems the problem is gone. If you still expect problems, please contact me.
http://maemo.org/packages/package_instance/view/fremantle_extras-devel_free_armel/libjson-glib-dev/0.6.2-6/
Cheers!
Conny
“it’s pretty easy”: “we won’t be writing the client’s back end; we’ll just assume that there’s a Glib-friendly client library for reddit already in existence. Oh, look, a handy Glib-friendly client library just conveniently sprang into existence for us…”
I’d say it’s pretty magic really.
May the Magic Marketing Force be with you! :)
can get it to work… doing an ls in my cross-compilation directory i get this:
greddit.c libjson-glib-dev_0.6.2-7_armel.deb
greddit.h libjson-glib-dev_0.8.0-1_armel.deb
libjson-glib-dev_0.6.2-5_armel.deb raeddit-01.c
if i try to install doing apt-get install libcurl3-dev libjson-glib-dev says everyting it’s already installed (in my cross-compilation directory) however among the 100+ errors i get trying to compile it the following are in my opinion the most relevant….
Package glib-2.0 was not found in the pkg-config search path.
Perhaps you should add the directory containing `glib-2.0.pc’
to the PKG_CONFIG_PATH environment variable
No package ‘glib-2.0′ found
Package hildon-1 was not found in the pkg-config search path.
Perhaps you should add the directory containing `hildon-1.pc’
to the PKG_CONFIG_PATH environment variable
No package ‘hildon-1′ found
Package json-glib-1.0 was not found in the pkg-config search path.
Perhaps you should add the directory containing `json-glib-1.0.pc’
to the PKG_CONFIG_PATH environment variable
No package ‘json-glib-1.0′ found
Package libcurl was not found in the pkg-config search path.
Perhaps you should add the directory containing `libcurl.pc’
to the PKG_CONFIG_PATH environment variable
No package ‘libcurl’ found
raeddit-01.c:8:21: gtk/gtk.h: No such file or directory
Thanks for the help
*can’t get it to work