First lets have a look at the mouse cursors available to X applications. One can use the Xcursor library directly, which allows for full color icon themes, or more usually one can use a toolkit like QT or GTK+ to indirectly select the (themed) X mouse cursor. Note QT has some inbuilt cursors that mostly map to equivalents in X, but the last 4 in the table below do not. GTK+ does not have inbuilt cursors and just makes the predefined X cursors available.
Note the bitmap cursors below are 2 color, not single color, because they are constructed from 2 bitmaps. The first defines what bits are to be set to the foreground and background colours, and the second determines what bits to display.
QT | X/GDK | ||
Qt::ArrowCursor | LEFT_PTR | ||
Qt::UpArrowCursor | SB_UP_ARROW | ||
Qt::CrossCursor | CROSSHAIR | ||
Qt::IBeamCursor | XTERM | ||
Qt::WaitCursor | WATCH | ||
Qt::PointingHandCursor | HAND2 | ||
Qt::WhatsThisCursor | QUESTION_ARROW | ||
Qt::SizeVerCursor | SB_V_DOUBLE_ARROW | ||
Qt::SizeHorCursor | SB_H_DOUBLE_ARROW | ||
Qt::SizeBDiagCursor | BOTTOM_LEFT_CORNER | ||
Qt::SizeFDiagCursor | BOTTOM_RIGHT_CORNER | ||
Qt::SizeAllCursor | FLEUR | ||
Qt::SplitVCursor | can use SB_V_DOUBLE_ARROW | ||
Qt::SplitHCursor | can use SB_H_DOUBLE_ARROW | ||
Qt::BusyCursor | |||
Qt::ForbiddenCursor | |||
Qt::OpenHandCursor | |||
Qt::ClosedHandCursor |
So one can see from the table above, that if I was using QT, selecting the "Busy-Interactive" mouse pointer would be trivial, but unfortunately there is no direct support in GTK+ or X. Now a themed version of this cursor is available to applications as can be seen for example in firefox, where it sets the "Busy-Interactive" cursor any time it loads a page. Looking in my cursor theme directories, shows the cursor I'm trying to set is "left_ptr_watch"
/usr/share/icons/Bluecurve/cursors/left_ptr_watch /usr/share/icons/Bluecurve/cursors/08e8e1c95fe2fc01f976f1e063a24ccd -> left_ptr_watch /usr/share/icons/Human/cursors/left_ptr_watch /usr/share/icons/Human/cursors/08e8e1c95fe2fc01f976f1e063a24ccd
So how do you find out the exact bits to set for the bitmap cursor? Well X uses the "XCURSOR_DISCOVER" environment variable to display the bitmap cursor an application sets and the corresponding hash. So running firefox with this enabled gives:
export XCURSOR_DISCOVER=1 firefox http://www.pixelbeat.org/ | tr ' ' . Cursor.image.name:.08e8e1c95fe2fc01f976f1e063a24ccd ................................ ................................ ..*............................. ..**............................ ..***........................... ..****.......................... ..*****......................... ..******........................ ..*******....................... ..********.***.................. ..*****....***.................. ..**.**...*.*.*................. ..*...**..***.**................ ......**..*...*................. .......**..***.................. .......**..***.................. ...
I converted this XBM string into a more concise python string, for use in the following pygtk program, which shows how to set the themed left_ptr_watch mouse cursor.
import os os.environ['XCURSOR_DISCOVER']='1' #Turn on logging in Xlib import gtk w=gtk.Window() w.realize() # X includes a left_ptr_watch cursor but doesn't have a name for it. # Instead it links the hash of the corresponding mozilla bitmap cursor to it. # redhat-artwork links 08e8e1c95fe2fc01f976f1e063a24ccd to its version # of left_ptr_watch. So since X does the link we can assume it's always present. mozilla_left_ptr_watch = "\ \x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x0c\x00\x00\x00\ \x1c\x00\x00\x00\x3c\x00\x00\x00\x7c\x00\x00\x00\xfc\x00\x00\x00\ \xfc\x01\x00\x00\xfc\x3b\x00\x00\x7c\x38\x00\x00\x6c\x54\x00\x00\ \xc4\xdc\x00\x00\xc0\x44\x00\x00\x80\x39\x00\x00\x80\x39"+"\x00"*66 left_ptr_watch=mozilla_left_ptr_watch try: pix = gtk.gdk.bitmap_create_from_data(None, left_ptr_watch, 32, 32) color = gtk.gdk.Color() LEFT_PTR_WATCH=gtk.gdk.Cursor(pix, pix, color, color, 2, 2) #Note mask is ignored when doing the hash except TypeError: #http://bugzilla.gnome.org/show_bug.cgi?id=103616 #older pygtks #http://bugzilla.gnome.org/show_bug.cgi?id=318874 #pygtk-2.8.[12] (breezy) LEFT_PTR_WATCH=None #default cursor w.window.set_cursor(LEFT_PTR_WATCH) w.connect("destroy", gtk.main_quit) w.show_all() gtk.main()
[Update Feb 2008: I notice that Fedora 8 now maps the WATCH cursor which is easily selectable and usually displayed as an hourglass, to LEFT_PTR_WATCH. So that means an hourglass is never displayed now?
/usr/share/icons/Bluecurve/cursors/_watch-old_ /usr/share/icons/Bluecurve/cursors/watch -> left_ptr_watch /usr/share/icons/Bluecurve/cursors/08e8e1c95fe2fc01f976f1e063a24ccd -> left_ptr_watchI also notice that the X `bitmap` utility referred to above is not installed by default in Fedora 8 at least.]