Development Guides: Simple Applications
Developing a Basic Marquee Plug-in
Sample Code

What is a Marquee?
The marquee is the top panel on the Hildon desktop and it may contain multiple components (plug-ins), including buttons to navigate, and system status indicators.


Figure 1-1: The marquee and status bar.

The status bar contains four buttons: the battery status, brightness, volume, and soft keyboard control, which are all implemented as status bar plug-ins. The other plug-ins are the Home Button, Application Menu, Clock, Network Status, and Close Button. They are implemented as marquee plug-ins. The empty space, between the soft keyboard control button and the close button, belongs to the status bar and can accommodate one extra status bar plug-in. This is where we will later place our new status bar plug-in.

Developing a Marquee Plug-in

To develop a plug-in for the marquee, you should first familiarize yourself with "Developing a Basic C/C++ Hildon Application".

To create a plug-in for the marquee panel, there are a few things that you must do:

  1. Modify the marquee.conf system file to add your new plug-in.
  2. Create the autogen.sh, configure.ac, and Makefile.am package to automate plug-in compiling and the installation process. This will save you a lot of time in development.
  3. Create a desktop file for your new plug-in.
  4. Create C/C++ code for your new plug-in.
  5. Compile, install, and test your new plug-in.

This guide will start by creating a simple marquee plug-in that displays GtkVolumeButton, a button which pops up a volume control. The plug-in will try to close an active app (if any) if you slide the volume control below the center line.

Our "Hello Marquee" Plug-in

If you wish, you can download our hello-marquee plug-in sample, compile it, and see how it works. To learn how to build it step-by-step, you can skip to the next section.

Chroot into the target environment, and make sure you have installed the libhildonwm-dev library, by typing this command:

# apt-get install libhildonwm-dev

You can download all of our completed hello-marquee files from here. To compile and install the files type:

# ./autogen.sh
# ./configure --prefix=/usr
# make install

Once this successfully finishes, you can start the Xephyr window by typing:

# ume-xephyr-start


Figure 1-2: The Moblin screen running in the Xephyr window.

Figure 2 is a screenshot of You should see a new speaker icon after the close icon in the marquee pane. Launch any application (Galculator for example), select the speaker icon, and slide the volume control below the center line. See what happens.


Figure 1-3: The selected hello-marquee plug-in.

It should work like selecting the close button, sliding the volume control below the center line will close Galculator application.

Close the Xephyr window. Uninstall and clean by typing:

# make uninstall
# make distclean

Now, let take the step-by-step approach.

Create autogen.sh, configure.ac, and Makefile.am

It is very convenient to use the set of auto tools to automate building the hello-marquee plug-in. You can find a detailed explanation of auto tools here.

Create a file called configure.ac and add this code:

#!/bin/sh
# Script for running GNU toolchain for configuration

set -x
libtoolize --automake --copy
aclocal || aclocal
autoconf
autoheader
automake --add-missing --foreign --force --copy || automake --add-missing --foreign --force --copy

Create a file called autogen.sh and add this code:

AC_INIT(hello-marquee, 1.0.0)
AM_INIT_AUTOMAKE([-Wall -Werror foreign])
AC_PROG_CC
AC_PROG_INSTALL
AC_PROG_RANLIB
AC_PROG_LIBTOOL
AC_CONFIG_SRCDIR([hello-marquee.c])
AM_CONFIG_HEADER(config.h)

PKG_CHECK_MODULES(GTK, gtk+-2.0 >= 2.6.0)
AC_SUBST(GTK_LIBS)
AC_SUBST(GTK_CFLAGS)

PKG_CHECK_MODULES(GLIB, glib-2.0 >= 2.6.0)
AC_SUBST(GLIB_LIBS)
AC_SUBST(GLIB_CFLAGS)

PKG_CHECK_MODULES(LIBHILDONDESKTOP, libhildondesktop)
AC_SUBST(LIBHILDONDESKTOP_LIBS)
AC_SUBST(LIBHILDONDESKTOP_CFLAGS)

PKG_CHECK_MODULES(LIBHILDONWM, libhildonwm)
AC_SUBST(LIBHILDONWM_LIBS)
AC_SUBST(LIBHILDONWM_CFLAGS)

marqueeentrydir=${datadir}/applications/hildon-marquee
AC_SUBST(marqueeentrydir)

marqueepluginsdir=${libdir}/hildon-desktop
AC_SUBST(marqueepluginsdir)

AC_CONFIG_FILES([
Makefile
hello-marquee.desktop
])

AC_OUTPUT

Create a file called Makefile.am and add this code:

AM_CPPFLAGS = $(GTK_CFLAGS) $(GLIB_CFLAGS) $(LIBHILDONDESKTOP_CFLAGS) $(LIBHILDONWM_CFLAGS)

LIBS = $(GTK_LIBS) $(GLIB_LIBS) $(LIBHILDONDESKTOP_LIBS) $(LIBHILDONWM_LIBS)

LDFLAGS = -module -avoid-version

marqueeplugins_LTLIBRARIES = libhellomarquee.la

marqueeentry_DATA = hello-marquee.desktop

libhellomarquee_la_LIBADD = $(LIBS)
libhellomarquee_la_SOURCES = hello-marquee.c

CLEANFILES = *~ *.la

Create a Desktop File for Your New Plug-in

The desktop file is necessary for the marquee panel to locate a plug-in shared object file. Create a file called hello-marquee.desktop (as in marquee.conf) with the following contents, and save it to the /usr/share/applications/hildon-marquee/ directory:

[Desktop Entry]
Name=Hello Marquee Plugin
Type=default
X-Path=libhellomarquee.so

The marquee plug-in shared object library file libhellomarquee.so should be installed to /usr/lib/hildon-desktop/ by default.

Create C/C++ Code for Your New Plug-in

The code for this simple plug-in looks easy after all of the previous steps of weird scripting - copy and paste were your best friends. Now we will have our revenge and write some real code, in a real language. Most of your time in plug-in development is spent here, creating and debugging the code. We won't do it this time and will try to make the smallest amount of working code possible.

Create a file called hello-marquee.c and add this code:

#include <gtk/gtk.h>
#include <libhildondesktop/libhildondesktop.h>
#include <libhildonwm/hd-wm.h>

typedef struct
{
  TaskNavigatorItem tnitem;
  GtkWidget *button;
} HelloPlugin;

typedef struct
{
  TaskNavigatorItemClass parent_class;
} HelloPluginClass;

HD_DEFINE_PLUGIN(HelloPlugin, hello_plugin, TASKNAVIGATOR_TYPE_ITEM);

static void changed(GtkWidget *button, gdouble value, HelloPlugin *plug-in)
{
  if (value < 0.5)
  {
    HDWMWindow *wnd = hd_wm_get_active_window();
    if (wnd != NULL)
    {
      hd_wm_window_close(wnd);
    }
  }
}

static void hello_plugin_init(HelloPlugin *p)
{
  GtkWidget *b = gtk_volume_button_new();
  g_signal_connect(b, "value-changed", G_CALLBACK(changed), (gpointer) p);
  gtk_container_add(GTK_CONTAINER(p), b);
  gtk_widget_show_all(b);
}

static void finalize(GObject *object)
{
   HelloPlugin *plug-in = (HelloPlugin *) HELLO_PLUGIN(object);
   /* Do your finalization here ... */
   G_OBJECT_CLASS(hello_plugin_parent_class)->finalize(object);
}

static void hello_plugin_class_init(HelloPluginClass *class)
{
  GObjectClass *object_class = G_OBJECT_CLASS(class);
  object_class->finalize = finalize;
}

The marquee is based on the Hildon task navigator, and plug-ins have the same interface as the Hildon task navigator items. To create a new marquee plug-in, we must first define a shared object, which is used to insert the plug-in into the marquee panel. To do that, we must place the "TaskNavigatorItem tnitem" as the first member of the plug-in data structure HelloPlugin, and also inherit the plug-in class from TaskNavigatorItemClass in HelloPluginClass.

The HD_DEFINE_PLUGIN macro takes HelloPlugin as the first parameter, our hello_plugin as the second parameter for base_name, and interface name TASKNAVIGATOR_TYPE_ITEM as the third parameter. After that, we should implement base_name##_ini and type_name##_class_init functions: hello_plugin_init and hello_plugin_class_init.

The marquee plug-ins can have any GTK+ widget as their representation on the marquee panel. The marquee loads the library and displays the main widget of the plug-in.

The marquee provides a container for the plug-ins, but the plug-ins are responsible for implementing their own UI, signals, and implementing the callback functions for them.

Compile, Install and Test Your New Plug-in

To compile, install, and test your new plug-in, use the steps that were provided previously in the Our "Hello Marquee" Plug-in section on this page.