This document describes how is Gwyddion organized and how it works from a slightly technical standpoint, but it does not go too deep. As such it is a recommended reading before hacking Gwyddion, or even writing modules.
Gwyddion is written in C and builds on Gtk+ and GLib libraries. It relies on the GLib utility library for portability and uses GLib object system GObject for its own objects. Graphical user interface is implemented with the Gtk+ toolkit, with a fair amount of Gwyddion specific extension widgets.
The program can be divided into four main components, each discussed in details below:
Libraries form the bulk of Gwyddion code and provide most of the real functionality that modules and the main application build on. The current set of libraries has a layered structure where each next library uses all previous, lower-level ones.
In following description, they are listed from from the lowest level to the highest level.
The libgwyddion library defines some core interfaces, like GwySerializable for data-like objects; general classes not directly related to data processing or GUI (GwyContainer, GwySIUnit); and various string, math, file and miscellaneous utilities and macros.
Of particular interest is the GwyContainer object, which serves as
a general-purpose container for data-like (i.e. serializable) objects in
the program. Both Gwyddion native
.gwy files and settings file
are technically just serialized GwyContainers; this allows quite a faithful
preservation of state in saved data.
The libprocess library defines two basic objects: GwyDataField. representing two-dimensional data and GwyDataLine, representing one-dimensional data. These objects encapsulate raw floating point arrays together with basic metadata – physical dimensions and their units.
Almost all of the many libprocess routines operate on these objects (a few operate on raw data arrays). There are elementary operations, like value, row, and column extraction, scaling, rotation, inversion; as well as high level functions, like grain marking, wavelet transform, statistical functions, or correlation and fractal analysis.
The libdraw library is a small library which provides a few colour handling and elementary data rendering functions. It defines false colour map objects, GwyGradients, OpenGL material objects, GwyGLMaterials, and an abstract selection class GwySelection.
It also defines a GwyRGBA floating point colour type used throughout Gwyddion for colour representation.
The libgwydgets library is essentially a collection of Gwyddion-specific Gtk+ widgets. There are several notable groups of widgets there.
GwyDataView and GwyDataWindow are used to display two-dimensional data. They are accompanied by a swarm of auxiliary widgets – various data view layers pluggable to the data view and false colour axis. One kind of data view layers, so called vector layers, allowing user to “draw” on data views has been modularized (to allow extensions to define their own means of interaction), so vector layers are implemented in layer modules.
Various constructors (for combo boxes, radio buttons and other selectors), stock icon handlers and general purpose widgets like rulers. And there are a few individual useful widgets, like a colour button or an improved statusbar.
The libgwymodule library deals with module administrative, loading and act as a proxy in their usage. It defines particular module types; module and module feature registration function. In some cases it implements more convenient wrappers around primitive module functions.
The libgwyapp library contains main application related functions, some of which could be probably equally well put into the main application. Nevertheless many can be useful outside Gwyddion itself – in a Gwyddion related work. Since it's not always clear which are which, the library contains everything that can be of any interest to outside world.
The content of libgwyapp is quite diverse. There are settings loading and saving functions, an undo facility, base classes for tool modules (GwyTool, GwyPlainTool), a “Please wait” progress bar helper, functions dealing with data and graph windows in the application, etc.
The main application is kept very small and simple, as it is practically the only non-reusable (or hardly reusable) part. In fact, a few standard modules are each larger than the main application.
The function of main application is to glue the other parts together in a common GUI framework. So beside some presentation and eye candy (About, splash screen) and a few global functions (metadata browser), it just handles command line arguments, loads settings, constructs the toolbox and then lets modules and libgwyapp functions rule.
While libraries form the bulk of code, modules are what makes the program what it is. If Gwyddion is run without any module, it starts, but the only thing one can do then is to quit it again. File loading is handled by modules, all operations on data are handled by modules too.
Technically, modules are shared/dynamically loaded libraries, scanned and loaded a program start. On load time they are asked to register their functions (also called features), there can be zero or more of them, although the former does not make a particularly useful module. The application then builds menus and toolbars representing registered functions.
There are several types of function a module can registed according to its role in the program – a module can register functions of different types, but this normally makes little sense, with the notable exception of the plug-in proxy module. Following types currently exist:
Since modules can use all Gwyddion libraries, including libgwyapp, it's up to them whether they present a GUI to the user, create new windows, or anything. There are actually few things they cannot do, albeit as a side-effect not correspoding to their role.
Modules store their persisent settings in a big hash table, called settings, of whose saving and loading main application takes care of.
Plug-ins are standalone programs, that are more or less independent of Gwyddion, both technically and legally. It runs them to perform a given task when necessary and it waits for them to finish.
Plug-in interaction with Gwyddion lies in a
format used for data exchange, and a small set of predefined program
arguments – like
load – telling the plug-in what it should do with the data
specified as other arguments. It then performs the task, and Gwyddion reads
back the result. This simplicity limits their possible roles and
functionality, but on the other hand it enables writing plug-ins in almost
There are two kinds of plug-ins – data processing and file type, bascially corresponding to data processing and file type modules.
The main application knows practially nothing about plug-ins. The ability to use plug-ins inheres to a smart module called plug-in proxy. In its registration phase it scans plug-in directories, queries found plug-ins and registers their features as its own features. Likewise, when it is asked to perform some task, it run appropriate plug-in to handle it. Thus it transparently maps plug-ins to module features.