Add support for X11+EGL.
[freeglut] / src / x11 / fg_state_x11.c
1 /*
2  * freeglut_state_x11.c
3  *
4  * X11-specific freeglut state query methods.
5  *
6  * Copyright (c) 2012 Stephen J. Baker. All Rights Reserved.
7  * Written by John F. Fay, <fayjf@sourceforge.net>
8  * Creation date: Sat Feb 4 2012
9  *
10  * Permission is hereby granted, free of charge, to any person obtaining a
11  * copy of this software and associated documentation files (the "Software"),
12  * to deal in the Software without restriction, including without limitation
13  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14  * and/or sell copies of the Software, and to permit persons to whom the
15  * Software is furnished to do so, subject to the following conditions:
16  *
17  * The above copyright notice and this permission notice shall be included
18  * in all copies or substantial portions of the Software.
19  *
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
23  * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
24  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
25  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26  */
27
28 #include <GL/freeglut.h>
29 #include "../fg_internal.h"
30
31 int fgPlatformGlutDeviceGet ( GLenum eWhat )
32 {
33     switch( eWhat )
34     {
35     case GLUT_HAS_KEYBOARD:
36         /*
37          * X11 has a core keyboard by definition, although it can
38          * be present as a virtual/dummy keyboard. For now, there
39          * is no reliable way to tell if a real keyboard is present.
40          */
41         return 1;
42
43     /* X11 has a mouse by definition */
44     case GLUT_HAS_MOUSE:
45         return 1 ;
46
47     case GLUT_NUM_MOUSE_BUTTONS:
48         /* We should be able to pass NULL when the last argument is zero,
49          * but at least one X server has a bug where this causes a segfault.
50          *
51          * In XFree86/Xorg servers, a mouse wheel is seen as two buttons
52          * rather than an Axis; "freeglut_main.c" expects this when
53          * checking for a wheel event.
54          */
55         {
56             unsigned char map;
57             int nbuttons = XGetPointerMapping(fgDisplay.pDisplay.Display, &map,0);
58             return nbuttons;
59         }
60
61     default:
62         fgWarning( "glutDeviceGet(): missing enum handle %d", eWhat );
63         break;
64     }
65
66     /* And now -- the failure. */
67     return -1;
68 }
69
70
71 int fgPlatformGlutGet ( GLenum eWhat )
72 {
73     switch( eWhat )
74     {
75
76     /*
77      * Those calls are somewhat similiar, as they use XGetWindowAttributes()
78      * function
79      */
80     case GLUT_WINDOW_X:
81     case GLUT_WINDOW_Y:
82     case GLUT_WINDOW_BORDER_WIDTH:
83     case GLUT_WINDOW_HEADER_HEIGHT:
84     {
85         int x, y;
86         Window w;
87
88         if( fgStructure.CurrentWindow == NULL )
89             return 0;
90
91         XTranslateCoordinates(
92             fgDisplay.pDisplay.Display,
93             fgStructure.CurrentWindow->Window.Handle,
94             fgDisplay.pDisplay.RootWindow,
95             0, 0, &x, &y, &w);
96
97         switch ( eWhat )
98         {
99         case GLUT_WINDOW_X: return x;
100         case GLUT_WINDOW_Y: return y;
101         }
102
103         if ( w == 0 )
104             return 0;
105         XTranslateCoordinates(
106             fgDisplay.pDisplay.Display,
107             fgStructure.CurrentWindow->Window.Handle,
108             w, 0, 0, &x, &y, &w);
109
110         switch ( eWhat )
111         {
112         case GLUT_WINDOW_BORDER_WIDTH:  return x;
113         case GLUT_WINDOW_HEADER_HEIGHT: return y;
114         }
115     }
116
117     case GLUT_WINDOW_WIDTH:
118     case GLUT_WINDOW_HEIGHT:
119     {
120         XWindowAttributes winAttributes;
121
122         if( fgStructure.CurrentWindow == NULL )
123             return 0;
124         XGetWindowAttributes(
125             fgDisplay.pDisplay.Display,
126             fgStructure.CurrentWindow->Window.Handle,
127             &winAttributes
128         );
129         switch ( eWhat )
130         {
131         case GLUT_WINDOW_WIDTH:            return winAttributes.width ;
132         case GLUT_WINDOW_HEIGHT:           return winAttributes.height ;
133         }
134     }
135     
136     /* Colormap size is handled in a bit different way than all the rest */
137     case GLUT_WINDOW_COLORMAP_SIZE:
138         if(
139 #ifndef EGL_VERSION_1_0
140            fgPlatformGetConfig( GLX_RGBA ) ||
141 #endif
142            fgStructure.CurrentWindow == NULL)
143         {
144             /*
145              * We've got a RGBA visual, so there is no colormap at all.
146              * The other possibility is that we have no current window set.
147              */
148             return 0;
149         }
150         else
151         {
152           XVisualInfo * visualInfo;
153 #ifdef EGL_VERSION_1_0
154           EGLint vid = 0;
155           XVisualInfo visualTemplate;
156           int num_visuals;
157           if (!eglGetConfigAttrib(fgDisplay.pDisplay.egl.Display,
158                                   fgStructure.CurrentWindow->Window.pContext.egl.Config,
159                                   EGL_NATIVE_VISUAL_ID, &vid))
160             fgError("eglGetConfigAttrib(EGL_NATIVE_VISUAL_ID) failed");
161           visualTemplate.visualid = vid;
162           visualInfo = XGetVisualInfo(fgDisplay.pDisplay.Display, VisualIDMask, &visualTemplate, &num_visuals);
163 #else
164           const GLXFBConfig fbconfig =
165                 fgStructure.CurrentWindow->Window.pContext.FBConfig;
166
167           visualInfo =
168                 glXGetVisualFromFBConfig( fgDisplay.pDisplay.Display, fbconfig );
169 #endif
170           const int result = visualInfo->visual->map_entries;
171
172           XFree(visualInfo);
173
174           return result;
175         }
176
177     default:
178 #ifdef EGL_VERSION_1_0
179       return fghPlatformGlutGetEGL(eWhat);
180 #else
181       return fghPlatformGlutGetGLX(eWhat);
182 #endif
183     }
184 }