USERNAME PASSWORD LOST PASSWORD? REGISTER
"A Complete Mobile Application Development Environment"
Advertisement

Downloads
Documentation
Forums
Blog
Press
Bug Tracking
Creator IDs
Contact Us




Creating a Simple ACCESS Linux Platform Application PDF Print E-mail
Documentation »  ACCESS Linux Platform Native Development »  Programming Guide »  Creating a Simple ACCESS Linux Platform Application

This chapter provides a basic introduction to the environment you'll use to develop ACCESS Linux Platform applications. It then presents a detailed walk-through of the creation and testing of all aspects of a basic ACCESS Linux Platform application.

The Development Environment ^TOP^

The ACCESS Linux Platform application development environment is delivered in a set of Debian packages collectively identified as the ACCESS Linux Platform SDK. Development is done on a computer running Linux. See Getting Started with the ACCESS Linux Platform SDK for instructions on installing the SDK.

SDK ^TOP^

The ACCESS Linux Platform Software Development Kit, or SDK, gives application developers the necessary components and tools to develop ACCESS Linux Platform applications.

The SDK includes header files, libraries, documentation, samples, tools, plus a complete runtime environment in the form of an x86 kernel and root filesystem. Applications can be targeted to an ACCESS Linux Platform device, or can be compiled and tested for the ACCESS Linux Platform Simulator.

Among the tools included in the ACCESS Linux Platform SDK are a set from open source software projects that have been either patched or unpatched by PalmSource. Also included are a set of tools specifically designed for ACCESS Linux Platform application development. For instance, the ACCESS Linux Platform Simulator, a version of the ACCESS Linux Platform that runs natively on an x86 version of Ubuntu Linux.

As Linux is the base for the ACCESS Linux Platform, it is also the natural development platform for ACCESS Linux Platform applications. Accordingly, ACCESS Linux Platform application developers need to use an x86 PC running Ubuntu version 6.10. This can either be a dedicated machine, a machine that dual-boots one or more other operating systems as well, or a virtual machine using an environment such as VMware®.


NOTE: Ubuntu 6.10 can be found at http://old-releases.ubuntu.com/releases/edgy/ (if you are in the United States) or at http://www.ubuntu.com/getubuntu/downloadmirrors/ otherwise.

Scratchbox ^TOP^

Application development using the ACCESS Linux Platform SDK is done within Scratchbox. Scratchbox is a chrooted build environment: an environment in which you have changed root to point to a new location. It is basically a sub-tree of the full filesystem tree. When you change the root from / ("slash") to some other location, you are redefining where the root of the filesystem is when viewed from within the chrooted environment. Note that this is not the same as creating a "virtual machine" — you are still dealing with files that live in your local filesystem tree. Files accessible from within your chrooted environment can also be accessed from outside of the chrooted environment; only the initial portion of the path is different. For instance, the standard ACCESS Linux Platform SDK installation puts your Scratchbox root at /scratchbox/users/imaCoder/ (assuming that your username is imaCoder).

Of course, Scratchbox does more than just running the chroot command would do. Scratchbox allows the creation of multiple target environments. Each target is a separate environment that has a selected toolchain (often for cross-compiling), target CPU and filesystem. Scratchbox provides a form of host simulation so that the cross compiler can be called simply as "gcc". This greatly simplifies your development environment as your configuration appears to be a native one rather than a cross configuration.

Beyond cross-compilation, additional fakery is needed so that you can run test code on a real or pretend target device. The Scratchbox documentation refers to this as CPU Transparency. ACCESS Linux Platform allows you to create targets for either (or both): emulated ARM targets are set up using qemu-arm emulation, and you can set up device targets that allow execution on an actual connected device.

Detailed documentation on Scratchbox can be obtained from their website, at http://www.scratchbox.org/documentation/user/scratchbox-1.0/.

Rootstraps

A rootstrap is a complete filesystem image that, in the case of the ACCESS Linux Platform SDK, is installed in a Scratchbox target environment. The SDK comes with two rootstrap packages:

alp-device-sdk-rel.tar.gz
This is an ARM device target. It is a "release" target; it does not contain any debugging information. This rootstrap package is only useful if you have suitable ARM hardware.
alp-simulator-sdk-dbg.tar.gz
This is a Simulator target. It contains debugging symbols, and can be used to run and debug your applications on the ACCESS Linux Platform Simulator.

Even if you have hardware suitable for testing your ACCESS Linux Platform applications, you'll likely do all of your initial development and testing on the Simulator using the alp-simulator-sdk-dbg target. It is important to note that although you can run the debugger using either target, the alp-device-sdk-rel target not only requires that you have hardware connected to your development machine, but because it contains no debugging symbols, it won't let you do symbolic debugging.


IMPORTANT: Except where hardware is specifically mentioned, this book assumes that the currently-selected Scratchbox target has been "roostrapped" with the alp-simulator-sdk-dbg.tar.gz rootstrap package.

Eclipse ^TOP^

The ACCESS Linux Platform SDK includes version 3.2.2 of Eclipse (with CDT version 3.1.2), a widely-used open source IDE. You use Eclipse to code, build, and debug both x86 and ARM versions of your ACCESS Linux Platform applications. Eclipse provides the front-end to tools such as gcc (the compiler) and gdb (the debugger). Testing and debugging from within Eclipse can be targeted to either an emulated environment or to an actual ACCESS Linux Platform device connected to the development host.

See http://www.eclipse.org for more information on Eclipse.

Figure 3.1  Eclipse

Glade ^TOP^

To enable drag-and-drop style development of ACCESS Linux Platform application user interfaces, the ACCESS Linux Platform SDK includes Glade. Glade is an open source user interface builder for GTK+. It produces an XML representation of the various forms and other user interface resources that are interpreted and rendered at runtime by libglade.

libglade, one of the many shared libraries that make up the ACCESS Linux Platform, loads and parses the XML interface description at runtime. It also provides functions that can be used to connect signal handlers to parts of the interface. Together, Glade and libglade allow you to separate your program code from the interface code.

Like Eclipse, Glade is an open source tool (on the web, Glade can be found at http://glade.gnome.org/). The version included in the ACCESS Linux Platform SDK is tailored specifically for ACCESS Linux Platform application development. In particular, the set of UI widgets provided for use in constructing your user interfaces is limited to those that are most useful in applications designed for a small screen such is typically found on an ACCESS Linux Platform device.

Figure 3.2  Glade

Simulator and Emulator ^TOP^

So that you don't have to have an ACCESS Linux Platform device on hand during the initial phases of application development, the ACCESS Linux Platform SDK includes two distinct software tools that can act as a target.

The Simulator is a virtual Linux system—what is known in the open source world as a User-mode Linux, or UML—that runs within Ubuntu on an x86 machine. It acts just like an ACCESS Linux Platform device and runs the rgdbd (a PalmSource-developed remote gdb daemon) enabling you to connect to it from gdb and debug your applications as if they were running on a real device. The Simulator runs at the speed of the underlying machine, but requires that you compile your application for the x86 architecture. Because of this, while you can do the bulk of your application testing on the Simulator, final testing of the ARM executable needs to be done on something that can run ARM code: either an actual ACCESS Linux Platform device, or on the Emulator.

Although similar on the surface, the Emulator is a full version of ACCESS Linux Platform—including the kernel—built for ARM. This lives on top of an emulated ARM development board, which employs an ARM instruction emulator. Because each ARM instruction must be interpreted and emulated, Emulator performance cannot match that of the Simulator. However, it has a huge advantage in that it is running the actual ARM code and can thus run ARM binaries. And like the Simulator, the Emulator also runs rgdbd and thus can act as a gdb target.

Creating a Simple Project ^TOP^

This section is intended to serve two purposes: to acquaint you with the tools you use to build an ACCESS Linux Platform application, and to introduce you to the basic structure of the application itself.

Classic "Hello World" ^TOP^

Partly for tradition's sake, and partly because it provides a gentle introduction to the application development process, let's start with the classic text-only version of "Hello World." Listing 3.1, below, shows the source for this.

Listing 3.1  main.c from the traditional "Hello World"


#include <stdio.h> 
 
int main (int argc, char *argv[]) { 
	printf("Hello, World!\n"); 
	return 0; 
} 

The fact that Hello World is so simple is what makes it so useful: it is easy to remember, and easy to key in without mistake, yet it exercises the build and run process. If Hello World works, you know that your toolchain is solid and that you are well on your way to creating more meaningful applications.

The version of Hello World shown in Listing 3.1 builds and runs just fine on the ACCESS Linux Platform. Granted, it isn't very exciting—when executed from the ACCESS Linux Platform launcher the screen momentarily goes blank and the launcher is then redrawn—but when run on the ACCESS Linux Platform Simulator the "Hello, World!" text does get printed to the console.1

In order to make Hello World into an application that will run on the ACCESS Linux Platform, you minimally need to:

  • Create a manifest file.
  • Create an icon to represent the application in the ACCESS Linux Platform launcher.
  • Compile the code into a shared object (.so) file.
  • Construct a bundle containing the manifest, the .so file, and the icon. To simplify the handling of the bundle, you usually create a compressed archive of the bundle: a .bar file.

Once you have created the manifest and the icon, the job of compiling your code and creating a bundle in the appropriate format can be left to a makefile.

The Manifest File

The manifest is an XML-format file that describes the purpose and structure of the various components that make up a bundle. For instance, Listing 3.2 shows the manifest for our Hello World application. This manifest specifies the following:

  • The bundle name. Note that application bundle names take the form com.yourCompany.apps.yourApp to ensure that the bundle name is unique.
  • The application name to be presented to the user in the ACCESS Linux Platform launcher ("Hello Simple", in this example).
  • The location within the bundle of the icon to be displayed by the ACCESS Linux Platform launcher.
  • The application executable.

Listing 3.2  Traditional "Hello World" application manifest


<manifest name="com.access.apps.hello"> 
ย ย ย <application> 
ย ย ย ย ย ย <name>Hello Simple</name> 
ย ย ย ย ย ย <icon>icon.jpg</icon> 
ย ย ย ย ย ย <library>libalp_hello.so</library> 
ย ย ย </application> 
</manifest> 

Depending upon the needs of the application, the manifest can also specify things like:

  • whether the application should be displayed in the application launcher
  • what should happen to the application whenever it is shut down
  • whether or not the application should be drawn using the user's chosen "theme"
  • dependencies upon other applications and shared libraries

The sample manifest shown above is a pretty minimal example; for complete details on what can go into the manifest file, see Appendix A, "Manifest File Reference."

Each ACCESS Linux Platform application must have its own manifest file. Create it with a text editor, name it Manifest.xml, and place in the directory that contains your application's makefile.

The Application Icon

If your application is to be presented to the user in the ACCESS Linux Platform launcher, it should include an appropriate icon (an icon isn't strictly necessary—the Launcher will display the application name regardless—but an icon adds an element of polish to your application).

Application icons can be in any of a number of common formats, such as JPEG, GIF, PNG, or SVG, as long as they are understood by GTK+. The launcher displays icons in one of two sizes: 34x34 pixels (when the launcher is displaying the "grid view") and 17x17 pixels (when it is displaying "list view'). The icon you supply will be scaled up or down by the launcher as necessary, maintaining the original image's aspect ratio. PNG-format icons should have a transparency channel.

Place your icon in your project's rsc directory. In the manifest use the <icon>...</icon> tag pair to specify the path to the image file, relative to the rsc directory, as shown in Listing 3.2.

Building the Application

To build the application, you can either compile them manually from the command line, construct and then run a makefile from the command-line to do that for you, or use Eclipse to build and run a makefile. In the remainder of this book we'll use Eclipse to manage and build our projects, but for this one example we'll walk through the process step-by-step so that you can see what Eclipse is doing for you.

When you build an ACCESS Linux Platform project in Eclipse, it constructs and then runs a makefile that essentially does the following:

  1. First, it constructs a directory to contain the bundle, and copies your Manifest.xml file into it. The path to the bundle directory depends upon the target. For our project, targeting the Simulator, the path (relative to the Eclipse workspace for our project) is build/alp-simulator/Debug/com.access.apps.hello.
  2. Next, it uses gcc to compile (but not link) the project's source file(s), producing an object file. In our example, it compiles main.c and produces build/alp-simulator/Debug/obj/hello.o.
  3. The makefile now re-invokes gcc to link the object files into a dynamically-loadable shared object. This step, for our example, produces build/alp-simulator/Debug/com.access.apps.hello/libalp_hello.so.
  4. Now that the manifest and executable are in place, the makefile next copies any needed resources into the bundle. In the simple Hello World application the only resource—and thus, the only file copied in this step—is the application's icon.
  5. Lastly, the makefile creates a compressed version of the bundle: a ".bar" file. It invokes the bartender tool to perform this particular task. Everything in build/alp-simulator/Debug/com.access.apps.hello/ is packed into build/alp-simulator/Debug/com.access.apps.hello.bar (and a copy of the manifest is placed into the .bar file's header for easy access).

A Proper "Hello World" ^TOP^

While the basic Hello World application described in the previous sections can indeed be compiled and run on the ACCESS Linux Platform, it really isn't an ACCESS Linux Platform application in the sense that it doesn't display to or interact with the user of a device in any way. To create an ACCESS Linux Platform version of Hello World, you need to add code that at a minimum displays "Hello World" on the ACCESS Linux Platform device screen. As well, to make it a "proper" ACCESS Linux Platform application, you need to:

  • Add a title bar and support for menus
  • Handle launch codes
  • Respond to ACCESS Linux Platform application exit requests

The following sections explain these requirements as they illustrate the creation of just such an application. They also show how to use the graphical development tools that most ACCESS Linux Platform application developers will presumably use: Eclipse and Glade.


NOTE: The steps in the following section assume that you have installed the ACCESS Linux Platform development environment and configured the Simulator target using the alp-simulator-sdk-dbg.tar.gz rootstrap package. For instructions on installing and configuring your development environment, see Getting Started with the ACCESS Linux Platform SDK.

Creating the Eclipse Project

The following steps walk you through the creation of a basic Eclipse project.

  1. Open a terminal window, and type the following command to launch Eclipse:
$ alp-eclipse

At this point you might want to minimize the terminal window from which you started Eclipse, if only to reduce the clutter on your screen. The alp-eclipse command will block until you exit Eclipse.


NOTE: Eclipse must be started from outside of Scratchbox. If you see an error message of the form bash: alp-eclipse: command not found, make sure that you are not in Scratchbox.
  1. The first time you launch Eclipse, it will ask you to select your workspace. The workspace is a logical collection of projects. When you select a directory for your workspace, alp-eclipse creates some files within the directory in order to manage the projects. Your projects don't actually have to reside in this directory. When creating a new project (you'll do this shortly, in step 4 on page 47), by default the project's directories and files are created inside of the workspace. However, you can choose not to accept the default for any given project, and instead specify a location outside of the workspace directory.

    The default workspace path will be /home/imaCoder/workspace (Note: in this example, and in many places throughout this book, "imaCoder" is a stand-in for your Linux username. Wherever you see "imaCoder", substitute your username). Your workspace needs to be located within your Scratchbox environment; thus, it is important that you change this path.

    1. Click the Browse button.
    2. Double-click on "File System" in the left-hand pane, then navigate to scratchbox/users/imaCoder/home/imaCoder/.
    3. If you wish, create an additional subdirectory (or multiple levels of subdirectories) to serve as your workspace (use the Create Folder button in the upper-right corner of the dialog).
    4. Click OK to confirm your workspace path and to dismiss the "Select Workspace Directory" dialog.
    5. In the "Workspace Launcher" dialog, check the "Use this as the default and do not ask again" checkbox. Figure 3.3 shows what the dialog should look like.
    6. Click OK to confirm your choice and dismiss the "Workspace Launcher" dialog.

Figure 3.3  Selecting an Eclipse workspace


TIP: If you use Nautilus—the graphical interface for Ubuntu—you may want to "bookmark" your Eclipse workspace to make it easy to locate your workspace contents from the Nautilus File Browser. To do this, navigate to your workspace folder using the File Browser. Then, select Add Bookmark from the Bookmarks menu. Your workspace is now listed in the Places menu; select it to view your workspace contents.
  1. Having specified a workspace, next you should let Eclipse know which Scratchbox target you have selected.
    1. Open the Preferences dialog by selecting the
      Window->Preferences... menu item.
    2. In the left-hand column of the Preferences dialog you'll see entries for "General", "ACCESS Linux Platform Developer Suite", "C/C++", etc. Click the disclosure triangle to the left of "ACCESS Linux Platform Developer Suite" to expand it.
    3. Click the one sub-item that appears, "Scratchbox Targets".
    4. In the body of the dialog all of your configured Scratchbox targets should be listed. Make sure that the appropriate target is selected—alp-simulator, for instance.
    5. Click Apply, and then OK.

      When Eclipse builds and debugs your project within Scratchbox, the target you just selected will be used.

  2. Create your project as follows:
    1. Select File->New->ACCESS C/C++ Application Project.
    2. Supply a name for the project. For Hello World, name it "Hello".
    3. Ensure that the "Use Default Location" checkbox is checked. The default location for our project is the workspace you specified when you originally started Eclipse (see step 2 on page 45), when viewed from outside of Scratchbox. From within Scratchbox, it can be found at the ~/hello/ (there may be an intervening subdirectory, if you created one as part of your workspace path).

      As was mentioned earlier, your projects don't actually have to reside within the workspace directory, although they must live somewhere beneath your Scratchbox directory. For this example we accept the default location (which is within the workspace you specified earlier), but if you prefer you can choose not to accept the default for any given project, and instead specify a location outside of the workspace directory.

    4. Click Next to proceed to the Templates dialog.
    5. Click the "Use Templates" checkbox.
    1. From among the available templates, select "Basic App".
    2. Click Finish to create the project.
  1. Eclipse may attempt to build your project at this point, even though it has no contents. Whether or not it does, now is a good time to set various Eclipse preferences:
    1. Select Window->Preferences.
    2. Click the disclosure triangle to the left of "General." Select "Workspace" from among the General preferences panels.
    3. Uncheck the "Build automatically" checkbox if it is checked.
    4. Check the "Refresh automatically" checkbox. This ensures that changes made outside of Eclipse are reflected automatically within Eclipse. Without this, you have to manually tell Eclipse when such a change has been made.
    5. Check "Save automatically before build." This is a convenience to ensure that changes made in any open files are saved before you build your project.
    6. Click Apply, then click OK.

Figure 3.4  The Eclipse general preferences panel

At this point the C/C++ Projects list should look something like that shown in Figure 3.5.

Figure 3.5  A basic application

The sequence of steps you just went through is common for most ACCESS Linux Platform applications. The project organization is also typical: the standard makefile assumes that your source files are located in your project's "src" directory, and project resources (icons, forms, and the like) are located in your project's "rsc" directory.

Building the User Interface

Although you can create your application's user interface entirely by making GTK+ calls, the code to do so can be somewhat cumbersome. Plus, you don't get the instant gratification that a visual user interface builder can provide. In the ACCESS Linux Platform development environment, Glade is the a visual interface builder. It allows you to lay out your interface in a more point-and-click fashion, providing a visual representation of what the interface will look like once it is actually running. Although Glade is less polished than some other visual interface builders you may have encountered, constructing an interface with it is nevertheless significantly easier than doing so entirely through calls to GTK+.

As stated earlier, a proper ACCESS Linux Platform application has a title bar which the user can click in order to display the application's menus. Accordingly, the version of Hello World that we will be building will need a title bar and one or more menus. Because this is the most basic of applications, it will only contain an "About" menu.

The main form of the application needs only to display the text "Hello, World!". In order to display this text, a widget is needed. Short text strings are often displayed using a GtkLabel widget, but this text isn't strictly a label. Thus, we'll use a GtkTextView.

Finally, all drawing needs to take place within a window, which, because this is an application, will occupy the entire screen (except for the small portion needed for the system status bar).

The following sections walk you through the process of constructing the Hello World application's user interface using Glade.

Launch Glade

In a new2 terminal window, type:

alp-glade

Once Glade has started, you should see one large window divided into four distinct areas, as shown in Figure 3.6.

Figure 3.6  The Glade window

Once you create a new project or open an existing project, graphical representations of the projects windows and dialogs will be drawn in the Project Area.

Inspector
The Inspector lists each of the widgets used in your project, organized hierarchically so that you can easily see the parent-child relationships between those widgets. You can select widgets either by clicking on them in the Project Area or by clicking on them in the Inspector.
For a new project, the Inspector will be empty. As you add widgets to your project, they will be listed here.
Palette
The Palette contains the set of widgets which you can employ in your Glade projects. Widgets are grouped into several broad categories—"Toplevels," "Containers," etc.—and represent windows, buttons, menus, and so on.

You add a widget to your interface by clicking on it in the palette and then clicking on the location in the Inspector where you want the widget to appear.

The image to the right shows a fairly compact view of the Palette—the view that initially appears when you launch Glade. An expanded view of the Palette showing both the widget icons and their names is shown in Figure 3.7. From within Glade, change the appearance of the Palette—from icons only, to text only, to a mix of text and icons—by selecting the appropriate option from the View -> Palette Appearance menu.

Figure 3.7  Glade widgets

Properties editor
The Properties editor is where you set the properties of the widgets that make up your application's user interface. Use it to assign widget names, set default sizes, specify whether or not a given widget is editable, and so forth. It uses a set of tabs to organize the various settings into logical groups. The "General" tab contains settings for the widget's class and name, its position, size, and the like. "Packing" is only relevant for widgets that are packed into containers, and specifies their position within the container and how they should occupy the allotted space. The "Common" tab is where you specify whether or not the widget is visible, whether or not it can receive the focus, whether or not it responds to input, and so on. And the "Signals" tab is where you can specify a callback function or signal handler for each signal event associated with the widget. The final tab, "Accessibility" (as indicated by the international symbol for handicapped) allows you to set parameters which will then comply with the Gnome accessibility guidelines.
The Properties editor shows the properties for the currently selected widget. If no widgets are selected, the Properties editor will be empty. Note that the name and type of the currently selected widget is displayed immediately above the Properties editor tabs.
Create the Application's Main Window

Applications need a window in which to run, so the first thing to do is to create that window:

  1. Click on the Window widget in the "Toplevels" section of the Palette. A widget named "window1" appears in the Inspector's widget list, a representation of that widget appears in the Project Area, and the Properties editor updates to show the Window widget's properties.
  1. The Window widget's name defaults to "window1". To give it a more meaningful name, select the "General" tab in the Properties editor, if it isn't already selected, and alter the text in the "Name" field. For this example, change it to "mainwindow" and press Return. Note that in the Inspector the name of the widget changes.
Add a Title Bar

Traditionally in X the window title is part of the window decoration. It is controlled by the Window Manager, and can be moved, resized, and have its depth-order altered.

In ACCESS Linux Platform, the window title is a widget within the form that opens the form's menu when tapped (or selected using the one-handed navigation device). This saves screen space while the menu is not in use. AlpTitleBar implements this behavior: it displays the window's title, and pops up a specified AlpMenuBar when selected.

Normally, the window title is left-justified within the AlpTitleBar, but because it is made up of standard GTK widgets, the layout and contents of the title bar can be customized. For instance, you can insert another widget—a small icon, say—to the left of the label. The appearance of an AlpTitleBar can be altered programmatically, or it can be specified with .gtkrc.

For applications where it is relevant, the right-hand side of the title bar contains a pop-up list of categories, used to categories the records within the application. For our sample application, there are no data records to categorize. Thus, the Hello World title bar contains only the name of the application. Selecting it brings up the application's menus.

To add the title bar to the Hello World application:

  1. First, divide the window into two parts, one to hold the title bar and one for the rest of the application's UI. In GTK+ you do this with a Vertical Box widget.
    1. Click on the Vertical Box widget in the Palette.
    2. Click within the application window (the window titled "Glade" that shows your application's UI).
    3. In the "Create a GtkVBox" dialog that appears, enter a value of 2 for the number of items and click OK. The dialog will disappear, and the application window will now show a light horizontal line dividing the window into two equally-sized areas (see Figure 3.8). As well, if you click the disclosure triangle next to the window name in the Inspector, you'll see that the application's main window now contains a vertical box named "vbox1". Because we won't be interacting with the vertical box programmatically, its name is not important and can be left as-is.

Figure 3.8  Adding a vertical box

    1. Click on the ACCESS Title Bar widget in the Palette.
    2. Click somewhere above the dividing line in your application's main window. The upper half of the vertical box will shrink in size so that it is just big enough to contain the title bar, and the lower half will grow to occupy the rest of the available window space.
    3. In the Properties editor, on the General tab, change the title bar's name to "titlebar" and change the label to "Hello World" (this is the text that is displayed as the application's title). Note that changes to a field in the Properties editor don't register until you have pressed Return or have selected a different field.
    4. While you are looking at the title bar's properties, verify that the "Number of items" field is set to 2. (Recall that the first item is the title itself, and the second is often—but not in this case—used to display the category information.)

Figure 3.9 shows what your Eclipse environment should look like after you have added the title bar.

Figure 3.9  A newly-added title bar

Add a Menu Bar and a Menu

One of the widgets ACCESS created specifically for the ACCESS Linux Platform is the AlpMenuBar widget. It works closely with the AlpTitleBar widget, displaying the application's menu bar when the user clicks the title bar and then hiding the menu bar when the user selects a menu item or taps outside of the menu. ACCESS Linux Platform applications use AlpMenuBar in place of the GtkMenuBar widget since the GtkMenuBar widget doesn't have the ability to "pop-up" and disappear automatically.

Having added an AlpTitleBar to the Hello World application as detailed in the previous section, you can now add a menu bar by following these steps:

  1. Click on the ACCESS Menu Bar widget in the Palette.
    Be sure not to confuse the ACCESS Menu Bar widget with the standard GTK "Menu Bar" widget that is found in the Containers section of the palette.

    Because the ACCESS Menu Bar is a top-level widget, nothing will appear in the application window, but you will see a new entry named "alpmenubar1" appear in the Inspector3. Note that the menu bar is not nested beneath the application's Window widget but is instead at the same level. This is because the menu bar and its menus are actually drawn in their own window on top of the application's window.

    If you click on the menu bar's disclosure triangle in the Inspector, you'll see that there are four "menu items" on the menu bar. Three of them have corresponding pull-down menus associated with them. These are standard menus that many applications will want to use. The first, "menuitem1", is a standard File menu, with default menu items for "New", "Open", "Save", "Save As", and "Quit". "menuitem2" is a standard Edit menu; it is pre-populated with "Cut", Copy", "Paste", and "Delete" items. The third item on the menu bar is "View"; it doesn't have an associated menu. The last item, "menuitem4", is a Help menu. It has a single item: "About". For our application, the "File", "Edit" and "View" items make no sense; in subsequent steps you'll delete them.

    To simplify the process of editing menus, menu items, and menu bars, alp-glade includes specialized editors for manipulating these objects. Whenever you select one of these objects in the Inspector, an Edit... button appears below the Properties editor that displays the appropriate object editor.

  2. Click "alpmenubar1" in the Inspector to select it. Click the Edit... button to bring up the Menu Bar Editor.

Figure 3.10  Menu Bar Editor

  1. Click "_File" in the left pane, if it isn't already selected, then click the Remove button found just below the pane. This will delete the File menu and all of its menu items.
  2. Delete the Edit and View menus as you did the File menu.
  3. The remaining menu—the Help menu—has the name "menuitem4", which isn't very clear. Rename it:
    1. Click "_Help" in the left pane, if it isn't already selected.
    2. Alter the contents of the Name field to read "helpmenuitem". Be sure to press Return to register the change to the Name field.
  1. There is a single menu item in the help menu. This item is already labeled "About", but has the somewhat cryptic name "imagemenuitem10". Rename it to "aboutmenuitem".
  2. With our one menu in place and appropriately named and labeled, the last thing you need to do is to indicate the code that should be executed when the user selects the About menu item. GTK+ uses what it terms signals for this: when the user selects the About menu item a signal is emitted by the menu item widget. A signal handler catches the signal and calls the appropriate function. If you tell Glade the name of the function that is to be called, a single function call early on in your program—to glade_xml_signal_autoconnect()—connects all of your widgets up to the specified functions. Do this for the About menu by:
    1. Ensure that aboutmenuitem is selected in the Menu Bar Editor.

      Note the pane near the bottom of the Menu Bar Editor with columns labeled "Signal", "Handler", and "User data"; this is where you specify the function that is to be called.

    2. Click on the disclosure triangle next to GtkMenuItem, if necessary, to expose those signals that are emitted by the GtkMenuItem widget and are not inherited from higher-level objects. (Note that the entire inheritance hierarchy for the GtkMenuItem widget is listed; the complete set of signals emitted by a GtkMenuItem widget can be shown by scrolling this portion of the Menu Bar Editor.)
    3. To the right of the signal name "activate", double-click in the "Handler" column (click on the text "<Type the signal's handler here>"). Type "onAboutMenu" (the name of the function that should be called when the About menu item is selected by the user), and press Return.

      You'll see the code for the onAboutMenu() function shortly, when it comes time to code the application.

    4. Close the Menu Bar Editor by clicking the Close button.

Figure 3.11  Setting a signal handling function

Connect the Menu Bar to the Title Bar

Having created both the application's title bar and menu bar, you now need to tie them together so that when the user selects the title bar the menu is displayed.

  1. In the Inspector, click on the titlebar widget. Recall that the title bar is nested inside of the vertical box named "vbox1" which is located on the application's main window. Thus you may need to click on the disclosure triangles next to the "mainwindow" and "vbox1" widgets.
  2. In the Properties editor, select the General tab.
  3. To the right of the field labeled "Menu:" is a button with three dots on it, like the one shown at the right.
    Click the button.

    A dialog will appear that lists the project's menu bars and menus.

  4. In the dialog click on the circle to the left of the top-level menu bar (named "alpmenubar1"). This indicates that the menu bar should be displayed when the user selects the title bar.
  5. Click OK to dismiss the dialog.

The name of the menu bar should now appear in the Properties editor's "Menu:" field.

Create a Text View

The one remaining piece of the UI still missing is a place into which the "Hello, World" string can be written and displayed. GTK+ provides a wealth of widgets that can serve this purpose. For this particular application the two best candidates are:

GtkLabel
A widget that displays a small to medium amount of text.
GtkTextView
A widget that displays a GtkTextBuffer.

GtkTextView is the more flexible of the two: it can be editable or not, portions of the text can be formatted differently from other portions (so that, for instance, you could italicize or bold an individual word or phrase), and it can easily work with large amounts of text. GtkLabel, on the other hand, is much more restricted. For our puposes—to simply display a short text string with no special formatting—either widget would work fine. Simply because the "Hello, World!" string isn't technically what one might consider a label, we've chosen to use a GtkTextView widget.

Add the text view to the UI as follows:

  1. In the Palette, click the Text View widget.
  2. Click within the application's main window, below the line that separates the title bar from the rest of the application's UI.
  3. Select the General tab in the Properties editor and rename the text view to "textview".
  4. Select the Common tab in the Properties editor and click the large button labeled "Sensitive" to toggle it from "Yes" to "No". This causes the text field to ignore button and key press events.
  5. Click the large button labeled "Editable" to toggle it from "Yes" to "No". This makes the text field display-only.

The Hello World application window should look like the following in the Glade Project Area:

Save the UI

At this point you have created all of the basic UI elements:

  • The application's main window
  • The title bar
  • The menu bar, tied to the title bar
  • A text view that will display the "Hello, World!" string

Save the UI by doing the following:

  1. Click on the Save button in the Glade toolbar.
  2. In the Save dialog:
    1. Specify a name. Enter "hello" into the "Name:" field. The actual name of the file will be "hello.glade".
    2. Ensure that the file will be saved into the resource folder (named "rsc") within your project. Click "Browse for other folders" and navigate to scratchbox/users/imaCoder/home/imaCoder/myApps/Hello/rsc (your path may have additional subdirectories depending upon where your workspace is located).
    1. Click Save to save the file and dismiss the Save dialog.

      The Glade window title now shows the name of your project—"hello.glade", in this case.

  1. Exit Glade by selecting Quit from the File menu.
  2. Bring up Eclipse (launch it from a terminal if necessary with alp-eclipse). If you did not choose to have your Eclipse workspace refreshed automatically (in step 5 on page 49), the rsc folder will appear to be empty. If so, right-click the project name ("Hello") in the left-hand pane, and select "Refresh" from the menu that appears. A disclosure triangle should appear to the left of the rsc folder icon—clicking this triangle reveals that hello.glade is now part of the project.

    In the future, you can edit the application's UI by simply double-clicking the .glade file in this Eclipse pane. This will launch Glade with the Inspector, Palette, and Properties editor showing. Double-click a top-level widget in the Inspector—such as the application's Window widget—to display the UI.

The .glade File

Before we move on to the application's source code, take a moment to look at the contents of the .glade file in text form. Because Glade uses an XML format, you can open the .glade file using a basic text editor. This is easy to do from within Eclipse. First, in the Navigator pane's C/C++ Projects tab click the disclosure triangle next to the rsc folder icon, if necessary, to expose the contents of the rsc folder. Then, simply right-click hello.glade and choose Open With -> Text Editor.


NOTE: In the Open With menu, a small black dot to the left of an editor name indicates the default editor for the selected file type: the editor that will be used either when you double-click a file of that type from within Eclipse, or when you right click a file of that type from within Eclipse and choose "Open" from the context-sensitive menu. When you use Open With to open a file with an editor other than the default, the chosen editor becomes the new default for files of that type. Thus, although the default editor for a .glade file initially is "ACCESS Interface Designer", once you've opened hello.glade with the Text Editor, the Text Editor will be the default editor for all .glade files until you once again use Open With to open a .glade file with another editor such as ACCESS Interface Designer.

Listing 3.3, below, shows what you should see in the Eclipse editor area: the actual contents of the hello.glade file (for clarity, the listing includes line numbers that you won't necessarily see in the text editor).

Listing 3.3  hello.glade (with line numbers added)


<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd"> 
<!--Generated with glade3 3.0.2 on Wed Dec 20 16:36:12 2006 by
		imaCoder@svicoderlnx--> 
<glade-interface> 
  <requires lib="alp_max_glade"/> 
  <widget class="GtkWindow" id="mainwindow"> 
    <property name="width_request">240</property> 
    <property name="height_request">320</property> 
    <property name="visible">True</property> 
    <property name="default_width">240</property> 
    <property name="default_height">320</property> 
    <child> 
      <widget class="GtkVBox" id="vbox1"> 
        <property name="visible">True</property> 
        <child> 
          <widget class="AlpTitleBar" id="titlebar"> 
            <property name="visible">True</property> 
            <property name="menu">menubar</property> 
            <property name="label" translatable="yes">Hello World
		</property> 
            <child> 
              <placeholder/> 
            </child> 
          </widget> 
          <packing> 
            <property name="expand">False</property> 
          </packing> 
        </child> 
        <child> 
          <widget class="GtkTextView" id="textview"> 
            <property name="visible">True</property> 
            <property name="sensitive">False</property> 
            <property name="editable">False</property> 
            <property name="cursor_visible">False</property> 
          </widget> 
          <packing> 
            <property name="position">1</property> 
          </packing> 
        </child> 
      </widget> 
    </child> 
  </widget> 
  <widget class="AlpMenuBar" id="menubar"> 
    <property name="visible">True</property> 
    <child> 
      <widget class="GtkMenuItem" id="helpmenuitem"> 
        <property name="visible">True</property> 
        <property name="label" translatable="yes">_Help</property> 
        <property name="use_underline">True</property> 
        <child> 
          <widget class="GtkMenu" id="helpmenu"> 
            <property name="visible">True</property> 
            <child> 
              <widget class="GtkImageMenuItem" id="aboutmenuitem"> 
                <property name="visible">True</property> 
                <property name="label" translatable="yes">gtk-about
		</property> 
                <property name="use_underline">True</property> 
                <property name="use_stock">True</property> 
                <signal name="activate" handler="onAboutMenu"/> 
              </widget> 
            </child> 
          </widget> 
        </child> 
      </widget> 
    </child> 
  </widget> 
</glade-interface> 

Careful inspection of the XML file shows two top-level widgets: the GtkWindow widget, which starts on line 6 and ends on line 41, and the AlpMenubar widget, which is defined using lines 42 through 65. The window widget contains a single "child" widget, a GtkVBox, which itself has two children: lines 15 through 27 specify the AlpTitleBar widget and how it is packed within the GtkVBox, while lines 28 through 38 define the GtkTextView and its position within the GtkVBox.

To close the Text Editor, click the "x" on the tab labeled hello.glade (if the tab doesn't have the current focus, you'll need to move your cursor to the tab in order for the "x" to be visible).

Writing the Source Code

With the UI in place, the next step is to write the application's source code. As you might expect, there isn't much code needed. Of course, because of the graphical interface, this version isn't nearly as simple as the text-only version of Hello World (Listing 3.1).

The following steps take you through the process of adding a source file to the Eclipse project:

  1. In the C/C++ Projects tab of the Navigation pane, click the disclosure triangle next to the folder named "src" to expose the folder's contents.
  2. Double-click appmain.c to open it in the Text Editor.
  3. In the Text Editor, replace the contents of appmain.c with the source code from Listing 3.4. Be sure to omit the line numbers that are included in the listing.
  4. Save the source file. There are a number of ways to do this, including (but not limited to) choosing Save from the File menu, pressing the Control and "S" keys, or right clicking the Text Editor window and choosing Save from the context-sensitive menu.

Listing 3.4  hello.c (with line numbers added)


#include <gtk/gtk.h> 
#include <glade/glade.h> 
 
#include <alp/alp.h> 
 
#define kGladeXML "hello.glade" 
#define kTextView "textview" 
 
 
void onAboutMenu(GtkMenuItem *menuItem, gpointer userData){ 
	// Get a pointer to the main window. It is used in the event that the 
	// app is shut down while the About dialog is displayed. 
	GtkWidget *topWindow = gtk_widget_get_toplevel(GTK_WIDGET(menuItem)); 
 
	alp_about_dialog_run(GTK_WINDOW(topWindow)); 
} 
 
// main window exit handler 
void onMainWindowExit(gpointer cbData){ 
	alp_max_dialog_cancel_all();รพรพรพ // closes any open "about" dialogs 
	gtk_main_quit();	 //Tells the main loop to return when it regains control 
} 
 
int alp_main(int argc, char *argv[]){ 
	GladeXML *xml; 
	GtkWidget *textView; 
	GtkTextBuffer *buffer; 
	int i; 
	bool regularLaunch; 
 
	// Look at launch codes. 
	// argv[0] is the bundle name ("bar:com.access.apps.hello") 
	// Launch codes (and any parameters) begin at argv[1] 
	regularLaunch = false; 
	for(i = 1; i < argc; i++){ 
		if(strcmp(argv[i], ALP_APP_PRIMARY) == 0){ 
			regularLaunch = true; 
		} 
	} 
 
	if(regularLaunch){ 
		gtk_init(&argc, &argv); 
		glade_init(); 
	 
		// Create the main window based upon the Glade XML 
		xml = alp_bundle_acquire_glade_xml(kGladeXML, NULL); 
	 
		// Hook all signal handlers set up with Glade 
		glade_xml_signal_autoconnect(xml); 
 
		// Hook the ACCESS Linux Platform exit handler 
		alp_app_add_exit_handler(onMainWindowExit, NULL); 
	 
		// Now set our text string 
		textView = glade_xml_get_widget(xml, kTextView); 
		gtk_text_view_set_justification(GTK_TEXT_VIEW(textView), 
			GTK_JUSTIFY_CENTER); 
		gtk_text_view_set_pixels_above_lines(GTK_TEXT_VIEW(textView), 100); 
		buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textView)); 
		gtk_text_buffer_set_text(buffer, "Hello, World!", -1); 
     
		gtk_main(); 
	} else { 
		// We didn't receive ALP_APP_PRIMARY; do nothing 
	} 
	 
	return 0;	 // Just return 0 - this isn't checked 
} 
 

The following sections highlight the more interesting aspects of the Hello World application.

Including Header Files

Lines 1 through 4 include various header files that declare functions, constants, and the like used by the application. Lines 1 and 2 include those headers needed to call various GTK and libglade functions, while line 4 includes a header that itself includes a number of headers specific to the ACCESS Linux Platform.

ACCESS Linux Platform applications are compiled from within Scratchbox. Scratchbox defines one or more target-specific environments; it is within one of these environments that the compiler is invoked. Thus, the actual locations of the various header files depends upon which Scratchbox target environment is current at the time the compiler is run. Assuming that you are compiling for the "alp-simulator" Scratchbox target, from within Scratchbox the headers can be found in /targets/alp-simulator/usr/include/. GTK, libglade, and ACCESS Linux Platform headers can be found in:

  • /targets/alp-simulator/usr/include/gtk-2.0/gtk/
  • /targets/alp-simulator/usr/include/libglade-2.0/glade/
  • /targets/alp-simulator/usr/include/alp/
  • /targets/alp-simulator/usr/include/hiker/

The above paths all assume that you are working within Scratchbox. From outside of Scratchbox, prepend /scratchbox/users/$USER to any of these paths. For instance, ACCESS Linux Platform header files would be located at /scratchbox/users/$USER/targets/alp-simulator/user/include/alp/.

Showing the About dialog

When you created the About menu item in Glade, you specified a handler for its "activate" signal (in step c on page 65): onAboutMenu. The signal name you supplied indicates the function that will be called when the user chooses the associated menu item—About, in this case. Lines 10 through 16 contain the code for the onAboutMenu() function:


void onAboutMenu(GtkMenuItem *menuItem, gpointer userData){ 
	// Get a pointer to the main window. It is used in the event that the 
	// app is shut down while the About dialog is displayed. 
	GtkWidget *topWindow = gtk_widget_get_toplevel(GTK_WIDGET(menuItem)); 
 
	alp_about_dialog_run(GTK_WINDOW(topWindow)); 
} 

This is a very simple function: it consists primarily of call to alp_about_dialog_run() in line 15 that, as you might guess, shows an application's About dialog. Because the About dialog is displayed in a separate window from the application's main window, the two need to be linked so that if the user switches to the launcher while the About dialog is displayed, the About dialog is closed when the application's topmost window is closed. This is enabled by passing a pointer to the topmost window when calling alp_about_dialog_run(); that pointer is obtained by calling gtk_widget_get_toplevel() in line 13.

While looking at this code, note the use of the GTK_WIDGET() and GTK_WINDOW() macros. Macros of this type are very common in GTK+ applications; they perform both type casting and type checking and are used in place of normal C type casting. In line 15, for example, the macro verifies that topWindow is an instance of type GTK_TYPE_WINDOW and emits a warning if it isn't. It then casts topWindow to a pointer to GtkWindow and returns it.

Unlike the standard GTK About dialog, the dialog produced by alp_about_dialog_run() is constructed using the contents of the <about> element in your application's manifest file. This about dialog can display a copyright notice, a version number, and a company name and logo, among other things. The precise contents of the manifest file for this application will be covered shortly, in "Creating the Manifest." For a detailed list of what you can present in your About dialog, see "The <about> Element".

Launching and Launch Codes

On the ACCESS Linux Platform, application execution is controlled by the Application Manager. The Application Manager is an open-source component—one of the key components of the Hiker Application Framework—that is responsible for starting and stopping applications (and moving them to the background or foreground, if appropriate). By centralizing control over application lifetimes, the Application Manager enforces a task-oriented usage model whereby only one application is designated to be the "main UI" application at a given time. It also ensures that only one instance of a given application is running at once.

Requests to launch a given application as the main UI application are sent to the Application Manager. The Application Manager checks to see if the requested application is already running; if so, the launch request is forwarded to it. If the requested application is not running, the Application Manager first shuts down (or moves to the background, as appropriate) the currently running main UI application. Then, it sets up the application execution environment, loads the application's executable, and calls its main entry point.

Irrespective of why an ACCESS Linux Platform application is being launched, at the time it is launched it is passed one or more launch codes that allow the application to know why it is being launched. Launch codes are not only passed when an application is initially launched; they can also be passed to an application that is already running. This is done when the system needs to communicate with the running application. Table 4.3 lists a number of common launch codes (most launch codes are defined as part of the Hiker Application Framework; see the reference documentation for the Application Manager for a list of system-defined launch codes).

By default, an ACCESS Linux Platform application's main entry point is its alp_main() function. Launch codes are passed through the main entry point's argc and argv parameters.

Following typical C program conventions, argc contains the number of arguments in the argv[] array. Further following C programming conventions, argv[0] contains the name by which the program was invoked. In this case, it is the full name of the bundle (for example, "bar:com.access.apps.hello").

The remaining arguments in argv are launch codes and any needed launch code parameters. Some, such as ALP_APP_PRIMARY, have no parameters. Others, such as ALP_APP_FIND, are followed by one or more parameters—in this case, the term to be searched for.

In our sample Hello World application, we do not support background operation, we do not respond to search requests, and we do not deal with alerts and alarms. In fact, the only launch code that our application can sensibly respond to is ALP_APP_PRIMARY; any other launch codes should be ignored. This is the reason for the regularLaunch variable, the loop in lines 35-39, and the if statement on line 41; only if ALP_APP_PRIMARY is among the launch codes sent by the Application Manager should this application actually launch. All other launch codes and any relaunch requests are ignored.

Note that many applications will respond to additional launch codes. As well, note that running applications should be prepared to have their alp_main() function called again. See Chapter 6, "Coding for the User Interface," and Chapter 10, "Improving Usability," for an explanation of why and how your application should handle additional launch codes.

Exit Handlers

Although an application can exit at any time, ACCESS Linux Platform applications normally run until told to quit by the Application Manager. Applications that need to clean up before exiting register one or more exit-handling callback functions. The Application Manager then "tells" the application to quit by calling its exit handler(s). If the application does not register any exit handlers, then the Application Manager instead raises a SIGTERM signal.

An application's exit handler should perform any necessary cleanup, and then cause the application to return from alp_main(). While some applications such as our sample Hello World application need only one exit handler, an application can have multiple exit handlers, adding and removing them at various times to associate different types of cleanup with the current program state. For example, if the application displays a dialog, it can also register an exit handler to dismiss that dialog. Exit handlers are always executed in reverse order, starting with the most recently added.

Add an exit handler by calling alp_app_add_exit_handler(), as the sample application does in line 52. You pass a pointer to the exit handling function, and can optionally pass a second pointer that will be given to the exit handler when the Application Manager calls your handler. If your exit handler doesn't need this extra information—Hello World doesn't—simply pass NULL. Note that your exit handler should have a single parameter—a gpointer—and should return void.

Our Hello World application doesn't need to do any application-specific cleanup. Thus, our exit handler only needs to ensure that any open About dialogs are closed (this is the purpose of the call in line 20) and then cause the application to return from alp_main(). Hello World does this final chore by calling gtk_main_quit(), on line 21.

GTK is an event-driven toolkit, which means it sleeps in gtk_main() until an event occurs causing control to be passed to the appropriate function. gtk_main(), which is called in line 62 of our program, does not return until after gtk_main_quit() is called. Note that gtk_main_quit() does not immediately cause a transfer of control to the line after the call to gtk_main(); only after gtk_main() regains control will it exit. Thus, we can do some processing in our exit handler after calling gtk_main_quit(), as long as we don't do anything that causes control to pass back to gtk_main(). Once the exit handler exits, control will eventually return to gtk_main(), which will then exit. After that, the next line of code to be executed is line 67, which causes a return from alp_main().

Note that we return a value of zero from alp_main(). An application's return value normally indicates whether or not the application executed successfully. On the ACCESS Linux Platform, however, application return values are ignored.

GTK and Glade Initialization

Before you call any other GTK+ functions, you need to initialize GTK itself by calling gtk_init(), as Hello World does on line 42.

In addition to initializing the toolkit, gtk_init() parses some standard command-line options, adjusting argc and argv to prevent your application from seeing them. Accordingly, you pass pointers to both argc and argv in your call to gtk_init(). Of course, ACCESS Linux Platform applications aren't invoked from a command line. As well, note that we've already taken a quick pass through argv looking for launch codes. Finally, note that we don't actually call gtk_init() unless we know that we're going to be using the display; if we received a launch code such as ALP_APP_FIND (in response to which we simply search for the specified term without becoming the main UI application), we needn't call gtk_init().

After initializing GTK+, if your application's UI was built using Glade—thus requiring the use of libglade—you need to initialize libglade. Hello World does this in line 43, with a call to glade_init(). This simply does some basic library initialization; in order to actually create the main window and connect up all of the needed GTK+ signals, the application needs to do a bit more.

The Bundle Manager (part of the Hiker Application Framework) includes the alp_bundle_acquire_glade_xml() macro that makes quick work of setting up the window: it is invoked in line 46 of our Hello World application. The first argument should identify the .glade file within the bundle containing the code that invoked the macro that defines the window. The second argument supplied to alp_bundle_acquire_glade_xml() allows you to specify a node within the XML interface description from which to build the interface. For a main window, supply a value of NULL for the root node parameter so that the user interface will be built from the top-level widget.

The invocation of alp_bundle_acquire_glade_xml() in line 46 causes the .glade file to be located and its contents parsed for eventual display. However, although you may have specified one or more signal handlers in your .glade file—as Hello World does when it named the onAboutMenu() function as the handler for the About menu's "activate" signal—alp_bundle_acquire_glade_xml() does not actually establish a connection between the signals defined in the XML file and the corresponding C functions. libglade provides a handy function—glade_xml_signal_autoconnect()—that looks at the current application's symbol table and matches the signal handler names given in the interface description with symbols in the application, connecting the signal when a match is found. This function takes a single argument: a pointer to a GladeXML structure. Conveniently, the alp_bundle_acquire_glade_xml() macro resolves to just such a pointer. The macro result is stored in the variable xml; other libglade functions also use this pointer, as you'll see in the next section.


NOTE: You may have noticed that the just concluded discussion of the alp_bundle_acquire_glade_xml() macro mentioned that it parsed the XML file's contents "for eventual display." The application's UI isn't actually drawn until control is passed back to GTK+. This is done when gtk_main() is called, in line 62.
The "Hello World" Portion of the Application

After some 53 lines of code (if you count comments and white space), we finally reach that portion of the application that is specific to Hello World. Although the code up to this point may seem like a lot, much of it is common from one ACCESS Linux Platform application to another. Menu handling, exit handling, launch code parsing, and GTK+/Glade initialization are common to nearly all ACCESS Linux Platform applications. Of course, many applications will respond to additional launch codes, most will handle additional menu items, and most will employ additional features of the ACCESS Linux Platform.

The heart of this version of Hello World is found in lines 54 to 60:


		// Now set our text string 
		textView = glade_xml_get_widget(xml, kTextView); 
		gtk_text_view_set_justification(GTK_TEXT_VIEW(textView), 
			GTK_JUSTIFY_CENTER); 
		gtk_text_view_set_pixels_above_lines(GTK_TEXT_VIEW(textView), 100); 
		buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textView)); 
		gtk_text_buffer_set_text(buffer, "Hello, World!", -1); 

Although somewhat more complex than a simple "printf" statement, it really is fairly simple. Line 55 obtains a pointer to the Text View widget in which we'll be displaying our text. Lines 56-57 aren't strictly required, but center the text horizontally within the text view. Note that once again a type-checking-and-casting macro is used to both ensure that textView really is a text view and to cast it to a pointer to GtkTextView (textView itself is declared in line 26 as a pointer to a more generic GtkWidget).

Some digging reveals that GTK+ doesn't provide a function equivalent to gtk_text_view_set_justification() for centering text vertically in a text view. Since doing the calculations to vertically center our text would unnecessarily complicate the application, we instead call gtk_text_view_set_pixels_above_lines() in line 58 to cause the "Hello, World!" string to be displayed close to the middle of the text view.

Lines 56 through 58 aren't strictly required, but they do improve the way the text is displayed on-screen. Lines 59 and 60 are the important ones. Line 59 obtains a pointer to the buffer displayed by the text view, and line 60 replaces the contents of the buffer with the string "Hello, World!".

Creating an Icon

Application icons as simply small4 images in any format that can be displayed by GTK+ (such as JPEG, GIF, PNG, or SVG). For those formats that can support it, your icon should have a transparency channel.

Among the applications that are included with Ubuntu is a copy of GIMP: the GNU Image Manipulation Program. Accessible from Ubuntu's Applications -> Graphics menu, this free program is designed along the lines of Adobe® Photoshop® and is ideal for creating icons. It lives on top of GTK+; in fact, GTK+5 was initially created solely as a replacement for Motif, the GUI toolkit that was originally at the foundation of GIMP.

There is extensive documentation on GIMP available from the GIMP website (http://www.gimp.org), from within the program itself, and even from your local bookstore. Accordingly, we will not go into how to use it to actually draw your icons. Simply ensure that your icons are an appropriate size and format, and be sure to place them in your project's rsc directory. In your manifest use the <icon>...</icon> tag pair to specify the path to the image file, relative to the bundle, as shown in Listing 3.2.

For the Hello World project, you can either create your own icon, or you can simply use the icon that is part of the basic project (appicon.png). Note that this default icon is referenced from the basic project's manifest; if you create your own icon and use a different icon name, you'll need to supply your icon name in your Manifest.xml file.

Creating the Manifest

Before you can construct the makefile and build your application, one additional piece is needed: the application's manifest.

On ACCESS Linux Platform, applications are packaged in bundles. A bundle is a concrete immutable lump of information which can contain an arbitrary amount of data in a format appropriate to that bundle. A manifest is an XML-format file named Manifest.xml that specifies a set of properties associated with the bundle.

Application manifests contain such information as:

  • The name of the application that is to be displayed in the Launcher.
  • The location and name of the application's icon.
  • Whether or not the application can run in the background.
  • The name of the application's main entry point.

There are a number of other properties that can be specified for an application in its manifest; see Appendix A, "Manifest File Reference," for a complete description of the structure and contents of a manifest file.

Listing 3.5  Manifest.xml (with line numbers added)


<?xml version="1.0" encoding="UTF-8"?> 
 
<!-- Basic App Manifest --> 
 
<manifest name="com.example.apps.basicapp"> 
รพ <application> 
รพรพรพ <name>Basic App</name> 
รพรพรพ <icon>appicon.png</icon> 
รพ </application> 
รพ <about> 
รพรพรพ <version>1.0</version> 
รพรพรพ <copyright>^t/Copyright (c) 2007 ACCESS Systems 
Americas, Inc. All rights reserved.</copyright> 
รพรพรพ <vendor>ACCESS Systems Americas, Inc.</vendor> 
รพ </about> 
</manifest> 

All bundles have an XML manifest, named Manifest.xml, that is stored at the top level of the bundle. This file contains important information about the contents of the bundle.

Lines 1-4 are ignored by the manifest file parser. The first line simply identifies this as an XML file and specifies the text encoding. Line 3 is a comment.

Line 5 is the opening tag for the manifest. It specifies the name of the bundle. Recall that application bundle names take the form com.yourCompany.apps.yourApp to ensure that the bundle name is unique. Thus, you should change this from the default ("example.basicapp") to something more appropriate for your application, as shown in Listing 3.5.

Line 6 is the opening tag for the "application" section of the manifest. It tells the system that the bundle contains an application, and will cause the application to appear in the Launcher.

Line 7 specifies the name to be displayed in the Launcher for this application.

Line 8 indicates the path to the icon displayed by the Launcher for this application. The path is relative to the bundle's resource (rsc) directory.

Line 9 is the closing tag for the application section.

Line 10 opens the "about" section, which contains information largely to be displayed in the application's About dialog.

Line 11 specifies the application's version number. This version number is displayed in the About dialog, and is also the version number applied to the application itself.

Line 12 specifies the copyright string to be displayed in the About dialog.

Line 13 specifies the application's vendor.

Line 14 is the closing tag for the about section.

Line 15 is the closing tag for the manifest.

Note that the name of the application executable is not specified. As long as the name of your application executable is of the form libalp_appname.so, where appname is the final component of the bundle name, you don't need to specify the name of the executable. In the case of the Hello World application, the complete name is com.access.apps.hello, and the name of the executable is of the specified form—libalp_hello.so—and thus doesn't need to be specified. (See the description of the <library> element in Appendix A,"Manifest File Reference," for a description of the tag used to specify a different executable name.)

Also note that applications normally specify an image to be displayed in the About dialog (see the description of the <logo> element in Appendix A,"Manifest File Reference," for a description of the tag used to specify this image). If you not specify your own image, an "ACCESS" company logo will appear in your About dialog.

Adding the Manifest to the Project

A manifest is simply a text file. If you have created your project using one of the Eclipse templates, your project already has a manifest file; simply double-click Manifest.xml in the C/C++ Projects tab of the Eclipse Navigation pane, and edit it as necessary.

If you have started with an empty project (by not specifying a template when you created the project), you can add a manifest by:

  1. In the C/C++ Projects tab of the Navigation pane, right-click on the project name.
  2. Select New->File.
  3. Specify the file name as "Manifest.xml" and click Finish.

    The file will be added at the root level of the project, and an empty text editor window will open, allowing you to edit the contents of the file.

  4. Type in the contents of your manifest. For this example, enter the text in Listing 3.5 (omitting the line numbers).
  5. Select File -> Save to save the contents of your manifest.

Writing the Makefile

The ACCESS Linux Platform application build environment is based on GNU Make (http://www.gnu.org/software/make/). Make controls the generation of your application bundles from the program's source files. Make relies upon a makefile for its knowledge of how to build your program. The makefile lists each of the non-source files and how to compute it from other files.


NOTE: At this time, alp-eclipse doesn't create or manage your makefiles for you. Accordingly, you need to manually create your own makefiles. Once you have done so, Eclipse will invoke make with your makefile whenever you instruct it to build your project.

There are many, many ways to write a makefile; there are whole books devoted to the subject. While you as an application developer are free to write your own, ACCESS has spent a good amount of time constructing makefiles that are optimized for ACCESS Linux Platform applications. You can capitalize on all of that work by simply copying and modifying a makefile from one of the samples for use in your own application projects.

Makefile Structure

Makefiles can be complex and difficult to read. To help application developers focus on just those settings that are likely to need changing, the makefile used by the ACCESS Linux Platform sample applications is broken into three files:

  • a makefile (named makefile) that specifies all of the important settings for your project.
  • a definitions file (make/defs.mk) that defines a number of variables that you usually don't need to change. For instance, this file names the directories that contain the source and resource files (src and rsc, respectively), plus it sets up a number of definitions needed to compile and link an ACCESS Linux Platform application.
  • a rules file (make/rules.mk) that contains the actual rules used to construct the various targets.

Figure 3.12 shows how your project should be structured (where my_project_dir is replaced by the name of your project).

Figure 3.12  Basic project layout


my_project_dir/ 
	Includes/ 
	build/ 
		build results go here  
	make/ 
		certificate 
		defs.mk 
		key 
		rules.mk 
	rsc/ 
		resource files go here 
	src/ 
		source files go here 
	makefile 
	Manifest.xml 

Makefile Contents

Listing 3.6 shows a Makefile for ACCESS Linux Platform version of the Hello World application. Following this listing is an explanation of the variables defined in this makefile.

Listing 3.6  Simple makefile


include make/defs.mk 
 
SOURCES รพรพรพรพรพรพรพ = appmain.c 
RESOURCES รพรพรพรพรพ = appicon.png hello.glade 
DEFINES รพรพรพรพรพรพรพ = 
INCLUDESย ย ย ย ย ย ย ย = 
LIBRARIES รพรพรพรพรพ = alp_appmgr alp_ui 
PACKAGES รพรพรพรพ ย ย = alp gtk+-2.0 libglade-2.0 
 
include make/rules.mk 

SOURCES
Here is where you specify the source files that make up your application. make/defs.mk specifies that your source files are all located relative to the project's src directory as shown in Figure 3.12. You can change this, if you want, by defining the SRC variable in your makefile.
RESOURCES
Like SOURCES, you use this variable to specify each of the resources that need to be included in your application's bundle, including images, sounds, any .glade files, any application-specific data files, and the like. The file make/defs.mk specifies that these resources are located relative to your projects rsc directory (see Figure 3.12). If you use a different layout and want to specify a different base directory for your resources, define the RSC variable in your makefile. Launcher icons and About dialog logos should be listed here.
DEFINES
Use this line to specify macro definitions to be passed to gcc. For instance, to define the FOO macro to have the variable BAR, do this:
DEFINES := FOO=BAR

This adds a -DFOO=BAR entry to the parameters supplied to gcc.

INCLUDES
Use this line to specify additional directories to be searched for header files. See gcc's -I option for specifics.
LIBRARIES
Here is where you specify some of the individual shared objects your application needs to have present in order to run. Not all shared libraries need to be listed here: some, such as the libraries that make up GTK+, needn't be listed individually. The ACCESS Linux Platform libraries (those prefixed with "alp_") that your application uses do need to be listed, however. See "Where are the Libraries, and Which Ones do I Need?" for tips on how to figure out just what should be included in your definition for LIBRARIES.
PACKAGES
Use this variable to list the library packages that your application uses. Most applications should list alp, gtk+-2.0, and, if they use Glade to specify their UI, libglade-2.0. If your application uses other technologies, such as SQLite, you'll need to add the appropriate package information file (sqlite3, for instance). See "Where are the Libraries, and Which Ones do I Need?" for more on package information files.

Building the Application

With all of the project files (source files, resource files, makefiles, and manifest) in place, building the project in Eclipse can be done one of several ways:

  • Right-click the name of the project in the C/C++ Projects pane, and select Build Project from the context-sensitive menu.
  • Click on the Build icon in the Eclipse toolbar:
  • Press Control+B.
  • Choose either Build All or Build Project from the Project menu.

Whichever you choose, Eclipse will build your project within Scratchbox and display the build progress in the Console pane, as shown in Figure 3.13.

Figure 3.13  Building an application in Eclipse

A successful build will result in the following be printed to the console:


Created build/alp-simulator/Debug/com.access.apps.hello.bar 
from folder build/alp-simulator/Debug/com.access.apps.hello/ 

Locating Errors in Your Source Code

Any errors will be listed in the console and identified by line number. (To turn on line numbering in Eclipse, Select Window->Preferences, then traverse to the General -> Editors -> Text Editors preference panel. Click the "Show line numbers" checkbox.)

The fact that there are errors in a source file is indicated by a white "X" in a small red box in the tab containing the filename (see Figure 3.14). The location of each error is indicated in the left margin by a white "X" in a red circle, and the line is underlined in red. To quickly navigate to errors and warnings, note the column just to the right of the vertical scrollbar in Figure 3.14: each red rectangle corresponds to an error, and each yellow rectangle corresponds to a warning. Click on a red or yellow rectangle, and the text editor will scroll to the corresponding point in the code. As well, simply "hover" over one of these small rectangles (that is, place your cursor over the rectangle and wait for a few seconds) and a yellow text box will appear containing the error message generated by the compiler.

Figure 3.14  Source code errors

It is important to note that linker errors can also be highlighted this way in your source files. If, for instance, you neglect to include a needed library in list defined for the LIBRARIES variable (as documented in "Makefile Contents"), all calls to functions implemented in that library will be so highlighted. Examine the console output: if near the end you see a line reading "collect2: ld returned 1 exit status", then the linker was unable to locate one or more functions. Of course, this could either be due to a misspelling in a function name, or it could be due to a missing library.

Running the Application

Once you have successfully built the application, it should be ready to run. You can run your application in either the Simulator or on compatible hardware, if available. Generally you'll do most of your work with the Simulator, and will only do final testing on hardware.

Start the Simulator

Although alp-eclipse will automatically start the Simulator for you if it is not already running, the xterm window it uses is not scrollable. As well, you can't supply startup options when you let alp-eclipse start the Simulator for you. Because of this, you may want to start it yourself. To start the Simulator manually, first open a new Terminal window and type:

alp-simulator

NOTE: There are a number of options that can be used when starting the Simulator; see "Using the Simulator" or type: alp-simulator --help

The alp-simulator script uses sudo. Accordingly, it may ask you for a password. Enter your login password at the prompt.

Next, it will display a long list of messages in your terminal window, and at one point a second window displaying the Simulator will open. Be patient! As of this writing, the Simulator boot sequence is quite lengthy and can take a minute or two to complete.

When you see the home screen in the Simulator, and once no more messages are appearing in your terminal window, make sure that your Terminal window has the focus and press Enter. You should see a welcome message, followed by a login prompt:


Welcome to your handheld device! Kernel 2.6.14.7-intcl-bs3 - (/dev/console) 
 
 
ALP-Device login:  

Type the word "root" and press Enter.

You can now use various Linux shell commands to examine and manipulate the Simulator. For instance, the "ps" command lists the processes that make up the Simulator. The "halt" command is useful: it kills the Simulator.


TIP: Be sure to select the terminal window before entering any such commands. If the window containing the Simulator has the focus, any keystrokes you enter will be sent to the primary application running in the Simulator.
Create a Launch Configuration

Before you can run your application, you must first create a launch configuration. A launch configuration specifies all aspects of program execution: the project to run, the target, the files that need to be copied to the target, which debugger to use (for debug targets), and so on. You will likely create multiple launch configurations for a given application. For instance, you might create one that runs your application using the debugger on the Simulator, and one that runs a release version of your application on a device