\r
/* -- PRIVATE FUNCTIONS --------------------------------------------------- */\r
\r
-#if TARGET_HOST_POSIX_X11 || TARGET_HOST_MAC_OSX || TARGET_HOST_SOLARIS\r
- #include <X11/cursorfont.h>\r
+extern void fgPlatformSetCursor ( SFG_Window *window, int cursorID );\r
+extern void fgPlatformWarpPointer ( int x, int y );\r
\r
-/*\r
- * A factory method for an empty cursor\r
- */\r
-static Cursor getEmptyCursor( void )\r
-{\r
- static Cursor cursorNone = None;\r
- if( cursorNone == None ) {\r
- char cursorNoneBits[ 32 ];\r
- XColor dontCare;\r
- Pixmap cursorNonePixmap;\r
- memset( cursorNoneBits, 0, sizeof( cursorNoneBits ) );\r
- memset( &dontCare, 0, sizeof( dontCare ) );\r
- cursorNonePixmap = XCreateBitmapFromData ( fgDisplay.Display,\r
- fgDisplay.RootWindow,\r
- cursorNoneBits, 16, 16 );\r
- if( cursorNonePixmap != None ) {\r
- cursorNone = XCreatePixmapCursor( fgDisplay.Display,\r
- cursorNonePixmap, cursorNonePixmap,\r
- &dontCare, &dontCare, 0, 0 );\r
- XFreePixmap( fgDisplay.Display, cursorNonePixmap );\r
- }\r
- }\r
- return cursorNone;\r
-}\r
-\r
-typedef struct tag_cursorCacheEntry cursorCacheEntry;\r
-struct tag_cursorCacheEntry {\r
- unsigned int cursorShape; /* an XC_foo value */\r
- Cursor cachedCursor; /* None if the corresponding cursor has\r
- not been created yet */\r
-};\r
-\r
-/*\r
- * Note: The arrangement of the table below depends on the fact that\r
- * the "normal" GLUT_CURSOR_* values start a 0 and are consecutive.\r
- */ \r
-static cursorCacheEntry cursorCache[] = {\r
- { XC_arrow, None }, /* GLUT_CURSOR_RIGHT_ARROW */\r
- { XC_top_left_arrow, None }, /* GLUT_CURSOR_LEFT_ARROW */\r
- { XC_hand1, None }, /* GLUT_CURSOR_INFO */\r
- { XC_pirate, None }, /* GLUT_CURSOR_DESTROY */\r
- { XC_question_arrow, None }, /* GLUT_CURSOR_HELP */\r
- { XC_exchange, None }, /* GLUT_CURSOR_CYCLE */\r
- { XC_spraycan, None }, /* GLUT_CURSOR_SPRAY */\r
- { XC_watch, None }, /* GLUT_CURSOR_WAIT */\r
- { XC_xterm, None }, /* GLUT_CURSOR_TEXT */\r
- { XC_crosshair, None }, /* GLUT_CURSOR_CROSSHAIR */\r
- { XC_sb_v_double_arrow, None }, /* GLUT_CURSOR_UP_DOWN */\r
- { XC_sb_h_double_arrow, None }, /* GLUT_CURSOR_LEFT_RIGHT */\r
- { XC_top_side, None }, /* GLUT_CURSOR_TOP_SIDE */\r
- { XC_bottom_side, None }, /* GLUT_CURSOR_BOTTOM_SIDE */\r
- { XC_left_side, None }, /* GLUT_CURSOR_LEFT_SIDE */\r
- { XC_right_side, None }, /* GLUT_CURSOR_RIGHT_SIDE */\r
- { XC_top_left_corner, None }, /* GLUT_CURSOR_TOP_LEFT_CORNER */\r
- { XC_top_right_corner, None }, /* GLUT_CURSOR_TOP_RIGHT_CORNER */\r
- { XC_bottom_right_corner, None }, /* GLUT_CURSOR_BOTTOM_RIGHT_CORNER */\r
- { XC_bottom_left_corner, None } /* GLUT_CURSOR_BOTTOM_LEFT_CORNER */\r
-};\r
-\r
-static void fghSetCursor ( SFG_Window *window, int cursorID )\r
-{\r
- Cursor cursor;\r
- /*\r
- * XXX FULL_CROSSHAIR demotes to plain CROSSHAIR. Old GLUT allows\r
- * for this, but if there is a system that easily supports a full-\r
- * window (or full-screen) crosshair, we might consider it.\r
- */\r
- int cursorIDToUse =\r
- ( cursorID == GLUT_CURSOR_FULL_CROSSHAIR ) ? GLUT_CURSOR_CROSSHAIR : cursorID;\r
-\r
- if( ( cursorIDToUse >= 0 ) &&\r
- ( cursorIDToUse < sizeof( cursorCache ) / sizeof( cursorCache[0] ) ) ) {\r
- cursorCacheEntry *entry = &cursorCache[ cursorIDToUse ];\r
- if( entry->cachedCursor == None ) {\r
- entry->cachedCursor =\r
- XCreateFontCursor( fgDisplay.Display, entry->cursorShape );\r
- }\r
- cursor = entry->cachedCursor;\r
- } else {\r
- switch( cursorIDToUse )\r
- {\r
- case GLUT_CURSOR_NONE:\r
- cursor = getEmptyCursor( );\r
- break;\r
-\r
- case GLUT_CURSOR_INHERIT:\r
- cursor = None;\r
- break;\r
-\r
- default:\r
- fgError( "Unknown cursor type: %d", cursorIDToUse );\r
- return;\r
- }\r
- }\r
-\r
- if ( cursorIDToUse == GLUT_CURSOR_INHERIT ) {\r
- XUndefineCursor( fgDisplay.Display, window->Window.Handle );\r
- } else if ( cursor != None ) {\r
- XDefineCursor( fgDisplay.Display, window->Window.Handle, cursor );\r
- } else if ( cursorIDToUse != GLUT_CURSOR_NONE ) {\r
- fgError( "Failed to create cursor" );\r
- }\r
-}\r
-\r
-\r
-static void fghWarpPointer ( int x, int y )\r
-{\r
- XWarpPointer(\r
- fgDisplay.Display,\r
- None,\r
- fgStructure.CurrentWindow->Window.Handle,\r
- 0, 0, 0, 0,\r
- x, y\r
- );\r
- /* Make the warp visible immediately. */\r
- XFlush( fgDisplay.Display );\r
-}\r
-#endif\r
-\r
-\r
-#if TARGET_HOST_MS_WINDOWS\r
-static void fghSetCursor ( SFG_Window *window, int cursorID )\r
-{\r
- /*\r
- * Joe Krahn is re-writing the following code.\r
- */\r
- /* Set the cursor AND change it for this window class. */\r
-#if !defined(__MINGW64__) && _MSC_VER <= 1200\r
-# define MAP_CURSOR(a,b) \\r
- case a: \\r
- SetCursor( LoadCursor( NULL, b ) ); \\r
- SetClassLong( window->Window.Handle, \\r
- GCL_HCURSOR, \\r
- ( LONG )LoadCursor( NULL, b ) ); \\r
- break;\r
- /* Nuke the cursor AND change it for this window class. */\r
-# define ZAP_CURSOR(a,b) \\r
- case a: \\r
- SetCursor( NULL ); \\r
- SetClassLong( window->Window.Handle, \\r
- GCL_HCURSOR, ( LONG )NULL ); \\r
- break;\r
-#else\r
-# define MAP_CURSOR(a,b) \\r
- case a: \\r
- SetCursor( LoadCursor( NULL, b ) ); \\r
- SetClassLongPtr( window->Window.Handle, \\r
- GCLP_HCURSOR, \\r
- ( LONG )( LONG_PTR )LoadCursor( NULL, b ) ); \\r
- break;\r
- /* Nuke the cursor AND change it for this window class. */\r
-# define ZAP_CURSOR(a,b) \\r
- case a: \\r
- SetCursor( NULL ); \\r
- SetClassLongPtr( window->Window.Handle, \\r
- GCLP_HCURSOR, ( LONG )( LONG_PTR )NULL ); \\r
- break;\r
-#endif\r
-\r
- switch( cursorID )\r
- {\r
- MAP_CURSOR( GLUT_CURSOR_RIGHT_ARROW, IDC_ARROW );\r
- MAP_CURSOR( GLUT_CURSOR_LEFT_ARROW, IDC_ARROW );\r
- MAP_CURSOR( GLUT_CURSOR_INFO, IDC_HELP );\r
- MAP_CURSOR( GLUT_CURSOR_DESTROY, IDC_CROSS );\r
- MAP_CURSOR( GLUT_CURSOR_HELP, IDC_HELP );\r
- MAP_CURSOR( GLUT_CURSOR_CYCLE, IDC_SIZEALL );\r
- MAP_CURSOR( GLUT_CURSOR_SPRAY, IDC_CROSS );\r
- MAP_CURSOR( GLUT_CURSOR_WAIT, IDC_WAIT );\r
- MAP_CURSOR( GLUT_CURSOR_TEXT, IDC_IBEAM );\r
- MAP_CURSOR( GLUT_CURSOR_CROSSHAIR, IDC_CROSS );\r
- MAP_CURSOR( GLUT_CURSOR_UP_DOWN, IDC_SIZENS );\r
- MAP_CURSOR( GLUT_CURSOR_LEFT_RIGHT, IDC_SIZEWE );\r
- MAP_CURSOR( GLUT_CURSOR_TOP_SIDE, IDC_ARROW ); /* XXX ToDo */\r
- MAP_CURSOR( GLUT_CURSOR_BOTTOM_SIDE, IDC_ARROW ); /* XXX ToDo */\r
- MAP_CURSOR( GLUT_CURSOR_LEFT_SIDE, IDC_ARROW ); /* XXX ToDo */\r
- MAP_CURSOR( GLUT_CURSOR_RIGHT_SIDE, IDC_ARROW ); /* XXX ToDo */\r
- MAP_CURSOR( GLUT_CURSOR_TOP_LEFT_CORNER, IDC_SIZENWSE );\r
- MAP_CURSOR( GLUT_CURSOR_TOP_RIGHT_CORNER, IDC_SIZENESW );\r
- MAP_CURSOR( GLUT_CURSOR_BOTTOM_RIGHT_CORNER, IDC_SIZENWSE );\r
- MAP_CURSOR( GLUT_CURSOR_BOTTOM_LEFT_CORNER, IDC_SIZENESW );\r
- MAP_CURSOR( GLUT_CURSOR_INHERIT, IDC_ARROW ); /* XXX ToDo */\r
- ZAP_CURSOR( GLUT_CURSOR_NONE, NULL );\r
- MAP_CURSOR( GLUT_CURSOR_FULL_CROSSHAIR, IDC_CROSS ); /* XXX ToDo */\r
-\r
- default:\r
- fgError( "Unknown cursor type: %d", cursorID );\r
- break;\r
- }\r
-}\r
-\r
-\r
-static void fghWarpPointer ( int x, int y )\r
-{\r
- POINT coords;\r
- coords.x = x;\r
- coords.y = y;\r
-\r
- /* ClientToScreen() translates {coords} for us. */\r
- ClientToScreen( fgStructure.CurrentWindow->Window.Handle, &coords );\r
- SetCursorPos( coords.x, coords.y );\r
-}\r
-#endif\r
\r
\r
/* -- INTERNAL FUNCTIONS ---------------------------------------------------- */\r
void fgSetCursor ( SFG_Window *window, int cursorID )\r
{\r
- fghSetCursor ( window, cursorID );\r
+ fgPlatformSetCursor ( window, cursorID );\r
}\r
\r
\r
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSetCursor" );\r
FREEGLUT_EXIT_IF_NO_WINDOW ( "glutSetCursor" );\r
\r
- fghSetCursor ( fgStructure.CurrentWindow, cursorID );\r
+ fgPlatformSetCursor ( fgStructure.CurrentWindow, cursorID );\r
fgStructure.CurrentWindow->State.Cursor = cursorID;\r
}\r
\r
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWarpPointer" );\r
FREEGLUT_EXIT_IF_NO_WINDOW ( "glutWarpPointer" );\r
\r
- fghWarpPointer ( x, y );\r
+ fgPlatformWarpPointer ( x, y );\r
}\r
\r
/*** END OF FILE ***/\r