Copyright © 2000, 2001 by Dirk-Jan C. Binnema
|Revision 1.0.1||August 11, 2001|
|Update: -Wall cleanups, OAF_INFO_PATH notice, misc. other stuff|
|Revision 1.0.0||April 4, 2001|
|Release: ready for mass consumption|
|Revision 0.8.0||October, 2001|
In this article, I'll try to give a practical introduction into the Art of Writing Bonobo Controls, and also provide some backgrounds. Turning the example into anything useful is left as an exercise to the reader. If you've never done any GTK+/GNOME programming, it may be a bit hard to follow; I suggest reading a good book on the subject first. At the end of this article, I've included some suggestions.
You can find the most recent HTML-version of this tutorial at http://www.djcbsoftware.nl/projecten/bonobo_controls, or download a tarball with the Docbook-source and the example code at http://www.djcbsoftware.nl/projecten/bonobo_controls/bonobo_controls.tar.gz
For comments, suggestions etc, you can reach me at email@example.com. Thanks to all the people who have helped in getting this tutorial in it's current state. You know who you are!
Bonobo is the component model that has grown from the GNOME project. Originally, Bonobo was designed and implemented by Miguel de Icaza, heavily inspired by Microsoft's OLE2. Now, what can we do with a component model? A lot of things:
embeddable documents (i.e. a word-processing document inside a spreadsheet);
controls (i.e., meta-widgets available through CORBA);
scripting and automation (e.g., writing some Perl to control Gnumeric). Currently, there's some work being done on a Perl-binding for Bonobo.
Before we dive into straight howtoism, let's have a short discussion of Bonobo's background, and its roots in CORBA and OLE2.
As stated, Bonobo is a component model or object model (I use the terms interchangeably), i.e., a technology that aims at having lots of objects interact. For a powerful object model, it's important to be able to 'connect' to this model in many different ways; i.e. you want to be able to freely choose the programming language for some task, while being able to connect to existing objects written in other languages. And you may want to access these objects from different machines, running different OS's, etc. This is the kind of stuff CORBA was designed for, and this is exactly why Bonobo uses it.
By setting standards, the CORBA runtime system can deal with the low-level plumbing of connecting objects. The question remains how to discover what capabilities other objects have, because this is a prerequisite for using them. The stuff that objects expose to the outside world, such as methods, attributes etc. is called the object's interface. This is very similar to C++ class definitions, or Java or Objective-C interfaces. To describe such interfaces, CORBA defines a special language, the interface definition language (IDL). The external interface of CORBA objects is specified completely in IDL, and IDL-compilers generate the plumbing code (skeletons and stubs) for you to enable communication between objects from the IDL descriptions.
In 1993, Microsoft introduced OLE2 to do some of the same things CORBA does, but primarily aimed at desktop-related things, such as embedding documents within each other, and controls. Bonobo's interfaces are very much 'inspired' by the OLE2 interfaces. On top of that, Bonobo also provides a default implementation for these interfaces, using GTK+ and its object system. Now, instead of writing lots of boilerplate code, writing a Bonobo control only takes a couple of lines of code, as I will show you. Still, you have the freedom to override any of the default implementations if you need to.
Note that what Bonobo really does is defining a communication protocol between objects, and that this protocol is defined in a number of IDL interfaces. So, in principle you could take these interfaces and implement them using Qt, Java, ncurses or whatever. The resulting objects would then be able to interact seamlessly, no matter what toolkit they'd be using. In theory, at least.
Ok, now back to howto-mode.
Bonobo-support for embedded scripting is not implemented yet. I have some ideas how to it, but I lack the time...
|Writing a Bonobo Control|