HowToWriteAMonoApplication

How to Write a Mono Application for the Nokia 770

Writing your own Mono applications and running it on the Nokia 770 is pretty easy, especially if you are familiar with Java or C#.

Prerequisites

You will have to gain root access to your Nokia 770: HowDoiBecomeRoot

You will have to install xterm from the ApplicationCatalog (the gui mono application below can only be started using xterm)

Find yourself a c# editor

As I'm on Linux I'm using: http://www.monodevelop.com. Monodevelop is a promising project but on my machine has a tendency to crash a little when doing intellisense (so save often).

Write yourself a gui program

In monodevelop create a new GTK#2.0 solution (name the solution Converter). This automatically creates two classes for Main.cs and MyWindow.cs. In this example I've changed MyWindow.cs only. The code listing for MyWindows.cs is for a simple temperature converter (from celcius to farenheit)

using System;
using Gtk;

public class MyWindow : Window
{   
    //labels are readonly text widgets
    Label farenheitLabel = new Label("farenheit");
    Label celciusLabel = new Label("celcius");

    //entries are editable text widgets
    Entry farenheitEntry = new Entry();
    Entry celciusEntry = new Entry();
    
    //vbox is a container for widgets that organises things vertically
    VBox vbox = new VBox();
    
    //hbox, similar to vbox but horizontal
    HBox farenheitHBox = new HBox();
    HBox celciusHBox = new HBox();
    
    public MyWindow () : base ("Temperature Converter")
    {
        //Set config for the main window
        this.SetDefaultSize (400, 100);
        
        Console.WriteLine("Write a debug message to the console");
        
        //Pack the widgets (place them on the window)
        this.Add(vbox);
        vbox.Add(farenheitHBox);
        vbox.Add(celciusHBox);
        farenheitHBox.Add(farenheitLabel);
        farenheitHBox.Add(farenheitEntry);
        celciusHBox.Add(celciusLabel);
        celciusHBox.Add(celciusEntry);
        
        //Hook up delegate methods to events 
        //(when the event occurs the method you specify with += will get called)
        this.DeleteEvent += OnMyWindowDelete;
        farenheitEntry.Changed += farenheitChanged;
        celciusEntry.Changed += celciusChanged;
        
        this.ShowAll ();
        
    }
    
    void farenheitChanged (object sender, EventArgs a) {
        
        Console.WriteLine("farenheitEntry has changed");
        //we need to temporarily remove the change event so that the two text boxes
        //don't try to recursively update themselves
        celciusEntry.Changed -= celciusChanged;
        
        try {
            float val = (float.Parse(farenheitEntry.Text) -32) * 5 / 9;
            celciusEntry.Text = val.ToString();
        } catch (FormatException e) {
            Console.WriteLine(e);
            celciusEntry.Text = "bad format";
        }
        celciusEntry.Changed += celciusChanged;
    }
    
    void celciusChanged (object sender, EventArgs a) {
        Console.WriteLine("celciusEntry has changed");
        
        //we need to temporarily remove the change event so that the two text boxes
        //don't try to recursively update themselves
        farenheitEntry.Changed -= farenheitChanged;
        
        try {
        
            float val =  (float.Parse(celciusEntry.Text) + 32) * 9/5;
            farenheitEntry.Text = val.ToString();
        } catch (FormatException e) {
            Console.WriteLine(e);
            farenheitEntry.Text = "bad format";
        }
        farenheitEntry.Changed += farenheitChanged;

    }
    
    //This is required so that the process closes when this window closes
    void OnMyWindowDelete (object sender, DeleteEventArgs a)
    {
        Application.Quit ();
        a.RetVal = true;
    }
}

You will still need the Main.cs class (unless you move the main method to the MyWindow.cs class):

using System;
using Gtk;

class MainClass
{
    public static void Main (string[] args)
    {
        Application.Init ();
        new MyWindow ();
        Application.Run ();
    }
}

Test and package the program

In monodevelop you test/launch the program by pressing F5. You package the application by pressing F8. In monodevelop this creates a Converter.exe file in the /bin/debug/ directory.

This program can be run outside of the development environment by typing: mono Converter.exe

Copy the mono environment to your Nokia 770

The mono environment can be obtained from here: http://www.mono-project.com/Mono:ARM the mono-nokia.tgz file is a zipped up tarball that contains the binaries for mono for the Nokia 770.

Save the mono-nokia.tgz file to a directory on your Nokia 770 (make sure its not on /media/mmc).

Configure the mono environment

The next 2 paragraph of instructions requires that you have installed and opened an xterm window and have gained root access.

I'm assuming you have created a directory called /home/mono and copied the mono-nokia.tgz file here. Type the 'gzip -d Nokia.tgz' to unzip the file. You should now see a file called mono-nokia.tar. Now unpack the tar using 'tar xvf mono-nokia.tar'. You should be able to navigate to /usr/mono/mono-nokia. There is a file in here called readme, not only should you read it but you should run it as it sets up some PATH variables that allows mono to run. This can be run using '. ./readme' (please note the first dot followed by a space is required).

Next you can copy your Converter.exe to /home/mono/mono-nokia. If you try to run the application using './mono Converter.exe' you will see one of two errors - if it complains about missing dlls you have probably not run '. ./readme' correctly (or you are using mono packages not installed on the Nokia - more on that later). Hopefully the error message you will see will be something like 'the sapwood server is not running'. Apologies for being vague here but I think I may have just typed 'sap' to start it (from the error message it's easy to guess how to start it). Now that the sapwood thingy is started you can run your application './mono Converter.exe'

Writing more complex apps

I compiled sqlite (a very small but powerful database) using the scratchbox toolkit (if you want to learn how to compile a useful app using scratchbox then sqlite is a good one to try - otherwise you can download the deb from here:http://www.owenwilliams.plus.com/maemo/). This database can be used from your Mono application - but you must copy more mono dlls into your /home/mono/mono-nokia directories. The following dlls were copied from my ubuntu filesystem:

/usr/lib/mono/gac/Mono.Data.SqliteClient/1.0.5000.0__0738eb9f132ed756/Mono.Data.SqliteClient.dll
/usr/lib/mono/gac/System.Data/1.0.5000.0__b77a5c561934e089/System.Data.dll

Your help wanted

Any one know how to make these apps appear in Nokia 770 menus?

Also the app can easily get hidden behind the 'Nokia Home app' and because it doesn't appear in the 'running applications' list it isn't possible to return focus to it. Anyone know a solution?

Happy coding !

And a big thanks goes out to whoever put the binaries on http://www.mono-project.com and the people who are working on the Hildon GTK bindings at http://maemo.ndesk.org/