My name is Michael Hutchinson and I'm a software engineer working for Xamarin on the MonoDevelop IDE and Mono for mobile platforms. Here you can find my journal, projects and photos.


AspNetEdit hits SVN

I've finally committed the ASP.NET Graphical Designer to Mono Subversion, module 'aspeditor'. It's unimaginatively codenamed AspNetEdit. If anyone *really* wants to play with it, please be aware that right now it doesn't do an awful lot. Also it requires Mono class libraries hot out of SVN. I would advise waiting till an actual release the beginning of September; I'll keep my blog updated with screenshots. Here's the next:

As before, you can add controls to the design surface from the toolbox, and change their properties with the Property Browser. In this screenshot you can also see the new Collection Editor. All of this has been polished, and you can now save the document to a .aspx file. However, ASP directives are not suported yet, and the interactive design surface is still a little way away.

ASP.NET Graphical Designer screenshot

Okay, it's not quite as exciting as the title suggests. I've been hacking away on the Services and Component Model, and have reached the stage where I can display controls, select them from a drop-down list, change their properties, and have the change reflected on the design surface. You can't interact with the design surface directly yet, and the controls aren't really in a document, just a collection of controls. But it looks pretty!

Update, 28-7-05: Noticed I'd put this in the wrong category.

It lives!

The inbound (Mono -> Gecko) C++ DOM function is working fine and I can recieve a C# call in JavaScript; now I just need to pass it off to the actual function.

There was a bit of trouble initially as I couldn't obtain an nsIWebBrowser pointer from gtk_moz_embed_get_nsIWebBrowser. This turned out to be because the Gecko# WebControl hadn't been shown yet (i.e. window.ShowAll()), but I didn't figure this out as other functions like gtk_moz_embed_get_location worked fine.

Here's Blagovest Dachev's XUL GUI demo hosted in my container, with a simple C#->JS call demonstration. For anyone who hasn't seen the Mono Summer of Code page, Blago's working on the Mozilla half of this project.

Shouldn't be hard now to get the outbound side working. I'll have to test how long the JavaScript status messages can be, or I'll have to finish the outbound C++ glue. Marshalling 'out' parameters isn't too easy, especially when I don't want to place any artificial limits on the size of the data that can be passed around, so I'll return the arguments from the function as a string pointer return value. I don't expect the names of the callee and callback functions to be more than a few hundred characters in the extreme case, so they should be able to be sent in the JavaScript status message.

However, splitting the call in two parts like this could have consequences; there's no telling what multithreading could do to concurrency. I guess some kind of unique identifier is in order.

I also need to finish all of the error and exception handling at some point, though it seems robust enough at the moment.

Gecko# interaction

Implementing the ASP.NET GUI designer with Mozilla's Gecko web rendering engine is an obvious decision: it's open-source, has strong standards support and a large feature set, is highly extensible and flexible thanks to its XPCOM component system, and using Gecko# it can be embedded in a GTK# GUI. Mozilla is becoming an application platform, with XUL for declaratively writting GUIs, and JavaScript for program logic.

Gecko# wraps GtkMozEmbed, which is a C GTK widget, hiding Mozilla's native C++. Understandably this widget isn't bloated by wrapping the Mozilla DOM or other internals: it claims to exposes enough functionality for "about 80% of uses". Essentially this means a basic web browser.

However, to do anything interesting I need to interact with Gecko# from my C# code, and vice versa. There are two obvious ways to approach this:

  • Expose everything
    Open up the whole of Mozilla's internals to Mono code, or at least the DOM and XPConnect for JavaScript interaction. This would be ideal, as it's the most flexible, and would find many other uses. However, wrapping enough functionality to do anything useful is a very significant task in itself.
  • Message-passing
    Simply restrict all of the Mozilla interaction code to JavaScript functions, which can be triggered from C# via a message-passing scheme of some kind. Pragmatic, and not inelegant, as JavaScript is a first-class citizen in the Mozilla world, and is used to write large parts of Mozilla.

So, assuming I choose the second for speed and ease of development, how do I go about implementing it? This time, I have four choices:

  1. Abusing Gecko#
    Relatively harmlessly, we can raise C# events by changing the JavaScript status message.
    A more serious abuse is to stream the document into Gecko#, then stream in additional elements containing our messages. JavaScript can catch these with the DOMNodeInserted event and act accordingly. Or so I thought. While Gecko will render an open HTML stream, it's not so forgiving in the case of XUL. Oh dear.
  2. Mono-XPCOM bridge
    Yes, there is one, and it would be the most elegant solution... unfortunately it's not nearly complete enough to begin using for a project like this just now, and I'm not familiar enough with XPCOM to fix it up myself. I can see switching to this when it becomes stable enough.
  3. Web server
    This would cause the editor to effectively become an "AJAX" application. Ouch. A horrible hack, and a horribly-named technology. On the upside, this would be relatively quick and easy.
  4. C++ wrapper and P/Invoke
    Similar to the Gecko# abuse, but strangely, more elegant, despite the additional dependecies and build steps this method entails. The handle from Gecko# can be passed to a C/C++ wrapper via Platform Invoke. The wrapper function then uses GtkMozEmbed's "gtk_moz_embed_get_nsIWebBrowser" function to access Gecko's internals, does interesting thisgs to it with XPCOM, and optionally even returns values.

Well, I initially tried the fourth method, until I realised how much easier the first would be, and cursed XPCOM and the days it had taken from my life.

Fate has twisted sense of humour. Two days into the initial implementation of the editor's high-level architecture, as I began to flesh out the message passing system, I discovered the fickleness of Gecko#'s streams, and had to revert to XPCOM and P/Invoke.

More on this story later, once I have something working.

ASP.NET GUI Designer

Hello everyone! (waves to as-yet nonexistent audience)

I finally bring to you some useful content in my blog. I have been accepted onto Google's Summer of Code and will be working with the Mono Project to bring you a user-friendly graphical designer for ASP.NET, which will be integrated into the MonoDevelop IDE.

I will be chronicling any interesting developments right here for your amusement and gratification. Stay tuned!

How embarrassing

Three months since I last posted on this site, and all of those early posts were just about setting the site up. Seems lie the site's a bit pointless, really. Not that I've been sitting idle; I've been snowed under with academic work. I'll get something interesting up here eventually, I promise.

For now, let it be known that I am procrastinating my exam revision by upgrading the site to Drupal 4.6.

Spam, spam, spam, spam....

The site's only been up for five days and I'm already getting referrer spam. No comment spam yet, but I'll probably disable comments and trackbacks until I have some interesting stuff up, and sort it out then.

Thanks to some helpful advice on Caveat Lector I used a bunch of Apache .htaccess rules to filter out domains containing spam-like words. It's likely that there will be some false positives but until I find another way, it'll have to do.

In other news, Drupal's project module is giving me trouble; it refuses to track my projects' releases. I think it's PostgreSQL compatibility-related, but the exact reason is proving to be difficult to track down.

GeSHi Code Filter module

I couldn't find a Drupal module to syntax highlight C# code, so I made one. I'm using the Generic Syntax Highlighter, GeSHi, to drive a filter loosely based on the codefilter module. While doing this, I discovered Nonstop Bits' Nonstop HiLighter module, which highlight many more languages, but I think GeSHi produces prettier output colours :). The next version will be supporting mixed-language files, such as PHP, CSS and JavaScript in XHTML, which looks amazing. It's also very configurable and can output line numbers and XHTML Strict/CSS code, and it wouldn't be hard to add options to the filter to turn these options on.

Using the filter's fairly simple. Once it's installed and registered to an input format, just surround your code with <code language>...</code> tags. Supported languages are actionscript, ada, apache, asm, asp, bash, caddcl, cadlisp, c, c_mac, cpp, csharp, css, delphi, html4strict, java, javascript, lisp, lua, nsis, objc, oobas, pascal, perl, php-brief, php, python, qbasic, smarty, sql, vb, vbnet, visualfoxpro, xml.

Here's some PHP:

function GeSHicodefilter_process_code($matches) {
  // Include the GeSHi library
  // Make a new GeSHi object, with the source, language and path set
  $path = module_get_path('geshicodefilter').'/geshicodefilter/geshi/';
  $geshi = new GeSHi($matches[2], $matches[1], $path);
  //GeSHi settings
  //dump the code!
  return $geshi->parse_code();

and some C#:

///<summary>Resizes the world</summary>
public void ResizeWorld(int w, int h)
	gridWidth = w;
	gridHeight = h;
	//Setup new grid
	CellGrid = new int[gridWidth, gridHeight];
	oldCellGrid = new int[gridWidth, gridHeight];
	//configure drawing bitmaps
	//seed the world with cells

Pretty, isn't it? You can get the module from its project page.

I also found a modified wiki module that uses GeShi to highlight a couple of languages, but it's not completely general. I think I'll just modify the Wiki module to ignore anything inside a <code> block (it insists on escaping it all at the moment!) and the GeSHi filter can sort out whatever comes out.

Progress is a good thing

I wasn't quite as far as I thought I was.

There were still a few PostgreSQL bugs in Drupal that I had to fix before getting on with theming the site. This turned out to be too big a task for an evening so I modified the Drupal port of Michael Heilemann's Kubrick theme, changing the title picture (anyone recogise the mountain?) and the footer, hacking the template so that the sidebar vanishes if it has no content, and making a few other tweaks. Personally I still have my reservations about a fixed-width layout like this - even though it's very pretty - so when I have time I'll fix it up to use relative units.

Additional modules I've installed now are the PHPTemplate theming engine, the Article, Trackback, Wiki Markup and Project Management. There's not really much else I need, though I'd like to be able to add screenshots and documentation to the projects.

I turned on comments for completeness, though I don't expect to recieve any yet. It does mean I'll have to be on the watch for comment spam but I don't think the spammers know about my site yet. Anyway, Drupal offers a Bayesian spam filter when I need it.

And so it begins...

I've been wondering for literally months how to set up this site. I almost went with a custom coded solution but Drupal's logging and modular 'plug-in features' were ultimately too alluring. The critical question, as always - what would be the best layout? Which modules to use to categorise and display my projects? How do I make all these features work together?

I finally got around to setting up the site properly. My year-old half-baked installation of Drupal should now be fixed (I've reinstalled it several times playing with various configurations) and set up to do everything I want it to. I had to use a few modules, several of which had to be ported to PostgreSQL, but overall the installation process was quite easy. The categories, blocks and links are all set up and all that remains is to create a theme. Then the content can be rolled in...


Subscribe to Journal