Help File Library: Custom Cursors
By
Wallex
This simple Help File provides a quick guide into how to get your own cursors (also called pointers) in the X windows system. What you basically need to know already is pretty basic bash stuff (deleting, moving, renaming, and creating symlinks).
Get the Cursor Programs
There are two programs I know that will help create your own cursors/pointers:
DeCurs
xmbdfed
Decurs is specifically designed for managing cursors, so I'll probably be easier to use, altough I used xmbdfed because that's the one I managed to get installed. Also, at the decur's site they offer some optional pointers in case you only want to change, let's say, to a more 'windows-like' set of pointers. This Help File will focus around the usage of xmbdfed for obvious reasons.
Create Your Cursors
The main cursor font (yes, in X the cursor is actually another font) is located in your fonts directory, under misc (in my configuration it is in /var/X11R6/lib/fonts/misc/cursor.pcf.gz). You can load this font from xmbdfed by choosing File->Import->Server Font (or Control+G for short) and then choosing the font called 'cursor'. As you can see, the cursor font is made up of pairs of 'glyphs' for each cursor. The first glyph is the one that decides which parts of the cursor will be painted used the foreground color and which ones will be painted using the background colors (which by default are white and black). And the second glyph is used to determine which pixels will be drawn and which ones will be not (it's the mask, black pixels on the mask are the pixels that will actually be drawn while the others will not).
DeCurs will take it easier on your mind as it will show you how the cursor will look (without you having to 'imagine' how the cursor will look from merging the two glyphs). One good tip of advice is to draw the cursor as you want it to look like on the first glyph, then copy/paste it into the second glyph and 'fill' the cursor with black pixels (unless you are planning to use 'see-through' areas in the inside of your cursor).
One piece of advice is to remember that the cursors should allow you to see what you are pointing at, so if you make a big flashy crosshair and you only leave 3*3 pixels of see-through area on the center, you'll have a hard time seeing what you are actually trying to point to. Also, you don't need to specify and modify all the cursors in the font files (you'll notice there's a lot more cursors defined there than the ones you'll see in your regular use).
When you are done, save your file under some other name (if you are really into making cursors, you might end up making your own 'library' of cursors, in which case it would be a good idea to define your own directory of cursors, perhaps ~/.fonts/cursors/).
Installing the Cursor
If you noticed, X uses cursors in the .pcf.gz extension, but the cursor programs create cursors under the .xbd extension. So what do you do with this xbd file (no, you don't just rename it to pcf)? You use a little tool called bdftopcf (you should have it lying around somewhere... it's in /usr/X11/bin/ or /usr/bin/X11, actually both are the same -symlinked-). The syntax for conversion is:
bdftopcf -o ~/.fonts/cursor.pcf ~/.fonts/cursors/<cursor you just created>.bdf
Now that you have the cursor in the extension you needed, it's time to tell X to use it. If you are drastic and want to install the cursor for 'everyone' you might as well rename the cursor.pcf.gz to blackcursor.pcf.gz and create a symlink called cursor.pcf.gz that points to your cursor.pcf file (you should gunzip the file, too). Otherwise, if you just want a local cursor installation, then you follow these steps:
- Use the command
mkfontdir inside the directory where your newly created cursor.pcf is located. This command will create the cursor catalogue for X (it'll create a file called fonts.dir)
- Set up your .xinitrc file so that it'll use your fonts instead of the system-wide fonts. This is the first line in my .xinitrc file:
xset +fp $HOME/.fonts/
Any fonts installed on this folder will be added the list of available fonts for the user, plus the cursor font that will be used is the one found here instead of fonts/misc/
That's it, now you just have to restart your font-server (I just logout and restart my windows manager session). Enjoy your cursors!
A Note on Cursors
Not all possible cursors are defined inside the cursor.pcf file, programs are free to use their own cursors (which has to be included somewhere along the source files), thus it'll be a bit harder to actually modify all the pointers to your liking. Some applications that use their own cursors are:
- Mozilla: The pointer+wait cursor.
- OpenOffice: That clock/wait cursor.
- Import: The only cursor it uses (hard to believe that even this program uses it's own cursor)
- xmbdfed: Ironic, isn't it?
A Note on Colors
As much as I'd like to be able to define which colors the pointers should be instead of the dull black & white schema, there seems to be a small problem with it: the black and white colors are 'hard-coded' into the XCreateFontCursor X-lib function (type man XCreateFontCursor to read more about it).
X tells you to use a function called XRecolorCursor to change the cursor color at will, but the problem is that in order to do this, you need the reference to the pointer you want to colorize. In other words, it's up to program to determine the cursor color. Some programs will be nice and look for which colors they should use from the .xDefaults or .xResources file, but most programs just create the cursor and give the user no choice but to accept the black and white.
The only real solution would be to patch the XCreateFontCursor function so that it will not use black and white by default (perhaps to fetch these values from the .Xresources file?), but patching the X libraries is a bit beyond my league.
Here's what I did to get my own colors in my windows manager (Fluxbox), in the fluxbox.cc file (inside /src/, before compiling) I added the following lines after the line 338 (where it defines the cursors Fluxbox uses):
//setup cursor bitmaps
cursor.session = XCreateFontCursor(getXDisplay(), XC_left_ptr);
cursor.move = XCreateFontCursor(getXDisplay(), XC_fleur);
cursor.ll_angle = XCreateFontCursor(getXDisplay(), XC_ll_angle);
cursor.lr_angle = XCreateFontCursor(getXDisplay(), XC_lr_angle);
//setup cursor colors
XColor pointerColorFG;
pointerColorFG.red=40960;
pointerColorFG.green=65535;
pointerColorFG.blue=65535;
XColor pointerColorBG;
pointerColorBG.red=0;
pointerColorBG.green=40960;
pointerColorBG.blue=40960;
XRecolorCursor(getXDisplay(), cursor.session, &pointerColorFG, &pointerColorBG);
XRecolorCursor(getXDisplay(), cursor.move, &pointerColorFG, &pointerColorBG);
XRecolorCursor(getXDisplay(), cursor.ll_angle, &pointerColorFG, &pointerColorBG);
XRecolorCursor(getXDisplay(), cursor.lr_angle, &pointerColorFG, &pointerColorBG);
It isn't the most efficient way to do it, but it works for me. Unfortunately, you'd have to recompile and reinstall fluxbox each time you feel like using different colors, but then again, this is just some insight for whomever has more time and is more willing to patch their windows manager (or even patch the X libraries?). I also have to note that even thought the colored cursors remain across applications, some programs will 're-create' their cursors (even if it's the same as the one you already defined) so you'll end up with black/white cursors for these applications anyway.
Conclusion
In my personal opinion, I say that we need a new cursor-server that should run inbetween X and the apps, something that will give us users more control over the cursor/pointers and perhaps give us something better than two-colored 2d pointers.It can be done, but it seems most people are happy with the way cursors are right now, so there just hasn't been any active development on the 'cursor/pointer' area.
Sources:
Here are the different sites I've visited while trying to get my cursors working, they could be of some use (altough there's little to none that they explain that hasn't already been explained):
DeCurs (good utility, or so it seems from the screenshots, they also provide you with some simple cursor alternatives)
xmbdfed (doesn't looks like the homepage, but I can't seem to find it anywhere)
Mouse-Cursor-Configuration MINI-HOWTO
The Mandrake eXPerience: White Mouse Cursors