logo

xlivebg manual


Table of Contents


About xlivebg

Xlivebg is a live wallpaper framework, and collection of live wallpapers, for the X window system. It provides all the groundwork necessary for displaying animated graphics with OpenGL on the root window, so that a variety of live wallpapers can be written without having to deal with how to tie everything to the X window system, how to create the OpenGL context itself, or how to present any configurable parameters of the live wallpaper to the user.

A live wallpaper under xlivebg, is simply a small program compiled as a shared library, which provides a number of callbacks to be called by xlivebg (initialization, cleanup, drawing, etc), and (optionally) a list of user-configurable options, to be presented on the wallpaper configuration GUI. See the section on "writing live wallpaper plugins" for details.

Xlivebg and its wallpaper plugins are configurable by a simple text-based configuration file. Configuration options can be changed on the fly, by sending commands to a running xlivebg instance from the command line, or through the GUI configuration tool which provides an easy way to tweak all the options interactively. See the section on "configuration" for details.

License

Copyright © 2019-2020 John Tsiombikas <nuclear@member.fsf.org>

Xlivebg is free software. Feel free to use, modify, and/or redistribute it under the terms of the GNU General Public License version 3, or at your option any later version published by the Free Software Foundation. See http://www.gnu.org/licenses/gpl-3.0.html for details.


Installation

The xlivebg distribution comes with four things:

Xlivebg is distributed as source code. So unless your operating system distribution comes with a pre-compiled package for xlivebg, you'll need to build it in order to install it. Fret not however, as in writing xlivebg extra care was taken to minimize dependencies to an absolute minimum, and make it very easy to build.

3rd party pre-compiled xlivebg packages are available from:

If you're distributing a pre-compiled xlivebg package and you're not in this list, contact me to add a link to your package.

Getting the xlivebg source

To download the latest official release of xlivebg, head over to the xlivebg web site, or to the github releases page.

Alternatively, you may grab the current source code from the git repository, by running: git clone https://github.com/jtsiomb/xlivebg.

Build instructions

To build xlivebg you first need to make sure you have the following dependencies installed:

Additionally, to build the xlivebg-gui configuration tool, you need the motif toolkit.

Tip: on Debian or Ubuntu and their derivatives, you can install all required dependencies with the following command:
apt install libx11-dev libxext-dev libxrandr-dev libglx-dev libglu1-mesa-dev libpng-dev libjpeg-dev libmotif-dev

Then to build and install everything, change into the directory where you extracted the xlivebg archive, or checked out from the xlivebg repository, and run:

./configure
make
make install-all

Make sure to run the last command as root, if you're installing on a system-wide prefix. Also check out ./configure --help for the available build options.

This will install all components of xlivebg, including the GUI configuration tool, and the bundled plugins. If you'd rather just install only the main xlivebg program, use make install instead, and then tou can separately install the other components with make install-plugins, and make install-gui as needed.

If you wish to exclude any specific bundled wallpaper plugins from the build, you may disable them by passing the --disable-plugin-<name> option to configure for each plugin you wish to disable. For to disable the "ripple" wallpaper plugin, you may invoke configure like so:

./configure --disable-plugin-ripple

Live wallpaper plugin directories

Xlivebg searches for live wallpaper plugins in the following locations:

Where PREFIX is the installation prefix. So for instance, if xlivebg was installed (as is the default) under /usr/local, the first plugin lookup directory would be /usr/local/lib/xlivebg.

If multiple locations contain plugins, all of them are collected and made available, unless there are two plugins with the same name, in which case only the first one encountered is used.

Hacking tip: in debug builds of xlivebg (NDEBUG not defined), the current directory is checked for the presence of a plugins subdirectory, and xlivebg attempts to use any shared libraries (anything with a .so suffix) under that directory, as a live wallpaper plugin. This makes hacking on live wallpaper plugins in the xlivebg source tree easier, as there's no need to install the plugins all the time for trying out changes.

Configuration

Configuration file

Xlivebg looks for the configuration file in the following locations, listed in search order:

The search for configuration files stop at the first one that exists, so the ones higher in that list, override any of the following if they also exist. Therefore you can have a global configuration file, with site-wide defaults for all users, and each user is able to copy it to their home directory and tweak its contents.

Warning: sending the "save" command to xlivebg, or chosing to "save configuration" from the GUI, will overwrite the second file on the list above, if it already exists. Make sure to save a backup copy of that file, if you made any manual configuration changes, before attempting to use the GUI configuration utility.

All the available configuration options for xlivebg and all bundled plugins from the official distribution, are detailed in comments in the example configuration file under docs/xlivebg.conf.

xlivebg-gui: interactive GUI configuration tool

GUI configuration tool

The easiest way to configure xlivebg, is through the GUI configuration tool which comes with the xlivebg distribution: xlivebg-gui. When you run the configuration tool it will attempt to connect to a running instance of xlivebg, and retrieve the current settings. Then it will present an intuitive user interface, which enables switching live wallpaper plugins, or interactively control all the tweakable parameters of xlivebg and the currently running live wallpaper plugin.

Any change performed in the configuration tool UI is immediately reflected in the running wallpaper, but the change is not made permanent, and will be lost when xlivebg exits, until a save is performed, either through the File menu, or the Save configuration button in the main window. This way you can play with all the settings, to see their effect, without fear of messing up your current configuration.

The configuration GUI is split into two halves halves horizontally. The left half of the UI is dedicated to selecting which wallpaper to use, and setting global options which are available to (but not necessarily used by) all wallpapers. The right pane presents controls for all the tweakable parameters of the currently active wallpaper plugin.

xlivebg-cmd: command-line interactive control

During installation, a symbolic link is created to xlivebg, under the name xlivebg-cmd. When xlivebg is invoked as xlivebg-cmd, or alternatively if it gets cmd as the first argument, it runs in client mode, trying to connect to an existing xlivebg instance and send commands to it.

Running xlivebg-cmd help shows the list of commands available:

Usage: xlivebg-cmd <command> [cmd-args]
Commands:
  ping: check to see if xlivebg is running
  save: save current settings to user configuration file
  getupd: print the current graphics update rate
  list: get list of available live wallpapers
  switch <name>: switch live wallpaper
  lsprop [name]: list properties of named or current live wallpaper
  setprop <type> <property> <value>: sets a property
  getprop <type>: prints the current value of a property
  help: print usage and exit

  <type> is one of: text, number, integer, vector
  <property> must be a full option pathname. For example: "xlivebg.image" or
        "xlivebg.stars.speed". not just "image" or "speed".

Bundled live wallpapers

Xlivebg comes bundled with a number of live wallpaper plugins.

Color cycling animation wallpaper

colcycle

Colcycle shows animated images utilizing the classic palette-cycling technique. Supported file formats are LBM (ILBM/PBM/IFF), and JSON files from the canvascycle website.

The colcycle live wallpaper plugin is derived from the colcycle image viewer, and you can refer to its wiki page for instructions on how to download some excellent color-cycling images to use with it.

Plugin: colcycle

optiontypedescription
imagefilepathcolor-cycling image to use (LBM or canvascycle-JSON)

Image distortion wallpaper

distort

Distort performs an animated distortion effect on the whole, or selected parts, of a background image. Distorting the whole image works very well for abstract or underwater background images, while having it affect only parts of the image is a powerful way to produce subtle animated backgrounds, where only the reflection in a pond moves, or the underwater part of a half-submerged-camera photograph is rippling.

To specify the parts of the background that should distort, you need to create an animatiom mask image (see configuration option: anim_mask), which should be black wherever the image should be static, white where the distortion needs to happen, and ideally smooth transitions in between.

anim_mask UI field

Plugin: distort

optiontypedescription
amplitudenumberamplitude of the distortion
frequencynumberspatial frequency of the distortion

Starfield wallpaper

stars

A starfield effect with a bunch of configurable parameters, such as density, speed, star size and color, and the option for the virtual "camera" to follow the mouse pointer around the screen.

Plugin: stars

optiontypedescription
countintegertotal number of stars
speednumbertravel speed through the starfield
sizenumberstar size
colorvectorstar color
follownumbermaximum displacement while following the mouse pointer (0 to disable)
follow_speednumbermouse following speed

Water ripples wallpaper

ripple

Water ripples emanating from the movement of the mouse pointer, and optionally from random raindrops. The ripples refract the background image as they start, propagate, reflect on the sides of the screen, and eventually die down.

Plugin: ripple

optiontypedescription
raindropsnumbernumber of raindrops to spawn per second (0 to disable)

Writing live wallpaper plugins

Even though xlivebg comes with a set of builtin wallpapers, it's main purpose is to be a framework for enabling the creation of 3rd party live wallpapers. The builtin wallpapers are mostly intended as examples of what can be done, rather than provide the total sum of wallpapers for end users. To this end, xlivebg provides an API for writing 3rd party live wallpapers, designed to be as unobtrusive as possible, and yet to make it extremely simple to write live wallpapers. Essentially xlivebg handles all the interactions with the X window system, sets up an OpenGL context on an appropriate drawable, and gets out of the way of the live wallpaper plugin, providing only a mechanism for settings, information about the screens and their geometry, and a certain number of helper functions which can be used at the plugin writer's discretion to make it dead-simple to do the right thing while drawing with OpenGL.

Minimal xlivebg wallpaper plugin

The best way to explain how to write live wallpapers, is to go through a simple example. Such a minimal example plugin, is included with the xlivebg distribution, under the doc/minimal_plugin directory.

How to build

The simplest way to build and iterate on a live wallpaper, is to place it under plugins in the xlivebg source tree. So as the first step, go on and copy the minimal_plugin directory as plugins/minimal. To build it, simply type make while in the plugin directory, or the xlivebg root.

To build a live wallpaper, all you need is to compile it as a shared library, and make sure it can include the xlivebg.h header file, which is installed under <installation prefix>/include. So feel free to use your own out-of-tree build system if you prefer. There's no need to link with any xlivebg libraries (there aren't any); calls to the xlivebg API entry points are left unresolved, and are left to the dynamic loader to resolve them at load time from symbols in the xlivebg executable itself.

When xlivebg is compiled with debug enabled, it will automatically look into the plugins directory to find wallpapers when executed from the project root, so there's no need to install the minimal example, or any other live wallpaper you're working on, in order to try your changes. Try that now: make sure you have compiled xlivebg without the --disable-debug configure option, and run it from the xlivebg root directory like so: ./xlivebg. The message xlivebg: registered plugin: minimal should appear on the terminal, and the minimal wallpaper should be used if you have active = "minimal" in your config file.

If you use the example Makefile for your own plugins, at minimum you need to change the name variable at the top, and just include ../plugin.mk. If you need to pass additional flags to the C compiler, set the plugin_cflags variable before the include line, and similarly for linker flags set the plugin_ldflags variable.

Source code overview

Live wallpapers typically start by including <xlivebg.h>, for the xlivebg API, and <GL/gl.h>, to be able to call OpenGL functions for drawing.

Every live wallpaper needs to define a register_plugin function, which calls xlivebg_register_plugin passing a pointer to an xlivebg_plugin structure to it, in order to register itself. This function is called automatically by xlivebg for every plugin it attempts to load.

The plugin structure is defined in xlivebg.h:

struct xlivebg_plugin {
    char *name, *desc;
    char *props;	/* list of properties this plugin uses (to restart or call prop when any change) */
    long upd_interval;	/* requested update interval in microseconds */
    xlivebg_init_func init;		/* called during init, with a valid OpenGL context */
    xlivebg_cleanup_func cleanup;	/* called during shutdown (optional) */
    xlivebg_start_func start;	/* called when the plugin is activated (optional) */
    xlivebg_stop_func stop;		/* called when the plugin is deactivated (optional) */
    xlivebg_draw_func draw;		/* called to draw every frame */
    xlivebg_prop_func prop;		/* called when a property in props has changed (optional) */

    void *data, *so;
};

name is a mandatory field, which must point to a string with the identifying name of the wallpaper. The name is used for selecting the active plugin, and as part of the configuration option pathnames, and must be unique. If multiple plugins with identical names are located in the plugin search directories, only the first one is loaded, the rest are ignored.

desc should be a short description of what the live wallpaper does. It might be presented as part of the user configuration UI, but has no other purpose at the moment.

props is an optional string to declare a list of tweakable properties the plugin responds to at runtime. Usually these properties should be the same as whatever configuration options are heeded by the plugin, so that they can all be tweaked interactively by the user. This list is used by the configuration tool to generate the plugin-specific configuration user interface. If left null, no plugin-specific options will be presented in the GUI. The properties list uses a very simple hierarchical curly-brace notation, describing the type and values accepted for each property. Search for PROPLIST in all the bundled plugins to see examples of the syntax.

upd_interval defines how often the plugin draw function should be called, in microseconds. It's recommended to keep this interval as large as possible (and therefore the framerate as low as possible), to avoid high CPU usage. This value can be changed at any time during the execution of the live wallpaper if there's need to vary the interval. Redraw times are approximate, and also the user can override this with the fps option, so don't rely on being called at exactly the same interval you asked for.

Finally there's a list of function pointers you can define, out of which only the draw function is mandatory:

In the case of the minimal example we can see the xlivebg_plugin structure definition and the register_plugin function near the top:

#define PROPLIST \
    "proplist {\n" \
    "    prop {\n" \
    "        id = \"speed\"\n" \
    "        desc = \"animation speed\"\n" \
    "        type = \"number\"\n" \
    "        range = [0, 10]\n" \
    "    }\n" \
    "}\n"

static struct xlivebg_plugin plugin = {
    "minimal",
    "Minimal live wallpaper example",
    PROPLIST,
    XLIVEBG_20FPS,
    init, 0,
    start, 0,
    draw,
    prop,
    0, 0
};

int register_plugin(void)
{
    return xlivebg_register_plugin(&plugin);
}

The plugin defines a single property of type number, with range of values between 0 and 10. Declares its identifying name to be minimal, its update rate to be the microsecond equivalent of 20 frames per second, and defines four callbacks: init, start, draw, and prop.

The initialization function simply sets a default value for the only config option used by the plugin. It's often necessary to define a default value, otherwise the configuration UI might misbehave if there is no default value, nor any user configuration option for a property:

static int init(void *cls)
{
    xlivebg_defcfg_num("xlivebg.minimal.speed", 1.0f);
    return 0;
}

The start function is usually where you create any OpenGL objects you're going to need, such as textures, shaders, and so on. It should return 0 for success, or -1 for failure. In the case of the minimal plugin, the only thing it does is to retrieve the current value of the "speed" configuration option, indirectly by calling the prop function manually, which otherwise would only be called if that value changes externally:

static int start(long tmsec, void *cls)
{
    prop("speed", 0);
}

static void prop(const char *prop, void *cls)
{
    if(strcmp(prop, "speed") == 0) {
        speed = xlivebg_getcfg_num("xlivebg.minimal.speed", 1.0f);
    }
}

The first thing the draw function needs to do, is clear the screen (ideally by calling xlivebg_clear, which handles clearing according to the user-selected background color and mode (solid color or vertical/horizontal gradient). If there's no way to see the background color behind the effect implemented by the live wallpaper, there's no need to clear the framebuffer.

While the OpenGL context is bound to a single drawable spanning all screens in a multi-screen scenario, it usually makes sense to treat drawing as separate for each screen, by looping over the screens and setting up an appropriate OpenGL viewport transformation for each. In this case the example code calls xlivebg_screen_count to determine the number of screens, and inside the loop for each screen, it calls the xlivebg_gl_viewport helper to set up the GL viewport.

num_scr = xlivebg_screen_count();
for(i=0; i<num_scr; i++) {
    xlivebg_gl_viewport(i);    /* set the viewport for each screen */

    if((img = xlivebg_bg_image(i))) {    /* grab the selected background image */
        /* compute the transformation necessary to fit the image to screen correctly */
        xlivebg_calc_image_proj(i, (float)img->width / img->height, xform);
        glMatrixMode(GL_PROJECTION);
        glLoadMatrixf(xform);

        glBindTexture(GL_TEXTURE_2D, img->tex);
        glEnable(GL_TEXTURE_2D);

        /* draw a fullscreen quad with texture coordinates and vertex positions */
        glBegin(GL_QUADS);
        /* ... glVertex2f and glTexCoord2f calls ... */
        glEnd();
    }
}

The xlivebg_bg_image function takes the screen number as an argument, and returns a pointer to a struct xlivebg_image structure for the currently selected background image. This structure has a tex field with the OpenGL texture id corresponding to this image, which can be used to draw it as a texture-mapped fullscreen quad. Of course not all wallpaper plugins need to use "the background image" if it doens't make sense to do so.

Another interesting mechanism at play here has to do with how to fit a background image of an arbitrary aspect ratio, to the screen with its own arbitrary aspect ratio in a pleasing manner. The user has the option to select to either stretch the image to fill the whole screen, show the whole image, potentially leaving black (or background-colored) bars if the image aspect ratio doesn't match the screen's, or crop it with a user-controllable zoom and pan factor. To implement all that correctly, xlivebg provides the xlivebg_calc_image_proj helper, which returns the projection matrix which can be used to simply draw a fullscreen [-1, 1] quad, and have it transformed appropriately to satisfy the fit option. Again for some wallpapers this will not be useful or necessary, but it's convenient if it happens to be applicable.

xlivebg API reference

List of all the function provided by the xlivebg API. For more details about the xlivebg_plugin structure see the discussion in the pre class="code"vious section, and for everything else refer to the header file itself: xlivebg.h.

xlivebg_register_plugin

int xlivebg_register_plugin(struct xlivebg_plugin *plugin)

Needs to be called by the plugin's register_plugin function, to provide the xlivebg_plugin structure to the live wallpaper system. See discussion in the pre class="code"vious section for details.

Returns -1 if plugin registration fails

xlivebg_screen_count

int xlivebg_screen_count(void)

Returns the number of screens covered by the wallpaper window.

xlivebg_screen

struct xlivebg_screen *xlivebg_screen(int scr_idx)

Returns a pointer to a sturcture with per-screen information, for the specified screen (0-based index). See the header file for details on the screen structure.

xlivebg_bg_image

struct xlivebg_image *xlivebg_bg_image(int scr_idx)

Returns a pointer to an xlivebg_image structure for the background image selected for this screen (0-based index), or null if no background image is selected. See the header file for details on the image structure.

xlivebg_anim_mask

struct xlivebg_image *xlivebg_anim_mask(int scr)

Returns a pointer to an xlivebg_image structure for the selected animation mask. The concept behind the animation mask, is that the user can provide a monochrome image to mask areas of the screen to animate or remain static. What this means for each wallpaper, if anything, is left open. If no animation mask is selected, null is returned.

xlivebg_memory_image

int xlivebg_memory_image(struct xlivebg_image *img, void *data, long datasz)

Creates an xlivebg_image by parsing an in-memory image file blob. The second argument is the pointer to the memory buffer, while the third argument specifies its size in bytes. Supported file formats: PNG, JPEG, TGA, PPM/PGM, LBM/PBM, RGBE

Note: To allow this function to be usable without an OpenGL context (callable from init), it does not attempt to create the texture corresponding to this image, and therefore the tex field will be null. To force the creation of the OpenGL texture before use, make sure to call xlivebg_image_texture instead of accessing the tex field directly.

Returns 0 for success, and -1 for failure.

xlivebg_image_texture

unsigned int xlivebg_image_texture(struct xlivebg_image *img)

Returns the OpenGL texture id corresponding to this xlivebg_image, making sure to create the OpenGL texture first if it's not already created.

xlivebg_fit_mode

int xlivebg_fit_mode(int scr)

Returns the selected fit mode for background images:

xlivebg_crop_zoom

float xlivebg_crop_zoom(int scr)

Returns the selected zoom factor for the crop fit mode. Typically a value between 0 and 1, with 0 being equivalent to the "full" fit mode leaving visible bars if the aspect ratio doesn't match, and 1 being fully zoomed in with no background visible, and a configurable panning for the cropped dimension (see xlivebg_crop_dir).

xlivebg_crop_dir

void xlivebg_crop_dir(int scr, float *dirvec)

Expects an array of two floats in the second argument, and writes the amount of panning to be used for each direction in case cropping makes it larger than the visible frame.

xlivebg_havecfg

int xlivebg_havecfg(const char *cfgpath)

Takes a configuration property path, and returns 1 if it exists, or 0 if it's not defined. Path example: xlivebg.stars.count corresponds to a configuration property defined as

xlivebg {
    stars {          # stars wallpaper options
        count = 100  # number of stars
    }
}

xlivebg_getcfg_str

const char *xlivebg_getcfg_str(const char *cfgpath, const char *def_val)

Returns a pointer to a "string" configuration property. If the property is undefined, def_val is returned.

xlivebg_getcfg_num

float xlivebg_getcfg_num(const char *cfgpath, float def_val)

Returns the value of a "number" configuration property. If the property is undefined, def_val is returned.

xlivebg_getcfg_int

int xlivebg_getcfg_int(const char *cfgpath, int def_val)

Returns the value of an "integer" configuration property. If the property is undefined, def_val is returned.

xlivebg_getcfg_vec

float *xlivebg_getcfg_vec(const char *cfgpath, float *def_val)

Returns a pointer to the value of a "vector" configuration property. If the property is undefined, def_val is returned.

xlivebg_setcfg_str

int xlivebg_setcfg_str(const char *cfgpath, const char *str)

Sets the value of a string configuration property. Returns 0 for success, -1 for failure.

xlivebg_setcfg_num

int xlivebg_setcfg_num(const char *cfgpath, float val)

Sets the value of a number configuration property. Returns 0 for success, -1 for failure.

xlivebg_setcfg_int

int xlivebg_setcfg_int(const char *cfgpath, int val)

Sets the value of an integer configuration property. Returns 0 for success, -1 for failure.

xlivebg_setcfg_vec

int xlivebg_setcfg_vec(const char *cfgpath, float *vec)

Expects a pointer to an array of 4 floats, and sets the value of a vector configuration property. Returns 0 for success, -1 for failure.

xlivebg_rmcfg

int xlivebg_rmcfg(const char *cfgpath)

Undefines a configuration property. Returns 0 for success, -1 for failure.

xlivebg_defcfg_str

int xlivebg_defcfg_str(const char *cfgpath, const char *str)

Set the default value of a string configuration property, to be returned by the equivalent "get" function if the property is not defined. Returns 0 for success, -1 for failure.

xlivebg_defcfg_num

int xlivebg_defcfg_num(const char *cfgpath, float val)

Set the default value of a number configuration property, to be returned by the equivalent "get" function if the property is not defined. Returns 0 for success, -1 for failure.

xlivebg_defcfg_int

int xlivebg_defcfg_int(const char *cfgpath, int val)

Set the default value of an integer configuration property, to be returned by the equivalent "get" function if the property is not defined. Returns 0 for success, -1 for failure.

xlivebg_defcfg_vec

int xlivebg_defcfg_vec(const char *cfgpath, float *vec)

Expects an array of 4 floats as its second argument, and sets the default value of a vector configuration property, to be returned by the equivalent "get" function if the property is not defined. Returns 0 for success, -1 for failure.

xlivebg_gl_viewport

void xlivebg_gl_viewport(int scr_idx)

Calls glViewport to set the viewport transformation which can be used to draw to the specified screen (0-based screen index).

xlivebg_clear

void xlivebg_clear(unsigned int clear_mask)

Handles clearing the screen according to the background color and mode (solid color, vertical/horizontal gradient) selected by the user. It takes the same argument expected by glClear, so that it can clear the depth and stencil buffers at the same time if required.

xlivebg_calc_image_proj

void xlivebg_calc_image_proj(int scr_idx, float img_aspect, float *xform)

Takes a screen number, the aspect ratio of the background image, and a pointer to an array of 16 floats, and calculates the projection matrix necessary to transform a fullscreen [-1, 1] quad to the screen in a way that conforms to the user-selected fit mode (see xlivebg_fit_mode). This matrix is in OpenGL-native order, and can be passed directly to glLoadMatrixf or glUniformMatrix4f without transposing it.

xlivebg_gl_image_proj

void xlivebg_gl_image_proj(int scr_idx, float img_aspect)

This is a convenience function, equivalent to:

float matrix[16];
xlivebg_calc_image_prog(scr_idx, aspect_ratio, matrix);
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(matrix);

xlivebg_mouse_pos

void xlivebg_mouse_pos(int *mx, int *my)

Returns the current mouse position in pixels, through the mx and my pointer arguments.


Frequently Asked Questions

1. I'm running a standalone compositor (like xcompmgr), and xlivebg does nothing, or produces a corrupted picture

Try passing the -n option to xlivebg, to instruct it to create its own "desktop" window, instead of trying to draw on the root or virtual root.