Development Guides: Simple Applications
Porting an Existing Maemo Application
Sample Code

Introduction
This document describes the changes which are needed to port an existing Maemo application to Moblin's Hildon Application Framework.

This document assumes that the reader is familiar with:

  • Basic Linux knowledge
  • Understanding of Mobile Internet Device (MID)

The first part of this guide describes the general changes needed to port an existing Maemo application and the second part uses MaemoPad as an example application, to describe the step-by-step porting process.

Maemo* is an open source development platform for Internet Tablets. It was developed by Nokia as part of its development process for the Nokia Internet Tablets devices. Maemo uses the Hildon Application Framework, which is based on GNOME technology. Hilden offers an enhanced UI, which meets the specific needs of handheld devices, for example, a small screen size. It has strong support from Nokia and will be separated from Maemo and become part of GNOME Mobile.

The Moblin project also uses the Hildon application framework. Since Moblin and Maemo applications are all based on Hildon application framework, the applications written for Maemo can be easily ported to Moblin.

Moblin is built on Hildon 2.0, while a number of Maemo applications are based on the old Hildon version. Although most of the Hildon widget definitions are the same, several of the Hildon framework packages, such as the Hildon file manager and the Hildon help, have been updated or renamed. Therefore, some modifications are required to compile the Maemo Hildon-based applications in the new environment.

In this guide, we'll cover the general steps required to port the Maemo applications to Moblin.

  1. Update configure.ac;
  2. Update header file path;
  3. Change Hildon program Initialization;
  4. Change the help context support;
  5. Change the HildonFileChooserDialog
  6. Gtk+ related changes
  7. Add application to menu.

These are the basic steps a developer should consider to successfully port a Maemo application to Moblin. We won't list all of the API changes because there are too many. For more specific information about those changes, refer to http://live.gnome.org/Hildon/TwoPointZero.


Porting a Maemo* Application
This section will give a general overview of the changes you would need to make to port a Maemo application to Moblin.  The next section will step through through the process, using MaemoPad as an example.

Update configure.ac
The first thing you must do is update configure.ac. The file, configure.ac, is where you can specify the macros that confirm that the correct libraries are present on the Moblin system. We need to provide the updated library names as parameters to the macro PKG_CHECK_MODULES. We will use the other GNU Autotools to load this file and build out Makefiles. For more information on using configure, see our guide, Using GNU Autotools

Make the following changes in configure.ac:
Old Value New Value
PKG_CHECK_MODULES(..., [hildon-libs]) PKG_CHECK_MODULES(..., [hildon-1])
PKG_CHECK_MODULES(..., [hildon-fm]) PKG_CHECK_MODULES(..., [hildon-fm-2])
PKG_CHECK_MODULES(..., [hildon-libossohelp]) PKG_CHECK_MODULES(..., [hildon-help])


Update Header File Path
The path to the directory that stores the Hildon widget header files is different for the new Hildon libraries.

All of the Hildon widget headers included in the source code should be updated like this:
Old Value New Value
#include <hildon-widgets/*.h > #include <hildon/*.h >


Change Hildon Program Initialization
The routine hildon-program-new(...), which is used to create and initialize the Hildon program widget, was also renamed in the new Hildon libraries.

The following function name in the beginning of your program should be updated, if you use it.
Old Value New Value
hildon-program-new(...) hildon-program-get-instance(...)


Change the Help Context support
Since the Hildon help is updated from libossohelp to hildon-help, the corresponding header file and the method call should be updated, if you use the help service.

Change the preprocessor includes:
Old Value New Value
#include <hildon/osso-helplib.h>  #include <hildon/hildon-help.h>

Here's the method call to show the required help topic from the help file:
Old Value New Value
ossohelp_show(...) hildon_help_show(...)

Here's the method call to enable the button in the dialog box:
Old Value New Value
ossohelp_dialog_help_enable(...) hildonhelp_dialog_help_enable(...)

For more details about the help framework, refer to http://maemo.org/development/documentation/how-tos/4-x/help_framework_howto.html.


Change the HildonFileChooserDialog
Maemo applications use HildonFileChooserDialog to create the dialog used for opening and saving files. However, HildonFileChooserDialog has a close binding with Nokia devices. The developer should replace it with GtkFileChooserDialog, which provides the same functionality without the close binding.

For more details about HildonFileChooserDialog, refer to http://maemo.org/api_refs/3.0/hildon-docs/fm-html/HildonFileChooserDialog.html, for GtkFileChooserDialog, refer to http://developer.gimp.org/api/2.0/gtk/GtkFileChooserDialog.html.


Gtk+ related changes
The Hildon libraries used by Maemo were based on a heavily modified GTK+ 2.6 (maemo-gtk), while the Hildon 2.0 libraries are based on maemo-gtk+ 2.10. Between the versions of GTK+, many GTK+ APIs have been updated or renamed. Developer should be aware of these changes when porting from Maemo to Moblin. For more details about the gtk+ API changes, refer tohttp://live.gnome.org/Maemo/Gtk210Migration.


Add Application to Menu
To add the application to the menu, the desktop entry file should be added to the /usr/share/mobile-basic-flash/applications directory, and the icon file should be added to the /usr/share/mobile-basic-flash/icons directory. You need to make sure that the desktop entry file contains the appropriate information. For details about the desktop entry file and icons, refer to SDK doc Integration with the Homescreen.


Example - Porting Maemopad

Overview
Here we will use MaemoPad as an example application. MaemoPad is a simple text editor, which has some basic features, such as "New", "Open", "Save", etc.


Figure 3-1: "MaemoPad" program running on a Nokia 700.

To develop applications for Moblin, you should work in the target platform's build-environment. All of the subsequent steps will be completed in the target. For more information about how to set up the Moblin development environment, refer to Preparing for Development.

The original source code can be downloaded from https://staging.maemo.org/svn/maemo/projects/tools/trunk/maemo_testing/maemo-examples/howtos/maemopad_1.5.tar.gz.

You can download our modified source here.


Step 1: Upzip the Source Package.

Chroot into the target and download the MaemoPad source, unzip it in the target's file-system, and change into the project directory:
# tar -zxf maemopad_1.5.tar.gz
# cd maemopad-1.5

Source files are located in the src/ directory, which contains the ui/ subdirectory for the UI-related code. The data/ subdirectory contains the desktop entry file, application icons, and help files. We will be making changes in two of the project's four subdirectories: src/ and data/. Localization files are located in the po/ directory. Files that allow you to create a Debian package are in the debian/ directory.


Step 2: Update configure.ac.
First, we are going to modify the file configure.ac to update the library names and the path names, to the install directories for the desktop entry file and icons.

In configure.ac, find the lines that read:
# Hildon library dependencies PKG_CHECK_MODULES(HILDON,
                    hildon-libs >= 0.9.50 hildon-fm libossohelp)

Change "hildon-libs >= 0.9.50 hildon-fm libossohelp" to read "hildon-1 hildon-fm-2 hildon-help":
# Hildon library dependencies PKG_CHECK_MODULES(HILDON,
                    hildon-1 hildon-fm-2 hildon-help)

You also need to update configure.ac's desktop entry file and icon install directories to /usr/share/mobile-basic-flash/applications, and /usr/share/mobile-basic-flash/icons, respectively. In configure.ac, find the line that reads:
desktopentrydir=`$PKG_CONFIG osso-af-settings --variable=desktopentrydir`

And change "`$PKG_CONFIG osso-af-settings --variable=desktopentrydir`" to read: "$datadir/ mobile-basic-flash/applications":
desktopentrydir=$datadir/mobile-basic-flash/applications

Find the line that reads:
# Application icon install directories
icon_26x26dir=$datadir/icons/hicolor/26x26/hildon

And change "$datadir/icons/hicolor/26x26/hildon" to "$datadir/mobile-basic-flash/icons":
# Application icon install directories
icon_26x26dir=$datadir/mobile-basic-flash/icons

Step 3: Install all required packages and generate Makefile.
To make building MaemoPad easier, you can use the parameters of the PKG_CHECK_MODULES macro in configure.ac to make sure that all required packages are installed on your target system: hildon-1, hildon-fm-2, hildon-help, osso-af-settings, etc.

Note: Make sure the latest osso-af-settings library is installed, or, when running configure, you may get this error:
Package requirements (osso-af-settings >= 0.8.5 ... ) were not met:
    Variable 'datarootdir' not defined in
    '/usr/lib/pkgconfig/osso-af-settings.pc'

You can download the source osso-af-settings 0.9.0-1ubuntu5 from https://launchpad.net/ubuntu/hardy/+source/osso-af-settings/0.9.0-1ubuntu5 and install it manually. Or you can add the following line to /usr/lib/pkgconfig/osso-af-settings.pc:
datarootdir=${prefix}/share

You can register the changes made to configure.ac and generate the Makefile with the GNU Autotools using the following commands. For more details about how to generate Makefile, refer to Using GNU Autotools.
# ./autogen.sh
# ./configure --prefix=/usr

Step 4: Update header file path.
Next, we need to change every hildon library include directive to point to the new location. We should check all source files under src/ directory and update the hildon widget headers in the source code.

In the files src/ui/interface.c, src/ui/interface.h, and src/main.c, find any line that includes a Hildon library in the hildon-widgets folder:
#include <hildon-widgets/*.h >

And change it to the hildon folder:
#include <hildon/*.h >

Step 5: Change the Help Context support.
The header file src/ui/callback.h uses the libosso help context, where it now needs to point to the Hildon help context. The callback_help(...) function in the src/ui/callback.c file also needs to be changed. Let's update include directive and the method call, to show the help context.

In the file src/ui/callback.h, find the line that reads:
#include <hildon/osso-helplib.h>

And change it to this:
#include <hildon/hildon-help.h>

In the callback_help(...) function in the source file src/ui/callback.c, change the function callback_help(...) so that it looks like this:
. . .
void callback_help( GtkAction * action, gpointer data )
{
    osso_return_t retval;

    /* connect pointer to our MainView struct */
    MainView *mainview = NULL;
    mainview = ( MainView * ) data;
    g_assert(mainview != NULL && mainview->data != NULL );
   
    retval = hildon_help_show(
    mainview->data->osso, /* global osso_context */
    HELP_TOPIC_ID, /* topic id */
    HILDON_HELP_SHOW_DIALOG);

}
. . .

Step 6: Change the HildonFileChooserDialog
The standard dialog that the Maemo application uses to chose files has a close binding with the Nokia hardware. We need to replace the code that uses the HildonFileChooserDialog with GTK+'s file chooser dialog, GtkFileChooserDialog.

In MaemoPad, the code that executes file selection is in the interface_file_chooser(...) function in interface.c.

Open the file src/ui/interface.c and find the interface_file_chooser(...) function. Remove the following line:
dialog = hildon_file_chooser_dialog_new(
                                    GTK_WINDOW(mainview->data->program),
                                    action);

And replace it with:
if(action == GTK_FILE_CHOOSER_ACTION_OPEN)
{
    dialog = gtk_file_chooser_dialog_new ("Open File",
                                    GTK_WINDOW(mainview->data->program),
                                    GTK_FILE_CHOOSER_ACTION_OPEN,
                                    GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                                    GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
                                    NULL);
}
else
{
    dialog = gtk_file_chooser_dialog_new ("Save File",
                                    GTK_WINDOW(mainview->data->program),
                                    GTK_FILE_CHOOSER_ACTION_SAVE,
                                    GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                                    GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
                                    NULL);
    gtk_file_chooser_set_do_overwrite_confirmation (
                                    GTK_FILE_CHOOSER (dialog),
                                    TRUE);
}

Find the line:
if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK)
{
    filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
}

And replace it with:
if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
{
    filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
}

Here is what the final version of the function interface_file_chooser should look like, with changes in bolded blue:
. . .
/* File chooser */
gchar* interface_file_chooser(MainView * mainview, GtkFileChooserAction action)
{
    GtkWidget *dialog;
    gchar* filename = NULL;

    if(action == GTK_FILE_CHOOSER_ACTION_OPEN)
    {
        dialog = gtk_file_chooser_dialog_new ("Open File",
                                        GTK_WINDOW(mainview->data->program),
                                        GTK_FILE_CHOOSER_ACTION_OPEN,
                                        GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                                        GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
                                        NULL);
    }
    else
    {
        dialog = gtk_file_chooser_dialog_new ("Save File",
                                        GTK_WINDOW(mainview->data->program),
                                        GTK_FILE_CHOOSER_ACTION_SAVE,
                                        GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                                        GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
                                        NULL);
        gtk_file_chooser_set_do_overwrite_confirmation (
                                        GTK_FILE_CHOOSER (dialog),
                                        TRUE);
    }


    gtk_widget_show_all (GTK_WIDGET(dialog));

    if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
    {
        filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
    }

    gtk_widget_destroy (dialog);
    return filename;
}
. . .

Step 7: Modify GTK+ API: Enable Rich Text Copy & Paste.
The API that is used in interface.c to enable rich text copy and paste has been updated in GTK+ 2.10. You should replace them with the new API.

In the file src/ui/interface.c, find the following lines in the function create_textarea(...):
/* Enable Rich Text Support */
 gtk_text_buffer_set_can_paste_rich_text ( main->buffer, TRUE );
gtk_text_buffer_set_rich_text_format ( main->buffer, "RTF" );

And change them to:
/* Enable Rich Text Support */
gtk_text_buffer_register_serialize_tagset ( main->buffer, "RTF");
gtk_text_buffer_register_deserialize_tagset ( main->buffer, "RTF" );

Step 8: Create a Desktop Entry File
Now we need to modify the desktop entry file data/maemopad.desktop, so that the Moblin desktop environment can make an icon on the home screen to launch our application. This will be installed in the correct directory for desktop entry files when we run make install, later. This is what your desktop entry file should contain:

[Desktop Entry]
Encoding=UTF-8
Version=0.1
Type=Application
Name=MaemoPad
Exec=/usr/bin/maemopad
Icon=maemopad
Categories=Mobile
X-Osso-Service=maemopad

Step 9: Compile the source and install
Now let's compile and run our ported MaemoPad and see if our changes worked! You should change into the maemopad-1.5 directory and run make to compile the source. If everything compiles well, then you can run make install to install the program and data files.
# cd maemopad-1.5
# make
# make install

Make sure you didn't get any errors during compilation, or you will have to go back and make sure you made the correct changes.

Step 10: Run MaemoPad and check its basic features.
First we need to start the Moblin desktop environment, which will display our home screen UI. We should see a button with the MaemoPad name and icon. If we click it, MaemoPad should launch and we can test our other changes. We should verify that the help is working correctly, and that we can open and save files.
Restart the UI. The MaemoPad application should show in the home screen.

Figure 3-2: Moblin Home Screen

Click MaemoPad icon, the application should launch successfully, the figure below demonstrates the main UI for the MaemoPad.
Figure 3-3: MaemoPad Main UI

Then you can check its basic features: open a new file or save the file under edit to make sure the MaemoPad application can work properly on Moblin.
Figure 3-4: MaemoPad Open Dialog
Figure 3-5: MaemoPad Save Dialog

Reference Documents

The following documents were used as references in the writing of this document. Refer to these documents for further details:

  1. Ubuntu Documentation - http://umeguide.net/C/ch08s05.html#id2608228
  2. Maemo Documentation: How to Write a New Application for Maemo 3.x - http://maemo.org/development/documentation/how-tos/3-x/howto_new_application_bora.html
  3. Maemo Documentation: Help Framework HOWTO - http://maemo.org/development/documentation/how-tos/4-x/help_framework_howto.html
  4. Hildon 2.0 Release - http://live.gnome.org/Hildon/TwoPointZero