Make it compile again with "-Wall -pedantic -Werror", redoing quite a
[freeglut] / src / freeglut_cursor.c
index 0d6d1ef..d26b581 100644 (file)
@@ -29,7 +29,7 @@
 #include "config.h"
 #endif
 
-#include "../include/GL/freeglut.h"
+#include <GL/freeglut.h>
 #include "freeglut_internal.h"
 
 #if TARGET_HOST_UNIX_X11
 
 /* -- INTERNAL FUNCTIONS --------------------------------------------------- */
 
+#if TARGET_HOST_UNIX_X11
+
+static int fghGetCursorError( Cursor cursor )
+{
+    int ret = 0;
+    char buf[ 256 ];
+
+    switch( cursor )
+    {
+    case BadAlloc:
+    case BadFont:
+    case BadMatch:
+    case BadPixmap:
+    case BadValue:
+        XGetErrorText( fgDisplay.Display, cursor, buf, sizeof buf );
+        fgWarning( "Error in setting cursor:\n %s.", buf );
+        ret = cursor;
+        break;
+    default:
+        /* no error */
+        break;
+    }
+
+    return ret;
+}
+
+#endif
+
+
 /* -- INTERFACE FUNCTIONS -------------------------------------------------- */
 
 /*
  */
 void FGAPIENTRY glutSetCursor( int cursorID )
 {
-    freeglut_assert_ready;  /* XXX WHY do we need the timer active for this? */
-    freeglut_assert_window;
+    FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSetCursor" );
+    FREEGLUT_EXIT_IF_NO_WINDOW ( "glutSetCursor" );
 
 #if TARGET_HOST_UNIX_X11
     /*
      * Open issues:
-     * (X) GLUT_CURSOR_NONE doesn't do what it should.  We can probably
-     *     build an empty pixmap for it, though, quite painlessly.
-     * (X) 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
+     * (a) Partial error checking.  Is that a problem?
+     *     Is fghGetCursorError() correct?  Should we abort on errors?
+     *     Should there be a freeglut-wide X error handler?  Should
+     *     we use the X error-handler mechanism?
+     * (b) 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?
+     * (c) Out-of-range cursor-types generate warnings.  Should we abort?
      */
     {
-        Cursor cursor;
-        Pixmap no_cursor;  /* Used for GLUT_CURSOR_NONE */
+        Cursor cursor = None;
+        Pixmap no_cursor = None ;  /* Used for GLUT_CURSOR_NONE */
+        int error = 0;
 
 #define MAP_CURSOR(a,b)                                     \
     case a:                                                 \
@@ -82,7 +110,7 @@ void FGAPIENTRY glutSetCursor( int cursorID )
 
         if( GLUT_CURSOR_FULL_CROSSHAIR == cursorID )
             cursorID = GLUT_CURSOR_CROSSHAIR;
-        
+
         switch( cursorID )
         {
             MAP_CURSOR( GLUT_CURSOR_RIGHT_ARROW, XC_right_ptr);
@@ -107,9 +135,16 @@ void FGAPIENTRY glutSetCursor( int cursorID )
                         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:
         {
-            static unsigned char no_cursor_bits[ 32 ];
+            /*
+             * 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 char no_cursor_bits[ 32 ];
             XColor black;
             no_cursor = XCreatePixmapFromBitmapData( fgDisplay.Display,
                                                      fgDisplay.RootWindow,
@@ -127,13 +162,17 @@ void FGAPIENTRY glutSetCursor( int cursorID )
                                           0, 0 );
             break;
         }
-        
+
         case GLUT_CURSOR_INHERIT:
             break;
+
         default:
+            fgWarning( "Unknown cursor type: %d", cursorID );
             return;
         }
 
+        error = fghGetCursorError( cursor );
+
         if( GLUT_CURSOR_INHERIT == cursorID )
             XUndefineCursor( fgDisplay.Display,
                              fgStructure.Window->Window.Handle );
@@ -147,7 +186,7 @@ void FGAPIENTRY glutSetCursor( int cursorID )
         }
     }
 
-#elif TARGET_HOST_WIN32
+#elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE
 
     /*
      * This is a temporary solution only...
@@ -161,7 +200,7 @@ void FGAPIENTRY glutSetCursor( int cursorID )
                           ( LONG )LoadCursor( NULL, b ) );       \
         break;
 
-        /* Nuke the cursor AND change it for this window class. */
+    /* Nuke the cursor AND change it for this window class. */
 #       define ZAP_CURSOR(a,b)                                   \
         case a:                                                  \
             SetCursor( NULL );                                   \
@@ -169,27 +208,27 @@ void FGAPIENTRY glutSetCursor( int cursorID )
                           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
 
-  fgStructure.Window->State.Cursor = cursorID;
+    fgStructure.Window->State.Cursor = cursorID;
 }
 
 /*
@@ -197,8 +236,8 @@ void FGAPIENTRY glutSetCursor( int cursorID )
  */
 void FGAPIENTRY glutWarpPointer( int x, int y )
 {
-    freeglut_assert_ready; /* XXX WHY do we need the timer active for this? */
-    freeglut_assert_window;
+    FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWarpPointer" );
+    FREEGLUT_EXIT_IF_NO_WINDOW ( "glutWarpPointer" );
 
 #if TARGET_HOST_UNIX_X11
 
@@ -211,13 +250,14 @@ void FGAPIENTRY glutWarpPointer( int x, int y )
     );
     XFlush( fgDisplay.Display ); /* XXX Is this really necessary? */
 
-#elif TARGET_HOST_WIN32
+#elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE
 
     {
-        POINT coords = { x, y };
-        /*
-         * ClientToScreen() translates {coords} for us.
-         */
+        POINT coords;
+        coords.x = x;
+        coords.y = y;
+
+        /* ClientToScreen() translates {coords} for us. */
         ClientToScreen( fgStructure.Window->Window.Handle, &coords );
         SetCursorPos( coords.x, coords.y );
     }