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 Computing
Conference & Expo
November 2-4, 2009 NYC
Register Today and SAVE !..

2008 West
DIAMOND SPONSOR:
Data Direct
SOA, WOA and Cloud Computing: The New Frontier for Data Services
PLATINUM SPONSORS:
Red Hat
The Opening of Virtualization
GOLD SPONSORS:
Appsense
User Environment Management – The Third Layer of the Desktop
Cordys
Cloud Computing for Business Agility
EMC
CMIS: A Multi-Vendor Proposal for a Service-Based Content Management Interoperability Standard
Freedom OSS
Practical SOA” Max Yankelevich
Intel
Architecting an Enterprise Service Router (ESR) – A Cost-Effective Way to Scale SOA Across the Enterprise
Sensedia
Return on Assests: Bringing Visibility to your SOA Strategy
Symantec
Managing Hybrid Endpoint Environments
VMWare
Game-Changing Technology for Enterprise Clouds and Applications
Click For 2008 West
Event Webcasts

2008 West
PLATINUM SPONSORS:
Appcelerator
Get ‘Rich’ Quick: Rapid Prototyping for RIA with ZERO Server Code
Keynote Systems
Designing for and Managing Performance in the New Frontier of Rich Internet Applications
GOLD SPONSORS:
ICEsoft
How Can AJAX Improve Homeland Security?
Isomorphic
Beyond Widgets: What a RIA Platform Should Offer
Oracle
REAs: Rich Enterprise Applications
Click For 2008 Event Webcasts
In many cases, the end of the year gives you time to step back and take stock of the last 12 months. This is when many of us take a hard look at what worked and what did not, complete performance reviews, and formulate plans for the coming year. For me, it is all of those things plus a time when I u...
SYS-CON.TV
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?
SOA World Latest Stories
Quick Response (QR) codes are intended to help direct users quickly and easily to information about products and services, but they are also starting to be used for social engineering exploits. This article looks at the emergence of QR scan scams and the rising concern for users today....
The Chinese company that claims it owns the iPad trademark says it plans to seek a ban on iPad exports out of China, threatening global supplies. According to what a lawyer for Proview Technology (Shenzhen) Co Ltd told Reuters, the firm is petitioning Chinese customs to stop shipment...
Cisco Wednesday filed suit in the European Union’s second-highest court, the General Court in Luxembourg, challenging the European Commission’s rubber stamp last October of Microsoft’s $8.5 billion acquisition of Skype. Cisco says it isn’t opposed to the merger, but figures the EC sh...
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 applic...
As more enterprises are adopting clouds, the nature of cloud computing is changing. Previously, clouds were used to test applications or for non-mission critical applications. Today, enterprises are using clouds for cost-saving advantages and launching more mission critical application...
Building a cloud computing environment with on-demand access to compute, network, and storage resources requires an elastic infrastructure at multiple levels. Virtualization combined with x86 servers has transformed the way we scale out compute resources. Unfortunately, legacy Fibre Ch...
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