<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://maemo.octonezd.me/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=88.114.203.150</id>
	<title>Maemo Wiki Mirror - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://maemo.octonezd.me/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=88.114.203.150"/>
	<link rel="alternate" type="text/html" href="https://maemo.octonezd.me/index.php/Special:Contributions/88.114.203.150"/>
	<updated>2026-04-22T01:51:47Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.45.1</generator>
	<entry>
		<id>https://maemo.octonezd.me/index.php?title=Documentation/Maemo_5_Developer_Guide/Application_Development/Writing_a_new_maemo_application&amp;diff=6482</id>
		<title>Documentation/Maemo 5 Developer Guide/Application Development/Writing a new maemo application</title>
		<link rel="alternate" type="text/html" href="https://maemo.octonezd.me/index.php?title=Documentation/Maemo_5_Developer_Guide/Application_Development/Writing_a_new_maemo_application&amp;diff=6482"/>
		<updated>2011-05-14T08:43:26Z</updated>

		<summary type="html">&lt;p&gt;88.114.203.150: I removed font tag from example code&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This section is a guide for making new applications for the Maemo platform. Maemo 5 SDK needs to be installed successfully as a pre-requisite. &lt;br /&gt;
&lt;br /&gt;
A simple text editor with a few essential features is used as a example. Let us name it as &#039;&#039;MaemoPad&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
MaemoPad has the following basic features: &#039;&#039;New&#039;&#039;, &#039;&#039;Open&#039;&#039;, &#039;&#039;Save&#039;&#039;, &#039;&#039;Save As...&#039;&#039;, &#039;&#039;Cut&#039;&#039;, &#039;&#039;Copy&#039;&#039;, &#039;&#039;Paste&#039;&#039;, &#039;&#039;Font&#039;&#039;, &#039;&#039;Full Screen&#039;&#039;, &#039;&#039;Full Screen&#039;&#039; hardware key handling, &#039;&#039;Send-Via email/bluetooth&#039;&#039; and &#039;&#039;Close&#039;&#039;. For simplicity, it does not contain advanced features like &#039;&#039;Undo&#039;&#039;, &#039;&#039;Redo&#039;&#039;, different fonts in one document, pictures, tables, etc.&lt;br /&gt;
&lt;br /&gt;
The figure below is a screenshot of the text editor.&lt;br /&gt;
&lt;br /&gt;
[[Image:Maemopad2.png|500px|alt=Screenshot of MaemoPad|MaemoPad text editor]]&lt;br /&gt;
&lt;br /&gt;
== Creating the application file structure ==&lt;br /&gt;
&lt;br /&gt;
In general, a Maemo application uses the [[../../GNU Build System|GNU Build System]] and has the following files and subdirectories:&lt;br /&gt;
* &amp;lt;code&amp;gt;src/&amp;lt;/code&amp;gt;: Contains the source files.&lt;br /&gt;
* &amp;lt;code&amp;gt;debian/&amp;lt;/code&amp;gt;: Contains the files related to Debian packaging&lt;br /&gt;
* &amp;lt;code&amp;gt;data/&amp;lt;/code&amp;gt;: Contains all data files needed to run the application. Maemopad will need the following data files:&lt;br /&gt;
**&amp;lt;code&amp;gt;maemopad.desktop&amp;lt;/code&amp;gt; file &lt;br /&gt;
**D-Bus &amp;lt;code&amp;gt;maemopad.service&amp;lt;/code&amp;gt; file &lt;br /&gt;
**application icons in a separate directory called &amp;lt;code&amp;gt;icons/&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;po/&amp;lt;/code&amp;gt;: Contains the localization files. Maemopad contains the following files:&lt;br /&gt;
** &amp;lt;code&amp;gt;POTFILES.in&amp;lt;/code&amp;gt; list the names of the files to be localized.&lt;br /&gt;
** Translation file &amp;lt;code&amp;gt;en_GB.po&amp;lt;/code&amp;gt; containing British English strings for the application.&lt;br /&gt;
** Translation file &amp;lt;code&amp;gt;fi_FI.po&amp;lt;/code&amp;gt; containing Finnish strings for the application.&lt;br /&gt;
* &amp;lt;code&amp;gt;autogen.sh&amp;lt;/code&amp;gt; is a shell script that provides automatic build system preparation.&lt;br /&gt;
* &amp;lt;code&amp;gt;configure.ac&amp;lt;/code&amp;gt; is an input file for &amp;lt;code&amp;gt;autoconf&amp;lt;/code&amp;gt; that contains &amp;lt;code&amp;gt;autoconf&amp;lt;/code&amp;gt; macros that test the system features the package needs or can use. It produces the &amp;lt;code&amp;gt;configure&amp;lt;/code&amp;gt; script.&lt;br /&gt;
* &amp;lt;code&amp;gt;Makefile.am&amp;lt;/code&amp;gt; is used by &amp;lt;code&amp;gt;automake&amp;lt;/code&amp;gt; to produce a standards-compliant &amp;lt;code&amp;gt;Makefile.in&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;Makefile.am&amp;lt;/code&amp;gt; in the top source directory is usually very simple and includes the files and subdirectories needed to make the application: &amp;lt;code&amp;gt;src/&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;po/&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;data/&amp;lt;/code&amp;gt; and all the &amp;lt;code&amp;gt;Makefile&amp;lt;/code&amp;gt;s in &amp;lt;code&amp;gt;src/&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;po/&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;data/&amp;lt;/code&amp;gt; directories.&lt;br /&gt;
&lt;br /&gt;
You can compile the source as follows:&lt;br /&gt;
 &lt;br /&gt;
  [sbox-FREMANTLE_X86 ~] &amp;gt; ./autogen.sh &lt;br /&gt;
  [sbox-FREMANTLE_X86 ~] &amp;gt;$ ./configure &lt;br /&gt;
  [sbox-FREMANTLE_X86 ~] &amp;gt;$ make&lt;br /&gt;
&lt;br /&gt;
For more information about GNU autoconf and automake, see the [[Documentation/Maemo 5 Developer Guide/GNU Build System|GNU build system]] article.&lt;br /&gt;
&lt;br /&gt;
== Coding the application ==&lt;br /&gt;
&lt;br /&gt;
The src/ directory of MaemoPad contains the following files:&lt;br /&gt;
* main.c&lt;br /&gt;
* maemopad-window.h&lt;br /&gt;
* maemopad-window.c&lt;br /&gt;
* fullscreenmanager.c&lt;br /&gt;
* fullscreenmanage.h&lt;br /&gt;
* Makefile.am&lt;br /&gt;
&lt;br /&gt;
=== maemopad-window.h ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[https://vcs.maemo.org/svn/maemoexamples/tags/maemo_5.0/maemopad/src/maemopad-window.h maemopad-window.h]&amp;lt;/code&amp;gt; defines the &amp;lt;code&amp;gt;MaemopadWindow&amp;lt;/code&amp;gt; structure to hold the application data and other declarations. Even though the data varies depending on the application, a sample structure might look like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
typedef struct _MaemopadWindow MaemopadWindow;&lt;br /&gt;
&lt;br /&gt;
struct _MaemopadWindow&lt;br /&gt;
{&lt;br /&gt;
  HildonWindow parent;&lt;br /&gt;
&lt;br /&gt;
  /* Osso context, needed for &amp;quot;send via&amp;quot; functionality. */&lt;br /&gt;
  osso_context_t *osso; &lt;br /&gt;
&lt;br /&gt;
  /* Fullscreen mode is on (TRUE) or off (FALSE): */&lt;br /&gt;
  gboolean fullscreen;&lt;br /&gt;
&lt;br /&gt;
  /* Button items for menu: */&lt;br /&gt;
  GtkWidget *new_item;&lt;br /&gt;
  GtkWidget *open_item;&lt;br /&gt;
  GtkWidget *save_item;&lt;br /&gt;
  GtkWidget *saveas_item;&lt;br /&gt;
  GtkWidget *cut_item;&lt;br /&gt;
  GtkWidget *copy_item;&lt;br /&gt;
  GtkWidget *paste_item;&lt;br /&gt;
  /*.....more...truncated...*/&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Where &amp;lt;code&amp;gt;MaemopadWindow&amp;lt;/code&amp;gt; is a structure containing pointers to all the UI objects, such as &amp;lt;code&amp;gt;HildonWindow&amp;lt;/code&amp;gt;, menu items, toolbar; and UI-related data, for instance a boolean variable indicating whether the application is in fullscreen mode.&lt;br /&gt;
&lt;br /&gt;
Each application creates its own &amp;lt;code&amp;gt;AppData&amp;lt;/code&amp;gt; variable, and this variable is usually passed around as a parameter in the functions, particularly the callback functions, so that the applications data can be accessible by the functions.&lt;br /&gt;
&lt;br /&gt;
Many applications declare this &amp;lt;code&amp;gt;AppData&amp;lt;/code&amp;gt; variable as global.&lt;br /&gt;
&lt;br /&gt;
=== main.c ===&lt;br /&gt;
&lt;br /&gt;
main.c usually performs, at least, the following functions:&lt;br /&gt;
&lt;br /&gt;
* Initializing GTK+&lt;br /&gt;
* Initializing localization&lt;br /&gt;
* Creating an instance of &amp;lt;code&amp;gt;HildonProgram&amp;lt;/code&amp;gt;&lt;br /&gt;
* Calling to a function, usually defined in &amp;lt;code&amp;gt;interface.c&amp;lt;/code&amp;gt;, to create the main view.&lt;br /&gt;
* Connecting the main view window to the created &amp;lt;code&amp;gt;HildonProgram&amp;lt;/code&amp;gt;&lt;br /&gt;
* Running &amp;lt;code&amp;gt;gtk_main()&amp;lt;/code&amp;gt;&lt;br /&gt;
* Connecting the &amp;lt;code&amp;gt;delete_event&amp;lt;/code&amp;gt; of the main view to a callback function to handle a proper application exit, such as destroying the main view window, freeing used memory and saving application states before exit.&lt;br /&gt;
* Call &amp;lt;code&amp;gt;gtk_main_quit()&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is the main function of MaemoPad with comments:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int main (int argc, char* argv[])&lt;br /&gt;
{&lt;br /&gt;
  osso_context_t *osso = NULL;&lt;br /&gt;
  AppData *data = g_new0 (AppData, 1);&lt;br /&gt;
 &lt;br /&gt;
  /* Initialize the locale stuff: */&lt;br /&gt;
  setlocale (LC_ALL, &amp;quot;&amp;quot;);&lt;br /&gt;
  bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);&lt;br /&gt;
  bind_textdomain_codeset(GETTEXT_PACKAGE, &amp;quot;UTF-8&amp;quot;);&lt;br /&gt;
  textdomain (GETTEXT_PACKAGE);&lt;br /&gt;
 &lt;br /&gt;
  /* Inititialize GTK+ and hildon: */&lt;br /&gt;
  hildon_gtk_init (&amp;amp;argc, &amp;amp;argv);&lt;br /&gt;
 &lt;br /&gt;
  if (!g_thread_supported()) {&lt;br /&gt;
    g_thread_init (NULL);&lt;br /&gt;
  }&lt;br /&gt;
 &lt;br /&gt;
  /* Create the hildon application and setup the title: */&lt;br /&gt;
  data-&amp;gt;program = HILDON_PROGRAM (hildon_program_get_instance ());&lt;br /&gt;
  g_set_application_name (_(&amp;quot;MaemoPad&amp;quot;));&lt;br /&gt;
 &lt;br /&gt;
  /* We need the osso context to call libmodest_dbus_client_compose_mail() later. */&lt;br /&gt;
  osso = osso_initialize (OSSO_SERVICE, VERSION, TRUE, NULL);&lt;br /&gt;
  g_assert (osso);&lt;br /&gt;
 &lt;br /&gt;
  /* Create the window for our application: */&lt;br /&gt;
  data-&amp;gt;window = maemopad_window_new (osso);&lt;br /&gt;
  hildon_program_add_window (data-&amp;gt;program, data-&amp;gt;window);&lt;br /&gt;
 &lt;br /&gt;
  /* Show the main window and start the mainloop, &lt;br /&gt;
   * quitting the mainloop when it the main window is hidden:&lt;br /&gt;
   */&lt;br /&gt;
  gtk_widget_show (GTK_WIDGET (data-&amp;gt;window));&lt;br /&gt;
  g_signal_connect(data-&amp;gt;window, &amp;quot;hide&amp;quot;, G_CALLBACK (&amp;amp;on_main_window_hide), NULL);&lt;br /&gt;
  g_signal_connect(data-&amp;gt;window, &amp;quot;delete_event&amp;quot;, &lt;br /&gt;
    G_CALLBACK (&amp;amp;gtk_widget_hide_on_delete), NULL);&lt;br /&gt;
  gtk_main();&lt;br /&gt;
   &lt;br /&gt;
  /* Clean up: */&lt;br /&gt;
  gtk_widget_destroy (GTK_WIDGET (data-&amp;gt;window));&lt;br /&gt;
  g_free (data);&lt;br /&gt;
 &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== User interface ==&lt;br /&gt;
&lt;br /&gt;
The graphical user interface code is implemented in directory &amp;lt;code&amp;gt;./src/ui/&amp;lt;/code&amp;gt;. It contains two .c files: &amp;lt;code&amp;gt;interface.c&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;callbacks.c&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== interface.c ===&lt;br /&gt;
&lt;br /&gt;
This file creates the graphical user interface (GUI) and connects the signals and events to appropriate handlers defined in &amp;lt;code&amp;gt;callbacks.c&amp;lt;/code&amp;gt;. See the [http://www.forum.nokia.com/info/sw.nokia.com/id/eb8a68ba-6225-4d84-ba8f-a00e4a05ff6f/Hildon_2_2_UI_Style_Guide.html Hildon UI style guide] for information on how to create GUI in Maemo. For more information on GTK+ see the [http://maemo.org/api_refs/5.0/5.0-final/gtk/ GTK+ Reference Manual].&lt;br /&gt;
&lt;br /&gt;
As a general practice, an &amp;lt;code&amp;gt;AppUIData&amp;lt;/code&amp;gt; struct variable is created when creating the GUI. And then, a &amp;lt;code&amp;gt;HildonWindow&amp;lt;/code&amp;gt; and smaller components are created in different functions, such as &amp;lt;code&amp;gt;create_menu()&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;create_toolbar()&amp;lt;/code&amp;gt;. When creating each component, &amp;lt;code&amp;gt;AppUIData&amp;lt;/code&amp;gt; should refer to various necessary UI objects created along the way.&lt;br /&gt;
&lt;br /&gt;
The following excerpt shows how &amp;lt;code&amp;gt;AppUIData&amp;lt;/code&amp;gt; is created, and how it points to the toolbar and the button &#039;&#039;New file&#039;&#039; on the toolbar.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* Creates and initializes a main_view */&lt;br /&gt;
AppUIData* interface_main_view_new( AppData *data )&lt;br /&gt;
{&lt;br /&gt;
    /* Zero memory with g_new0 */&lt;br /&gt;
    AppUIData* result = g_new0( AppUIData, 1 );&lt;br /&gt;
    /*....*/&lt;br /&gt;
    create_toolbar( result );&lt;br /&gt;
    /*....*/&lt;br /&gt;
}&lt;br /&gt;
/* Create toolbar to mainview */&lt;br /&gt;
static void create_toolbar ( AppUIData *main )&lt;br /&gt;
{&lt;br /&gt;
    /* Create new GTK toolbar */&lt;br /&gt;
    main-&amp;gt;toolbar = gtk_toolbar_new ();&lt;br /&gt;
    /*....*/&lt;br /&gt;
    /* Create the &amp;quot;New file&amp;quot; button in the toolbar */&lt;br /&gt;
    main-&amp;gt;new_tb = gtk_tool_button_new_from_stock(GTK_STOCK_NEW);&lt;br /&gt;
    /*....*/&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== callbacks.c ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;callbacks.c&amp;lt;/code&amp;gt; defines all the functions that handle the signals or events that might be triggered by the UI. When creating different UI objects in &amp;lt;code&amp;gt;interface.c&amp;lt;/code&amp;gt;, the handlers are registered as follows.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* Create the menu items needed for the drop down menu */&lt;br /&gt;
static void create_menu( AppUIData *main )&lt;br /&gt;
{&lt;br /&gt;
    /* ... */&lt;br /&gt;
    main-&amp;gt;new_item = gtk_menu_item_new_with_label ( _(&amp;quot;New&amp;quot;) );&lt;br /&gt;
    /* ... */&lt;br /&gt;
    /* Attach the callback functions to the activate signal */&lt;br /&gt;
    g_signal_connect( G_OBJECT( main-&amp;gt;new_item ), &amp;quot;activate&amp;quot;,&lt;br /&gt;
                      G_CALLBACK ( callback_file_new), main );&lt;br /&gt;
    /* ... */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Function &amp;lt;code&amp;gt;callback_file_new&amp;lt;/code&amp;gt; is implemented in &amp;lt;code&amp;gt;callbacks.c&amp;lt;/code&amp;gt;, saving the current file if needed, and then opening a new file to edit.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void callback_file_new(GtkAction * action, gpointer data)&lt;br /&gt;
{&lt;br /&gt;
    gint answer;&lt;br /&gt;
    AppUIData *mainview = NULL;&lt;br /&gt;
    mainview = ( AppUIData * ) data;&lt;br /&gt;
    g_assert(mainview != NULL &amp;amp;&amp;amp; mainview-&amp;gt;data != NULL );&lt;br /&gt;
    /* save changes note if file is edited */&lt;br /&gt;
    if( mainview-&amp;gt;file_edited ) {&lt;br /&gt;
        answer = interface_save_changes_note( mainview );&lt;br /&gt;
        if( answer == CONFRESP_YES ) {&lt;br /&gt;
            if( mainview-&amp;gt;file_name == NULL ) {&lt;br /&gt;
                mainview-&amp;gt;file_name = interface_file_chooser(mainview, GTK_FILE_CHOOSER_ACTION_SAVE);&lt;br /&gt;
            }&lt;br /&gt;
            write_buffer_to_file ( mainview );&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    /* clear buffer, filename and free buffer text */&lt;br /&gt;
    gtk_text_buffer_set_text ( GTK_TEXT_BUFFER (mainview-&amp;gt;buffer), &amp;quot;&amp;quot;, -1 );&lt;br /&gt;
    mainview-&amp;gt;file_name = NULL;&lt;br /&gt;
    mainview-&amp;gt;file_edited = FALSE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
N.B. The &amp;lt;code&amp;gt;AppUIData&amp;lt;/code&amp;gt; struct variable &amp;lt;code&amp;gt;mainview&amp;lt;/code&amp;gt; is retrieved in such a way that the handlers can have a direct effect on the UI for the users.&lt;br /&gt;
&lt;br /&gt;
MaemoPad contains many functions:&lt;br /&gt;
&lt;br /&gt;
* File Save/Save-As/Open: This uses &amp;lt;code&amp;gt;HildonFileChooserDialog&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Edit Cut/Copy/Paste: This uses the clipboard ([[Documentation/Maemo 5 Developer Guide/Using Data Sharing/Clipboard Usage|clipboard usage]])&lt;br /&gt;
* Font/Color Selector: These are explained in &amp;lt;code&amp;gt;HildonFontSelectionDialog&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;HildonColorChooser&amp;lt;/code&amp;gt;.&lt;br /&gt;
* [[Documentation/Maemo 5 Developer Guide/Using Data Sharing/Sharing Plug-in#Writing .22Send Via.22 Functionality to E-mail and Bluetooth|Send via Email/Bluetooth]]&lt;br /&gt;
&lt;br /&gt;
=== interface.h ===&lt;br /&gt;
&lt;br /&gt;
In the interface header file &amp;lt;code&amp;gt;interface.h&amp;lt;/code&amp;gt;, public functions are defined for &amp;lt;code&amp;gt;main.c&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;callbacks.c&amp;lt;/code&amp;gt;. In the case of MaemoPad, confirmation responses for the save changes note, &amp;lt;code&amp;gt;MaemopadError&amp;lt;/code&amp;gt; enum for the Hildon error note and the &amp;lt;code&amp;gt;AppUIData&amp;lt;/code&amp;gt; are also defined here. &#039;&#039;&#039;N.B.&#039;&#039;&#039; &amp;lt;code&amp;gt;AppUIData&amp;lt;/code&amp;gt; can also be defined in &amp;lt;code&amp;gt;appdata.h&amp;lt;/code&amp;gt; in some other applications. MaemoPad&#039;s &amp;lt;code&amp;gt;interface.h&amp;lt;/code&amp;gt; looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define MAIN_VIEW_NAME &amp;quot;AppUIData&amp;quot;&lt;br /&gt;
typedef enum {&lt;br /&gt;
    MAEMOPAD_NO_ERROR = 0,&lt;br /&gt;
    MAEMOPAD_ERROR_INVALID_URI,&lt;br /&gt;
    MAEMOPAD_ERROR_SAVE_FAILED,&lt;br /&gt;
    MAEMOPAD_ERROR_OPEN_FAILED&lt;br /&gt;
} MaemopadError;&lt;br /&gt;
/* Struct to include view&#039;s information */&lt;br /&gt;
typedef struct _AppUIData AppUIData;&lt;br /&gt;
struct _AppUIData&lt;br /&gt;
{&lt;br /&gt;
    /* Handle to app&#039;s data */&lt;br /&gt;
    AppData *data;&lt;br /&gt;
    /* Fullscreen mode is on (TRUE) or off (FALSE) */&lt;br /&gt;
    gboolean fullscreen;&lt;br /&gt;
    /* Items for menu */&lt;br /&gt;
    GtkWidget *file_item;&lt;br /&gt;
    GtkWidget *new_item;&lt;br /&gt;
    /* ... */&lt;br /&gt;
    GtkWidget *font_item;&lt;br /&gt;
    GtkWidget *fullscreen_item;&lt;br /&gt;
    /* Toolbar */&lt;br /&gt;
    GtkWidget* toolbar;&lt;br /&gt;
    GtkWidget* iconw;&lt;br /&gt;
    GtkToolItem* new_tb;&lt;br /&gt;
    GtkToolItem* open_tb;&lt;br /&gt;
    /* ... */&lt;br /&gt;
    /* Textview related */&lt;br /&gt;
    GtkWidget* scrolledwindow;   /* textview is under this widget */&lt;br /&gt;
    GtkWidget* textview;         /* widget that shows the text */&lt;br /&gt;
    GtkTextBuffer* buffer;       /* buffer that contains the text */&lt;br /&gt;
    GtkClipboard* clipboard;     /* clipboard for copy/paste */&lt;br /&gt;
    PangoFontDescription* font_desc;    /* font used in textview */&lt;br /&gt;
    gboolean file_edited;     /* tells is our file on view edited */&lt;br /&gt;
    gchar* file_name;         /* directory/file under editing */&lt;br /&gt;
};&lt;br /&gt;
/* Public functions: */&lt;br /&gt;
AppUIData* interface_main_view_new( AppData* data );&lt;br /&gt;
void interface_main_view_destroy( AppUIData* main );&lt;br /&gt;
char* interface_file_chooser( AppUIData* main, GtkFileChooserAction action );&lt;br /&gt;
PangoFontDescription* interface_font_chooser( AppUIData * main );&lt;br /&gt;
/* ... */&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Localization ==&lt;br /&gt;
&lt;br /&gt;
Localization means translating the application into different languages. In Maemo, this is fairly easily performed by grouping all the strings needing translations into a .po file, giving them each an id, and then using the id in the code instead of hard-coded strings. The function used to generate the translated strings from an id in Maemo is the standard GNU &amp;lt;code&amp;gt;gettext()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Initialization ===&lt;br /&gt;
&lt;br /&gt;
When the application runs, &amp;lt;code&amp;gt;gettext()&amp;lt;/code&amp;gt; is used to determine the correct language depending on the locale settings. The application initializes the text domain as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int main( int argc, char* argv[] )&lt;br /&gt;
{&lt;br /&gt;
    /* ... */&lt;br /&gt;
    /* Initialize the locale stuff */&lt;br /&gt;
    setlocale ( LC_ALL, &amp;quot;&amp;quot; );&lt;br /&gt;
    bindtextdomain ( GETTEXT_PACKAGE, LOCALEDIR );&lt;br /&gt;
    bind_textdomain_codeset(GETTEXT_PACKAGE, &amp;quot;UTF-8&amp;quot;);&lt;br /&gt;
    textdomain ( GETTEXT_PACKAGE );&lt;br /&gt;
    /* ... */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More information on localization can be found in the [[Documentation/Maemo 5 Developer Guide/Application Development/Maemo Localization|Maemo localization]] section.&lt;br /&gt;
&lt;br /&gt;
=== File structure ===&lt;br /&gt;
&lt;br /&gt;
Localization files are stored in the &amp;lt;code&amp;gt;po/&amp;lt;/code&amp;gt; directory. The following files are used for MaemoPad localization:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;Makefile.am&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;POTFILES.in&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;en_GB.po&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;POTFILES.in&amp;lt;/code&amp;gt; contains the list of the source code files to be localized. In MaemoPad, only main.c and interface.c contain strings that need to be localized.&lt;br /&gt;
&lt;br /&gt;
 # List of MaemoPad source files to be localized&lt;br /&gt;
 ../src/main.c&lt;br /&gt;
 ../src/ui/interface.c&lt;br /&gt;
&lt;br /&gt;
File &amp;lt;code&amp;gt;en_GB.po&amp;lt;/code&amp;gt; includes translated text for British English. It contains pairs of id/string as follows:&lt;br /&gt;
&lt;br /&gt;
 # ...&lt;br /&gt;
 msgid &amp;quot;maemopad_yes&amp;quot;&lt;br /&gt;
 msgstr &amp;quot;Yes&amp;quot;&lt;br /&gt;
 # ...&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;N.B.&#039;&#039;&#039; The comments in .po file start with ``#``.&lt;br /&gt;
&lt;br /&gt;
=== Using en_GB.po ===&lt;br /&gt;
&lt;br /&gt;
The msgid(s) are passed to the GNU &amp;lt;code&amp;gt;gettext()&amp;lt;/code&amp;gt; function as a parameter to generate the translated string. In Maemo, the recommended way is&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define _(String) gettext(String)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Therefore, in MaemoPad, the string for Menu-&amp;amp;gt;File-&amp;amp;gt;Open menu is created as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
main-&amp;gt;open_item = gtk_menu_item_new_with_label ( _(&amp;quot;Open&amp;quot;) );&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Creating .po files from source ====&lt;br /&gt;
&lt;br /&gt;
Sometimes code must be localized for applications that were not originally designed for localization. You can create .po files from source code using [http://www.gnu.org/software/gettext/ GNU xgettext], by extracting all the strings from the source files into a &amp;lt;code&amp;gt;template.po&amp;lt;/code&amp;gt; file&lt;br /&gt;
&lt;br /&gt;
 xgettext -f POTFILES.in -C -a -o template.po&lt;br /&gt;
&lt;br /&gt;
Read the man page for xgettext for more information, in short:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;-f POTFILES.in&amp;lt;/code&amp;gt; uses &amp;lt;code&amp;gt;POTFILES.in&amp;lt;/code&amp;gt; to get the files to be localized&lt;br /&gt;
* &amp;lt;code&amp;gt;-C&amp;lt;/code&amp;gt; is for C-code type of strings&lt;br /&gt;
* &amp;lt;code&amp;gt;-a&amp;lt;/code&amp;gt; is for ensuring that we get all strings from specified files&lt;br /&gt;
* &amp;lt;code&amp;gt;-o template.po&amp;lt;/code&amp;gt; defines the output filename.&lt;br /&gt;
&lt;br /&gt;
The next step is to copy this &amp;lt;code&amp;gt;template.po&amp;lt;/code&amp;gt; into &amp;lt;code&amp;gt;./po/en_GB.po&amp;lt;/code&amp;gt; and add or edit all the strings in British English. Other languages can be handled in the same way.&lt;br /&gt;
&lt;br /&gt;
== Adding application to menu ==&lt;br /&gt;
&lt;br /&gt;
In short, the &amp;lt;code&amp;gt;maemopad.desktop&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;com.nokia.maemopad.service&amp;lt;/code&amp;gt; files are stored in the &amp;lt;code&amp;gt;./data&amp;lt;/code&amp;gt; directory, and they look like this, respectively:&lt;br /&gt;
&lt;br /&gt;
 [Desktop Entry]&lt;br /&gt;
 Encoding=UTF-8&lt;br /&gt;
 Version=0.1&lt;br /&gt;
 Type=Application&lt;br /&gt;
 Name=MaemoPad&lt;br /&gt;
 Exec=/usr/bin/maemopad&lt;br /&gt;
 Icon=maemopad&lt;br /&gt;
 X-Window-Icon=maemopad&lt;br /&gt;
 X-Window-Icon-Dimmed=maemopad&lt;br /&gt;
 X-Osso-Service=com.nokia.maemopad&lt;br /&gt;
 X-Osso-Type=application/x-executable&lt;br /&gt;
&lt;br /&gt;
(&#039;&#039;&#039;N.B.&#039;&#039;&#039; Whitespace is not allowed after the lines.)&lt;br /&gt;
&lt;br /&gt;
 # Service description file&lt;br /&gt;
 [D-BUS Service]&lt;br /&gt;
 Name=com.nokia.maemopad&lt;br /&gt;
 Exec=/usr/bin/maemopad&lt;br /&gt;
&lt;br /&gt;
These files reside on the device here:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;/usr/share/applications/hildon&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;/usr/share/dbus-1/services&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When the Debian package is installed to Maemo platform, .desktop and .service files are used to link MaemoPad to the Task Navigator.&lt;br /&gt;
&lt;br /&gt;
== Packaging the application ==&lt;br /&gt;
&lt;br /&gt;
{{main|Packaging}}&lt;br /&gt;
&lt;br /&gt;
A Debian package is an application packed in one file to make installing easy in Debian-based operating systems, like Maemo platform. More information about creating a Debian packages can be found in the [[Documentation/Maemo 5 Developer Guide/Packaging%2C Deploying and Distributing#Creating Debian Packages|creating Debian packages]] section of the [[Documentation/Maemo 5 Developer Guide/Packaging, Deploying and Distributing|Packaging, Deploying and Distributing chapter]]. Our goal in this section is to create a Debian package of MaemoPad, to be installed in the Maemo platform.&lt;br /&gt;
&lt;br /&gt;
If creating a package that can be installed using the Application Manager, be sure that the package is in an [[Documentation/Maemo 5 Developer Guide/Packaging%2C Deploying and Distributing#Sections|allowed section]].&lt;br /&gt;
&lt;br /&gt;
=== Creating debian/ Directory ===&lt;br /&gt;
&lt;br /&gt;
In order to create the package, the following files are created in the &amp;lt;code&amp;gt;debian/&amp;lt;/code&amp;gt; directory:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;changelog&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;control&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;copyright&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;rules&amp;lt;/code&amp;gt;&lt;br /&gt;
* ... etc ...&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;rules&amp;lt;/code&amp;gt; file is the file defining how the Debian package is built. The &amp;lt;code&amp;gt;rules&amp;lt;/code&amp;gt; file tells where the files should be installed. Also a &amp;lt;code&amp;gt;control&amp;lt;/code&amp;gt; file is needed to define what kind of packages (often different language versions) are going to be created. &amp;lt;code&amp;gt;changelog&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;copyright&amp;lt;/code&amp;gt; files are also needed, or the package does not build. The &amp;lt;code&amp;gt;changelog&amp;lt;/code&amp;gt; file consists of the version number of the package, and a short description about changes compared to older versions. The &amp;lt;code&amp;gt;copyright&amp;lt;/code&amp;gt; file includes information in plain text about the package copyrights.&lt;br /&gt;
&lt;br /&gt;
Most important lines in rules file are:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Add here commands to install the package into debian/&amp;lt;installation directory&amp;gt;&lt;br /&gt;
$(MAKE) install DESTDIR=$(CURDIR)/debian/&amp;lt;installation directory&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These lines define where the package files are installed. &amp;lt;code&amp;gt;debian/&amp;lt;installation directory&amp;gt;&amp;lt;/code&amp;gt; is used as a temporary directory for package construction.&lt;br /&gt;
&lt;br /&gt;
=== Creating and building the package ===&lt;br /&gt;
&lt;br /&gt;
The package is made using the following command:&lt;br /&gt;
&lt;br /&gt;
 dpkg-buildpackage -rfakeroot -uc -us -sa -D&lt;br /&gt;
&lt;br /&gt;
The result should be these MaemoPad files:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;maemopad_x.x.dsc&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;maemopad_x.x.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;maemopad_x.x_i386.changes&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;maemopad_x.x_i386.deb&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A .deb file now exists. This package can be installed using:&lt;br /&gt;
 fakeroot dpkg -i maemopad_x.x_i386.deb&lt;br /&gt;
The icon to the application should now be in the Maemo Task Navigator menu, and it should be launchable from there. To remove the package, use the command&lt;br /&gt;
 fakeroot dpkg -r maemopad&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;br /&gt;
[[Category:Documentation]]&lt;br /&gt;
[[Category:Fremantle]]&lt;/div&gt;</summary>
		<author><name>88.114.203.150</name></author>
	</entry>
</feed>