vendredi 17 juin 2011

Spicy apples

It has been a few months since I've been hired by Red Hat to hack on Spice, and I realized I haven't blogged as much as I should have :)

Introduction

First, let me introduce Spice quickly. Spice is a protocol which then gets implemented in clients such as Vinagre (using the spice-gtk widget) and in servers (QEMU or the experimental X11 driver). Using this protocol, the video, sound, keyboard, mouse inputs and ouputs can be abstracted away from a virtual machine. This means you can run a Spice client application on one box to get the display of a QEMU virtual machine running on another box. Or you can have a big server running dozens of virtual machines, and connect to the VM you're interested in from your laptop. Or you use it in a VDI setup where you'll have N different PCs connecting to a single server running N virtual machines.

One of the thing I've done during these few months at Red Hat is to look into building a Mac client for Spice. Indeed, so far we have a linux client (as well as a GTK widget if you want to embed Spice in your applications, a Windows client, but nothing on Mac OS X. Since I was the only one in the team with a functional OS X install, I was volunteered to look into this port ;)

The long way toward Vinagre on OS X

I started by building the gtk+ OS X port. Using these build instructions, it was quite straightforward even though it took some time since there were a few bugs to fix here and there in the stack. Then I realized I needed gtk3 and that I had only built gtk2, so I started again, and fixed some more bugs (the glib maintainers really didn't want me to succeed :-) )

Once I had gtk-demo running, it was time to start thinking about my real goal, getting spice-gtk and vinagre to compile. Luckily, I had made a jhbuild moduleset for these, which I could reuse (after adapting it) for the OS X build since gtk-osx is using jhbuild too. This way, I could focus on the real porting work. The easy bits were tweaking spice-gtk build options to use gstreamer instead of pulse-audio, gthreads instead of coroutines, ... And then I finally had to do some actual porting work ;) This ranged from small fixes due to OS X BSD roots, or to older libraries on OS X, to new code to write because there was some linux/Windows specific code to handle screen detection/resolution changes. And after that, lo and behold, I could connect to my remote VM from my Mac!

Then, with the help of Marc-André, I could tackle Vinagre. This mainly meant making some Vinagre dependencies optional (namely gtk-vnc, gnome-keyring and GtkApplication) because I didn't want to compile/use dbus. After some confusion because of a regression in glib causing Vinagre to crash on startup, I was really thrilled to connect to finally connect to a virtual machine running on my work laptop from my Mac OS X laptop!

While this was great, things were far from being over :) In order for this work to be usable by other people, I had to build an application bundle, this basically means making Vinagre relocatable at runtime. Thanksfully, the work from the people porting gtk+ to OS X came to the rescue once again! They provide an ige-mac-bundler to help generate application bundles for gtk+ applications. I had to tweak it since it's not fully ready for gtk3 yet, and to figure out how to get it to change the location of libpeas plugins, typelibs, pango modules, gdk-pixbuf modules at runtime. The good new is that all these modules provide handy environment variables which help with that (PEAS_PLUGIN_LOADERS_DIR, GI_TYPELIB_PATH, PANGO_SYSCONFDIR and GDK_PIXBUF_MODULE_FILE), but it took quite a bit of trial and error to figure out all of these :) Last but not least, I wrote a few patches for Vinagre to add similar environment variables to locate its data files.

The reward

And here is the final result (disclaimer: it's still a work in progress) :

As you can see in the video above (bigger ogg version here), it's already working pretty well, you can connect to a VM, go fullscreen, sound is working, ... But as always, there are still some improvements to be done...
The most important one is to upstream the various changes I had to make in Vinagre, spice-gtk and ige-mac-bundler. For spice-gtk, this is mostly done, for Vinagre and ige-mac-bundler, I have to clean up the changes first. I also have to make building Vinagre on OS X much easier And then, there is more work to do to polish the OS X integration, like looking at GtkOSXApplication to get the usual OS X top menu bar, finding a better looking theme, having a native GtkApplication backend, and developing native OS X code for things like monitor detection/resolution changes/... (which is currently not implemented/not working). And obviously, it also needs lots of testing :)

All in all, I'm pleased with the result so far, it's a really good basis for a rocking Spice OS X client! Any takers for working on an iOS Spice client next ?

There is some work on a spice android client at http://code.google.com/p/spice-client-android/A few changes are needed for now to account for unaligned memory accesses, to use the android framework, ...

Very nice effort. Performance seems to be lacking considerably from the Windows client though (on snow leopard). Updated to Lion yesterday and it sems to be broken on Lion (some libiconv error).What would be really great would be to embed this inside an NSView component to be able to use in a Cocoa application, don't know how much work that would take though...Any update on getting these changes in the main git repositories - would be great if you could push this in the meantime on to some public repo like github so we could play with the code :-)

@masc: I think this is a known issue in gtk-osx and is being discussed on their mailing list, http://sourceforge.net/mailarchive/forum.php?thread_name=BF13A130-7A29-4FF9-B1A4-7824036778DF%40ceridwen.us&forum_name=gtk-osx-devs might be relevant.This means the package will need to get rebuilt...

@Tryggvi LarussonFor your question on making the changes publically available, I thinkI merged all of them to spice-gtk, any uncommitted stuff would be inhttps://gitorious.org/~teuf/spice-gtk/teuf-spice-gtk/commits/osxVinagre needed one patch that wasn't merged, it can be found athttps://gitorious.org/~teuf/vinagre/vinagre-teuf/commit/23b296a40572fbc525dc24a3334f8b80e7c696a0And the moduleset I used for the builds ishttp://cgit.freedesktop.org/~teuf/spice-jhbuild/log/?h=osx

Last but not least, spice-gtk is divided in 2 parts, a glib part handlingall the low-level network interaction with a spiced VM, which sends drawinginformation to a separate gtk part which handles the drawing. So maybereusing this glib part, but doing drawing and event handling usingcocoa/core graphics/... wouldn't be too hard. I don't know much about osxdevelopment, so maybe this is just wishful thinking :)