X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Ffreeglut_cursor.c;h=44ab5e0cccb2b91f7e852024890fbef0e4502e6c;hb=ba1d6bb50131c6396078a1512e06abf1e82d7191;hp=9d519c04141f4869b5dd12b8921c964c8fb8d905;hpb=646676b8dbf8ab504ac8a275fe9a63a403a3190b;p=freeglut diff --git a/src/freeglut_cursor.c b/src/freeglut_cursor.c index 9d519c0..44ab5e0 100644 --- a/src/freeglut_cursor.c +++ b/src/freeglut_cursor.c @@ -35,14 +35,13 @@ #include "freeglut_internal.h" #if TARGET_HOST_UNIX_X11 - #include + #include #endif /* * TODO BEFORE THE STABLE RELEASE: - * - * fgDisplayCursor() -- this waits for better times - * glutSetCursor() -- both X and Win32 mappings are incomplete + * glutSetCursor() -- Win32 mappings are incomplete + * X mappings are nearly right. * * It would be good to use custom mouse cursor shapes, and introduce * an option to display them using glBitmap() and/or texture mapping, @@ -51,17 +50,6 @@ /* -- INTERNAL FUNCTIONS --------------------------------------------------- */ -/* - * Display the mouse cursor using OpenGL calls - */ -void fgDisplayCursor( void ) -{ - /* - * Do nothing for the moment - */ -} - - /* -- INTERFACE FUNCTIONS -------------------------------------------------- */ /* @@ -69,82 +57,99 @@ void fgDisplayCursor( void ) */ void FGAPIENTRY glutSetCursor( int cursorID ) { - /* - * Make sure freeglut is ready and there is a current window set - */ - freeglut_assert_ready; freeglut_assert_window; + freeglut_assert_ready; + freeglut_assert_window; #if TARGET_HOST_UNIX_X11 - { - Cursor cursor; - - /* - * For now we'll limit ourselves to the X cursor fonts... - */ -# define MAP_CURSOR(a,b) case a: cursor = XCreateFontCursor( fgDisplay.Display, b ); break; - - switch( cursorID ) - { - MAP_CURSOR( GLUT_CURSOR_RIGHT_ARROW, XC_left_ptr ); - MAP_CURSOR( GLUT_CURSOR_LEFT_ARROW, XC_right_ptr ); - MAP_CURSOR( GLUT_CURSOR_INFO, XC_question_arrow ); - MAP_CURSOR( GLUT_CURSOR_DESTROY, XC_target ); - MAP_CURSOR( GLUT_CURSOR_HELP, XC_question_arrow ); - MAP_CURSOR( GLUT_CURSOR_CYCLE, XC_circle ); - MAP_CURSOR( GLUT_CURSOR_SPRAY, XC_spraycan ); - MAP_CURSOR( GLUT_CURSOR_WAIT, XC_watch ); - MAP_CURSOR( GLUT_CURSOR_TEXT, XC_draft_large ); - MAP_CURSOR( GLUT_CURSOR_CROSSHAIR, XC_crosshair ); - MAP_CURSOR( GLUT_CURSOR_NONE, XC_trek ); - - default: - MAP_CURSOR( GLUT_CURSOR_UP_DOWN, XC_arrow ); - } - - /* - * Define a window's cursor now - */ - XDefineCursor( fgDisplay.Display, fgStructure.Window->Window.Handle, cursor ); - } + /* + * Open issues: + * (a) GLUT_CURSOR_NONE doesn't do what it should. We can probably + * build an empty pixmap for it, though, quite painlessly. + * (b) Are we allocating resources, or causing X to do so? + * If yes, we should arrange to deallocate! + * (c) No error checking. Is that a problem? + * (d) 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. + * (e) Out-of-range cursor-types are ignored. Should we abort? + * Print a warning message? + */ + { + Cursor cursor; +#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_INHERIT: + break; + default: + return; + } + + if( GLUT_CURSOR_INHERIT == cursorID ) + XUndefineCursor( fgDisplay.Display, fgStructure.Window->Window.Handle ); + else + XDefineCursor( fgDisplay.Display, fgStructure.Window->Window.Handle, cursor ); + } #elif TARGET_HOST_WIN32 - /* - * This is a temporary solution only... - */ - /* Set the cursor AND change it for this window class. */ -# define MAP_CURSOR(a,b) case a: SetCursor( LoadCursor( NULL, b ) ); \ + + /* + * This is a temporary solution only... + */ + /* Set the cursor AND change it for this window class. */ +# define MAP_CURSOR(a,b) case a: SetCursor( LoadCursor( NULL, b ) ); \ SetClassLong(fgStructure.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 ); \ + /* Nuke the cursor AND change it for this window class. */ +# define ZAP_CURSOR(a,b) case a: SetCursor( NULL ); \ SetClassLong(fgStructure.Window->Window.Handle,GCL_HCURSOR,(LONG)NULL); \ break; - 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 ); - - default: - MAP_CURSOR( GLUT_CURSOR_UP_DOWN, IDC_ARROW ); - } - + 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 ); + + default: + MAP_CURSOR( GLUT_CURSOR_UP_DOWN, IDC_ARROW ); + } #endif - /* - * Remember the currently selected cursor - */ - fgStructure.Window->State.Cursor = cursorID; + fgStructure.Window->State.Cursor = cursorID; } /* @@ -152,36 +157,30 @@ void FGAPIENTRY glutSetCursor( int cursorID ) */ void FGAPIENTRY glutWarpPointer( int x, int y ) { - freeglut_assert_ready; freeglut_assert_window; + freeglut_assert_ready; + freeglut_assert_window; #if TARGET_HOST_UNIX_X11 - /* - * Move the mouse pointer to given window coordinates - */ - XWarpPointer( + + XWarpPointer( fgDisplay.Display, None, fgStructure.Window->Window.Handle, 0, 0, 0, 0, x, y - ); - - XFlush( fgDisplay.Display ); + ); + XFlush( fgDisplay.Display ); #elif TARGET_HOST_WIN32 - { - POINT coords = { x, y }; - - /* - * First of all, we need to find the new screen-relative coordinates of the mouse cursor - */ - ClientToScreen( fgStructure.Window->Window.Handle, &coords ); - /* - * Now set the new mouse cursor position... - */ - SetCursorPos( coords.x, coords.y ); - } + { + POINT coords = { x, y }; + /* + * ClientToScreen() translates {coords} for us. + */ + ClientToScreen( fgStructure.Window->Window.Handle, &coords ); + SetCursorPos( coords.x, coords.y ); + } #endif }