3 Application Code Template

Maemo platform is based on GTK+ which is a modern framework for building graphical user interfaces providing a C programming API. Like most of the UI widget toolkits GTK+ is based on events. The program itself is executing it's main loop and whenever something needs to be done, like a button is pressed on the touchscreen, an event is triggered. The program has registered a callback function for each event it needs to be aware of, and when the event occures the callback function is executed.

3.1. MaemoProgram and the main Function

The code template is build upon MaemoProgram class which wraps up the maemo platform functionality. By creating an instance of MaemoProgram you will automatically initialize GTK+, create the HildonProgram and HildonWindow objects, load GConf settings for the application, initialize libOSSO and gettext, set up the pixmap directory and the clipboard, and create the main menu with at least the standard items and the application toolbar having at least the standard buttons (the exact menu and toolbar items to be created can be specified with the @menus masking argument). This is all described in maemo Tutorial in detail but is not necessary to know in order to start working with the code.

Now let's examine the main function that can be found in the src/main.c file.

 * The main function.
main(int argc, char *argv[])
	MaemoProgram *program;

	const gchar *application_name = "myapp3";
	const gchar *service_name     = "";
	const gchar *help_id          = "osso_myapp3_Content";

	const gchar *copyright        = "Copyright (C) 2008  jiivonen";
	const gchar *description      = "";
	const gchar *url              = "maemo website";
	const gchar *web              = "";
	const gchar *license          = "";

        gpointer data_ptr;

	g_thread_init( NULL );

/* -------------------> Initialize your application engine here and store it's state to the @data_ptr. */
        data_ptr = NULL; 

	program = maemo_program_new( argc, argv, application_name, service_name,
                                     help_id, data_ptr, NULL );
	maemo_program_set_about( program, copyright, license, description, NULL );
	maemo_program_set_about_website( program, url, web );

/* -------------------> Add menu items, toolbar icons etc. */
	maemo_program_add_menu_item (program, program->main_menu, _("My Item"), cb_my_item);
	/* Bind signals for the application user interface. */
	bind_standard_callbacks( program, NULL );

	/* Go to the main loop. */
	maemo_program_main( program );

	return 0;

As you can see the the main function creates the MaemoProgram instance, sets up the about dialog content, binds the standard callback functions, and then goes into the GTK+ main loop. In order to extend the code into a full application you can add a call to initialize your application before creating the MaemoProgram instance. Then you can pass a data structure containing the application engine state to the MaemoProgram instance when it is created. This will make sure that you can access the application engine data structure in all signal handlers.

3.2 Callback Functions for System Events

The plugin generates an initial src/callbacks.c file which contains all default callback functions of MaemoProgram instance. You should provide an implementation for those callbacks that your specific application requires to function properly. For instance, you might want to implement cb_state_system_inactivity callback to shut down an activity (or scale it down) of the application engine to save power since the device has been an idle for awile.


If you now open up the callbacks.c file you will see that it contains a lot of empty functions like the following.

 * Callbacks for the hardware keys.
cb_hw_key_up(MaemoProgram *program, gpointer data)
    /* TODO: Provide the full implementation. */

If you now replace the function, for example, with the following implementation

cb_hw_key_up(MaemoProgram *program, gpointer data)
    hildon_banner_show_information( program->window, NULL, "Hello world, key up is pressed!" );

and then build the software and run it on the target device, you will get a message when you press the hardware navigation key up. Other system events are wrapped in the same way. The following table contains the list of events and their corresponding callback function:

Hardware State Signals:

SYSTEM EVENT                           CALLBACK FUNCTION
System shutdown                        cb_state_shutdown
Memory Low                             cb_state_memory_low
Save buffers wakeup call               cb_state_save_unsaved_data
System being inactive for some time    cb_state_system_inactivity
Device normal mode state entered       cb_state_normal_mode
Device flight mode state entered       cb_state_flight_mode

Hardware Keypress Signals:

Navigation key Up pressed              cb_hw_key_up
Navigation key Down pressed            cb_hw_key_down
Navigation key Left pressed            cb_hw_key_left
Navigation key Right pressed           cb_hw_key_right
Navigation key Select pressed          cb_hw_key_select
Menu key pressed                       cb_hw_key_menu
Home key pressed                       cb_hw_key_home
Power key pressed                      cb_hw_key_power

3.3 Creating Menus and Submenus

If you want to add menu items you can use maemo_program_add_menu_item function. It is also possible to create some standard menu structures by passing MaemoMenuStructure structure as an argument for the maemo_program_new function. This can be done by changing the main function, for example, like this:

	MaemoMenuStructure menu;
	menu.first_submenu_name = _("File");
	menu.submenus           = MaemoMenuFile;
	menu.file_menu          = MaemoFileMenuNew | MaemoFileMenuOpen | MaemoFileMenuSave | MaemoFileMenuClose;
	menu.edit_menu          = MaemoEditMenuEmpty;
	menu.view_menu          = MaemoViewMenuEmpty;
	menu.tools_menu         = MaemoToolsMenuEmpty;
	menu.play_menu          = MaemoPlayMenuEmpty;

	g_thread_init( NULL );

/* -------------------> Initialize your application engine here and store it's state to the @data_ptr. */
        data_ptr = NULL; 

	program = maemo_program_new( argc, argv, application_name, service_name,
                                     help_id, data_ptr, &menu );

New the a File menu is created with submenu items New, Open, Save, and Close. In order to provide implementations for these actions you need to provide an implementation for cb_file_new, cb_file_open, cb_file_save, and cb_file_close in your projects src/callbacks.c file. Other menus can be done the same way, see the correct masks in src/maemo.h.

3.3 The Content of the Code Template

This chapter summarizes the content of the code template. Here is the list of files generated by the template.                              Autogenerate script                            The main configuration
    data/.desktop         maemo desktop file
    data/.service         maemo service file
    data/_help.xml        The content in XML of the help
    debian/changelog                    Debian package changelog
    debian/control                      Debian package control file
    debian/postinst                     Debian postinst script
    debian/rules                        Debian rules file                             Writes src/maemo-version.h
    src/callbacks.c                     Callback functions for system events
    src/callbacks.h                     The header file of the src/callbacks.c
    src/main.c                          Contains the main function
    src/support.c                       Contains some helper functions
    src/support.h                       The header file of src/support.c

3.3.1 Data Directory

The data/ directory contains the maemo desktop, service and help files whose names are passed as arguments for the maemo_program_new function. These names must match and the files need to be present, otherwise the application does not work properly. The names are initially generated by using the application name you gave to the application wizard. So if you manually change the file names, please, make sure to change them for the main function as well.

3.3.2 Debian Directory

The debian/ directory contains the Debian packaging files. If you want to run some application or a script after your application package is installed into the target device you can edit the debian/postinst file to do it. The script is a shell script and is run after the package has been installed into the target device. By default it only runs maemo-select-menu-location to place the application into the main application launcher menu.

3.3.3 Po Directory

The po/ directory contains the files needed for the application internationalization.

3.3.4 Source Directory

The src/ directory contains the application source code.