Click here to Skip to main content
Click here to Skip to main content
Go to top

Develop a Mono application for the XO laptop

, 21 Apr 2009
Rate this:
Please Sign up or sign in to vote.
Learn how to develop an application for the XO laptop - the OLPC project's machine - using Mono on Sugar OS
This is an old version of the currently published article.

Abstract

This article will learn you how to develop an application for Sugar and the XO, the OLPC project machine. More precisely, In this article, I will use C# and Mono to create a new "activity" which works on the XO and on the Sugar emulator included in the downloadable virtual machine.

Introduction

About the OLPC project and the XO

One Laptop per ChildThe XO laptopSugar ArchitectureSugar desktopMonoA sample in MonoTorello Querci is a contributor on the Mono project. Torello wrote one year ago a C#/Sugar binding to let you use Mono to create Sugar Activities. This binding is packaged as a .NET assembly named Sugar.dll. Most of Sugar API is callable from this assembly. Of course, the Sugar.dll assembly is need for the sample described here.

Create the project

To create our first activity, we're going to use MonoDevelop. MonoDevelop is a Visual Studio like IDE. So MonoDevelop let you edit and package a Mono application.

Let's start:

  • Launch MonoDevelop (Applications/Programming/MonoDevelop),
  • Create a new solution (File/New Solution…) Choose a "C# / Gtk# 2.0 Project" template,
  • Fill the form with "LabActivity" as name.

Choose a template in M/></p>

<p>We're using the Gtk# template because Sugar is based on Gtk. Let's now configure this solution to add the Sugar binding.</p>

<p>We just need to add the <code>Sugar.dll</code> assembly. Right click on References, "Edit References…", choose the ".Net Assembly" sheet and select the right assembly. </p>

<p align=Add the Sugar assembly as referenceusing System; using System.Collections; using Gtk; using Sugar; namespace LabActivity { public class MainWindow : Sugar.Window { public new static string activityId = ""; public new static string bundleId = ""; public MainWindow(string activityId, string bundleId) : base("Lab", activityId, bundleId) { this.SetDefaultSize(400, 400); this.Maximize(); this.DeleteEvent += new DeleteEventHandler(OnMainWindowDelete); VBox vbox = new VBox(); vbox.BorderWidth = 8; Label _text = new Label("Hello Lab Activity"); vbox.Add(_text); Button _button = new Button(); _button.Label = "Quit"; _button.Clicked += new EventHandler(OnClick); vbox.Add(_button); this.Add(vbox); ShowAll(); } void OnMainWindowDelete(object sender, DeleteEventArgs a) { Application.Quit(); a.RetVal = true; } void OnClick(object sender, EventArgs a) { Application.Quit(); } } }

If you are a .NET WinForm developer, the Gtk framework should look familiar to you.

The MainWindow's constructor is responsible of the window initialization: it creates controls and setup event handlers. The Sugar binding adds the need to inherit from the Sugar.Window class to access to the low level communication with the Sugar API. More precisely, the main Window should handle the activity's identifier and the instance's identifier. Both values are send to the window manager and should be retrieve from the activity entry point. Here's how:

    public static void Main(string[] args)
    {
        if (args.Length > 0)
        {
            IEnumerator en = args.GetEnumerator();
            while (en.MoveNext())
            {
                if (en.Current.ToString().Equals("-sugarActivityId"))
                {
                    if (en.MoveNext())
                    {
                        activityId = en.Current.ToString();
                    }
                }
                if (en.Current.ToString().Equals("-sugarBundleId"))
                {
                    if (en.MoveNext())
                    {
                        bundleId = en.Current.ToString();
                    }
                }
            }
        }

        Application.Init();
        new MainWindow(activityId, bundleId);
        Application.Run();
    }

We can now build and run the new application: click on "Project/Run". You should obtain this:

Our sample activity on UbuntuA Mono bundleOur sample activity on UbuntuActivities page of the OLPC wiki, you could find all activities downloadable on the XO laptop.

The following screen capture shows a small part of this page. As you could see, downloading a new activity means downloading a .XO file. Let's see what is a ".xo" file and how we can generate this sort of file ?

Activities on OLPC wiki2.so bin/libgladesharpglue-2.so bin/libglibsharpglue-2.so bin/libgtksharpglue-2.so bin/libMonoPosixHelper.so bin/libpangosharpglue-2.so bin/labactivity-activity bin/labactivity.exe bin/uiX11Util.so

The manifest file describes all files in the .XO file. The .XO file has two directories: activity which hold activity's properties and bin which hold binary files.

Binary files are: Mono bundle for the activity (labactivity.exe), Gtk# shared libraries (.so files) and a python script to start activity (labactivity-activity).

The first file in the activity directory is the activity's icon. This file use the SVG format. SVG is a vectorial format based on XML. The SVG file used here just draws a little square:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
  <!ENTITY stroke_color "#666666">
  <!ENTITY fill_color "#FFFFFF">
]>

Another important file is the activity.info file. This file contains all properties for the activity. Here is our file:

                [Activity]
                name = LabActivity
                activity_version = 1
                host_version = 1
                service_name = org.olpcfrance.LabActivity
                icon = activity-labactivity
                exec = labactivity-activity
                mime_types =

The activity.info file is just a text file containing values for each property: name, id, link to the icon file, link to the start script, ...

So, as a conclusion, to create the .xo file you should:

  • Launch the build for the Mono application,
  • Create a Mono bundle,
  • Build a .zip file with all binaries and config files,
  • Rename the file from .zip to .xo.

The deploy script included with the source file of the project build automatically the .XO file. You should launch it at the end of each build. At the end of the script, a LabActivity-1.xo is generated:

Generating XO fileSugar emulator shortcutSugar homepage in the emulatorInstalling activitySample activity on the desktopOur activity in SugarGbrainy application. Gbrainy is a collection of little games based on memory. The following screen capture shows you the application on the XO.

Gbrainy in SugarGlade is a window design tool for Gtk. Glade comes with a dedicated designing tool and use a file format based on XML to store resources.

Gettext is the localization tool for Gnome. The Mono.Unix namespace allow call to Gettext from your C# application. Note that both Gettext and the standard localization mechanism of .NET are usable from Mono. The main advantage of Gettext is to be supported by a large community of developers and to be compliant with lot of common tools like the Pootle server or the Poedit editor.

The following source code comes from the Sugarized Gbrainy application. You could see: the Sugar features, the use of Glade properties ([Glade.Widget]) and some calls to localization methods (Catalog.GetString(...)).

public class gbrainy
{
        [Glade.Widget("gbrainy")] Gtk.Window app_window;
        [Glade.Widget] Box drawing_vbox;
        [Glade.Widget] Gtk.Label question_label;
        [Glade.Widget] Gtk.Label solution_label;
        [Glade.Widget] Gtk.Entry answer_entry;
        [Glade.Widget] Gtk.Button answer_button;
        [Glade.Widget] Gtk.Button tip_button;
        [Glade.Widget] Gtk.Button next_button;
        [Glade.Widget] Gtk.Statusbar statusbar;
        [Glade.Widget] Gtk.Toolbar toolbar;
        GameDrawingArea drawing_area;
        GameSession session;
        const int ok_buttonid = -5;
        ToolButton pause_tbbutton;    
        string activityId="";
        string bundleId="";
 
        public gbrainy (string [] args, params object [] props) 
        {
              Catalog.Init ("gbrainy", Defines.GNOME_LOCALE_DIR);
              IconFactory icon_factory = new IconFactory ();
              AddIcon (icon_factory, "math-games", "math-games-32.png");
              AddIcon (icon_factory, "memory-games", "memory-games-32.png");
              AddIcon (icon_factory, "pause", "pause-32.png");
              AddIcon (icon_factory, "resume", "resume-32.png");
              AddIcon (icon_factory, "endgame", "endgame-32.png");
              AddIcon (icon_factory, "allgames", "allgames-32.png");
              AddIcon (icon_factory, "endprogram", "endprogram-32.png");
              icon_factory.AddDefault ();

              Glade.XML gXML = new Glade.XML (null, "gbrainy.glade", "gbrainy", null);
              gXML.Autoconnect (this);
              Sugar.Activity activity=new Sugar.Activity(app_window, activityId, bundleId);
              activity.SetActiveEvent += activeChanged;

              app_window.Show();

              toolbar.IconSize = Gtk.IconSize.Dnd;
                
              Tooltips tooltips = new Tooltips ();

              ToolButton button = new ToolButton ("allgames");
              button.SetTooltip (tooltips, Catalog.GetString ("Play all the games"), null);
              button.Label = Catalog.GetString ("All");
              button.Clicked += OnAllGames;
              toolbar.Insert (button, -1);
                               
              // ...
      }

      // ...
}


Conclusion

This article is an introduction to Sugar development using Mono. Mono allows you to use your .NET and C# skill to create software for the XO laptop, to contribute to the OLPC project and then to provide educative material for the world's poorest children. Why don't take this chance ?

Links

This article comes from a full tutorial on the SugarLabs wiki. A French version is also available on the TechHead Brothers web site. Do not hesitate to contact me for more information on the OLPC project.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Lionel LASKE
Architect C2S
France France
Lionel is a software architect at C2S, a software company based in France and subsidiary of the Bouygues group.
Lionel is also the author of Liogo, an open-source Logo compiler for .NET.
Lionel is a contributor of DotNetGuru and Dr.Dobb's Journal.
Lionel is President and co-founder of OLPC France.

Comments and Discussions


Discussions posted for the Published version of this article. Posting a message here will take you to the publicly available article in order to continue your conversation in public.
 
QuestionSharing the activity Pinmemberoptimus_prime127-Sep-10 2:07 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.140922.1 | Last Updated 21 Apr 2009
Article Copyright 2009 by Lionel LASKE
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid