Comments
Richard Davies wrote: The UK has a good crop of technology pioneers in cloud computing - for example ElasticHosts, FlexiScale, Flexiant, OnApp - and also some strong government initiatives such as G-Cloud. We will have to see whether this kind of technical leadership converts into swift mass-market adoption or not.
Cloud Expo on Google News

SYS-CON.TV
Cloud Expo & Virtualization 2009 East
PLATINUM SPONSORS:
IBM
Smarter Business Solutions Through Dynamic Infrastructure
IBM
Smarter Insights: How the CIO Becomes a Hero Again
Microsoft
Windows Azure
GOLD SPONSORS:
Appsense
Why VDI?
CA
Maximizing the Business Value of Virtualization in Enterprise and Cloud Computing Environments
ExactTarget
Messaging in the Cloud - Email, SMS and Voice
Freedom OSS
Stairway to the Cloud
Sun
Sun's Incubation Platform: Helping Startups Serve the Enterprise
POWER PANELS:
Cloud Computing & Enterprise IT: Cost & Operational Benefits
How and Why is a Flexible IT Infrastructure the Key To the Future?
Click For 2008 West
Event Webcasts
Adding eye candy to your desktop
You need XFree86 4.3 to enjoy the sweetest improvements

(LinuxWorld) — To each his own, but I like eye candy. For all their benefits and power, X11 and X Window System managers have been among the most drab and poorly rendered graphical environments for years. Recent versions of XFree86 began to support anti-aliased fonts, which helped. But that's pure protein. It's good for you, and it helps you get your work done. Only recently has XFree86 begun to add the sugary content that we shallow folks crave.

You'll have to get XFree86 4.3 to enjoy the sweetest improvements. This version supports custom-animated cursors, and it's reasonably easy to create cursor sets. Here's a picture of one of my favorite cursor sets, which I found on www.kde-look.org.

The above image doesn't do the gold cursor-set justice, because the beauty is in the animation. I recommend you try it for yourself. KDE-Look.org has another great cursor set built around Tux the penguin. It's a bit too sweet for me, but I appreciate the work that must have gone into making this set.

Stardock

Brad Wardell, an ex-OS/2 geek and (current) friend of mine, created the company Stardock for the purpose of supplementing OS/2 with cool gadgets and games. When Brad saw the writing on the wall with respect to OS/2, he jumped on the Windows wagon. Forgive him, folks; he knows not what he did. But he and his programmers do know what they do, and they do it well. They create lots of Windows gadgets, including one called CursorXP. CursorXP is a mouse-cursor enhancement to Windows XP, and there are lots of animated eye-candy cursors created for it.

Wouldn't it be nice if we could use some of those cursors? It isn't that difficult to fire up Gimp or some other graphics program to convert them. You won't have to go to that trouble, thanks to Eric Windisch.

Eric created a script in Perl and ImageMagick that translates Stardock mouse-cursor sets into files XFree86 4.3 can use. The script is still in its infancy, so the code for creating drop shadows and transparency effects is incomplete. I rewrote the drop-shadow code to make it work well enough for my taste (see below for the complete source code). You can also download it from VarLinux.org (see Resources for a link).

Here's how to use the script (this article assumes you are using my modified version of the script).

If you want to generate plain X11 mouse-cursors, use this command:

# cd [directory where the Stardock cursor set is stored]
# sd2xc.pl

I tend to prefer drop shadows for my X11 cursors, but some of the cursor sets look better without them. If you want to generate X11 mouse-cursors with a drop shadow, use this command:

# cd [directory where the Stardock cursor set is stored]
# sd2xc.pl --shadow

There are other parameters you can change to adjust the look of the drop shadow, but I've hard-coded them to unusual defaults to compensate for the fact that I can't figure out how to get ImageMagick to adjust opacity the way I'd like. In the meantime, I'm afraid you'll have to RTFSC (read the fine source code) if you want to know how to use them.

Anyway, assuming the script does its job properly, it will place the cursors in the sub-directory ./theme/cursors. Rename theme to whatever you want to call this particular cursor set. For example, if you are converting the Stardock IBounce set, you might do this:

# mv theme bouncy

Then move bouncy to the place where you want to store your cursors. If you want the cursor set to be available to everyone on the system, move it to /usr/share/icons.

# mv bouncy /usr/share/icons

If you want this set to be available to a specific user, move it to their .icons directory (substitute the username for joeblough).

# mv bouncy /home/joeblough/.icons

Now you have to tell X11 which cursor-set you want to use. There are a number of ways you can do this. First, let's assume you want to do it on a per-user basis. In that case, create the user's default icon directory if it doesn't already exist (substitute the user name for joeblough.) :

# mkdir /home/joeblough/.icons/default

Then create an index.theme text file in that directory and make sure the file includes the following (substitute the name of the cursor theme you want to use for bouncy).

[Icon Theme]
Inherits=bouncy

As long as there is a bouncy theme in either your user's home .icon directory or the global directory (usually /usr/share/icons, as shown above), this user should start to see the custom mouse-cursors the next time he or she starts up X11.

Another method is to edit the .Xdefaults file in your home directory and add a line such as the following:

Xcursor.theme: bouncy

How the ImageMagick Perl script works

I almost refused to hack the Perl script due to my allergy to Perl. Perl is a fine language, but I hate it. In case you're wondering how much I hate it, let me put it this way: if I were handcuffed to a Perl manual, I would chew through my arm to get it off. In fact, one of the only languages I hate more than Perl is Scheme, which is what Gimp uses for its scripting capability. That's a shame, because it would probably have been easier to perform the conversion from Stardock CursorXP to X11 XCursors with Gimp. But Perl, being the lesser of two extreme evils, was the way I chose, though not without some regrets.

Fortunately, this particular Perl script is fairly legible, so it wasn't very difficult to grasp and change it to my liking. The ImageMagick extensions to Perl, on the other hand, gave me no end of trouble and were the sole source of my regrets.

The script works fine if you don't want to have drop shadows for your cursors, but the shadow feature didn't seem to work for me. I modified the code that creates the drop shadow so that it works for me. Unfortunately, I had to come up with a pretty convoluted way to create the drop shadows, thanks to the mysterious and poorly documented way ImageMagick handles composite images.

Here is the logical method of creating a drop shadow (at least it seems logical to me) and the workarounds I had to apply. The first step:

  1. Create a canvas large enough to contain the cursor plus the drop shadow.

    The script always places drop shadows to the right and below the image. One could modify the code to have a drop shadow appear elsewhere, but that would often require you to move the hotspot for the mouse cursor (the part of the image that matters when you click the mouse button). It's not difficult to do that, but I have no problem with a drop shadow down and to the right, so I didn't code for that possibility.

    Given how the drop shadow is placed, one must calculate how much the image may grow when you add the drop shadow. It depends on the size of the image and the transparent background canvas. Nevertheless, one must assume the worst: one or more cursor images is as large as the canvas. If you don't, you risk clipping the drop shadow so that part of it is missing, which will make it look silly.

    There's the potential for one or more frames to grow in size in two respects. First, it may grow by the amount of offset you specify for the drop shadow (so much to the right and so far down from the image). It may also grow due to the amount of blur you create for the drop shadow, because the blur radius spreads the shadow image. I fudged the growth potential by adding the blur radius to the X and Y offsets, then starting with a canvas much larger than the original image. This is overkill for some images, but it works out just right in others.

  2. Create the drop shadow.

    Under normal circumstances, I would create the drop shadow using these steps:

    • Place a copy of the original cursor image on a transparent canvas, but place it offset by the X and Y offset for the drop shadow.
    • Convert the image to all black (or gray).

    Instead of the above, I simply create a composite image against a transparent background using the "CopyOpacity" feature, with the X and Y offset specified as part of the composition process. This creates a "stencil" of the image in black, which appears at the offset amount. A black stencil of the original image is actually not the result I would have expected from this operation, but I stumbled on this result and used it.

  3. Blur the image.

    Normally, I would blur the image only slightly. I'll explain in a moment why the script does otherwise.

  4. Adjust the opacity (transparency) of the image to your liking.

    For the life of me, I could not figure out how to adjust the opacity of the drop shadow using any of the techniques that are seemingly designed to get this result. I tried creating composite images of a transparent background with the drop shadow and adjusting the opacity amount, but that never worked. I tried the "dissolve" method of combining a transparent background with the drop shadow. That always produced a black background, even if I tried to mask the image. I can get dissolve to work in other ways. For example, I can combine two images so that one color dissolves into another. But I can never seem to combine an image with transparency so that the result is only partially transparent.

    I have the feeling that there is a combination of settings, such as color spaces, image types, etc., that one must manage (although because I was able to get dissolve to work with certain colors and the image formats I used support transparency, one would think I had these settings right). Regardless, whatever I may be missing is probably obvious to those who created and refined ImageMagick. But that doesn't help me at all, as I cannot find a shred of documentation that explains how to use ImageMagick to create a partially transparent image on a fully transparent background.

    I discovered, however, that if I blur the image enough, the blurred shadow becomes partially transparent. So I cranked up the blur parameters just enough to get a result similar to what I would shoot for if I could do it "right". This seems to work for the most part.

    At this point, it should be easy to create the final image.

  5. Superimpose the original cursor image in its original location on top of the newly created drop shadow.

    That's almost all there is to it. The rest of the code handles the gory details that arise from the different way Stardock stores its images. Stardock puts all of the animated frames in a single PNG file. The XCursor format requires these animated frames to be separate files. The code looks up the number of frames in the Stardock INI file and uses that to figure out how to crop the multi-frame PNG into separate images. The code also examines the INI file for other information, such as the hotspot and the animation rate.

The Perl code

Here is the code, as of publication. Note that not all of it is useful yet, but Eric Windisch left in several options for later expansion (some of which I changed, and I removed a section of code that wasn't being used).

I invite anyone who knows Perl, ImageMagick, Scheme, Gimp, or whatever other combination that works to send me code that can do this job better. I'd love to fix this code to dissolve the shadow into a proper level of transparency or even replace the code with a script using some other tool set. Until then, enjoy the eye candy, but be careful not to go into insulin shock.

#!/usr/bin/perl
#
# Copyright Eric Windisch, 2003.
# Licensed under the MIT license.
# Modified by Nicholas Petreley, March 2003
#
use strict;
use Image::Magick;
use Getopt::Long;
use Config::IniFiles;

my ($config_file, $path, $tmppath, $generator,$verbose, $inherits,$tmpscheme,$shadow, $opacity, $shadowopacity, $shadowx, $shadowy, $shadowblur,$shadowblursigma);

# default for variables $verbose=1; $shadow=0; $opacity=100; $shadowopacity=70; $shadowx=9; $shadowy=4; $shadowblur=5; $shadowblursigma=7; $path="theme/"; $tmppath="tmp/"; $generator="/usr/bin/X11/xcursorgen"; # it seems that recursive inheritance does not yet exist. $inherits="whiteglass";

sub process { print <<EOF; Usage: $0 [-v] [--inherits theme] [--shadow] [--shadow-x pixels] [--shadow-y pixels] [--shadow-blur size] [--shadow-blur-sigma size] [--shadow-opacity] [--generator xcursorgen-path] [--tmp temp-dir] EOF exit 0; };

GetOptions ( 'inherits=s'=>\$inherits, 'tmp=s'=>\$tmppath, 'shadow'=>\$shadow, 'v'=>\$verbose, 'generator=s'=>\$generator, 'opacity=i'=>\$opacity, '<>' => \&process, 'help'=>\&process, 'shadow-x=i'=>\$shadowx, 'shadow-y=i'=>\$shadowy, 'shadow-blur=i'=>\$shadowblur, 'shadow-blur-sigma=i'=>\$shadowblursigma, 'shadow-opacity=i'=>\$shadowopacity );

# make sure path and tmppath end in / if ($path =~ /[^\/]$/) { $path=$path."/"; } if ($tmppath =~ /[^\/]$/) { $tmppath=$tmppath."/"; }

if (! -d $path) { mkdir ($path); } if (! -d $path."cursors/") { mkdir ($path."cursors/"); } if (! -d $tmppath) { mkdir ($tmppath); } $tmpscheme=$tmppath."Scheme.ini";

# I did this much nicer, but Perl < 5.8 choked. open (INI, "< Scheme.ini") or die ("Cannot open Scheme.ini"); open (INF, ">", $tmpscheme); while (<INI>) { unless (!/=/ && !/^\s*\[/) { #$config_file.=$_; print INF $_; } } close (INI); close (INF);

my $cfg=new Config::IniFiles(-file=>$tmpscheme) or die ("Scheme.ini in wrong format? -".$@); my @sections=$cfg->Sections;

my $filemap={ Arrow=>["left_ptr","X_cursor","right_ptr",'4498f0e0c1937ffe01fd06f973665830'], Cross=>["tcross","cross"], Hand=>["hand1", "hand2",'9d800788f1b08800ae810202380a0822','e29285e634086352946a0e7090d73106'], IBeam=>"xterm", UpArrow=>"center_ptr", SizeNWSE=>["bottom_right_corner","top_left_corner",'c7088f0f3e6c8088236ef8e1e3e70000'], SizeNESW=>["bottom_left_corner","top_right_corner",'fcf1c3c7cd4491d801f1e1c78f100000'], SizeWE=>["sb_h_double_arrow", "left_side", "right_side",'028006030e0e7ebffc7f7070c0600140'], SizeNS=>["double_arrow","bottom_side","top_side",'00008160000006810000408080010102'], Help=>["question_arrow",'d9ce0ab605698f320427677b458ad60b'], Handwriting=>"pencil", AppStarting=>["left_ptr_watch", '3ecb610c1bf2410f44200f48c40d3599'], SizeAll=>"fleur", Wait=>"watch", NO=>"03b6e0fcb3499374a867c041f52298f0" };

foreach my $section (@sections) { my ($filename);

$filename=$section.".png"; unless (-f $filename) { next; }

my ($image, $x, $frames, $width, $height, $curout);

$image=Image::Magick->new; $x=$image->Read($filename); warn "$x" if "$x";

$frames=$cfg->val($section, 'Frames'); $width=$image->Get('width')/$frames; $height=$image->Get('height');

if (defined($filemap->{$section})) { $curout=$filemap->{$section}; } else { $curout=$section; }

my $array=-1; eval { if (defined (@{$curout}[0])) { }; }; unless ($@) { $array=0; }

LOOP: my $outfile;

if ($array > -1) { if (defined (@{$curout}[0])) { $outfile=pop @{$curout}; } else { next; } } else { $outfile=$curout; } $outfile=$path."cursors/".$outfile;

if ($verbose) { print "Writing to $section -> $outfile\n"; }

open (FH, "| $generator > \"$outfile\"");

my $yoffset = $shadowy + $shadowblur; my $xoffset = $shadowx + $shadowblur; my $swidth = $width + $xoffset; my $sheight = $height + $yoffset; for (my $i=0; $i<$frames; $i++) { my ($tmpimg, $outfile); $outfile=$tmppath.$section.'-'.$i.'.png'; $tmpimg=$image->Clone();

$x=$tmpimg->Crop(width=>$width, height=>$height, x=>$i*$width, y=>0); warn "$x" if "$x";

if ($shadow) { my $blank = Image::Magick->new; $blank->Set(size=>$swidth."x".$sheight); $blank->ReadImage('xc:transparent'); $blank->Set(type=>"TrueColorMatte"); $blank->Quantize(colorspace=>"RGB"); $blank->Colorize(fill=>"black",opacity=>0); $blank->Transparent(color=>"black"); my $blankcanvas=$blank->Clone();

$x=$blank->Composite(image=>$tmpimg, compose=>"CopyOpacity", x=>$shadowx, y=>$shadowy, opacity=>0); warn "$x" if "$x"; $x=$blank->Blur(radius=>$shadowblur, sigma=>$shadowblursigma); warn "$x" if "$x"; $x=$blank->Composite(image=>$tmpimg, compose=>"Over", x=>0, y=>0, opacity=>0);

$tmpimg=$blank; }

$x=$tmpimg->Write($outfile); warn "$x" if "$x";

print FH "1 ". $cfg->val($section,'Hot spot x')." ". $cfg->val($section,'Hot spot y')." ". $outfile." ". $cfg->val($section,'Interval')."\n"; }

if ($array > -1) { goto LOOP; } }

print "Writing theme index.\n"; open (FH, "> ${path}index.theme"); print FH <<EOF; [Icon Theme] Inherits=$inherits EOF close (FH);

print "Done. Theme wrote to ${path}\n";

About Nicholas Petreley
Nicholas Petreley is a computer consultant and author in Asheville, NC.

In order to post a comment you need to be registered and logged in.

Register | Sign-in

Reader Feedback: Page 1 of 1

That is /home/USERNAME/.icons/THEMENAME/cursors

I fixed the problem. By adding 08e8e1c95fe2fc01f976f1e063a24ccd, left_ptr_wait works. By adding some cursor names, the other problems also went away. If anyone is having similar problems as I, just look at some theme and see which cursors are linked to others and add these names to the script appropriately. These files should be in the folder /home//.icons//cursors

The shadow option didn't work for me at all, as transparency was lost at some point, and I only got a white square containing the cursor with a square shadow. So I rewrote that to work, although I don't know ImageMagick very well and probably made it inefficient. Anyway, my only problem now is that left_ptr_wait, the resize cursor for the bottom edge, and one of the window resizing cursors doesn't work. I'm not sure what they are called as documentation is crap. I only get the defaults instead even though the cursors are supposedly generated, or at least I know the left_ptr_wait is as well as the crazy named file that goes with it. This is true for whatever theme I try to convert. Any ideas as to what the problem is?


Your Feedback
James Barron wrote: That is /home/USERNAME/.icons/THEMENAME/cursors
James Barron wrote: I fixed the problem. By adding 08e8e1c95fe2fc01f976f1e063a24ccd, left_ptr_wait works. By adding some cursor names, the other problems also went away. If anyone is having similar problems as I, just look at some theme and see which cursors are linked to others and add these names to the script appropriately. These files should be in the folder /home//.icons//cursors
James Barron wrote: The shadow option didn't work for me at all, as transparency was lost at some point, and I only got a white square containing the cursor with a square shadow. So I rewrote that to work, although I don't know ImageMagick very well and probably made it inefficient. Anyway, my only problem now is that left_ptr_wait, the resize cursor for the bottom edge, and one of the window resizing cursors doesn't work. I'm not sure what they are called as documentation is crap. I only get the defaults instead even though the cursors are supposedly generated, or at least I know the left_ptr_wait is as well as the crazy named file that goes with it. This is true for whatever theme I try to convert. Any ideas as to what the problem is?
Latest Cloud Developer Stories
Rackspace Hosting, the service leader in cloud computing, on Thursday announced its acquisition of SharePoint911, an industry leader in SharePoint consulting, training, and "JumpStart" services within SharePoint. The unification of both companies provides capabilities to deliver ...
With Cloud Expo 2012 New York (10th Cloud Expo) now under four months away, what better time to start introducing you in greater detail to the distinguished individuals in our incredible Speaker Faculty for the technical and strategy sessions at the conference... We have techn...
Nimble, the social CRM platform has announced the launch of Nimble 2.0, billed as the “most social” CRM platform on the market today. Nimble was designed entirely with social CRM in mind and is the first social business platform that empowers companies with the ability to get clo...
2011 was a year of rapid adoption for public and private cloud services. Instant and on-demand server provisioning was the driving force behind the massive growth. On top, cloud server templates and script automation simplified application installation for simple and pre-defined ...
"Having been in the IT field for many years, I believe the cloud computing chapter in the industry is an exciting one and I am proud to be a part of it," said National Reconaissance Office (NRO) Chief Information Officer Jill T. Singer Tuesday, as it was announced that she was on...
Subscribe to the World's Most Powerful Newsletters
Subscribe to Our Rss Feeds & Get Your SYS-CON News Live!
Click to Add our RSS Feeds to the Service of Your Choice:
Google Reader or Homepage Add to My Yahoo! Subscribe with Bloglines Subscribe in NewsGator Online
myFeedster Add to My AOL Subscribe in Rojo Add 'Hugg' to Newsburst from CNET News.com Kinja Digest View Additional SYS-CON Feeds
Publish Your Article! Please send it to editorial(at)sys-con.com!

Advertise on this site! Contact advertising(at)sys-con.com! 201 802-3021

SYS-CON Featured Whitepapers
ADS BY GOOGLE