- Cursor cursor = None;
- Pixmap no_cursor = None ; /* Used for GLUT_CURSOR_NONE */
- int error = 0;
-
-#define MAP_CURSOR(a,b) \
- case a: \
- cursor = XCreateFontCursor( fgDisplay.Display, b ); \
- break;
-
- if( GLUT_CURSOR_FULL_CROSSHAIR == cursorID )
- cursorID = GLUT_CURSOR_CROSSHAIR;
-
- switch( cursorID )
- {
- MAP_CURSOR( GLUT_CURSOR_RIGHT_ARROW, XC_right_ptr);
- MAP_CURSOR( GLUT_CURSOR_LEFT_ARROW, XC_left_ptr);
- MAP_CURSOR( GLUT_CURSOR_INFO, XC_hand1);
- MAP_CURSOR( GLUT_CURSOR_DESTROY, XC_pirate);
- MAP_CURSOR( GLUT_CURSOR_HELP, XC_question_arrow);
- MAP_CURSOR( GLUT_CURSOR_CYCLE, XC_exchange);
- MAP_CURSOR( GLUT_CURSOR_SPRAY, XC_spraycan);
- MAP_CURSOR( GLUT_CURSOR_WAIT, XC_watch);
- MAP_CURSOR( GLUT_CURSOR_TEXT, XC_xterm);
- MAP_CURSOR( GLUT_CURSOR_CROSSHAIR, XC_crosshair);
- MAP_CURSOR( GLUT_CURSOR_UP_DOWN, XC_sb_v_double_arrow);
- MAP_CURSOR( GLUT_CURSOR_LEFT_RIGHT, XC_sb_h_double_arrow);
- MAP_CURSOR( GLUT_CURSOR_TOP_SIDE, XC_top_side);
- MAP_CURSOR( GLUT_CURSOR_BOTTOM_SIDE, XC_bottom_side);
- MAP_CURSOR( GLUT_CURSOR_LEFT_SIDE, XC_left_side);
- MAP_CURSOR( GLUT_CURSOR_RIGHT_SIDE, XC_right_side);
- MAP_CURSOR( GLUT_CURSOR_TOP_LEFT_CORNER, XC_top_left_corner);
- MAP_CURSOR( GLUT_CURSOR_TOP_RIGHT_CORNER, XC_top_right_corner);
- MAP_CURSOR( GLUT_CURSOR_BOTTOM_RIGHT_CORNER,
- XC_bottom_right_corner);
- MAP_CURSOR( GLUT_CURSOR_BOTTOM_LEFT_CORNER, XC_bottom_left_corner);
- /* MAP_CURSOR( GLUT_CURSOR_NONE, XC_bogosity); */
-
- case GLUT_CURSOR_NONE:
- {
- /*
- * Note that we *never* change {no_cursor_bits} from anything
- * but all-zeros. It is our image and mask. We also apparently
- * need to pick a color for foreground/background---but what
- * one we pick doesn't matter for GLUT_CURSOR_NONE.
- */
- static unsigned char no_cursor_bits[ 32 ];
- XColor black;
- no_cursor = XCreatePixmapFromBitmapData( fgDisplay.Display,
- fgDisplay.RootWindow,
- no_cursor_bits,
- 16, 16,
- 1, 0, 1 );
- XParseColor( fgDisplay.Display,
- DefaultColormap( fgDisplay.Display,
- DefaultScreen( fgDisplay.Display ) ),
- "black",
- &black );
- cursor = XCreatePixmapCursor( fgDisplay.Display,
- no_cursor, no_cursor,
- &black, &black,
- 0, 0 );
- break;
+ Cursor cursor;
+ /*
+ * XXX FULL_CROSSHAIR demotes to plain CROSSHAIR. Old GLUT allows
+ * for this, but if there is a system that easily supports a full-
+ * window (or full-screen) crosshair, we might consider it.
+ */
+ int cursorIDToUse =
+ ( cursorID == GLUT_CURSOR_FULL_CROSSHAIR ) ? GLUT_CURSOR_CROSSHAIR : cursorID;
+
+ if( ( cursorIDToUse >= 0 ) &&
+ ( cursorIDToUse < sizeof( cursorCache ) / sizeof( cursorCache[0] ) ) ) {
+ cursorCacheEntry *entry = &cursorCache[ cursorIDToUse ];
+ if( entry->cachedCursor == None ) {
+ entry->cachedCursor =
+ XCreateFontCursor( fgDisplay.Display, entry->cursorShape );
+ }
+ cursor = entry->cachedCursor;
+ } else {
+ switch( cursorIDToUse )
+ {
+ case GLUT_CURSOR_NONE:
+ cursor = getEmptyCursor( );
+ break;
+
+ case GLUT_CURSOR_INHERIT:
+ cursor = None;
+ break;
+
+ default:
+ fgError( "Unknown cursor type: %d", cursorIDToUse );
+ return;
+ }