Qtopia Home - Classes - Hierachy - Annotated - Functions - Qt Embedded |

# Qtopia - Customizing Qtopia for a Device

- Introduction
- Custom Qtopia Launcher User Interface
  - Launcher
  - Other User Interface Components
- Device Hardware Factors
  - Device-Specific Code
- Non-installed Components
- Unsupported Components
- Required Plugins
- Power Management
  - Technical Details
  - For PDA Edition
  - For Phone Edition
- Removable Storage Cards
- I18N
- Access Permissions and Read-only Filesystems
- MMS Client
  - WAP Stack Integration
  - AMR Encoder
- GSM Module Integratation

## Introduction

This document sets out the implementation requirements for specific devices and makes recommendations for the optimal installation of Qtopia on a handheld device. How you install Qtopia on a given device will be determined by the functionality of that device.

See Also Qtopia - Customizing Qtopia for a Device: Keys and Buttons.

## Custom Qtopia Launcher User Interface

In some cases it is desirable to have a customized launcher interface that better suits the intended application of the target device. Qtopia supports custom laucher user interfaces via the ServerInterface. This interface provides all of the infrastructure necessary to implement a launcher while maintaining compatibility with the Qtopia application and document models.

The launcher user interface is part of the Qtopia server ($QPEDIR/src/server) which provides services such as syncing and filesystem management.

### Launcher

The first step when writing a user interface is to implement a class derived from ServerInterface. This interface provides the functionality necessary to show the available applications and documents available on a Qtopia device.

The createGUI() and destroyGUI() functions must be implemented to create and show the launcher and any other user interface components.

Most of the functions provided by the ServerInterface are to manage adding and removing applications and documents as necessary. The ServerInterface documentation describes each one in detail.

The default Qtopia launcher is implemented by the Launcher class.

### Other User Interface Components

In addition to the launcher itself, it is usually necessary to provide some system components, such as input methods and status display.

There are several classes in the default Qtopia user interface that may be reused in a custom interface. Most user interfaces will make use of some of these classes to ensure a useable system:

- InputMethods - loads and displays input methods.
- RunningAppBar - displays running application icons.
- SysTray - loads and displays applets.
- StartMenu - provides menus for launcher tabs and accessory plugins.

An interface providing these components will support most of the default Qtopia launcher functionality.

The Qtopia libraries also assume that QPE/Taskbar QCOP channel is available and supports the following functions:

- message(QString) - display a status message.
- hideInputMethod() - hide any visible input method.
- showInputMethod() - show the currently selected input method.
- showInputMethod(QString) - show the specified input method.
- reloadInputMethods() - release and reload the input method plugins.
- reloadApplets() - release and reload the applets.

The default Qtopia launcher uses the TaskBar class to encapsulate the above functionality.

## Device Hardware Factors

When planning to customize and install Qtopia on a specific device, there are a number of factors that must be taken into consideration. The following is a list of typical factors:

- If the device has a touch screen, Qtopia calibration must be enabled.
- If the device runs off batteries, Qtopia may be required to call APM functions for power saving. See the Power Management section below for more details.
- If the device has special hardware buttons, they may need to be mapped to applications and have associated images displayed in the user interface.
- If the device has a buzzer for alarms and other beeps, Qtopia will need to know how to use this hardware and enable it for the associated events.
- If the device has an LCD screen with a back or front light, Qtopia will need to know how to adjust its brightness.
- If the device has any special LEDs to indicate status to the user, Qtopia will need to know how to set the LEDs.
- If the device has or supports a camera, a Video4Linux (version 1) kernel driver has to be provided so that the Qtopia Camera application can use it.
- If the device has or supports phone hardware, a serial device that supports GSM AT-commands should be provided, so that Qtopia Phone can use it.
- If the device supports sound, the sound volume should be locked to the maximum intended volume.

All of the changes required to add these device specific customizations are centralized in Qtopia and involve a small number of files (described below). This document should make it easy for OEMs and system integrators to understand how to make Qtopia aware of any special hardware that a device might have.

### Device-Specific Code

During configure, the `-platform` option is used to select which custom-<platform-spec>.h file will be used when compiling Qtopia. The following macros can be defined or undefined in a custom.h file to customize Qtopia for the specific hardware. The associated custom-<platform-spec>.cpp file will be compiled and linked to provide any custom functions that are required.

- QPE_USE_MALLOC_FOR_NEW - #define this to have memory alloced using malloc() instead of the default C++ new implementation (this is faster in some cases).
- QPE_NEED_CALIBRATION - #define this if there is a touch screen that requires calibration.
- QPE_OWNAPM - #define this if the device has existing APM settings that must be disabled first by qtopia via ioctls to /dev/apm_bios.
- QPE_HAVE_TOGGLELIGHT - #define this if the device has a hardware button for turning on and off an LCD backlight.
- QPE_HAVE_MEMALERTER - #define this if the device needs Qtopia to alert the user of low memory conditions, a function called initMemalerter() must be implemented.
- QPE_MEMALERTER_IMPL - #define this as a macro that implements any functions required to implement the MEMALERTER functionality (including initMemalerter()).
- QPE_INITIAL_NUMLOCK_STATE - #define this as a macro that implements any device specific methods used to initialize the numlock state.
- QPE_ARCHITECTURE - #define this with a string that contains the manufacturer and model that uniquely identifies the device, for example "SHARP/SL5500".
- QPE_DEFAULT_TODAY_MODE - #define this as "Daily" or "Never" (including the quotes) to tell Qtopia if by default it should run the today program daily or never.
- QPE_FONT_HEIGHT_TO_ICONSIZE(x) - #define this as a macro to provide a mapping from a font height to an icon size in pixels.
- QPE_SYSTEM_SYSFILEMONITOR - #define this if your device's HotPlug system for Removable Storage Cards is Qtopia-aware.
- CUSTOM_SOUND_INIT - #define this to call a function to initialize any custom sound devices like buzzers.
- CUSTOM_SOUND_IMPL - #define this as a macro to define any custom functions required to be used by the other CUSTOM_SOUND macros.
- CUSTOM_SOUND_ALARM - #define this as a macro which implements the device specific code to sound an alarm (perhaps using a buzzer).
- CUSTOM_LEDS( led, status ) - #define this as a macro which can set an LED to a given status if applicable. The first argument specifies which LED, and the status is an integer with device specific meaning.
- CUSTOM_SOUND_TOUCH( press ) - #define this as a macro which implements a given sound to be associated with taps to the screen if applicable.
- CUSTOM_SOUND_KEYCLICK( k, p, r ) - #define this as a macro which implements a given sound to be associated with keyboard key presses if applicable.

In addition to the above macros and defines, the following three functions must be implemented in the custom-<platform-spec>.cpp file.

- int qpe_sysBrightnessSteps(); - This function is called by qtopia to query the number of graduations the device's LCD backlight/frontlight has.
- void qpe_setBrightness(int); - This function must be implemented with any device specifc code used to set the backlight/frontlight brightness to the specified level.
- void PowerStatusManager::getStatus(); - This function must be implemented to query the power status. The PowerStatus class in qtopia/power.h defines the power status abstraction. See the custom-linux-generic-g++.cpp file for details of a default implementation.

For reference implementations of the device specific code, the existing `custom-*.*` files found in src/libraries/qtopia/ may be of guidance.

## Non-installed Components

There are a number of applications/features supplied with Qtopia that are not intended to be shipped with production devices:

- Rotation Setting - This is provided to test and demonstrate Qtopia's ability to display in different orientations. This may be helpful during development if the device uses the transformation display driver.
- Shutdown Setting - This is provided as a development tool. It should not be necessary on a production device. It can be removed by deleting apps/Settings/quit.desktop, on most devices it is expected that there is a physical power button, therefore the user is not expected to ever manually run or shutdown Qtopia.
- screensize applet - allows changing the maximum window size for testing different screensizes quickly during development. This is a development tool only which is also not intended for end users.
- Terminal - This is provided as a development tool. It may be reasonable to provide this as a seperate installable package for advanced users who are familiar with Linux however it is not expected that the majority of users will find this tool at all useful, only confusing. Therefore it is recommended this program is not included.
- File Manager - Provided as a development tool. Qtopia is functional without it using just Qtopia's document model. Adding the File Browser can make it possible for users to add and remove files from the device in a way which does not correspond to Qtopia's document model which can break the interface. We therefore do not recommend this program should be included on a device to ensure a consistent document model in addition to protecting critical user and system files and settings.

## Unsupported Components

The following applications are unsupported 3rd party applications/ports intended purely to demonstrate the flexibility of Qtopia:

- VNC Viewer

## Required Plugins

If Qtopia crashes twice in quick succession "Safe Mode" will be entered and no plugins will be loaded in case the crash was caused by a misbehaving plugin. In some cases there are plugins that are required for correct operation of the device. These plugins can be specified in the .directory file in $QPEDIR/plugins/<type>/.directory. For example, if the simple8 text codec is always required:

    [Desktop Entry]
    Name=Text Codecs
    Comment=Provides support for various international languages.
    Required=simple8
    Apply=QPE/System restart()

## Power Management

A number of points should be considered when integrating Qtopia with a device that has power management.

- Qtopia controls the power state (using pen and key input to restart timeouts), not the kernel.
- The system's "Power" key just sends a key to Qtopia, which then does the actual suspend.
- Qtopia supports multiple shutdown levels. By default these are On, Light Dim, LightOff, and Suspend. Additional levels can be added with a small amount of coding.
- Qtopia calls platform-specific functions to set lighting level for 'dimming' and turning off the light.
- Qtopia runs the 'apm' command to suspend.
- The system's `at` daemon is used to unsuspend upon RTC alarms.
- The system's `at` daemon is used to write the RTC clock (because on some systems only one process can manipulate the RTC).

### Technical Details

Qtopia's power management is handled by Qt embedded. The `QWSServer` uses the `QWSScreenSaver` interface in order to decide what to do. Qtopia provides the screensaver behaviour by extending from `QWSScreenSaver`. This screensaver (`QPEScreenSaver`) is implemented in `qpeapplication.cpp` and provides the following three screensaver levels:

- 0 - dims display light
- 1 - turns display light off
- 2 - depends on the Qtopia version

Qtopia will call the platform-specific function `qpe_setBrightness(int)` in order to adjust the light for the display.

The last level depends on the specific version of Qtopia. The PDA version will use the APM daemon and suspends the execution of Qtopia whereas the phone editon closes open applications and returns to the home screen. For further information please refer to: For PDA Edition and For Phone Edition.

The `QWSServer` provides the following interface which allows the registration and customization of arbitrary screensavers:

    \list
    \i - void setScreenSaver ( QWSScreenSaver * )
    \i - void setScreenSaverIntervals ( int * ms )
    \i - void screenSaverActivate ( bool )
    \endlist

Qtopia's screensaver can be adjusted by the user via the power management (Light & Power) application.

### For PDA Edition

Qtopia runs the 'apm' command to suspend. The system's AT daemon is used to unsuspend upon RTC alarms. The system's AT daemon is used to write the RTC clock (because on some systems only one process can manipulate the RTC).

The system's "Power" key or the third screensaver level just sends a key (`Qt::KeyF34`) to Qtopia, which then does the actual suspend. It triggers the execution of `ServerApplication::togglePower()`. All CPU functions are suspended once

     system("apm --suspend");

is executed. Normal operation will resume once a "Wake up" event comes from `apmd`.

### For Phone Edition

Suspension is not enabled in the phone edition.

     "apm --suspend"

would suspend the CPU and shutdown the device. This behaviour is acceptable for PDA's because they don't need to listen for incoming calls. However, the qpe server must be running in order to receive calls. If Qtopia shuts down the power, everything would stop working. We will assume that Qtopia Phone does not do that (or that if it does, Linux ensures resume on modem activity).

Rather than suspending the device the number of CPU cycles has been minimized while the qpe server is showing the home screen. In addition to the first and second screensaver level (already known from the PDA edition) Qtopia Phone automatically closes applications and returns to the home screen. Background activities (like time/date updates and the execution of the battery monitor) are reduced to ensure that the CPU consumption is at the lowest possible level.

## Removable Storage Cards

Files from external devices such as SD and CF cards are scanned on insertion and supported documents are mapped in to Qtopia's document view.

The scanning is triggered when the Qtopia library receives one of the following messages via the QPE/Card QCOP channel:

- mtabChanged() - Sent when /etc/mtab have changed.
- stabChanged() - Sent when /var/run/stab, /var/state/pcmcia/stab, or /var/lib/pcmcia/stab have changed.

If QPE_SYSTEM_SYSFILEMONITOR (see above) is defined, Qtopia assumes that the surrounding system generates these messages (eg. by using the qcop command in the system HotPlug scripts). Otherwise, Qtopia polls every few seconds (wasting CPU).

When Qtopia scans for external devices such as SD and CF cards, it uses an heuristic to work out what is an external card. If this automatic detection is inadequate due to the specifics of your device, you may alternatively provide the file /opt/Qtopia/etc/default/Storage.conf, with a group for each relevant device in /etc/mtab, with settings of this form:

    [/dev/hda1]
    Name = Internal Storage
    Removable = 0
    [/dev/sda1]
    Name = Card
    Removable = 1

With the above, /dev/hda1 will be internal storage, and when /dev/sda1 is mounted (eg. by Linux Hotplug system), a storage location named "Card" will be available to the user: any documents there will appear on the Documents page. This file can be translated as with any Qtopia Config file.

## I18N

Qtopia uses UTF8 for all file formats. System functions are also expected to use UTF8 encoding. For example, with $LANG set to "ja", strftime() must return a string in UTF8 encoding. Depending on the underlying operating system, this may require "ja" to be an alias for the "ja_JP.utf8" locale.

Note that Qtopia expects all file systems to use utf8 encoding. This usually requires attention in /etc/mtab and /usr/share/locale. Particular attention should be paid to removable media.

## Access Permissions and Read-only Filesystems

Qtopia can run as any user, provided that user has read and write permissions to certain file areas for certain functionality:

- /dev/fb0 - Frame Buffer
- /etc/ppp/... - PPP configuration options
- /etc/pcmcia/... - LAN/wireless network options
- /opt/Qtopia/... - Installing additional software

If a read-only filesystem is used, such as cramfs, then a symlink shadow should be created such that the above directories are writeable, but those files that are to be storeda in the cramfs filesystem are symbolic links to the actual files. For example, /opt/Qtopia/apps/Applications/calculator.desktop would be a symbolic link to /opt/Qtopia-ROM/apps/Applications/calculator.desktop.

As an alternative to the single directory specified by $QPEDIR, most Qtopia components support $QTOPIA_PATH, with is a colon-separated list of directories. By setting this variable (to, for example, "/opt/Qtopia:/opt/Qtopia-ROM"), and setting $PATH and $LD_LIBRARY_PATH appropriately, the following component directories can be searched in multiple places:

- $QPEDIR/bin
- $QPEDIR/help
- $QPEDIR/i18n
- $QPEDIR/lib
- $QPEDIR/pics
- $QPEDIR/plugins
- $QPEDIR/sounds

This greatly reduces the overhead of using symbolic links.

## MMS Client

The Qtopia Phone Edition includes MMS functionality in the messages client.

### WAP Stack Integration

Qtopia does not include a WAP stack with the MMS client. Instead, an interface is provided which allows any WAP stack to be integrated. The MmsComms class must be subclassed and the virtual functions implemented and signals emitted as appropriate. The MmsCommsHttp class provides a sample implementation using HTTP over TCP/IP see : $QPEDIR/src/applications/qtmail/mmscomms_http.{cpp,h}

To choose an alternate WAP stack connection method

- modify the MmsClient::setAccount function in $QPEDIR/src/applications/qtmail/mmsclient.cpp to choose your MmsComms implementation
- modify MMSCOMMS_HEADERS and MSCOMMS_SOURCES in $QPEDIR/src/applications/qtmail/qtmail.pri to list the source/header files for your MmsComms implementation.

### AMR Encoder

The AMR encoder included with Qtopia is a reference implementation only. It is recommended that an encoder optimized for the target platform be installed. The media recorder plugin interface provides a convenient method of integrating the codec. See MediaRecorderEncoder class.

## GSM Module Integratation

We have found that the implementation of the GSM specification varies from GSM module to GSM module. It is therefore highly likely that there will be a need to modify at least $QPEDIR/src/libraries/qtopiaphone/{muxdevice.*, atchat.*} to ensure that the GSM subset that the module supports is being used.

To support a GSM module the follow guide may be used:

1. Check the AT commands that Qtopia requires (see phonelibrary.html ) and determine which ones your GSM module does and does not support.
2. Determine the appropriate alternative AT commands suited to your GSM module and modify the phonelibrary as required.
3. Run Qtopia.
4. Check the error/message log for commands that are reported as error.
5. Using the error log modify the phonelibrary so that the modem's supported AT command parameters are used. For example, `AT+CMUX=1,0,5` vs `AT+CMUX=0,0,5` .
6. Repeat from step 3 until GSM calls are possible, SIM details are being read etc ...