164
Qt f or Maemo Developer's Guide v0.5 Beta Maemo for Mobile Developers

Qt for Maemo Developers Guide v0 5 Beta

Embed Size (px)

Citation preview

Page 1: Qt for Maemo Developers Guide v0 5 Beta

Qt for Maemo Developer's Guide v0.5  Beta

Maemo for Mobile Developers 

Page 2: Qt for Maemo Developers Guide v0 5 Beta

 

CHAPTER 1: INTRODUCTION 

1 WHAT IS MAEMO AND QT? ........................................................................................................ 8

2 MAEMO COMMUNITY................................................................................................................... 9

3 WHAT MAEMO CAN DO? ...........................................................................................................10

4 WHAT’S NEW IN MAEMO 5 (FREMANTLE)? .......................................................................11 

 

CHAPTER 2: GETTING STARTED 

1 MAEMO SDK CONCEPTS ............................................................................................................14

2 INSTALL DEVELOPMENT ENVIRONMENT...........................................................................15

2.1 INSTALL VMWARE (WINDOWS OS / MAC OS)........................................................................15 2.2 INSTALL SCRATCHBOX..................................................................................................................16 2.3 INSTALL MAEMO SDK AND NOKIA BINARIES .............................................................................16 2.4 INSTALL QT ON SCRATCHBOX......................................................................................................17

3 CREATE A QT PROJECT..............................................................................................................18

4 COMPILE THE APPLICATION...................................................................................................18

     

5 RUN THE APPLICATION ON THE EMULATOR....................................................................19

5.1 START THE SDK UI ......................................................................................................................19 5.2 RUN THE APPLICATION.................................................................................................................20 5.3 CLOSE THE SDK UI.......................................................................................................................20

6 TEST THE APPLICATION ON A DEVICE ................................................................................21

6.1 T PA ......................................................................................................21LOY APPLICATION TO THE DEVICE USING 

INSTALL Q CKAGES ........... 6.2 EP SSH.....................................................................226.2.1 INSTALL SSH ON THE DEVICE.................................................................................................................226.2.2 TRANSFER THE APPLICATION TO THE DEVICE............................

D

.........................................................236.3 DEPLOY THE APPLICATION USING PC­CONNECTIVITY........... ERROR! BOOKMARK NOT DEFINED. 6.4 RUN THE APPLICATION ON DEVICE ..............................................................................................23

7 CREATE A DEBIAN INSTALLATION PACKAGE ...................................................................24

7.1 EDIT THE RULES FILE ....................................................................................................................25 7.2 EDIT THE CONTROL FILE...............................................................................................................26 7.3 EDIT THE CHANGELOG FILE ..........................................................................................................27 7.4 MAKE THE APPLICATION VISIBLE IN THE MENU WITH A .DESKTOP FILE ..................................27 7.5 CHANGE THE .PRO FILE .................................................................................................................28 7.6 BUILD THE PACKAGE.....................................................................................................................29

Maemo for Mobile Developers 

Page 3: Qt for Maemo Developers Guide v0 5 Beta

7.7 INSTALL THE PACKAGE ON DEVICE...............................................................................................30  

CHAPTER 3: USING ESBOX IDE 

1 PREREQUISITES ...........................................................................................................................31

2 INSTALL AND SETUP ESBOX ON WINDOWS.......................................................................32

2.1 INSTALL SSH SERVER.....................................................................................................................35

3 INSTALL AND SETUP ESBOX ON LINUX ...............................................................................35

4 COMPILE THE APPLICATION ON ESBOX..............................................................................36

4.1 RUN  THE  APPLICATION ON ESBOX ............................................................................................39

5 CREATE A DEBIAN INSTALLATION FILE..............................................................................41

6 DEPLOY THE APPLICATION TO THE DEVICE.....................................................................43 

 

CHAPTER 4 QT FOR MAEMO IMPLEMENTATION NOTES 

1 PLATFORM SPECIFIC CHANGES..............................................................................................45

2 PORTING A QT APPLICATION TO MAEMO..........................................................................48

3 UPLOADING THE APPLICATION TO GARAGE ....................................................................49

4 LINKS ...............................................................................................................................................49 

 

CHAPTER 5: USING MAEMO APIS IN QT APPLICATIONS 

1 LIBLOCATION................................................................................................................................50

1.1 A ES AND DS.....................................................................................................501.1.1 LOCATIONGPSDEVICE.............................................................................................................................501.1.2 LOCATIONGPSDCONTROL .....................................................................................................................52

M IN CLASS  METHO

1.2 LOCATION­DISTANCE­UTILS .........................................................................................................53 1.3 LIBLOCATION EXAMPLE ...............................................................................................................53 1.4 LINKS .............................................................................................................................................59

2 LIBCITYINFO .................................................................................................................................59

2.1 EXAMPLE .......................................................................................................................................59

3 MCE­DEV.........................................................................................................................................62

3.1 MCE HEADERS FILES.....................................................................................................................63 3.2 QT MCE­DEV EXAMPLE..................................................................................................................64

Maemo for Mobile Developers 

Page 4: Qt for Maemo Developers Guide v0 5 Beta

4 CALENDAR­BACKEND ................................................................................................................66

4.1 MAIN CLASSES AND METHODS.....................................................................................................67 4.2 EXAMPLE .......................................................................................................................................68 4.3 LINKS .............................................................................................................................................74

5 ICD2..................................................................................................................................................75

5.1 INTRODUCTION .............................................................................................................................75 5.2 ARCHITECTURE .............................................................................................................................75 5.3 A ...... ..........................................................................765.4 XAMPLE .......................................................................................................................................78

TERNET CONNECTION DA N 2 EXAMPLE ..................................................................................78

M IN CLASSES AND METHODS....... .............. E

5.4.1 IN EMO

5.5 INKS .............................................................................................................................................83 OCUMENTATION/MAEMO 5 DEVELOPER GUON

L 5.5.1 D IDE/USING CONNECTIVITY 

NTS/MAEMO 

COMP E CONNECTIVITY ..............................................................................................................835.5.2 INTERNET CONNECTIVITY DAEMON VERSION 2..................................................................................845.5.3 BIBLIOGRAPHY..........................................................................................................................................84

6 A GUI EXAMPLE............................................................................................................................84

6.1 INTRODUCTION .............................................................................................................................84 6.2 AI D METHODS......................................................................................................85

M N CLASSES AN 6.3 XAMPLE .......................................................................................................................................856.3.1 MAIN WINDOW .........................................................................................................................................876.3.2 TABLE.........................................................................................................................................................91

E

6.4 LINKS .............................................................................................................................................95

7 WHAC­A­MOLE GAME EXAMPLE ............................................................................................95

7.1 ..................................................................................................................95MPLE ........

INTRODUCTION............ 7.2 XA ...............................................................................................................................96

AME MAIN WIND

E 7.2.1 G OW ..............................................................................................................................96

AIN SCREEN...........

7.2.2 M .................................................................................................................................97ECORDS SCREEN ............

7.2.3 R .........................................................................................................................98

ME CONT

7.2.4 GA ROLLER .............................................................................................................................. 1007.2.5 GRAPHICS VIEW WIDGET...................................................................................................................... 1017.2.6 MOLE ITEM ............................................................................................................................................. 103 7.3 LINKS ..........................................................................................................................................104

8 CAPTURING KEY EVENTS....................................................................................................... 105

8.1 EXAMPLE .................................................................................................................................... 105  

CHAPTER 6: ADDITIONAL MAEMO TOOLS 

1 MISCELLANEOUS....................................................................................................................... 107

1.1 SCREENSHOT­TOOL....................................................................................................................107 1.2 HOMEIP...................................................................................................................................... 107 1.3 DPKG AND APT...........................................................................................................................108

Maemo for Mobile Developers 

Page 5: Qt for Maemo Developers Guide v0 5 Beta

2 NETWORKING............................................................................................................................ 109

2.1 IPUTILS ....................................................................................................................................... 109 2.2 NETCAT....................................................................................................................................... 111 2.3 TCPDUMP.................................................................................................................................... 113 2.4 TRACEROUTE..............................................................................................................................113 2.5 NSLOOKUP .................................................................................................................................. 114 2.6 WGET..........................................................................................................................................114

3 WIRELESS TOOLS ..................................................................................................................... 114

3.1 BLUETOOTH TOOLS....................................................................................................................114 3.2 WIRELESS­TOOLS.......................................................................................................................115

4 TEST AUTOMATION................................................................................................................. 116

4.1 SP­TESTS..................................................................................................................................... 116 4.2 XNEE............................................................................................................................................117 4.3 XRESPONSE................................................................................................................................. 117

5 RESOURCE USAGE..................................................................................................................... 117

5.1 HTOP...........................................................................................................................................117 5.2 SP­MEMUSAGE............................................................................................................................118 5.3 SP­SMAPS­MEASURE ..................................................................................................................122 5.4 SP­SMAPS­VISUALIZE.................................................................................................................123 5.5 XRESTOP..................................................................................................................................... 123  

CHAPTER 7: DEBUGGING AND PROFILING 

1 DEBUGGING ................................................................................................................................124

1.1   LS.........................................................................................................................125MAEM ‐DEBUG‐SCRI

G ENERAL TOO

1.1.1 O PTS...................................................................................................................... 125NATIVE‐GDB .... ........

1.1.2 .. ............................................................................................................................. 1261.1.3 DEBUG‐DEP‐INSTALL ............................................................................................................................ 126

IST‐MMAPPED‐LIBS .................. 1.1.4 L ........................................................................................................... 127B.................................... ..... ...... ....................

1.2 D .. ... ................................................................... 127

STALLING AND TESTING GDB ......

G . 1.2.1 IN ..................................................................................................... 128

EBUGGING WITH

1.2.2 D  NATIVE‐GDB ON SCRATCHBOX ........................................................................... 129

EBUGGING WITH GDB 

1.2.3 D ON DEVICE ..................................................................................................... 134

ORE DU

1.2.4 C MP FILES.................................................................................................................................. 1381.2.5 SP‐ERROR‐VISUALIZER ......................................................................................................................... 1431.2.6 SYSLOG .................................................................................................................................................... 143

2 PROFILING ..................................................................................................................................143

2.1 A ...... ... ................................................................................. 144ROFILE ..... ................. ................ ..........

V LGRIND..... ................. ................... 2.2 P ...... .. ... ........................................................................ 1492.2.1 INSTALLING OPROFILE ON SCRATCHBOX.......................................................................................... 1492.2.2 INSTALLING OPROFILE ON INTERNET TABLET................................................................................ 149

O

Maemo for Mobile Developers 

Page 6: Qt for Maemo Developers Guide v0 5 Beta

2.2.3 FILE................................................................................................................................... 1512.2.4 OPROFILE WITH CALLGRAPH .............................................................................................................. 1552.2.5 OPROFILEUI ............................................................................................................................................ 157

USING OPRO

2.3 STRACE ....................................................................................................................................... 158 2.4 LTRACE ....................................................................................................................................... 162  

Maemo for Mobile Developers 

Page 7: Qt for Maemo Developers Guide v0 5 Beta

Maemo for Mobile Developers 

Page 8: Qt for Maemo Developers Guide v0 5 Beta

 

Chapter 1  Introduction This document is targeted for developers interested in developing and porting Qt applications 

for Maemo. Qt  application development environment  is  currently  relying on  the underlying 

Maemo  toolchain.  This  document  provides  step‐by‐step  instructions  how  to  set  up 

development environment, and how  to create, compile, and  run a  simple Qt project on  the 

emulator and on target. It also covers Maemo‐specific considerations and presents how to use 

Maemo  APIs  in  Qt  applications.  Debugging,  profiling,  and  additional Maemo  development 

tools are also covered. 

1 What is Maemo and Qt? Maemo is an open source development platform originally use in Internet Tablets (Nokia 770, 

Nokia N800 and Nokia N810).   The Maemo platform  itself  is the set of software components 

used to develop and test software for Nokia Maemo devices. It is built from large parts of open 

source projects. 

  The  Maemo  operating  system  is  based  on  Debian  GNU/Linux 

(http://www.debian.org/index.en.html). As it was designed for resource constrained devices, a 

lot of changes and new features where required to make it best fit to the target characteristics 

such  as  smaller  screens,  battery  powered, multiple  input methods,  etc.  One  of  the most 

important  is  the Hildon UI application  framework. Hildon was designed by Nokia  to provide 

mobile  device  oriented  functionality  (ex.:  finger‐friendly  interface),  but  also  provides 

functionalities common to desktop environments such as task navigator, control panel, status 

bar, etc. Hildon is based on GTK+ and makes part of the GNOME project.  

  The Maemo SDK contains tools required to create, build, test and port applications to 

Maemo platform. The base programming  language  is C, but  it also supports C++ and Python 

through  bindings  and  Qt.  One  important  concept  brought  by  the  SDK  is  the  Scratchbox. 

Scratchbox  (http://www.scratchbox.org/)  is  a  cross‐compilation  toolkit  designed  to  make 

easier the embedded Linux application development. The main task of Scratchbox is to enable 

compilation to ARM processors which are used in Internet Tablets. To do this Scratchbox uses 

a cross compiler that is able to create binaries to a platform different from the one that makes 

the compilation (ex.: create binaries for ARM from an X86 machine). 

Qt is a cross‐platform application and UI framework. Using Qt, you can write applications 

once  and  deploy  them  across  desktop, mobile  and  embedded  operating  systems  without 

rewriting the source code. Qt features intuitive C++ class library, portability across desktop and 

embedded  operating  systems,  integrated  development  tools  with  cross‐platform  IDE  (in 

officially  supported  platforms),  and  high  runtime  performance  and  small  footprint  on 

embedded. Qt 4.5  is adapted to Maemo/Hildon and currently provided as a community port 

for  Diablo  and  Fremantle  (the  4.5.3  version  of  this  is  used  in  the  in  the  Getting  Started 

instructions  in  this  document).  Qt  4.6 will  be  officially  supported  in Maemo  in  Harmattan 

Maemo for Mobile Developers 

Page 9: Qt for Maemo Developers Guide v0 5 Beta

where all applications are built on top of Qt. In October 2009 Nokia also announced that it will 

officially  support  Qt  4.6  already  in  Fremantle  as  a  technology  preview,  available  at 

http://qt.nokia.com/developer/qt‐for‐maemo‐developers. 

2 Maemo community The Maemo open community has over 16.000 registered members that contribute to 

more  than  700  development  projects.  It works with  open  source  tools  and  processes.  The 

community members are able to develop new software for both the platform itself and on top 

of the platform. Applications developed with the Maemo SDK are used today by thousands of 

consumers. 

The  community has a wide number of  tools and  services  to easier  the development 

process and keep close with the community needs. The most important are: 

Garage  (https://garage.maemo.org/)  which  is  meant  for  hosting  software 

projects related to the Maemo development platform. Any developer can host 

Maemo‐related projects  in garage. Don’t have an account? Create one here: 

https://garage.maemo.org/account/register.php. 

Planet Maemo  (http://maemo.org/news/planet‐maemo/) which  is a blog hub 

for Maemo developers. If can create your own blog and aggregate to this hub. 

Aggregate  now!  (http://maemo.org/news/planet‐

maemo/aggregate_your_blog/) 

Maemo  bug  report  (http://maemo.org/development/bugs/)  enables 

developers to report problems with the Maemo platform. 

Maemo  Feature  Request 

(https://garage.maemo.org/tracker/?func=browse&group_id=29&atid=188) 

shows  that  Maemo  is  close  to  the  community  and  wish  to  receive  its 

contribution and opinion.  

Maemo  extras  repository  (http://maemo.org/community/application‐

catalog/extras_repository/)  allows  developers  to  host  applications  to  be 

distributed to the Maemo users directly on their devices with no cost for the 

developer.  

#maemo  freenode 

(http://irc.netsplit.de/channels/details.php?room=%23maemo&net=freenode) 

is  the Maemo  IRC  channel  for  developers  to  free  talk  about  the  platform, 

consult friends, share opinions, etc. 

Maemo Mailing  lists  (http://wiki.maemo.org/Community_mailing_lists) allows 

users, developers, community to discuss about Maemo platform. The following 

lists are available: 

o maemo‐announce (https://lists.maemo.org/mailman/listinfo/maemo‐

announce) News and updates about maemo.org and Maemo  

o maemo‐users  (https://lists.maemo.org/mailman/listinfo/maemo‐

users)  For Maemo users  

Maemo for Mobile Developers 

Page 10: Qt for Maemo Developers Guide v0 5 Beta

o maemo‐developers  

(https://lists.maemo.org/mailman/listinfo/maemo‐developers)  For 

Maemo developers and hackers  

o maemo‐

community (https://lists.maemo.org/mailman/listinfo/maemo‐

community)  For  maemo.org  web  and  community‐process  related 

discussions  

o maemo‐commits   (https://lists.maemo.org/mailman/listinfo/maemo‐

commits) For following Maemo svn commit activity  

The picture below shows the most important projects related to the Maemo platform. 

 

3 What Maemo can do? Maemo  platform  provides  support  for  development  that  targets  all  the  important 

technologies categories required for mobile devices. The most important components for each 

category are given below: 

Maemo for Mobile Developers 

Page 11: Qt for Maemo Developers Guide v0 5 Beta

 

4 What’s new in Maemo 5 (Fremantle)? Maemo 5 aka Fremantle  is the new version of the Maemo platform.  It brings a  lot of 

new features. The most noticeable are given below: 

Hardware 

o Accelerated graphics with OpenGL ES 2.0 

o OMAP3 architecture 

o HSPA ( High Speed Packet Access / Cellular 3G connectivity ) 

o High resolution camera 

o Acceleration sensor 

Base services 

o A2DP  (Advanced Audio Distribution Profile)  and AVRCP  (Audio/Video 

Remote Control Profile) for an improved Bluetooth interactions 

o Compositing window manager 

Application framework 

o Suport to Qt 4.5 (a community port from Forum Nokia) 

UI 

o New UI style 

o Animated UI technologies 

New API's 

o Clutter: advanced and easy to use graphical API 

o Location API: methods to build location‐aware applications. 

Maemo for Mobile Developers 

Page 12: Qt for Maemo Developers Guide v0 5 Beta

o City Information: methods to obtain information about cities, including 

city name, country name, and country code. 

o Time management: an interface for handling time change notifications 

and collect relevant time and time zone information. 

o Vibration service: methods for triggering and controlling vibrations. 

o Device  orientation:  respond  to  changes  in  orientation  and  discover 

current orientation 

o Alarm service 

Top framework level changes from Diablo 

o Removal of left side Task Navigator and plug‐ins 

o Removal of stylus keyboard 

o New design for task switching and task handling 

o Renewal of Home and Status bar 

o New design for incoming event previews and indications 

o Widgets and application space renewal 

o UI  style  changes. E.g.: Navigation  logic  in  applications,  visual  style of 

dialogs, menus etc 

Desktop changes  o In home screen there is only application menu button and applets 

 o Applications are now in applications menu o Bigger icons 

  

New file chooser 

Maemo for Mobile Developers 

Page 13: Qt for Maemo Developers Guide v0 5 Beta

o Kinetic scroll 

 

Maemo for Mobile Developers 

Page 14: Qt for Maemo Developers Guide v0 5 Beta

 

Chapter 2 Getting started with Qt development on Maemo 

1 Maemo SDK concepts  

The Maemo hardware architecture is different from PC or Mac architecture, as it is based on 

an ARM processor. Thus, to create Maemo executable codes using a PC or Mac machine, we 

need a compiler that runs on these machines and compiles codes for the ARM architecture. 

Compilers that do this work are called cross‐compilers.  

The Maemo  Software Development  Kit  (Maemo  SDK)  contains  Scratchbox.  It  is  the 

base of Maemo  SDK  a  toolkit,  containing  a  cross‐compiler  and other  tools, which  creates  a 

complete Maemo development environment. The Maemo SDK emulates the operating system 

on the device, but with development tools added. 

The Maemo SDK is officially supported only on Debian and Ubuntu Linux distributions, 

but  installing Maemo SDK  is also possible for other distributions. On other operating systems 

such  as Windows,  a Virtual Machine  can be used  to provide  a working  Linux  environment. 

Virtual  Machines  are  software  containers  that  can  emulate  a  real  machine  and  run  one 

operating system as if it was in a physical computer. Thus, to develop for Maemo in a Windows 

or Mac machine, it is possible to use a Virtual Machine running Linux with Maemo SDK. 

Developing software using the Maemo SDK is quite similar to using a Symbian OS SDK. 

You write, compile, and run the code, usually using an  Integrated Development Environment 

(for example, Carbide.c++ for S60, Visual Studio for Windows Mobile, or ESbox + Eclipse for the 

Maemo  platform).  The  Symbian  OS  SDKs  include  a  phone  simulator,  which  is  a Windows 

executable capable to run Symbian OS software on an x86 workstation. The Windows Mobile 

SDK  kit  also  includes  similar  phone  emulators  and  is  capable  of  running  .NET  Compact 

Framework software.  

The Maemo SDK provides an emulator in a similar way, so it is possible to run Maemo 

applications inside it. The Maemo SDK is quite accurate in emulating the environment in a real 

device,  but  it  isn't  identical.  Especially  applications  that make  use  of  the  device's  special 

hardware can behave differently on the device than on Maemo SDK. They even may not work 

at all. Fortunately, testing the software on device is quite straightforward using either SSH, SCP 

or a tool called sbrsh. These tools are capable to quickly copy and run your application on the 

device during the development. 

Qt  is  a  cross‐platform  application  and  UI  framework,  which  can  be  used  on  the  Maemo 

platform  together  with  Scratchbox,  Maemo  SDK,  and  Eclipse  IDE  (EsBox).  The  following 

Maemo for Mobile Developers 

Page 15: Qt for Maemo Developers Guide v0 5 Beta

sections describe the steps that you need to do in order to setup a Qt for Maemo development 

environment. 

2 Install development environment 

2.1 Install VMWare (Windows OS / MAC OS) 

If you are working on a machine with the Microsoft Windows Operating System, you can emulate a Linux environment to be able to work with the Maemo SDK. In principle virtual machine is not needed if you use Linux as the native OS but even then it is possible to use the Maemo  virtual  image  if  you do not want  to  change  your  system  installing  the Maemo  SDK packages. To emulate a Linux environment you need to setup a virtual machine where you will install and run the Maemo SDK. The Linux environment emulated can be a virtual  image pre‐configured containing Maemo SDK with all files and tools installed. These images, available at http://maemovmware.garage.maemo.org/, will help us to get a full development environment easily. The basic difference between Windows and Mac  is  the virtual machine emulator  that you will use. On Windows the virtual machine emulator recommended is the VMWare player 

(http://www.vmware.com/products/player/). On  Mac  the  virtual  machine  emulator recommended  is  the VMWare  fusion  (http://www.vmware.com/products/fusion/).  Another alternative is Virtual Box (http://www.virtualbox.org/). 

To setup VMware image:  

1. Download  and  install  the  latest  version of  the  virtual machine  suitable  for  your operating system (VMWare player, VMWare fusion or Virtual Box);  

2. Once you have installed the virtual machine program, go to Maemo SDK VMware Appliance and download the Maemo SDK virtual image. These virtual images come with all files and applications needed to develop for Maemo.  If you get an  image which  comes  in  two  parts  (for  example  maemosdk_desktop_intrepid‐10‐08.zip.001  and maemosdk_desktop_intrepid‐10‐08.zip.002),  decompress  it  using 7-zip.  To  decompress  on  Windows,  just  right  click  over  the  file  with  “.001” extension and select 7‐zip  ‐> Extract files. On Linux, navigate to the folder where the  .7z file(s) are  located  (type "cd /path/to/folder" for example without quotes) and run the following command: 

$7z x FileName.001

3. Start the installed virtual machine program; 4. Click  Open  button  on  the  virtual  machine  program,  navigate  to  the  directory 

where the VMWare SDK package is, and choose the <maemoxxxx>*.vmx file; 5. Click  OK  to  launch  the  Linux  virtual  machine  containing  the  Maemo  SDK 

environment; 6. Once the Virtual Machine starts up, if required, log in with (username/password): 

maemo/maemo. 7. Once  the  Virtual Machine  starts  up,  you  should  open  a  terminal  and  run  the 

command: 

$/scratchbox/login

Maemo for Mobile Developers 

Page 16: Qt for Maemo Developers Guide v0 5 Beta

8. Now that you are logged in the Scratchbox, you can compile and run programs for Maemo. 

 

2.2 Install Scratchbox 

The Maemo  SDK  can be  installed on operating  systems  considered native environments 

directly. For Linux operating system, the Maemo SDK  installation  is quite easy.  It comes with 

two installation scripts: 

Scratchbox  installer  (http://repository.maemo.org/unstable/5.0beta/maemo‐scratchbox‐install_5.0beta.sh) script which downloads and installs the required version of Scratchbox onto your host machine; 

Maemo  SDK  installer  (http://repository.maemo.org/unstable/5.0beta/maemo‐sdk‐install_5.0beta.sh) which  installs  the  SDK  packages  and  sets  up  two  targets  (arm architecture and x86 architecture) inside Scratchbox. 

Maemo SDK also provides essential Nokia proprietary binary packages needed for Maemo development from an authenticated repository. In order to have access to this repository, you will need to accept the End User License Agreement (EULA). 

To install Scratchbox follow the steps below: 

1. Get Scratchbox installation script from: 

http://repository.maemo.org/unstable/5.0beta/maemo‐scratchbox‐install_5.0beta.sh 

2. Open a console; 3. Run the following command with root permission: 

$sh maemo-scratchbox-install_5.0beta.sh

4. The  installation script adds  the current user  to “sbox” user group. For  the group membership to be effective in the current terminal session, run the command: 

$newgrp sbox

5. Add a username to scratchbox by executing the command: 

$/scratchbox/sbin/sbox_adduser <username>

6. Add the group sbox to the user by executing the command:   

$groupadd sbox

2.3 Install Maemo SDK and Nokia binaries 

After  Scratchbox  installation  you  can  install Maemo  SDK.  To  do  this,  follow  the  steps below: 

Maemo for Mobile Developers 

Page 17: Qt for Maemo Developers Guide v0 5 Beta

1. Get Maemo SDK Fremantle installer from:  

  "http://repository.maemo.org/unstable/5.0beta/maemo‐sdk‐install_5.0beta.sh" 

2. Open a console; 3. Run the command: 

$sh maemo-sdk-install_5.0beta.sh

Maemo SDK needs an X11 server to provide a device screen for the developer on the host machine. The X11 server used to do this work  is the Xephyr X11 server software. On Debian based  linux systems, Xephyr can be  installed outside scratchbox environment using apt with root permission. To install, just run following command: 

$sudo apt-get install xserver-xephyr

Now you are able to login to Scratchbox by executing /scratchbox/login. After login, install 

Nokia binaries that are essential for the complete functionality of the Maemo SDK.  

4. Open  this  webpage (http://tablets-dev.nokia.com/eula/index.php)  in  your preferred browser and accept the EULA; 

5. Follow  the  instructions  in  the  next  page  to  add  one  line  to  the  file /etc/apt/sources.list inside Scratchbox for both x86 and ARMEL targets; 

6. To install the nokia‐binaries packages, execute these commands inside Scratchbox: 

$apt-get update

$fakeroot apt-get install nokia-binaries

7. This will install nokia‐binaries just for one target. To install on the other target run the  command  sb‐menu  inside  Scratchbox  to  change  the  target  and  run  the commands above. 

8. The Maemo SDK is now prepared to provide all tools to develop with C language. If you want to develop with C++  language, complete the  installation by running the following command inside Scratchbox: 

$fakeroot apt-get install libhildonmm-dev libhildonmm maemo-cplusplus-env libossomm-dev

Now you would be able  to compile and  run C/C++ programs  for Maemo  (for more  info, check  this  this  website  (http://maemo.org/development/sdks/maemo_5‐0_installation/)). However, we continue with the installation of Qt in next sections. 

2.4 Install Qt on Scratchbox 

Now that we have installed Scratchbox and Maemo SDK, we can install Qt. We will use the 

community port based on Qt 4.5.3. 

1. To install Qt on Scratchbox follow the steps below: 

Maemo for Mobile Developers 

Page 18: Qt for Maemo Developers Guide v0 5 Beta

Open a terminal and run the command: 

$/scratchbox/login

2. Now  edit  the  file  /etc/apt/sources.list.  At  the  moment  of  writing,  the  Qt  for Maemo  libraries were  in  the  extras‐devel  repository.  To  get  it  visible,  add  the Fremantle extra‐devel by adding the following line: 

deb http://repository.maemo.org/extras-devel/ fremantle free non-free

3. Run the following command to update the apt cache: 

$apt-get update

4. To install the Qt binaries, run: 

$fakeroot apt-get install libqt4-gui 

5. To install the development packages, run: 

$fakeroot apt-get install libqt4-dev

The above command  installs some basic UI packages. To  install other Qt modules, for example Webkit or OpenGL (ES 2.0), you have to run:

$fakeroot apt-get install libqt4-webkit libqt4-opengl

3 Create a Qt project 

This application creates a label on the Maemo screen displaying the “Hello World” string. The 

following code shows the content of hello.cpp: 

#include <QApplication> #include <QLabel> int main(int argc, char* argv[]) { QApplication app(argc,argv); QLabel *label = new QLabel("Hello World!"); label->show(); return app.exec(); }

4 Compile the application 

In  order  to  compile  your  Qt  Hello  World  application  you  need  to  login  in  the 

Scratchbox using the following command: 

$ /scratchbox/login

Maemo for Mobile Developers 

Page 19: Qt for Maemo Developers Guide v0 5 Beta

  Then, create a folder to hold the Hello World application. To do this you may run the 

following command: 

$ mkdir /home/maemo/workspaceqt/hello 

  Copy the hello.cpp to the created folder and run the following commands to build 

the application: 

  $ qmake -project

$ qmake hello.pro

$ make

  The first command creates the file hello.pro that defines a Qt project. It contains 

the files to be compiled, libraries to link with, etc. For more information about Qt project files 

go  to  qt  projects  file  (http://doc.trolltech.com/4.1/qmake‐project‐files.html#project‐

templates) page. The second command creates the Makefile file which contains directives 

to  compile  the  project.  The  last  command  compiles  the  project  using  the Makefile file 

creating the hello file which is the executable. The .pro file of the “Hello World” project 

is shown below  (Notice  that  the TARGET entry  is not automatically  filled by  the qmake –

project command): 

# hello.pro TEMPLATE = app TARGET = hello DEPENDPATH += . INCLUDEPATH += . # Input SOURCES += hello.cpp

5 Run the application on the emulator 

5.1 Start the SDK UI  

Follow these steps to start the Maemo SDK: 

1. Run Xephyr outside Scratchbox environment: 

$ Xephyr :2 -host-cursor -screen 800x480x16 -dpi 96 -ac -kb &

 2. Inside Scratchbox, set the DISPLAY variable to match the display setting given for the 

Xephyr server above, so the SDK can find the X server window 

$ export DISPLAY=:2

 3. Inside  Scratchbox,  initiate  the UI  framework  (NOTE:  a  script  o  can  be  created  on 

Linux to run these commands easily. Take a  look at How to Create a First Shell Script (http://www.linfo.org/create_shell_1.html)) 

$ af-sb-init.sh start

Maemo for Mobile Developers 

Page 20: Qt for Maemo Developers Guide v0 5 Beta

You will see the following screen on your Xephyr window: 

 

5.2 Run the application 

With the Maemo SDK running, execute the Hello World application with the following 

command. 

$ run-standalone.sh ./hello

  After that, the Hello World application will start on the Xephyr window. 

 

5.3 Close the SDK UI  When you finish the development, you can stop the Maemo SDK running: 

$ af-sb-init.sh stop

 

Maemo for Mobile Developers 

Page 21: Qt for Maemo Developers Guide v0 5 Beta

6 Test the application on a device  To run the application or install debian packages on device it is necessary to copy them to 

it. There is at least two ways to do that. The first way, consists of using PC‐connectivity project 

to configure a connection from PC to the tablet through USB, Bluetooth or WLAN connections. 

The second way consists in connecting manually the PC and tablet through WLAN interface of 

the Internet tablet. First, you however need to install the Qt packages on the device. 

6.1 Install Qt packages 

Before run Qt applications on devices, the installation of some Qt packages is required. At the moment of writing  , Qt  libraries were  in  the extras‐devel  repository. To  install packages, follow the steps below: 

1. Open the Application Manager in the device and make sure Extras‐devel is enabled (go 

to menu > Application Catalogue). If there is no Extras‐devel catalogue in the list you 

can create one.  Inside Applications Catalogue window press the New button and  fill 

out the dialog box that appear with the following information: 

Catalogue name: Extras‐devel 

Web address: http://repository.maemo.org/extras‐devel 

Distribution: fremantle 

Components: free non‐free 

 

2. After this, press “Save” button; 3. Open an ssh session with the device: 

PC_$> ssh root@DEVICE-IP

Maemo for Mobile Developers 

Page 22: Qt for Maemo Developers Guide v0 5 Beta

4. To install the Qt binaries, run: 

#apt-get install libqt4-gui 

5. To install other Qt modules, for example Webkit, DBus or OpenGL (ES 2.0), you have to run: 

#apt-get install libqt4-webkit libqt4-opengl libqt4-dbus 

NOTE: The Qt 4.5.3 packages are expected to be moved under Extras repository  in near 

future.  

 

6.2 Deploy application to the device 

 

6.2.1 Install SSH on the device   

   To  communicate  with  a  device,  which  allows  install  and  run  applications,  the 

installation of an SSH (http://wiki.maemo.org/SSH) server in the tablet is required. To do this, 

open the Application Manager  in the device and make sure Extras  is enabled  (go to menu > 

Application Catalogue).  If  there  is no Extras catalogue  in  the  list you can create one.  Inside 

Applications Catalogue window press the New button and fill out the dialog box that appear 

with the following information: 

Catalogue name: Extras 

Web address: http://repository.maemo.org/extras 

Distribution: fremantle 

Components: free 

Maemo for Mobile Developers 

Page 23: Qt for Maemo Developers Guide v0 5 Beta

 

After this, press Save button and then search for the package openssh‐server.  Install 

the packaging selecting it from the list.  

 

6.2.2  Install PC­Connectivity   The PC‐Connectivity project provides tools to easily setup the connection between PC 

and  the  Internet  Tablet.  The  connection  can  be  done  through  USB, WLAN  and  Bluetooth. 

Installation  instructions  of  PC‐connectivity  can  be  found  http://pc‐

connectivity.garage.maemo.org/installation.html. Detailed user guide can be found http://pc‐

connectivity.garage.maemo.org/documentation.html.  Note  when  installing  the  PC‐

Connectivity also  the openssh‐server package will be installed on the device. 

 

6.2.3 Copy the application to the device  

Now you can copy the application from the PC to the folder /home/user in the tablet. If 

you use Linux or Mac, the developer can use the scp command as shown below: 

PC_$> scp filename root@DEVICE-IP:/home/user

If you use Windows you can use Winscp (http://www.winscp.net/). More  information 

about how to configure Winscp, how to transfer files and how to execute commands can be 

found here: http://winscp.net/eng/docs/guides. 

6.3 Run the application on device We  can  now  run  the  application  on  the  device.  To  execute  the  application  run  the 

following commands in the shell. The first command opens a ssh session with the device. The 

next  two commands gains privileges of super user and  runs  the application.  If you are using 

Maemo for Mobile Developers 

Page 24: Qt for Maemo Developers Guide v0 5 Beta

Winscp you need to open a terminal (select Commands > Open terminal) and run the last two 

commands. 

PC_$> ssh root@DEVICE-IP tablet_#> su - user tablet_$> run-standalone.sh ./hello

 

           Note that testing an application on a device without a Debian installation package does 

not detect any dependencies to libraries. Also the application cannot be then run on from the 

application shell. 

7 Create a Debian installation package 

In the Section 6.3,"Run the application on device" we already tested the compiled project 

on  the  device.  However,  it  is  required  to  create  a  Debian  installation  package  to  enable 

installation and uninstallation with dependency handling and version control, and to create an 

application hierarchy  (to,  for example, copy data  files  into correct directories). Also you can 

define application icon and name so that users can launch the application from the application 

shell.  

The  first  step  to create  the debian package  for a Qt application  is  to change  the  folder 

name of your project. This is required by the dh_make tool to create the basic structure of the 

package. The naming convention accepted by dh_make tool is (if dh_make is not installed, run 

“apt‐get install dh_make”): 

<project>-<version>

Change  the  Hello  World  project  folder  to  helloworld-1.0.  After  this,  run  the 

following dh_make command inside the project folder to create a basic package structure (run 

“man dh_make” for more information): 

dh_make --createorig --single -e [email protected] -c gpl

This command makes a copy of the original source archive (--createorig), sets the 

package class to single application (--single), sets the maintainer e‐mail address to the given 

e‐mail (-e <e-mail>) and sets the license (-c).  dh_make creates the folder debian/ inside 

the project folder with the files needed to generate the debian package. The most  important 

files are: 

debian/rules 

debian/control 

debian/copyright

debian/compat

debian/changelog

The following sections show how to do the modifications needed in the files inside the 

debian/ folder. Also, it shows the .desktop file, which contains application information such as 

name, icon, etc. that are used to show the application in Maemo UI. Next, the changes needed 

Maemo for Mobile Developers 

Page 25: Qt for Maemo Developers Guide v0 5 Beta

in the .pro file to copy the.desktop file and icon files to Maemo are explained. At the end, 

the commands to build and install the package are shown. 

7.1 Edit the rules file   This  file  is  a  Makefile which  effectively  run  the  commands  to  build  the  package, 

including the sources compilation. The default file generated by dh_make doesn’t know how 

to build Qt applications, so the file has to be updated to do this. The following code contains 

the adaptations to the rules file needed to build a Qt package. The only change you need to do 

is the entry APPNAME. In the case of the Hello World application package the file used  is the 

following. 

 

 

 

 

#!/usr/bin/make -f APPNAME := Hello builddir: mkdir -p builddir builddir/Makefile: builddir cd builddir && qmake-qt4 PREFIX=/usr ../$(APPNAME).pro build: build-stamp build-stamp: builddir/Makefile dh_testdir # Add here commands to compile the package. cd builddir && $(MAKE) touch $@ clean: dh_testdir dh_testroot rm -f build-stamp # Add here commands to clean up after the build process. rm -rf builddir dh_clean install: build dh_testdir dh_testroot dh_clean -k dh_installdirs # Add here commands to install the package into debian/your_appname cd builddir && $(MAKE) INSTALL_ROOT=$(CURDIR)/debian/$(APPNAME) install # Build architecture-independent files here. binary-indep: build install # We have nothing to do by default. # Build architecture-dependent files here.

NOTE:  The  empty  space  of  each  line  should  begin with  TAB  characters  instead  of 

multiple  space  characters.  If  you  copy  this  chunk,  you most  probably  get  spaces 

instead of tabs and the file will not be correct. So, change spaces into TAB characters. 

Maemo for Mobile Developers 

Page 26: Qt for Maemo Developers Guide v0 5 Beta

binary-arch: build install dh_testdir dh_testroot dh_installdocs dh_installexamples dh_installman dh_link dh_strip dh_compress dh_fixperms dh_installdeb dh_shlibdeps dh_gencontrol dh_md5sums dh_builddeb binary: binary-indep binary-arch .PHONY: build clean binary-indep binary-arch binary install configure

 

7.2 Edit the control file   This  file  specifies  package  data  like  name,  dependencies  and  description  for  both 

source and binary packages. To generate  the package  for Maemo,  the  following entries are 

important: 

Section:  this  entry  is  used  by  the  Maemo  Application  Manager  to  select  which 

packages  it will show. By default  the Application Manager shows only packages  that 

belong to the user segment. As a result, the Section entry should assume the following 

form: 

 

Section: user/SUBSECTION

 

where SUBSECTION, may assume one of the values from the table below. 

 

Subsection  Keyword 

Accessories         user/accessories

Communication user/communication

Games    user/games

Multimedia          user/multimedia

Office  user/Office

Other  user/other

Programming        user/programming

Support          user/support

Themes           user/themes

Tools            user/tools

 

Maintainer: This field MUST be changed if the upstream package has been modified. 

XB‐Maemo‐Icon‐26: It contains the PNG icon encoded in base64 visible in the 

Application Manager. To encode such file from Scratchbox do the following: 

apt-get update

Maemo for Mobile Developers 

Page 27: Qt for Maemo Developers Guide v0 5 Beta

apt-get install sharutils uuencode -m <name of 26x26 image> > <name of 26x26 image>.base64

 

The control file to the Hello World application is shown below. Notice that there is a space in 

the beginning of each new line of the sections Description and XB-Maemo-Icon-26.

Source: my-application Section: user/valid_subsection Priority: optional Maintainer: name surname <[email protected]> XSBC-Original-Maintainer: name surname <[email protected]> Build-Depends: debhelper (>= 5), libqt4-dev, OTHERS_BUILD DEPENDECIES Standards-Version: 3.7.3 Package: my-application Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} Description: A simple test application A very simple application with a short description. Which spans multiple lines actually. XB-Maemo-Icon-26: iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOAAAABmJLR0QA/wD/AP+g vaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH1gURDQoYya0JlwAAAU9J REFUSMftlL1KA0EUhb/NZl/ggnHQxsJUxt5CUucVJCCkDfgyKdIGG5/A0s5HEBtJ EdDAQGBgmw0YJmMzgXXYza5CtNkDW9zZw5z7c+ZCgwb/Ai3i9sVl/Bq8RIs4LRK1 gJDsKvJyNXmJMuYTsMoY1zpgozaABdYArQNPZQ1kfyGU7SpqVwxzAMwABWhgpIwp 4vWBB+AUWAI3ypjnfEXtPU4bLKx9vErTeCeiRSYF+fTn1j5dp2myE9EiU+DSi3wX ymeqRQAmZ3EcA5E/fgO6BULT8zhOcrwXoJdrXRa2Lgps2y2odAUcBUIXQdz78YyC SldAp8b7+bXrIv91qjZBietqCc2DjbAt4b2WxJkyZljVujlwp0U0cPxuLcAIuC+4 dKxFlsDJarvdAGP/b6hFnDImYs+uG3hbO2AB3Jbsur63tQM+fFx3bzZocEB8AdV2 gJBZgKTwAAAAAElFTkSuQmCC

 

7.3 Edit the changelog file This file describes the changes made in each package version. It is important because it 

sets the version number to be used when the current package is to be generated.  

If an upstream package  is modified for Maemo, the Maemo revision string should be 

appended to the upstream revision. For  instance,  if  in Debian distribution the package name 

was  something  like  "Myapp‐0.4‐2",  in  Maemo  this  package  could  be  called  "Myapp‐0.4‐

2maemo1". The number after the "maemo" string is a progressive number. 

7.4 Make the application visible in the menu with a .desktop file   To make  an  application  visible  in Maemo menu,  a  Desktop  file  is  needed  for  the application.  If you don’t want  to do  this you can skip  this session and go straight  to Section 7.6,"Build  the package".  This  file  contains  all  the  essential  information needed  to  show  the application entry  in the menu, such as name,  icon  logical name, application binary file name, etc. The name of the file should be [application-name].desktop. The location in Maemo filesystem should be /usr/share/applications/hildon/.   The desktop  file  is not  generated by  any  tool,  so  it  is necessary  to  create one.  The 

following example can be used. Just copy and paste the following content to the src/ folder 

of your Qt project.  If you don’t have a src/  folder, create one and copy  the source code  to 

there. 

Maemo for Mobile Developers 

Page 28: Qt for Maemo Developers Guide v0 5 Beta

[Desktop Entry] Encoding=UTF-8 Version=0.1 Type=Application Name=myapp Exec=/usr/bin/myapp Icon=myapp X-HildonDesk-ShowInToolbar=true X-Osso-Type=application/x-executable

 

7.5 Change the .pro file   At this point the project folder of your Qt application should be similar to this: 

helloworld-1.0/ src/ hello.cpp hello.desktop hello.pro

  It  is necessary  to make  some modifications  to  the hello.pro  file.  They will  copy  the 

.desktop file and the  icon file to the right place  in Maemo when  installing the application. To 

do this you just need to append some lines to the end of your .pro file. These lines will check 

the right place to put the .desktop and the icons file. As it can be seen, the .desktop file goes to 

the applications/hildon and the  icon goes to pixmap and icons/hicolor folder. The 

resultant hello.pro file is shown below. 

# hello.pro TEMPLATE = app TARGET = hello DEPENDPATH += . INCLUDEPATH += . # Input SOURCES += hello.cpp # ----------------------------------------------------------------- # Added section # ----------------------------------------------------------------- unix { #VARIABLES isEmpty(PREFIX) { PREFIX = /usr/local } BINDIR = $$PREFIX/bin DATADIR =$$PREFIX/share DEFINES += DATADIR=\"$$DATADIR\" PKGDATADIR=\"$$PKGDATADIR\" #MAKE INSTALL INSTALLS += target desktop iconxpm icon26 icon40 icon64 target.path =$$BINDIR desktop.path = $$DATADIR/applications/hildon desktop.files += $${TARGET}.desktop

Maemo for Mobile Developers 

Page 29: Qt for Maemo Developers Guide v0 5 Beta

iconxpm.path = $$DATADIR/pixmap iconxpm.files += ../data/maemo/$${TARGET}.xpm icon26.path = $$DATADIR/icons/hicolor/26x26/apps icon26.files += ../data/26x26/$${TARGET}.png icon40.path = $$DATADIR/icons/hicolor/40x40/apps icon40.files += ../data/40x40/$${TARGET}.png icon64.path = $$DATADIR/icons/hicolor/64x64/apps icon64.files += ../data/64x64/$${TARGET}.png }

It is also advised to verify the Qt version. You can do this moving the hello.pro file to the src 

folder and renaming it to src.pro. The following command does this. 

mv src/hello.pro src/src.pro 

Then create a new hello.pro file in the project root folder. 

# hello.pro QMAKEVERSION = $$[QMAKE_VERSION] ISQT4 = $$find(QMAKEVERSION, ^[2-9]) isEmpty( ISQT4 ) { error("Use the qmake include with Qt4.4 or greater, on Debian that is qmake-qt4"); } TEMPLATE = subdirs SUBDIRS = src

 

7.6 Build the package 

  Run  the  following command  in  the project  root  folder  to generate  the package. The 

generated file will be created  in the folder before the project root folder. Make sure you are 

compiling in FREMANTLE_ARMEL target to generate the package suitable for the device. 

$ dpkg-buildpackage -rfakeroot -b

 

Maemo for Mobile Developers 

Page 30: Qt for Maemo Developers Guide v0 5 Beta

 

7.7 Install the package on device To install the generated debian package to a device, copy it to device like described in the 

section 6,"Test the application on a device".  Connect with the device using ssh an then install 

the debian package by running the following command as root: 

$ssh root@DEVICE‐IP 

#dpkg ‐i filename.deb 

If the desktop was created (as described in 7.4,"Make the application visible in the menu 

with a .desktop file") the application will appear in the menu. 

Maemo for Mobile Developers 

Page 31: Qt for Maemo Developers Guide v0 5 Beta

 

Chapter 3 Using ESBox IDE Instead of using command  line (shown  in Chapter 2, Getting Started),  it  is possible to 

create  Qt  applications  for  Maemo  platform  with  an  Eclipse‐Ganymede‐based  IDE,  ESBox (http://esbox.garage.maemo.org/beta1/installation_update_site.html). 

ESBOX supports C/C++ and Python programming  languages with source editing, code completion, build, launch, debug, profiling, and packaging generation.  

ESBox may be used on  all major platforms  (Linux, Win32, Mac OS X). On non‐Linux systems,  it  is possible to use a Virtual Machine or a remote Linux system to host the Maemo SDK. ESbox will translate all IDE UI commands to SDK commands behind the scenes. 

1 Prerequisites 

Here,  you will  learn  how  to  prepare  the  environment  to  use  ESBox.  The  environment needs some prerequisites, which are listed below: 

Java 1.5 or newer  (http://java.com/en/download/manual.jsp) 

Cygwin (http://www.cygwin.com/) (only for windows) 

PC  Connectivity  (http://pc‐connectivity.garage.maemo.org/beta1/documentation_usbnet.html) 

A Virtual Machine like QEMU, VirtualBox or VMWare (http://www.vmware.com/) (only for windows) 

A Maemo SDK virtual image (http://maemovmware.garage.maemo.org/) 

The Java will be used to host Eclipse. The Cygwin will be used to create an ssh server under Windows  environment.  The  PC  Connectivity will  be  used  to  easily  configure  of  Cygwin  ssh server and to deploy applications to device. The virtual machine will be used to run the image of linux containing the Maemo SDK. 

There  are  two ways  to  install ESBox.  The  first way  is  to  get  the  Full Product Archive of ESBox. The second way is to use Eclipse Update Site. 

We will  use  the  first way.  If  you want  to  install  ESBox  using  Eclipse  Update  Site,  see instructions at http://esbox.garage.maemo.org/beta1/installation_update_site.html.  

The Full Product Archive consists of two parts: one common archive containing the bulk of the  installation  and  an OS‐specific  archive.  The  first  step  is  to  get  these  two  archives  from https://garage.maemo.org/frs/?group_id=192.  In our  case, we will  get  the  common  file  and the win32 file. Then, create an empty directory and unzip both files  into that. After,  just run esbox.exe from the created directory. 

Maemo for Mobile Developers 

Page 32: Qt for Maemo Developers Guide v0 5 Beta

2 Install and setup ESBox on Windows 

Now,  we  need  a  Linux  virtual machine  containing  the Maemo  SDK  to  allow  ESBox  to properly  build  the  applications  for  Maemo.  First  get  the  VMware  player  from  here: http://www.vmware.com/. Then,  get  a  Maemo  SDK  virtual  image  from  here: http://maemovmware.garage.maemo.org/.  There  are  several  Maemo  SDK  virtual  images available.  Some  of  them  do  not  have  Scratchbox  and  others  need  files  installed.  You  can 

download  one  of  those  images  and  use  the  instructions  in  the  section 2.2, "Install  Scratchbox"  or  get  an  image  that  already  has  these  applications  and  files  installed. Now, follow the steps below: 

1. Open the ESBox; 2. Go to Window ‐> Preferences ‐> ESBox ‐> Build Machines; 

3. Select VMware Linux Build Machine as build machine; 4. Browse the VMware player executable and browse the Maemo SDK virtual image;  

Maemo for Mobile Developers 

Page 33: Qt for Maemo Developers Guide v0 5 Beta

5. Go to Machine Access tab; 

6. You  need  to  edit  the  address  and  port  settings  depending  on  your  networking configuration. Use the Autoselect Network Settings button to tell ESBox to guess the networking  settings  from  current  virtual machine  settings  and  the  host machine's network interfaces. Check the log message shown to see if any error happened; 

Maemo for Mobile Developers 

Page 34: Qt for Maemo Developers Guide v0 5 Beta

 

7. Note, when configuring a virtual machine using Bridged networking,  it's  impossible to guess the actual address the machine will have. By default, ESbox selects the network address  (*.0)  and  warns  you  to  update  it.  To  discover  the  ip  address  of  Virtual Machine, just open a console and type ifconfig; 

8. Go to Shared Folders tab to select a folder shared for host and target; 

9. Here we can see that we will need a windows shared folder. It is required to be visible to both the ESBox and the Virtual Machine, so all projects need to be stored on a path shared from the host and mapped to the Virtual Machine.  

10. Go to the Windows environment and share a folder of your choice; 11. In the ESBox, put the shared folder path in all Shared path field; 12. Leave all others fields as they are. 

Maemo for Mobile Developers 

Page 35: Qt for Maemo Developers Guide v0 5 Beta

If you click on Apply and Validate Machine or Apply buttons you will probably get an error. This  is  due  to  communication  error.  The  ESBox  and  the  Maemo  SDK  virtual  image communicates  among  themselves  using  SSH.  Usually, Windows  don’t  come  with  any  SSH server, then, the installation of an ssh server is necessary. 

2.1 Install ssh server 

We will use Cygwin to create an ssh server on Windows. To use it, follow the steps described below: 

1. Get Cygwin installation file from “http://www.cygwin.com/” ; 2. In addition  to  the default Cygwin  installation packages,  install  the  latest versions  for: 

cygrunsrv, nfs‐server, openssh, xinit; 3. Get  PC  Connectivity  from  “http://pc‐

connectivity.garage.maemo.org/beta1/documentation_usbnet.html] and install”. 

The installation process will configure and initiate Cygwin ssh server properly. Now you can back  to  ESBox Window  ‐>  Preferences  ‐>  ESBox  ‐>  Build Machines  and  click  on  Apply  and Validate Machine. If all run ok, it will pass clean and silent. If no, probably the target address is wrong. To solve this problem, go to virtual machine, open a console a type ifconfig to get the correct net address. Back to ESBox and change target address. 

For  troubleshooting,  see  “http://pc‐connectivity.garage.maemo.org/beta1/documentation_usbnet.html”. 

3 Install and setup ESBox on Linux To run ESBox on Linux the following prerequisites are needed: 

Maemo for Mobile Developers 

Page 36: Qt for Maemo Developers Guide v0 5 Beta

Java 1.5 or newer; 

Scratchbox and Maemo SDK. 

To  install  Scratchbox  and  Maemo  SDK  you  can  use  the  instructions  on  the  section  2.2, "Install Scratchbox". The installation using ESBox is quite easy. To do this, first install ESBox. 

Here, there are also two ways to install ESBox. The first way is to get the Full Product Archive 

of ESBox. The second way is to use Eclipse Update Site. 

We will use  the  first way.  If  you want  to  install  ESBox using  Eclipse Update  Site,  see  these 

instructions (http://esbox.garage.maemo.org/beta1/installation_update_site.html).  

The Full Product Archive consists of two parts: one common archive containing the bulk of the 

installation  and  an  OS‐specific  archive.  The  first  step  is  to  get  these  two  archives 

fromhttps://garage.maemo.org/frs/?group_id=192 

“https://garage.maemo.org/frs/?group_id=192”. In our case, we will get the common file and 

the Linux  file. Then, create an empty directory and unzip both  files  into  that. After,  just  run 

ESBox from the created directory. At this point you are able to install Scratchbox and Maemo 

SDK if you have not done yet. 

4 Compile the application on ESBox 

 

 

 

 

 

Eclipse  (http://www.eclipse.org/)  is an  IDE  for developing C/C++/Java applications.  It 

provides tools for debugging and building applications, among various other utilities. ESbox is 

an Eclipse plug‐in designed to make project development easier in Maemo. 

ESBox  (http://esbox.garage.maemo.org/)  runs  inside  Eclipse  with  CDT  (C/C++ Development Tools) installed. Eclipse needs a Java Virtual Machine to run properly (Sun's Java 6 or above  is  recommended). ESbox also needs Scratchbox  targets  to build and  run Maemo 

projects.  More  information  about  installing  ESBox  can  be  found  here: http://esbox.garage.maemo.org/installation.html. 

The ESBox IDE interacts directly with Scratchbox and Maemo SDK. Although it’s current 

release doesn’t have  a proper perspective  to develop  for Qt,  it  can be used  to develop Qt 

applications.  Its  main  benefit  is  that  it  automatically  configures  the  environment.    The 

developer doesn’t need to direct run commands to build and run the application.   

The first step to build the Hello World application  is to open ESBox IDE and create an 

empty C++ Maemo project as it is shown in the picture below. This can be done selecting File > 

New > C++ Maemo Project. This will open the following screen where the option Empty C++ 

Automake Project  should be chosen  (1). After  this,  the project  should be configured  setting 

the  Project  name  and  Build  configurations  (2).  After  this,  the  project  is  created  and  the 

NOTE: ESBox IDE doesn’t have native support to develop Qt applications. However  it 

is  fully  integrated with  Scratchbox.  This makes  the  development  easier  since  none 

command  line  execution  is  required  to  build  and  execute  the  application  in  the 

emulator. This is the main advantage of using it.  

Maemo for Mobile Developers 

Page 37: Qt for Maemo Developers Guide v0 5 Beta

main.cpp can be edited to contain the Hello World Qt code (3). See the pictures below to see 

all these steps. 

 

 

Maemo for Mobile Developers 

Page 38: Qt for Maemo Developers Guide v0 5 Beta

After  this,  it  is  necessary  to  create  a  “Make  target”  for Qt.  To  do  this,  click  in  the 

project with right mouse button and select Create Make Target. The following dialog box will 

appear  where  the  build  command  needs  to  be  changed  to  compile  a  Qt  project.  The 

commands needed  are  the  same  as before:   qmake –project ; qmake ; make. You 

need  to  create  two  targets:  the  first  one  contains qmake –project command  and 

generates  the .pro project  file;  the  second  contains qmake; make commands  that  are 

responsible for building the application.  

The  last  step  is  to  remove  some  flags 

used  to  compile  C++.  As  Qt  uses  a  different  build  system  (see 

http://doc.trolltech.com/4.2/qmake‐manual.html)  these  flags  don’t  need  to  be  configured 

manually. These flags can be found in Properties > Maemo build configurations. The following 

picture shows the variables to be removed. 

Maemo for Mobile Developers 

Page 39: Qt for Maemo Developers Guide v0 5 Beta

 

Now the project can be compiled selecting Build Make Target.  If  it the first time the 

project is built the all target need to be build to generate the .pro file. Once this file has been 

generated, the next compilations only need to build the build target.  

4.1 Run  the  application on ESBox 

1. Click on the “X” button and select “start” to start an X server; 

2. If you get an error, try to change Cygwin paths on Window ‐> Preferences ‐> ESBox ‐> X Server as shown below; 

Maemo for Mobile Developers 

Page 40: Qt for Maemo Developers Guide v0 5 Beta

3. Click on the “maemo” button to start the Maemo SDK on de X server; 

Maemo for Mobile Developers 

Page 41: Qt for Maemo Developers Guide v0 5 Beta

 

4. After building the application and steps above  it can be run pressing the right mouse 

button in the generated binary file and selecting Run As > Maemo Local Application. 

5 Create a Debian installation file 

To deploy an application to device, the debian package generation is required. To do this, 

follow the steps below: 

1. Right click on the project and select the Debian Package option; 

2. Select Create Debian Structure; 

Maemo for Mobile Developers 

Page 42: Qt for Maemo Developers Guide v0 5 Beta

3. Here you can select the options of your choice. After that, click Finish button and the 

debian structure will be created; 

4. Right click again on the project and select Debian Package ‐> Build Debian Package; 

Maemo for Mobile Developers 

Page 43: Qt for Maemo Developers Guide v0 5 Beta

5. Select the desired target. You will be prompted to choose the destination folder. After 

that, the “.deb” file will be generated; 

6 Deploy the application to the device Follow  the  PC  Connectivity  installation  instruction  from  http://pc‐

connectivity.garage.maemo.org/documentation_usbnet.html  to  configure  the  connection 

between PC and internet tablet; 

 

1. Right  click  the  last  time on  the project and  select Debian Package  ‐>  Install Debian 

Package on Device; 

Maemo for Mobile Developers 

Page 44: Qt for Maemo Developers Guide v0 5 Beta

2. Browse  the  created debian  file,  select  the  appropriated device  connection  and  click 

Finish button; 

If all run ok, the application will be deployed to the device. 

Maemo for Mobile Developers 

Page 45: Qt for Maemo Developers Guide v0 5 Beta

 

Chapter 4 Qt for Maemo implementation notes 

Qt is a cross‐platform application and UI framework. With Qt, the developer can create 

applications and  run  them  in multiple platforms  including desktops and mobile devices. The 

most important features of Qt are: 

Intuitive C++ class library 

Portability across multiple platforms 

High runtime performance and small footprint on embedded systems 

Complete collection of cross platform libraries 

Qt is an additional component in Maemo platform. In the latest Maemo release, called 

Fremantle  the Qt  libraries  porting  have  been  improved  to  provide  better  performance  and 

enhanced platform integration. This includes Maemo Hildon compatibility with Hildon menus, 

Hildon style support and Hildon input menu support. Also, Fremantle brings Qt with support to 

Opengl ES 2.0, Webkit and Mysql, among other things. More information about Qt in Maemo 

can be  found  in at http://qt4.garage.maemo.org/. There are  some  reasons  to  support Qt  in 

Maemo: 

• Qt is Nokia cross platform toolkit, made by Nokia Qt Software 

• Same applications with no modifications or just small changes can be compiled and 

run  in  S60  but  also  in  Desktop  Linux Macintosh, Windows  and  even Windows 

mobile 

• UI needs to be tailored to specific device characteristics and Qt can solve this in a 

straightforward way 

The  following  sections  provide  a  quick,  but  detailed,  guide  to  start  developing 

applications with Qt for Maemo platform.  

1 Platform specific changes    This  session  indicates  the  changes  made  in  the  standard  Qt  libraries  needed  to 

integrate  then  to  Maemo  platform  concepts.  For  an  extensive  reference  of  standard  Qt 

libraries go to “http://doc.trolltech.com/”. Fremantle  integration with Qt  included adaptation 

for:  

Hildon Menus 

Hildon style 

Hildon Input methods 

Widgets like QDialog and QMenu 

Qt packages 

Maemo for Mobile Developers 

Page 46: Qt for Maemo Developers Guide v0 5 Beta

  Maemo  Qt  is  based  on  Qt  for  X11.  It  shares  the  same  API  with  no  API  breaks.  

Therefore, every Qt application that runs in other platforms runs in Maemo. So, the Qt official 

documentation (http://doc.trolltech.com/4.5/index.html) can be used to develop applications 

for Qt to Maemo. However, the reverse doesn’t hold in all situations as there are some small 

changes in Maemo. The list of changes is presented below. 

Storage  Location: the  function storageLocation of  the  class QDesktopServices receives StandardLocation as parameter. Below there  is a table matching each parameter value for this function with the returned value when running in Maemo. 

StandardLocation  Folder in Maemo  DesktopLocation  /MyDocs DocumentsLocation /MyDocs/.documentsPicturesLocation  /MyDocs/.images MusicLocation  /MyDocs/.sounds MoviesLocation  /MyDocs/.videos 

  Input events:  QInputEvents doesn’t move the cursor along the screen. This is done through QInputMethodEvents. The reason for this is that when the user highlights the text from right to left, and the highlighted text is erased, the cursor will remain in the last char instead of the first.  To  do  that  some  changes  has  been  added  to  some  widget  function  like inputMethodEvent(QInputMethodEvent *e). Modifying that function  in some custom widgets may be necessary. If these functions are not re‐implemented some full screen virtual keyboard features will be break.    Also QMainWindow has some hardcoded keys.  They are: 

F6 ‐ Toggle full screen the application 

F4 ‐ Shows/Hides the application context menu 

 Zoom in  ‐ is a standard key sequence QKeySequence::ZoomIn   Zoom out ‐ is a standard key sequence QKeySequence::ZoomOut  

Input method:   Maemo Qt uses the Hildon  IM as default  Input method. Each kind of widget can  set  the  IM mode.  This  allows  the  input method  to  focus on  the  type of  input  that  the application  is expecting.  For example,  spin boxes  can  receive only numeric  characters  (1‐9). Notice  that Qt widgets  like QTextEdit and QLineEdit  set  the  right  input method mode automatically.  A developer can change the input method by using: 

 void QInputContext::setInputMode(int mode);

This will update the Hildon Input method immediately to the following modes: 

Input method mode  Description HILDON_GTK_INPUT_MODE_ALPHA alphabetical characters and whitespace HILDON_GTK_INPUT_MODE_NUMERIC  numbers 0‐9 and the '‐' character HILDON_GTK_INPUT_MODE_SPECIAL  special characters HILDON_GTK_INPUT_MODE_HEXA  hexadecimal characters; numbers 0‐9, characters 

a‐f, and A‐F HILDON_GTK_INPUT_MODE_TELE  telephone numbers; numbers 0‐9, whitespace, 

and the characters "pwPW/().‐+*#?," HILDON_GTK_INPUT_MODE_FULL  unrestricted entry mode, combination of the 

Maemo for Mobile Developers 

Page 47: Qt for Maemo Developers Guide v0 5 Beta

alpha, numeric and special modes HILDON_GTK_INPUT_MODE_MULTILINE  the client contains multiple lines of text or 

accepts line breaks in the input HILDON_GTK_INPUT_MODE_INVISIBLE  do not echo or save the input in the IM when 

entering sensitive information such as passwords HILDON_GTK_INPUT_MODE_AUTOCAP  automatically capitalize the first letter at the start 

of a sentence HILDON_GTK_INPUT_MODE_DICTIONARY  enable predictive dictionaries and learning based 

on the input 

The code snippet below shows how to set up the input method for a password field: 

int mode = HILDON_GTK_INPUT_MODE_FULL|HILDON_GTK_INPUT_MODE_INVISIBLE; QInputContext qic = widget->inputContext(); qic->setInputMode(mode);

If you are developing a Custom widget capable to receive input text, you can set the widget to use  the  right  input method mode  just  returning  the mode  identifier.  If  the  Custom widget mode  property  is  not  set  properly,  the  IM  will  use  HILDON_GTK_INPUT_MODE_FULL  (the default mode) for that widget.   Setting the input method mode is quite easy. Check the code below for more understanding. The code snippet below shows how to do this.   #ifdef Q_WS_HILDON #include <QInputContext> #endif QVariant QAbstractSpinBox::inputMethodQuery(Qt::InputMethodQuery query) const { Q_D(const QAbstractSpinBox); switch(query) { case Qt::ImMode:{ int mode = HILDON_GTK_INPUT_MODE_NUMERIC; return QVariant(mode); } default: return d->edit->inputMethodQuery(query); } }

 

QDialogs: The Fremantle WM doesn't allow QDialogs without a parent (at least this is true for Qt apps). A dialog without a parent won't be shown by the WM. The code below should be avoided:  

QColorDialog::getColor ( Qt::white, 0 ); Use this code instead: 

QColorDialog::getColor ( Qt::white, this );

Maemo for Mobile Developers 

Page 48: Qt for Maemo Developers Guide v0 5 Beta

2 Porting a Qt application to Maemo 

 

  Porting  a Qt  application  from  desktop  environment  to Maemo  is  really  simple  and 

requires very little effort. In most cases the above relation is true, because the developer only 

needs to recompile the project to Maemo using the SDK. The Maemo style and Hildon look & 

feel are  implemented underneath  so  the developer doesn’t need  to  take care of  them. One 

example  is  the menu.  The  picture  below  shows  a menu  in  desktop  (smaller)  and Maemo 

(bigger). 

0  

 

  Although  it may be straightforward to port an application, some guidelines should be 

followed to get the best porting of the application to Maemo. These guidelines are explained 

below: 

The user may use fingers to interact with the application, this means the area of the UI 

elements should take this into account 

The  virtual  keyboard may  appear  on  the  screen when  the  focus  is  on  some  input 

widgets, so the dialogs should be arranged to fit in same screen. 

 

Avoid the use of absolute layout because in Maemo style, fonts and buttons are much 

larger to best fit the finger input 

If possible, avoid  to wrap a group of widgets  in a QScrollArea  in order  to  fit  then  in 

your dialogs 

 

Maemo for Mobile Developers 

Page 49: Qt for Maemo Developers Guide v0 5 Beta

You  can  get  more  information  about  porting  Qt  application  to  Maemo  here: 

http://wiki.maemo.org/Qt4_Hildon#Porting_a_Qt_application_to_Maemo. 

3 Uploading the application to Garage   Maemo offers a Garage (https://garage.maemo.org/) repository where developers can 

upload their applications to be available for all Maemo users.   There are two repositories for 

third‐party applications: the extras-devel and extras.  

extras-devel This  repository  is  the  first place  for applications which are 

under development. This repository  is  intended to packaging  testing of alpha 

and beta releases of applications. It should be used before the application gets 

mature  enough  to  go  to  extras  repository.  This  repository  is  not 

recommended  for  regular usage  since applications on  it are usually unstable 

and may  potentially  break  the  system.  You  can  add  the  extra‐devel  in  the 

tablet  by  opening  the  .install  (https://garage.maemo.org/extras‐

assistant/install/extras‐devel.install) link from it.  

extras This  repository  is  the  place  to  put  3rd‐party  applications  that  are 

stable  and  can  be  installed  on  internet  tablets  flawlessly.  To  upload  an 

application to this repository, the application should meet some requirements 

that  are  stated  at  Extras  Repository  Process  Definition 

(http://wiki.maemo.org/Extras_repository_process_definition).    More 

information  about  extras  repository  can  be  found  here: 

http://wiki.maemo.org/Extras_repository_process_definition. 

The upload process to extras and extras-devel requires an account at Garage 

web  site.  After  the  creation  of  this  account  you  can  upload  your  application  to  both 

repositories  following  the  instructions  found  here: 

http://wiki.maemo.org/Uploading_to_Extras.  After  this,  any  Internet  Tablet  owner with  the 

proper  repository configuration can use  the Maemo Application Manager search and  install 

the applications.  

4 Links  Qt software – http://www.qt.nokia.com/  

Qt4 maemo –  http://qt4.garage.maemo.org/  

Maemo 5  SDK – http://www.forum.nokia.com/info/sw.nokia.com/id/c05693a1‐265c‐

4c7f‐a389‐fc227db4c465/Maemo_5_SDK.html  

Maemo 5 Hildon Reference Manual – 

http://maemo.org/api_refs/5.0/beta/hildon/index.html  

Qt Documentation – http://doc.trolltech.com/  

Maemo training – http://maemo.org/development/training/ 

Forum Nokia Wiki – http://wiki.forum.nokia.com/index.php/Wiki_Home  

ESBox – http://esbox.garage.maemo.org/index.html  

 

Maemo for Mobile Developers 

Page 50: Qt for Maemo Developers Guide v0 5 Beta

 

Chapter 5 Using Maemo APIs in Qt applications 

1 Liblocation Location services have become a common feature in mobile applications. The Maemo platform 

provides  a  high  level  library  called  liblocation  to  allow  applications  to  easily  control  and 

retrieve data from the GPS. The  library provides methods to start and stop the GPS daemon, 

and allows the application to register  itself to  listen for GPS data changes, such as fix status, 

satellite information, position, speed and so on. 

It is completely different than the libgpsmgr, which is one of the libraries used to get location 

information  in the Diablo. The package containing  liblocation binaries  is the  liblocation0, but 

the package you must install to develop is the liblocation‐dev. 

At  the moment,  this  library  is  only  available  for Maemo  and  it  lies  on  the  nokia‐binaries 

repository for both Diablo and Fremantle releases. The library documented here is the version 

for Fremantle, as the Diablo version is a little different.  

The  package  containing  liblocation  binaries  is  the  liblocation0,  but  to  develop  applications 

using  the  lib,  it  is  needed  to  install  the  package  liblocation‐dev,  as  shown  below  (see  this 

section to learn how to add nokia‐binaries repository): 

$ apt-get install liblocation-dev

The summary of the package characteristics is shown below: 

Library name  liblocation 

Package name  liblocation0 

Development package  liblocation‐dev 

Last version of the package  0.94‐7+0m5 

Repository of the package  nokia‐binaries 

 

1.1 Main Classes and Methods liblocation provides two classes and one utility method as described below. 

1.1.1 LocationGPSDevice The LocationGPSDevice class allows applications  to  register  themselves  to  listen  to GPS data 

changes. Three different signals can be received: 

Maemo for Mobile Developers 

Page 51: Qt for Maemo Developers Guide v0 5 Beta

“changed”: emitted when any data has been changed; 

“connected”: emitted when device managed to connect to the location server; 

“disconnected”: emitted when device is disconnected from the location server. 

All signals have the same function signature, as shown below: 

void  user_function (LocationGPSDevice *device, gpointer user_data) 

The example  in  the next  session will  show  the code  to  register  the  functions  to  listen  these 

signals with g_signal_connect(). 

The  LocationGPSDevice  object  received  by  the  callback  functions  has  public  variables 

containing the GPS data provided by the API. The structure as defined in the class header file is 

shown below: 

typedef struct { gboolean online; LocationGPSDeviceStatus status; LocationGPSDeviceFix *fix; int satellites_in_view; int satellites_in_use; GPtrArray *satellites; LocationCellInfo *cell_info; } LocationGPSDevice;

The  “online”  flag  keeps  the  connection  status with  the  hardware.  If  it  is  TRUE,  the GPS  is 

connected. 

The  “status”  field  is  an  enumeration  with  the  GPS  fix  status: 

LOCATION_GPS_DEVICE_STATUS_FIX and LOCATION_GPS_DEVICE_STATUS_NO_FIX. 

The “satellites_in_view” field is the number of satellites the GPS device can see. 

The  “satellites_in_use”  field  is  the number of  satellites used  to  calculate  information  about 

location, speed, and others. 

The  “satellites”  field  contains  data  about  all  found  satellites.  This  is  an  array  of  structure 

LocationGpsDeviceSatellite, which contains satellite data. The structure as defined in the class 

header file is shown below: 

typedef struct { int prn; int elevation; int azimuth; int signal_strength; gboolean in_use; } LocationGPSDeviceSatellite;

 

 

Maemo for Mobile Developers 

Page 52: Qt for Maemo Developers Guide v0 5 Beta

The “cell_info” field is a structure of type LocationCellInfo containing the fields _gsm_cell_info 

and wcdma_cell_info, which provides  information  about  the mobile  telephony  cell  that  the 

device  in  connected.  With  more  than  one  cell  information,  is  possible  to  calculate  the 

approximate location. 

The  “fix”  field  is  a  structure  of  type  LocationGpsDeviceFix,  and  is  where  the  location 

information  lands. It contains  latitude,  longitude, altitude, current speed, current direction of 

motion  in degrees, and other  information. The structure as defined  in the class header file  is 

shown below: 

typedef struct { LocationGPSDeviceMode mode; guint32 fields; double time; double ept; double latitude; double longitude; double eph; double altitude; double epv; double track; double epd; double speed; double eps; double climb; double epc; } LocationGPSDeviceFix;

 

The most important fields of this structure are: 

“latitude”: the latitude coordinate value. 

 “longitude”:  the longitude coordinate value. 

 “altitude”: the altitude in meters. 

 “speed”: the current speed in km/h. 

 “track”: the current direction of motion in degrees (between 0 and 359). 

1.1.2 LocationGPSDControl This  class  is  responsible  for  controlling  the  location  service  daemon  (gpsd)  running  in  the 

device. This means that it can be used to start and stop the location services.  

The class  implements the singleton pattern, so the application can hold only one  instance of 

the  control  class.  To  get  the  singleton  object,  use  the  function 

location_gpsd_control_get_default() as shown below:  

LocationGPSDControl *control; 

control = location_gpsd_control_get_default(); 

Maemo for Mobile Developers 

Page 53: Qt for Maemo Developers Guide v0 5 Beta

The  application  can  start  and  stop  the  gpsd  daemon  with  the  methods 

location_gpsd_control_start() and location_gpsd_control_stop(), respectively. 

The LocationGPSDControl emits three signals:  

“error”:  emitted when an error has occurred; 

“gpsd_running”:  emitted after the location_gpsd_control_start has been called.; 

“gpsd_stopped”: emitted after the location_gpsd_control_stop has been called.  

The  application must  create  a  function  to  connect  to  the  signal.  The  function  signature  is 

shown below: 

void user_function(LocationGPSDControl *locationgpsdcontrol, gpointer user_data) 

Here,  locationgpsdcontrol  is the object that received the signal and the user_data  is the user 

data  set  when  the  signal  handler  was  connected.  See  the  GObject  documentation 

(http://library.gnome.org/devel/gobject/2.20/)  to know how  to  connect a user  function  to a 

signal. 

1.2 location­distance­utils The  library  also provides  an useful  function  to  calculate  the distance on  the  surface of  the 

earth  between  two  points.  This  function  is  called  location_distance_between()  and  can  be 

used like in the example below: 

double distance; double latitude_s = -37.1443 double longitude_s = -7.2554 double latitude_f = -38.6554 double longitude_f = -6.5778 distance = location_distance_between(latitude_s, longitude_s, latitude_f, longitude_f);

The function receives four double values, which represents the latitude/longitude coordinates 

of  two points. This  function also  returns a double value, which  is  the  calculated distance  in 

kilometers between the two points. 

1.3  Liblocation Example In order to archive a better understanding, the example was designed to have a very simple UI 

focusing more on  liblocation  functionalities. As shown on Figure 1,  the UI  is  just a  form  that 

will have the location data values updated based on liblocation events. 

Maemo for Mobile Developers 

Page 54: Qt for Maemo Developers Guide v0 5 Beta

 

Figure 1 – Liblocation example UI. 

This example was written using the GTK+ framework and uses libraries from hildon framework 

to  show  a  banner  on  the  screen.  The  full  example  can  be  downloaded  from  [here].  The 

example code is explained below. First, it is needed include the following header files: 

#include <gtk/gtk.h> #include <hildon/hildon-banner.h>

The main() method  initializes  the GTK+  framework and call  the methods  to build  the UI and 

setup the location API: 

int main( int argc, char *argv[] ) { /* Initialise GTK */ gtk_init (&argc, &argv); setupUi(); setupLocation(); gtk_main (); stopLocation(); return 0; }

The function setupUi() creates the GTK objects and build the application layout. First it creates 

the main  window  and  connects  its  destroy  signal  to  the  gtk_main_quit()  callback,  so  the 

application will exit when close button is pressed. 

Then, a GtkTable  is  created  to organize  the  labels as a grid. The  table here  consists of  two 

columns and five rows as shown in Figure 1.  

In order to change the window background color a GdkColor object  is  instantiated, having  its 

value defined  right after by  the gdk_color_parse()  function  that assigns  the gray color  for  it. 

Finally, the gtk_widget_modify_bg()function sets the given color as the background color. 

Maemo for Mobile Developers 

Page 55: Qt for Maemo Developers Guide v0 5 Beta

The  next  statement  adds  the  table widget  to  the window.  In  an  effort  to  archive  a  better 

modularization, this example defines a function to add a new row to the table and  initializes 

the UI with default values. 

Finally gtk_widget_show_all() displays all widgets on the window. 

void setupUi() { GtkWidget *frame; GtkWidget *label; GtkWidget *eventBox; window = gtk_window_new (GTK_WINDOW_TOPLEVEL); g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (gtk_main_quit), NULL); gtk_window_set_title (GTK_WINDOW (window), "LibLocation Example"); gtk_container_set_border_width (GTK_CONTAINER (window), 25); /* Create table */ table = gtk_table_new (4, 2, TRUE); gtk_table_set_col_spacings(GTK_TABLE (table), 20); gtk_table_set_row_spacings(GTK_TABLE (table), 10); GdkColor color; gdk_color_parse ("gray", &color); gtk_widget_modify_bg (window, GTK_STATE_NORMAL, &color); gtk_container_add (GTK_CONTAINER (window), table); addRow(0, "GPS Status", "No Fix"); addRow(1, "Satellites in use", "0"); addRow(2, "GeoPosition", NULL); addRow(3, "Altitude", NULL); addRow(4, "Speed", NULL); gtk_widget_show_all (window); }

The addRow() function is defined as follows: 

void addRow(guint rowPos, const gchar *key, const gchar *value) { GtkWidget *label; GtkWidget *eventBox; GdkColor color; label = gtk_label_new (key); gtk_table_attach (GTK_TABLE (table), label, 0, 1, rowPos, rowPos + 1, GTK_SHRINK, GTK_SHRINK, 0, 0); setRowValue(rowPos, value); }

This function adds a row by  instantiating a new GtkLabel and attaching  it to the table. As the 

last step it calls the setRowValue: 

Maemo for Mobile Developers 

Page 56: Qt for Maemo Developers Guide v0 5 Beta

void setRowValue(guint rowPos, const gchar *value) { GtkWidget *label; GtkWidget *eventBox; GdkColor color; label = gtk_label_new ( (value) ? value : " - " ); eventBox = gtk_event_box_new(); gtk_container_add (GTK_CONTAINER (eventBox), label); gtk_table_attach (GTK_TABLE (table), eventBox, 1, 2, rowPos, rowPos + 1, GTK_SHRINK | GTK_FILL, GTK_SHRINK, 20, 0); }

Now that the UI is created, the function setupLocation() will use the liblocation to register the 

example to retrieve  location data. To use the  liblocation you must  include  the  following two 

header files:  

/*including header files*/ #include <location/location-gps-device.h> #include <location/location-gpsd-control.h>

Now,  the  setupLocation()  function  will  use  the  classes  LocationGPSDevice  and 

LocationGPSDControl.  It  first  gets  the  LocationGPSDControl  object  with  the  function 

location_gpsd_control_get_default()  and  starts  it  with  the  function 

location_gpsd_control_start().  This  allows  the  example  to  control  the  GPS  Daemon  control 

starting the GPS service in the device. Afterwards, the example creates the LocationGPSDevice 

object and register itself to receive notifications about location data changes: 

void setupLocation() { LocationGPSDControl* control; control = location_gpsd_control_get_default(); location_gpsd_control_start(control); LocationGPSDevice* device; device = g_object_new(LOCATION_TYPE_GPS_DEVICE, NULL); g_signal_connect(device, "changed", G_CALLBACK(location_changed), NULL); g_signal_connect(device, "connected", G_CALLBACK(location_connected), NULL); g_signal_connect(device, "disconnected", G_CALLBACK(location_disconnected), NULL); }

When  the  “connected”  and  “disconnected”  signals  are  received,  the  callback  functions only 

show a hildon banner to update the user about the new state: 

static void location_connected( LocationGPSDevice* device, gpointer userdata) { hildon_banner_show_information(GTK_WIDGET (window), "GPS Connected", "GPS Connected");

Maemo for Mobile Developers 

Page 57: Qt for Maemo Developers Guide v0 5 Beta

} static void location_disconnected( LocationGPSDevice* device, gpointer userdata) { hildon_banner_show_information(GTK_WIDGET (window), "GPS Connected", "GPS Disconnected"); }

On  the other hand, when  the  “changed”  signal  is  received,  the UI  is updated with  the new 

data:  

static void location_changed( LocationGPSDevice* device, gpointer userdata) { handleStatus( device->status ); handleSatellites( device->satellites_in_view, device->satellites_in_use, device->satellites); handleDeviceFix ( device->fix ); } The location_changed() method was divided into three procedures. The first two are as follow: static void handleStatus( LocationGPSDeviceStatus status ) { /* Handle Status Changed */ if (status == LOCATION_GPS_DEVICE_STATUS_NO_FIX) { setRowValue(0, "No Fix"); } else { setRowValue(0, "Fixed"); } } static void handleSatellites(int satellites_in_view, int satellites_in_use, GPtrArray *satellites) { /* Handle satellites in view */ gchar* numSatellites = g_strdup_printf("%i", satellites_in_use); setRowValue(1, numSatellites); g_free(numSatellites); }

The handleStatus() function handles the status of the GPS device indicating if it has connected 

to enough satellites to calculate the position. The handleSatellites() function updates the UI to 

indicate the number of satellites the GPS device is connected with. 

The last function, handleDeviceFix (), is set out below: 

static void handleDeviceFix ( LocationGPSDeviceFix *fix ) { gchar* location = NULL; gchar* altitude = NULL; gchar* speed = NULL;

Maemo for Mobile Developers 

Page 58: Qt for Maemo Developers Guide v0 5 Beta

switch(fix->mode) { case LOCATION_GPS_DEVICE_MODE_NOT_SEEN: case LOCATION_GPS_DEVICE_MODE_NO_FIX: break; case LOCATION_GPS_DEVICE_MODE_3D: /* Testing if the altitude field of LocationGPSDeviceFix is valid. */ if (fix->fields & LOCATION_GPS_DEVICE_ALTITUDE_SET) { altitude = g_strdup_printf("%.2f m", fix->altitude); } case LOCATION_GPS_DEVICE_MODE_2D: /* Testing if the latitude and longitude fields of LocationGPSDeviceFix are valid. */ if (fix->fields & LOCATION_GPS_DEVICE_LATLONG_SET) { gchar latitude = (fix->latitude >= 0)?'N':'S'; gchar longitude = (fix->longitude >= 0)?'E':'W'; location = g_strdup_printf("%.2f° %c\n%.2f° %c", ABS(fix->latitude), latitude, ABS(fix->longitude), longitude); } break; } /* Testing if the speed field of LocationGPSDeviceFix is valid. */ if (fix->fields & LOCATION_GPS_DEVICE_SPEED_SET) { speed = g_strdup_printf("%.2f Km/h", fix->speed); } setRowValue(2, location); setRowValue(3, altitude); setRowValue(4, speed); g_free(location); g_free(altitude); g_free(speed); }

This  function  formats  the  location,  altitude  and  speed  information  retrieved  from  the 

LocationGPSDeviceFix structure. In case of GPS device not be able to see any satellites nor fix, 

the output of the location will be the default, “ ‐“.  

In case of being working on 2D mode  (none altitude  information),  the  function checks  if  the 

latitude and longitudes fields are valid and formats the output in such a way that if latitude is 

negative,  the  letter S  from South  is shown  followed by  the absolute value of  the  location.  It 

does the same way with the longitude, applying instead of S the letter W from West. 

If working  on  3D mode,  the  function  also  checks  if  the  altitude  field  is  valid  and  sets  the 

respective field on UI in addition to longitude and latitude. 

The last step is to release gchar resources by calling the g_free() function. 

There are other location data available in the LocationGPSDevicestructure. You can access the 

other values in the same way. 

Maemo for Mobile Developers 

Page 59: Qt for Maemo Developers Guide v0 5 Beta

1.4 Links  Liblocation reference manual: http://maemo.org/api_refs/5.0/beta/liblocation/ 

Python liblocation: http://brewer123.home.comcast.net/~brewer123/projects/nokia/ 

Using liblocation: 

http://maemo.org/maemo_release_documentation/maemo4.1.x/node10.html#SECTI

ON001027000000000000000 

GPSJinni application: http://maemo.org/downloads/product/OS2008/gpsjinni/ 

libgpsmgr API reference: http://maemo.org/api_refs/4.1/libgpsmgr‐0.2/ 

2 Libcityinfo 

The libcityinfo API can be used to get information about a large set of cities around the world. 

The information is stored in ASCII format database inside the device. The following information 

can be accessed through libcityinfo API: 

City name; 

Country name (in which the city is placed); 

Country code; 

Time zone; 

Geographical position; 

Position on the map of clocks world map image; 

Locale used in country. 

2.1 Example 

The following example displays the names of all countries available in the database. The 

application also contains a filter edit line to find the country name. The list is constructed using 

the function cityinfo_get_all(). The Qt class QListWidget is inherited and its subclass creates a 

slot to update the list according to the typed string in the edit line. The most important classes 

of this example APIs are: libcityinfo, QListWidget and QLineEdit. 

 

Maemo for Mobile Developers 

Page 60: Qt for Maemo Developers Guide v0 5 Beta

The example contains two source files (main.cpp and QCityInfoWidget.cpp) and one header 

(QCityInfoWidget.h). The QCityInfoWidget class is derived from QListWidget. The source code 

is shown below. 

//QCityInfoWidget.h #ifndef QCITYINFOWIDGET_H #define QCITYINFOWIDGET_H #include <QListWidget> class QCityInfoWidget : public QListWidget { Q_OBJECT public: QCityInfoWidget(); public slots: void findSearchedString(const QString& searchString ); }; #endif // QCITYINFOWIDGET_H // QCityInfoWidget.cpp #include <cityinfo.h> #include "QCityInfoWidget.h" QCityInfoWidget::QCityInfoWidget(): QListWidget() { Cityinfo** cityArray = cityinfo_get_all(); for (int i = 0; cityArray != NULL && cityArray[i] != NULL; ++i) { addItem( QString(cityinfo_get_country( cityArray[i] )) ); } } void QCityInfoWidget::findSearchedString( const QString& searchString ) { QList<QListWidgetItem *> listItem = findItems ( searchString, Qt::MatchStartsWith ); if( listItem.count() > 0 ) { scrollToItem( listItem[0] ); } }

The class defines a public slot (findSearchedString) to be connected with a signal from the 

QLineEdit class. This slot is used to scroll the list to the item that starts with the string typed of 

the box. 

Maemo for Mobile Developers 

Page 61: Qt for Maemo Developers Guide v0 5 Beta

In the constructor of the QCityInfoWidget, the list is populated with the country names using 

the addItem() method of the superclass. The registries are accessed using the cityinfo_get_all() 

call. The country names are then accessed through the function cityinfo_get_country(). 

The main file defines the layout of the screen. In this example, the graphical elements are 

displayed horizontally or vertically. Thus, QHBoxLayout and QVBoxLayout are used as screen 

layouts.  

On main method, the slot of the QCityInfoWidget class is connected with QLineEdit 

textChanged by using QObject::connect. The main.cpp source is shown below: 

#include <QApplication> #include <QLineEdit> #include <QLabel> #include <QHBoxLayout> #include <QListWidget> #include <QHeaderView> #include "QCityInfoWidget.h" int main(int argc, char *argv[]) { QApplication app(argc, argv); QWidget window; window.show(); QLabel *queryLabel = new QLabel(QString("Filter:")); QLineEdit *queryEdit = new QLineEdit(); QCityInfoWidget* listWidget = new QCityInfoWidget(); listWidget->setSelectionMode(QAbstractItemView::MultiSelection); QObject::connect(queryEdit, SIGNAL(textChanged ( const QString&) ), listWidget, SLOT(findSearchedString( const QString& ))); QHBoxLayout *queryLayout = new QHBoxLayout(); queryLayout->addWidget(queryLabel); queryLayout->addWidget(queryEdit); QVBoxLayout *mainLayout = new QVBoxLayout(); mainLayout->addLayout(queryLayout); mainLayout->addWidget(listWidget); window.setLayout(mainLayout); return app.exec(); }

And the .pro file: 

Maemo for Mobile Developers 

Page 62: Qt for Maemo Developers Guide v0 5 Beta

TEMPLATE = app TARGET = DEPENDPATH += . INCLUDEPATH += . /usr/include/glib-2.0/glib /usr/include/glib-2.0/ /usr/lib/glib-2.0/include LIBS += -lcityinfo0 -lglib-2.0 # Input HEADERS += QCityInfoWidget.h SOURCES += main.cpp QCityInfoWidget.cpp

 

3 mce­dev Some Maemo applications often need to get information about the device mode. For example, 

an application needs  to know  if device  is on offline mode  in a meeting  time and,  if not,  the 

device mode should be changed to the correct one.  

Maemo  development  environment  provides  mechanisms  to  manage  the  device  mode.  It 

provides  the Mode  Control  Entity,  which manages  the  device mode.  In  addition, Maemo 

development  environment  provides  DBus  interfaces  to  the  Mode  Control  Entity,  so  the 

developer can easily use  it on his application.  It means that the developer can control or get 

information  about  device mode  through  DBus messages.  For  example,  the  developer  can 

query the inactivity status or request to blank the screen. 

The package which contains mce development  files  is  the mce‐dev package.  It  is required  to 

install such package on your development environment to use MCE DBus interfaces. However, 

both Diablo and Fremantle commonly have MCE development packages already installed.  

To install mce‐dev files, use the following command (see this section to learn how to add 

nokia‐binaries repository): 

#apt-get install mce-dev

The summary of the package characteristics is shown below: 

Library name  mce 

Package name  mce‐dev 

Development package  mce‐dev 

Last version of the package  1.6.3 

Repository of the package  fremantle/sdk free 

 

Maemo for Mobile Developers 

Page 63: Qt for Maemo Developers Guide v0 5 Beta

The MCE  defines  two  header  files  that  can  be  used  in  the  development  process:  “dbus‐

names.h” and “mode‐names.h”. The “dbus‐names.h”  file contains names definition  required 

to send messages through DBus (it will be explained in details later). The “mode‐names.h” file 

contains names definition of modes and states. 

3.1 MCE headers files The “dbus‐names.h” header file contains MCE service name, paths and  interfaces required to 

create a proxy object for the DBus driver. They are summarized on the following table: 

Macro  Value  Description 

MCE_SERVICE  "com.nokia.mce"  MCE D‐Bus service 

MCE_REQUEST_IF "com.nokia.mce.request"  MCE  D‐Bus  Request 

interface 

MCE_SIGNAL_IF  "com.nokia.mce.signal"  MCE D‐Bus Signal interface 

MCE_REQUEST_PATH  "/com/nokia/mce/request"  MCE D‐Bus Request path 

MCE_SIGNAL_PATH  "/com/nokia/mce/signal"  MCE D‐Bus Signal path 

 

Note that names for signal and for requests are listed above. The service name is the same for 

both, but the interface and the path differs from each other.  

File  “dbus‐names.h” also defines names  for MCE DBus methods and MCE DBus  signals. The 

MCE  DBus methods  names  are  used  to  request  changes  in  the  device mode  or  query  for 

information. The DBus signals names are the names used to get connected with a signal and 

observe changes on device mode.  

File  “mode‐names.h”  contains  current  values  for  Internet  Tablet  mode.  These  modes  are 

returned  by  methods  used  to  query  about  device  mode,  for  example  the  method 

"get_device_mode". Existing Internet Tablet modes are summarized on the following table: 

Macro  Value  Description 

MCE_NORMAL_MODE  "normal"  Normal device mode 

MCE_FLIGHT_MODE  "flight" Offline device mode; 

RF's disabled 

MCE_OFFLINE_MODE  "offline" 

Offline device mode; 

RF's disabled; alias for 

flight mode 

MCE_INVALID_MODE  "invalid" invalid device mode; 

this should never occur 

Maemo for Mobile Developers 

Page 64: Qt for Maemo Developers Guide v0 5 Beta

3.2 Qt mce­dev example MCE API  for Maemo only provides a DBus  interface, which consists of methods and  signals. 

Thus,  in  order  to  use  MCE,  DBus  is  required.  In  this  section,  one  example  is  used  to 

demonstrate  how MCE  can  be  used  on  Qt  applications.  This  example  does  a  simple MCE 

method call and also  listens to a MCE signal. The full example will be available for download 

later.  

The  example  contains  a  button  and  a  label. When  button  is  pressed,  the  screen  becomes 

totally blanked. We simply change the state of Internet Tablet display to OFF, by using method 

"req_display_state_off" of MCE API. This example also connects a function to a signal.  In this 

case, the function  is called whenever device mode  is changed (“normal”, “flight”, “offline” or 

“invalid”). In addition, this example also changes the text of a label widget. 

This example has two files: “mce_example.cpp” and “mce_example.h”. The “mce_example.h” 

file  is shown below. This  file contains declarations of a class, variables, slots, and a method. 

The class inherits from QWidget, which is required to create Qt GUI applications, and then the 

QWidget header file must be included. Slots are declared in this file as well, so the Q_OBJECT 

macro must be called and the QObject header file must be included. 

Two slots are declared in the class: cb_func and button_callback. The cb_func slot is connected 

to  the  signal  emitted when  the mode of  the device  is  changed.  The button_callback  slot  is 

connected  to  the signal emitted when  the button  is clicked. The method connect_to_mce  is 

used to connect the cb_func slot to a MCE signal. 

#ifndef QT_SIGNAL_H #define QT_SIGNAL_H #include <QObject> #include <QDBusMessage> #include <QWidget> class MCEExample : public QWidget { Q_OBJECT public: MCEExample(QWidget *parent = 0); ~MCEExample(); public: void connect_to_mce(); public slots: void cb_func(const QDBusMessage& rep); void button_callback(); }; #endif // QT_SIGNAL_H

The “mce_example.cpp” file contains the implementation of the class and methods declared in 

the  “mce_example.h”  header  file.  At  first,  the  required  header  files  are  included.  The 

Maemo for Mobile Developers 

Page 65: Qt for Maemo Developers Guide v0 5 Beta

“QApplication”, “QLabel”, “QPushButton”, and “QVBoxLayout” files are used to create the Qt 

QUI.  The  “QDBusInterface”,  “QDBusConnection”  and  “mce/dbus‐names.h”  files  are  used  to 

create a connection to a DBus signal and a remote call to a MCE method: 

#include <mce_example.h> #include <QApplication> #include <QLabel> #include <QPushButton> #include <QVBoxLayout> #include <QDBusInterface> #include <QDBusConnection> #include <mce/dbus-names.h>

Two variables are declared as static because  they are used  in more  than one method  in  the 

code. The connection variable  is used  in the button callback function and the  label variable  is 

used in the function connected to the MCE signal: 

static QDBusConnection connection = QDBusConnection::systemBus(); static QLabel *label;

The constructor of the class is shown below. Here, a button and a label are created: 

MCEExample::MCEExample(QWidget *parent): QWidget(parent){ label = new QLabel("Device mode :"); QPushButton *button = new QPushButton("Blank screen"); connect(button, SIGNAL(clicked()), this, SLOT(button_callback())); QVBoxLayout *layout = new QVBoxLayout; layout->addWidget(label, 0, Qt::AlignHCenter); layout->addWidget(button); setLayout(layout); }

The signal emitted when the button is pressed is connected to the method button_callback(), 

which is shown below. In this method, a QDBusInterface is created and it is used to make the 

call of the remote MCE method MCE_DISPLAY_OFF_REQ, which requests the device to change 

its screen status: 

void MCEExample::button_callback() { QDBusInterface mce_if(MCE_SERVICE, MCE_REQUEST_PATH, MCE_REQUEST_IF, connection); mce_if.call(MCE_DISPLAY_OFF_REQ); }

The  following  method  is  used  to  connect  the  method  cb_func()  to  the  MCE  signal 

MCE_TKLOCK_MODE_SIG, which returns the device mode:  

void MCEExample::connect_to_mce() {

connection.connect(MCE_SERVICE, MCE_SIGNAL_PATH, MCE_SIGNAL_IF, MCE_TKLOCK_MODE_SIG,

Maemo for Mobile Developers 

Page 66: Qt for Maemo Developers Guide v0 5 Beta

this, SLOT(cb_func(const QDBusMessage&)));

}

The cb_func() method only receives the mode name and set it to the label: 

void MCEExample::cb_func(const QDBusMessage& rep) { label->setText("Device mode :" + rep.arguments().value(0).value<QString>()); }

The  main  function  is  shown  below.  It  creates  the  application,  creates  an  instance  of 

MCEExample and starts the application: 

int main(int argc, char* argv[]){ QApplication app(argc,argv); MCEExample example; example.call_remote_method(); example.show(); return app.exec(); }

Finally, to compile this example, include the qdbus name to the CONFIG key in the “.pro” file: 

CONFIG =+ qdbus

To run this application on device you will need to  install qtgui and  libqtdbus. A screenshot of 

the application is shown below: 

 

4 Calendar­backend The Calendar‐backend library allows the developer to manage calendars and events. Such 

library provides a C++ API to create a calendar and add events, birthdays, journal, or to‐do´s, 

including attendees and organizers. 

Maemo for Mobile Developers 

Page 67: Qt for Maemo Developers Guide v0 5 Beta

All the calendar data is stored in the SQLite (http://www.sqlite.org/) database of the device. 

The Calendar‐backend library provides mechanisms to interact with database by using 

methods implemented by CCalendarDB class. This library also interacts with alarm daemon 

and it stores the alarm data in the local calendar database using CAlarm class methods. 

Calendar‐backend is a closed library and it is available on Nokia‐binaries meta‐package. 

Therefore, it is necessary to configure Nokia‐binaries local repository to install it. 

The first implementation of this library was in the Fremantle. The package containing calendar 

backend libraries is the calendar‐backend, and the files needed to develop applications are in 

the package calendar‐backend‐dev. To install Calendar‐backend packages on your 

environment, execute the following commands: 

# apt-get install calendar-backend

# apt-get install calendar-backend-dev

The summary of the package characteristics is shown on the following table: 

Library name  Calendar backend 

Package name  calendar‐backend 

Development package  calendar‐backend‐dev 

Last version of the package  0.5‐8.12+0m5 

Repository of the package  nokia‐binaries 

 

4.1 Main Classes and Methods The calendar backend library contains several classes that help the developer to create 

calendar and add events. The most important classes are CMulticalendar, CCalendar, and the 

classes derived from CComponent. 

The CMulticalendar class is the main element to access the calendar backend. Only one 

instance of CMulticalendar is allowed per process. The instance of CMulticalendar can be 

retrieved by using the static method MCInstance(). Once you have access to CMulticalendar 

instance, it is possible to: 

add a calendar with the method addCalendar(); 

delete a calendar with the function deletCalendar(); 

get a calendar by name or by ID using the functions getCalendarByName() and 

getCalendarById()  respectively.  

However, before adding a calendar to the CMulticalendar, you have to create a CCalendar. This 

class allows the developer to add, modify or delete components such as event, to‐do´s , 

journal or birthdays. It is possible to set the next alarm event with the method setNextAlarm(). 

Maemo for Mobile Developers 

Page 68: Qt for Maemo Developers Guide v0 5 Beta

The CCalendar type can be set to Local calendar, Sync calendar or Smart calendar by using the 

method setCalendarType(). The current CCalendar type can be obtained by method 

getCalendarType(). 

The components, which can be added to the calendar, inherit from the class CComponent. This 

class contains methods to get or set parameters for any event, to‐do, journal or birthday. For 

example, the developer can set the ID of the component by using the method setId().  

The event type that can be added to the calendar are: CBdayEvent, CEvent, CJournal, and 

CTodo.  Each of these classes has a set of common methods inherited from the base class 

CComponent and they have their own specific methods. For example, the CEvent class 

provides method method setGeo() that allows the developer to set the location (latitude and 

longitude) parameter. Other example is the class CBdayEvent, which allows the developer to 

set the birth date by using method setBirthDate(). 

Calendar‐backend library also contains the class ICalConverter, used to convert local database 

format to iCal (http://www.apple.com/support/ical/) data and vice versa. VCalConverter  is 

other class which converts local database format to other format. This class converts local 

database format to vCal format and vice versa. 

You can found more information about other classes, such as CCalendarDB, on API reference 

of calendar backend (http://maemo.org/api_refs/5.0/beta/calendar‐backend/index.html). 

4.2 Example The example used in this section is a simple calendar. It is implemented in Qt and it also uses 

the Calendar‐backend API.  The example manages a calendar such as the one illustrated on the 

following pictures: 

 

 After creating a calendar, the application allows the management of events: 

Maemo for Mobile Developers 

Page 69: Qt for Maemo Developers Guide v0 5 Beta

 

The events, to‐do´s or birthdays can be visualized. It is possible to create new elements as well: 

 

The example contains the following files (available for download later): 

main.cpp: creates the Qt application and initializes calendar widget; 

widget.h: contains declaration of names and methods to be implementated on 

“widget.cpp” file;  

widget.cpp: implements of main screen; 

eventdialog.h: contains declaration of names and methods to be implementated on 

“eventdialog.cpp” file; 

eventdialog.cpp: implements event creation screen; 

calendar.h: contains declaration of names and methods used on calendar.cpp file; 

calendar.cpp: direclty accesses Calendar‐backend API.  

The content of file “calendar.h” is shown below. This file declares class Calendar, including 

variables and methods. This class inherits from QObject, which is the superclass for all Qt 

applications. Then, it is necessary to add QObject hearder file. In this application, the date and 

the time are managed in some functions, thus QDateTime header file must be included too.  

Maemo for Mobile Developers 

Page 70: Qt for Maemo Developers Guide v0 5 Beta

This header file also contains the declaration of five methods: addCalendar, removeCalendar, 

addEvent, getEventsDays, and getEventsDescription. 

#ifndef CALENDAR_H #define CALENDAR_H #include <QObject> #include <QDateTime> class CCalendar; class CMulticalendar; class CComponent; class Calendar : public QObject { Q_OBJECT public: Calendar(); ~Calendar(); public: bool addCalendar(const QString& calendarName); bool removeCalendar(const QString& calendarName); void addEvent(const QString& calendarName, const QDateTime& date, const QString& eventName, const QString& description, int type); /* Returns a list of dates that have events.*/ QList< QDate > getEventsDays(const QString& calendarName, int type, const QDateTime& startDate, const QDateTime& endDate); /* Returns a list of events descriptions.*/ QList<QString> getEventsDescription(const QString& calendarName, int type, const QDateTime& date); private: CMulticalendar* multiCalendar; }; #endif // CALENDAR_H

 

The “calendar.cpp” file contains the implementation of the functions declared in the header 

file Calendar.h. At first, insert the required header files (calendar.h, CCalendar.h, etc.). These 

files provide methods to manage calendars, multicalendars, events, to‐do´s, and birthdays: 

#include "calendar.h" #include <CCalendar.h>

Maemo for Mobile Developers 

Page 71: Qt for Maemo Developers Guide v0 5 Beta

#include <CMulticalendar.h> #include <CTodo.h> #include <CBdayEvent.h> #include <CEvent.h>

The variable DAY_IN_SECONDS is declared to be used in some methods: 

static const int DAY_IN_SECONDS = 86400;

In Calendar class constructor, a single instance of a CMulticalendar is retrieved by using the 

method MCInstance() of CMulticalendar: 

Calendar::Calendar() { multiCalendar = CMulticalendar::MCInstance(); }

The destructor deletes the CMulticalendar instance: 

Calendar::~Calendar() { delete multiCalendar; }

The method addCalendar adds a calendar to the CMulticalendar instance. This function 

receives a string representing the calendar name to be added. To add a calendar, the method 

addCalendar() of CMulticalendar must be used. This method receives the following parameters 

in sequence: calendar title, color, flag for read only, flag for visible, type (0 for Local calendar, 1 

for Sync calendar or 2 for Smart calendar), the tune which will be played in alarms, string for 

calendar version, and the reference to the error code. When an error occurs, the value of the 

errorCode is set to 0: 

bool Calendar::addCalendar(const QString& calendarName) { CalendarType type = (CalendarType) 0; int errorCode = 0; multiCalendar->addCalendar (calendarName.toStdString(), COLOUR_RED, 0, 1, type , "Default", "0.1", errorCode); return (errorCode); }

The method removeCalendar() is used to remove a calendar from the CMultiCalendar instance. 

This method receives the name of the calendar to be removed and uses the method 

deleteCalendar() of CMultiCalendar to delete the calendar. The method deleteCalendar() 

receives a calendar ID and a reference to error code. To get the calendar ID, a calendar 

instance is required. The CMultiCalendar allows the developer to get an instance of CCalendar 

by using the method getCalendarByName(), which receives the name of the calendar and a 

Maemo for Mobile Developers 

Page 72: Qt for Maemo Developers Guide v0 5 Beta

poiters to error code. Then, the ID of the calendar can be obtained with the method 

getCalendarId() of CCalendar. 

bool Calendar::removeCalendar(const QString& calendarName) { int errorCode = 0; bool success = false; CCalendar *calendar = multiCalendar->getCalendarByName (calendarName.toStdString(), errorCode); if (errorCode) { success = multiCalendar->deleteCalendar (calendar->getCalendarId(), errorCode); } delete calendar; return success; }

 

The method addEvent() add an event (to do, birthday or event) to a calendar. This method 

receives four parameters which are: the name of the calendar in which the event will be 

added, the date of the event, the name of the event, the description of event and the type of 

event, which should be 0 for to do, 1 for birthday and 2 for event. The methods used to add 

events are addTodo(), addBirthDay(), or addEvent() from CMultiCalendar. These methods 

receive an instance of CTodo, CBdayEvent, or CEvent respectively. Each of these classes 

receives in constructor the summary of the event, the due date and, in some cases, the status. 

The possible values for status are: NEEDSACTION_STATUS , COMPLETED_STATUS, 

INPROCESS_STATUS, CANCELLED_STATUS, CONFIRMED_STATUS, TENTATIVE_STATUS, 

DRAFT_STATUS, FINAL_STATUS, SENT_STATUS, DECLINED_STATUS, DELEGATED_STATUS, or 

ACCEPTED_STATUS.  

void Calendar::addEvent(const QString& calendarName, const QDateTime& date, const QString& eventName, const QString& description, int type) { int errorCode = 0; int dateUtc = date.toTime_t(); CCalendar *calendar = multiCalendar->getCalendarByName (calendarName.toStdString(), errorCode); switch (type) { case 0: { CBdayEvent *pBdayEvent = new CBdayEvent(eventName.toStdString(), eventName.toStdString(), dateUtc); calendar->addBirthDay(pBdayEvent, errorCode); delete pBdayEvent; } break; case 1: { CEvent *pEvent = new CEvent(eventName.toStdString(), description.toStdString(), "", dateUtc, dateUtc);

Maemo for Mobile Developers 

Page 73: Qt for Maemo Developers Guide v0 5 Beta

multiCalendar->addEvent(pEvent, calendar->getCalendarId(), errorCode); delete pEvent; } break; case 2: { CTodo *pTodo = new CTodo(eventName.toStdString(), dateUtc, ACCEPTED_STATUS); multiCalendar->addTodo(pTodo, calendar->getCalendarId(), errorCode); delete pTodo; } break; } delete calendar; }

The method getEventsDays() receives the calendar name, the type of the component (1 for 

event, 2 for to do, or 3 to journal), the start date and the end date. The returned value is a 

vector containing the dates of events:  

QList< QDate > Calendar::getEventsDays(const QString& calendarName, int type, const QDateTime& startDate, const QDateTime& endDate) { int errorCode = 0; type = (type) ? type : 4; CCalendar *calendar = multiCalendar->getCalendarByName (calendarName.toStdString(), errorCode); vector< CComponent * > components; components = multiCalendar->getComponents(calendar->getCalendarId(), type, startDate.toTime_t(), endDate.toTime_t(), errorCode); QList<QDate> componentsVector; for (vector<CComponent *>::iterator it = components.begin();it!=components.end(); ++it) { QDateTime date = QDateTime::fromTime_t ( (*it)->getDateStart() ); componentsVector.append(date.date()); } return componentsVector; }

 

Maemo for Mobile Developers 

Page 74: Qt for Maemo Developers Guide v0 5 Beta

The method getEventsDescription() receives three parameters: the calendar name, the type of 

the component (1 for event, 2 for to do, or 3 to journal), and the date of events. The returned 

value is a vector containing the description of the events of the specified date: 

 

QList<QString>Calendar::getEventsDescription(const QString& calendarName, int type, const QDateTime& date) { int errorCode = 0; type = (type) ? type : 4; CCalendar *calendar = multiCalendar->getCalendarByName (calendarName.toStdString(), errorCode); vector< CComponent * > components; components = multiCalendar->getComponents (calendar->getCalendarId(), type, date.toTime_t(), date.toTime_t() + DAY_IN_SECONDS, errorCode); QList<QString> componentsVector; for (vector<CComponent *>::iterator it = components.begin();it!=components.end(); ++it) { QString output; QDateTime date = QDateTime::fromTime_t ( (*it)->getDateStart() ); output.append(date.toString(Qt::SystemLocaleShortDate)); output.append(" - "); output.append(QString::fromStdString((*it)->getSummary())); output.append("\n"); output.append(QString::fromStdString((*it)->getDescription())); componentsVector.append(output); } return componentsVector; }

 

4.3 Links  SQLite ‐ http://www.sqlite.org/ 

Calendar backend ‐ http://maemo.org/api_refs/5.0/beta/calendar‐

backend/index.html 

Maemo for Mobile Developers 

Page 75: Qt for Maemo Developers Guide v0 5 Beta

5 ICD2 

5.1 Introduction   The Internet Connection Daemon 2 (ICd2) is responsible to manage connections to the internet  on  Maemo.  It  helps  developers  by  providing  an  abstract  layer  to  be  used  on applications that needs to get connected on  internet. It  is  initialized at system boot time and stopped at system shutdown by /etc/init.d/icd2 init script.   The main  concept  behind  internet  connections  on Maemo  devices  is  the  Internet Access  Point  (IAP).  As  described  in  (Maemo.org,  2009),  IAP  represents  a  logical  internet connection defined by the user.  It defines, among other things, the radio bearer, procedures for authentication, proxy servers and the corresponding access point in the internet.   ICd2 API defines methods  to  retrieve  information about  system  connections besides requesting a  connection,  initiate  scan procedures and  request  connection  state.  Such API  is proprietary, becoming impossible to compile it and run on other platforms or in standard Linux as well.  Although, it provides header files to be include in C and C++ source codes. The latest version is 0.85+0m5 and it is compatible with Diablo and Fremantle Maemo SDK versions. It is simple and it has only three header files to be exported.   ICd2  is a D‐Bus API,  internal to the connectivity subsystem and  it  is used by LibConic and  connectivity  UIs.  LibConic  is  indicated  to  be  used  instead  of  requesting  network connections by interacting directly with ICd2 since it is the stable maintained API for network connectivity,  which  encapsulates  D‐Bus  calls.  As  pointed  by  (Maemo.org,  2009),  ICd2  is considered to be  in alpha state and  it may change without further notice. Despite that, using LibConic becomes harder  if  the code has  to be written  in Qt, once LibConic  is written using Glib, what incurs in a problem of two main loops needing to run concurrently.  In addition, Qt provides an easy way  to call methods or  receive signals  from D‐Bus  through QtDBus  library. Considering that, this documentation focus on ICd2 usage linked to Qt through D‐bus.   Once this API works through D‐Bus, it is better to test codes on target device. It is also necessary  to  check  if  environment  settings  are  correctly  defined,  which  would  lead  to  a problem of connecting to this service.   This  API  also makes  it  possible  to write  new  Network  or  Service modules  and  run Debian‐style  network  scripts  to  be  executed  before  and/or  after  a  network  connection  is connected and disconnected.   A Network module has three layers: the link layer, the authentication layer and the IP layer. A module can choose to implement functions on one or more layer. It is necessary to a link  layer module  to  implement  network  search  functionality, which  reports  to  ICd2 what networks are available.   Service modules provide functionalities that are often used after  IP address has been acquired, such as authentication for WLAN hotspot logins.    

5.2 Architecture  ICd2 API has three modules: Network module API definitions, Service Provider API and 

ICd2 D‐Bus API. The first one  is used to define the network  itself regarding the  link  layer, the 

authentication layer and/or the IP Layer.  

The Service Provider API provides an  identification  function, which  receives network 

module search results and returns service module information if the service module is able to 

use the network (Maemo.org, 2009). 

The ICd2 D‐Bus API generates responses to D‐Bus API requests. It also creates IAP’s and 

it selects the right networks associated with it.  

 

Maemo for Mobile Developers 

Page 76: Qt for Maemo Developers Guide v0 5 Beta

5.3 Main Classes and Methods   This documentation is focused on using the ICd2 D‐bus API to call methods from Qt 

using QtDBus library. The main methods of this module are: 

ICD_DBUS_API_ADDRINFO_REQ   "addrinfo_req" Requests specific connection addresses info.  Callback:ICD_DBUS_API_ADDRINFO_SIG   "addrinfo_sig" 

o DBUS_TYPE_STRING           service type or empty string o DBUS_TYPE_UINT32           service attributes, see o DBUS_TYPE_STRING           service id or empty string o DBUS_TYPE_STRING           network type or empty string o DBUS_TYPE_UINT32           network attributes, see o DBUS_TYPE_ARRAY (BYTE)     network id or empty string o DBUS_TYPE_ARRAY ( o    DBUS_TYPE_STRING        IP address o    DBUS_TYPE_STRING        IP netmask o    DBUS_TYPE_STRING        IP default gateway o    DBUS_TYPE_STRING        IP address of DNS server #1 o    DBUS_TYPE_STRING        IP address of DNS server #2 o    DBUS_TYPE_STRING        IP address of DNS server #3 o ) 

 

ICD_DBUS_API_CONNECT_REQ  "connect_req" Requests a network connection. It makes ICd2 to select a suitable connection or try the specified connection.  Callback: ICD_DBUS_API_CONNECT_SIG "connect_sig" 

o DBUS_TYPE_STRING              service type or empty string o DBUS_TYPE_UINT32              service attributes o DBUS_TYPE_STRING              service id or empty string o DBUS_TYPE_STRING              network type or empty string o DBUS_TYPE_UINT32              network attributes o DBUS_TYPE_ARRAY (BYTE)        network id or empty string o DBUS_TYPE_UINT32              status 

 

ICD_DBUS_API_DISCONNECT_REQ   "disconnect_req" Requests to disconnect an ongoing connection or the last connection.  

ICD_DBUS_API_SCAN_REQ   "scan_req" Initiates or stops an IAP scan.   Callback: ICD_DBUS_API_SCAN_SIG   "scan_result_sig" 

o DBUS_TYPE_UINT32              icd_scan_status o DBUS_TYPE_UINT32       timestamp when last seen o DBUS_TYPE_STRING       service type o DBUS_TYPE_STRING       service name o DBUS_TYPE_UINT32       service attributes  o DBUS_TYPE_STRING       service id o DBUS_TYPE_INT32        service priority within a service type o DBUS_TYPE_STRING       network type o DBUS_TYPE_STRING      network name 

Maemo for Mobile Developers 

Page 77: Qt for Maemo Developers Guide v0 5 Beta

o DBUS_TYPE_UINT32       network attributes  o DBUS_TYPE_ARRAY(BYTE)  network id o DBUS_TYPE_INT32        network priority for different network types o DBUS_TYPE_INT32        signal strength/quality,0(none) ‐ 10(good) o DBUS_TYPE_STRING       station id o DBUS_TYPE_INT32        signal value in dB 

 

ICD_DBUS_API_SELECT_REQ   "select_req" Requests the 'Select connection' dialog.  

ICD_DBUS_API_STATE_REQ   "state_req" Requests connection state.   Callback: ICD_DBUS_API_STATE_SIG   "state_sig" States signal sent in response to ICD_DBUS_API_STATE_REQ or broadcasted whenever the state of a connection changes. This is the unique signal that is broadcasted regardless of a previous request. 

o DBUS_TYPE_STRING              service type or empty string o DBUS_TYPE_UINT32              service attributes o DBUS_TYPE_STRING              service id or empty string o DBUS_TYPE_STRING              network type or empty string o DBUS_TYPE_UINT32              network attributes o DBUS_TYPE_ARRAY (BYTE)        network id or empty string o DBUS_TYPE_STRING              error that occurred; empty string on success o DBUS_TYPE_UINT32              state of the network 

 

ICD_DBUS_API_STATISTICS_REQ   "statistics_req" Requests specific connection statistics or for all connections.  Callback:ICD_DBUS_API_STATISTICS_SIG   "statistics_sig" Sent if there are ongoing connections. 

o DBUS_TYPE_STRING              service type or empty string o DBUS_TYPE_UINT32              service attributes  o DBUS_TYPE_STRING              service id or empty string o DBUS_TYPE_STRING              network type or empty string o DBUS_TYPE_UINT32              network attributes  o DBUS_TYPE_ARRAY (BYTE)        network id or empty string o DBUS_TYPE_UINT32              time active, measured in seconds o DBUS_TYPE_INT32               signal strength/quality  o DBUS_TYPE_UINT32              bytes sent 

Maemo for Mobile Developers 

Page 78: Qt for Maemo Developers Guide v0 5 Beta

 

5.4 Example 

5.4.1 Internet Connection Daemon 2 Example This example was designed to have a very simple UI focusing on Internet Connection Daemon 

2  functionalities.  As  shown  on  Figure  1,  the  UI  is  a  form  with  two  columns  where  the 

connection state and activity will be displayed. 

 

Figure 2 – Icd2 example UI. 

This example was written using the Qt framework. It is split into five files: widget.cpp, 

widget.h, icdhandler.cpp, icdhandler.h and main.cpp. The files widget.cpp and widget.h 

contains functions to control user interface. The files icdhandler.cpp is responsible to 

communicate with ICd2 by using the QtDBus library. The file main.cpp has only the main 

function to create the described objects and start the application. 

The UI developed for this example uses QVBoxLayouts and QHBoxLayouts in addition to a 

QFormLayout in the left column and QGridLayout on the right column to organize the widgets. 

The majority of widgets are QLabels but a QProgressBar is used to display the signal quality. 

The example application will be availa ble for download later. The example code is explained as 

follows. The main functionality is implemented by a class labeled IcdHandler. It is used to 

encapsulate D‐Bus calls. In doing so, it is necessary to include the headers from ICd2 library 

and QDbus library into the source file as follows: 

#include <QtDBus> 

#include <icd/dbus_api.h> 

To link the example against QDBus and ICd2 library, it is necessary to add the following line to 

the project file:  

CONFIG += icd2 qdbus 

 

Maemo for Mobile Developers 

Page 79: Qt for Maemo Developers Guide v0 5 Beta

 

 

To get connected to the system bus through QDBus library, it is necessary to call the static 

method systemBus() from QDBusConnection class. 

static QDBusConnection bus = QDBusConnection::systemBus(); 

In order to connect to ICd2 Bus API interface, an object of QDBusInterface has to be 

instantiated. It is necessary to pass the ICD_DBUS_API_INTERFACE, the ICD_DBUS_API_PATH 

and the system bus as arguments to the constructor. 

IcdHandler::IcdHandler(QObject *parent):QObject(parent)  

    interface = new QDBusInterface (ICD_DBUS_API_INTERFACE, 

        ICD_DBUS_API_PATH, 

        ICD_DBUS_API_INTERFACE, 

        bus); 

 

    bus.connect(ICD_DBUS_API_INTERFACE, ICD_DBUS_API_PATH, ICD_DBUS_API_INTERFACE, 

        ICD_DBUS_API_STATISTICS_SIG, this, SLOT(statisticsSentResult(const QDBusMessage&))); 

 

    bus.connect(ICD_DBUS_API_INTERFACE, ICD_DBUS_API_PATH, ICD_DBUS_API_INTERFACE, 

        ICD_DBUS_API_STATE_SIG, this, SLOT(changeState(const QDBusMessage&))); 

 

In order to listen to a signal from ICD_DBUS_API_INTERFACE, the connect() method from 

QDBusConnection is used to connect a signal emitted from D‐Bus to a slot of this class.  

The first connect call links the ICD_DBUS_API_STATISTICS_SIG to the statisticsSentResult(const 

QDBusMessage&) slot. The second connects the ICD_DBUS_API_STATE_SIG signal from ICd2 to 

the changeState(const QDBusMessage&) slot. The interaction between these classes can be 

seen on Figure 2. 

Maemo for Mobile Developers 

Page 80: Qt for Maemo Developers Guide v0 5 Beta

 

To retrieve information from a QDBusMessage, it is necessary to call the arguments() method 

from QDBusMessage object. It returns a QList object with QVariants objects. 

Both changeState(const QDBusMessage&) and statisticsSentResult(const QDBusMessage& 

rep) slots just receive the signal from ICd2, retrieve the QList and emit a Qt signal as shown on 

the following code snip: 

void IcdHandler::changeState(const QDBusMessage& rep) 

    emit stateChanged(rep.arguments()); 

 

void IcdHandler::statisticsSentResult(const QDBusMessage& rep) 

    emit statisticsChanged(rep.arguments()); 

 

The main.cpp file has only the main function, which creates the Widget and the IcdHandler 

classes. In addition, the main class also connects both classes through signals and slots. 

The IcdHandler class has the following slots and signals: 

class IcdHandler : public QObject 

… 

    public slots: 

        void statisticsSentResult(const QDBusMessage& rep); 

        void changeState(const QDBusMessage& rep); 

        void disconnect(); 

        void connect(); 

        void updateStatistics(); 

        void updateConnectionState(); 

 

    signals: 

ICD_DBUS_API_STATISTICS

ICD_DBUS_API_STATE_REQ

ICD_DBUS_API_DISCONNECT_REQ

statisticsSentResult ICD_DBUS_API_STATISTICS_SIG 

IcdHandler  D‐Bus 

ICD_DBUS_API_STATE_SIGchangeState 

Maemo for Mobile Developers 

Page 81: Qt for Maemo Developers Guide v0 5 Beta

        void stateChanged(const QList<QVariant> state); 

        void statisticsChanged(const QList<QVariant> statistics); 

    … 

}; 

 

The Widget class has the following slots and signals: 

class Widget : public QWidget 

    … 

 

signals: 

        void connectionButton_clicked(); 

        void disconnectButton_clicked(); 

        void updateStatisticsRequested(); 

        void updateStateRequested(); 

 

public slots: 

        void updateConnectionState(const QList<QVariant> state); 

        void updateStatisticsState(const QList<QVariant> statistics); 

 

private slots: 

        void on_disconnectButton_clicked(); 

        void on_connectionButton_clicked(); 

        void timer_tick(); 

    … 

    private: 

    … 

        QTimer *timer; 

}; 

Once Widget and IcdHandle object are instantiated, the main function connects signals and 

slots from them as follows: 

int main(int argc, char *argv[]) 

    QApplication a(argc, argv); 

 

    Widget widget; 

    IcdHandler handler; 

 

    QObject::connect(&widget, SIGNAL(connectionButton_clicked()), &handler, 

SLOT(connect())); 

    QObject::connect(&widget, SIGNAL(disconnectButton_clicked()), &handler, 

SLOT(disconnect())); 

Maemo for Mobile Developers 

Page 82: Qt for Maemo Developers Guide v0 5 Beta

    QObject::connect(&widget, SIGNAL(updateStatisticsRequested()), &handler, 

SLOT(updateStatistics())); 

 

    handler.updateConnectionState(); 

 

    QObject::connect(&handler, SIGNAL(stateChanged(const QList<QVariant>)),  

&widget, SLOT(updateConnectionState(const QList<QVariant>))); 

 

    QObject::connect(&handler, SIGNAL(statisticsChanged(const QList<QVariant>)),  

&widget, SLOT(updateStatisticsState(const QList<QVariant>))); 

 

    widget.show(); 

    return a.exec(); 

 

 

 

 

 Figure 3 – Signals and slots connections between Widget, IcdHandler and Timer classes 

 

Widget 

Timer

connectionButton_clicked

disconnectButton_clicked

connect

disconnect

updateStatisticsRequested updateStatistics

updateConnectionState stateChanged

IcdHandler

statisticsChangedupdateStatisticsState

Besides interacting with IcdHandler, the Widget also receives periodic signals from QTimer to 

be used to update connection statistics. It is done in the following way: 

D‐Bus

Widget::Widget(QWidget *parent) 

Maemo for Mobile Developers 

Page 83: Qt for Maemo Developers Guide v0 5 Beta

    : QWidget(parent) 

    timer = new QTimer(this); 

    … 

}  

 

void Widget::updateConnectionState(const QList<QVariant> state) 

    unsigned int connectionStatus = state.value(7).value<unsigned int>(); 

 

    if (connectionStatus) 

    { 

        QObject::connect(timer, SIGNAL(timeout()), this, SLOT(timer_tick())); 

        timer‐>start(800); 

    } 

    else 

    { 

        timer‐>stop(); 

        networkField‐>setText(""); 

        durationField‐>setText(""); 

        progressBar‐>setValue(0); 

        sentField‐>setText(""); 

        receivedField‐>setText(""); 

    } 

 

    if (connectionStatus < 6) 

    { 

        statusField‐>setText(connectionStates[connectionStatus]); 

    } 

 

When connections status becomes different of zero, it indicates that the device is connected 

to the internet the timer has been started. As the device gets disconnected, it is stopped and 

the statistics fields of the UI are cleaned. 

5.5 Links    ‐ Garage project 

   ‐ SVN 

   ‐ Upstream project page 

   ‐ Applications using this lib 

5.5.1 Documentation/Maemo 5 Developer Guide/Using Connectivity Components/Maemo Connectivity 

http://wiki.maemo.org/Documentation/Maemo_5_Developer_Guide/Using_Connectivity_Co

mponents/Maemo_Connectivity 

Maemo for Mobile Developers 

Page 84: Qt for Maemo Developers Guide v0 5 Beta

5.5.2 Internet Connectivity daemon version 2 http://maemo.org/api_refs/5.0/beta/icd2 

5.5.3 Bibliography Maemo.org. (17 de Agosto de 2009). Internet Connectivity daemon version 2 API Reference. 

Acesso em 17 de Agosto de 2009, disponível em Internet Connectivity daemon version 2: 

http://maemo.org/api_refs/5.0/beta/icd2/ 

Maemo.org. (17 de Agosto de 2009). Maemo 5 Developer Guide. Acesso em 17 de Agosto de 

2009, disponível em Maemo 5 Developer Guide: 

http://wiki.maemo.org/Documentation/Maemo_5_Developer_Guide/Using_Connectivity_Co

mponents/Maemo_Connectivity 

6 A GUI example 

6.1 Introduction One of the greatest advantages of Qt framework is its portability to different platforms, so an 

application  that  runs on Desktop probably  runs on mobile devices as well. With Qt, porting 

applications to Maemo platform is a painless task. Only few things must be considered, such as 

storage location, input events and input method, which are detailed in this section. 

For Maemo platform,  the Qt  framework  is significantly well  integrated. However, Qt  looks a 

little bit different  in Maemo platform, because  it was modified to be  integrated with Hildon. 

Hildon  is  an  application  framework  for mobile devices based on  Linux operating  system.  In 

addition,  Hildon  takes  into  account  all  constraints  of mobile  devices,  such  as  restrict  user 

interface, in order to provide enhancements for user experience. The following screenshot of a 

Qt application running on Maemo without Hildon integration: 

 

Note  that widgets  (combo boxes,  lists, menu, etc.) are small and  they are not suitable  to be 

selected with fingers. In addition, considering that the font is also small, the labels are difficult 

to read. Now, look at the same Qt application running with Hildon: 

Maemo for Mobile Developers 

Page 85: Qt for Maemo Developers Guide v0 5 Beta

 

6.2 Main classes and methods The most  important  class  in Qt,  concerning  about  graphical  user  interface,  is  the QWidget 

class, which is the base class of all GUI objects. 

One  of  the most  important  classes  inherited  from QWidget  is  the main window. On main 

window,  it  is possible  to  add widgets,  such  as menus,  tables,  boxes, buttons,  text  fields or 

other useful components. In Qt, the class representing the main window is the QMainWindow. 

Some other useful methods of QMainWindow are described below: 

setCentralWidget: this method receives a widget and places  it on the central area of 

the main window; 

menuBar:  returns  the menu  bar  for  the main window, which  allows  to  add menu 

actions. The menu lies in the top of window; 

statusBar: returns the status bar for the main window. It  is possible to add messages 

on it. 

As  additional  examples,  other  useful  widgets  inherited  from  QWidget  are  QPushButton, 

QLineEdit, and QComboBox. QPushButton is a Qt button that emits the clicked() signal when it 

is activated. QLineEdit  is a text  field that emits signals, such as textChanged()  (emitted when 

the  text  inside  the widget  is  changed). QComboBox  is  a widget  that merges  a  button  and 

popup list and it emits the signal currentIndexChanged() when the selection is changed.  

You can use other widgets. For more documentation about  it, see Qt classes documentation 

(http://doc.trolltech.com/4.5/classes.html). 

6.3 Example To describe how  to develop Qt GUI Maemo applications, we provide an  interesting example 

that  implements a SIP extensions viewer. The SIP and names values are retrieved from a file. 

This  example  will  be  available  for  download  later.  The  main  window  contains  a  list  of 

extensions as shown on the following picture: 

Maemo for Mobile Developers 

Page 86: Qt for Maemo Developers Guide v0 5 Beta

 

In addition, the main window also contains a menu list with a few options: 

 

When the Menu → Import from file option is selected, a dialog is opened to insert the file 

location which is used to populate the list: 

 

After file selection, the table is updated: 

Maemo for Mobile Developers 

Page 87: Qt for Maemo Developers Guide v0 5 Beta

 

Finally, it is possible to search for contacts: 

 

 

The example package contains eight files, which are described as follows: 

sip_finder.cpp:  contains  the  class  SIPFinder  implementation,  which  represents  the 

main window; 

sip_finder.h: contains the definition of the SIPFinder class and variables definition; 

sip_finder_table.h:  contains  the  definition  of  the  SIPFinderTable  class.  This  class 

inherits  from  table  types  that  lists SIP extensions and  their names. The  table can be 

filtered with regular expressions inserted in a text field; 

sip_finder_table.cpp: provides SIPFinderTable class implementation; 

import_dialog.h: contains the definition of the ImportDialog class; 

import_dialog.cpp:  contains  the  implementation  of  ImportDialog  class,  which  is  a 

dialog containing a text field and a button; 

sip_finder.pro: contains information to compile the application. 

 

6.3.1 Main window  

Maemo for Mobile Developers 

Page 88: Qt for Maemo Developers Guide v0 5 Beta

The  “sip_finder.h”  file  is  shown  as  follows.  Note  that  the  class  SIPFinder  inherits  from 

QMainWindow, so the “QMainWindow” header file must be  included. The constructor of the 

class SIPFinder receives an  instance of SIPFinderTable as parameter, so the “qt_gui.h” header 

file  must  be  included.  This  instance  is  used  as  main  widget  of  the  window.  The  slot 

importFromFile()  will  be  connected  to  a  menu  action.  The  methods  createActions()  and  

createMenus() help to create menus and their actions: 

 

#ifndef SIPFinder_H 

#define SIPFinder_H 

 

#include <QMainWindow> 

#include <qt_gui.h> 

 

class QAction; 

class QActionGroup; 

class QLabel; 

class QMenu; 

 

class SIPFinder : public QMainWindow 

    Q_OBJECT 

 

public: 

    SIPFinder(SIPFinderTable *table); 

 

protected: 

    void contextMenuEvent(QContextMenuEvent *event); 

 

private slots: 

    void importFromFile(); 

 

private: 

    void createActions(); 

    void createMenus(); 

 

    SIPFinderTable *sipFinderTable; 

    QMenu *fileMenu; 

    QActionGroup *alignmentGroup; 

    QAction *importFromFileAct; 

    QAction *exitAct; 

}; 

 

#endif 

 

Maemo for Mobile Developers 

Page 89: Qt for Maemo Developers Guide v0 5 Beta

The “sip_finder.cpp” file is described in details as follows. This file includes seven header files. 

The  “QtGui”  header  is  used  for  create  GUI  components.  The  “QFile”,  “QIODevice”  and 

“QTextStream” files allow reading data from local files: 

#include <QtGui> 

 

#include <QFile> 

#include <QIODevice> 

#include <QTextStream> 

 

#include "sip_finder_table.h" 

#include "sip_finder.h" 

#include "import_dialog.h" 

The constructor of SIPFinder class receives a SIPFinderTable instance as parameter and set it as 

the  central  widget  of  application.  This  is  made  by  the  function  setCentralWidget()  of 

QMainWindow.  The  window  title  is  set  with  the  function  setWindowTitle().  The  methods 

createActions()  and  createMenus()  are  called  to  create  the  actions  for menu  and  the menu 

itself: 

SIPFinder::SIPFinder(SIPFinderTable *table) 

    sipFinderTable = table; 

    setCentralWidget(sipFinderTable); 

    createActions(); 

    createMenus(); 

    setWindowTitle(tr("Menu")); 

The method createActions() creates two QAction objects:  importFromFileAct and exitAct. The 

QAction  receives  a  String  as menu  item  name.  The  importFromFileAct  is  connected  to  slot 

importFromFile(), which  imports  the  file with SIP extensions, and  the exitAct  is connected  to 

the slot close(), which closes the window: 

void SIPFinder::createActions() 

    importFromFileAct = new QAction(tr("Import from file"), this); 

    importFromFileAct‐>setStatusTip(tr("Import extensions from a local file")); 

    connect(importFromFileAct, SIGNAL(triggered()), this, SLOT(importFromFile())); 

 

    exitAct = new QAction(tr("Exit"), this); 

    exitAct‐>setStatusTip(tr("Exit the application")); 

    connect(exitAct, SIGNAL(triggered()), this, SLOT(close())); 

Maemo for Mobile Developers 

Page 90: Qt for Maemo Developers Guide v0 5 Beta

The  method  createMenus()  calls  the  method  menuBar()  of  QMainWindow.  This  method 

returns a QMenuBar instance, which provides the method addMenu(), which is used to append 

a new menu (with the name passed as paremeter) to the menu bar. This operation returns a 

QMenu  instance, which  is associated to the fileMenu variable. The actions  importFromFileAct 

and  exitAct are added to fileMenu by using method addAction(): 

void SIPFinder::createMenus() 

    fileMenu = menuBar()‐>addMenu(tr("Import")); 

    fileMenu‐>addAction(importFromFileAct); 

    fileMenu‐>addSeparator(); 

    fileMenu‐>addAction(exitAct); 

The method  importFromFile() creates a dialog. The dialog contains a  text  field and a button. 

The user can  insert the file location containing SIP extensions and names in the text field and 

press the button to confirm. After that, the file is opened and the content of the table placed 

on  central  part  of  the  window  is  changed  with  the  function  setSourceModel()  of 

SIPFinderTable. To open a  file, an QFile object  is  created and  the method open() of QFile  is 

called. To read the file, an QTextStream object  is created and, until  it reaches the end of file, 

each line is read with the method readLine() of  QTextStream: 

void SIPFinder::importFromFile() 

    ImportDialog import(this);  

    import.exec(); 

 

    QFile file(import.getLineEditText()); 

    QStringList sipAndName; 

    QStringList sip; 

    QStringList name; 

    QString line; 

 

    if (file.open(QIODevice::ReadOnly)) {  

              

        QTextStream textStream( &file ); 

        while ( ! textStream.atEnd() ) { 

                     

            line = textStream.readLine(); 

            sipAndName = line.split(","); 

            sip.append(sipAndName[0]); 

            name.append(sipAndName[1]);             

        }         

    } 

 

    file.close();     

Maemo for Mobile Developers 

Page 91: Qt for Maemo Developers Guide v0 5 Beta

    sipFinderTable‐>setSourceModel(sipFinderTable‐>createSIPModel(sip, name)); 

The following file is used to populate the list of SIP extensions and names. To separate the SIP 

extension  and  the  name,  methods  split()  of  QString  are  used.  This  method  receives  the 

separation token as parameter and creates a QStringList with the separated elements. 

101,Diego Bezerra 

102,Mateus Lima 

103,Hallyson Melo 

 

6.3.2 Table The “sip_finder_table.h”  is shown below. The class SIPFinderTable  inherits  from QWidget, so 

we need  to  include QWidget header  file. Three methods are defined  to help  the creation of 

table:  setSourceModel(),  addExtension(),  and  createSIPModel(). One  slot,  SetRegExpFilter,  is 

invoked whenever the pattern of filter changes. 

#ifndef SIPFinderTable_H 

#define SIPFinderTable_H 

 

#include <QWidget> 

 

class QAbstractItemModel; 

class QComboBox; 

class QGroupBox; 

class QLabel; 

class QLineEdit; 

class QSortFilterProxyModel; 

class QTreeView; 

 

class SIPFinderTable : public QWidget 

    Q_OBJECT 

 

public: 

    SIPFinderTable(); 

    void setSourceModel(QAbstractItemModel *model); 

    void addExtension(QAbstractItemModel *model, const QString &extension, 

                      const QString &name); 

    QAbstractItemModel *createSIPModel(QStringList sip, QStringList name); 

 

private slots: 

    void SetRegExpFilter(); 

    void filterColumnChanged(); 

Maemo for Mobile Developers 

Page 92: Qt for Maemo Developers Guide v0 5 Beta

 

private: 

    QSortFilterProxyModel *proxyModel; 

    QGroupBox *proxyGroupBox; 

    QTreeView *proxyView; 

    QLabel *filterPatternLabel; 

    QLabel *filterColumnLabel; 

    QLineEdit *filterPatternLineEdit; 

    QComboBox *filterColumnComboBox; 

 

}; 

#endif 

 

File “sip_finder_table.cpp” is described as follows. At first, the QtGui header file is included so 

it is possible to use Qt GUI components:  

#include <QtGui> 

 

#include "sip_finder_table.h" 

 

The constructor creates the table which contains the SIP extensions and names, and it creates 

a  text  field  to  allow  the  user  searching  for  names  or  SIP  extensions.  The  table  created, 

proxyView, is of type QTreeView. Such table type needs a model. In this case, it is used a model 

of  type QSortFilterProxyModel  (named proxyModel), which provides  support  for  sorting and 

filtering  data.  After  that,  a  text  field  is  created  with  name  filterPatternLineEdit  and  type 

QLineEdit,  and  is  associated  to  label  filterPatternLabel.  Once  created,  the  text  field  is 

connected to slot SetRegExpFilter, which is called when the text changes. 

A combo box named filterColumnComboBox of type QComboBox is created to hold the search 

options  “Name”  or  “Extension”.  It  indicates  in  which  text  field  the  string  pattern  will  be 

located.  This  combo  box  is  connected  to  the  slot  filterColumnChanged(),  which  is  called 

whenever the option in the combo box is changed. 

 

Finally,  the  grid  layout  proxyLayout  of  type  QGridLayout  is  created  to  hold  some  GUI 

components, which is implemented by function addWidget(). 

SIPFinderTable::SIPFinderTable() 

/*The QSortFilterProxyModel class provides support for sorting and 

 filtering data passed between another model and a view*/ 

    proxyModel = new QSortFilterProxyModel; 

    proxyModel‐>setDynamicSortFilter(true); 

 

    proxyGroupBox = new QGroupBox(tr("Extensions list")); 

    proxyView = new QTreeView; 

Maemo for Mobile Developers 

Page 93: Qt for Maemo Developers Guide v0 5 Beta

    proxyView‐>setRootIsDecorated(false); 

    proxyView‐>setAlternatingRowColors(true); 

    proxyView‐>setModel(proxyModel); 

    proxyView‐>setSortingEnabled(true); 

 

    filterPatternLineEdit = new QLineEdit; 

    filterPatternLabel = new QLabel(tr("Search:")); 

    filterPatternLabel‐>setBuddy(filterPatternLineEdit); 

 

    connect(filterPatternLineEdit, SIGNAL(textChanged(const QString &)), 

            this, SLOT(filterRegExpChanged())); 

 

    filterColumnComboBox = new QComboBox; 

    filterColumnComboBox‐>addItem(tr("Extension")); 

    filterColumnComboBox‐>addItem(tr("Name")); 

    filterColumnLabel = new QLabel(tr("Search for:")); 

    filterColumnLabel‐>setBuddy(filterColumnComboBox); 

 

    connect(filterColumnComboBox, SIGNAL(currentIndexChanged(int)), 

             this, SLOT(filterColumnChanged())); 

 

    QGridLayout *proxyLayout = new QGridLayout; 

    proxyLayout‐>addWidget(proxyView, 0, 0, 1, 3); 

    proxyLayout‐>addWidget(filterPatternLabel, 1, 0); 

    proxyLayout‐>addWidget(filterPatternLineEdit, 1, 1, 1, 2); 

    proxyLayout‐>addWidget(filterColumnLabel, 2, 0); 

    proxyLayout‐>addWidget(filterColumnComboBox, 2, 1, 1, 2); 

 

    proxyGroupBox‐>setLayout(proxyLayout); 

 

    QVBoxLayout *mainLayout = new QVBoxLayout; 

    mainLayout‐>addWidget(proxyGroupBox); 

    setLayout(mainLayout); 

 

    setWindowTitle(tr("Basic Sort/Filter Model")); 

    resize(800, 480); 

 

    proxyView‐>sortByColumn(1, Qt::AscendingOrder); 

    filterColumnComboBox‐>setCurrentIndex(1); 

The method createSIPModel() is called in the main window by method importFromFile(), which 

reads a file and populate the table with the SIP extensions and names from the file. A generic 

model for storing custom data is created with name model and type QStandardItemModel. The 

constructor  of  QStandardItemModel  receives  three  parameters:  the  rows  quantity,  the 

Maemo for Mobile Developers 

Page 94: Qt for Maemo Developers Guide v0 5 Beta

columns quantity and the parent window. The method setHeaderData  is used to set columns 

names. The method addExtension() is called to populate the table and it is detailed later.  

 

QAbstractItemModel* SIPFinderTable::createSIPModel(QStringList sip, QStringList name) 

    QStandardItemModel *model = new QStandardItemModel(0, 2, this); 

 

    model‐>setHeaderData(0, Qt::Horizontal, QObject::tr("Extension")); 

    model‐>setHeaderData(1, Qt::Horizontal, QObject::tr("Name")); 

 

    for (int i = 0; i < sip.size(); ++i){ 

        addExtension(model, sip[i], name[i]); 

    } 

 

    return model; 

The  method  addExtension()  update  SIP  extensions  and  names  of  an  model  received  as 

QAbstractItemModel  as  parameter.  This  is  made  by  using  the  method  setData()  of 

QAbstractItemModel. 

 

void SIPFinderTable::addExtension(QAbstractItemModel *model, const QString &extension, 

              const QString &name) 

    model‐>insertRow(0); 

    model‐>setData(model‐>index(0, 0), extension); 

    model‐>setData(model‐>index(0, 1), name); 

The method setSourceModel() is called in the constructor of SIPFinder class. This method only 

sets the source model of QAbstractItemModel, by using the method setSourceModel(). 

void SIPFinderTable::setSourceModel(QAbstractItemModel *model) 

    proxyModel‐>setSourceModel(model); 

The slot filterRegExpChanged() creates a regular expression (QRegExp) based on text  inserted 

by  the  user.  It  uses  such  expression  as  filter  and  set  it  to  proxyModel  using  the method 

setFilterRegExp(). 

void SIPFinderTable::filterRegExpChanged() 

    QRegExp regExp(filterPatternLineEdit‐>text(), Qt::CaseInsensitive, QRegExp::RegExp); 

    proxyModel‐>setFilterRegExp(regExp); 

 

Maemo for Mobile Developers 

Page 95: Qt for Maemo Developers Guide v0 5 Beta

The slot  filterColumnChanged only sets  the  filter,  to a selected column  in  the combo box,  to 

the proxyModel using the method setFilterKeyColumn. 

 

void SIPFinderTable::filterColumnChanged() 

    proxyModel‐>setFilterKeyColumn(filterColumnComboBox‐>currentIndex()); 

6.4 Links  Qt examples: http://doc.trolltech.com/4.5/examples.html 

Opening files in Qt: http://doc.trolltech.com/4.5/qfile.html 

7 Whac­a­mole game example 

7.1 introduction In this section we present a whac‐a‐mole Qt game for Maemo. This example uses a lot of Qt 

widgets and uses the touch screen functionality. Through this section we will show some 

screenshots and the code to generate them.  The example will be available for download later. 

The complete example contains the following files: 

main.cpp: entry point of application; 

game_window.cpp: implementation of main window; 

main_screen.cpp: implementation of a screen for start the game and set the player 

name; 

records_screen.cpp: implementation of a screen to show the game records; 

records.txt: file for records persistence; 

moleCatcher.pro: project definition file; 

gamecontroller.cpp: implementation of game core. It is responsible for all game 

control; 

graphwidget.cpp: implementation of QGraphicsView class, which is responsible for 

display a QGraphicsScene; 

mole.cpp: implementation of a class that encapsulates a QGraphicsPixmapItem item. 

This item will be managed in QGraphicsScene described above; 

mainui.cpp: implementation of a class responsible for set up the game screen 

(QGraphicsView mentioned above), such as set up background image; 

pngitem.cpp: implementation of a QGraphicsPixmapItem wich will be managed in 

QGraphicsScene described above. It loads a png image file. ; 

graphwidgetpositioner.cpp: implementation of a class responsible for calculate 

positions for QGraphicsPixmapItem items on QGraphicsScene scene. 

Maemo for Mobile Developers 

Page 96: Qt for Maemo Developers Guide v0 5 Beta

The game start point is the class GameWindow. This class creates the main window, initiates 

the GameController class and creates a MainUi instance. The main game classes are described 

below.   

7.2 Example 

7.2.1 Game main window The game_window.cpp file contains the implementation of the game main window. It inherits 

from QMainWindow, which allows the creation of a window to hold menu, status bar, widgets, 

layouts, toolbars and other things. In this example, the main window will hold a menu and 

some widgets as central widgets. The central widget will change in time. At first, we set a 

widget containing a label, a text field for player name entry, and a start button. When the user 

presses the start button, the central widget is changed to a QGraphicsView, which is the game 

action screen. When the user choices “Show records” menu option, a widget containing a 

QTreeView (used to show the table of records) is set as central widget. A screenshot of the 

game main window is show below: 

 

To set a widget as central widget of a QMainWindow is very easy. It is made by using the 

function setCentralWdget(), which receives a widget as parameter. An example code is shown 

below: 

... 

mainScreen = new MainScreen(); setCentralWidget(mainScreen); ... 

The window menu bar holds three options: “Start Game”, “Show records”, and “exit”. At first, 

the actions are created with the following code: 

void GameWindow::createActions() 

    startGameAct = new QAction(tr("Start Game"), this); 

    startGameAct‐>setStatusTip(tr("Starts the game")); 

    connect(startGameAct, SIGNAL(triggered()), this, SLOT(startGame())); 

Maemo for Mobile Developers 

Page 97: Qt for Maemo Developers Guide v0 5 Beta

 

    showRecordsAct = new QAction(tr("Show records"), this); 

    showRecordsAct‐>setStatusTip(tr("Shows the records list")); 

    connect(showRecordsAct, SIGNAL(triggered()), this, SLOT(showRecords())); 

 

    exitAct = new QAction(tr("Exit"), this); 

    exitAct‐>setStatusTip(tr("Exit the application")); 

    connect(exitAct, SIGNAL(triggered()), this, SLOT(close())); 

Note that startGameAct  and showRecordsAct  actions are connected to startGame() and 

showRecords() slots respectively. These slots are used to set widgets as central widget. After 

that, a menu is created on the menu bar and the actions above are added: 

    mainMenu = menuBar()‐>addMenu(tr("Main menu")); 

    mainMenu‐>addAction(startGameAct); 

    mainMenu‐>addAction(showRecordsAct); 

    mainMenu‐>addAction(exitAct); 

 

A screenshot of menu is shown below: 

 

 

7.2.2 Main screen The “main_screen.cpp” file contains the implementation of a widget to get the player name 

and start the game. This widget is shown in the initialization of the game as the main screen 

central widget. A screenshot of this widget is shown below: 

Maemo for Mobile Developers 

Page 98: Qt for Maemo Developers Guide v0 5 Beta

 

The player name is set through a QLineEdit widget. An example of QLineEdit creation is shown 

below: 

QLineEdit *playerNameLineEdit = new QLineEdit(); 

To get the text inserted in this widget is quite easy by using the method text(), for example: 

 playerNameLineEdit‐>text(); 

Other widget used in main screen is a QPushButton. The button is created using the code 

below: 

QPushButton *startGameButton = new QPushButton("Start game"); 

The button is connected to a signal in spite of a slot. This is made by using the macro SIGNAL 

such as in following code: 

connect(startGameButton, SIGNAL(clicked()), this, SIGNAL(startButtonPressed())); 

In this case, the signal clicked() of QPushButton is connected to the signal startButtonPressed() 

(declared as signal in “main_screen.h” header file). When the button is pressed, the signal 

startButtonPressed() is emitted. This signal is connected to a slot, which starts the game, in 

“game_window.cpp” file.  

7.2.3 Records screen The “records_screen.cpp” file contains the implementation of a widget used to show records 

(names and scores) in a table. A screenshot of this widget is shown below: 

Maemo for Mobile Developers 

Page 99: Qt for Maemo Developers Guide v0 5 Beta

 

The table itself is a QTreeView, which is created with the following code: 

QTreeView *proxyView = new QTreeView(); 

A model must be created and set as QTreeView model by using setModel() method. The model 

can be of type: QAbstractListModel, QAbstractProxyModel, QAbstractTableModel, QDirModel, 

QFileSystemModel, QHelpContentModel, QProxyModel, or QStandardItemModel. All these 

models inherit from QAbstractItemModel. In this example we have used 

QSortFilterProxyModel such as in the code below: 

QSortFilterProxyModel  *proxyModel = new QSortFilterProxyModel(); 

proxyView‐>setModel(proxyModel); 

In this example a QStandardItemModel object is created and is processed by proxyModel. It is 

possible by using the method setSourceModel(). The code below shows how to create a 

QStandardItemModel and add two columns to it: 

    QStandardItemModel *model = new QStandardItemModel(0, 2, this); 

    model‐>setHeaderData(0, Qt::Horizontal, QObject::tr("player")); 

    model‐>setHeaderData(1, Qt::Horizontal, QObject::tr("score")); 

Here, two columns are created with “player” and “score” names as headers, respectively. To 

add items to QStandardItemModel, we firstly insert a new row with insertRow() and then use 

setData() to insert items on it. The setData() method receives item index (index(row, column)), 

and the item value: 

model‐>insertRow(0); model‐>setData(model‐>index(0, 0), “player1”); model‐>setData(model‐>index(0, 1), “1200”); 

Now we can set the source model to QSortFilterProxyModel: 

proxyModel‐>setSourceModel(model); 

Maemo for Mobile Developers 

Page 100: Qt for Maemo Developers Guide v0 5 Beta

7.2.4 Game controller The “gamecontroller.cpp” file contains the GameController class implementation. This class is 

responsible for controlling game timers, such as the timer which will count the game duration 

and the timer which will count the duration of a mole on the screen. It also choices randomly 

the position where a new created mole will appear on the screen. 

The class GameController constructor generates, at first, a random number sequence of 

pseudo random integers.  It will be used latter for determine a new mole position on screen. It 

also assigns the value zero to currentScore integer: 

qsrand((QTime::currentTime()).msec()); 

currentScore = 0; 

After it, all the game timers are initialized: 

    mole_timer = new QTimer(this); 

    connect(mole_timer, SIGNAL(timeout()), this, SLOT(timerTick())); 

    mole_timer‐>start(MOLE_DURATION); 

    QTimer::singleShot(GAME_DURATION, this, SLOT(gameTimeout())); 

 

Note that a QTimer is created and its signal timeout() is connected to timerTick() slot. After it, 

the timer is started with MOLE_DURATION integer as parameter. It means that when the timer 

reaches the MOLE_DURATION milliseconds value, the slot timerTick() is called. This slot is 

shown below: 

void GameController::timerTick() 

    int position = qrand() % NUM_SLOTS; 

    emit moleAdded(position, MOLE_DURATION); 

This slot calculates a random number between zero and NUM_SLOTS and emits the 

moleAdded() signal with the calculated number (position) and the duration which a new mole 

will stay on the screen. 

Let’s take a look at the method startGame() of GameWindow: 

void GameWindow::startGame() 

    playerName = mainScreen‐>getPlayerName(); 

   

    controller = new GameController(); 

    gameUi = new MainUi(); 

 

    showRecordsAct‐>setVisible(false); 

 

Maemo for Mobile Developers 

Page 101: Qt for Maemo Developers Guide v0 5 Beta

    QObject::connect(controller, SIGNAL(moleAdded(int, int)), gameUi, SLOT(addMole(int, int))); 

    QObject::connect(controller, SIGNAL(gameStarted(quint32)), gameUi, 

SLOT(setupUi(quint32))); 

    QObject::connect(controller, SIGNAL(scoreChanged(int)), gameUi, SLOT(changeScore(int))); 

    QObject::connect(controller, SIGNAL(gameEnded(int)), this, SLOT(endGame(int))); 

 

    QObject::connect(gameUi, SIGNAL(hit()), controller, SLOT(updateScore())); 

    QObject::connect(gameUi, SIGNAL(userLeave()), controller, SLOT(endGame())); 

 

    controller‐>startGame(); 

    setCentralWidget(gameUi); 

Note that three signals defined in GameController are connected to MainUi() slots. The signals 

are: moleAdded(), gameStarted() and scoreChanged(). The GameController  moleAdded() signal 

is connected to MainUi() addMole() slot, which is called when a mole is requested to be added 

on the scene. The GameController scoreChanged() signal is connected to MainUi() 

changeScore() slot to change score value on screen. Two GameController slots are connected 

to MainUi() signals: updateScore() and endGame(). The first is called when MainUi() emits the 

signal hit(), which means that the player has hit a mole and the score must be updated. The 

second is called when MainUi() emits userLeave() signal, which means that the player leaves 

the game. 

When the game is finished the following screen is shown: 

 

7.2.5 Graphics view widget The file “mainui.cpp” contains the class MainUi, which is responsible to create, set up and 

manage an instance of GraphWidget class. This class inherits from QGraphicsView, providing a 

way to display the contents of a QGraphicsScene. The content may be a QGraphicsItem item, 

or an item which inherits from it, in our case a QGraphicsPixmapItem. 

A screenshot of the game QGraphicsView with the QGraphicsPixmapItem representing the 

mole is shown below: 

Maemo for Mobile Developers 

Page 102: Qt for Maemo Developers Guide v0 5 Beta

 

At the constructor of GraphWidget a QGraphicsScene object is created with a QRect as 

parameter. The QGraphicsScene is created with the device desktop size, so we need to create a 

QDesktopWidget: 

QDesktopWidget* desktopWidget = QApplication::desktop(); 

QRect rect = desktopWidget‐>availableGeometry(); 

Then, we create a scene and set it to GraphWidget: 

scene = new QGraphicsScene( QRect( QPoint(0, 0), rect.size() ) );    

setScene( scene ); 

 

We also create a text and add it to the scene to serve as score display: 

text = new QGraphicsTextItem(QString("0")); 

text‐>setPos(scene‐>width() ‐ 60, scene‐>height() ‐ 80); 

scene‐>addItem(text); 

 

Let’s take a look at the moleAdded() method: 

void GraphWidget::addMole(int position, int duration) 

  QPoint point = positioner‐>getPosition(this‐>width(), this‐>height(), position);   

  Mole *mole = new Mole(point, duration, scene); 

  QObject::connect(mole, SIGNAL(animationStopped(Mole*)), this,  

            SLOT(removeMole(Mole*))); 

  QObject::connect(mole, SIGNAL(animationClicked(Mole*)), this, SLOT(hit(Mole*))); 

  QGraphicsItem* graphic = mole‐>getGraphicItem(); 

  scene‐>addItem(graphic); 

This method creates a mole and adds it to scene. The Mole class receives a random position 

where it will be placed on the scene and the duration it will be displayed. Two Mole signals are 

used here: animationStopped() and animationClicked(). The first signal is emitted when the 

Maemo for Mobile Developers 

Page 103: Qt for Maemo Developers Guide v0 5 Beta

duration of a mole on the screen ends, so it is connected to GraphWidget removeMole() slot, 

which removes the mole item from scene: 

void GraphWidget::removeMole(Mole* mole) 

  scene‐>removeItem(mole‐>getGraphicItem()); 

The signal animationClicked() is emitted when the player hits a mole, so GraphWidget hit() slot 

is called. This slot is shown below: 

void GraphWidget::hit(Mole* mole) 

  scene‐>removeItem(mole‐>getGraphicItem()); 

  emit animationClicked(); 

 

It only removes the hit mole from scene and emits the signal animationClicked(). At MainUI 

class, this signal is connected to the signal hit(). 

QObject::connect(graphWidget, SIGNAL(animationClicked()), this, SIGNAL(hit())); 

The signal hit is connected to GameController updateScore() slot, so it will increment the score 

value: 

QObject::connect(gameUi, SIGNAL(hit()), controller, SLOT(updateScore())); 

 

7.2.6 Mole item The “mole.cpp” file contains the class Mole. This class basically creates a PngItem 

(QGraphicsPixmapItem) object and animates it. At first a PngItem object is created and its 

scale is set up: 

static const double INITIAL_SCALE = 0.001; 

... 

mole = new PngItem();  

mole‐>scale(INITIAL_SCALE, INITIAL_SCALE); 

Now a QtimeLine is created with mole duration set in GameController:  

duration = (duration >= 25) ? duration : 1000; 

timer = new QTimeLine(duration, this); 

A QgraphicsItemAnimation is used to make item animation. The method setItem() is used to 

set the PngItem as item to be animated and the method setTimeLine() to set the QtimeLine as 

controler of the rate of animation: 

 

Maemo for Mobile Developers 

Page 104: Qt for Maemo Developers Guide v0 5 Beta

QGraphicsItemAnimation *animation = new QGraphicsItemAnimation(this); 

animation‐>setItem(mole); 

animation‐>setTimeLine(timer); 

The PngItem scale is changed on animation using the method setScaleAt() of 

QgraphicsItemAnimation as shown below: 

animation‐>setScaleAt(i / (2.0 * numSteps), angleCoefficient*(i+INITIAL_SCALE),  

angleCoefficient*(i+INITIAL_SCALE));  

 

The method setScaleAt() receives three qreal values: the animation step when the scale must 

be changed, the horizontal shear factor and the vertical shear factor. The animation starts 

when the timer is started: 

timer‐>start(); 

Two slots are used in this class: stopAnimation() and setMoleClicked(). The first is connected to 

QtimeLine finished() signal, so this slot will be called when the timer reaches the end. The 

second slot is connected to PngItem clicked() signal, so it will be called when the PngItem is 

clicked: 

QObject::connect(timer, SIGNAL(finished()), this, SLOT(stopAnimation())); 

QObject::connect(mole, SIGNAL(clicked()), this, SLOT(setMoleClicked())); 

The slot stopAnimation() only emits the signal animationStopped(): 

void Mole::stopAnimation() 

    emit animationStopped(this); 

The slot setMoleClicked()only emits the signal setMoleClicked(): 

void Mole::setMoleClicked() 

    emit animationClicked(this); 

The signals animationStopped() and setMoleClicked() are connected to GraphWidget 

removeMole() and hit() slots respectively. 

7.3 Links  Whac‐a‐mole description: http://en.wikipedia.org/wiki/Whac‐A‐Mole 

QGraphicsView API: http://doc.trolltech.com/4.5/qgraphicsview.html 

 

Maemo for Mobile Developers 

Page 105: Qt for Maemo Developers Guide v0 5 Beta

8 Capturing key events When a widget has the keyboard input focus, key events are sent to it when keys are 

pressed or released. Sometimes the developer wants to use events from keyboard to perform 

custom action, such as control in games. It can be done by reimplementing the virtual 

protected method QWidget::keyPressEvent in a class which inherits from QWidget. 

8.1 Example The example shown here contains a button in which the central text chages when the 

user types some text using keyboard. When the button is pressed, the actuan button text is 

shown in a warning message box. The complete example can be achieved at 

http://wiki.forum.nokia.com/index.php/Qt_Key_Event_test_example. 

This example consists of a QMainWindow class, which inherits from QWidget, so it can 

handle keyboard events. Then, the method keyPressEvent is reimplemented. This method 

receves a QKeyEvent parameter so, when a key is pressed, this method is called with the 

QKeyEvent, representing the key pressed, as parameter. Let’s look at the code: 

#include "capturekeys.h" #include "ui_capturekeys.h" #include <QDebug> #include <QPushButton> #include <QMessageBox> CaptureKeys::CaptureKeys(QWidget *parent) : QMainWindow(parent) { buttonText = ""; centralButton = new QPushButton("Insert some text"); connect(centralButton, SIGNAL(clicked()), this, SLOT(buttonPressed())); setCentralWidget(centralButton); } CaptureKeys::~CaptureKeys() { } void CaptureKeys::keyPressEvent( QKeyEvent * event){ buttonText += event->text(); centralButton->setText(buttonText); } void CaptureKeys::buttonPressed(){ QString msg(centralButton->text()); QMessageBox::warning(this, QLatin1String("button pressed"), msg, QMessageBox::Ok, QMessageBox::Ok); }

At first, we have created a big button with the text “Insert some text” and connected it to 

slot buttonPressed .  Below is shown the screenshot of the application start screen: 

Maemo for Mobile Developers 

Page 106: Qt for Maemo Developers Guide v0 5 Beta

 

The reimplementation of the method keyPressEvent() only change the value of the button 

text to text typed by the user. Look at the screenshot of the application when the user has 

typed “ok”: 

 

If the user presses the button, a warning message is shown with the typed text: 

 

 

Chapter 6 Additional Maemo tools In  this  section  are  presented  some  useful  tools  to  help  the  development  to  the Maemo platform.  Many  of  these  tools  are  available  in  the  official  Maemo  tools  repository 

Maemo for Mobile Developers 

Page 107: Qt for Maemo Developers Guide v0 5 Beta

(http://repository.maemo.org/). Some of  them may have already been available unofficially, but these versions are tested for functionality. 

These tools can be split in the following subsections: 

Miscellaneous; 

Networking; 

Wireless tools; 

Test automation tools.  To use these tools the lines below must be added in the /etc/apt/sources.list in the scratchbox target or in real device. 

# Fremantle tools

deb http://repository.maemo.org fremantle/tools free non-free

# Fremantle extras-devel

deb http://repository.maemo.org/extras/ fremantle free non-free

1 Miscellaneous  

1.1 Screenshot­tool Screenshot‐tool is a command line utility used to capture screenshots of the tablet screen. This tool takes a screenshot of the current screen and saves the image as a PNG file. To install it use the following command: 

# apt-get install screenshot-tool

The use of this feature is simple as: 

$ screenshot-tool screen.png

Additionally, this feature allows to take delayed screenshots, with the command: 

$ screenshot-tool -d 5 screen.png

taking screenshot in 3 seconds...

taking screenshot in 2 seconds...

taking screenshot in 1 second...

Where the “‐d” option specifies the delay in seconds before taking the screenshot.  There is 

also the “‐q” option for quiet mode. 

1.2 HomeIP HomeIP  is a small widget which displays  the current  IP address of  the  internet  tablet on  the desktop area. To install it use the following command: 

# apt‐get install homeip 

Maemo for Mobile Developers 

Page 108: Qt for Maemo Developers Guide v0 5 Beta

 

1.3 Dpkg and Apt Maemo platform, as any Debian distribution, packages software into Debian packages. It is 

possible to manage packages (install, remove and configure) and obtain information about 

them with tools provided by Debian Package Management System: dpkg and apt (Advantage 

Packaging Tool). 

Dpkg contains a set of tools which install, remove, and provide information about Debian 

packages. To install a Debian package, execute the following command: 

$ dpkg –I <debian_package>.deb

To remove the Debian package, execute the following command: 

$ dpkg –r <debian_package>.deb

In addition, it possible to get information about Debian packages installed on the system. In 

order to get the list of installed packages, the following command can be used: 

$ dpkg –l

Dpkg also provides information about a certain package. For example, to information about a 

package (dependencies, description, size and version): 

$ dpkg --status <debian_package>

 

 

Dpkg is very useful, but it a low level tool. To help package management, Apt can be used to 

fetch packages from remote repositories and compute complex package relations. Apt also 

retrieve information about packages, such as description, version, size and dependencies. It is 

important to configure remote repository, so Apt can work properly. 

Maemo for Mobile Developers 

Page 109: Qt for Maemo Developers Guide v0 5 Beta

During package installation, Apt checks if package exists on any of configured repositories and 

it computes dependencies as well. To install a package, use the following command: 

# apt-get install <debian_package>

To remove a package, execute the following command: 

# apt-get remove <debian_package>

You can get information about any package: 

# apt-cache showpkg <debian_package>

For more information, see Dpkg or Apt man pages. 

2 Networking This category presents  tools  to retrieve and analyze network  information,  like routing, name resolution, IP address check and network package tracking. 

2.1 Iputils Once your application  is properly tested on Scratchbox environment,  it  is  important to test  it  on Internet Tablet. Generally, the device is on a TCP/IP wireless network and problems, such as network downtime, may happen. Thus, utility tools that help to  inspect connection problems on a TCP/IP network are very useful to developers. 

Iputis is a small collection of utilities to monitor/check TCP/IP related issues. The components of  this  collection are: ping,  to  test network  functionality; arping,  to  send ARP  requests  to a host; and tracepath, to trace a path to a host discovering MTU (Maximum Transmission Unit) along the way.  

To install them on the device use the following command: 

#apt-get install iputils-arping iputils-tracepath iputils-ping

The usage of these tools is simple as: 

$ ping nokia.com

PING nokia.com (147.243.3.83): 56 data bytes

64 bytes from 147.243.3.83: seq=0 ttl=226 time=409.8 ms

64 bytes from 147.243.3.83: seq=1 ttl=227 time=427.0 ms

64 bytes from 147.243.3.83: seq=2 ttl=227 time=437.4 ms

--- nokia.com ping statistics ---

4 packets transmitted, 3 packets received, 25% packet loss

round-trip min/avg/max = 409.8/424.7/437.4 ms

Maemo for Mobile Developers 

Page 110: Qt for Maemo Developers Guide v0 5 Beta

The  time  shown  in  this case  (409.8 ms),  is  the  round‐trip  time of an  IP package  sent  to  the remote  host.  It  uses  the  protocol  ICMP  (Internet  Control  Message  Protocol)  to  test  the connectivity of a link. 

$ arping -c 4 host.name.net -I wlan0

ARPING 4.79.81.157 from 192.168.1.163 wlan0

Sent 4 probes (4 broadcast(s))

Received 0 response(s)

This command sends ARP (Address Resolution Protocol) requests to the specified host (in the same local network) through the wireless interface (wlan0) to calculate the round‐trip time of sent packages. 

$ tracepath www.maemo.org

1: 192.168.1.163 (192.168.1.163) 2.869ms pmtu 1500

1: 192.168.1.1 (192.168.1.1) 60.944ms

2: 192.168.254.254 (192.168.254.254) 9.796ms

3: 192.168.254.254 (192.168.254.254) asymm 2 7.873ms pmtu 1492

4: gigabitethernet13-0.91-vpt-pb-rotd-02.telemar.net.br (200.164.197.145) 65.613ms

5: pos10-2-bvg-pe-rotd-02.telemar.net.br (200.164.196.42) asymm 7 200.775ms

6: pos6-0-cen-ce-rotn-01.telemar.net.br (200.223.131.58) asymm 7 91.980ms

7: 200223045158.host.telemar.net.br (200.223.45.158) asymm 8 308.686ms

8: 194.25.208.61 (194.25.208.61) asymm 16 307.343ms

9: 194.25.6.201 (194.25.6.201) asymm 14 394.287ms

10: no reply

11: so-0-2-0.XT1.HEL2.ALTER.NET (146.188.5.206) asymm 16 589.966ms

12: POS1-0.GW3.HEL2.ALTER.NET (146.188.12.105) asymm 17 510.498ms

13: 62.176.60.162 (62.176.60.162) asymm 15 512.207ms

Maemo for Mobile Developers 

Page 111: Qt for Maemo Developers Guide v0 5 Beta

This command tries to calculate a network path to the remote host across the Internet. 

2.2 Netcat On certain scenarios, the developer needs to test if the internet tablet is receiving data over 

TCP or UDP networks in a specific port. For example, consider that the developer is creating a 

chat program that uses port 5060 to receive data. Thus, it is necessary to know if such port is 

not blocked by any firewall and if it is possible to receive data over TCP properly. Netcat tool 

can be used on such problem. 

Netcat is a simple utility used to read and write data across network connections, using TCP or UDP protocols. The name of the command line executable is nc. 

To install it on the device use the following command: 

# apt-get install netcat

The usage of this feature is as simple as: 

# nc -l -p 5060

This  command  opens  a  TCP  port.  The  option  ‐l  stands  for  listen  and  the  option  ‐p  allows specifying  the  port  number.  Then,  a  listening  socket  will  be  created  on  port  5060. When someone connects to this port and send data to it, the data will be printed on the console. 

After run the command above, you can test  if the  internet tablet  is receiving data  in the port specified using the following Python program: 

import socket

HOST = '192.168.1.163'

PORT = 5060

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

s.connect((HOST, PORT))

s.send('netcat test')

data = s.recv(1024)

s.close()

print 'Received', repr(data)

This program just connects to the IP address assigned to HOST and to the port assigned to 

PORT. In this case, we have assigned the IP address and the port of the internet tablet which is 

running the Netcat command.  

If you run the program above, you will see this output on internet tablet: 

# nc -l -p 5060

Maemo for Mobile Developers 

Page 112: Qt for Maemo Developers Guide v0 5 Beta

netcat test

It  is  also  possible  to  use  Netcat  to  connect  to  a  host  and  send  data  to  it  by  running  the following command: # nc host port

 In this case, the host can be the IP address of one computer which are running the following Python program. The port can be the value assigned to the PORT variable in the program 

import socket

HOST = "192.168.1.52"

PORT = 5060

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

s.bind((HOST, PORT))

s.listen(1)

conn, addr = s.accept()

print 'Connected by', addr

data = conn.recv(1024)

print data

conn.close()

This program creates a socket server over TCP and listens for a connection. 

For  effective  example  test,  first  run  the  Python  program  described  above  (using  the  local machine IP address for HOST) and after run the command (using the correct IP address): 

# nc 192.168.1.52 5060

ok

The output of the python program will be: 

Connected by ('192.168.1.163', 51723)

ok

The Netcat tool allows connecting to or waiting for UDP connections by using the ‐u option. 

Others options can be used (like ‐t for enable telnet negotiation) on Netcat and you can get 

details about it in the Netcat manual page 

(http://maemo.org/development/documentation/man_pages/nc/). 

Maemo for Mobile Developers 

Page 113: Qt for Maemo Developers Guide v0 5 Beta

2.3 Tcpdump On some cases, Netcat tool is not enough. For example, the developer needs to monitor all 

packets received from some computer on the network (and not only the data send for it). In 

such case, you can use Tcpdump. 

Tcpdump is a utility to capture and monitor data from the network. This tool can filter network data traffic using boolean expressions. A description for each captured packet could be printed on the screen. For a better analysis, it is preferred to save the captured data in a file for later analysis. 

To install it on the device use the following command: 

#apt-get install tcpdump

As an example, the following command can be used to catch packages from a specific domain: 

$ tcpdump -w capture.cap src host.domain.net

In this case, all data that comes from the host host.domain.net to the target device is captured and saved in the file capture.cap. 

$ tcpdump -X udp and dst host.domain.net

In this second example, the content of UDP packets going to host.domain.net are displayed on the screen in hexadecimal representation. 

2.4 Traceroute Traceroute is a utility that prints the route packets to a network host. It displays each network hop and the time taken to reach it. 

To install them on the device use the following command: 

# apt-get install traceroute

To use this tool, run the command: 

$ traceroute www.maemo.org

traceroute to maemo.org (62.61.69.114), 30 hops max, 40 byte packets

1 192.168.1.1 (192.168.1.1) 3.052 ms 4.272 ms 3.387 ms

2 192.168.254.254 (192.168.254.254) 3.937 ms 4.273 ms 5.250 ms

3 200.217.72.216 (200.217.72.216) 316.925 ms 404.786 ms 311.005 ms

4 gigabitethernet13-0.91-vpt-pb-rotd-02.telemar.net.br (200.164.197.145) 305.969 ms 303.589 ms 407.409 ms

5 pos10-2-bvg-pe-rotd-02.telemar.net.br (200.164.196.42) 309.479 ms 405.487 ms 409.851 ms

Maemo for Mobile Developers 

Page 114: Qt for Maemo Developers Guide v0 5 Beta

6 pos6-0-cen-ce-rotn-01.telemar.net.br (200.223.131.58) 405.182 ms 200223045201.host.telemar.net.br (200.223.45.201) 307.953 ms 309.479 ms

7 200.223.254.81 (200.223.254.81) 402.740 ms 200223045158.host.telemar.net.br (200.223.45.158) 421.265 ms 200.223.254.81 (200.223.254.81) 395.385 ms

8 194.25.208.61 (194.25.208.61) 506.592 ms 508.667 ms

2.5 Nslookup Nslookup  is  a  utility  to  query  Internet  name  servers  interactively.  There  is  a  command  to translate a name to an IP address. With this command  is possible to  identify problems  in the name resolution process. 

This  command  comes  to Maemo  through busybox binary. As an example, use  the  following command: 

$ nslookup www.maemo.org

Server: 127.0.0.1

Address 1: 127.0.0.1 Nokia-N800-43-7

Name: www.maemo.org

Address 1: 62.61.69.114

This command shows the IP address of the specified host. The ping command described above could also be used to retrieve an IP address from the internet name. 

2.6 Wget Wget  is  a utility  to download  files  from  the web  through  the  command  line.   With wget  is possible to retrieve files using the protocols HTTP, HTTPS and FTP. 

To install it on the device use the following command: 

# apt-get install wget

Use this tool like in the example: 

$wget http://www.host.net/file.txt

3 Wireless tools In  this category are present  tools used  to manage wireless connections using Bluetooth and Wi‐Fi technologies. 

3.1 Bluetooth tools Bluez‐hcidump allows the capture of raw data in the Bluetooth HCI (Host controller interface) layer in a human readable way. 

To install on the device use the following command: 

Maemo for Mobile Developers 

Page 115: Qt for Maemo Developers Guide v0 5 Beta

# apt-get install bluez-hcidump

To use bluez‐hcidump, run this command: 

$ hcidump -V -x

This command enables the decoding of Bluetooth packets interactively and display the content in a hexadecimal form. 

3.2  Wireless­tools Wireless‐tools is a package containing a lot of utilities to manage Wi‐Fi connections. With it, it is possible to manipulate wireless LAN specific parameters like wireless SSID and grab statistics about connections. The applications provided by these tools are: 

ifrename: allow user to change network interfaces names; 

iwconfig: used to configure parameters of the wireless interface, analogous to ifconfig command;   

iwevent: display wireless events generated by drivers and settings changes; 

iwgetid: used to get information about the current wireless network, like the Id of the network,    the  access  point MAC  address,  the  channel  number,  the  frequency,  the connected mode and the protocol  info. This  information  is also reported by  iwconfig command,  but iwgetid is more friendly to be used in scripts;  

iwlist: display additional  information  from a   wireless network  interface, and can be used  to scan network  in  the coverage area. The  information  that can be grabbed by this command are frequency, rate, keys, power, txpower, retry, event, auth, wpakeys, genie and modulation; 

iwpriv:  allow  the  configuration  of  private  parameters  of  a wireless  network.  These parameters should be indicated in the documentation of each driver; 

iwspy: used to grab statistics from specific wireless nodes. This feature isn’t supported currently with the native wireless interface. 

 

To install them on the device use the following command: 

#apt-get install wireless-tools ifrename

Usage examples of these tools are shown below: 

$ ifrename -p -i wlan0 -n eth1

This command renames the wlan0 interface to eth1 interface. It only works when the interface is not in use. 

$ iwconfig wlan0 essid MaemoNet key 123456789A mode Ad-Hoc channel 7

To  create  an  Ad‐Hoc  network  with  ESSID MaemoNet  using WEP  security  and  listening  on channel 7. 

$ iwevent

23:02:54.392303 wlan0 Scan request completed

To listen events that happens in the wireless network card. 

Maemo for Mobile Developers 

Page 116: Qt for Maemo Developers Guide v0 5 Beta

$ iwgetid -r -a

To get the MAC address of the connected access point. 

$ iwlist wlan0 scanning

To scan the wireless network reachable by internet tablet device. 

$ iwpriv wlan0

To list the available IO controls calls for the wireless interface. 

4 Test automation In this category, a set of tools used to automate test execution for Maemo based systems are described. With these tools, it is possible to perform stress tests, simulate user interaction and measure how long times it takes between an action and the execution. 

4.1 Sp­tests This tool makes it possible to generate extra demand for system and see how the application deal with  situations  of  high  system  loads  in  terms  of  CPU, memory  and  I/O  requests.  This package consists of the following utilities: 

cpuload: used to generate CPU load; 

ioload: used to generate I/O load; 

memload: used to generating memory load.  

To install them on the device, use the following command: 

# apt-get install sp-stress

As a first example, execute the following command to start CPU stress tests: 

$ cpuload 25

The above command generates an extra CPU load of 25 percent. Now, the following example creates a file on memory card used to generate I/O extra load: 

$ dd if=/dev/zero of=/media/mmc1/workfile count=1024 bs=1024

$ ioload /media/mmc1/workfile

The  internal memory of  Internet Tablet should not be used because  its  file‐system  (JFFS2)  is not appropriated for this kind of operation. Then,  ioload  is used to start  I/O stress tests. The content  of  the  file  created  is  destroyed  at  the  end  of  tests.  Finally, memload  is  used  to generate stress tests on memory: 

$ memload 25

The command above creates a process that consumes 25 megabytes of memory. 

Maemo for Mobile Developers 

Page 117: Qt for Maemo Developers Guide v0 5 Beta

4.2 Xnee This tool is used to automate user interaction under X server. Xnee make it possible to record, replay  and  redistribute  user  actions  (X  events)  under  the  X11  environment.  This  package contains the following utilities: 

cnee: a command line utility; 

gnee: a graphical user interface for cnee.  

To install Xnee on Internet Tablet, use the following command: 

# apt-get install xnee

As your first example, execute the following command: 

$ cnee --record --mouse --events-to-record 100 -o input_events_rec.xnl

The  command  above  records  the  first  100  input  events.  Then,  use  the  following  command replays the commands recorded in the file input_events_rec.xnl.  

$ cnee --replay --file input_events_rec.xnl

4.3 Xresponse With Xresponse,  it  is possible  to monitor  screen updates.  It  is also possible  to measure  the time used to update the screen after user interactions. The screen update areas are output in the “X geometry” format (width x height + X position + Y position). It can also simulate stylus taps. 

To install it on the device, use the following command: 

# apt-get install xresponse

As your first example, execute the following command: 

$ xresponse -w 0 -i

This  command  start  to  listen  the  screen  changes  for  ever  (or  until  a  control‐C  press),  ‐w  0 option, and display the area changed in the occurrence of an update screen event. 

A detailed analysis of screen changes can be done with the Xresponse‐visualize scripts. This set of scripts allows the generation of animations from xresponse logs.  

5 Resource usage 

5.1 Htop Htop is a text‐only, interactive process viewer similar to 'top'. 

The process list is scrollable; 

Control screen items with the stylus in addition to the keyboard; 

The information on screen is configurable; 

Strace can be attached to a process with a single keypress. 

Maemo for Mobile Developers 

Page 118: Qt for Maemo Developers Guide v0 5 Beta

To install Htop connect with device using ssh and run the following command: 

$ apt-get install htop

Now, you can run Htop with the command as follows: 

$htop

Htop generates the following output: 

 

5.2 Sp­memusage Maemo programming environment also provides tools to monitor memory usage. sp‐

memusage consists of utility scripts and tools that monitor memory usage of your system. 

With sp‐memusage, it is possible to check how the memory is being used by a certain process, 

for example. It provides the following tools and scripts: 

mem‐smaps‐private: shows information about private memory usage of a process; 

run‐with‐mallinfo: executes a Maemo application under mallinfo, a function that 

provides data regarding to space usage; 

run‐with‐memusage: executes a Maemo application under memusage, a Glib function 

that provides data regarding to memory usage; 

mem‐dirty‐code‐pages: shows information about dirty code pages allocated by the 

processes; 

mem‐monitor: monitors system memory usage during a certain interval and prints 

information about it; 

mem‐monitor‐smaps: monitors memory usage of some specified processes during an 

interval and prints information about it. 

To install sp‐memusage on your develop environment, open an SSH section with device and 

execute the following command: 

Maemo for Mobile Developers 

Page 119: Qt for Maemo Developers Guide v0 5 Beta

#apt-get install sp-memusage

mem‐dirty‐code‐pages helps to check how many dirty code pages the processes are using. It 

summarizes how many KBs of shared or private dirty code pages the processes are using. If the 

processes are using a lot of dirty code pages, it means that they are not properly compiled with 

option –fPIC. The usage of mem‐dirty‐code‐pages is very simple: 

$mem-dirty-code-pages PID1 [ PID2 ... ]

Consider PIDs as processes identification numbers. The output will look like this: 

Applications with private/shared dirty code pages:

Shared dirty code summed from all processes = 0 kB

Private dirty code pages total = 0 kB

mem‐monitor is very useful, because it monitors system memory usage during a certain 

interval. This tool collects information from /proc/meminfo at given intervals. If you do not 

specify time interval, it use 3 seconds as default. On the following example, mem‐monitor 

provides information about system memory usage during 5 seconds: 

$mem-monitor 5

It generates the following ouput: 

time: total: avail: used: use-%: status:

12:59:06 126796 73084 53712 42

12:59:11 126796 73080 53716 42

12:59:16 126796 73080 53716 42

mem‐monitor‐smaps provides information about memory usage of the specified processes 

during a given time interval. As mem‐monitor, mem‐monitor‐maps also collects information 

from /proc/meminfo system file. It can be used with the options ‐i (to determine the interval 

between memory usage information updates) and –p (to determine the PID of the process 

which the tool has to monitor). On the following example, mem‐monitor‐smaps monitors 

process with PID 1272 and the memory usage information have to be updated every 4 

seconds: 

$mem-monitor-smaps -i 4 -p 1272

The command described above outputs the following result: 

List available system memory and given process memory usage

for /usr/bin/mediaplayer-engine[1272] according to SMAPS.

(without swap as SMAPS doesn't report swap correctly)

Maemo for Mobile Developers 

Page 120: Qt for Maemo Developers Guide v0 5 Beta

system process private /------ dirty ---------\

time: avail: size: rss: clean: shared: private: change:

10:05:16 72908 16640 3780 60 0 572 +0 kB

10:05:20 72888 16640 3780 60 0 572 +0 kB

10:05:24 72888 16640 3780 60 0 572 +0 kB

10:05:29 72888 16640 3780 60 0 572 +0 kB

mem‐smaps‐private monitors private memory usage of a given process. This information is 

collected from /proc/PID/smaps system file. The usage of mem‐smaps‐private is very simple: 

$mem-smaps-private PID

Consider PID as the identification number of the process the mem‐smaps‐private has to 

monitor. It generates the following output: 

PID 1272: mediaplayer-engine

- Dirty shared memory: 0 kB

- Dirty private memory: 572 kB

- Clean private memory: 60 kB

run‐with‐memusage runs a given application under memusage, a wrapper library provided by 

GLib. It collects information about application memory usage during its execution and 

generates a report with the summary of memory management. The sintax of run‐with‐

memusage command is as follows: 

$run-with-memusage <binary> [args]

Consider binary as the application to be monitor and args as arguments of the specified binary. 

It outputs the following result: 

Maemo for Mobile Developers 

Page 121: Qt for Maemo Developers Guide v0 5 Beta

 

run‐with‐mallinfo  runs a given application under mallinfo wrapper  library and  reports space 

usage based on several memory  information, such as number of ordinary blocks, number of 

small  blocks,  space  in  free  ordinary  blocks,  and  much  more.  The  result  is  saved  on 

$HOME/mallinfo‐PID.trace file. The usage of run‐with‐mallinfo script is very simple: 

$run-with-mallinfo <binary> [args]

Consider binary as the application to be monitor and args as arguments of the specified binary. 

However,  it  is  necessary  to  set  MALLINFO  environment  variable  before  using  run‐with‐

mallinfo: 

$export MALLINFO=yes

For a certain example, run‐with‐mallinfo generates the following output: 

Using LD_PRELOAD for loading mallinfo to ./qtmaemo

To enable tracing you have to set MALLINFO variable:

export MALLINFO=yes -- use 5 seconds timeout and SIGALRM

export MALLINFO=signal=10 -- use SIGUSR1 to generate the report

export MALLINFO=period=10 -- periodic report for 10 seconds

mallinfo version 0.2.0 build Sep 17 2008 17:21:49 (c) 2005 Nokia

Maemo for Mobile Developers 

Page 122: Qt for Maemo Developers Guide v0 5 Beta

detected variable MALLINFO with value 'yes'

signal 14 (Alarm clock) is used for reporting

report will be created every 5 seconds

report file /home/user/mallinfo-1558.trace

Hello World

Closing application...

mallinfo finalization completed

In this case, the result is saved on file /home/user/mallinfo‐1558.trace: 

time,arena,ordblks,smblks,hblks,hblkhd,usmblks,fsmblks,uordblks,fordblks,keepcost,total,sbrk

0,135168,1,0,0,0,0,0,440,134728,134728,135168,0x00034000

5,1200128,33,3,3,208896,0,136,1147792,52336,49160,1409024,0x00138000

8,1200128,217,709,0,0,0,26960,1009584,190544,45328,1200128,0x00138000

The  following output provides  information about:  time  interval  (time),  total  space  in arena 

(arena), number of ordinary blocks  (ordblks), number of  small blocks  (smblks),  space  in 

holding block headers  (hblks), number of holding blocks  (hblkhd), space  in small blocks  in 

use  (usmblks),  space  in  free  small  (fsmblks),  space  in ordinary blocks  in use  (uordblks), 

space  in  free ordinary blocks  (fordblks),   space penalty  if keep option  is used  (keepcost) 

and result of sbrk tool (sbrk). 

5.3 Sp­smaps­measure sp‐smaps‐measure installs an utility that can be invoked to take a snapshot of 

/proc/PID/smaps files. The smaps files contain very detailed information about processes 

memory consumption. 

To install sp‐smaps‐measure, just run the command: 

#apt-get install sp-smaps-measure

To put it to work, run the command: 

$sp_smaps_snapshot

It will print several information about processes memory usage on the screen. To avoid it, is 

also possible to send the information to a file using this command: 

$sp_smaps_snapshot > file.cap

The “.cap” extension file can be analyzed by the sp‐smaps‐visualize tool.  

Maemo for Mobile Developers 

Page 123: Qt for Maemo Developers Guide v0 5 Beta

5.4 Sp­smaps­visualize sp‐smaps‐visualize provides utilities to analyze smaps data captured by sp‐smaps‐measure. To 

install it run the command: 

#apt-get install sp-smaps-visualize

Now you be able to run the command: 

$sp-smaps-visualize file.cap

Where file “.cap” is the file containing information generated by sp_smaps_snapshot tool. 

After run, an html will be generated containing information in an easy to view format. 

5.5 Xrestop Xrestop shows how much X resources from the X server are being used by the X clients. It is 

similar to top and htop. 

To install Xrestop, run the following command: 

#apt-get install xrestop

As your first example, you can run xrestop using the command: 

$xrestop

Then, the xrestop application appears as shown on the following image: 

 

 

Maemo for Mobile Developers 

Page 124: Qt for Maemo Developers Guide v0 5 Beta

 

Chapter 7 Debugging and Profiling 

1 Debugging Even if you are worried about bugs on your code and develop Maemo applications considering 

good programming practices, it is not possible to assure that your application is bug‐free. Thus, 

it is important to find in which part the application has problems and correct them.   

Debugging is known as the technique that helps to find errors in a code with purpose to 

correct them. This section is targeted to show some of the Maemo debugging tools that help 

developers to find errors easily. 

In this section, we will get into details of the following debugging tools: 

Maemo‐debug‐scripts 

Gdb 

Sp‐error‐visualizer 

Sp‐rich‐core 

Syslog 

These tools can be installed in the device by activating the tools repository in the Application 

manager. There are different repositories for Diablo and Fremantle releases. Developers can 

install them to the device and in Scratchbox using the command line interface. In this tutorial, 

Fremantle is being used as main platform.  

To activate the tools repository with the Application Manager, create a new catalogue like this:  

1. Start the Application Manager 

2. From its menu bar select Tools and then Application catalogue... 

3. Press the “New” button 

4. Enter the following: 

Catalogue name:fremantle tools 

Web address:http://repository.maemo.org 

Distribution:fremantle/tools 

Components:free non‐free 

Disabled:leave unchecked 

5. Click OK 

If you prefer to edit configuration files yourself instead of using the Application Manager, add 

these lines to /etc/apt/sources.list: 

For Diablo: 

# diablo tools 

Maemo for Mobile Developers 

Page 125: Qt for Maemo Developers Guide v0 5 Beta

deb http://repository.maemo.org diablo/tools free non‐free # diablo tools sources deb‐src http://repository.maemo.org diablo/tools free non‐free 

For Fremantle: 

# Fremantle tools 

deb http://repository.maemo.org fremantle/tools free non‐free 

 

# Fremantle tools sources 

deb‐src http://repository.maemo.org fremantle/tools free non‐free 

Note: To have these tools visible in the Application Manager, you need to have the Red Pill 

Mode (http://maemo.org/community/wiki/ApplicationManagerRedPillMode/) activated. 

To install a binary package in Scratchbox: 

$ fakeroot apt‐get install <package_name> 

To install a binary package into device: 

$ sudo gainroot 

$ apt‐get install <package_name>    

1.1 General tools 

1.1.1 Maemo­debug­scripts maemo‐debug‐scripts is a convenience package for Maemo developers needing to debug their 

programs. To install maemo‐debug‐scripts use the following command: 

$ apt‐get install maemo‐debug‐scripts    

This command will install a few helper scripts: 

native‐gdb 

o runs the target native GDB (by default Scratchbox runs the host binary if it 

exists, this script overrides that) 

debug‐dep‐install 

o installs debug symbols for given binaries and their dependencies listed by 

"ldd" 

debug‐pkg‐check 

o checks the correctness of a debug package for a given package 

list‐mmapped‐libs 

o lists all packages containing libs and binaries that given process uses. It can be 

used to find out the libraries mmapped through dlopen that "ldd" (used by 

debug‐deb‐install script) doesn't find 

run‐with‐valgrind 

Maemo for Mobile Developers 

Page 126: Qt for Maemo Developers Guide v0 5 Beta

o helper script for running a binary with Valgrind memcheck plugin (memory 

access errors, leaks etc) so that all suitable options are set for it 

run‐with‐callgrind 

o helper script for running a binary with Valgrind callgrind plugin (performance 

profiling) so that all suitable options are set for it 

run‐with‐massif 

o helper script for running a binary with Valgrind massif plugin (memory usage 

visualization) so that all suitable options are set for it 

run‐with‐helgrind 

o helper script for running a binary with Valgrind helgrind plugin (race condition 

detector for threaded programs) so that all suitable options are set 

run‐with‐strace 

o helper script for running a binary with strace. Like above helper scripts, 

handles Maemo‐launched binaries automatically 

Following, we will show some of these scripts in details. 

1.1.2 native­gdb By default Scratchbox uses its own host tools instead of the target ones, if such are installed. 

This (trivial) script overrides that setting for /usr/bin/gdb. To use it, run the command: 

$native‐gdb 

Because the host Gdb will use the thread_db coming with the toolchain with which has been 

built with, it cannot debug threads properly.  Instead of using this script, you can also remove 

or rename the Scratchbox host Gdb.  

1.1.3 debug­dep­install debug‐dep‐install is a helper script for installing debug symbol packages in the Maemo 

GNU/Linux environment. The script checks what libraries the given binaries and libraries are 

linked against, into which packages those belong to, and whether they have corresponding 

debug symbols packages. Then it installs the available debug symbols packages. To use it just 

run: 

$ debug‐dep‐install <binaries> 

Then, the debug symbol packages will be installed for the given binaries. For example, run the 

debug‐dep‐install for native‐gdb binaries: 

$ debug‐dep‐install /usr/bin/native‐gdb 

Note: you must use the full path for the script binaries to make it work. You can use the 

command “which” to find application’s full path. 

The script works on both device and Scratchbox development environments. 

Maemo for Mobile Developers 

Page 127: Qt for Maemo Developers Guide v0 5 Beta

1.1.4 list­mmapped­libs list‐mmapped‐libs is a helper script that can be used with debug‐dep‐install. Debug‐dep‐install 

installs only the dependencies that the given binaries (or libraries) link directly. This script can 

find out what additional libraries have been dlopened by the given process so that you can give 

them also to debug‐dep‐install. To use it just run: 

$list‐mmapped‐libs <PID> 

Here, PID is the process identification number which you want to observe. To get the process 

identification number, just run the command: 

ps xau 

1.2 GDB Debugging  is an  important method  to  find bugs  in order  to  fix  them. Such  iterative cycle of 

find‐fix bugs improves application quality, and the result is a more stable and reliable system. 

Debugging is often used to find more complex bugs that cannot be detected using traditional 

testing  approaches  (unit  tests,  for  example).  In  the  context  of  embedded  systems 

development, the developer generally faces strange errors that cannot be properly defined. 

When developing for Maemo using Scratchbox, the host platform  is different from the target 

one. In general, you may face some complex bugs (a segmentation fault, for example) related 

to memory  or  registers  usage.  As  developers, we  need  a  useful  tool  that  displays  a  lot  of 

detailed data about application which is being launched and also about the platform. 

GDB,  the  GNU  Project  debugger,  is  a  helpful  debugger  that  provides  information  about  a 

program during its execution: control over application execution (start, pause, stop), memory 

map,  registers, variables, source code, backtrace and much more. GDB was developed  to be 

used on many Unix‐like systems and it works for many programming languages, such as C, C++ 

and Java. 

With GDB,  it  is possible to see what  is going on  inside a program while  it executes,  including 

the moment it crashed. It is possible to check variables values to verify if the program logic is 

correct, or follow the function calls to see what peace of the code is been executed for a given 

feature. 

GDB can be used to debug a Maemo application on different scenarios: on Scratchbox  (both 

ARMEL  and  X86  targets)  and  also  directly  on  Internet  Tablet.  However,  for  each  of  these 

environments,  there are some configuration steps  to be performed. This section shows how 

you  can  use  GDB  to  debug  a Maemo  application  in  order  to  improve  the  quality  of  your 

software. 

An advanced way to debug with GDB is running it as a client‐server application. The gdbserver 

is  launched on remote device and  it runs application debugging section. On the desktop side, 

GDB  is  used  as  a  client  to  control  the  gdbserver  and  view  the  debugging  results.  The 

communication  between  the machines  is  established  using GDB  protocol  via  serial  port  or 

TCP/IP. More details about how to debug with gdbserver is described in this section. 

Maemo for Mobile Developers 

Page 128: Qt for Maemo Developers Guide v0 5 Beta

1.2.1 Installing and testing gdb As described before, you can debug a Maemo application on Scratchbox or on Internet Tablet. 

On this section, we describe how to  install GDB on both environments and how to check  if  it 

was properly installed.  

1.2.1.1 Preparing Scratchbox environment Both Fremantle targets (FREMANTLE_ARMEL and FREMANTLE_X86) provide a GDB executable.  

However, such GDB executables are not suitable  for Maemo development, because they are 

not properly configured to application debugging on Maemo rootstraps.  Instead, we need to 

use  a  native  executable,  a  non  Scratchbox  version  of GDB, which  is  accessible  using  script 

native‐gdb.  At  first,  in  order  to  set  properly  native‐gdb,  it  is  necessary  to  install  package 

Maemo‐debug‐scripts as described on this section. As your first try, launch native‐gdb without 

any parameter: 

[sbox-FREMANTLE_X86: ~] > native-gdb

GNU gdb (GDB) 6.8.50.20090417-debian

Copyright (C) 2009 Free Software Foundation, Inc.

License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software: you are free to change and redistribute it.

There is NO WARRANTY, to the extent permitted by law. Type "show copying"

and "show warranty" for details.

This GDB was configured as "i486-linux-gnu".

For bug reporting instructions, please see:

<http://www.gnu.org/software/gdb/bugs/>.

(gdb)

Therefore,  from  now  one  native‐gdb  script  is  used  instead  of  GDB  for Maemo  application 

debugging on Scratchbox. 

1.2.1.2 Preparing Internet Tablet environment  You need to establish an SSH section as root with Internet Tablet to proceed.  

maemo@maemo-desktop:~$ ssh [email protected]

[email protected]'s password:

In addition, GDB for  Internet Tablet  is available on Maemo Tools repository. Then,  if Maemo 

Tools  repository  is  not  properly  configured  on  your  Internet  Tablet,  edit  file 

/etc/apt/sources.list and add the following line: 

deb http://repository.maemo.org/ fremantle/tools free non-free

Maemo for Mobile Developers 

Page 129: Qt for Maemo Developers Guide v0 5 Beta

Once Maemo Tools repository was added as a valid repository,  it  is necessary  to update  the 

packages  list. Execute  the  following commands as  root  to  refresh  the package database and 

install GDB in the device: 

Nokia-N810:~# apt-get update

… snip …

Nokia-N810:~# apt-get install gdb

Now, you have GDB installed on Internet Tablet. You can start debugging maemo applications on device.

Nokia-N810:~# gdb

GNU gdb 6.8-debian

Copyright (C) 2008 Free Software Foundation, Inc.

License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software: you are free to change and redistribute it.

There is NO WARRANTY, to the extent permitted by law. Type "show copying"

and "show warranty" for details.

This GDB was configured as "arm-linux-gnueabi".

(gdb)

To quit from GDB, press ‘q’ and hit ENTER key. 

1.2.2 Debugging with native­gdb on Scratchbox NOTE: Qt  libraries for Maemo are supposed to be  installed on Scratchbox before continuing. 

See Section 2.3, on Chapter chapter 2. 

On this section, we present one example application that will help to understand the basic use 

of native‐gdb on Scratchbox. The application defines a simple Qt widget, which  inherits from 

QWidget  class.  This  widget  creates  a  Qt  push  button  and  connects  it  to  a  slot  function 

(MyButton::printAndQuit). When such button is clicked, the function MyButton::printAndQuit 

is invoked: a message (“Hello World...”) is printed on console and the application is finished. A 

screenshot with the application is shown as follows: 

Maemo for Mobile Developers 

Page 130: Qt for Maemo Developers Guide v0 5 Beta

  

The code of first example (gdb_qt_example.cpp and gdb_qt_example.h) is as follows: 

1 #ifndef GDB_QT_EXAMPLE_H 2 #define GDB_QT_EXAMPLE_H 3 4 #include <QWidget> 5 6 class MyButton : public QWidget { 7 Q_OBJECT 8 public: 9 MyButton(QWidget *parent = 0); 10 private: 11 void printMessage(); 12 void quitApplication(); 13 public slots: 14 void printAndQuit(); 15 }; 16 17 #endif 1 #include <QApplication> 2 #include <QPushButton> 3 #include <QWidget> 4 #include <QVBoxLayout> 5 #include <iostream> 6 7 void MyButton::printMessage() { 8 std::cout << "Hello World\n"; 9 std::cout << "Closing application...\n"; 10 } 11 12 void MyButton::quitApplication() {

Maemo for Mobile Developers 

Page 131: Qt for Maemo Developers Guide v0 5 Beta

13 qApp->quit(); 14 } 15 16 void MyButton::printAndQuit() { 17 printMessage(); 18 quitApplication(); 19 } 20 21 MyButton::MyButton(QWidget *parent) : QWidget(parent) { 22 QPushButton *quitButton = new QPushButton("Quit"); 23 connect(quitButton, SIGNAL(clicked()), this, SLOT(printAndQuit())); 24 25 QVBoxLayout *layout = new QVBoxLayout; 26 layout->addWidget(quitButton); 27 setLayout(layout); 28 } 29 30 int main(int argc, char* argv[]) { 31 int x = 10; 32 std::cout << "Value of x: " << x; 33 QApplication app(argc,argv); 34 MyButton *button = new MyButton; 35 button->show(); 36 return app.exec(); 37 }

This  application  is  a  very  simple  Qt  application  with  a  push  button. When  the  button  is 

pressed, the function MyButton::printAndQuit (file gdb_qt_example.cpp,  line #16)  is  invoked: 

it prints a message on console and quit from application. 

Before debugging the application, it is necessary to compile it properly in order to generate an 

executable with debug symbols, so we can debug  it with GDB. The debugging  information  is 

stored in object file and contains data type of each symbol (variable or function) and also the 

correspondence between source line numbers and memory addresses of executable code. 

If  you want  to  request debugging  information  for Qt Maemo  application,  it  is necessary  to 

modify the *.pro file of the project. Include the following configuration option on *.pro file: 

TEMPLATE = app TARGET = DEPENDPATH += . INCLUDEPATH += . CONFIG += debug # Input HEADERS += gdb_qt_example.h SOURCES += gdb_qt_example.cpp

Now, (re)generate the project´s Makefile, and build the sources: 

[sbox-FREMANTLE_X86: ~/gdbexample] > qmake

Maemo for Mobile Developers 

Page 132: Qt for Maemo Developers Guide v0 5 Beta

[sbox-FREMANTLE_X86: ~/gdbexample] > make

The application  is ready  for debugging with GDB. Remember  that we have  to use  the native 

GDB (native‐gdb), not Scratchbox one. Finally, start native‐gdb application: 

[sbox-FREMANTLE_X86: ~/gdbexample] > native-gdb gdbexample

... snip …

(gdb)

During debugging sections, we often need  to  follow  the application control  flow.  In order  to 

pause application execution at a certain line of the source code, you need to set breakpoints. 

Once your application execution  is  frozen at a  certain point of  the  code, you  can  check  the 

values  of  variables,  registers  and memory.  As  an  example,  insert  two  breakpoints:  one  on 

function MyButton::printAndQuit(),  and  another one on  function MyButton::printMessage(). 

To do this use GDB function break: 

(gdb) break MyButton::printAndQuit

Breakpoint 1 at 0x804a6d8: file gdb_qt_example.cpp, line 19.

(gdb) break MyButton::printMessage

Breakpoint 2 at 0x804a1e4: file gdb_qt_example.cpp, line 10.

You can also insert a breakpoint on a certain line of source code. For example, if you want to 

insert a breakpoint on line 33, execute the following command: 

(gdb) break gdb_qt_example.cpp:33

Breakpoint 2 at 0x804a400: file gdb_qt_example.cpp, line 33.

For more information about GDB breakpoints, see GDB documentation. 

Once breakpoints are properly inserted, we can start debugging the application under native‐

gdb. 

(gdb) run

Starting program: /home/maemo/gdbexample/gdbexample

[Thread debugging using libthread_db enabled]

QGtkStyle cannot be used together with the GTK_Qt engine.

Breakpoint 1, MyButton::printAndQuit (this=0x8061998) at gdb_qt_example.cpp:19

19 printMessage();

(gdb)

Maemo for Mobile Developers 

Page 133: Qt for Maemo Developers Guide v0 5 Beta

 

As  you  can  see,  the  application  pauses  on  first  breakpoint  it  found:  function 

MyButton::printAndQuit(). It is possible to see the source code around a certain line number. 

For example, if you want to see the code around line #20, use GDB function list: 

(gdb) list 19 14 void MyButton::quitApplication() { 15 qApp->quit(); 16 } 17 18 void MyButton::printAndQuit() { 19 printMessage(); 20 quitApplication(); 21 } 22 23 MyButton::MyButton(QWidget *parent) : QWidget(parent) {

To continue the debugging section until the next breakpoint, use GDB function “continue”.  If 

you want to continue running your program until control reaches a different source  line, use 

GDB function step: 

(gdb) continue

Continuing.

Breakpoint 2, MyButton::printMessage (this=0x80718e8) at gdb_qt_example.cpp:10

10 std::cout << "Hello World\n";

(gdb) step

Hello World

11 std::cout << "Closing application...\n";

GDB provides a list with functions that have been called during the current debugging section 

(GDB function backtrace). The list goes from recent to older. The oldest function was naturally 

the main() function at the end of the list. It shows also the parameters to the called functions: 

(gdb) backtrace

#0 MyButton::printMessage (this=0x8061998) at gdb_qt_example.cpp:10

#1 0x0804a685 in MyButton::printAndQuit (this=0x8061998) at gdb_qt_example.cpp:19

#2 0x0804a8d2 in MyButton::qt_metacall (this=0x8061998, _c=QMetaObject::InvokeMetaMethod, _id=0, _a=0xbfffd2f8) at moc_gdb_qt_example.cpp:66

Maemo for Mobile Developers 

Page 134: Qt for Maemo Developers Guide v0 5 Beta

#3 0xb73f320e in QMetaObject::activate(QObject*, int, int, void**) () from /usr/lib/libQtCore.so.4

#4 0xb73f362e in QMetaObject::activate(QObject*, QMetaObject const*, int, int, void**) () from /usr/lib/libQtCore.so.4

#5 0xb7df4473 in QAbstractButton::clicked(bool) () from /usr/lib/libQtGui.so.4

#6 0xb7ade609 in QAbstractButtonPrivate::emitClicked() () from /usr/lib/libQtGui.so.4

As mentioned before, you can  inspect the value of the variables. Let´s  insert a breakpoint on 

file gdb_qt_example.cpp line #36 to verify the values of main function variables: 

(gdb) break gdb_qt_example.cpp:36 Breakpoint 3 at 0x804a43b: file gdb_qt_example.cpp, line 36. (gdb) continue Continuing. Breakpoint 3, main (argc=1, argv=0xbffff5e4) at gdb_qt_example.cpp:36 36 QApplication app(argc,argv);

Use GDB function print to inspect a variable (variable x, for example): 

(gdb) print x $1 = 10

GDB  has  very  interesting  functions  to  display  registers  values  (GDB  function  info  registers), 

show memory  regions  (GDB  function display  [EXP]), and much more. For more  information, 

see GDB documentation. 

1.2.3 Debugging with gdb on device NOTE: Qt  libraries for Maemo are supposed to be  installed on Scratchbox before continuing. 

See 2.4,"Install Qt on Scratchbox" on Chapter 2. 

In this section, we will use the same example adopted in previous section to demonstrate how 

to debug with GDB on Internet Tablet. 

It is possible to debug an application in the Internet Tablet device itself using GDB. In order to 

make the work easier, we need to establish a SSH section with device. Please, look in the 

section  6.2,"Deploy application to the device" to learn how to connect with device using SSH. 

Since the executable is supposed to be launched on Internet Tablet, we need to compile it to 

ARMEL architecture. Thus, we need to change the Scratchbox target from FREMANTLE_X86 to 

FREMANTLE_ARMEL.  

Now,  compile  the Qt. Do  not  forget  to modify  *.pro  file  so  debug  information  is  properly 

generated into object file: 

Maemo for Mobile Developers 

Page 135: Qt for Maemo Developers Guide v0 5 Beta

[sbox-FREMANTLE_ARMEL: ~/gdbexample] > qmake

[sbox-FREMANTLE_ARMEL: ~/gdbexample] > vim gdbexample.pro

[sbox-FREMANTLE_ARMEL: ~/gdbexample] > make

Copy the ARMEL version of the gdb_qt_example to the tablet using SCP: 

[sbox-FREMANTLE_ARMEL: ~/gdbexample] >scp gdbexample [email protected]:/home/user

Log in on the device with SSH as user. The IP address is an example, your device IP address can 

be different: 

[sbox-FREMANTLE_ARMEL: ~/gdbexample] > ssh [email protected] [email protected]'s password:

Start the gdb debugger with the gdb_qt_example application: 

Nokia-N810:~# gdb gdbexample GNU gdb 6.8-debian Copyright (C) 2008 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "arm-linux-gnueabi"... (gdb)

If you try to debug the executable gdbexample on device, you will certainly face the following 

problem: 

(gdb) break MyButton::printAndQuit Breakpoint 1 at 0xa24c: file gdb_qt_example.cpp, line 19. (gdb) run Starting program: /home/user/gdbexample … snip… [Switching to Thread 0x40020cd0 (LWP 2423)] Breakpoint 1, MyButton::printAndQuit (this=0x115208) at gdb_qt_example.cpp:19 20 gdb_qt_example.cpp: No such file or directory. in gdb_qt_example.cpp

Since the source file is not on device, you cannot verify the corresponding source code. Then, if 

you want to follow your application execution, it is necessary to copy the source code into the 

same folder where the binary is located in the device. 

[sbox-FREMANTLE_ARMEL: ~/gdbexample] >scp gdb_qt_example.cpp [email protected]:/home/user

Maemo for Mobile Developers 

Page 136: Qt for Maemo Developers Guide v0 5 Beta

Now,  it  is possible  to  inspect  the  source  code during  the GDB debugging  section on device. 

Launch the application again on GDB and start debugging: 

(gdb) run Starting program: /home/user/gdbexample … [Switching to Thread 0x40020cd0 (LWP 2473)] Breakpoint 1, MyButton::printAndQuit (this=0x115208) at gdb_qt_example.cpp:19 19 printMessage(); (gdb) list 19 14 void MyButton::quitApplication() { 15 qApp->quit(); 16 } 17 18 void MyButton::printAndQuit() { 19 printMessage(); 20 quitApplication(); 21 } 22 23 MyButton::MyButton(QWidget *parent) : QWidget(parent) { (gdb)

The version of GDB for Internet Tablet has the same features of the one for Scratchbox. Then, 

you  can  check  variables,  registers, memory  and much more.  The  instruction  described  on 

section 2.1.2.3 can also be applied for GDB debugging on device. 

1.2.3.1 Debugging with gdbserver on device GDB  also  provides  an  interesting  feature:  the  remote  debugging.  Such  feature was  initially 

provided to debug applications on machines that could not run GDB in usual way. At first years 

of Maemo development, GDB was not available for Internet Tablet and gdbserver was the only 

way  to  debug Maemo  application  on  device.  In  addition,  gdbserver  does  not  require  the 

application´s  source  code. Then,  it  is not necessary  to  copy all  source  code  files  to  Internet 

Tablet in order to debug you application. This seems not a big issue, but it is really very helpful 

for large application with a lot of source code files. 

There are two different environments involved: gdbserver launches the application on Internet 

Tablet while  GDB  (client)  is  launched  on  host machine.  gdbserver  is  the  one  that  controls 

application  debugging  and  it  sends  information  to  GDB  instance  on  host  machine.  The 

communication  is established by  serial or TCP/IP protocols, using  the  standard GDB  remote 

serial protocol. 

Gdbserver belongs  to GDB package. Thus,  if GDB  is  installed on  Internet Tablet, gdbserver  is 

installed on  it as well. To  start with, you need  to  start gdbserver on device  so GDB  can get 

connected with  remote  debugging  section.  You  need  a  copy  of  the  program  you want  to 

debug, including any libraries it requires.  

On  device,  launch  gdbserver  and  tell  it  how  it  can  communicate with GDB,  its  TCP/IP  host 

address and port: 

Maemo for Mobile Developers 

Page 137: Qt for Maemo Developers Guide v0 5 Beta

Nokia-N810-43-7:~# gdbserver 192.168.2.15:2345 ./gdbexample Process ./gdbexample created; pid = 1488 Listening on port 2345 Remote debugging from host 192.168.2.15

Now, in the host machine, GDB can get connected with device and start application debugging. 

On GDB, you need a copy of your application compiled with debug option, since GDB needs 

symbol  and  debugging  information.  gdbserver  does  not  need  your  program's  symbol  table, 

then you can  strip  the program  if necessary. Before  starting  the debug process, we need  to 

specify  the  executable  on GDB  in  order  to  load  symbols  for  your  application. Use GDB  file 

command: 

[sbox-FREMANTLE_ARMEL: ~/gdbexample] > native-gdb GNU gdb 6.4.90 Copyright (C) 2006 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "arm-linux-gnueabi"... (gdb) file gdbexample Reading symbols from /home/maemo/gdbexample/gdbexample...done.

Once gdbserver is up and running on Internet Tablet, use GDB command target remote to get 

connected with gdbserver: 

(gdb) target remote 192.168.2.15:2345 Remote debugging using 192.168.2.15:2345 [New thread 1488] 0x400007d0 in ?? ()

On  GDB,  you  can  proceed  as  a  local  debugging  section,  including  registers  and  memory 

inspection. For example, you can set breakpoints, proceed with execution and list source code 

lines. 

(gdb) break MyButton::printAndQuit Breakpoint 1 at 0xa24c: file gdb_qt_example.cpp, line 19. (gdb) continue Continuing. Breakpoint 1, MyButton::printAndQuit (this=0x113268) at gdb_qt_example.cpp:19 19 printMessage(); (gdb) list 19 14 void MyButton::quitApplication() { 15 qApp->quit(); 16 } 17 18 void MyButton::printAndQuit() {

Maemo for Mobile Developers 

Page 138: Qt for Maemo Developers Guide v0 5 Beta

19 printMessage(); 20 quitApplication(); 21 } 22 23 MyButton::MyButton(QWidget *parent) : QWidget(parent) {

For more information about gdbserver, see gdbserver documentation. 

1.2.4 Core dump files Internal errors may occur, which cause processes  to crash.    In  this  situation,  it  is  somewhat 

difficult to debug the application directly, considering you have no  idea  in which function the 

application had broken. Some developers start to  look  for the error  in the code adding print 

messages  all  around  it,  execute  the  code,  add  some more messages,  and  follow  this  slow 

process until to find the bug. 

A common error while programming with GTK  is when the application connects signals to an 

object,  and  the object  responsible  for  the  callback  is destroyed  by  the  program. When  the 

signal is troughed, it does not find its callback and them a crash happens. This situation is very 

difficult to find with print messages, since the developer  is not expecting the program flow  is 

passing into the callback function. 

Fortunately, there are options to generate  log files (core dumps) with  information capable to 

retrieve  the  scenario  when  the  error  occurred.  In  general,  the  developer  can  open  the 

generated core dump file with GDB and  inspect the system state  in the exact moment  it had 

crashed.  

There are some Maemo tools available to help developers to retrieve core dump files from the 

device. These tools are available  in the sp‐rich‐core package. Once  installed, sp‐rich‐core will 

produce a core dump file and also additional  information about process, most of /proc data, 

last lines from syslog, df, ifconfig output and much more.  All of such information is added to a 

rich core dump package (.rcore) and then, it is compressed (.lzop) in order to save disk space. 

sp‐rich‐core  generates  the  core  dump  files  as  lzop  compressed  files,  so  they  have  to  be 

uncompressed before using them on debuggers.   The package sp‐rich‐core‐postproc provides 

the rich‐core‐extract utility, which extracts the information from a rich core dump file so GDB 

can read it. Before continue, install packages sp‐rich‐core and sp‐rich‐core‐postproc. 

Nokia-N810:~# apt-get install sp-rich-core sp-rich-core-postproc

The  Internet Tablet kernel does not save core dump  files as default. The default options  for 

code dump file saving are defined in the file /mnt/initfs/linuxrc. Its content is as follows: 

enable_coredumps() { coredir=/media/mmc1/core-dumps echo -n "Enabling core dumps to $coredir/..." echo "$coredir/%e-%s-%p.core" > /proc/sys/kernel/core_pattern ulimit -c unlimited

Maemo for Mobile Developers 

Page 139: Qt for Maemo Developers Guide v0 5 Beta

echo "done." } …

The core dumps are saved by default on directory /media/mmc1/core‐dumps. These options 

also define the size  limit of core dump files and their names, which  includes the name of the 

executable (%e), the signal (%s) and the PID number (%p).   

The following example shows how to generate a core dump file and how we can debug it. To 

show how GDB can be used to debug an application from its core dump file, a modified version 

of  gdbexample  application  is  used  (gdb_qt_buggy_example.cpp  and 

gdb_qt_buggy_example.h).  The  only  changes  remain  on  function  crashApplication():  it  is 

invoked before printing messages on console and  it  tries  to assign a value  to a uninitialized 

pointer  (ptr).  Such  operation  is  invalid  and  it  throws  a  segmentation  fault  exception.  The 

modified code is as follows:  

01 #include <QWidget> 02 #include <QVBoxLayout> 03 #include <iostream> 04 05 #include "gdb_qt_example.h" 06 07 void MyButton::crashApplication() { 08 char *ptr = 0; 09 memcpy(ptr, 0x00, sizeof(ptr)); 10 } 11 12 void MyButton::printMessage() { 13 std::cout << "Hello World\n"; 14 std::cout << "Closing application...\n"; 15 crashApplication(); 16 } 17 18 void MyButton::quitApplication() { 19 qApp->quit(); 20 } …snip…

Now, compile application gdbbuggyexample on FREMANTLE_ARMEL rootstrap and copy  it  to 

device. Do not forget to edit file *.pro to add debug option: 

[sbox-FREMANTLE_ARMEL: ~] > make

… snip …

[sbox-FREMANTLE_ARMEL: ~] >scp gdbbuggyexample [email protected]:/home/user

Run the gdbexample application in the device: 

Nokia-N810:~#./gdbbuggyexample

Maemo for Mobile Developers 

Page 140: Qt for Maemo Developers Guide v0 5 Beta

The  gdbbuggyexample  is  now  running  in  the  background  and  the  application  is  shown  on 

Internet  Tablet  screen.  The  application  crashes when  the button  “Quit”  is pressed: method 

MyButton::crashApplication is invoked inside method MyButton::printMessage.: 

Nokia-N810:~# ./gdbbuggyexample Value of x: 10 Hello World Closing application... Segmentation fault (core dumped)

The  core  dump  file  with  information  about  gdbbuggyexample  application  is  saved  under 

/media/mmc1/core‐dumps.  As  configured  on  /mnt/initfs/linuxrc  file,  its  name  includes  the 

name of the file and the PID number of the gdbbuggyexample program at the end. You can see 

the compressed core dump file (.lzo) saved under /media/mmc1/core‐dumps: 

Nokia-N810:~# cd /media/mmc1/core-dumps

Nokia-N810:/media/mmc1/core-dumps# ls -l gdbbuggyexample-11-2478.rcore.lzo

-rw-r--r-- 1 user root 665.9k Jul 21 12:07 gdbbuggyexample-11-2478.rcore.lzo

The core dump file is now properly generated, but it is still compressed. GDB cannot read the 

core  dump  file  in  such  format,  so  it  is  needed  to  uncompress  it  with  rich‐core‐extract 

application. 

Nokia-N810:/media/mmc1/core-dumps# rich-core-extract \ gdbbuggyexample-11-2478.rcore.lzo coredir

Nokia-N810:/media/mmc1/core-dumps# ls -l coredir/

drwxr-xr-x 2 user root 0 Jul 21 12:35 .

drwxr-xr-x 3 user root 0 Jul 21 12:35 ..

-rw-r--r-- 1 user root 9 Jul 21 12:36 cmdline

-rw-r--r-- 1 user root 55 Jul 21 12:36 component_version

-rw-r--r-- 1 user root 2.7M Jul 21 12:36 coredump

-rw-r--r-- 1 user root 30 Jul 21 12:36 date

-rw-r--r-- 1 user root 521 Jul 21 12:36 df

-rw-r--r-- 1 user root 741 Jul 21 12:36 fd

-rw-r--r-- 1 user root 796 Jul 21 12:36 ifconfig

-rw-r--r-- 1 user root 1.2k Jul 21 12:36 ls_proc

-rw-r--r-- 1 user root 397 Jul 21 12:36 osso-product-info

Maemo for Mobile Developers 

Page 141: Qt for Maemo Developers Guide v0 5 Beta

-rw-r--r-- 1 user root 15.2k Jul 21 12:36 packagelist

-rw-r--r-- 1 user root 28.9k Jul 21 12:36 proc2csv

-rw-r--r-- 1 user root 11.9k Jul 21 12:36 slabinfo

-rw-r--r-- 1 user root 44.1k Jul 21 12:36 smaps

As described before,  the compressed  rich core dump has a  lot of  information about system, 

including  the  core dump  file  (coredump) and  files with  system package  list,  ifconfig output, 

df/fd output,  the command  line used  to  launch  the application and much more.  In addition, 

such compressed format saves disk space and speeds up information recording. 

The debug  information  from the example code  is available  in the core dump due to the “‐g” 

option  used  to  compile  it  (automatically  added when  *.pro  file  is modified  by  adding  line 

CONFIG  += debug), however,  as  the  application  is dynamically  linked  against other  libraries 

(e.g. libc6, libqt4), if you want to be able to resolve symbols also for these library, it is needed 

to  install the package containing debug symbols of such  library. For example, for Qt  libraries, 

you have to  install  libqt4‐dbg package  in order to resolve Qt debug symbols. The debug‐dep‐

install utility described in this section provides an easy way to install the debug packages for all 

libraries the application depends. 

The  gdbexample  is  linked  against  libc,  glib  and qt  libraries. We need  to  install  them  to  get 

debug symbols for these libraries: 

Nokia-N810:~# apt-get install libc6-dbg libglib2.0-0-dbg libqt4-dbg

Now,  you  can  start  to debug  the  application using  the  core dump  file. You need both  core 

dump  and  gdbexample  binary  previously  compiled  with  debug  option  (‐g).  Execute  the 

following command  in order  to  launch GDB  (gdbexample binary as  first parameter and core 

dump file as the second parameter: 

Nokia-N810:~# gdb ./gdbbuggyexample /media/mmc1/core-dumps/coredir/coredump

GNU gdb 6.8-debian

Copyright (C) 2008 Free Software Foundation, Inc.

License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software: you are free to change and redistribute it.

There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details.

This GDB was configured as "arm-linux-gnueabi"...

Reading symbols from /usr/lib/libQtGui.so.4...done.

Loaded symbols for /usr/lib/libQtGui.so.4

Reading symbols from /usr/lib/libQtCore.so.4...done.

Maemo for Mobile Developers 

Page 142: Qt for Maemo Developers Guide v0 5 Beta

Core was generated by `./gdbbuggyexample'.

Program terminated with signal 11, Segmentation fault.

[New process 3068]

#0 0x40db99ec in memcpy () from /lib/libc.so.6 (gdb)

You need now to find out what function caused the crash. The backtrace command will show 

the functions invoked during the application execution: 

(gdb) backtrace

#0 0x40db99ec in memcpy () from /lib/libc.so.6

#1 0x0000a120 in MyButton::crashApplication (this=0x110ee8) at gdb_qt_example.cpp:10

#2 0x0000a2a0 in MyButton::printMessage (this=0x110ee8) at gdb_qt_example.cpp:17

#3 0x0000a2f4 in MyButton::printAndQuit (this=0x110ee8) at gdb_qt_example.cpp:25

#4 0x0000ac70 in MyButton::qt_metacall (this=0x110ee8, _c=QMetaObject::InvokeMetaMethod, _id=0, _a=0xbed59930) at moc_gdb_qt_example.cpp:66

#5 0x40bd3b2c in QMetaObject::activate () from /usr/lib/libQtCore.so.4

#6 0x408c0e28 in QAbstractButton::clicked () from /usr/lib/libQtGui.so.4

#7 0x405dcc10 in QAbstractButtonPrivate::emitClicked () from /usr/lib/libQtGui.so.4

#8 0x405dd5bc in QAbstractButtonPrivate::click () from /usr/lib/libQtGui.so.4

#9 0x405dd778 in QAbstractButton::mouseReleaseEvent () from /usr/lib/libQtGui.so.4

#10 0x4025df48 in QWidget::event () from /usr/lib/libQtGui.so.4

#11 0x405dcbd8 in QAbstractButton::event () from /usr/lib/libQtGui.so.4

#12 0x4068d778 in QPushButton::event () from /usr/lib/libQtGui.so.4

#13 0x402059e8 in QApplicationPrivate::notify_helper () from /usr/lib/libQtGui.so.4

#14 0x402072d8 in QApplication::notify () from /usr/lib/libQtGui.so.4

Maemo for Mobile Developers 

Page 143: Qt for Maemo Developers Guide v0 5 Beta

#15 0x40bbddc0 in QCoreApplication::notifyInternal () from /usr/lib/libQtCore.so.4

#16 0x40206660 in QApplicationPrivate::sendMouseEvent () from /usr/lib/libQtGui.so.4

#17 0x4027f38c in QETWidget::translateMouseEvent () from /usr/lib/libQtGui.so.4

#18 0x4027dd10 in QApplication::x11ProcessEvent () from /usr/lib/libQtGui.so.4

#19 0x402a50d0 in ?? () from /usr/lib/libQtGui.so.4

#20 0x0000a634 in main (argc=1, argv=0xbe8486c4) at gdb_qt_example.cpp:37

1.2.5 Sp­error­visualizer 

sp‐error‐visualizer is a small utility that's designed to help you in noticing errors that are 

written to syslog. 

To install it, run the command: 

#apt-get install sp-error-visualizer

Just install the sp‐error‐visualizer package and it will immediately start tracking syslogged messages. It's also started automatically on bootup. If syslog is not running, it provides itself the syslog socket for the applications. 

The error visualizer can be disabled by running the following command or uninstalling the package. 

$ /etc/init.d/sp-error-visualizer stop

1.2.6 Syslog 

The syslogd daemon is responsible for providing logging of messages received from programs and facilities on the local host as well as from remote hosts. 

The klogd daemon listens to kernel message sources and is responsible for prioritizing and processing operating system messages. The klogd daemon can run as a client of syslogd or optionally as a standalone program. 

To install sysklogd run the command: 

#apt-get install sysklogd

To start the sysklogd daemon: 

$ /etc/init.d/sysklogd start

Maemo for Mobile Developers 

Page 144: Qt for Maemo Developers Guide v0 5 Beta

2 Profiling On Maemo development, it is important to assure that your application does not demand a lot 

of system resources, for example memory consumption and processing. An application that 

demands a considerable amount of memory, certainly impacts directly on Internet Tablet 

performance as well. 

Thus, it is necessary to inspect how much of system resources the application is demanding. 

Profilling allows extracting information about application execution and it generates a lot of 

interesting information, such as system resources and potencial bugs related to memory 

management, for example.  

In this section, we will get into details of the following profilling tools: 

Valgrind 

OProfile 

Strace 

Ltrace 

These applications can be installed from Tools repository, as described on Section 1. 

2.1 Valgrind On  C/C++  development,  applications  commonly  use memory management  operations.  The 

developer has to handle carefully the dynamically allocated memory in order to avoid memory 

leaks,  invalid  assign  operations,  cyclic  references,  undefined  pointers  operations  and much 

more.  The  Valgrind  tool  can  be  used  to  debug  memory  operations  to  find  this  kind  of 

problems. 

Valgrind  is  a  suite  of  debugging  and  profiling  tools  for  Linux  applications.  It  has  tools  for 

memory debugging, memory leak detection, and profiling. Originally designed to be a powerful 

memory debugging  tool, Valgrind has evolved and  it  is now a generic  framework  to develop 

tools  for debugging  and profiling  Linux  applications.Valgrind  simulates X86 processor  and  it 

instruments binary code on the fly. Then, it directly impacts on application performance by 10‐

300 times slower than usual scenario, depending on the used Valgrind tool.  

It  runs  on  X86/Linux,  AMD64/Linux,  PPC32/Linux  and  PPC64/Linux  platforms,  but  not  on 

ARM/Linux platform. Therefore, it is not possible to run Valgrind on scratchbox ARMEL target 

or on  Internet Tablet. Considering Maemo development environment, Valgrind  can be used 

only on X86 targets.  

Valgrind have some tools available to help debugging. Some of them are described here: 

massif: Run‐time memory usage graph and hyperlinked allocation backtraces; 

memcheck: This tool detects memory access errors and memory  leaks.  It reports  less 

false positives than any other tool and can call GDB when the error happens; 

cachegrind: A performance profiler which can be started and stopped at any moment 

and the results can be sorted according to instructions, cache hits etc; 

callgrind:  AsCachegrind,  but  stores  also  callgraph  information  (but  can  show  only 

instruction counts); 

Maemo for Mobile Developers 

Page 145: Qt for Maemo Developers Guide v0 5 Beta

helgrind: This tool detects race conditions when threaded programs access global data. 

To install Valgrind on Scratchbox, run de command: 

[sbox-FREMANTLE_X86: ~] > apt-get install valgrind

Valgrind package install all necessary dependencies, including libc6‐dbg. Most of dependencies 

are  packages  with  symbols,  so  Valgrind  can  match  suppressions  to  the  internal  library 

functions. 

An example of Maemo C application  is used to demonstrate the basic usage of Valgrind tool. 

The following example allocates two pointers, but only one is deallocated (ptra) and memory is 

lost (memory leak). In addition, file descriptor fp is opened (line #23), but it is not closed. Also, 

remember that file descriptor fd is also a pointer and it should be deallocated. 

01 #include <stdio.h> 02 #include <malloc.h> 03 04 int main() { 05 FILE* fp; 06 char *ptra, *ptrb; 07 // First allocation: 50 bytes 08 if ((ptra= (char *) malloc(50)) == NULL) { 09 perror("malloc failed for 50 bytes."); 10 exit(-1); 11 } 12 13 // Second allocation: 100 bytes 14 if ((ptrb= (char *) malloc(100)) == NULL) { 15 perror("malloc failed for 100 bytes."); 16 exit(-1); 17 } 18 19 // 100 bytes allocated above are cleaned. 20 free(ptra); 21 22 // the following file descriptor is not closed 23 fp=fopen("/tmp/tempfile.txt","a"); 24 25 return 0; 26 }

Create a directory to save example: 

[sbox-FREMANTLE_X86: ~] >mkdir valgrind_example [sbox-FREMANTLE_X86: ~] >cd valgrind_example

Compile the example: 

[sbox-FREMANTLE_X86: ~/valgrind_example] >gcc–g valgrind_example.c \ -o valgrind_example

Maemo for Mobile Developers 

Page 146: Qt for Maemo Developers Guide v0 5 Beta

After compiling the small example application, it can be run under Valgrind. The basic usage of 

Valgrind is: 

valgrind [options] prog-and-args

Run Valgrindwith some arguments and example application with the command: 

[sbox-FREMANTLE_X86: ~/valgrind_example] >valgrind --tool=memcheck \ --leak-check=full --show-reachable=yes --num-callers=20 \ --track-fds=yes ./valgrind_example

Explanation of the parameters and their meanings:  

‐‐tool=memcheck 

o Defines which tool Valgrind should use.  In this example, the memory checker 

tool  (memcheck)  is used, but you can use one of  the  tools described above. 

Default option is memcheck. 

‐‐leak‐check=full 

o Searchs for potential memory  leaks at exit. Possible options are no, summary 

or  full.  In order  to  see  full  report about memory  leak,  full option  should be 

used. Default option is summary. 

‐‐show‐reachable=yes  

o Shows stack trace of reachable blocks that contain memory leak errors. Default 

option is no. 

‐‐num‐callers=20  

o Defines  the  number  of  function  call  levels  that  Valgrind  displays. More  the 

value is increased, more memory Valgrind demands. Default value is 12. 

‐‐track‐fds=yes  

o Report status of file descriptors. If application opens files with fopen()oropen() 

but do not close them properly, Valgrind reports the problems. Default option 

is no. 

Based on the following example, Valgrind  is supposed to detect a memory  leak generated by 

ptrb pointer lost and also open file descriptors detected at program exit. 

Here you can see a piece of the output generated by Valgrind tool for the example above: 

==8829== Memcheck, a memory error detector.

==8829== Copyright (C) 2002-2008, and GNU GPL'd, by Julian Seward et al.

Maemo for Mobile Developers 

Page 147: Qt for Maemo Developers Guide v0 5 Beta

==8829== Using LibVEX rev 1884, a library for dynamic binary translation.

==8829== Copyright (C) 2004-2008, and GNU GPL'd, by OpenWorks LLP.

==8829== Using valgrind-3.4.1-maemo, a dynamic binary instrumentation framework.

==8829== Copyright (C) 2000-2008, and GNU GPL'd, by Julian Seward et al.

==8829== For more details, rerun with: -v

==8829==

==8829==

==8829== FILE DESCRIPTORS: 4 open at exit.

==8829== Open file descriptor 3: /tmp/testfile.txt

==8829== at 0x40CF14E: __open_nocancel (in /targets/FREMANTLE_X86/lib/libc-2.5.so)

==8829== by 0x40829D1: _IO_file_fopen@@GLIBC_2.1 (in /targets/FREMANTLE_X86/lib/libc-2.5.so)

==8829== by 0x40786C6: __fopen_internal (in /targets/FREMANTLE_X86/lib/libc-2.5.so)

==8829== by 0x407871E: fopen@@GLIBC_2.1 (in /targets/FREMANTLE_X86/lib/libc-2.5.so)

==8829== by 0x80484C8: main (valgrind_example.c:25)

==8829==

==8829== Open file descriptor 2: /dev/pts/0

==8829== <inherited from parent>

==8829==

==8829== Open file descriptor 1: /dev/pts/0

==8829== <inherited from parent>

==8829==

==8829== Open file descriptor 0: /dev/pts/0

==8829== <inherited from parent>

==8829==

==8829==

==8829== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 13 from 1)

Maemo for Mobile Developers 

Page 148: Qt for Maemo Developers Guide v0 5 Beta

==8829== malloc/free: in use at exit: 402 bytes in 2 blocks.

==8829== malloc/free: 3 allocs, 1 frees, 502 bytes allocated.

==8829== For counts of detected errors, rerun with: -v

==8829== searching for pointers to 2 not-freed blocks.

==8829== checked 56,280 bytes.

==8829==

==8829== 50 bytes in 1 blocks are definitely lost in loss record 1 of 2

==8829== at 0x4020C19: malloc (in /targets/FREMANTLE_X86/usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)

==8829== by 0x8048452: main (valgrind_example.c:10)

==8829==

==8829==

==8829== 352 bytes in 1 blocks are still reachable in loss record 2 of 2

==8829== at 0x4020C19: malloc (in /targets/FREMANTLE_X86/usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)

==8829== by 0x407867A: __fopen_internal (in /targets/FREMANTLE_X86/lib/libc-2.5.so)

==8829== by 0x407871E: fopen@@GLIBC_2.1 (in /targets/FREMANTLE_X86/lib/libc-2.5.so)

==8829== by 0x80484C8: main (valgrind_example.c:25)

==8829==

==8829== LEAK SUMMARY:

==8829== definitely lost: 50 bytes in 1 blocks.

==8829== possibly lost: 0 bytes in 0 blocks.

==8829== still reachable: 352 bytes in 1 blocks.

==8829== suppressed: 0 bytes in 0 blocks.

The Valgrind output  shows  that  there  are  some open  file descriptors  at program  exit. As  a 

good programming practice,  file descriptors  (and other  resources) should be properly closed 

before quit  from  application.  In  this  case,  there  are 4 open  file descriptors:  the  first one  is 

related  to  /tmp/testfile.txt  file  (line  #25);  the  last  3  file  descriptors  are  related  to  file 

/dev/pts/0 and they are closed by operating system. 

Maemo for Mobile Developers 

Page 149: Qt for Maemo Developers Guide v0 5 Beta

In addition, Valgrind output reports 402 unallocated bytes in 2 different blocks: the first block 

is ptrb pointer allocation (line #10) and the second one is fd pointer allocation (line #25). Thus, 

the  following  scenario  clearly  defines  a memory  leak  on  the  application  and  it  should  be 

avoided. Then, programmer should review the code and free properly allocated pointers.  

It is possible to use the same example on more Valgrind tools, such as cachegrind and massif. 

For more information about Valgrind, including its profiling and debugging tools, see Valgrind 

User Manual. 

2.2 OProfile Today,  even with  advances  on  hardware  for mobile  devices,  including  the  Internet  Tablet, 

programmers  often  deal  with  system  resources  constraints,  such  as  memory  and  CPU 

processing. Although in some cases the device CPU speed is enough for the application, using 

fewer resources will save device battery. These restrictions impact directly on how developers 

do their  jobs: the code cannot demand too much memory or CPU processing. Thus, even  if a 

certain Maemo application under development is considered bug‐free, it is necessary to check 

if it is consuming a considerable amount of system resources. 

It is important to check where application´s bottlenecks are: hardware and software interrupt 

handlers,  kernel  modules,  the  kernel,  shared  libraries  or  applications.  The  Maemo 

development environment provides OProfile, a well known profiling tool for systems running 

Linux 2.2, 2.4, and 2.6 kernels. OProfile runs transparently in the background and profile data 

can be collected at any time. It can be used to find CPU usage bottlenecks in the whole system 

and within processes. 

2.2.1 Installing OProfile on Scratchbox OProfile can be installed on both Maemo rootstraps: X86 and ARMEL. OProfile is available on 

Maemo Tools repository. Then,  if Maemo Tools repository  is not properly configured on your 

environment, edit file /etc/apt/sources.list and add the following line: 

deb http://repository.maemo.org/ fremantle/tools free non-free

Once Maemo Tools repository was added as a valid repository,  it  is necessary  to update  the 

packages list. Execute the following command as root to refresh the package: 

[sbox-FREMANTLE_X86: ~] > fakeroot apt-get update

To install OProfile on Scratchbox, execute the following command: 

[sbox-FREMANTLE_X86: ~] > fakeroot apt-get install oprofile

2.2.2 Installing OProfile on Internet Tablet At first,  install OProfile  in device. Do not forget to configure Maemo Tools repository and get 

connected with device through a SSH section as described on section 2.2.1. 

Nokia-N810:~# apt-get install oprofile

In order to run OProfile on Internet Tablet, it is necessary to update the system kernel so it is 

possible to catch required system events used by OProfile, such as signals and interruptions. A 

Maemo for Mobile Developers 

Page 150: Qt for Maemo Developers Guide v0 5 Beta

pre‐compiled kernel with OProfile support is provided by kernel‐oprofile package and it can be 

downloaded from the Fremantle tools repository in Scratchbox environment: 

[sbox-FREMANTLE_ARMEL: ~] > fakeroot apt-get install kernel-oprofile

Package kernel‐oprofile installs the kernel image suitable for OProfile into /boot/ directory. 

[sbox-FREMANTLE_ARMEL: ~] >ls -l /boot

lrwxrwxrwx 1 root root 19 Sep 26 23:43 XXX

Once oprofile‐enabled kernel is saved, it is possible to flash Internet Tablet so OProfile can be 

used  on  device.  However,  it  is  necessary  to  copy  oprofile‐enabled  kernel  image  to  outer 

environment (host Desktop system) so flasher tool can be used to flash Internet Tablet. 

Remember that Scratchbox  is under Desktop environment, so the contents of Scratchbox file 

system can be easily accessed by Desktop user.  

Now, copy the kernel image to the /tmp directory using the following command: 

[sbox-FREMANTLE_ARMEL: ~] >cp /boot/XXX/tmp

Flasher tool  is required to flash kernel  image  into Internet Tablet. Visit flasher tool download 

page (http://tablets‐dev.nokia.com/d3.php) and download the newest version of flasher tool. 

In this tutorial, flasher‐3.0 is being used. 

Once  flasher  tool  is available,  it  is necessary  to change  its permissions  so  flasher‐3.0 can be 

executed.  Go  to  the  directory  where  flasher‐3.0  was  previously  saved  and  execute  the 

following command: 

maemo@maemo-desktop:~$ chmod +x flasher-3.0

For  more  information  about  flasher  tool,  see  visit  flasher  tool  page 

(https://wiki.maemo.org/Flasher). 

Once kernel oprofile‐enabled and flasher tool are available,  it  is possible to flash the Internet 

Tablet. 

2.2.2.1 Flashing the kernel This approach flashes the device, so the current kernel is replaced by oprofile‐enabled kernel. 

To  flash  the  new  kernel  image,  use  the  linux  flasher  utility with  options  –f  (flash)  and  –R 

(reboot): 

maemo@maemo-desktop:~$ sudo./flasher-3.0 -f --kernel /tmp/XXX-R

This operation does not destroy existing data in the device. However, it is suggested to backup 

Internet Tablet data before  flashing  the device. Once  flasher  tool has  finished,  the device  is 

ready for OProfile. 

Maemo for Mobile Developers 

Page 151: Qt for Maemo Developers Guide v0 5 Beta

Once there is nothing more to do with OProfile, the user can restore the normal kernel. In such 

case,  since  the  system kernel was  replaced by oprofile‐enabled kernel,  it  is necessary  to  re‐

flash the device with other kernel using the following command: 

maemo@maemo-desktop:~$ flasher -f --flash-only kernel -F \ <image> -R

# The FIASCO image is the whole product image with a name like:

# RX-44_DIABLO_3.2008.17-8_PR_COMBINED_MR0_ARM.bin

As suggested before, re‐flashing  the kernel does not destroy any of  the other parts, but  it  is 

safe to backup Internet Tablet data before flashing the device. 

2.2.2.2 Boot with the new kernel This approach only boots  the device with oprofile‐enabled kernel. Thus,  if  Internet Tablet  is 

turned off, the normal kernel is restored. 

maemo@maemo‐desktop:~$ sudo./flasher‐3.0 ‐‐load ‐‐boot ‐‐kernel /tmp/X 

2.2.3 Using OProfile The  following  instructions  can  be  executed  on  both  Scratchbox  and  Internet  Tablet, 

considering  that  OProfile  is  properly  installed  and  configured  on  them.  In  addition,  the 

instructions must be executed as root. 

If OProfile  is executed on  Internet Tablet,  remember  that  it  is necessary  to establish  a  SSH 

section with device in order to make things easier. Thus, get connected with Internet Tablet as 

described before. In this tutorial, commands are executed on Internet Tablet.  

To start with, it is necessary to init opcontrol, which controls OProfile execution and manages 

data collection. The following commands are used to load modules and other essential files to 

OProfile (‐‐init option),  indicate that there  is no kernel  image available  (‐‐no‐vmlinux option) 

so  kernel  events  are  not  supposed  to  be  hold,  and  the  number  of  CPU  cycles  between 

interrupts  (‐e  option).  It  is  possible  to  use  other  system  events  (CPU_CLK_UNHALTED  or 

RTC_INTERRUPTS) to define interrupts.  

Nokia-N810:~# opcontrol --init

Nokia-N810:~# opcontrol --no-vmlinux

Nokia-N810:~# opcontrol -e=CPU_CYCLES:100000

For  more  information  about  opcontrol,  visit  OProfile  User  Documentation 

(http://oprofile.sourceforge.net/doc/index.html).  

Now, OProfile data collection can be started: 

Nokia-N810:~# opcontrol–start

Using 2.6+ OProfile kernel interface.

Using log file /var/lib/oprofile/samples/oprofiled.log

Maemo for Mobile Developers 

Page 152: Qt for Maemo Developers Guide v0 5 Beta

Daemon started.

Profiler running.

OProfile collects all necessary information to generate reports. Once data collection has been 

started,  the  application  to  analyze  can  be  launched.  Data  about  the  current  application 

execution is collected as well. 

To  collect  information  about  Qt  libraries  and  symbols,  it  is  suggested  to  execute  the 

gdb_example  application:  a  simple Qt  application with  a  push  button. When  the  button  is 

pressed, the application is finalized. 

Considering that the application is finalized, opcontrol data collection can be stopped: 

Nokia-N810:~# opcontrol--stop

Stopping profiling.

It is possible to reset data just collected and restart the process: 

Nokia-N810:~# opcontrol --reset

Nokia-N810:~# opcontrol --init

Once some data has been collected,  it can be processed. OProfile provides different tools to 

process dump files and show human‐readable information: opreport, opannotate, or opgprof.  

opreport  utility  generates  two  types  of  data:  image  summaries  and  symbol  summaries. An 

image  summary  shows  statistics  about  individual  binary  images  such  as  libraries  or 

applications, and symbol summary provides per‐symbol profile data.  

These numbers are very  important  to  inspect where application bottlenecks are  located and 

how  it  is  possible  to  speed  up  application  execution.  For  example,  if  a  certain  application 

spends more than 50% of its execution time on a single function, the programmer has to check 

why  it  takes  too much  time and how  it  is possible  to modify  the algorithm  in order  to  save 

time. The following example shows information about image and symbol symmaries collected 

by OProfile: 

Nokia-N810:~# opreport

CPU: ARM V6 PMU, speed 0 MHz (estimated)

Counted CPU_CYCLES events (clock cycles counter) with a unit mask of 0x00 (No unit mask) count 100000

CPU_CYCLES:100000|

samples| %|

------------------

7788 43.7848 no-vmlinux

2000 11.2442 ld-2.5.so

Maemo for Mobile Developers 

Page 153: Qt for Maemo Developers Guide v0 5 Beta

1552 8.7255 libc-2.5.so

1070 6.0156 libglib-2.0.so.0.1200.12

906 5.0936 libgobject-2.0.so.0.1200.12

608 3.4182 Xomap

485 2.7267 libQtGui.so.4.5.2

428 2.4063 libgtk-x11-2.0.so.0.1000.12

424 2.3838 oprofiled

397 2.2320 libgcc_s.so.1

381 2.1420 libpthread-2.5.so

327 1.8384 libQtCore.so.4.5.2

252 1.4168 libgdk-x11-2.0.so.0.1000.12

238 1.3381 busybox

151 0.8489 libX11.so.6.2.0

121 0.6803 libmb.so.1.0.9

86 0.4835 libfontconfig.so.1.1.0

70 0.3935 libfreetype.so.6.3.16

60 0.3373 libz.so.1.2.3

50 0.2811 esd

42 0.2361 libgthread-2.0.so.0.1200.12

42 0.2361 libpango-1.0.so.0.1600.4

38 0.2136 libsapwood.so

35 0.1968 libexpat.so.1.0.0

30 0.1687 libpng12.so.0.1.2.8

25 0.1406 libgdk_pixbuf-2.0.so.0.1000.12

15 0.0843 libhildondesktop.so.0.0.0

14 0.0787 UTF-16.so

13 0.0731 libcairo.so.2.11.5

13 0.0731 libstdc++.so.6.0.3

... snip ...

To see more detailed symbol analysis use opreport ‐l: 

Maemo for Mobile Developers 

Page 154: Qt for Maemo Developers Guide v0 5 Beta

Nokia-N810:~# opreport -l|more

warning: /no-vmlinux could not be found.

BFD: /usr/lib/debug/lib/ld-2.5.so: warning: sh_link not set for section `.ARM.exidx'

BFD: /usr/lib/debug/lib/libc-2.5.so: warning: sh_link not set for section `.ARM.exidx'

CPU: ARM11 PMU, speed 0 MHz (estimated)

Counted CPU_CYCLES events (clock cycles counter) with a unit mask of 0x00 (No unit mask) count 100000

7788 43.7848 no-vmlinux /no-vmlinux

609 3.4238 ld-2.5.so do_lookup_x

608 3.4182 Xomap /usr/bin/Xomap

485 2.7267 libQtGui.so.4.5.2 /usr/lib/libQtGui.so.4.5.2

428 2.4063 libgtk-x11-2.0.so.0.1000.12 /usr/lib/libgtk-x11-2.0.so.0.1000.12

424 2.3838 oprofiled /usr/bin/oprofiled

397 2.2320 libgcc_s.so.1 /lib/libgcc_s.so.1

327 1.8384 libQtCore.so.4.5.2 /usr/lib/libQtCore.so.4.5.2

267 1.5011 ld-2.5.so check_match.0

259 1.4561 ld-2.5.so strcmp

252 1.4168 libgdk-x11-2.0.so.0.1000.12 /usr/lib/libgdk-x11-2.0.so.0.1000.12

238 1.3381 busybox /bin/busybox

185 1.0401 libc-2.5.so memcpy

179 1.0064 libc-2.5.so _int_malloc

151 0.8489 ld-2.5.so _dl_relocate_object

151 0.8489 libX11.so.6.2.0 /usr/lib/libX11.so.6.2.0

133 0.7477 ld-2.5.so _dl_map_object

126 0.7084 libpthread-2.5.so pthread_mutex_lock

121 0.6803 libmb.so.1.0.9 /usr/lib/libmb.so.1.0.9

112 0.6297 libgobject-2.0.so.0.1200.12 g_type_check_instance_is_a

110 0.6184 libc-2.5.so strcmp

Maemo for Mobile Developers 

Page 155: Qt for Maemo Developers Guide v0 5 Beta

108 0.6072 libglib-2.0.so.0.1200.12 g_hash_table_lookup

100 0.5622 libc-2.5.so malloc

96 0.5397 libc-2.5.so strchr

86 0.4835 libfontconfig.so.1.1.0 /usr/lib/libfontconfig.so.1.1.0

86 0.4835 libpthread-2.5.so pthread_getspecific

82 0.4610 ld-2.5.so dl_new_hash

80 0.4498 ld-2.5.so __udivsi3

80 0.4498 libglib-2.0.so.0.1200.12 g_slice_alloc

… snip …

opannotate  is used to generate annotated source code.  It  is possible to show assembly code 

mixed  with  source  code,  including  the  number  of  samples  for  each  line.  In  order  to  use 

opannotate,  the application must have debug  information, and the source must be available 

through this debug information. 

opgprof generates reports on GNU‐gprof format, so you can use the output on many gprof UI 

analyzers. 

2.2.4 OProfile with callgraph OProfile is commonly used on basic mode to collect statistics about a certain application and it 

is  possible  to  obtain  interesting  information  about  your  application  by  using  utility  tools 

(opreport, opannotate, opgprof). However, more sophisticated information can be obtained by 

using OProfile together with callgraphs, which show relationships between callers and callees. 

To use  callgraphs,  it  is  required  to  recompile all  the  code  (binaries,  libraries) of application. 

Before recompiling the code, it is necessary to change compiling options by adding ‐fno‐omit‐

frame‐pointer to GCC options  (for more  information about Scratchbox environment variable, 

see /scratchbox/doc/variables.txt file): 

Nokia-N810:~# export SBOX_BLOCK_COMPILER_ARGS="-fomit-frame-pointer"

Nokia-N810:~# export SBOX_EXTRA_COMPILER_ARGS="-fno-omit-frame-pointer"

Once  the  code  is  properly  recompiled,  copy  the  result  to  device  by  using  SCP,  just  like 

described in this section. 

Init  oprofileand  enablecallgraph  sample  collection  (‐c  option) with  an  integer  as  argument 

which represents the maximum depth: 

Nokia-N810:~# opcontrol --init

Nokia-N810:~# opcontrol --no-vmlinux

Maemo for Mobile Developers 

Page 156: Qt for Maemo Developers Guide v0 5 Beta

Nokia-N810:~# opcontrol -e=CPU_CYCLES:100000 –c 20

Run the opreport command with ‐c option: 

Nokia-N810:~# opreport -l -c

The output is as follows:

CPU: ARM V6 PMU, speed 0 MHz (estimated) Counted CPU_CYCLES events (clock cycles counter) with a unit mask of 0x00 (No unit mask) count 1000000

BFD: /usr/lib/debug/lib/ld-2.5.so: warning: sh_link not set for section `.ARM.exidx'

BFD: /usr/lib/debug/lib/libc-2.5.so: warning: sh_link not set for section `.ARM.exidx'

samples % app name symbol name ---------------------------------------------------------------------- 141 55.5118 no-vmlinux /no-vmlinux 141 100.000 no-vmlinux /no-vmlinux [self] ---------------------------------------------------------------------- 20 7.8740 busybox /bin/busybox 20 100.000 busybox /bin/busybox [self] ---------------------------------------------------------------------- 13 5.1181 libgobject-2.0.so.0.1200.12 /usr/lib/libgobject-2.0.so.0.1200.12 13 100.000 libgobject-2.0.so.0.1200.12 /usr/lib/libgobject-2.0.so.0.1200.12 [self] ---------------------------------------------------------------------- 6 2.3622 libc-2.5.so strchr 6 100.000 libc-2.5.so strchr [self] ---------------------------------------------------------------------- 6 2.3622 libgtk-x11-2.0.so.0.1000.12 /usr/lib/libgtk-x11-2.0.so.0.1000.12 6 100.000 libgtk-x11-2.0.so.0.1000.12 /usr/lib/libgtk-x11-2.0.so.0.1000.12 [self] ---------------------------------------------------------------------- 5 1.9685 Xomap /usr/bin/Xomap 5 100.000 Xomap /usr/bin/Xomap [self] ---------------------------------------------------------------------- 4 1.5748 ld-2.5.so _dl_relocate_object 4 100.000 ld-2.5.so _dl_relocate_object [self] ---------------------------------------------------------------------- 4 1.5748 ld-2.5.so check_match.0 4 100.000 ld-2.5.so check_match.0 [self] ---------------------------------------------------------------------- 4 1.5748 ld-2.5.so do_lookup_x 4 100.000 ld-2.5.so do_lookup_x [self] ---------------------------------------------------------------------]

Maemo for Mobile Developers 

Page 157: Qt for Maemo Developers Guide v0 5 Beta

OProfile  report  represents  calling  relationships  between  subroutines  of  the  same 

application/library. The output shows the nodes of callgraph: for example, on library ld‐2.5.so, 

functions do_lookup_x, check_match.0 and __dl_relocate_object are  invoked during OProfile 

data collection. 

2.2.5 oprofileui oprofileui is a graphical user interface to the oprofile system profiler. At first, it is necessary to 

establish a SSH section to the device as root and install oprofileui‐viewer and oprofileui‐server 

packages: 

Nokia-N810:~# apt-get install oprofileui-viewer oprofileui-server

… snip …

To  see  callgraphs, do not  forget  to  compile  the  target binaries with  frame pointers enabled 

(GCC ‐fno‐omit‐frame‐pointer option) just like described in the section OProfile with callgraph. 

Reset opcontrol to clear old dump and start oprofile‐server in the device: 

Nokia-N810:~# opcontrol --reset

Nokia-N810:~# oprofile-server&

Start oprofile‐viewer in the device: 

Nokia-N810:~# oprofile-viewer

A graphical user interface for OProfile will appear on Internet Tablet screen: 

 

Press “Connect”button on toolbar: 

Maemo for Mobile Developers 

Page 158: Qt for Maemo Developers Guide v0 5 Beta

 

Select “This Computer” and click “Connect” button. 

Click “Start” button and then click “Stop” button.  

oprofileui lists the report as list on main window: 

 

Note  that  oprofileui  components  are  also  visible  at  OProfile  report,  since  it  collects  all 

symbols/functions invoked during data collection. 

2.3 Strace Maemo applications certainly do a lot of system calls, such as I/O and memory operations. In 

some  situations  it might be needed  to monitor what  system calls are been executed by  the 

application,  for  example  to  look  for  a  crash  related  to  the  interaction  with  system  or  to 

optimize  some  peace  of  the  code  that  is  executing  system  calls  too  often,  like  heavy  file 

opening and closing. 

Strace  is  a debugging  tool  that monitors  all  system  calls used by  a process  and  also  all  the 

signal it receives. Strace is really simple to use: the application under analysis does not need to 

have debugging  symbols available.  In addition,  strace can be attached  to a  running process, 

and retrieve information about the system calls used by it. 

Maemo for Mobile Developers 

Page 159: Qt for Maemo Developers Guide v0 5 Beta

Strace can be  installed on both Scratchbox and Internet Tablet environments. On Scratchbox, 

strace  is  already  installed  by  default.  If  strace  is  supposed  to  be  used  on  Scratchbox,  it  is 

suggested that strace be used  in an X86 target rather than  in an ARMEL target:  in an ARMEL 

target strace will actually trace the system calls of the QEMU process. 

Strace is available at Maemo Tools repository. Then, if Maemo Tools repository is not properly 

configured on your environment, edit file /etc/apt/sources.list and add the following line: 

deb http://repository.maemo.org/ fremantle/tools free non-free

Once Maemo Tools repository was added as a valid repository,  it  is necessary  to update  the 

packages list. Execute the following command as root to refresh the package: 

Nokia-N810:~# apt-get update

On Internet Tablets, you need to install strace by using the following command: 

Nokia-N810:~# apt-get install strace

… snip …

The usage of strace is very simple like in the command below: 

Nokia-N810:~# strace program

Strace also can be attached to a running process. To do this run the command: 

Nokia-N810:~# strace -p PID

Here, PID is the process identification number.You can find the process PID with ps command. 

For  more  information  about  strace,  visit  the  Strace  manual  page 

(http://maemo.org/development/documentation/man_pages/strace/). 

In  this  tutorial,  a  very  simple  Qt  example  is  used  to  demonstrate  the  strace  tool 

(strace_example.cpp). The application just opens a Qt application with a “Hello World” label. 

01 #include <QApplication>

02 #include <QLabel>

03

04 int main(intargc, char* argv[]) {

05 QApplicationapp(argc,argv);

06 QLabel *label = new QLabel("Hello World!");

07 label->show();

08 return app.exec();

09 }

Maemo for Mobile Developers 

Page 160: Qt for Maemo Developers Guide v0 5 Beta

Compile the application on ARMEL roostrap: 

[sbox-FREMANTLE_ARMEL: ~] >qmake –project

[sbox-FREMANTLE_ARMEL: ~] >qmake

.. snip …

Copy the application to device using SCP (see Section 6,"Test the application on a device" in 

Chapter 2.). Now, run strace with strace_example as parameter: 

Nokia-N810:~# strace ./strace_example

execve("./strace_example", ["./strace_example"], [/* 59 vars */]) = 0

brk(0) = 0x11000

uname({sys="Linux", node="Nokia-N810", ...}) = 0

mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x4001b000

access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)

open("/etc/ld.so.cache", O_RDONLY) = 3

fstat64(3, {st_mode=S_IFREG|0644, st_size=26046, ...}) = 0

mmap2(NULL, 26046, PROT_READ, MAP_PRIVATE, 3, 0) = 0x40024000

close(3) = 0

open("/usr/lib/libQtGui.so.4", O_RDONLY) = 3

read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0\320\25\35\0004\0\0\0t"..., 512) = 512

fstat64(3, {st_mode=S_IFREG|0644, st_size=10445228, ...}) = 0

mmap2(NULL, 10485276, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x4002c000

mprotect(0x409f9000, 28672, PROT_NONE) = 0

mmap2(0x40a00000, 172032, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x9cc) = 0x40a00000

mmap2(0x40a2a000, 7708, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x40a2a000

close(3) = 0

… snip …

write(6, "@"..., 1) = 1

Maemo for Mobile Developers 

Page 161: Qt for Maemo Developers Guide v0 5 Beta

close(6) = 0

close(5) = 0

rt_sigaction(SIGCHLD, {SIG_DFL}, {0x40b94da0, [], SA_NOCLDSTOP|0x4000000}, 8) = 0

exit_group(0) = ?

 

 

Each  line  has  the  name,  parameters  and  returned  value  of  system  calls. As  the  example  is 

linked against Qt libraries. You can see in the strace output the system call to load Qt libraries. 

Basically, library loading consists of a .so file opening and the system call open is used for this 

issue.  For  example,  strace_example  loads QtGui  library  ("/usr/lib/libQtGui.so.4"),  as  a  read‐

only file (O_RDONLY), as listed on strace output:  

open("/usr/lib/libQtGui.so.4", O_RDONLY) = 3

For open  system call,  the  returned value  is  the  identifier of  file descriptor  (3). Such value  is 

used to close the file when necessary (close system call). 

 

As example of failed system call, there is the following example extracted from previous strace 

output: 

access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)

The  system  call access  checks  if  file  ld.so.preload  ("/etc/ld.so.preload") has  read permission 

(R_OK). The file does not exists and access system call returns error code (‐1). 

It  is possible  to generate a  summary with count  time, calls, and errors  for each  system call. 

Execute the strace tool with ‐c option: 

Nokia-N810:~# strace -c ./strace_example

% time seconds usecs/call calls errors syscall

------ ----------- ----------- --------- --------- ----------------

31.39 0.005429 1 6313 5 lstat64

20.98 0.003629 3 1369 901 open

15.35 0.002655 5 517 1 mmap2

10.60 0.001833 3 711 5 read

7.23 0.001250 3 387 munmap

4.94 0.000854 4 194 write

NOTE: Failed system calls usually (not always) return a return code of ‐1. 

NOTE: If you are using strace  in scratchbox with ARMEL target, the option ‐f needs to 

be given, so that the process run under the QEMU is also traced. 

Maemo for Mobile Developers 

Page 162: Qt for Maemo Developers Guide v0 5 Beta

3.17 0.000549 1 638 26 access

2.82 0.000488 1 573 readlink

2.47 0.000428 19 22 writev

1.06 0.000183 2 86 44 stat64

0.00 0.000000 0 473 close

0.00 0.000000 0 1 execve

0.00 0.000000 0 2 pipe

0.00 0.000000 0 15 brk

0.00 0.000000 0 56 ioctl

0.00 0.000000 0 4 gettimeofday

… snip …

0.00 0.000000 0 5 2 connect

0.00 0.000000 0 1 shutdown

0.00 0.000000 0 1 SYS_305

0.00 0.000000 0 1 SYS_307

------ ----------- ----------- --------- --------- ----------------

2.4 Ltrace Applications often use subroutines and symbols defined on dynamic  libraries  installed  in  the 

system. For example  the Qt  libraries: QtGui and QtCore. Maemo development environment 

provides Ltrace as a tool for monitoring dynamic libraries calls performed by a process and also 

to  trace  the  signals which are  received by  such process.  Ltrace  is very  similar  to  strace, but 

strace only intercepts and records system calls. 

Ltrace  can  be  used  on  both  Scratchbox  and  Internet  Tablet  environments.  It  is  available  at 

Maemo Tools repository. Before  installing  it, configure Maemo Tools repository as described 

on previous section about strace. In order to install ltrace, execute the following command: 

[sbox-FREMANTLE_ARMEL: ~] >apt-get install ltrace

… snip …

 

To demonstrate how  ltrace can be used, the same example of section strace  is used. At first, 

compile the application on ARMEL roostrap: 

[sbox-FREMANTLE_ARMEL: ~] >qmake –project

[sbox-FREMANTLE_ARMEL: ~] >qmake

.. snip …

Maemo for Mobile Developers 

Page 163: Qt for Maemo Developers Guide v0 5 Beta

Them, copy the executable to Internet Tablet using SCP. Now, run ltrace with strace_example 

as parameter: 

Nokia-N810:~# ltrace ./ltrace_example

__libc_start_main(35000, 1, 0xbe80c6e4, 35300, 35412 <unfinished ...>

_ZN12QApplicationC1ERiPPci(0xbe80c568, 0xbe80c554, 0xbe80c6e4, 263426, 0xbe80c590) = 0xbe80c568

_ZN7QString16fromAscii_helperEPKci(35436, -1, 0, 0x40a24ee8, 0xbe80c590) = 168952

_Znwj(20, 168994, 0, 33, 0xbe80c590) = 0x110368

_ZN6QLabelC1ERK7QStringP7QWidget6QFlagsIN2Qt10WindowTypeEE(0x110368, 0xbe80c560, 0, 0xbe80c558, 0xbe80c590) = 0x110368

_ZN12QApplication4execEv(0xbe80c4f8, 0xbe80c4f8, 4, 0x40c9e468, 0xbe80c590) = 0

_ZN12QApplicationD1Ev(0xbe80c568, 0x40e5f0ac, 0, 0, 0xbe80c590) = 0xbe80c568

+++ exited (status 0) +++

The  output  format  of  ltrace  looks  like  strace  output:  each  line  consists  of  library  function 

name, a list of parameters and the result code. 

In addition, it is possible to track system calls with ltrace as well (‐S parameter): 

Nokia-N810:~# ltrace -S ./ltrace_example

3119 SYS_brk(NULL) = 0x00011000 <0.000366>

3119 SYS_uname(0xbe83c1f0) = 0 <0.000366>

3119 SYS_mmap2(0, 4096, 3, 34, -1) = 0x4001b000 <0.000427>

3119 SYS_access("/etc/ld.so.preload", 04) = -2 <0.000397>

3119 SYS_open("/etc/ld.so.cache", 0, 01) = 3 <0.000488>

3119 SYS_fstat64(3, 0xbe83baa0, 0xbe83baa0, 0, 3) = 0 <0.000366>

3119 SYS_mmap2(0, 26046, 1, 2, 3) = 0x40024000 <0.000457>

3119 SYS_close(3 = 0 <0.000702>

3119 SYS_open("/usr/lib/libQtGui.so.4", 0, 010000433450) = 3 <0.000519>

3119 SYS_read(3, "\177ELF\001\001\001", 512) = 512 <0.000427>

3119 SYS_fstat64(3, 0xbe83bad0, 0xbe83bad0, 0, 23) = 0 <0.000397>

3119 SYS_mmap2(0, 0x9ffe1c, 5, 2050, 3) = 0x4002c000 <0.000458>

Maemo for Mobile Developers 

Page 164: Qt for Maemo Developers Guide v0 5 Beta

Maemo for Mobile Developers 

3119 SYS_mprotect(0x409f9000, 28672, 0) = 0 <0.000580>

3119 SYS_mmap2(0x40a00000, 172032, 3, 2066, 3) = 0x40a00000 <0.000732>

3119 SYS_mmap2(0x40a2a000, 7708, 3, 50, -1) = 0x40a2a000 <0.000671>

3119 SYS_close(3) = 0 <0.000366>

… snip …

ltrace outputs the process ID, name of system call, its parameters and its result code: 

3119 SYS_open("/etc/ld.so.cache", 0, 01) = 3 <0.000488>

As  strace,  ltracegenerates  a  summary  with  count  time,  calls,  and  calls  for  each  library 

invocation. Execute the ltrace tool with ‐c option: 

% time seconds usecs/call calls function

------ ----------- ----------- --------- --------------------

71.98 6.845215 6845215 1 _ZN12QApplicationC1ERiPPci

27.74 2.638214 2638214 1 _ZN12QApplication4execEv

0.24 0.022552 22552 1 _ZN12QApplicationD1Ev

0.02 0.002258 2258 1 _ZN6QLabelC1ERK7QStringP7QWidget6QFlagsIN2Qt10WindowTypeEE

0.01 0.000732 732 1 _Znwj

0.01 0.000702 702 1

_ZN7QString16fromAscii_helperEPKci

------ ----------- ----------- --------- --------------------

100.00 9.509673 6 total

For more information about ltrace, visit the Ltrace manual page 

(http://maemo.org/development/documentation/man_pages/ltrace/).