X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Ffreeglut_cursor.c;h=33708319d8d938a0fdc6a5ee0bb11c243fe1c9ad;hb=ded8742fba5a4622b49778679cc7e26d197d75c5;hp=db033ed12ffe74f609ee0a3c09269143bc2eb64f;hpb=ba21dbc1eca4d994466497da8a309ce1300e775f;p=freeglut diff --git a/src/freeglut_cursor.c b/src/freeglut_cursor.c index db033ed..3370831 100644 --- a/src/freeglut_cursor.c +++ b/src/freeglut_cursor.c @@ -28,10 +28,6 @@ #include #include "freeglut_internal.h" -#if TARGET_HOST_UNIX_X11 - #include -#endif - /* * TODO BEFORE THE STABLE RELEASE: * glutSetCursor() -- Win32 mappings are incomplete. @@ -41,7 +37,10 @@ * apart from the windowing system version. */ -/* -- INTERNAL FUNCTIONS --------------------------------------------------- */ +/* -- PRIVATE FUNCTIONS --------------------------------------------------- */ + +#if TARGET_HOST_POSIX_X11 || TARGET_HOST_MAC_OSX || TARGET_HOST_SOLARIS + #include /* * A factory method for an empty cursor @@ -102,102 +101,171 @@ static cursorCacheEntry cursorCache[] = { { XC_bottom_left_corner, None } /* GLUT_CURSOR_BOTTOM_LEFT_CORNER */ }; -/* -- INTERFACE FUNCTIONS -------------------------------------------------- */ - -/* - * Set the cursor image to be used for the current window - */ -void FGAPIENTRY glutSetCursor( int cursorID ) +static void fghSetCursor ( SFG_Window *window, int cursorID ) { - FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSetCursor" ); - FREEGLUT_EXIT_IF_NO_WINDOW ( "glutSetCursor" ); + 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 TARGET_HOST_UNIX_X11 - { - 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; - } + 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; - if ( ( cursorIDToUse != GLUT_CURSOR_NONE ) && ( cursor == None ) ) { - fgError( "Failed to create cursor" ); + case GLUT_CURSOR_INHERIT: + cursor = None; + break; + + default: + fgError( "Unknown cursor type: %d", cursorIDToUse ); + return; } - XDefineCursor( fgDisplay.Display, - fgStructure.Window->Window.Handle, cursor ); } -#elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE + if ( cursorIDToUse == GLUT_CURSOR_INHERIT ) { + XUndefineCursor( fgDisplay.Display, window->Window.Handle ); + } else if ( cursor != None ) { + XDefineCursor( fgDisplay.Display, window->Window.Handle, cursor ); + } else if ( cursorIDToUse != GLUT_CURSOR_NONE ) { + fgError( "Failed to create cursor" ); + } +} + + +static void fghWarpPointer ( int x, int y ) +{ + XWarpPointer( + fgDisplay.Display, + None, + fgStructure.CurrentWindow->Window.Handle, + 0, 0, 0, 0, + x, y + ); + /* Make the warp visible immediately. */ + XFlush( fgDisplay.Display ); +} +#endif + +#if TARGET_HOST_MS_WINDOWS +static void fghSetCursor ( SFG_Window *window, int cursorID ) +{ /* - * This is a temporary solution only... + * Joe Krahn is re-writing the following code. */ /* Set the cursor AND change it for this window class. */ +#if !defined(__MINGW64__) && _MSC_VER <= 1200 # define MAP_CURSOR(a,b) \ case a: \ SetCursor( LoadCursor( NULL, b ) ); \ - SetClassLong( fgStructure.Window->Window.Handle, \ + SetClassLong( window->Window.Handle, \ GCL_HCURSOR, \ ( LONG )LoadCursor( NULL, b ) ); \ break; - /* Nuke the cursor AND change it for this window class. */ # define ZAP_CURSOR(a,b) \ case a: \ SetCursor( NULL ); \ - SetClassLong( fgStructure.Window->Window.Handle, \ + SetClassLong( window->Window.Handle, \ GCL_HCURSOR, ( LONG )NULL ); \ break; +#else +# define MAP_CURSOR(a,b) \ + case a: \ + SetCursor( LoadCursor( NULL, b ) ); \ + SetClassLongPtr( window->Window.Handle, \ + GCLP_HCURSOR, \ + ( LONG )( LONG_PTR )LoadCursor( NULL, b ) ); \ + break; + /* Nuke the cursor AND change it for this window class. */ +# define ZAP_CURSOR(a,b) \ + case a: \ + SetCursor( NULL ); \ + SetClassLongPtr( window->Window.Handle, \ + GCLP_HCURSOR, ( LONG )( LONG_PTR )NULL ); \ + break; +#endif switch( cursorID ) { - MAP_CURSOR( GLUT_CURSOR_RIGHT_ARROW, IDC_ARROW ); - MAP_CURSOR( GLUT_CURSOR_LEFT_ARROW, IDC_ARROW ); - MAP_CURSOR( GLUT_CURSOR_INFO, IDC_HELP ); - MAP_CURSOR( GLUT_CURSOR_DESTROY, IDC_CROSS ); - MAP_CURSOR( GLUT_CURSOR_HELP, IDC_HELP ); - MAP_CURSOR( GLUT_CURSOR_CYCLE, IDC_SIZEALL ); - MAP_CURSOR( GLUT_CURSOR_SPRAY, IDC_CROSS ); - MAP_CURSOR( GLUT_CURSOR_WAIT, IDC_WAIT ); - MAP_CURSOR( GLUT_CURSOR_TEXT, IDC_UPARROW ); - MAP_CURSOR( GLUT_CURSOR_CROSSHAIR, IDC_CROSS ); - /* MAP_CURSOR( GLUT_CURSOR_NONE, IDC_NO ); */ - ZAP_CURSOR( GLUT_CURSOR_NONE, NULL ); + MAP_CURSOR( GLUT_CURSOR_RIGHT_ARROW, IDC_ARROW ); + MAP_CURSOR( GLUT_CURSOR_LEFT_ARROW, IDC_ARROW ); + MAP_CURSOR( GLUT_CURSOR_INFO, IDC_HELP ); + MAP_CURSOR( GLUT_CURSOR_DESTROY, IDC_CROSS ); + MAP_CURSOR( GLUT_CURSOR_HELP, IDC_HELP ); + MAP_CURSOR( GLUT_CURSOR_CYCLE, IDC_SIZEALL ); + MAP_CURSOR( GLUT_CURSOR_SPRAY, IDC_CROSS ); + MAP_CURSOR( GLUT_CURSOR_WAIT, IDC_WAIT ); + MAP_CURSOR( GLUT_CURSOR_TEXT, IDC_IBEAM ); + MAP_CURSOR( GLUT_CURSOR_CROSSHAIR, IDC_CROSS ); + MAP_CURSOR( GLUT_CURSOR_UP_DOWN, IDC_SIZENS ); + MAP_CURSOR( GLUT_CURSOR_LEFT_RIGHT, IDC_SIZEWE ); + MAP_CURSOR( GLUT_CURSOR_TOP_SIDE, IDC_ARROW ); /* XXX ToDo */ + MAP_CURSOR( GLUT_CURSOR_BOTTOM_SIDE, IDC_ARROW ); /* XXX ToDo */ + MAP_CURSOR( GLUT_CURSOR_LEFT_SIDE, IDC_ARROW ); /* XXX ToDo */ + MAP_CURSOR( GLUT_CURSOR_RIGHT_SIDE, IDC_ARROW ); /* XXX ToDo */ + MAP_CURSOR( GLUT_CURSOR_TOP_LEFT_CORNER, IDC_SIZENWSE ); + MAP_CURSOR( GLUT_CURSOR_TOP_RIGHT_CORNER, IDC_SIZENESW ); + MAP_CURSOR( GLUT_CURSOR_BOTTOM_RIGHT_CORNER, IDC_SIZENWSE ); + MAP_CURSOR( GLUT_CURSOR_BOTTOM_LEFT_CORNER, IDC_SIZENESW ); + MAP_CURSOR( GLUT_CURSOR_INHERIT, IDC_ARROW ); /* XXX ToDo */ + ZAP_CURSOR( GLUT_CURSOR_NONE, NULL ); + MAP_CURSOR( GLUT_CURSOR_FULL_CROSSHAIR, IDC_CROSS ); /* XXX ToDo */ default: - MAP_CURSOR( GLUT_CURSOR_UP_DOWN, IDC_ARROW ); + fgError( "Unknown cursor type: %d", cursorID ); + break; } +} + + +static void fghWarpPointer ( int x, int y ) +{ + POINT coords; + coords.x = x; + coords.y = y; + + /* ClientToScreen() translates {coords} for us. */ + ClientToScreen( fgStructure.CurrentWindow->Window.Handle, &coords ); + SetCursorPos( coords.x, coords.y ); +} #endif - fgStructure.Window->State.Cursor = cursorID; + +/* -- INTERNAL FUNCTIONS ---------------------------------------------------- */ +void fgSetCursor ( SFG_Window *window, int cursorID ) +{ + fghSetCursor ( window, cursorID ); +} + + +/* -- INTERFACE FUNCTIONS -------------------------------------------------- */ + +/* + * Set the cursor image to be used for the current window + */ +void FGAPIENTRY glutSetCursor( int cursorID ) +{ + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSetCursor" ); + FREEGLUT_EXIT_IF_NO_WINDOW ( "glutSetCursor" ); + + fghSetCursor ( fgStructure.CurrentWindow, cursorID ); + fgStructure.CurrentWindow->State.Cursor = cursorID; } /* @@ -208,31 +276,7 @@ void FGAPIENTRY glutWarpPointer( int x, int y ) FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWarpPointer" ); FREEGLUT_EXIT_IF_NO_WINDOW ( "glutWarpPointer" ); -#if TARGET_HOST_UNIX_X11 - - XWarpPointer( - fgDisplay.Display, - None, - fgStructure.Window->Window.Handle, - 0, 0, 0, 0, - x, y - ); - /* Make the warp visible immediately. */ - XFlush( fgDisplay.Display ); - -#elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE - - { - POINT coords; - coords.x = x; - coords.y = y; - - /* ClientToScreen() translates {coords} for us. */ - ClientToScreen( fgStructure.Window->Window.Handle, &coords ); - SetCursorPos( coords.x, coords.y ); - } - -#endif + fghWarpPointer ( x, y ); } /*** END OF FILE ***/