Join Now
Quality Rating:
  • Currently 0.0 / 5
(0.0 / 5 - 0 votes cast)
Expertise Level:
  • Currently 0.0 / 5
(0.0 / 5 - 0 votes cast)

This page was last modified 05:21, 12 December 2007.

Writing a Plug-in for Maemo

From Forum Nokia Wiki

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<libhildondesktop/libhildondesktop/hildon-desktop-home-item.h>
#include<hildon-desktop/hildon-desktop/hd-plugin-loader.h>
#include<libosso.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);
 
enum
{
	
	COL_NAME,
	COL_AGE,
 
	NUM_COLS
 
};
 
 
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);
	gtk_rc_parse("/usr/share/oboe-home/oboe-home-gtk.rc");
 
	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);
	GTK_WIDGET_SET_FLAGS (app->previous, GTK_CAN_DEFAULT);
 
	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);
	GTK_WIDGET_SET_FLAGS (app->next, GTK_CAN_DEFAULT);
 
	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),
			NULL);
 
	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;
}
 
void
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)
{
	    return;
}
 
void hildon_home_applet_lib_foreground (void *applet_data)
{
	return;
}
 
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
Type=HildonHomeApplet
X-home-applet=libhello.so
 
Powered by MediaWiki