PDA

View Full Version : Programmably change the desktop background



el_supremo
08-04-2004, 06:22 PM
I can change the desktop background by right clicking on it and going through the resulting menu but I'd like to be able to write a program which cycles through my chosen backgrounds by selecting a new one on each reboot.
How can a program specify which image is to be used as the background?

Best Wishes
Pete

UnderScore
08-04-2004, 06:47 PM
The following examples were used on Knoppix 3.4 5-17 boot from CD.


knoppix@0[knoppix]$ grep -r background.jpg /home/knoppix/.k*
grep: /home/knoppix/.kde/socket-Knoppix/klauncherZYhkEb.slave-socket: No such device or address
grep: /home/knoppix/.kde/socket-Knoppix/kdeinit-:0: No such device or address
grep: /home/knoppix/.kde/socket-Knoppix/kdeinit__0: No such device or address
/home/knoppix/.kde/share/config/kdesktoprc:CurrentWallpaper=/cdrom/KNOPPIX/background.jpg
/home/knoppix/.kde/share/config/kdesktoprc:Wallpaper=/cdrom/KNOPPIX/background.jpg

According to the above output, the default KNOPPIX background is called at /cdrom/KNOPPIX/background.jpg.


knoppix@0[knoppix]$ sed -e 's/\/cdrom\/KNOPPIX\/background.jpg/\/home\/knoppix\/wp\/MyGreatWallpaper.jpg/g' .kde/share/config/kdesktoprc
That code will perform a substitution of /home/knoppix/wp/MyGreatWallpaper.jpg in place of /cdrom/KNOPPIX/background.jpg You can dump that command in a console window and see the results. I swear that it will not harm anything.

Now I will continue this post later.

el_supremo
08-04-2004, 06:57 PM
Hi UnderScore,
Thanks, I should have thought of looking for the filename in the .kde directory!

Any idea which command is required to make the background change right now, as opposed to waiting for the next reboot?

Best Wishes
Pete

UnderScore
08-04-2004, 09:48 PM
My continuation with perl script.

getRandomName.pl

#!/usr/bin perl
use File::Glob ':globally';

# The next 2 lines specify a folder to open
my $FolderOfImages = "/home/knoppix/wp";
opendir(DIR, $FolderOfImages) || die "can't opendir $FolderOfImages: $!";
# The next line reads the file listing from the folder, parses out the . and
# .. items, and then assigns the rest to the array fileListing.
my @fileListing = grep { /^\./ && -f "$FolderOfImages/$_" } readdir(DIR);

#This line closes the directory for reading
closedir DIR;
#This next line lets us only use the listed extensions in our array
@fileListing = <*.{jpg,png,gif,JPG,PNG,GIF,jpeg,JPEG}>;

# This line is used to correctly set up our integer count when randomized
push @fileListing,"garbage";
# The next 2 lines gets the total number of images and then chooses
# a integer in between 0 and the total number
my $randomnumfloat = rand $#fileListing;
my $randomnumint = int ($randomnumfloat);

#The next 3 lines make the full filename of the image & prints it to the screen
my $fullFileName;
$fullFileName = "$FolderOfImages/$fileListing[$randomnumint]";
print "$fullFileName \n";
This script will read through the folder of your choice and randomly select 1 image for you and it will print the name to the screen. This should be able to be extended to change the kdesktoprcvia either additional modifications or a helper bash script.

The key to the above script is the $FolderOfImages variable. You can change it from /home/knoppix/wp to any folder where you have some images. This script will reads through the folder and creates an array of filenames. These filename are of types .jpg .gif .png .jpeg .JPG .GIF .PNG .JPEG. Then it generates a random number and uses that number to select one image at random.

UnderScore
08-05-2004, 03:55 AM
changeToRandomWP.pl

#!/usr/bin/perl
use File::Glob ':globally';
my $FolderOfImages = $ARGV[0];
if ( -d "$FolderOfImages" ) {
opendir(DIR, $FolderOfImages) || die "can't opendir FolderOfImages:
$!";
# The next line reads the file listing from the folder, parses out the . and
# .. items, and then assigns the rest to the array fileListing.
my @fileListing = grep { /^\./ && -f "$FolderOfImages/$_" }
readdir(DIR);

#This line closes the directory for reading
closedir DIR;
#This next line lets us only use the listed extensions in our array

@fileListing = <*.{jpg,png,gif,JPG,PNG,GIF,jpeg,JPEG}>;

# This line is used to correctly set up our integer count when randomized
push @fileListing,"garbage";
# The next 2 lines gets the total number of images and then chooses
# a integer in between 0 and the total number
my $randomnumfloat = rand $#fileListing;
my $randomnumint = int ($randomnumfloat);

#The next 3 lines make the full filename of the image & prints it to the screen
my $fullFileName;
$fullFileName = "$FolderOfImages/$fileListing[$randomnumint]";
# This opens the kdesktoprc file so we can read from it
open(INPUT, "</home/knoppix/.kde/share/config/kdesktoprc") || die "Sorry could not open file: $!";
# This opens the kdesktoprc.new file so we can write to it
open(OUTPUT, ">/home/knoppix/.kde/share/config/kdesktoprc.new") || die "Sorry could not open file: $!";

# while reading in from kdesktoprc, perform the contents of the loop on each line
while (<INPUT>) {
# if a line matches Wallpaper
if ( $_ =~ /^Wallpaper=\/*/ ) {
# print to the output file a modified Wallpaper line
print OUTPUT "Wallpaper=$fullFileName\n";
}
# if a line matches CurrentWallpaper
elsif ( $_ =~ /^CurrentWallpaper=\/*/ ) {
# print to the output file a modified CurrentWallpaper line
print OUTPUT "CurrentWallpaper=$fullFileName\n";
}
# if there are no matches then print the line to the output file
else {
print OUTPUT $_;
}
}
# close the input and output files
close(OUTPUT) || die "couldn't close output file: $!\n";
close(INPUT) || die "couldn't close input file: $!\n";
}
The above script produces no output but will create a new kdesktop.new file with a randomly selected wallpaper.

swap-rc-file.sh

#!/bin/bash
perl changeToRandomWP.pl /home/knoppix/wp
if [ -e /home/knoppix/.kde/share/config/kdesktoprc.new ] ; then
cp /home/knoppix/.kde/share/config/kdesktoprc /home/knoppix/.kde/share/config/kdesktoprc.old
mv /home/knoppix/.kde/share/config/kdesktoprc.new /home/knoppix/.kde/share/config/kdesktoprc
fi

This script produced no visible output but will swap the .new to kdesktoprc, thus enabling the changes that the previous perl script made.

Copy each script into a text editior and save the files with the specified names. Next chmod 700 both files and execute them like so:
./swap-rc-files.sh
These 2 scripts will randomly select a wallpaper for you and will apply it to the kdesktoprc file so that it will take effect on next initialization

*These script assumes that there is a folder called /home/knoppix/wp and that folder has images in it. You can change it to point to a different location by changing it in line 2 of swap-rc-file.sh. These scripts also assume that we are doing to this to user knoppix who have a home directory. To apply this to a different user, change every reference of /home/knoppix to /home/yourusername.

I wrote these scripts to check to see if files exist before opening them or copying them and these scripts are designed to fail gracefully. That is, if you were to change a folder location but misspelled a folder name, it will tell you that it doesn't exist. You can also do diff kdesktoprc kdesktoprc.new to check to see if had made the changes.

I didn't have to write these but I felt that I should challenge myself and give back to community. I sat down & reaquainted myself to perl and 3 hours later, these are done. By day I am a sysadmin so scripting in perl keeps me sharp. Finally, if anyone has read this far and found these scripts interesting, then please login and post a message as I would much appreciate it.
Thanks,
James

el_supremo
08-05-2004, 05:40 PM
Hi UnderScore,
Thanks for the code. I am writing my own C program to do what your script does and I'll probably borrow the part which uses sed.

Best Wishes
Pete

mqzaidi
08-13-2004, 11:09 AM
I remember that you can use dcop to change the background instantly.

Don't remeber the exact function through, try kdcop and find out yourself.

If you need any help, just drop me a line at the email address encrypted below.

unsigned y[] = {0,48239,26913,345,57574,27526,1786,61007,8243,138 68,51008,32976}
;
void x(z){putchar(z);}; unsigned t;
main(i){if(i<12){t=(y[i]*47560)%65521;x(t>>8);x(t&255);main(++i);}}

marcovaldo
09-04-2004, 12:33 PM
Yep, dcop is the answer to changing the background instantly.
Here's the command (if the syntax looks weird just run kdcop and it will make more sense):

dcop kdesktop KBackgroundIface setWallpaper /home/luser/pics/hotbabe.jpg 1

Replace picture path appropriately and change the last number to the way you want to have the background displayed:
1: Centered
2: Tiled
3: Center Tiled
4: Centered Maxpect
5: Tiled Maxpect
6: Scaled
7: Centered Auto Fit

This will actually update the file:
~/.kde/share/config/kdesktoprc
so that the lines Wallpaper=, and WallpaperMode= will be changed by dcop instantly. So using this command is arguably cleaner than using the sed and perl scripts posted above.

Here's a quick and dirty shell script to get the job done.
It picks a random picture from a specified directory (that must contain only pictures, all in the same folder) and changes the background immediately.


!/bin/bash

# ---Replace with appropriate path to wallpaper pics [use /path/* notation]---
wallpaperPath="/home/luser/wallpaper/*"

# ---Replace number with preferred tiling method---
# 1: Centered
# 2: Tiled
# 3: Center Tiled
# 4: Centered Maxpect
# 5: Tiled Maxpect
# 6: Scaled
# 7: Centered Auto Fit
tilingMethod=4

# Count total number of pictures in directory
totalCnt=0
for picture in $wallpaperPath
do
totalCnt=`expr $totalCnt + 1`
done

# Seed random generator with date in seconds and choose random picture
RANDOM=`date '+%s'`
randomPic=$[($RANDOM % $totalCnt)+1]

# Find chosen picture in directory
picCnt=1
for picture in $wallpaperPath
do
if [ $picCnt = $randomPic ]
then
break
fi
picCnt=`expr $picCnt + 1`
done

echo New random background: $picture

# Set wallpaper immediately
dcop kdesktop KBackgroundIface setWallpaper "$picture" $tilingMethod

I've tested this only on SuSE 9.1, but I'm pretty sure it will work in most KDE environments.
I'm tempted to write a cleaner, more flexible C version... maybe if I feel bored enough.
Hope this helps, cheers.

el_supremo
09-05-2004, 01:19 AM
I'm tempted to write a cleaner, more flexible C version
I have written a C program which changes the background to a random image from a specified directory. However, it does not immediately change it, although that's easy to do. The new image will show after a reboot. I run the program from my .profile.

Best Wishes
Pete

Doctor
02-02-2005, 12:10 PM
UnderScore: thats the most commented code i've ever seen, keep up the good work!

CrashedAgain
02-03-2005, 02:17 AM
Finally, if anyone has read this far and found these scripts interesting, then please login and post a message as I would much appreciate it.
Thanks,
James

It is indeed interesting. Will try it, although the 'other user' will probably go ballistic if her desktop keeps changing. Hmmmmm...