Editing Documentation/Maemo 5 Developer Guide/Porting Software/Porting MaemoPad

Warning: You are not logged in. Your IP address will be recorded in this page's edit history.
The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then save the changes below to finish undoing the edit.
Latest revision Your text
Line 1: Line 1:
-
This is a practical example of porting a [[Open development/Maemo roadmap/Diablo|Diablo]] (Maemo 4.1) application to [[Open development/Maemo roadmap/Fremantle|Fremantle]] (Maemo 5). The example application, MaemoPad, is a simple Notepad-like editor.
+
== Porting MaemoPad ==
-
[[Image:maemopad.png|frame|center|alt=Screenshot of MaemoPad|MaemoPad main window]]
+
This is a practical example of porting a Diablo (Maemo 4.1) application to Fremantle (Maemo 5). The example application, MaemoPad, is a simple Notepad-like editor.
 +
<div align="CENTER">
-
== Porting MaemoPad from Diablo to Fremantle  ==
+
{| summary="MaemoPad"
 +
|+ align="BOTTOM" |'''Figure:''' MaemoPad
 +
|-
 +
|
 +
<div align="CENTER">[[Image:maemopad.png|Image maemopad]]</div>
 +
|}
-
Porting from Diablo to Fremantle involved mostly changes in GTK+- and Hildon-specific parts of the code, because newer versions of these libraries are now in use, and because of the new Fremantle GUI guidelines. This subsection will first explain how to install MaemoPad, and then proceeds to describing the main changes in the code. The reader is recommended to familiarize with chapters [[Documentation/Maemo 5 Developer Guide/Application Development|Application Development]] and [[Documentation/Maemo 5 Developer Guide/Human Interface Guidelines|Human Interface Guidelines]] before this one. For reference, see GTK+ and Hildon APIs from [http://maemo.org/development/sdks/maemo_5_api_documentation/ Maemo Fremantle APIs].
+
</div>
 +
 
 +
Porting from Diablo to Fremantle involved mostly changes in GTK+- and Hildon-specific parts of the code, because newer versions of these libraries are now in use, and because of the new Fremantle GUI guidelines. This subsection will first explain how to install MaemoPad, and then proceeds to describing the main changes in the code. The reader is recommended to familiarize with chapters Application Development[/node7.html#chap:application_dev [[Image:crossref.png|[*]]]] and Hildon Human Interface Guidelines[/node12.html#chap:Hildon_Human_Interface_Guidelines [[Image:crossref.png|[*]]]] before this one. For reference, see GTK+ and Hildon APIs from [http://maemo.org/development/sdks/maemo_5_api_documentation/ Maemo Fremantle APIs].
=== Installing MaemoPad ===
=== Installing MaemoPad ===
-
MaemoPad can be installed and tested in the Scratchbox environment.
+
MaemoPad can be installed and tested in the scratchbox environment.
* If not already activated, activate the X86 target, go to the testing directory, and download the source package of maemopad application.
* If not already activated, activate the X86 target, go to the testing directory, and download the source package of maemopad application.
   
   
-
<pre>
+
[sbox-FREMANTLE_ARMEL] sb-conf select FREMANTLE_X86
-
[sbox-FREMANTLE_ARMEL] > sb-conf select FREMANTLE_X86
+
[sbox-FREMANTLE_X86 ~] mkdir maemopad
-
[sbox-FREMANTLE_X86 ~] > mkdir maemopad
+
[sbox-FREMANTLE_X86 ~/maemopad] cd maemopad
-
[sbox-FREMANTLE_X86 ~/maemopad] > cd maemopad
+
[sbox-FREMANTLE_X86 ~/maemopad] apt-get source maemopad
-
[sbox-FREMANTLE_X86 ~/maemopad] > apt-get source maemopad
+
...apt output...
-
...apt output...
+
-
</pre>
+
* Check that you have the correct files.
* Check that you have the correct files.
-
 
+
-
<pre>
+
[sbox-FREMANTLE_X86: ~/maemopad] &gt; ls -l
-
[sbox-FREMANTLE_X86: ~/maemopad] > ls -l
+
total 352
-
total 352
+
drwxrwxr-x  6 maemo maemo  4096 Jul 28 14:09 maemopad-2.5
-
drwxrwxr-x  6 maemo maemo  4096 Jul 28 14:09 maemopad-2.5
+
-rw-rw-r--  1 maemo maemo    465 Jul  6 16:02 maemopad_2.5.dsc
-
-rw-rw-r--  1 maemo maemo    465 Jul  6 16:02 maemopad_2.5.dsc
+
-rw-rw-r--  1 maemo maemo 346129 Jul  6 16:02 maemopad_2.5.tar.gz
-
-rw-rw-r--  1 maemo maemo 346129 Jul  6 16:02 maemopad_2.5.tar.gz
+
-
</pre>
+
* Go to the <code>maemopad-2.5</code> source directory, and build the maemopad package with <code>dpkg-buildpackage</code> command as shown here:
* Go to the <code>maemopad-2.5</code> source directory, and build the maemopad package with <code>dpkg-buildpackage</code> command as shown here:
-
 
+
-
<pre>
+
[sbox-FREMANTLE_X86: ~/maemopad] &gt; cd maemopad-2.5
-
[sbox-FREMANTLE_X86: ~/maemopad] > cd maemopad-2.5
+
[sbox-FREMANTLE_X86: ~/maemopad/maemopad-2.5] &gt; dpkg-buildpackage -rfakeroot
-
[sbox-FREMANTLE_X86: ~/maemopad/maemopad-2.5] &gt; dpkg-buildpackage -rfakeroot
+
dpkg-buildpackage: source package is maemopad
-
dpkg-buildpackage: source package is maemopad
+
dpkg-buildpackage: source version is 2.5
-
dpkg-buildpackage: source version is 2.5
+
dpkg-buildpackage: source changed by Soumya Bijjal &lt;soumya.3.bijjal@nokia.com&gt;
-
dpkg-buildpackage: source changed by Soumya Bijjal &lt;soumya.3.bijjal@nokia.com&gt;
+
dpkg-buildpackage: host architecture i386
-
dpkg-buildpackage: host architecture i386
+
dpkg-buildpackage: source version without epoch 2.3
-
dpkg-buildpackage: source version without epoch 2.3
+
.... etc ....
-
.... etc ....
+
-
</pre>
+
* Install the newly compiled <code>maemopad_2.5_i386.deb</code> file inside the Scratchbox environment:
* Install the newly compiled <code>maemopad_2.5_i386.deb</code> file inside the Scratchbox environment:
-
 
+
-
<pre>
+
[sbox-FREMANTLE_X86: ~/maemopad] &gt; dpkg -i maemopad_2.5_i386.deb
-
[sbox-FREMANTLE_X86: ~/maemopad] > dpkg -i maemopad_2.5_i386.deb
+
... output from dpkg ...
-
... output from dpkg ...
+
-
</pre>
+
* Make sure you have the SDK UI running in Xephyr.
* Make sure you have the SDK UI running in Xephyr.
Line 57: Line 57:
The MaemoPad source code resides in folder <code>maemopad-2.5/src:</code>
The MaemoPad source code resides in folder <code>maemopad-2.5/src:</code>
-
<pre>
+
-
[sbox-FREMANTLE_X86: ~/maemopad] ls maemopad-2.5/src
+
[sbox-FREMANTLE_X86: ~/maemopad] ls maemopad-2.5/src
-
total 280
+
total 280
-
-rw-rw-r--  1 maemo maemo 25491 Jul 28 15:45 Makefile
+
-rw-rw-r--  1 maemo maemo 25491 Jul 28 15:45 Makefile
-
-rw-rw-r--  1 maemo maemo  491 Jul 28 14:09 Makefile.am
+
-rw-rw-r--  1 maemo maemo  491 Jul 28 14:09 Makefile.am
-
-rw-rw-r--  1 maemo maemo 23238 Jul 28 14:09 Makefile.in
+
-rw-rw-r--  1 maemo maemo 23238 Jul 28 14:09 Makefile.in
-
-rwxrwxr-x  1 maemo maemo 83433 Jul 28 15:45 maemopad
+
-rwxrwxr-x  1 maemo maemo 83433 Jul 28 15:45 maemopad
-
-rw-rw-r--  1 maemo maemo 82928 Jul 28 15:45 maemopad-maemopad-window.o
+
-rw-rw-r--  1 maemo maemo 82928 Jul 28 15:45 maemopad-maemopad-window.o
-
-rw-rw-r--  1 maemo maemo 18564 Jul 28 15:45 maemopad-main.o
+
-rw-rw-r--  1 maemo maemo 18564 Jul 28 15:45 maemopad-main.o
-
-rw-rw-r--  1 maemo maemo 20400 Jul 28 14:09 maemopad-window.c
+
-rw-rw-r--  1 maemo maemo 20400 Jul 28 14:09 maemopad-window.c
-
-rw-rw-r--  1 maemo maemo  2391 Jul 28 14:09 maemopad-window.h
+
-rw-rw-r--  1 maemo maemo  2391 Jul 28 14:09 maemopad-window.h
-
-rw-rw-r--  1 maemo maemo  2193 Jul 28 14:09 main.c
+
-rw-rw-r--  1 maemo maemo  2193 Jul 28 14:09 main.c
-
</pre>
+
For comparison, the Diablo version of MaemoPad can also be examined:
For comparison, the Diablo version of MaemoPad can also be examined:
-
<pre>
+
-
[sbox-FREMANTLE_X86: ~/maemopad] &gt; svn export https://vcs.maemo.org/svn/\
+
[sbox-FREMANTLE_X86: ~/maemopad] &gt; svn export https://garage.maemo.org/svn/\
-
maemoexamples/tags/maemo_4.1/maemopad diablo_maemopad
+
maemoexamples/tags/maemo_4.1/maemopad diablo_maemopad
-
[sbox-FREMANTLE_X86: ~/src] ls -lR diablo_maemopad/src
+
[sbox-FREMANTLE_X86: ~/src] ls -lR diablo_maemopad/src
-
diablo_maemopad/src/:
+
diablo_maemopad/src/:
-
total 16
+
total 16
-
-rw-rw-r--  1 maemo maemo  537 May 15  2008 Makefile.am
+
-rw-rw-r--  1 maemo maemo  537 May 15  2008 Makefile.am
-
-rw-rw-r--  1 maemo maemo  557 May 15  2008 appdata.h
+
-rw-rw-r--  1 maemo maemo  557 May 15  2008 appdata.h
-
-rw-rw-r--  1 maemo maemo 2789 Dec  3  2008 main.c
+
-rw-rw-r--  1 maemo maemo 2789 Dec  3  2008 main.c
-
drwxrwxr-x  2 maemo maemo 4096 Aug 20 11:53 ui
+
drwxrwxr-x  2 maemo maemo 4096 Aug 20 11:53 ui
 +
 +
diablo_maemopad/src/ui:
 +
total 36
 +
-rw-rw-r--  1 maemo maemo 12163 Dec  3  2008 callbacks.c
 +
-rw-rw-r--  1 maemo maemo  1682 Oct 29  2008 callbacks.h
 +
-rw-rw-r--  1 maemo maemo 14982 Dec  3  2008 interface.c
 +
-rw-rw-r--  1 maemo maemo  2695 Dec  3  2008 interface.h
-
diablo_maemopad/src/ui:
 
-
total 36
 
-
-rw-rw-r--  1 maemo maemo 12163 Dec  3  2008 callbacks.c
 
-
-rw-rw-r--  1 maemo maemo  1682 Oct 29  2008 callbacks.h
 
-
-rw-rw-r--  1 maemo maemo 14982 Dec  3  2008 interface.c
 
-
-rw-rw-r--  1 maemo maemo  2695 Dec  3  2008 interface.h
 
-
</pre>
 
=== Code reorganization ===
=== Code reorganization ===
Line 103: Line 102:
=== Device-specific changes ===
=== Device-specific changes ===
-
The previous device, N810, had a separate full-screen and ESC keys that were dropped from the new device. In MaemoPad, pressing the full-screen key was replaced by Ctrl-F. This required the following addition:
+
The previous device, N810, had a separate full-screen and ESC keys that were dropped from the new device. In MaemoPad, pressing the full-screen key was replaced by Ctrl-F. This required the following addition
-
maemopad-window.c  
+
* maemopad-window.c  
-
<source lang="c">
+
 
-
#include <gdk/gdkkeysyms.h>
+
#include <gdk/gdkkeysyms.h>
-
</source>
+
to include GDK definition for key "f", <code>GDK_f</code> to replace the earlier <code>HILDON_HARDKEY_FULLSCREEN</code>. Callback for Esc was completely removed. The full-screen action itself was principally unchanged. The key event function was modified correspondingly:
to include GDK definition for key "f", <code>GDK_f</code> to replace the earlier <code>HILDON_HARDKEY_FULLSCREEN</code>. Callback for Esc was completely removed. The full-screen action itself was principally unchanged. The key event function was modified correspondingly:
-
Diablo callbacks.c
+
* Diablo callbacks.c  
-
<source lang="c">
+
 
-
gboolean key_press(GtkWidget * widget, GdkEventKey * event,
+
gboolean key_press(GtkWidget * widget, GdkEventKey * event,
-
                  gpointer data)
+
                      gpointer data)
-
{
+
{
-
    ...
+
    ...
-
  if (event->keyval == HILDON_HARDKEY_FULLSCREEN && !keypressed){
+
    if (event->keyval == HILDON_HARDKEY_FULLSCREEN && !keypressed){
-
        keypressed = TRUE;
+
        keypressed = TRUE;
-
    ...
+
    ...
-
    if (event->keyval == HILDON_HARDKEY_ESC && !keypressed){
+
    if (event->keyval == HILDON_HARDKEY_ESC && !keypressed){
-
        keypressed = TRUE;
+
        keypressed = TRUE;
-
    ...
+
    ...
-
</source>
+
 
 +
* Fremantle maemopad-window.c
-
Fremantle maemopad-window.c
+
static gboolean maemopad_window_on_key_press(GtkWidget *widget, GdkEventKey *event,
 +
                      gpointer data)
 +
{
 +
    ...
 +
    if (event->keyval == GDK_f && (event->state & GDK_CONTROL_MASK) && !self- >key_pressed) {
 +
        self->key_pressed = TRUE;
 +
    ...
-
<source lang="c">
 
-
static gboolean maemopad_window_on_key_press(GtkWidget *widget, GdkEventKey *event,
 
-
                                            gpointer data)
 
-
{
 
-
    ...
 
-
    if (event->keyval == GDK_f && (event->state & GDK_CONTROL_MASK) && !self- >key_pressed) {
 
-
        self->key_pressed = TRUE;
 
-
    ...
 
-
</source>
 
=== Dropped libraries ===
=== Dropped libraries ===
Line 142: Line 138:
Hildon help library, libhildonhelp, was dropped from Fremantle so all dependencies to it had to be removed.
Hildon help library, libhildonhelp, was dropped from Fremantle so all dependencies to it had to be removed.
-
libhildonhelp-dev needs to removed from build dependencies:
+
libhildonhelp-dev needs to removed from build depencies:
Diablo: debian/control:
Diablo: debian/control:
-
<pre>
+
-
Build-Depends: debhelper (&gt;= 4.0.0), intltool,
+
Build-Depends: debhelper (&gt;= 4.0.0), intltool,
-
libhildon1-dev, libgtk2.0-dev, libosso-gnomevfs2-dev,
+
  libhildon1-dev, libgtk2.0-dev, libosso-gnomevfs2-dev,
-
libglib2.0-dev, libdbus-glib-1-dev, libosso-dev, libmodest-dbus-client-dev,
+
  libglib2.0-dev, libdbus-glib-1-dev, libosso-dev, libmodest-dbus-client-dev,
-
conbtdialogs-dev,libhildonhelp-dev, libhildonfm2-dev, osso-af-settings
+
  conbtdialogs-dev,libhildonhelp-dev, libhildonfm2-dev, osso-af-settings
-
</pre>
+
Fremantle: debian/control:
Fremantle: debian/control:
-
<pre>
+
-
Build-Depends: debhelper (&gt;= 4.0.0), intltool,
+
Build-Depends: debhelper (&gt;= 4.0.0), intltool,
-
libhildon1-dev, libgtk2.0-dev, libosso-gnomevfs2-dev,
+
  libhildon1-dev, libgtk2.0-dev, libosso-gnomevfs2-dev,
-
libglib2.0-dev, libdbus-glib-1-dev, libosso-dev, libmodest-dbus-client-dev,
+
  libglib2.0-dev, libdbus-glib-1-dev, libosso-dev, libmodest-dbus-client-dev,
-
conbtdialogs-dev,  libhildonfm2-dev, osso-af-settings
+
  conbtdialogs-dev,  libhildonfm2-dev, osso-af-settings
-
</pre>
+
 
Callback and all other help stuff removed:
Callback and all other help stuff removed:
-
Diablo callbacks.c  
+
* Diablo callbacks.c  
-
<source lang="c">
+
/* help */
-
/* help */
+
void callback_help( GtkAction * action, gpointer data )
-
void callback_help( GtkAction * action, gpointer data )
+
{
-
{
+
    osso_return_t retval;
-
    osso_return_t retval;
+
    /* connect pointer to our AppUIData struct */
-
    /* connect pointer to our AppUIData struct */
+
    AppUIData *mainview = NULL;
-
    AppUIData *mainview = NULL;
+
    mainview = ( AppUIData * ) data;
-
    mainview = ( AppUIData * ) data;
+
    g_assert(mainview != NULL && mainview->data != NULL );
-
    g_assert(mainview != NULL && mainview->data != NULL );
+
    retval = hildon_help_show(
-
    retval = hildon_help_show(
+
      mainview->data->osso, /* osso_context */
-
      mainview->data->osso, /* osso_context */
+
      HELP_TOPIC_ID,        /* topic id */
-
      HELP_TOPIC_ID,        /* topic id */
+
      HILDON_HELP_SHOW_DIALOG);
-
      HILDON_HELP_SHOW_DIALOG);
+
}
-
}
+
-
</source>
+
-
Diablo interface.c  
+
* Diablo interface.c  
-
<source lang="c">
+
GtkWidget *help = NULL;
-
GtkWidget *help = NULL;
+
help = gtk_menu_item_new_with_label( _("Help") );
-
help = gtk_menu_item_new_with_label( _("Help") );
+
gtk_menu_append( main_menu, help );
-
gtk_menu_append( main_menu, help );
+
g_signal_connect( G_OBJECT( help ), "activate",  
-
g_signal_connect( G_OBJECT( help ), "activate",  
+
G_CALLBACK ( callback_help ), main );
-
  G_CALLBACK ( callback_help ), main );
+
-
</source>
+
-
Diablo callbacks.c  
+
* Diablo callbacks.c  
-
<source lang="c">
+
#include <hildon/hildon-help.h>
-
#include <hildon/hildon-help.h>
+
#define HELP_TOPIC_ID "Example_MaemoPad_Content"
-
#define HELP_TOPIC_ID "Example_MaemoPad_Content"
+
-
</source>
+
-
Diablo configure.ac:
 
-
<source lang="autoconf">
+
* Diablo configure.ac:
-
PKG_CHECK_MODULES(HILDON, hildon-1 hildon-fm-2 hildon-help conbtdialogs)
+
-
</source>
+
-
Fremantle configure.ac:
 
-
<source lang="c">
+
-
PKG_CHECK_MODULES(HILDON, hildon-1 hildon-fm-2 conbtdialogs)
+
PKG_CHECK_MODULES(HILDON, hildon-1 hildon-fm-2 hildon-help conbtdialogs)
-
</source>
+
 
 +
 
 +
* Fremantle configure.ac:
 +
 +
PKG_CHECK_MODULES(HILDON, hildon-1 hildon-fm-2 conbtdialogs)
 +
 
Removed data/help directory which contained an example help file.
Removed data/help directory which contained an example help file.
Line 215: Line 205:
Some files contained items related to it and they were also removed:
Some files contained items related to it and they were also removed:
-
Diablo data/Makefile.am:
+
* Diablo data/Makefile.am:
 +
 +
helpfile_engb_DATA = help/en_GB/MaemoPad.xml
 +
-EXTRA_DIST = $(serviceentry_DATA) $(desktopentry_DATA) $(icon_26x26_DATA) $(icon_40x40_DATA)
 +
$(icon_scalable_DATA) *$(helpfile_engb_DATA)*
-
<source lang="make">
 
-
helpfile_engb_DATA = help/en_GB/MaemoPad.xml
 
-
-EXTRA_DIST = $(serviceentry_DATA) $(desktopentry_DATA) $(icon_26x26_DATA) $(icon_40x40_DATA)
 
-
$(icon_scalable_DATA) *$(helpfile_engb_DATA)*
 
-
</source>
 
Diablo data/Makefile.am:
Diablo data/Makefile.am:
-
<source lang="make">
+
<nowiki>
-
# Help file install directory
+
# Help file install directory
-
helpfile_engbdir=$datadir/hildon-help/en_GB
+
helpfile_engbdir=$datadir/hildon-help/en_GB
-
AC_SUBST(helpfile_engbdir)
+
AC_SUBST(helpfile_engbdir) NOT YET
-
</source>
+
</nowiki>
=== GUI design changes ===
=== GUI design changes ===
-
Because of new UI guidelines, a toolbar that was at the bottom of the MaemoPadwindow in Diablo was dropped. This meant removing the function <code>create_toolbar</code> and its declaration from <code>interface.c</code>. Also the call for the function was dropped from the same file. Likewise, related declarations were dropped:
+
Because of new UI guidelines, a toolbar that was at the bottom of the MaemoPadwindow in Diablo was dropped. This meant removing the function <code>create_toolbar</code> from <code>interface.c</code>, line 282 and its declaration on line 47 of the same file. Also the call for the function was dropped from the same file. Likewise, related declarations were dropped:
-
Diablo interface.h  
+
* interface.h  
-
<source lang="c">
+
/* Toolbar */
-
/* Toolbar */
+
GtkWidget* toolbar;
-
GtkWidget* toolbar;
+
GtkWidget* iconw;
-
GtkWidget* iconw;
+
GtkToolItem* new_tb;
-
GtkToolItem* new_tb;
+
GtkToolItem* open_tb;
-
GtkToolItem* open_tb;
+
...
-
...
+
GtkToolItem* fullscreen_tb;
-
GtkToolItem* fullscreen_tb;
+
-
</source>
+
-
Also the menu system was changed. In Diablo, a <code>GtkMenu</code> was used, but it was replaced with a <code>HildonAppMenu</code> in Fremantle, as shown in Figure:
 
-
[[Image:maemopad_menu.png|frame|center|alt=Screenshot of MaemoPad menu|MaemoPad menu]]
+
 
 +
Also the menu system was changed. In Diablo, a GtkMenu was used, but it was replaced with a HildonAppMenu in Fremantle, shown in Figure [localhost#fig:maemopad_menu [[Image:crossref.png|[*]]]].
 +
 
 +
<div align="CENTER">
 +
 
 +
{| summary="MaemoPad Menu"
 +
|+ align="BOTTOM" |'''Figure:''' MaemoPad Menu
 +
|-
 +
|
 +
<div align="CENTER">[[Image:maemopad_menu.png|Image maemopad_menu]]</div>
 +
|}
 +
 
 +
</div>
Function <code>create_menu()</code> is responsible for creating the menus in both versions:
Function <code>create_menu()</code> is responsible for creating the menus in both versions:
-
Diablo interface.c  
+
* Diablo interface.c  
-
<source lang="c">
+
static void create_menu( AppUIData *main )
-
static void create_menu( AppUIData *main )
+
{
-
{
+
    /* Create needed handles */
-
    /* Create needed handles */
+
    GtkMenu *main_menu;
-
    GtkMenu *main_menu;
+
    GtkWidget *file_menu, *edit_menu, *sendvia_menu;
-
    GtkWidget *file_menu, *edit_menu, *sendvia_menu;
+
    GtkWidget *separator = NULL;
-
    GtkWidget *separator = NULL;
+
    GtkWidget *close = NULL;
-
    GtkWidget *close = NULL;
+
    /* Create main menu and new menus for submenus in our drop down menu */
-
    /* Create main menu and new menus for submenus in our drop down menu */
+
    main_menu = GTK_MENU( gtk_menu_new () );
-
    main_menu = GTK_MENU( gtk_menu_new () );
+
    file_menu = gtk_menu_new ();
-
    file_menu = gtk_menu_new ();
+
    edit_menu = gtk_menu_new ();
-
    edit_menu = gtk_menu_new ();
+
    sendvia_menu = gtk_menu_new ();
-
    sendvia_menu = gtk_menu_new ();
+
    /* Create the menu items */
-
    /* Create the menu items */
+
    main->file_item = gtk_menu_item_new_with_label ( _("File") );
-
    main->file_item = gtk_menu_item_new_with_label ( _("File") );
+
    main->new_item = gtk_menu_item_new_with_label ( _("New") );
-
    main->new_item = gtk_menu_item_new_with_label ( _("New") );
+
    main->open_item = gtk_menu_item_new_with_label ( _("Open") );
-
    main->open_item = gtk_menu_item_new_with_label ( _("Open") );
+
    ...
-
    ...
+
    /* Add menu items to right menus */
-
    /* Add menu items to right menus */
+
    gtk_menu_append( main_menu, main->file_item );
-
    gtk_menu_append( main_menu, main->file_item );
+
    gtk_menu_append( file_menu, main->new_item );
-
    gtk_menu_append( file_menu, main->new_item );
+
    gtk_menu_append( file_menu, main->open_item );
-
    gtk_menu_append( file_menu, main->open_item );
+
    ...
-
    ...
+
    gtk_menu_append( main_menu, close );
-
    gtk_menu_append( main_menu, close );
+
    /* Add submenus to the right items */
-
    /* Add submenus to the right items */
+
    gtk_menu_item_set_submenu( GTK_MENU_ITEM (main->file_item), file_menu );
-
    gtk_menu_item_set_submenu( GTK_MENU_ITEM (main->file_item), file_menu );
+
    gtk_menu_item_set_submenu( GTK_MENU_ITEM (main->edit_item), edit_menu );
-
    gtk_menu_item_set_submenu( GTK_MENU_ITEM (main->edit_item), edit_menu );
+
    gtk_menu_item_set_submenu( GTK_MENU_ITEM (main->sendvia_item),  sendvia_menu );
-
    gtk_menu_item_set_submenu( GTK_MENU_ITEM (main->sendvia_item),  sendvia_menu );
+
    /* Attach the callback functions to the activate signal */
-
    /* Attach the callback functions to the activate signal */
+
    g_signal_connect( G_OBJECT( main->new_item ), "activate",  
-
    g_signal_connect( G_OBJECT( main->new_item ), "activate",  
+
      G_CALLBACK ( callback_file_new), main );
-
      G_CALLBACK ( callback_file_new), main );
+
    g_signal_connect( G_OBJECT( main->open_item ), "activate",  
-
    g_signal_connect( G_OBJECT( main->open_item ), "activate",  
+
      G_CALLBACK ( callback_file_open), main );
-
      G_CALLBACK ( callback_file_open), main );
+
    ...
-
    ...
+
    g_signal_connect( G_OBJECT( close ), "activate", gtk_main_quit, NULL );
-
    g_signal_connect( G_OBJECT( close ), "activate", gtk_main_quit, NULL );
+
    /* Add menu to HildonWindow */
-
    /* Add menu to HildonWindow */
+
    hildon_window_set_menu(main->data->window, main_menu);
-
    hildon_window_set_menu(main->data->window, main_menu);
+
    /* We need to show menu items */
-
    /* We need to show menu items */
+
    gtk_widget_show_all( GTK_WIDGET( main_menu ) );
-
    gtk_widget_show_all( GTK_WIDGET( main_menu ) );
+
}
-
}
+
-
</source>
+
-
Fremantle maemopad-window.c  
+
* Fremantle maemopad-window.c  
-
<source lang="c">
+
  static GtkWidget* add_menu_item (GtkWidget *main_menu, const gchar* title,
-
static GtkWidget* add_menu_item (GtkWidget *main_menu, const gchar* title,
+
    GCallback clicked_callback, gpointer user_data)
-
    GCallback clicked_callback, gpointer user_data)
+
{
-
{
+
  HildonAppMenu *app_menu = HILDON_APP_MENU (main_menu);
-
  HildonAppMenu *app_menu = HILDON_APP_MENU (main_menu);
+
  /* Create a button, add it, and return it: */  
-
  /* Create a button, add it, and return it: */  
+
  GtkWidget *button = hildon_button_new_with_text (HILDON_SIZE_AUTO,  
-
  GtkWidget *button = hildon_button_new_with_text (HILDON_SIZE_AUTO,  
+
        HILDON_BUTTON_ARRANGEMENT_VERTICAL, title, NULL);
-
        HILDON_BUTTON_ARRANGEMENT_VERTICAL, title, NULL);
+
  gtk_widget_show (button);
-
  gtk_widget_show (button);
+
  g_signal_connect_after (button, "clicked",  
-
  g_signal_connect_after (button, "clicked",  
+
  G_CALLBACK (clicked_callback), user_data);
-
  G_CALLBACK (clicked_callback), user_data);
+
  hildon_app_menu_append (app_menu, GTK_BUTTON (button));
-
  hildon_app_menu_append (app_menu, GTK_BUTTON (button));
+
  return button;
-
  return button;
+
}
-
}
+
/* Create the menu items needed: */
-
/* Create the menu items needed: */
+
static void create_menu (MaemopadWindow *self)
-
static void create_menu (MaemopadWindow *self)
+
{
-
{
+
  /* Create needed handles */
-
  /* Create needed handles */
+
  GtkWidget *main_menu = hildon_app_menu_new ();
-
  GtkWidget *main_menu = hildon_app_menu_new ();
+
  /* Create the menu items */
-
  /* Create the menu items */
+
  self->new_item = add_menu_item (main_menu, _("New"),
-
  self->new_item = add_menu_item (main_menu, _("New"),
+
    G_CALLBACK (&maemopad_window_on_menu_file_new), self);
-
    G_CALLBACK (&maemopad_window_on_menu_file_new), self);
+
  self->open_item = add_menu_item (main_menu, _("Open"),
-
  self->open_item = add_menu_item (main_menu, _("Open"),
+
    G_CALLBACK (&maemopad_window_on_menu_file_open), self);
-
    G_CALLBACK (&maemopad_window_on_menu_file_open), self);
+
  ...
-
  ...
+
    self->close_item = add_menu_item (main_menu, _("Close"),
-
  self->close_item = add_menu_item (main_menu, _("Close"),
+
    G_CALLBACK (&maemopad_window_on_menu_close), self);
-
    G_CALLBACK (&maemopad_window_on_menu_close), self);
+
  /* Add menu to HildonWindow */
-
  /* Add menu to HildonWindow */
+
  hildon_window_set_app_menu (
-
  hildon_window_set_app_menu (
+
    HILDON_WINDOW (self),
-
    HILDON_WINDOW (self),
+
    HILDON_APP_MENU (main_menu));
-
    HILDON_APP_MENU (main_menu));
+
  /* We need to show menu items */
-
  /* We need to show menu items */
+
  gtk_widget_show_all (GTK_WIDGET (main_menu));
-
  gtk_widget_show_all (GTK_WIDGET (main_menu));
+
}
-
}
+
-
</source>
+
-
As a result to changes in the .c file, the following menu widget declarations used in Diablo became unnecessary:
 
-
Diablo interface.h
 
-
<source lang="c">
+
As a result to changes in the .c file, the following menu widget declarations used in Diablo became unnecessary:
-
GtkWidget *file_item;
+
-
GtkWidget *edit_item;
+
-
GtkWidget *sendvia_item;
+
-
</source>
+
-
Menu callbacks were also changed. There were some changes in the callbacks themselves as a result of code reorganizations, but the main change from the menu viewpoint was that the 1st arguments of the callbacks were changed from <code>GtkAction</code> to <code>GtkButton</code>, like in the following example:
+
* interface.h
-
Diablo callbacks.c
+
GtkWidget *file_item;
 +
GtkWidget *edit_item;
 +
GtkWidget *sendvia_item;
-
<source lang="c">
 
-
void callback_file_new(GtkAction * action, gpointer data)
 
-
</source>
 
-
Fremantle maemopad-window.c
 
-
<source lang="c">
+
Menu callbacks were also changed. There were some changes in the callbacks themselves as a result of code reorganizations, but the main change from the menu viewpoint was that the 1st arguments of the callbacks were changed from GtkAction to GtkButton, like in the following example.
-
static void maemopad_window_on_menu_file_new (GtkButton *button, gpointer data)
+
-
</source>
+
-
=== Other updates in GTK+ and Hildon ===
+
* Diablo callbacks.c
-
<ul>
+
void callback_file_new(GtkAction * action, gpointer data)
-
<li>
+
-
Rich text support was changed with the new GTK+, as described in [http://live.gnome.org/Maemo/Gtk210Migration Maemo-GTK+ 2.6 to 2.10 Migration].This required editing two lines:
+
-
Part of function <code>create_textarea()</code> in Diablo interface.c  
+
* Fremantle maemopad-window.c  
-
<source lang="c">
+
static void maemopad_window_on_menu_file_new (GtkButton *button, gpointer data)
-
/* 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" );
+
-
</source>
+
-
Part of function <code>create_textarea()</code> in Fremantle maemopad-window.c
 
-
<source lang="c">
+
=== Other updates in GTK+ and Hildon ===
-
/* Enable Rich Text Support */
+
-
gtk_text_buffer_register_serialize_tagset (self->buffer, "RTF");
+
-
gtk_text_buffer_register_deserialize_tagset (self->buffer, "RTF");
+
-
</source>
+
-
</li>
+
-
<li>
+
* Rich text support was changed with the new GTK+, as described in [http://live.gnome.org/Maemo/Gtk210Migration Maemo-GTK+ 2.6 to 2.10 Migration].This required editing two lines: <br />Part of function create_textarea() in Diablo interface.c
-
<code>HildonFontSelectionDialog</code> was deprecated and replaced with a <code>GtkFontButton</code>. In Diablo, the font callback was a callback to a regular <code>GtkAction</code>:
+
-
callback.c  
+
/* 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" );
 +
 
 +
Part of function create_textarea() in Fremantle maemopad-window.c  
-
<source lang="c">
+
/* Enable Rich Text Support */
-
void callback_font( GtkAction * action, gpointer data )
+
gtk_text_buffer_register_serialize_tagset (self->buffer, "RTF");
-
{
+
gtk_text_buffer_register_deserialize_tagset (self->buffer, "RTF");
-
    ...
+
-
    new_font = interface_font_chooser( mainview );
+
-
    /* if we got a new font from chooser -> change font */
+
-
    if( new_font != NULL ) {
+
-
        mainview->font_desc = new_font;
+
-
        gtk_widget_modify_font ( mainview->textview, mainview->font_desc );
+
-
    }
+
-
}
+
-
</source>
+
-
Function <code>callback_font</code> got the font from an auxiliary function <code>interface_font_chooser()</code> and then modified the font in the text view. The auxiliary function <code>interface_font_chooser()</code> in turn opened a <code>HildonFontSelectionDialog</code> that returned the font parameters:
+
* HildonFontSelectionDialog was deprecated and replaced with a GtkFontButton.
 +
In Diablo, the font callback was a callback to a regular GtkAction:
callback.c  
callback.c  
-
<source lang="c">
+
void callback_font( GtkAction * action, gpointer data )
-
/* Font chooser */
+
{
-
PangoFontDescription* interface_font_chooser( AppUIData * main )
+
    ...
-
{
+
    new_font = interface_font_chooser( mainview );
-
    ...
+
    /* if we got a new font from chooser -> change font */
-
    font = pango_font_description_new();
+
    if( new_font != NULL ) {
-
    /* create dialog */
+
        mainview->font_desc = new_font;
-
    dialog = HILDON_FONT_SELECTION_DIALOG ( hildon_font_selection_dialog_new( NULL, NULL ) );
+
        gtk_widget_modify_font ( mainview->textview, mainview->font_desc );
-
    gtk_widget_show_all (GTK_WIDGET(dialog));
+
    }
-
    if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK)
+
}
-
    {
+
-
        g_object_get(G_OBJECT(dialog),
+
-
                    "family", &family,
+
-
                    "size", &size,
+
-
                    "bold", &bold,
+
-
                    "italic", &italic,
+
-
                    NULL);
+
-
        pango_font_description_set_family(font, family);
+
-
        pango_font_description_set_size(font, size * PANGO_SCALE);
+
-
        if (bold) {
+
-
            pango_font_description_set_weight(font, PANGO_WEIGHT_BOLD);
+
-
        } else {
+
-
            pango_font_description_set_weight(font, PANGO_WEIGHT_NORMAL);
+
-
        }
+
-
        if (italic) {
+
-
            pango_font_description_set_style(font, PANGO_STYLE_ITALIC);
+
-
        } else {
+
-
            pango_font_description_set_style(font, PANGO_STYLE_NORMAL);
+
-
        }
+
-
    }
+
-
    gtk_widget_destroy(GTK_WIDGET(dialog));
+
-
    return font;
+
-
}
+
-
</source>
+
-
Instead of the deprecated <code>HildonFontSelectionDialog</code>, Fremantle uses a <code>GtkFontButton</code> directly in the font button callback:
+
Function <code>callback_font</code> got the font from an auxiliary function <code>interface_font_chooser()</code> and then modified the font in the text view. The auxiliary function <code>interface_font_chooser()</code> in turn opened a HildonFontSelectionDialog that returned the font parameters:
 +
callback.c
-
maemopad-window.c
+
/* Font chooser */
 +
PangoFontDescription* interface_font_chooser( AppUIData * main )
 +
{
 +
    ...
 +
    font = pango_font_description_new();
 +
    /* create dialog */
 +
    dialog = HILDON_FONT_SELECTION_DIALOG ( hildon_font_selection_dialog_new( NULL, NULL ) );
 +
    gtk_widget_show_all (GTK_WIDGET(dialog));
 +
    if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK)
 +
    {
 +
        g_object_get(G_OBJECT(dialog),
 +
                    "family", &family,
 +
                    "size", &size,
 +
                    "bold", &bold,
 +
                    "italic", &italic,
 +
                    NULL);
 +
        pango_font_description_set_family(font, family);
 +
        pango_font_description_set_size(font, size * PANGO_SCALE);
 +
        if (bold) {
 +
            pango_font_description_set_weight(font, PANGO_WEIGHT_BOLD);
 +
        } else {
 +
            pango_font_description_set_weight(font, PANGO_WEIGHT_NORMAL);
 +
        }
 +
        if (italic) {
 +
            pango_font_description_set_style(font, PANGO_STYLE_ITALIC);
 +
        } else {
 +
            pango_font_description_set_style(font, PANGO_STYLE_NORMAL);
 +
        }
 +
    }
 +
    gtk_widget_destroy(GTK_WIDGET(dialog));
 +
    return font;
 +
}
-
<source lang="c">
+
Instead of the deprecated HildonFontSelectionDialog, Fremantle uses a GtkFontButton directly in the font button callback:
-
/* font */
+
-
static void maemopad_window_on_font_set (GtkFontButton *button, gpointer data)
+
-
{
+
-
  ...
+
-
  font_name = gtk_font_button_get_font_name (button);
+
-
  if (!font_name)
+
-
    return;
+
-
  new_font = pango_font_description_from_string (font_name);
+
-
  /* Change the font used in the GtkTextView */
+
-
  if (new_font) {
+
-
    if (self->font_desc)
+
-
      pango_font_description_free (self->font_desc);
+
-
    self->font_desc = new_font;
+
-
    gtk_widget_modify_font (self->textview, self->font_desc);
+
-
  }
+
-
}
+
-
</source>
+
-
This <code>GtkFontButton</code> was initialized in function <code>create_menu()</code> (see above) in <code>maemopad-window.c</code> so that it would respond to the <code>"font-set"</code> signal and call the callback above:
+
* maemopad-window.c  
-
<source lang="c">
+
/* font */
-
self->font_item = gtk_font_button_new ();
+
static void maemopad_window_on_font_set (GtkFontButton *button, gpointer data)
-
gtk_widget_show (self->font_item);
+
{
-
g_signal_connect_after (self->font_item, "font-set",
+
  ...
-
  G_CALLBACK (maemopad_window_on_font_set), self);
+
  font_name = gtk_font_button_get_font_name (button);
-
hildon_app_menu_append (HILDON_APP_MENU (main_menu), GTK_BUTTON (self->font_item));
+
  if (!font_name)
-
</source>
+
    return;
-
</li>
+
  new_font = pango_font_description_from_string (font_name);
 +
  /* Change the font used in the GtkTextView */
 +
  if (new_font) {
 +
    if (self->font_desc)
 +
      pango_font_description_free (self->font_desc);
 +
      self->font_desc = new_font;
 +
      gtk_widget_modify_font (self->textview, self->font_desc);
 +
  }
 +
}
-
<li>
+
This GtkFontButton was initialized in function <code>create_menu()</code> (see above) in maemopad-window.c so that it would respond to the <code>"font-set"</code> signal and call the callback above:
-
Instead of <code>GtkTextView</code>, a [http://maemo.org/api_refs/5.0/5.0-final/hildon/HildonTextView.html HildonTextView] is now used:
+
-
Diablo callback.c
+
  self->font_item = gtk_font_button_new ();
 +
  gtk_widget_show (self->font_item);
 +
  g_signal_connect_after (self->font_item, "font-set",
 +
    G_CALLBACK (maemopad_window_on_font_set), self);
 +
  hildon_app_menu_append (HILDON_APP_MENU (main_menu), GTK_BUTTON (self->font_item));
-
<source lang="c">
+
* Instead of GtkTextView, a [http://maemo.org/api_refs/5.0/beta/hildon/HildonTextView.html HildonTextView] is now used.
-
/* Create the text area */
+
-
void create_textarea( AppUIData *main )
+
-
{
+
-
    /* Text view */
+
-
    main->textview = gtk_text_view_new ();
+
-
    ...
+
-
    /* Get handle */
+
-
    main->buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (main->textview));
+
-
    ...
+
-
}
+
-
</source>
+
-
Fremantle maemopad-window.c
 
-
<source lang="c">
+
* Diablo callback.c
-
static void create_textarea (MaemopadWindow *self)
+
-
{
+
-
    /* Text view */
+
-
    self->textview = hildon_text_view_new ();
+
-
    ....
+
-
    /* Get handle */
+
-
    self->buffer = hildon_text_view_get_buffer (GTK_TEXT_VIEW (self->textview));
+
-
}
+
-
</source>
+
-
</li>
+
-
<li>
+
/* Create the text area */
-
All Hildon applications should now initialize hildon before using it. In maemopad this is done by calling <code>hildon_gtk_init()</code> which also calls <code>gtk_init()</code> so the original call can be removed:
+
void create_textarea( AppUIData *main )
 +
{
 +
    /* Text view */
 +
    main->textview = gtk_text_view_new ();
 +
    ...
 +
    /* Get handle */
 +
    main->buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (main->textview));
 +
    ...
 +
}
-
Diablo main.c
 
-
<source lang="c">
+
* Fremantle maemopad-window.c
-
/* Init the gtk - must be called before any hildon stuff */
+
-
gtk_init( &argc, &argv );
+
-
</source>
+
-
Fremantle main.c
+
static void create_textarea (MaemopadWindow *self)
 +
{
 +
    /* Text view */
 +
    self->textview = hildon_text_view_new ();
 +
    ....
 +
    /* Get handle */
 +
    self->buffer = hildon_text_view_get_buffer (GTK_TEXT_VIEW (self->textview));
 +
}
-
<source lang="c">
+
* All Hildon applications should now initialize hildon before using it. In maemopad this is done by calling <code>hildon_gtk_init()</code> which also calls <code>gtk_init()</code> so the original call can be removed:
-
/* Inititialize GTK+ and hildon: */
+
Diablo main.c
-
hildon_gtk_init( &argc, &argv );
+
/* Init the gtk - must be called before any hildon stuff */
-
</source>
+
gtk_init( &argc, &argv );
-
 
+
Fremantle main.c
-
[[Category:Development]]
+
/* Inititialize GTK+ and hildon: */
-
[[Category:Documentation]]
+
hildon_gtk_init( &argc, &argv );
-
[[Category:Fremantle]]
+

Learn more about Contributing to the wiki.


Please note that all contributions to maemo.org wiki may be edited, altered, or removed by other contributors. If you do not want your writing to be edited mercilessly, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource (see maemo.org wiki:Copyrights for details). Do not submit copyrighted work without permission!


Cancel | Editing help (opens in new window)