Novell Home

Mono, Gtk#, Gecko# and the Gecko Runtime Environment on Windows

Novell Cool Solutions: Feature
By Simon Nattrass

Digg This - Slashdot This

Posted: 18 May 2005
 

Abstract

Mono is an exciting new open source development platform based on the .NET framework enabling developers to build platform agnostic applications.

This document focuses on recent developments in porting Gtk# and Gecko# – previously Linux specific components of Mono, onto the Windows platform.

Gtk# is a .NET binding to the popular Gimp Tool Kit (Gtk+) SDK for the development of graphical applications on the desktop. While Gecko# leverages the Gecko Runtime Environment (GRE) providing the embedding of Mozilla's Gecko engine into new applications. Together these two recent additions to Mono for Windows show great potential for cross platform graphical desktop development.

Contents
  1. The "Browser Example"
  2. Installing Mono on Windows
  3. Install the Gecko Runtime Environment (GRE) for Gecko#
  4. Install Gecko#
  5. Rebuild the Code
  6. Execute

The "Browser Example"

The Mono "browser example" is a popular choice for developers wishing to understand how Mono GUI development all hangs together. This example combines drag and drop GUI creation in the Glade GUI builder, coding in the MonoDevelop IDE and uses the Mozilla embedded libraries to create a simple web browser application. Until recently this example has been restricted to the Linux platform.

Typically the solution code (excluding the interface created with Glade) will look something like the following:

using System;
using Gtk;
using Glade;
using Gecko;

public class WebBrowser
{
     [Widget] Entry urlEntry;
     [Widget] Frame frame1;
     
     WebControl web;
          
     public static void Main(string[] args)
     {
          new WebBrowser(args);
     }

     public WebBrowser(string[] args) 
     {
     Application.Init();

         Glade.XML gxml = new Glade.XML(null, "gui.glade",
                                          "browserMainWnd", null);
          gxml.Autoconnect (this);
               
         web = new WebControl();          
         web.Show();
         frame1.Add(web);
         urlEntry.Activated += OnLoadUrlEvent;
          
         Application.Run();
     }

     // Connect the Signals defined in Glade 
     public void OnWindowDeleteEvent (object o, DeleteEventArgs args) 
     {
     Application.Quit ();
          args.RetVal = true;
     }
     public void OnLoadUrlEvent (object o, EventArgs args)
     {
     web.LoadUrl(urlEntry.Text);
     }
}

The finished application should look similar to:



Installing Mono on Windows

The first step is go put the Mono environment on Windows. "Mono on Windows?" you say?! Well yes! – as Mono is a cross-platform open source development environment there is indeed a distribution for the Windows platform and it may be downloaded from the Mono project web page.

The current stable version (1.1.4) includes Gtk# (1.9.2), so we don't need to install this separately.

Once installed, it's wise to create a MONO_HOME environment variable and place %MONO_HOME%/bin in the PATH.

With the PATH configured, open up a command prompt and check that Mono has installed correctly with mono --version

An alternative to the standard Window Mono installer is the "combined" installer from the Mono Windows Integration website which includes the Gecko# assemblies and an experimental version MonoDoc.

Install the Gecko Runtime Environment (GRE) for Gecko#

The Gecko Runtime Environment (GRE) provides the libraries required to embed the Gecko browsing engine in your applications. That's right you could develop your own Mozilla based browser (although it make take you some time!).

On your SUSE box these are usually already part of the distribution since they ship with the Mozilla browser which is normally installed. For Windows we need a customized GRE and not the official Mozilla release which is built with Microsoft Visual C++ 6.0 and has a problem passing UTF8 strings to Gecko#.

The Mono Windows Integration web site hosts the GRE that we require (actual hosting by Novell Forge):

  • GRE for Gecko# 1.7.3
    http://forge.novell.com/modules/xfcontent/downloads.php/monowin32/GRE%20for%20Gecko-Sharp/ v1.7.3-0.1/

  • The install will set the GECKOSHILLA_BASEPATH environment variable which points to the home of the GRE install.

    Install Gecko#

    With Mono and the GRE installed we now need the the .NET bindings for GRE namely the Gecko# assembly (gecko-sharp.dll). If you opted for the "Combined Installer" from the Mono Windows Integration site mentioned previously then give yourself a pat on the back, you've already completed this step. However if you decided on the vanilla Mono 1.1.4 Windows install from the Mono Project website then we need to grab Gecko#.

  • Gecko# assembly

    Once we have Gecko# it can be place in the Mono Global Assembly Cache (GAC).

    gacutil -i gecko-sharp.dll

    If you looked at the download page for the Combined Installer you may have noticed two other downloads, namely:

  • Gtk# 1.9.2 Win32 Installer for .NET Framework 1.1 SDK
  • Gtk# 1.9.2 Win32 Installer for .NET Framework 1.1 Runtime
  • These installers will place the Gtk# and Gecko# assemblies in the respective Microsoft .NET GAC.

    For the convenience of later compilation, we'll also put gecko-sharp.dll in the standard library path for Mono at <MONO_HOME>/lib/mono/gecko-sharp.

    Rebuild the Code

    With all the necessary libraries in place, we can now run our Browser executable without change? Unfortunately not! - currently there are a couple of additional lines of code required for the GRE and Gecko# on Windows.

    Edit the code to include the following:

    ...
    gxml.Autoconnect (this);
    			
    // Get the GRE for Gecko# Path in Windows systems
    String mozillaEnvPath 
         = System.Environment.GetEnvironmentVariable
             ("GECKOSHILLA_BASEPATH");
    if(mozillaEnvPath != null && mozillaEnvPath.Length != 0)
    {
        Gecko.WebControl.CompPath = mozillaEnvPath;
    }
                   
    web = new WebControl();		
    web.Show();
    ...

    Having edited the code, it will now needed to be rebuilt on the Windows box, ensuring all the necessary assemblies are referenced.

         
  • System
  • – either Mono or .NET
     
  • System.XML
  • – either Mono or .NET
     
  • System.Data
  • – either Mono or .NET
     
  • atk-sharp
  • – Mono only
     
  • gdk-sharp
  • – Mono only
     
  • gecko-sharp
  • – Mono only
     
  • glade-sharp
  • – Mono only
     
  • glib-sharp
  • – Mono only
     
  • gtk-sharp
  • – Mono only
     
  • pango-sharp
  • – Mono only

    Rebuilding the code can either be done using the Mono C# Compiler - mcs

    mcs -debug --stacktrace -lib:d:/mono/lib/mono/1.0 -lib:
    d:/mono/lib/mono/gtk-sharp-2.0 -lib:d/mono/lib/mono/gecko-sharp -r:
    System.dll -r:System.Data.dll -r:System.Xml.dll -r:atk-sharp.dll -r:gdk-
    sharp.dll -r:glade-sharp.dll -r:glib-sharp.dll -r:gtk-sharp.dll -r:pango-
    sharp.dll -r:gecko-sharp.dll -target:winexe -out:./
    bin/Debug/WinWebBrowser.exe -resource:gui.glade AssemblyInfo.cs Main.cs
    
    

    Or using the Microsoft C# Compiler - csc

    csc -nologo -optimize+ -d:TRACE -r:System.dll -r:System.Data.dll -r:
    System.Xml.dll -r:d:\mono\lib\mono\gtk-sharp-2.0\atk-sharp.dll -r:
    d:\mono\lib\mono\gtk-sharp-2.0\gdk-sharp.dll -r:d:\mono\lib\mono\gtk-sharp-
    2.0\glade-sharp.dll -r:d:\mono\lib\mono\gtk-sharp-2.0\glib-sharp.dll -r:
    d:\mono\lib\mono\gtk-sharp-2.0\gtk-sharp.dll -r:d:\mono\lib\mono\gtk-sharp-
    2.0\pango-sharp.dll -r:d:\mono\lib\mono\gecko-sharp\gecko-sharp.dll
    -target:winexe -out:.\bin\Debug\WinWebBrowser.exe -resource:gui.glade
    AssemblyInfo.cs  Main.cs
    
    

    Note - for some peculiar reason csc will not accept the shorthand event handler registration in this example, thus: urlEntry.Activated += OnLoadUrlEvent; must become: urlEntry.Activated += new EventHandler(OnLoadUrlEvent);

    To make life a little easier you may wish to put these build instructions into a Makefile. Below are some examples for both compilers using the Nmake tool distributed with Microsoft Visual Studio.NET. An alternative would be to use GNU make available on Windows through the Cygwin tool set.

    If you prefer to set the project environment up in an IDE then either Microsoft Visual Studio.NET or the open source substitute, Sharp Develop may be employed.

  • Makefile.mcs.nmake (for Mono)

  • !if !defined (TARGET)
    TARGET=.\bin\Debug
    !else
    TARGET=.\bin\$(TARGET)
    !endif
    
    MCS=mcs
    !if !defined(RELEASE)
    MCSFLAGS=-debug --stacktrace
    !endif
    
    LIBS=-lib:`pkg-config --variable=libdir mono`/mono/1.0 -lib:`pkg-config --variable=libdir gtk-sharp`/mono/gtk-sharp-2.0 -lib:`pkg-config --variable=libdir gecko-sharp`/mono/gecko-sharp
    
    BROWSERSHARP_EXE=$(TARGET)\WinWebBrowser.exe
    BROWSERSHARP_PDB=$(TARGET)\WinWebBrowser.exe
    BROWSERSHARP_SRC=AssemblyInfo.cs \
         Main.cs
    BROWSERSHARP_RES=-resource:gui.glade
    
    $(BROWSERSHARP_EXE): $(BROWSERSHARP_SRC) 
         -md $(TARGET)
         $(MCS) $(MCSFLAGS) $(LIBS) -r:System.dll -r:System.Data.dll -r:System.Xml.dll -r:atk-sharp.dll -r:gdk-sharp.dll -r:glade-sharp.dll -r:glib-sharp.dll -r:gtk-sharp.dll -r:pango-sharp.dll -r:gecko-sharp.dll -target:winexe -out:$(BROWSERSHARP_EXE) $(BROWSERSHARP_RES) $(BROWSERSHARP_SRC)
    
    
    # common targets
    
    all:  $(BROWSERSHARP_EXE)
    
    clean:
         -del "$(BROWSERSHARP_EXE)" 2> nul
         -del "$(BROWSERSHARP_PDB)" 2> nul
    	 


  • Makefile.csc.nmake (Microsoft)

  • !if !defined (TARGET)
    TARGET=.\bin\Debug
    !else
    TARGET=.\bin\$(TARGET)
    !endif
    
    MCS=csc
    MCSFLAGS=-nologo
    
    !if !defined(RELEASE)
    MCSFLAGS=$(MCSFLAGS) -optimize+ -d:TRACE
    !else
    MCSFLAGS=$(MCSFLAGS) -debug+ -d:TRACE,DEBUG
    !endif
    
    BROWSERSHARP_EXE=$(TARGET)\WinWebBrowser.exe
    BROWSERSHARP_PDB=$(TARGET)\WinWebBrowser.exe
    BROWSERSHARP_SRC=AssemblyInfo.cs \
         Main.cs
    BROWSERSHARP_RES=-resource:gui.glade
    
    GTKLIBS=d:\mono\lib\mono\gtk-sharp-2.0
    GECKOLIBS=d:\mono\lib\mono\gecko-sharp
    
    $(BROWSERSHARP_EXE): $(BROWSERSHARP_SRC) 
         -md $(TARGET)
         $(MCS) $(MCSFLAGS) -r:System.dll -r:System.Data.dll -r:System.Xml.dll -r:$(GTKLIBS)\atk-sharp.dll -r:$(GTKLIBS)\gdk-sharp.dll -r:$(GTKLIBS)\glade-sharp.dll -r:$(GTKLIBS)\glib-sharp.dll -r:$(GTKLIBS)\gtk-sharp.dll -r:$(GTKLIBS)\pango-sharp.dll -r:$(GECKOLIBS)\gecko-sharp.dll -target:winexe -out:$(BROWSERSHARP_EXE) $(BROWSERSHARP_RES) $(BROWSERSHARP_SRC)
    
    # common targets
    
    all:  $(BROWSERSHARP_EXE)
    
    clean:
         -del "$(BROWSERSHARP_EXE)" 2> nul
         -del "$(BROWSERSHARP_PDB)" 2> nul
    

    The eagle eyed may have spotted the pkg-config which is used to help find the libraries in the Mono makefile. A Windows port of this standard Linux tool is shipped with Mono. Since gecko-sharp.dll was installed by hand we will need to create a gecko-sharp.pc file for pkg-config to reference.

  • <MONO_HOME>/lib/pkgconfig/gecko-sharp.pc

  • prefix=D:/mono
    exec_prefix=${prefix}
    libdir=${exec_prefix}/lib
    
    Name: Gecko#
    Description: Gecko# - Mozilla Gecko .NET Binding
    Version: 0.7
    Libs: -r:${libdir}/mono/gecko-sharp/gecko-sharp.dll


    Execute

    All that's left for us to do now is run the application which may be done either using Mono's Common Language Runtime (CLR) which will use the Mono GAC

    mono WebBrowser.exe

    Using the Microsoft CLR uses the Microsoft GAC which in this example does not contain the additional Mono assemblies, thus the simplest solution to this problem is to copy the required assemblies locally to the ./bin/Debug directory and then execute.

    WebBrowser.exe

    Of course a more complete solution would be to insert these assemblies into the Microsoft GAC. This is left as an exercise for the reader.

    Even though we've ported to Windows we still maintain the internationalization functionality of the Gtk.

    LANG=he_IL mono WebBrowser.exe

    Having got this far don't stop – keep going! The Glade interface designer is also shipped with the Mono, look in the <MONO_HOME>/bin directory. Fire it up, start adding to the interface, a few more event handlers in the code and who knows you may have Mozilla Firefox 2 on your hands!

    Summary

    Hot out of the oven, the Gtk# and Gecko# libraries on Windows show that there is a cross platform alternative to Microsoft System.Windows.Forms on the horizon. Looking at success and innovation shown by recent Mono based projects such as Tomboy, Beagle and iFolder, we see that the future looks bright for desktop development.

    References


    Novell Cool Solutions (corporate web communities) are produced by WebWise Solutions. www.webwiseone.com

    © 2014 Novell