Gitorious Merge Request Monitor

In Maliit, all changes have to be reviewed by two people in order to be merged to mainline. This helps us catch issues early and keep code quality high. Since the code is hosted on Gitorious, we use their merge requests feature for that purpose. Up until now we have periodically checked the website for changes (potentially going through each and every one of the repositories), and manually mentioned updates in the IRC channel. This is both tedious and inefficient, so I wrote a simple tool to help the issue: Gitorious Merge Request Monitor

It provides an IRC Bot which gives status updates on merge requests in an IRC channel:

16:01 < mrqbot-AfFa1> desertconsulting requested merge of ~desertconsulting/maliit/desertconsultings-maliit-framework with maliit-framework in http://gitorious.org/maliit/maliit-framework/merge_requests/126
16:01 < mrqbot-AfFa1> mikhas updated http://gitorious.org/maliit/maliit-framework/merge_requests/125  State changed from Go ahead and merge to Merged

One can also query the current status from it:

15:02 < jonnor> mrqbot-7ACeB: list
15:02 < mrqbot-7ACeB> maliit-framework/127: - New - Allow QML plugins to add custom import paths for QML files and QML modules
15:02 < mrqbot-7ACeB> maliit-framework/126: - Need info - configurable importPath for qml
15:02 < mrqbot-7ACeB> maliit-plugins/26: - New - Add PluginClose from main view and add key repetition support
15:02 < mrqbot-7ACeB> maliit-plugins/25: - New - Clear active keys and magnifier on keyboard change
15:02 < mrqbot-7ACeB> maliit-plugins/24: - New - Remove QtGui dependency from libmaliit-keyboard
15:02 < mrqbot-7ACeB> maliit-plugins/23: - New - Get rid of Qt keywords
15:02 < mrqbot-7ACeB> maliit-plugins/22: - New - Add phone number and number layout getters.

Status changes are retrieved by periodically checking the Gitorious project activity feed (Atom)*, and the status itself is scraped from the website. There is no other API right now, unfortunately. Implemented in Python with Twisted, feedparser and BeautifulSoup doing all of the heavy lifting.

Get it from PyPi, using easy_install or pip:
pip install gitorious-mrq-monitor
gitorious-mrq-monitor --help # For usage information

For now this solves the immediate need for the development work-flow we have in the Maliit project. Several ideas for extending the tool are mentioned in the TODO. Contributions welcomed!

The Maliit buildbot

After having set up the typical things open source projects needs like a website/wiki, mailing-list and bug-tracker, Maliit now also has something not so common: a build-bot.

As Maliit consists of several components that can be built in several different ways (and for several different platforms), we wanted to automate the build and tests of the different variations to ensure that we do not break any of them. This is especially important for variations which are not easy to test for the individual developers, like for instance Maliit on Qt 5.

The software chosen to help with this task was Buildbot. Getting an initial instance it up and running was very quick and pain-free, especially thanks to packages being easily available and the excellent documentation. The current setup now builds, tests and installs the two major components we have: Maliit Framework and Maliit (Reference) Plugins, in the most important build/config variations we have. A total of 12 individual build jobs, plus 2 meta-builds. The configuration for the instance can be found in the maliit-buildbot-configuration repository.

For security reasons the build-bot is not directly exposed to the Internet. Instead a script runs every 5 minutes to generate a static HTML website and publish on the public web-server: Maliit build-bot

Buildbot says: All green!

This gives us a minimal continuous integration system for Maliit, which for now will hopefully helps us avoid breakage. In the future, the usage of the build-bot might extend to include:

  • Automating the release process
  • Testing of merge-requests/patches before merging to master
  • Automated integration/system testing, complementing the unit-tests
  • Triggering external builders for packaging. OpenSUSE OBS, Maemo 5 Garage, etc.
  • Automating certain aspects of bug-lifetime. Resolving when fix is committed, closing on release if pre-verified, etc

 

GTK+ application support integrated into Maliit mainline

GTK+ application support for Maliit input methods has existed for a long time, but up until now it has lived in separate repositories. This has been inconvenient for users and for developers, and was the major cause for it to not be on the same level as the Qt support. This has changed as the GTK+ support has now been merged into the maliit-framework repository, and along side the Qt support. Maliit 0.80.8, which was released yesterday, contains these changes.

Maliit running on WeTab with Fedora 15, showing QML reference plugin and GTK+ application

Two implementations existed for Maliit GTK+ support. One was written by Javis Pedro as part of a Google Summer of Code project for MeeGo in 2010. His blog has several posts on the topic. The other implementation was maintained by Raymond Liu (Intel). This is the implementation shipped in Meego Netbook, and the one improved by Claudio Saavedra (Igalia) as part of the GTK+ on MeeGo project. It was also the only one that was updated to work with the DBus connection changes that was done quite some time ago, and supporting both GTK 2 and 3. For these reasons this was the implementation integrated into mainline Maliit.

Once the code was integrated, improvements soon followed. The application now correctly reconnects to server, and make install will automatically update the GTK+ input module cache on Ubuntu, thanks to Łukasz Zemczak (Canonical), and on Fedora. This means GTK+ application support will work out of the box, no twiddling needed.

While this is a huge step in the right direction, the GTK+ support is not as good as for Qt yet. Javis Pedros implementation has features that does not exist in mainline, so code/principles can hopefully be reused from there to implement these. This includes custom toolbars and attribute extensions, and content type hints for text entries. Other features looks hard to implement due to limitations/differences in the input context plugin architecture found in GTK+, and will probably need work in GTK+ itself to solve.

Combining PySide and PyGObject introspection bindings

Some while back I added basic GObject Introspection support to GEGL and GEGL-GTK master a while back. This will* allow application developers to write their Gegl + Gtk based applications in any language supported by GObject Introspection, like Python, Vala and Javascript. For GeglQt, the Qt integration library for using Gegl in Qt based applications, it was natural to use PySide to provide Python bindings for it. The initial setup was quick and easy, thanks to the binding tutorial, but there was one challenge.

The current widgets provided by GeglQt are for displaying the output of a node in the GEGL graph. Therefore they have methods with the following signature to hook up it up:

From gegl-qt/nodeviewwidget.h
GeglNode *inputNode() const;
void setInputNode(GeglNode *node);

GeglNode is a GObject (from the C based glib) subclass, and without help the bindings generator (Shiboken) does not know what to do with it so the method cannot be bound. PySide could have been used to also generate bindings for Gegl itself, but what we actually want to do is to make use of the existing PyGObject based bindings.

Marcelo Lira on #pyside let me know that this should be possible by adding some annotations to the typesystem.xml file, and implementing a Shiboken::Converter<T>. It is indeed possible, and for the above type looks something like this:

From typesystem_gegl-qt.xml
<primitive-type name="GeglNodePtr">
      <conversion-rule file="geglnode_conversions.h"/>
      <include file-name="pygobject.h" location="global"/>
</primitive-type>

From geglnode_conversions.h
namespace Shiboken {
template<>
struct Converter<GeglNodePtr>
{
    static inline bool checkType(PyObject* pyObj)
    {
        return GEGL_IS_NODE(((PyGObject *)pyObj)->obj);
    }

    static inline bool isConvertible(PyObject* pyObj)
    {
        return GEGL_IS_NODE(((PyGObject *)pyObj)->obj);
    }

    static inline PyObject* toPython(void* cppObj)
    {
        return pygobject_new(G_OBJECT((cppObj)));
    }

    static inline PyObject* toPython(const GeglNodePtr geglNode)
    {
        return pygobject_new(G_OBJECT(geglNode));
    }

    static inline GeglNodePtr toCpp(PyObject* pyObj)
    {
        return GEGL_NODE(((PyGObject *)pyObj)->obj);
    }
};
}

The PyGObject C API and the GObject type system is here being used to implement what Shiboken needs. The attentive reader will note that GeglNodePtr is used and not GeglNode*. This is a simple “typedef GeglNode * GeglNodePtr“, which looks to be neccesary with current PySide (1.0.6) to avoid it being confused by the pointer. Hopefully that is fixable and won’t be necessary in the future.

With this solved, I committed the initial Python support to GeglQt master yesterday. It contains a trivial Python example showing the usage. Some build cleanups, binding generator tweaks and testing remains to be done, but expect Python support to be a prominent feature for GeglQt 0.1.0

 

* There are still a lot of GObject Introspection annotations missing in Gegl. See the tracking bug. Help wanted!

Making GEGL easier to use in graphical applications

So, in the last couple of months I’ve been working a bit on GEGL. Some of the work has already been covered by LWN, so I guess it is time that I blog about it…

GEGL is a generic image processing library which is used by applications like GIMP, (and in the future maybe MyPaint and DarkTable). It provides applications with a graph based image processing backend that can do non-destructive processing of high-bitdepth images, among other things.

One of the problems that I think has been limiting adaptation of GEGL has been the entry barrier to starting to use it in a graphical application. While GEGL provides the image processing backend, it did not provide good and easy ways of displaying the output on screen. Now it does!

GTK+, Clutter and Qt integration libraries

Some code for integrating GEGL in GTK+ based applications has existed in the GEGL tree for a long time, but it was not well maintained and there was no public API. After brushing up the code to use Cairo for rendering and to support both GTK+ 2 and 3, it was split out to a separate library and repository: gegl-gtk. This library now provides a GtkWidget for displaying the output of a node in the GEGL graph, with basic support for scaling and translations. Any change in the GEGL graph will be reflected in the view widget. This makes it trivial for applications using a GTK+ based user interface to get started using GEGL, see for instance the provided examples in C or in Python.

The same functionality is provided for Clutter based user interfaces by gegl-clutter in form of a ClutterActor. This code was previously available as clutter-gegl, but has now been renamed and moved to be a part of the GEGL project, and is maintained by Øyvind Kolsås. Example code in C.

Last but not least, gegl-qt was created to serve the needs of applications using Qt based user interfaces. The different widget systems (QWidget-, QGraphicsWidget- and QML-based) are all supported. In addition to the features currently available in the GTK+ and Clutter versions, the Qt view widgets also support auto-scaling and auto-centering. Python bindings via PySide is planned, but blocking on a PySide issue at the moment.

A pretty boring screenshot showing two QWidget based examples (code: 1, 2) for transformations:

Artwork: “Wanted“, speedpainting by David Revoy

The first stable release of gegl-qt and gegl-gtk will hopefully be available soon. The list of tasks can be found in the README files.

Display operations

In GEGL, image processing is described as a graph of operations. “gegl:display” and “gegl:gtk-display” operations existed in the gegl tree, and by attaching one of these to a node in the graph one could display the output of the graph at the given node in a window . Such display operations are useful for applications that just want to show the output of a graph without having to use a GUI library directly.

The problem was that both of these operations were optional, so applications could not rely on this functionality to be present. This is solved by letting the “gegl:display” operation be a meta-operation, which uses other operations as a handler to actually display the output. Such display handler operations are now provided by gegl (optional, using SDL), gegl-gtk (using GTK+) and gegl-qt (using Qt). In addition a fallback operation that will export a PNG file and launch an external application to display it will be provided in GEGL.

More to GEGL stuff to come soon, hopefully.

Registration open for Workshops & BoFs at the DesktopSummit 2011

As a member of the local organizing team for the Desktop Summit 2011 in Berlin, I’m glad to say that you can now register your workshop or BoF session. These sessions take place during the last 3 days of the conference, and complement the presentations that take place during the 3 first days: The Workshops & BoFs sessions are hands-on sessions where people get together to discuss and work on issues face to face.

Short excerpt from the news entry on the webpage:

All forms of hands-on activities that aim to further the Free Desktop are welcomed. Examples of such sessions include BoF, project and cross-project meetings, workshops, hacking sessions and training/teaching sessions. Each session is self-organized and it is up to the hosts and participants to decide if the session is to be loosely oriented around a set of topics, or have a well-defined agenda.

The organisation committee would like to schedule as many of these sessions beforehand as possible. We expect over 1000 visitors and scheduling helps to ensure minimal overlap with other sessions and allows us to provide a clear timetable for the visitors.
The remainder of the rooms will be scheduled via the wiki but we urge you to pre-register and get a proposal in before the deadline, July 3rd!

I will be proposing a session or two of my own very soon, I suggest you do the same! Use this link

MyPaint and OpenRaster talks

One of my goals for this year was to give a presentation at a conference. And I can now say that I have achieved that goal.

I gave a talk about MyPaint at Libre Graphics Meeting 2011 in Montreal, Canada: MyPaint – the past, the present and the future.

[hdplay id=1]

Download in Ogg/Theora

I will also be giving a lighting talk at the DesktopSummit in Berlin about OpenRaster. It looks like this will be on August 7th at 14.00, but you should of course come for the whole week. Just look at the awesome program!

 

Example plugins for Maliit available

In Maliit input methods are implemented as plugins. This flexibility is important because it allows the same framework to provide very different text input methods, without us having to implement them all. Different virtual keyboards, hardware keyboard input, handwriting, speech-to-text, input methods for accessibility, et.c. are all possible with the Maliit framework. This makes the input method plugin API the most important extension point.

To make it simple to start developing an input method for Maliit, we have written a set of example plugins that can be used as a skeleton* for a new input method. There is one “Hello World” example showing the C++ interface, and one showing the newly added QML interface. The latest documentation for the framework in HTML format is also included, along with a simple test application. How to get started is documented on our wiki page: Go!

A very conventional example: An input method that allows you to input "Hello World"

A nice thing is that these examples are in our framework repository: built as part of the standard build, with simple tests run as part of our test-suite. This ensures that the examples stay up-to-date and working, something I find that step-by-step, code-and-talk tutorials in some documentation repository/directory typically do not.

If you want to look at real-life examples of plugins, check out the Meego Keyboard code (C++), the Meego Keyboard Quick code (QML), or foolegg from maemo.org’s cute-input-method code (QML with Pinjyin support!). Also make sure to check out Michael Hasselmanns talk at the Meego Spring 2011 Conference: Developing custom input methods for Meego.

If you hit any issues, contact us through one of our communication channels.

* Note that currently the license of the examples is LGPLv2 like the rest of the framework.

geglfilter: GStreamer element for manipulating video using Gegl

Gegl is an image processing framework used in projects like Gimp and DarkTable. It will eventually allow Gimp to allow non-destructive, high bit-depth image processing, among other things. And GStreamer is the multimedia framework for GNU/Linux, handling video/audio/other playback/recording/manipulation on your favorite desktop/server/mobile/embedded system.

After writing the Cairo overlay GStreamer element, I implement a basic GStreamer element which allows you to apply a filter to video in a GStreamer pipeline using Gegl. Using this element, video editing/manipulation applications like Pitivi could allow users to apply effects provided by Gegl to videos. Gegl is a very powerful image processing framework, and already has a significant number of image processing operations. More operations is expected, especially from the port the tools, filters and plugins used in Gimp to Gegl.

Here are some screenshots showing the standard GStreamer video test data being manipulated in different ways using Gegl. Note: the size of the images are only different because the output windows had different sizes when I took the screenshot.

Top left: original video. Top right: color temperature adjusted from 6500 to 9000 K Bottom left: inverted colors. Bottom right: inverted colors and black-white threshold

Top left: original video (no-op). Top right: color temperature adjusted from 6500 to 9000K. Bottom left: inverted colors. Bottom right: inverted colors and black-white threshold conversion

A bug has been filed for inclusion of this element into gst-plugins-good. The patch attached there also contains an example application, showing how to use the element.

In the patches you will find an example.