framebuffers

0.0.0

About Framebuffers

This library implements direct access to underlying operating system framebuffer mechanisms, including input handling. With it you can create native windows on Windows (win32), Linux (x11/wayland), Mac (Cocoa), and Mezzano, all without relying on external C libraries.

How To

A trivial example is as follows, assuming org.shirakumo.framebuffers is locally nicknamed to fb:

(fb:with-window (w :size '(800 . 600))

This will open a window and start its event loop. When the user requests a close, it'll automatically close it and clean it back up again.

To watch what events are going on, we can add a catchall handler:

(fb:with-window (w :size '(800 . 600))
  (T (type &rest args)
    (print (list* type args))))

However, this being a framebuffer library, you're likely most interested in how to actually push pixels to the screen. Let's fill the window with a repeating gradient:

(fb:with-window (w :size '(800 . 600))
  (fb:window-refreshed ()
    (fb:do-pixels (buf i x y) w
      (setf (aref buf (+ 0 i)) (mod x 256))
      (setf (aref buf (+ 1 i)) (mod y 256))
      (setf (aref buf (+ 2 i)) 0)
      (setf (aref buf (+ 3 i)) 255))
    (fb:swap-buffers w)))

do-pixels simply iterates over the pixels in the backing buffer, using an BGRA layout. You can use whatever method you like to fill the buffer with pixel data, and call swap-buffers to display it.

The API also exposes various functions to manage the window properties and let you handle events that occur. Please refer to the documentation of window and event-handler for a listing of each.

Controlling the Event Loop

The previously used with-window macro uses a dynamically established event handler to let you conveniently create an event loop. However, for larger projects you'll usually want a more decentralised code structure, in which case you'll instead want to manually manage the loop and how events are handled. To do so, you'll first want to define your own event-handler class, and methods for the events you care about:

(defclass event-handler (fb:event-handler) ())

(defmethod fb:key-changed ((handler event-handler) key scan-code modifiers)
  (print key))

Then when you create your window using open, pass an instance of your event handler as an initarg.

(fb:open :event-handler (make-instance 'event-handler))

Alternatively you can set it later using the event-handler accessor. The window object returned by open is specific to the type of backend used, which is why you must use an event-handler subclass to specialise methods on, instead.

In order to retrieve the associated window for the handler within a callback method, simply use the window accessor function.

Once you have your window instance, you must periodically call process-events on it in order to handle whatever has been queued for it. process-events also has a couple of options to more efficiently wait for events in a loop.

Supported Backends

Currently this library supports the following backends:

  • Wayland

  • Win32

  • X11

System Information

0.0.0
Yukari Hafner
zlib

Definition Index