This article explains how to cycle randomly through a directory structure of graphic images and display them on your desktop background. GNOME, KDE and other X desktops/window managers are covered. This is a good exercise in shell scripting and piping, and it shows off the programs find and xargs. We also cover how to select only images of a given size, say 1024x768.
So, you have a broadband connection to the Net, and you have a lot of nice images you'd like to display in your desktop background. Because you use wget's -r option to get your images, you also have a nice directory structure mirroring your source Web sites. In fact, it would be really nice if you could cycle through them at random. You also would like to use it with any desktop or window manager that runs on XFree86. On the way, you'd like to learn a few useful shell scripting techniques.
The result is a shell script, called Wallpaper, shown in Listing 1. You can make variants, such as Wallpaper1024x768 or WallpaperAirplanes, by changing some variables.
The first thing to do in our script is to specify to the shell that this is a shell script, with the traditional "shebang", #! line. Next, include a time stamp and a brief description of what the script does.
Now you need a short function that prints out an error message. The larger a script is, the more possible errors there are, so it is a good idea to do this as a function. Then, you can call the function from any place your code might detect an error.
Now, we set up some standard variables; you probably want to change them for your computer. You also have the option to override them from the command line. $imagepath is the absolute path, the path from root, to the top of the directory tree where all our images are stored. $duration indicates how long to wait, in seconds, between slides.
$size is a regular expression, suitably escaped or modified to prevent shell expansion, used to select the size(s) of the images we are going to use. As you can see from the default, we can select multiple sizes by specifying a suitable regex. The shell uses some characters, such as open and close parentheses, the vertical bar and the ampersand, for its own purposes. By preceding each one with a backslash, we prevent the shell from interpreting those characters and force the shell to pass them intact to our program. The backslash is the shell's escape character.
The final variable sets our verbosity level. With $verbosity turned on, Wallpaper leaves a trail of the image names it displays and shows other information.
The next several lines take our command-line options (if any) and process them. We pass the built-in function getops a string that indicates which options we accept, and we indicate with a colon which ones expect a parameter. For example, the first option we accept is -d, and it accepts a parameter. We also pass to getopts the variable Option. As we process options, the contents of Option indicates which option we're working on.
The case statement processes the options. For example, the parameter of the -d option is used to set the duration, the time between images. Other parameters override the default path, size and verbosity values. You are welcome to add more options to override other variables, such as the names of the files for which we're looking.
The next bit of code tests which desktop we are using. This is important because GNOME doesn't let us use the same technique to display our wallpaper that other window managers or desktops use. This test works on Red Hat distributions, and it may work on other distributions. If it doesn't work on your computer, you may have to do some detective work. Alternatively, you could hard code it in your private copy of the script. As we see about five lines down, if the variable desktop equals 0, we're running GNOME; otherwise we're running something else.
The next three lines show some of the parameters if $verbosity is turned on, which is useful for debugging. Next, we determine if we are running GNOME. X allows programs to write directly to the background. In X nomenclature, this is the root window, and all other windows are children of the root window. As we'll see later on with the non-GNOME branch of the code, we can use any number of programs to write to the root window. But GNOME doesn't let us write to the root window, so we have to do something else.
GNOME allows us to set all sorts of characteristics by using a tree structure of variables. If you look at that structure in the program gconf-editor, it looks suspiciously like Windows' registries. Fortunately, it is implemented in a much more robust manner. The superficial resemblance allows those familiar with Windows' registries to work with GNOME's configuration. The background characteristics are set at /desktop/gnome/background/, and the two entries that interest us right now are picture_options and background.
picture_options determines the way GNOME displays the background. The value must be a text string, one of Wallpaper, Centered, Scaled, Stretched or No Picture. For our purposes, the last is useless; if picture_options is set to No Picture, GNOME can't display our pictures. For more information on what these do, see "1.2. Customizing the Desktop Background" under "Using the Basic Preference Tools" in the GNOME help. Or, use the background preferences tool (Start Here icon on your desktop --> Preferences --> Background) to experiment with them.
Fortunately, we are not restricted to a GUI tool to set options. We can use gconftool-2 to set our picture options, in this case to scaled.
The next thing we need to do is build an array in Bash, called pictures, and populate it with the files to be displayed. We use two different lines of code, depending on whether a $size has been specified. If no size is specified, we use find to search the image tree for files that fit the file specification *.jpg. We pipe the results of that to another program, called randomize. More on how randomize works comes later on; for now treat it as a black box.
If we have a size specified, things get a bit hairier. We take the output from find and pipe it to the ImageMagick tool identify. identify examines a file and returns all sorts of interesting information about it. Fortunately, we can use a format string rather like sprintf's format string to indicate exactly what information we want and how identify should show it. We specify that we want the path to it, a literal slash, followed by the file name. That is followed by a space, the width, a literal x and then the height.
- High-Availability Storage with HA-LVM
- DNSMasq, the Pint-Sized Super Dæmon!
- Localhost DNS Cache
- Real-Time Rogue Wireless Access Point Detection with the Raspberry Pi
- Days Between Dates: the Counting
- Linux for Astronomers
- You're the Boss with UBOS
- The Usability of GNOME
- PostgreSQL, the NoSQL Database
- Multitenant Sites