Writing a Plug-in for Maemo

From Nokia Developer 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.
35 page views in the last 30 days.

Was this page helpful?

Your feedback about this content is important. Let us know what you think.


Thank you!

We appreciate your feedback.