Please note that as of October 24, 2014, the Nokia Developer Wiki will no longer be accepting user contributions, including new entries, edits and comments, as we begin transitioning to our new home, in the Windows Phone Development Wiki. We plan to move over the majority of the existing entries. Thanks for all your past and future contributions.

Writing a Plug-in for Maemo

From Wiki
Jump to: navigation, search
Article Metadata
Created: rbelwal (11 Dec 2007)
Last edited: hamishwillee (31 Jul 2012)

Further Reading

Getting started with Maemo development using C

This example code shows how to write an applet for Maemo

#include <gtk/gtk.h>
#include <gtk/gtkmain.h>
#include <gtk/gtkbutton.h>
#include "callbacks.h"
#include <glib.h>
#define APPLET_X_SIZE 400
#define APPLET_Y_SIZE 300
GtkWidget * metar_ui_init (osso_context_t* osso) ;
void on_refresh_clicked (GtkButton *button, gpointer user_data);
static void test_button_clicked (GtkButton* button, gpointer data);
static GtkWidget *xpm_label_box( gchar *xpm_filename,
gchar *label_text )
GtkWidget *box;
GtkWidget *label;
GtkWidget *image;
/* Create box for image and label */
box = gtk_hbox_new (FALSE, 0);
gtk_container_set_border_width (GTK_CONTAINER (box), 2);
/* Now on to the image stuff */
image = gtk_image_new_from_file (xpm_filename);
/* Create a label for the button */
label = gtk_label_new (label_text);
/* Pack the image and label into the box */
gtk_box_pack_start (GTK_BOX (box), image, FALSE, FALSE, 3);
gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 3);
gtk_widget_show (image);
gtk_widget_show (label);
return box;
void * hildon_home_applet_lib_initialize (void *state_data,int *state_size, GtkWidget **widget)
osso_context_t *osso;
/* Initialize libosso */
osso = osso_initialize ("METAR_APP", "0.1", FALSE, NULL);
if (!osso) {
g_debug ("Error initializing the osso"
"maemo metar applet");
return NULL;
* * Call private function metar_ui_init which does the initialization
* * for this applet. It returns the GtkWidget which is then returned
* * to Home. The function content could be implemented here too, but for
* * maintainability reasons it has been moved to different function in different
* * source file.
* */

*widget = metar_ui_init(osso);
g_debug ("Initialized maemo metar applet");
/* Libosso context is returned to Home */
return (void*)osso;
/* Test button */
static void test_button_clicked (GtkButton* button, gpointer data)
printf("Hello world. You clicked the test button!\n");
/* Application UI data struct */
typedef struct {
GtkWidget *frame1;
GtkWidget *vbox0;
GtkWidget *button0;
GtkWidget *label0 ;
osso_context_t* osso;
GtkWidget *alignment1;
GtkWidget *vbox1;
GtkWidget *hbuttonbox2;
GtkWidget *eventbox3;
GtkWidget *refresh;
GtkWidget *Search_Jobs;
GtkWidget *Search;
GtkWidget *hseparator1;
GtkWidget *scrolledwindow1;
GtkWidget *treeview1;
GtkWidget *hbuttonbox3;
GtkWidget *eventbox2;
GtkWidget *previous;
GtkWidget *eventbox1;
GtkWidget *next;
GtkWidget *label1;
GtkWidget *box;
} MetarApp;
MetarApp *app;
/* Create the widget for the applet that is returned to the caller (maemo desktop) */
static void metar_ui_create_home_applet (void)
/* Create the main widget of the applet */
app->frame1 = gtk_frame_new(NULL);
gtk_widget_set_size_request ( GTK_WIDGET (app->frame1), APPLET_X_SIZE, APPLET_Y_SIZE );
gtk_widget_set_name (GTK_WIDGET (app->frame1), "oboe-home-applet");
/* Finally show the thing */
app->alignment1 = gtk_alignment_new (0.5, 0.5, 1, 1);
gtk_widget_show (app->alignment1);
gtk_container_add (GTK_CONTAINER (app->frame1), app->alignment1);
gtk_alignment_set_padding (GTK_ALIGNMENT (app->alignment1), 0, 0, 12, 0);
app->vbox1 = gtk_vbox_new (FALSE, 0);
gtk_widget_show (app->vbox1);
gtk_container_add (GTK_CONTAINER (app->alignment1), app->vbox1);
app->hbuttonbox2 = gtk_hbutton_box_new ();
gtk_widget_show (app->hbuttonbox2);
gtk_box_pack_start (GTK_BOX (app->vbox1), app->hbuttonbox2, TRUE, TRUE, 0);
app->eventbox3 = gtk_event_box_new ();
gtk_widget_show (app->eventbox3);
gtk_container_add (GTK_CONTAINER (app->hbuttonbox2), app->eventbox3);
app->box = xpm_label_box ("/usr/share/pixmaps/pix/info.xmp", "cool button");
gtk_widget_show (app->box);
app->refresh = gtk_button_new (); /* gtk_button_new_with_mnemonic ("Refresh");*/
gtk_widget_set_name (GTK_WIDGET (app->refresh), "button");
gtk_container_add (GTK_CONTAINER (app->refresh), app->box);
gtk_widget_show (app->refresh);
gtk_container_add (GTK_CONTAINER (app->eventbox3), app->refresh);
app->hseparator1 = gtk_hseparator_new ();
gtk_widget_show (app->hseparator1);
gtk_box_pack_start (GTK_BOX (app->vbox1), app->hseparator1, TRUE, TRUE, 0);
app->scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL);
gtk_widget_show (app->scrolledwindow1);
gtk_box_pack_start (GTK_BOX (app->vbox1), app->scrolledwindow1, TRUE, TRUE, 0);
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (app->scrolledwindow1), GTK_SHADOW_IN);
app->treeview1 = gtk_tree_view_new ();
gtk_widget_show (app->treeview1);
gtk_container_add (GTK_CONTAINER (app->scrolledwindow1), app->treeview1);
app->hbuttonbox3 = gtk_hbutton_box_new ();
gtk_widget_show (app->hbuttonbox3);
gtk_box_pack_start (GTK_BOX (app->vbox1), app->hbuttonbox3, TRUE, TRUE, 0);
app->eventbox2 = gtk_event_box_new ();
gtk_widget_show (app->eventbox2);
gtk_container_add (GTK_CONTAINER (app->hbuttonbox3), app->eventbox2);
app->previous = gtk_button_new_with_mnemonic ("Show Previous");
gtk_widget_show (app->previous);
gtk_container_add (GTK_CONTAINER (app->eventbox2), app->previous);
app->eventbox1 = gtk_event_box_new ();
gtk_widget_show (app->eventbox1);
gtk_container_add (GTK_CONTAINER (app->hbuttonbox3), app->eventbox1);
app->next = gtk_button_new_with_mnemonic ("Show More");
gtk_widget_show (app->next);
gtk_container_add (GTK_CONTAINER (app->eventbox1), app->next);
app->label1 = gtk_label_new ("<b>frame1</b>");
gtk_widget_show (app->label1);
gtk_frame_set_label_widget (GTK_FRAME (app->frame1), app->label1);
gtk_label_set_use_markup (GTK_LABEL (app->label1), TRUE);
g_signal_connect ((gpointer) app->refresh, "clicked",
G_CALLBACK (on_refresh_clicked),
gtk_widget_show_all (GTK_WIDGET (app->frame1));
/* Init UI */
GtkWidget * metar_ui_init (osso_context_t* osso)
if (!app) {
/* Create the struct for storing the globals nicely inside a namespace */
app = g_new0 (MetarApp, 1);
app->osso = osso;
/* The UI initialization could be inside this function, but I
* did choose to put it to another function */

metar_ui_create_home_applet ();
/* IMPORTANT! This returns the main widget of the applet (frame1) to maemo desktop */
return app->frame1;
metar_ui_quit (void) {
/* This is for freeing the stuff allocated earlier */
if (app) {
g_free (app);
app = NULL;
void hildon_home_applet_lib_deinitialize (void *applet_data)
osso_context_t *osso = (osso_context_t*)applet_data;
/* Call private function which deinitializes your UI. Not necessary required to be
* separate, but for maintainability reasons it may be cleaner to place it to different file
* than this API implementation */

metar_ui_quit ();
/* Deinitialize libosso */
osso_deinitialize (osso);
void hildon_home_applet_lib_background (void *applet_data)
void hildon_home_applet_lib_foreground (void *applet_data)
int hildon_home_applet_lib_save_state (void *applet_data,
void **state_data,
int *state_size)
/* we don't want to save state in a simple weather applet */
(*state_data) = NULL;
if (state_size) {
(*state_size) = 0;
} else {
g_debug ("State_size pointer was not pointing to right place");
return 1;
void append_list_totree(GtkWidget *tree)
GtkListStore *store;
GtkTreeIter iter;
store = gtk_list_store_new (NUM_COLS, G_TYPE_STRING, G_TYPE_UINT);
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter,COL_NAME, "Heinz El-Mann", COL_AGE, 51, -1);
GtkWidget* hildon_home_applet_lib_settings (void *applet_data,GtkWindow *parent)
return NULL;
void on_refresh_clicked (GtkButton *button, gpointer user_data)

Example of desktop Applet

Example of desktop applet

[Desktop Entry]
Name=Hello, Ravi!
Comment=Example Home plugin
This page was last modified on 31 July 2012, at 11:44.
30 page views in the last 30 days.