The Barium Toolkit

An X Window System toolkit for Common Lisp

Home | Gallery | Source

Barium is an X widget toolkit intended to aid the creation of desktop application graphical user interfaces (GUIs). In this capacity, it is similar to many others such as Xwt, Motif, Gtk, Qt, Tcl/tk, etc.

What makes Barium a bit special is a combination of two properties:

  1. Barium is natively implemented in Common Lisp, directly accessing the X client library and other platform libraries. It is not a wrapper for an existing non-lisp GUI toolkit. As a consequence, Barium:
    • has a simple, lispy API;
    • has no significant library dependencies;
    • works on every platform where Common Lisp and the X Window System are adequately supported;
    • has its own look and feel.
  2. Barium provides first class OpenGL support, allowing the creation of rich user interfaces mixing ordinary toolkit-provided widgets and OpenGL rendering surfaces in the same toplevel window. Barium has seamless support for multiple concurrent OpenGL rendering contexts.

Barium is aimed at use cases where the above properties play a crucial role; it is not trying to satisfy everyone. In particular, Barium is geared towards exploratory GUIs for scientific applications where the availability of high performance, hardware-accelerated rendering (OpenGL) is important, but so is the ability to dynamically create a GUI containing "traditional" widgets, updated on-the-fly in the usual style of incremental Lisp development. Regular (non-GL) widgets are rendered using Cairo.

Barium is created to serve the author's own needs (read The Barium Experiment for a narrative explanation) and is released to the public under the MIT license. Contributions are accepted subject to the same license. Please refer to the file LICENSE for the complete license.

Features and development status

At the moment, the Barium toolkit is highly experimental. Please do not build on it with the expectation that any of the exposed interfaces or functionality will remain stable. Rather, at this point Barium acts as a research vehicle and is at the same time gradually gaining features (widgets and other capabilities), incrementally added as the need for them arises. This work is far from complete.

Installation

Barium has no library dependencies other than cffi and trivial-garbage (both quasi-standard and commonly available via Quicklisp), and the actual shared libraries used to access the X window system, Cairo and OpenGL (on Linux, these files have names such as libX11.so, libcairo.so and libGL.so).

Note that Barium does not use or otherwise depend on CLX, the "de facto" standard Lisp interface to the X Window System (chiefly because CLX does not seem to have adequate support for extensions such as GLX, required for Barium's OpenGL support). Barium uses its own thin layer of CFFI bindings to all platform libraries, including Xlib.

Barium provides first-class support for creating widgets that contain an OpenGL context. However, to actually invoke OpenGL functions from Common Lisp, you also need cl-opengl. Just pull it in as a dependency via Quicklisp, and you're good to go!

Assuming SBCL or CCL on Linux with Quicklisp already set up:

  1. Clone the Barium source repository at https://git.hq.sig7.se/barium.git
  2. Create a symlink to it from ~/quicklisp/local-projects.
  3. In the REPL: (ql:quickload :barium)

First time you do this, you might find yourself in the Lisp debugger invoked by QUICKLISP-CLIENT:SYSTEM-NOT-FOUND. Note the restart called REGISTER-LOCAL-PROJECTS. Select it and you should be fine.

Barium is known to work with at least SBCL and CCL. Other conforming, modern Common Lisp implementations should work as well, but are not tested.

Example code

Most of Barium is yet to be documented in the traditional sense of the word. If you are interested in how to do stuff, the best way is to look at the source of example programs. There is a suite of small test programs that you can launch from a menu (they can also be run as standalone programs, but the menu is better for discovery).

To run test programs:

(ql:quickload :barium-test)
(ba-test:test-menu)

The test programs are written so they share a single event loop, so that many of them can be run side by side. There are also standalone demo programs. Each of these needs to be started individually, and they run by themselves in their own event loop. Look in the demo subdirectory to see them.

To run a demo program:

(ql:quickload :barium-demo)
(ba-demo:bmi-calculator)

Since demos are independent programs in their own right, you can easily build executables from them. See the build-{sbcl,ccl}.sh shell scripts. For example, after running build-sbcl.sh all demos will be built as SBCL executables. After this step, any demo can be invoked, e.g., ./molview.sbcl will run molview on SBCL.

Known issues

OpenGL-induced floating point exceptions

In certain configurations (operating systems such as OpenBSD; Common Lisp implementations such as SBCL; OpenGL implementations such as a software renderer) floating point exceptions and SIGFPE due to division by zero might be encountered when using OpenGL.

For example, provoking this on SBCL on Linux is easy when forcing OpenGL to use software rendering:

$ LIBGL_ALWAYS_SOFTWARE=true rlwrap sbcl
(ql:quickload :barium-test)
(ba-test:test-gl)

debugger invoked on a FLOATING-POINT-INVALID-OPERATION in thread
#<THREAD "main thread" RUNNING {1001358113}>:
  arithmetic error FLOATING-POINT-INVALID-OPERATION signalled

A robust workaround is to disable float traps prior to executing Barium code (this is SBCL-specific):

(sb-int:set-floating-point-modes :traps nil)

Another seemingly effective workaround is to mask float traps (again, this is SBCL-specific):

$ LIBGL_ALWAYS_SOFTWARE=true rlwrap sbcl
(ql:quickload :barium-test)
(sb-int:with-float-traps-masked (:divide-by-zero :invalid)
  (ba-test:test-menu))

More information: https://bugs.launchpad.net/sbcl/+bug/1519630

YMMV.

Wayland incompatibilities

Barium can be run on Wayland via XWayland, and things will mostly work. However, there are a couple known issues:

  • Grabs are not supported by Wayland, which means that popup window behaviour will slightly differ. In particular, the user will be able to interact with the rest of the desktop regardless of the grab.
  • Putting a periodically refreshing OpenGL scene on a different (non-visible) workspace might stall the event processing.
  • Performance regressions.

At this point it is not the primary goal of Barium to be fully Wayland-compatible; issues will be debugged and fixed subject to available resources.