Other alternatives for application development
This is a great place for getting started with Moblin development. This page describes how to create a simple application and introduces a few useful tools to help quick start your development efforts.
Note: This is not a Linux software development tutorial. It is assumed that you already know how to develop software in Linux, including using <your favorite editor>, gcc and gdb, Makefiles, compiling, and debugging.
Moblin Compliance and Applications
Moblin Compliance is a program to improve application compatibility across distributions, by aligning the libraries and library versions that OSVs include in their distributions. When developing an application, you are encouraged to use the libraries and versions that are included in the pre-built development images. Doing so, will make sure that your application will run with minimal changes on all Moblin compliant distributions.
System Requirements
This tutorial assumes you have the following:
- Any recent, mainstream Linux distribution with standard development tools
- (optional) netbook or MID is recommended, but not required
- (optional) A PC with Intel graphics chipset is required to install the Moblin v2 ISO image (most Netbooks have this)
Sample Project Code
A simple Clutter application will be used for this tutorial. Code explained here.
Development Environments
There are a variety of ways to set up your development environment. We describe two.
- Develop on your Linux workstation with an occasional remote validation and debugging task on a target device.
- Develop within a Moblin v2 environment using a platform such as a netbook.
or
Eventually, you will likely do some development in both types of environments. Here is a short comparison:
| Developing on Linux workstation | Developing in Moblin v2 environment | |
| Benefits |
|
|
| Drawbacks |
|
|
Option 1: Developing on Linux Workstation
Most development can take place on a recent, mainstream distribution, such as Ubuntu 8.04, Fedora 9, or newer that has standard development tools
Install or Update development packages
One of the biggest tasks is to align the version of the development libraries that your application needs to those found on Moblin v2 Library list. If you do not do this, then you risk incompatibilities when you try to run your application on a Moblin-compliant distribution. Given that today there are no Moblin-compliant distributions, in most cases you will need to get the new version from upstream, either as a package (if the upstream provides it) or as source that you download, build, and install.
In our tutorial, we depend on clutter v0.9. Eventually v1.0 will be released and part of standard distributions, but for now we have to download the bleeding edge upstream source and install it ourselves. Knowing how to do this in general will empower you to be able to get any version of library or app. Please follow the steps in Building and Installing Clutter from Source.
Running project in Moblin v2 environment
At this stage you can continue with most application development tasks, compiling, running, and debugging your application. Occasionally (early is recommended), you should run your application inside a Moblin v2 environment. Additionally, you will want to understand how to remotely debug your application running on a netbook or in a virtual environment from your workstation.
Option 2: Developing in Moblin v2 Environment
You can develop applications directly in the Moblin v2 environment.
- Download and start up a development image (running on a netbook).
- Inside the Moblin v2 environment, install the standard development tools.
- In a terminal on your Linux workstation, copy your project source to the Moblin v2 image.
(in terminal outside the Moblin v2 environment)
$ scp -r ./clutter_hw <ip addr of Moblin v2 system>:/<directory to place source in> - Build, install, and run your project. See next section (this is the same as if you are developing on your workstation).
Download, Build, and Run Project
In our development environment (whether workstation or Moblin v2 environment), we can now build the sample project.
$ git clone git://git.moblin.org/moblin-sdk-examples
$ cd moblin-sdk-examples/examples/apps/helloworld
$ ./autogen.sh
$ make
(optionally install -- see comments below)
$ sudo make install"make" above creates the binary and places it in the ./src directory. We can run it there without installing the application
$ ./src/clutter-helloworld![]()
"make install" (run as root) installs the binary into /usr/local/bin and registers the application to appear in the standard system menu, under "Other" category. The program is now in your path and can be run from any location
$ clutter-helloworldProject Features / Recommendations
The following aspects of the sample project should exist in all projects:
- Moblin v2 Libraries: Link with the libraries and versions found in the Moblin v2 Library list.
- autoconf: Use the autoconf system. Setting this up can be challenging. Full documentation is here.
- menu registration: Follow the freedesktop.org standard for application menu registration. Full documentation is here.
- Internationalization: Internationalize your application so that it can be localized in different languages. See the Internationalization getting started page. Full documentation is here.
- Docbook documentation: Use gtk-doc (or doxygen) style comments around your APIs for auto-html-format API generation. See API Doc Generation getting started page.
- Packaging: Package your application as RPM and DEB for easy installation on all Moblin compliant distributions.
Linux Project Generator
Often just getting an initial project started with all of the appropriate components is time consuming. To help quickstart this process, see Linux Project Generator.
Next Steps
Now that you have set up the basic development environment, the following links may be useful. Welcome to Moblin development!
| Linux Project Generator | Generate an autogen-based project template for your new application or library |
| API reference | The APIs for the primary application libraries |
- Printer-friendly version
- Login or register to post comments
Comments (10 total)
problem installing sample_apps in Moblin 2.1
Just realized how stupid I am :-) I was using the wrong image. Problem solved.
-----------
Hi,
I just installed Moblin 2.1 on my HP mini 1000 ( went smoothly, except for a broadcom WiFi driver that gave me a bit of work ).
I am now trying to install the moblin sample_apps, but can't even go past the autoconf stage. Package Clutter-1.0 appears to be missing. Running a "clutter.h" file search, does not return any link...
Did anyone else have the same pb ?
Stephane
Missing clutter-helloworld.c from the latest update
Hi Bob,
I was trying to get the sample app but the latest update for 1.0 is missing the clutter-helloworld.c file.
http://git.moblin.org/cgit.cgi/sample_apps/
Can you please help on that.
Problem installing Projgen
Hi,
Iam having problem while installing projgen. Following is the error what I get while installing.
Steps followed are;-
1. ./autogen.sh --prefix=/usr --enable-gtk-doc
2. sudo make install
make install-data-hook
make[3]: Entering directory `/home/ic001252/projgen-master/libprojgen'
/usr/share/projgen
/bin/bash: /usr/share/projgen: No such file or directory
make[3]: *** [install-data-hook] Error 127
make[3]: Leaving directory `/home/ic001252/projgen-master/libprojgen'
make[2]: *** [install-data-am] Error 2
make[2]: Leaving directory `/home/ic001252/projgen-master/libprojgen'
make[1]: *** [install-am] Error 2
make[1]: Leaving directory `/home/ic001252/projgen-master/libprojgen'
make: *** [install-recursive] Error 1
«API reference» link points
«API reference» link points to current page (http://moblin.org/documentation/moblin-sdk/create-new-application). This is mustake, i think.
I modified the helloworld to print chinese(just utf-8) for fun.
#include <clutter/clutter.h>
#include <stdlib.h>
#include <string.h>
#define SCN_WIDTH 800
#define SCN_HEIGHT 480
//const char *MAIN_STR = "GNU 汉字";
const char *MAIN_STR = "春江花月夜";
const char *TEXT_FONT = "Courier Bold 170px";
const int FONT_SIZE = 170;
const guint32 colors[] = {0xFF0000FF/*red*/, 0x00FF00FF/*green*/,
0x0000FFFF/*blue*/, 0xFFFF00FF/*yellow*/,
0xFF00FFFF/*pink*/, 0x00FFFFFF/*teal*/,
0xFF8000FF/*orange*/, 0xFFFFFFFF/*white*/};
const int NUM_COLORS = 8;
// Return the next color in the colors[] array
ClutterColor *get_next_color ()
{
static int i=0;
ClutterColor *cc = malloc (sizeof (ClutterColor));
clutter_color_from_pixel (cc, colors[i++]);
if (i > (NUM_COLORS-1)) {
i=0;
}
return cc;
}
gulong get_rand_animation()
{
int r = rand()%11;
switch (r) {
case 0: return CLUTTER_EASE_IN_OUT_QUAD;
case 1: return CLUTTER_EASE_IN_OUT_CUBIC;
case 2: return CLUTTER_EASE_IN_OUT_QUART;
case 3: return CLUTTER_EASE_IN_OUT_QUINT;
case 4: return CLUTTER_EASE_IN_OUT_SINE;
case 5: return CLUTTER_EASE_IN_OUT_EXPO;
case 6: return CLUTTER_EASE_IN_OUT_CIRC;
case 7: return CLUTTER_EASE_IN_OUT_ELASTIC;
case 8: return CLUTTER_EASE_IN_OUT_BACK;
case 9: return CLUTTER_EASE_IN_OUT_BOUNCE;
default: return CLUTTER_LINEAR;
}
}
gint get_rand_option (gint opt1, gint opt2, gint opt3)
{
gint num = rand()%3;
if (num==0) {
return opt1;
} else if (num==1) {
return opt2;
} else {
return opt3;
}
}
// Each time the frame is painted, shade or lighten the coloring
void on_new_frame (ClutterTimeline *tl,
gint frame_num,
gpointer data)
{
static gboolean get_darker = TRUE;
ClutterActor *actor = CLUTTER_ACTOR(data);
ClutterColor *orig_color = g_object_get_data (G_OBJECT (actor), "color");
gint color_adj = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(actor),
"color_adjustment"));
if (get_darker) {
color_adj --;
if (color_adj < -100) {
color_adj = -100;
get_darker = FALSE;
}
} else {
color_adj += 1;
if (color_adj > 0) {
color_adj = 0;
get_darker = TRUE;
}
}
gdouble scale = 1.0+(0.005*(gdouble)color_adj);
ClutterColor c;
clutter_color_shade (orig_color, scale, &c);
clutter_text_set_color (CLUTTER_TEXT(actor), &c);
g_object_set_data (G_OBJECT (actor),
"color_adjustment",
GINT_TO_POINTER(color_adj));
}
ClutterActor *create_new_character (char *wstr, int xpos, int ypos)
{
ClutterActor *actor;
ClutterColor *color;
//*(wstr+strlen(wstr)) = '\0';
color = get_next_color();
//printf("%s\n",wstr);
actor = clutter_text_new_full (TEXT_FONT, wstr, color);
clutter_actor_set_position (actor, xpos, ypos);
//Setup animation
ClutterTimeline *timeline;
timeline = clutter_timeline_new (360, 60); //num frames, fps
clutter_timeline_set_loop (timeline, TRUE);
//Create animation behavior (rotations)
ClutterAlpha *alpha;
ClutterBehaviour *behaviour;
alpha = clutter_alpha_new_full (timeline, get_rand_animation());
behaviour = clutter_behaviour_rotate_new (alpha,
get_rand_option(CLUTTER_X_AXIS,
CLUTTER_Y_AXIS,
CLUTTER_Z_AXIS),
CLUTTER_ROTATE_CW,
0.0, 360.0);
clutter_behaviour_rotate_set_center (CLUTTER_BEHAVIOUR_ROTATE (behaviour),
FONT_SIZE/2, FONT_SIZE/2, 0);
clutter_behaviour_apply (behaviour, actor);
g_signal_connect (timeline, "new-frame", G_CALLBACK (on_new_frame), actor);
clutter_timeline_start (timeline);
//save variables for later destruction
g_object_set_data (G_OBJECT (actor), "color", color);
g_object_set_data (G_OBJECT (actor), "color_adjustment", GINT_TO_POINTER(0));
g_object_set_data (G_OBJECT (actor), "timeline", timeline);
g_object_set_data (G_OBJECT (actor), "alpha", alpha);
g_object_set_data (G_OBJECT (actor), "behaviour", behaviour);
return actor;
}
static gboolean key_pressed_cb (ClutterStage *stage,
ClutterEvent *event, gpointer data)
{
if (event->type == CLUTTER_KEY_RELEASE) {
ClutterKeyEvent *kev = (ClutterKeyEvent *) event;
guint symb = clutter_key_event_symbol (kev);
if (symb == CLUTTER_Escape || symb == CLUTTER_q) {
clutter_main_quit ();
return TRUE;
}
}
return FALSE;
}
int w_of_utf8 (unsigned char c)
{
//unsigned char c;
//c = (unsigned char)s;
//printf("c=%d ",c);
if (c <= 0x7F) /* 01111111B */
return 1;
else if (c <= 0xDF) /* 11011111B */
return 2;
else if (c <= 0xEF) /* 11101111B */
return 3;
else
return 4;
}
int main (int argc, char **argv)
{
const ClutterColor scn_bkgd = {0x33,0x33,0x33,0x33}; //{0x00,0x00,0xFF,0xFF};
ClutterActor *stage;
srand(time(NULL)); //for random colors
clutter_init(&argc, &argv);
//create stage, make fullscreen, set colors
stage = clutter_stage_get_default();
// 让 stage 全屏
clutter_stage_fullscreen (CLUTTER_STAGE(stage));
guint scn_width = SCN_WIDTH, scn_height = SCN_HEIGHT;
// 全屏后 stage 的宽和高值
clutter_actor_get_size (stage, &scn_width, &scn_height);
clutter_actor_set_size(stage, scn_width, scn_height);
clutter_stage_set_color (CLUTTER_STAGE(stage), &scn_bkgd);
// 全屏后看不见下面设置的 title 了
clutter_stage_set_title(CLUTTER_STAGE(stage), "Clutter Helloworld");
//show MAIN_STR ('Hello World') and animate
gint num_actors = 0;
ClutterActor *actor;
ClutterActor *arrActors[strlen(MAIN_STR)];
gint xpos = (scn_width - (FONT_SIZE/3 * strlen(MAIN_STR)))/2;
int i=0,j=0,w=1;
char wstr[6];
for (i=0; i<strlen(MAIN_STR); i += w) {
if (MAIN_STR[i]==' ') {
xpos += FONT_SIZE/3;
w = 1;
continue;
}
w = w_of_utf8(MAIN_STR[i]);
//printf("%d ",w);
for (j=0;j<w;j++)
wstr[j] = MAIN_STR[i+j];
wstr[j]='\0';
actor = create_new_character (wstr, xpos,
(scn_height-FONT_SIZE)/2);
arrActors[num_actors++] = actor;
clutter_container_add_actor (CLUTTER_CONTAINER (stage), actor);
if (w <= 2)
xpos += FONT_SIZE/3;
else
xpos += FONT_SIZE; // 现在中文显示漂亮了!
}
clutter_actor_show_all (stage);
// ESC exits
g_signal_connect (stage, "key-release-event",
G_CALLBACK (key_pressed_cb), arrActors);
clutter_main ();
return EXIT_SUCCESS;
}
Fails to compile
Following the above steps, while make-ing I get this
[moblin@localhost sample_apps]$ make
make all-recursive
make[1]: Entering directory `/home/moblin/sample_apps'
Making all in src
make[2]: Entering directory `/home/moblin/sample_apps/src'
gcc -DHAVE_CONFIG_H -I. -I.. -pthread -I/usr/include/clutter-0.9 -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/gtk-2.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -Wall -Werror -g3 -O0 -ggdb -DPKGDATADIR="\"/usr/local/share/sample_apps\"" -g -O2 -MT helloworld.o -MD -MP -MF .deps/helloworld.Tpo -c -o helloworld.o helloworld.c
helloworld.c: In function ‘on_new_frame’:
helloworld.c:118: error: incompatible type for argument 2 of ‘clutter_color_shade’
helloworld.c:118: error: incompatible type for argument 3 of ‘clutter_color_shade’
make[2]: *** [helloworld.o] Error 1
make[2]: Leaving directory `/home/moblin/sample_apps/src'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/home/moblin/sample_apps'
make: *** [all] Error 2
Same error occurred in my computer too.
Help !! Why?
instruction above not correct...
above,
$ ./src/clutter-helloworld
i found incorrect,
$ ./src/helloworld
was the file actually built.
ymmv, hth, jackc..
Installing of Moblin image
Hi,
I am trying to install Moblin on my PC which has the following configuration.
Microsoft XP - Service Pack 2
Hope Edition.
AMD Athlon XP 3000
2.1 GHz
1GB RAM.
Can I install the image for this config?
Haran
Maybe -- try the live image.
Maybe -- try the live image. Do you want to test-drive Moblin using VMWare in Windows, or do you want to replace Windows XP with Moblin? If the latter, then I would recommend first using a live image on a USB drive to verify that it can boot and function correctly before you install it. Our focus has been on Intel Atom-processor-based mobile devices that have Intel graphics chipsets. Your mileage may vary.