Thanks to CL-GTK2's author Dmitry Kalyanov for his help and patience and also thanks to several #lisp residents for testing some of my builds.
Go to http://www.aerique.net/software/okra-gtk-demo/ for the downloads.
This post should be treated more as a work-in-progress report than as the blog I hoped I could publish, which would have had a title like: "Easy cross-platform executable delivery using CL-GTK2 and Okra".
So this post should be considered as a first step and perhaps a helpful reference for people with the same intent as I did. It should definitely not be treated as a completed project or as a reference on the proper way to build such things in Common Lisp (CL)!
I set out to write a little demo that would have an Ogre window embedded in a GUI application and that could distributed as an executable on both Linux and Windows. (I have neither access to nor experience with OS X.)
I settled on CL-GTK2 for the GUI. I also wanted it to work on SBCL for Windows so that ruled out using threads. Not a smart decision on my part since it would have been better to use a separate thread for the GUI. Eventually I didn't use SBCL on Windows anyway since it didn't work out how I initially used CL-GTK2. (It might work using #'GTK:GTK-MAIN but I never tried.)
Keep in mind I used Glade to construct my GUI. CL-GTK2 comes with many examples if you want to construct your GUI programmatically.
Let CL-GTK2 run in its separate background thread, this will avoid many awkward constructs and unresponsiveness in the GUI.
Use a GTKEventBox for embedding the Ogre window if you need to catch events. It also needs to be declared "can focus" and of course you'll need to enable all the events you want to catch.
Ogre: You'll need to use Ogre::WindowEventUtilities.messagePump() in configure_event or the GUI will hang when it is being realized.
Linux: I had better success using the downloadable 0.1 release than the latest from the Git repository. Especially with signals the GUI just hung. I'll still advice you to use the latest version from the repository but if you're running into these kind of problems you'll know what to try. When using the 0.1 release gtk/gtk.widget.lisp will need to be patched: http://github.com/dmitryvk/cl-gtk2/commit/804b4c8f24b3725eb90f29d7e6910b2598b68771 (%gtk-widget:state and -:saved-state need to become :uint8).
Windows: I couldn't restart a Clozure CL (CCL) saved application when using the CL-GTK2 0.1 release. However the latest from Git HEAD also had issues which were resolved by commenting out (:file "gdk.threads") in gdk/cl-gtk2-gdk.asd. See: http://github.com/dmitryvk/cl-gtk2/commit/061cf59f4abaa71f92182ee8db56e023208718d0.
Windows: I had to declare the event box as "above child" for the mouse events to be caught.
Windows: The Ogre render window needs to be repositioned to 0,0. At the start it will be offset by a couple of hundred pixels.
CCL: To be fair I didn't put in the time to figure this out but I'm not sure what the top-level function given as argument to SAVE-APPLICATION needs to work like. I wasn't able to reload the foreign libraries using this function and I needed to use the :INIT-FILE argument.
SBCL: It doesn't seem to be possible to set cffi:foreign-library-directories before the saved image starts looking for them. Because of this I still need a start-up script.
CCL vs SBCL: On CCL (at least on Windows) you'll need to manually reload the foreign libraries when starting up the saved image. SBCL does this automatically.
Resizing doesn't really work well yet. Ogre::RenderWindow: update vs windowMovedOrResized vs renderOneFrame?
I wasn't able to get a configure_event to fire for the GTKEventBox nor was I able to make it available from Glade for the top level window.
I also was not able to make the destroy event for the top level window available from Glade.
How do I neatly align the text in the camera, mouse and statistics frames using Glade? I've been fooling around using different approaches but didn't succeed.
What's the easiest way to distribute an executable on Linux? :-) (don't answer this)
Ogre: When to use messagePump?
Linux: BadDrawables, I get these now and then and I've tried and tried to debug them but since they come only sporadically it's hard. What causes them? My guess would be Ogre trying to use an invalid GDK window but several different approaches to fix this were all unsuccessful.
The source-code is in a "Hey it compiles, ship it!" state, albeit a little cleaned up. Still I think it is more useful to no source-code at all. The intention was to provide a single package that would work on both Linux and Windows, hence the init.lisp script.
I got familiar with CL-GTK2 and GTK throughout this project which explains several awkward constructs in the source-code.
The demo uses keyboard scan-codes. I know this is hopeless.
I'm depending on the keyboard repeat for continuous movement instead of the key press and release events like one should for nice control and feedback. Check the Okra demos for how that should be done.
This project was developed on Linux using SBCL 1.0.31.debian and GTK 2.18.x and on both Windows XP and Vista using Clozure CL and GTK 2.16.x.
 On which I won't be spending any more work in the near future.
 I tried out several GTK and QT bindings for CL and CL-GTK2 was the easiest to get working on both Linux and Windows of the active projects.
I forgot to mention: the Windows demo will probably work on most win32 machine as long as you have 3D acceleration and proper OpenGL drivers (Direct3D didn't want to play nice with GTK). The Linux demo will work on only few machines straight away and maybe some more if you fiddle with the libraries.
Saturday, 05 December, 2009
No Lisp tag?
Saturday, 05 December, 2009