How would I change the wallpaper on a Linux desktop (using GNOME) within a C/C++ program? Is there a system API to do it?
Asked
Active
Viewed 7,994 times
7

Kirill V. Lyadvinsky
- 97,037
- 24
- 136
- 212

nonpolynomial237
- 2,109
- 4
- 27
- 35
-
1If you figure out how, please do it, I've wanted to be able to do that for some time. – fauxCoder Aug 03 '09 at 06:00
3 Answers
19
You could use gconf library to do it. The following sample is a complete program to change background:
// bkgmanage.c
#include <glib.h>
#include <gconf/gconf-client.h>
#include <stdio.h>
typedef enum {
WALLPAPER_ALIGN_TILED = 0,
WALLPAPER_ALIGN_CENTERED = 1,
WALLPAPER_ALIGN_STRETCHED = 2,
WALLPAPER_ALIGN_SCALED = 3,
WALLPAPER_NONE = 4
} WallpaperAlign;
gboolean set_as_wallpaper( const gchar *image_path, WallpaperAlign align )
{
GConfClient *client;
char *options = "none";
client = gconf_client_get_default();
// TODO: check that image_path is a file
if ( image_path == NULL ) options = "none";
else {
gconf_client_set_string( client,
"/desktop/gnome/background/picture_filename",
image_path,
NULL );
switch ( align ) {
case WALLPAPER_ALIGN_TILED: options = "wallpaper"; break;
case WALLPAPER_ALIGN_CENTERED: options = "centered"; break;
case WALLPAPER_ALIGN_STRETCHED: options = "stretched"; break;
case WALLPAPER_ALIGN_SCALED: options = "scaled"; break;
case WALLPAPER_NONE: options = "none"; break;
}
}
gboolean result = gconf_client_set_string( client,
"/desktop/gnome/background/picture_options",
options,
NULL);
g_object_unref( G_OBJECT(client) );
return result;
}
int main(int argc, const char* argv[])
{
if ( argc > 1 ) {
printf( "Setting %s as wallpaper... ", argv[1] );
if ( set_as_wallpaper( argv[1], WALLPAPER_ALIGN_STRETCHED ) ) printf( "Ok\n" );
else printf( "Failed\n" );
} else printf( "Usage: ./bkgmanage <filename>\n" );
return 0;
}
The source above is based on gthumb project. It could be compiled with the following string:
gcc -Wall -g `pkg-config --libs --cflags glib-2.0 gconf-2.0` bkgmanage.c -o bkgmanage

Kirill V. Lyadvinsky
- 97,037
- 24
- 136
- 212
10
Though the question was gnome-specific, there's also a way to deal with the wallpaper that is not depepndant on the higher layer toolkits. You should be able to deal with the root window (which the wallpaper is, in fact) by studying the source of xsetroot.c, the most interesting part of which I copypaste here:
static void
SetBackgroundToBitmap(Pixmap bitmap, unsigned int width, unsigned int height)
{
Pixmap pix;
GC gc;
XGCValues gc_init;
gc_init.foreground = NameToPixel(fore_color, BlackPixel(dpy, screen));
gc_init.background = NameToPixel(back_color, WhitePixel(dpy, screen));
if (reverse) {
unsigned long temp=gc_init.foreground;
gc_init.foreground=gc_init.background;
gc_init.background=temp;
}
gc = XCreateGC(dpy, root, GCForeground|GCBackground, &gc_init);
pix = XCreatePixmap(dpy, root, width, height,
(unsigned int)DefaultDepth(dpy, screen));
XCopyPlane(dpy, bitmap, pix, gc, 0, 0, width, height, 0, 0, (unsigned long)1);
XSetWindowBackgroundPixmap(dpy, root, pix);
XFreeGC(dpy, gc);
XFreePixmap(dpy, bitmap);
if (save_colors)
save_pixmap = pix;
else
XFreePixmap(dpy, pix);
XClearWindow(dpy, root);
unsave_past = 1;
}

Bhawani Singh
- 3
- 2

Andrew Y
- 5,107
- 2
- 28
- 29
2
If nothing else, you could probably use system()
to invoke one of the command lines suggested here:
http://www.linuxquestions.org/questions/linux-general-1/change-background-via-command-line-350936/

Amber
- 507,862
- 82
- 626
- 550
-
2
-
1If you go to post #5 in the thread, a gconftool-2 command is mentioned that sets the background picture in GNOME. – Amber Aug 03 '09 at 07:45
-
2OK. Finally found it. Would have been more helpful if you pasted that line in your post (along with the link), though. – innaM Aug 03 '09 at 08:24
-
the command is gconftool-2 --type string --set /desktop/gnome/background/picture_filename /path/to/image.jpg – lcapra Feb 25 '20 at 12:03