Archive | GModule RSS for this section

DMP Photo Booth: First Commit

Well, it’s been a long time coming, but this weekend 45 days of work has culminated in my first milestone: DMP Photo Booth has received its first commit. If you go to this page, you’ll find the newly created Github repository for it. Feel free to go judge all the choices I made, I’ll wait…

…done? Good, now I’d like to use this post to talk about it.

The Story So Far

dmp_photo_booth_screenshot

So far, most of the work is done in the core. There are module stubs for each module, and they are loadable and “function”, but they don’t do much of anything. However, the UI for the core is, for the most part, done. If you build the core (Either open the projects in NetBeans or cd into its directory and enter make build), and run it (as of this writing, it must be run from the project root directory, since the supporting files are located here and referenced by relative paths) it will launch. At this point, you can launch the about window, the config window, or exit the program. From the config window you can load your modules (built stub modules are included for your convenience), and the status indicators on the main window will detect it.

All this is fine and good, but the real story here is the plumbing that has been laid.

Said Plumbing

Not much works at the moment, but the groundwork has been laid for things to come. Going down the list:

Global Defines

In this header, you’ll find all the magic integer constant return values used throughout DMP Photo Booth and friends. I touched on this topic briefly in a previous post, but the cliff’s notes version is that I feel that using a bare integer instead of an enum reduces the burden on module developers, and that the benefits of an enum aren’t great enough to justify this burden.

As this header has no accompanying .c file, it can be #included by module developers so they can make use of it if they like. I do this in my modules.

Module

One of the first things I worked on was module handling. This header holds all the functions required for the loading and unloading of modules, and the calling of module functions. At first I was implementing all of this with POSIX calls, but it occurred to me that I was defeating the purpose of my modular architecture by using non-portable calls. For this reason, I switched to GModule for module handling. I wrote a post about this if you want to hear more.

Module Callbacks

This header contains functions that will be added to modules as callbacks. Currently, this is the function that will be called when the user presses “the button”, and the function that will be called to push a message to the console queue.

Error Handling

My general approach to function design is that functions should not return void. All functions that would, instead return gint. This way, I have a mechanism to detect error conditions. In a language without Exception Handling, this is a nice thing to have. This header contains functions to extend this. Since sometimes you can’t return gint, I’ve created a facility to log error codes, similar to how the POSIX errno function works.

Console Queue

This header contains a thread safe queue to store messages to print to the console. Currently, this is implemented with a GQueue and mutex locking, but I made that choice before I knew about GAsyncQueue. I may refactor this at some point to use GAsyncQueue, but for now it works fine, and I see no immediate issue with my implementation.

The idea behind the console queue is that there should be a generic way to store messages. Currently the console is a GtkTextBuffer, but if I build around this, it limits future functionality. Suppose I wanted to support a command line only option? It’d be silly to require GTK for that, wouldn’t it?

That said, the default implementation uses a function placed in the GtkMainLoop to pop all messages out of the queue and place them into the GtkTextBuffer.

Module Status Watchdog

This header file is in charge of keeping those fancy module status indicators up to date. There are two main moving parts here: a thread that polls the module status, and a function run by the GtkMainLoop.

The Thread polls the modules every 3 seconds and pushes any status changes to a GAsyncQueue. Meanwhile the GtkMainLoop checks the GAsyncQueue for updates, and sets the indicator status accordingly. Why doesn’t the GtkMainLoop just check the module status you ask? I wanted to make sure the GtkMainLoop does as little work as possible. Currently the calls to check module status are pretty trivial, but there is no guarantee that they will stay that way. Since nobody likes an unresponsive interface, I kept them separate.

User Interface

This rather hefty header contains two things: a function to build and launch the UI, and all the callbacks called by said UI. All the callbacks are named according to their glade widget name to maintain some semblance of readability.

The Next Step

Obviously, looking through the User Interface source, there are signals to be hooked up. But aside from that, the core is coming along. The one big portion of the core remaining to be done is the photo booth strip logic. The camera module will take X pictures and download them. At this point it is up to the core to assemble them into on image file to be printed.

For now, I will continue to hook up signals and refine the existing portions of the core. While I do this, I will research image handling libraries. I’d like to keep things within the GLib family, but failing this, I will try to keep it limited to libraries shipped with Ubuntu (The default platform). Windows compatibility will come, but version 1.0 will work on Ubuntu.

Also looming on the horizon are the modules. I have a general idea of how I will deal with these, but nothing is set in stone. The first module that I will likely handle is the trigger module. I plan to implement the trigger module using Arduino. This is a topic that interest me, but I’ve never had a good project idea. Whenever I get tired of dealing with GTK, it should be a nice change of pace.

Bringing The Portability With GModule

As I’ve been writing DMP Photo Booth, I’ve been taking great pains to improve portability. I’ve got a fancy module-based architecture designed to segregate the non-portable sections of the project from the Core. The only problem? A bunch of ugly POSIX calls: dlopen(), dlsym(), and dlclose(). Kind of defeats the purpose of using modules for portability if I don’t load said modules in a portable way, doesn’t it? I thought so too…

Enter GModule

GModule is part of the GLib family of libraries. GModule provides a portable way to handle working with shared libraries. It works on any POSIX compliant platform, as well as Windows, and HP-UX via its shl_load() mechanism. You can read more about GModule in the GLib Reference Manual. While I’m sure there is some edge case that GLib doesn’t cover, this is far more portable than I’d initially envisioned DMP Photo Booth being. (Yay, HP-UX support!)

Another consideration in all of this is the adding of dependencies. However, since I’m already using GTK3 for my GUI, I already have a GLib dependency, so there is no added burden to using GModule.

The How

GModule is actually quite similar to using POSIX dlfcn.h functions. Some semantics are different, but GModule has functions that are roughly equivalent to the POSIX functions.

GModule * g_module_open(const gchar *file_name, GModuleFlags flags);

G_module_open() is the replacement for dlopen() in POSIX. The GModule pointer that it returns is the replacement for the void pointer returned by dlopen(). GModuleFlags is an integer flag that can be boolean or’d in. Your options for this are G_MODULE_BIND_LAZY and G_MODULE_BIND_LOCAL which are equivalent to RTLD_LAZY and RTLD_LOCAL.

gboolean g_module_symbol(GModule *module, const gchar *symbol_name, gpointer *symbol);

This is your replacement for dlsym(), and functions mostly in the same way. module is the gmodule pointer to extract symbols from, symbol_name is the symbol to get, and symbol is the function pointer to populate. This function returns true if successful, and false if not. This function is commonly called like this:

if (!g_module_symbol(dmp_pb_camera_module, "dmp_cm_capture", (gpointer *) &dmp_cm_capture)) { /* error handling here */ }

This idiom can be found throughout the GLib documentation. Did you see the craziness that is argument number 3? Dmp_cm_capture is a function pointer, as you may remember, but GObject tends to make things a little tricky, and will throw thousands of warnings if you don’t cast your function pointer to a gpointer *. The definition of gpointer is:

typedef void* gpointer;

That means that a gpointer * is actually void **. Therefore, you are expected to pass in the address of your pointer using an ampersand, hence (gpointer *) &dmp_cm_capture.

gboolean g_module_close(GModule *module);

As a nice change of pace from the last function, this one is quite straight forward. You pass in your GModule pointer, and it closes it, just like dlclose(), then returns true (or false, if an error occurs). Nothing particularly noteworthy here.

gboolean g_module_supported();

While this function does not line up with a POSIX function, I felt it was important to mention this one. This function returns true if you are on a platform that GModule supports. If you’re on Linux/UNIX/OSX, or Windows, or HP-UX, this should return true. If you’re hacking your Atari-2600, it will most likely return false. Stick this in front of calls to GModule functions and save yourself a headache.

Moving Forward

My design philosophy for DMP Photo Booth is that the Core should compile on any (typical) platform with no changes. Using GLib, this seems to be within reach. With GModules, GTK3 User Interfaces, I’ve kept the faith so far. Looking through the GLib documentation, it has GThreads, so when I inevitably get mired in threaded programming, I should be golden. GLib also has support for Pipes and file IO via GIOChannel, but the documentation claims only partial support in Windows.

Here’s hoping all goes well!

%d bloggers like this: