Sunday 18 May 2008

Calling Vala code from Python

Today I gave a try at using vala and python together in my OpenMoko mobile phone.
Python is a powerful object oriented script language, and vala is a C gobject compiler that makes it easy to generate object oriented code in C. It is quite easy to mix python and vala in a same programme, allowing us to write very quickly modular and fast applications.

So here is how it works :

Let say I have a vala module, that defines one class, with one public method. Here is the file (test.vala) :

using GLib;

namespace Test {
public class Test : Object {
public int sum(int x, int y) {
return x + y;
}
}
}

I can generate the C/gobject code for this module, using vala :

valac -C test.vala

this command will create test.c and test.h. These files are conform C and can be compiled with gcc (in fact these are the files people using gobject in C would write. If we have a look at it, we understand the pain that it is to write gobject code in C !).
But to be able to call the functions from python, we need to create wrapper to the python C interface. This can be easily done using some tools (included in the debian pygtk-dev package). For more information, see this page.

Here are the commands that generate our C python interface :

python /usr/share/pygtk/2.0/codegen/h2def.py test.h > test.defs
pygtk-codegen-2.0 -o test.override -p test test.defs > test_wrap.c

Where 'test.override' is a compulsory file that looks like this :

%%
headers
#include
#include "pygobject.h"
#include "test.h"
%%
modulename test
%%
import gobject.GObject as PyGObject_Type
%%
ignore-glob
*_get_type
%%

Alright we now have a file called test_wrap.c, that contains all the wrapper functions from the python C interface to gobject C.

The next step is to actually create the C library callable from python. this library must contains a function 'inittest' (this is the function that will be called when we import the module from python.) The file looks like this (test_module.c) :

#include

void test_register_classes (PyObject *d);
extern PyMethodDef test_functions[];

DL_EXPORT(void)
inittest(void)
{
PyObject *m, *d;
init_pygobject();
m = Py_InitModule("test", test_functions);
d = PyModule_GetDict(m);
test_register_classes(d);
if (PyErr_Occurred ()) {
Py_FatalError ("can't initialise module test");
}
}

And then we are almost done... finally we compile and link everything :

CFLAGS="`pkg-config --cflags gtk+-2.0 pygtk-2.0` -I/usr/include/python2.5/ -I."
LDFLAGS=`pkg-config --libs gtk+-2.0 pygtk-2.0`
gcc -c -o test.o test.c
gcc $CFLAGS -c test_wrap.c -o test_wrap.o
gcc $CFLAGS -c test_module.c -o test_module.o
gcc $LDFLAGS -shared test.o test_wrap.o test_module.o -o test.so

And now we finally have our library : test.so, that can be directly used from python. Here is our python script (test.py):

import test
t = test.Test()
print t.sum(2,3)

Conclusion :
This combination (python + vala) is ideal to write applications for OpenMoko : there is no need to compile the python part, and since the vala code generate C code, it can be easily compiled for different targets.
So no excuses not to write great apps for OpenMoko :)

Monday 12 May 2008

First day at OpenMoko

Today is my first working day at OpenMoko.

After I met my new coworkers - I will need some time to get used to all the new faces - I started to play with the Neo FreeRunner. So I followed the wiki instructions to flash my cell phone with the last kernel and file system image. It worked fine :-)

Of course, since I am a fan of python and gtk, the second thing I tried was to run a python / gtk / glade application. And the proof that it works with no problem :

Here is a screenshot of glade designer running on my laptop :
And here is the same interface running on the Neo FreeRunner, from a python script :

This is pretty cool. The only problem is that the menu bar looks a little bit too small for a screen touch interface.