glutGet window position should be relative to parent
[freeglut] / src / x11 / fg_state_x11.c
index 3523477..79a7ac9 100644 (file)
  */
 
 #include <GL/freeglut.h>
-#include "../fg_internal.h"
-
-/*
- * TODO BEFORE THE STABLE RELEASE:
- *
- *  fgPlatformChooseFBConfig()      -- OK, but what about glutInitDisplayString()?
- */
-
-/* A helper function to check if a display mode is possible to use */
-GLXFBConfig* fgPlatformChooseFBConfig( int* numcfgs );
-
-/*
- * Queries the GL context about some attributes
- */
-int fgPlatformGetConfig( int attribute )
-{
-  int returnValue = 0;
-  int result;  /*  Not checked  */
-
-  if( fgStructure.CurrentWindow )
-      result = glXGetFBConfigAttrib( fgDisplay.pDisplay.Display,
-                                     *(fgStructure.CurrentWindow->Window.pContext.FBConfig),
-                                     attribute,
-                                     &returnValue );
-
-  return returnValue;
-}
+#include "fg_internal.h"
+#ifdef EGL_VERSION_1_0
+#include "egl/fg_state_egl.h"
+#else
+#include "x11/fg_state_x11_glx.h"
+#endif
 
-int fgPlatformGlutGet ( GLenum eWhat )
+int fgPlatformGlutDeviceGet ( GLenum eWhat )
 {
-    int nsamples = 0;
-
     switch( eWhat )
     {
-    /*
-     * The window/context specific queries are handled mostly by
-     * fgPlatformGetConfig().
-     */
-    case GLUT_WINDOW_NUM_SAMPLES:
-#ifdef GLX_VERSION_1_3
-        glGetIntegerv(GL_SAMPLES, &nsamples);
-#endif
-        return nsamples;
-
-    /*
-     * The rest of GLX queries under X are general enough to use a macro to
-     * check them
-     */
-#   define GLX_QUERY(a,b) case a: return fgPlatformGetConfig( b );
-
-    GLX_QUERY( GLUT_WINDOW_RGBA,                GLX_RGBA                );
-    GLX_QUERY( GLUT_WINDOW_DOUBLEBUFFER,        GLX_DOUBLEBUFFER        );
-    GLX_QUERY( GLUT_WINDOW_BUFFER_SIZE,         GLX_BUFFER_SIZE         );
-    GLX_QUERY( GLUT_WINDOW_STENCIL_SIZE,        GLX_STENCIL_SIZE        );
-    GLX_QUERY( GLUT_WINDOW_DEPTH_SIZE,          GLX_DEPTH_SIZE          );
-    GLX_QUERY( GLUT_WINDOW_RED_SIZE,            GLX_RED_SIZE            );
-    GLX_QUERY( GLUT_WINDOW_GREEN_SIZE,          GLX_GREEN_SIZE          );
-    GLX_QUERY( GLUT_WINDOW_BLUE_SIZE,           GLX_BLUE_SIZE           );
-    GLX_QUERY( GLUT_WINDOW_ALPHA_SIZE,          GLX_ALPHA_SIZE          );
-    GLX_QUERY( GLUT_WINDOW_ACCUM_RED_SIZE,      GLX_ACCUM_RED_SIZE      );
-    GLX_QUERY( GLUT_WINDOW_ACCUM_GREEN_SIZE,    GLX_ACCUM_GREEN_SIZE    );
-    GLX_QUERY( GLUT_WINDOW_ACCUM_BLUE_SIZE,     GLX_ACCUM_BLUE_SIZE     );
-    GLX_QUERY( GLUT_WINDOW_ACCUM_ALPHA_SIZE,    GLX_ACCUM_ALPHA_SIZE    );
-    GLX_QUERY( GLUT_WINDOW_STEREO,              GLX_STEREO              );
+    case GLUT_HAS_KEYBOARD:
+        /*
+         * X11 has a core keyboard by definition, although it can
+         * be present as a virtual/dummy keyboard. For now, there
+         * is no reliable way to tell if a real keyboard is present.
+         */
+        return 1;
 
-#   undef GLX_QUERY
+    /* X11 has a mouse by definition */
+    case GLUT_HAS_MOUSE:
+        return 1 ;
 
-    /* Colormap size is handled in a bit different way than all the rest */
-    case GLUT_WINDOW_COLORMAP_SIZE:
-        if( (fgPlatformGetConfig( GLX_RGBA )) || (fgStructure.CurrentWindow == NULL) )
+    case GLUT_NUM_MOUSE_BUTTONS:
+        /* We should be able to pass NULL when the last argument is zero,
+         * but at least one X server has a bug where this causes a segfault.
+         *
+         * In XFree86/Xorg servers, a mouse wheel is seen as two buttons
+         * rather than an Axis; "freeglut_main.c" expects this when
+         * checking for a wheel event.
+         */
         {
-            /*
-             * We've got a RGBA visual, so there is no colormap at all.
-             * The other possibility is that we have no current window set.
-             */
-            return 0;
+            unsigned char map;
+            int nbuttons = XGetPointerMapping(fgDisplay.pDisplay.Display, &map,0);
+            return nbuttons;
         }
-        else
-        {
-          const GLXFBConfig * fbconfig =
-                fgStructure.CurrentWindow->Window.pContext.FBConfig;
 
-          XVisualInfo * visualInfo =
-                glXGetVisualFromFBConfig( fgDisplay.pDisplay.Display, *fbconfig );
+    default:
+        fgWarning( "glutDeviceGet(): missing enum handle %d", eWhat );
+        break;
+    }
 
-          const int result = visualInfo->visual->map_entries;
+    /* And now -- the failure. */
+    return -1;
+}
 
-          XFree(visualInfo);
 
-          return result;
-        }
+int fgPlatformGlutGet ( GLenum eWhat )
+{
+    switch( eWhat )
+    {
 
     /*
      * Those calls are somewhat similiar, as they use XGetWindowAttributes()
@@ -128,15 +88,23 @@ int fgPlatformGlutGet ( GLenum eWhat )
     case GLUT_WINDOW_HEADER_HEIGHT:
     {
         int x, y;
-        Window w;
+        Window p,w;
 
         if( fgStructure.CurrentWindow == NULL )
             return 0;
 
+        if (fgStructure.CurrentWindow->Parent)
+            /* For child window, we should return relative to upper-left
+             * of parent's client area.
+             */
+            p = fgStructure.CurrentWindow->Parent->Window.Handle;
+        else
+            p = fgDisplay.pDisplay.RootWindow;
+            
         XTranslateCoordinates(
             fgDisplay.pDisplay.Display,
             fgStructure.CurrentWindow->Window.Handle,
-            fgDisplay.pDisplay.RootWindow,
+            p,
             0, 0, &x, &y, &w);
 
         switch ( eWhat )
@@ -145,7 +113,8 @@ int fgPlatformGlutGet ( GLenum eWhat )
         case GLUT_WINDOW_Y: return y;
         }
 
-        if ( w == 0 )
+        if ( w == 0 || fgStructure.CurrentWindow->Parent)
+            /* logic below needs w, and child windows don't have borders */
             return 0;
         XTranslateCoordinates(
             fgDisplay.pDisplay.Display,
@@ -177,187 +146,56 @@ int fgPlatformGlutGet ( GLenum eWhat )
         case GLUT_WINDOW_HEIGHT:           return winAttributes.height ;
         }
     }
-
-    /* I do not know yet if there will be a fgChooseVisual() function for Win32 */
-    case GLUT_DISPLAY_MODE_POSSIBLE:
-    {
-        /*  We should not have to call fgPlatformChooseFBConfig again here.  */
-        GLXFBConfig * fbconfig;
-        int isPossible;
-
-        fbconfig = fgPlatformChooseFBConfig(NULL);
-
-        if (fbconfig == NULL)
-        {
-            isPossible = 0;
-        }
-        else
+    
+    /* Colormap size is handled in a bit different way than all the rest */
+    case GLUT_WINDOW_COLORMAP_SIZE:
+        if(
+#ifndef EGL_VERSION_1_0
+          fgPlatformGetConfig( GLX_RGBA ) ||
+#endif
+          fgStructure.CurrentWindow == NULL)
         {
-            isPossible = 1;
-            XFree(fbconfig);
-        }
-
-        return isPossible;
-    }
-
-    /* This is system-dependant */
-    case GLUT_WINDOW_FORMAT_ID:
-        if( fgStructure.CurrentWindow == NULL )
+            /*
+             * We've got a RGBA visual, so there is no colormap at all.
+             * The other possibility is that we have no current window set.
+             */
             return 0;
-
-        return fgPlatformGetConfig( GLX_VISUAL_ID );
-
-    default:
-        fgWarning( "glutGet(): missing enum handle %d", eWhat );
-        break;
-    }
-
-       return -1;
-}
-
-
-int fgPlatformGlutDeviceGet ( GLenum eWhat )
-{
-    switch( eWhat )
-    {
-    case GLUT_HAS_KEYBOARD:
-        /*
-         * X11 has a core keyboard by definition, although it can
-         * be present as a virtual/dummy keyboard. For now, there
-         * is no reliable way to tell if a real keyboard is present.
-         */
-        return 1;
-
-    /* X11 has a mouse by definition */
-    case GLUT_HAS_MOUSE:
-        return 1 ;
-
-    case GLUT_NUM_MOUSE_BUTTONS:
-        /* We should be able to pass NULL when the last argument is zero,
-         * but at least one X server has a bug where this causes a segfault.
-         *
-         * In XFree86/Xorg servers, a mouse wheel is seen as two buttons
-         * rather than an Axis; "freeglut_main.c" expects this when
-         * checking for a wheel event.
-         */
-        {
-            unsigned char map;
-            int nbuttons = XGetPointerMapping(fgDisplay.pDisplay.Display, &map,0);
-            return nbuttons;
         }
-
-    default:
-        fgWarning( "glutDeviceGet(): missing enum handle %d", eWhat );
-        break;
-    }
-
-    /* And now -- the failure. */
-    return -1;
-}
-
-
-int *fgPlatformGlutGetModeValues(GLenum eWhat, int *size)
-{
-  int *array;
-
-  int attributes[9];
-  GLXFBConfig * fbconfigArray;  /*  Array of FBConfigs  */
-  int fbconfigArraySize;        /*  Number of FBConfigs in the array  */
-  int attribute_name = 0;
-
-  array = NULL;
-  *size = 0;
-
-  switch (eWhat)
-    {
-    case GLUT_AUX:
-    case GLUT_MULTISAMPLE:
-
-      attributes[0] = GLX_BUFFER_SIZE;
-      attributes[1] = GLX_DONT_CARE;
-
-      switch (eWhat)
-        {
-        case GLUT_AUX:
-          /*
-            FBConfigs are now sorted by increasing number of auxiliary
-            buffers.  We want at least one buffer.
-          */
-          attributes[2] = GLX_AUX_BUFFERS;
-          attributes[3] = 1;
-          attributes[4] = None;
-
-          attribute_name = GLX_AUX_BUFFERS;
-
-          break;
-
-
-        case GLUT_MULTISAMPLE:
-          attributes[2] = GLX_AUX_BUFFERS;
-          attributes[3] = GLX_DONT_CARE;
-          attributes[4] = GLX_SAMPLE_BUFFERS;
-          attributes[5] = 1;
-          /*
-            FBConfigs are now sorted by increasing number of samples per
-            pixel.  We want at least one sample.
-          */
-          attributes[6] = GLX_SAMPLES;
-          attributes[7] = 1;
-          attributes[8] = None;
-
-          attribute_name = GLX_SAMPLES;
-
-          break;
-        }
-
-      fbconfigArray = glXChooseFBConfig(fgDisplay.pDisplay.Display,
-                                        fgDisplay.pDisplay.Screen,
-                                        attributes,
-                                        &fbconfigArraySize);
-
-      if (fbconfigArray != NULL)
+        else
         {
-          int * temp_array;
-          int result;   /*  Returned by glXGetFBConfigAttrib. Not checked.  */
-          int previous_value;
-          int i;
-
-          temp_array = malloc(sizeof(int) * fbconfigArraySize);
-          previous_value = 0;
-
-          for (i = 0; i < fbconfigArraySize; i++)
-            {
-              int value;
+          XVisualInfo * visualInfo;
+                 int result;
+#ifdef EGL_VERSION_1_0
+         EGLint vid = 0;
+         XVisualInfo visualTemplate;
+         int num_visuals;
+         if (!eglGetConfigAttrib(fgDisplay.pDisplay.egl.Display,
+                                 fgStructure.CurrentWindow->Window.pContext.egl.Config,
+                                 EGL_NATIVE_VISUAL_ID, &vid))
+           fgError("eglGetConfigAttrib(EGL_NATIVE_VISUAL_ID) failed");
+         visualTemplate.visualid = vid;
+         visualInfo = XGetVisualInfo(fgDisplay.pDisplay.Display, VisualIDMask, &visualTemplate, &num_visuals);
+#else
+         {
+          const GLXFBConfig fbconfig =
+                fgStructure.CurrentWindow->Window.pContext.FBConfig;
 
-              result = glXGetFBConfigAttrib(fgDisplay.pDisplay.Display,
-                                            fbconfigArray[i],
-                                            attribute_name,
-                                            &value);
-              if (value > previous_value)
-                {
-                  temp_array[*size] = value;
-                  previous_value = value;
-                  (*size)++;
-                }
-            }
+          visualInfo =
+                glXGetVisualFromFBConfig( fgDisplay.pDisplay.Display, fbconfig );
+         }
+#endif
+          result = visualInfo->visual->map_entries;
 
-          array = malloc(sizeof(int) * (*size));
-          for (i = 0; i < *size; i++)
-            {
-              array[i] = temp_array[i];
-            }
+          XFree(visualInfo);
 
-          free(temp_array);
-          XFree(fbconfigArray);
+          return result;
         }
 
-      break;
-
     default:
-      break;
+#ifdef EGL_VERSION_1_0
+      return fghPlatformGlutGetEGL(eWhat);
+#else
+      return fghPlatformGlutGetGLX(eWhat);
+#endif
     }
-
-  return array;
 }
-
-