[Piglit] [PATCH 2/5] Add utility for EGL, with a subset of glut implemented
Shuang He
shuang.he at intel.com
Wed Feb 23 18:59:43 PST 2011
---
tests/util/CMakeLists.txt | 4 +
tests/util/glut_egl/CMakeLists.txt | 16 ++
tests/util/glut_egl/glut_egl.c | 378 ++++++++++++++++++++++++++++++++++++
tests/util/glut_egl/glut_egl.h | 94 +++++++++
tests/util/glut_egl/glut_egl_x11.c | 245 +++++++++++++++++++++++
tests/util/glut_egl/glut_eglint.h | 103 ++++++++++
6 files changed, 840 insertions(+), 0 deletions(-)
create mode 100644 tests/util/glut_egl/CMakeLists.txt
create mode 100644 tests/util/glut_egl/glut_egl.c
create mode 100644 tests/util/glut_egl/glut_egl.h
create mode 100644 tests/util/glut_egl/glut_egl_x11.c
create mode 100644 tests/util/glut_egl/glut_eglint.h
diff --git a/tests/util/CMakeLists.txt b/tests/util/CMakeLists.txt
index df28ec7..486dbca 100644
--- a/tests/util/CMakeLists.txt
+++ b/tests/util/CMakeLists.txt
@@ -38,3 +38,7 @@ ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
add_library (piglitutil
${UTIL_SOURCES}
)
+
+IF(OPENGL_egl_LIBRARY)
+ add_subdirectory (glut_egl)
+ENDIF(OPENGL_egl_LIBRARY)
diff --git a/tests/util/glut_egl/CMakeLists.txt b/tests/util/glut_egl/CMakeLists.txt
new file mode 100644
index 0000000..72d9567
--- /dev/null
+++ b/tests/util/glut_egl/CMakeLists.txt
@@ -0,0 +1,16 @@
+add_definitions ( -DSOURCE_DIR="${piglit_SOURCE_DIR}/" )
+
+include_directories(
+ ${OPENGL_INCLUDE_PATH}
+)
+
+link_libraries (
+ ${OPENGL_egl_LIBRARY}
+)
+
+IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+ add_library (piglitglutegl_x11
+ glut_egl.c
+ glut_egl_x11.c
+ )
+ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
diff --git a/tests/util/glut_egl/glut_egl.c b/tests/util/glut_egl/glut_egl.c
new file mode 100644
index 0000000..0a2af5e
--- /dev/null
+++ b/tests/util/glut_egl/glut_egl.c
@@ -0,0 +1,378 @@
+/*
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Chia-I Wu <olv at lunarg.com>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <sys/time.h>
+
+#include "EGL/egl.h"
+#include "EGL/eglext.h"
+
+#include "glut_eglint.h"
+
+static struct glut_egl_state _glut_egl_state = {
+ .api_mask = GLUT_EGL_OPENGL_ES1_BIT,
+ .window_width = 300,
+ .window_height = 300,
+ .verbose = 0,
+ .num_windows = 0,
+};
+
+struct glut_egl_state *_glut_egl = &_glut_egl_state;
+
+void
+_glut_eglFatal(char *format, ...)
+{
+ va_list args;
+
+ va_start(args, format);
+
+ fprintf(stderr, "GLUT_EGL: ");
+ vfprintf(stderr, format, args);
+ va_end(args);
+ putc('\n', stderr);
+
+ exit(1);
+}
+
+/* return current time (in milliseconds) */
+int
+_glut_eglNow(void)
+{
+ struct timeval tv;
+#ifdef __VMS
+ (void) gettimeofday(&tv, NULL );
+#else
+ struct timezone tz;
+ (void) gettimeofday(&tv, &tz);
+#endif
+ return tv.tv_sec * 1000 + tv.tv_usec / 1000;
+}
+
+static void
+_glut_eglDestroyWindow(struct glut_egl_window *win)
+{
+ if (_glut_egl->surface_type != EGL_PBUFFER_BIT &&
+ _glut_egl->surface_type != EGL_SCREEN_BIT_MESA)
+ eglDestroySurface(_glut_egl->dpy, win->surface);
+
+ _glut_eglNativeFiniWindow(win);
+
+ eglDestroyContext(_glut_egl->dpy, win->context);
+}
+
+static EGLConfig
+_glut_eglChooseConfig(void)
+{
+ EGLConfig config;
+ EGLint config_attribs[32];
+ EGLint renderable_type, num_configs, i;
+
+ i = 0;
+ config_attribs[i++] = EGL_RED_SIZE;
+ config_attribs[i++] = 1;
+ config_attribs[i++] = EGL_GREEN_SIZE;
+ config_attribs[i++] = 1;
+ config_attribs[i++] = EGL_BLUE_SIZE;
+ config_attribs[i++] = 1;
+ config_attribs[i++] = EGL_DEPTH_SIZE;
+ config_attribs[i++] = 1;
+
+ config_attribs[i++] = EGL_SURFACE_TYPE;
+ config_attribs[i++] = _glut_egl->surface_type;
+
+ config_attribs[i++] = EGL_RENDERABLE_TYPE;
+ renderable_type = 0x0;
+ if (_glut_egl->api_mask & GLUT_EGL_OPENGL_BIT)
+ renderable_type |= EGL_OPENGL_BIT;
+ if (_glut_egl->api_mask & GLUT_EGL_OPENGL_ES1_BIT)
+ renderable_type |= EGL_OPENGL_ES_BIT;
+ if (_glut_egl->api_mask & GLUT_EGL_OPENGL_ES2_BIT)
+ renderable_type |= EGL_OPENGL_ES2_BIT;
+ if (_glut_egl->api_mask & GLUT_EGL_OPENVG_BIT)
+ renderable_type |= EGL_OPENVG_BIT;
+ config_attribs[i++] = renderable_type;
+
+ config_attribs[i] = EGL_NONE;
+
+ if (!eglChooseConfig(_glut_egl->dpy,
+ config_attribs, &config, 1, &num_configs) || !num_configs)
+ _glut_eglFatal("failed to choose a config");
+
+ return config;
+}
+
+static struct glut_egl_window *
+_glut_eglCreateWindow(const char *title, int x, int y, int w, int h)
+{
+ struct glut_egl_window *win;
+ EGLint context_attribs[4];
+ EGLint api, i;
+
+ win = calloc(1, sizeof(*win));
+ if (!win)
+ _glut_eglFatal("failed to allocate window");
+
+ win->config = _glut_eglChooseConfig();
+
+ i = 0;
+ context_attribs[i] = EGL_NONE;
+
+ /* multiple APIs? */
+
+ api = EGL_OPENGL_ES_API;
+ if (_glut_egl->api_mask & GLUT_EGL_OPENGL_BIT) {
+ api = EGL_OPENGL_API;
+ }
+ else if (_glut_egl->api_mask & GLUT_EGL_OPENVG_BIT) {
+ api = EGL_OPENVG_API;
+ }
+ else if (_glut_egl->api_mask & GLUT_EGL_OPENGL_ES2_BIT) {
+ context_attribs[i++] = EGL_CONTEXT_CLIENT_VERSION;
+ context_attribs[i++] = 2;
+ }
+
+ context_attribs[i] = EGL_NONE;
+
+ eglBindAPI(api);
+ win->context = eglCreateContext(_glut_egl->dpy,
+ win->config, EGL_NO_CONTEXT, context_attribs);
+ if (!win->context)
+ _glut_eglFatal("failed to create context");
+
+ _glut_eglNativeInitWindow(win, title, x, y, w, h);
+ switch (_glut_egl->surface_type) {
+ case EGL_WINDOW_BIT:
+ win->surface = eglCreateWindowSurface(_glut_egl->dpy,
+ win->config, win->native.u.window, NULL);
+ break;
+ case EGL_PIXMAP_BIT:
+ win->surface = eglCreatePixmapSurface(_glut_egl->dpy,
+ win->config, win->native.u.pixmap, NULL);
+ break;
+ case EGL_PBUFFER_BIT:
+ case EGL_SCREEN_BIT_MESA:
+ win->surface = win->native.u.surface;
+ break;
+ default:
+ break;
+ }
+ if (win->surface == EGL_NO_SURFACE)
+ _glut_eglFatal("failed to create surface");
+
+ return win;
+}
+
+void
+glut_eglInitAPIMask(int mask)
+{
+ _glut_egl->api_mask = mask;
+}
+
+void
+glutInitWindowSize(int width, int height)
+{
+ _glut_egl->window_width = width;
+ _glut_egl->window_height = height;
+}
+
+void
+glutInit(int argc, char **argv)
+{
+ int i;
+
+ for (i = 1; i < argc; i++) {
+ if (strcmp(argv[i], "-display") == 0)
+ _glut_egl->display_name = argv[++i];
+ else if (strcmp(argv[i], "-info") == 0) {
+ _glut_egl->verbose = 1;
+ }
+ }
+
+ _glut_eglNativeInitDisplay();
+ _glut_egl->dpy = eglGetDisplay(_glut_egl->native_dpy);
+
+ if (!eglInitialize(_glut_egl->dpy, &_glut_egl->major, &_glut_egl->minor))
+ _glut_eglFatal("failed to initialize EGL display");
+
+ _glut_egl->init_time = _glut_eglNow();
+
+ printf("EGL_VERSION = %s\n", eglQueryString(_glut_egl->dpy, EGL_VERSION));
+ if (_glut_egl->verbose) {
+ printf("EGL_VENDOR = %s\n", eglQueryString(_glut_egl->dpy, EGL_VENDOR));
+ printf("EGL_EXTENSIONS = %s\n",
+ eglQueryString(_glut_egl->dpy, EGL_EXTENSIONS));
+ printf("EGL_CLIENT_APIS = %s\n",
+ eglQueryString(_glut_egl->dpy, EGL_CLIENT_APIS));
+ }
+}
+
+int
+glutGet(int state)
+{
+ int val;
+
+ switch (state) {
+ case GLUT_EGL_ELAPSED_TIME:
+ val = _glut_eglNow() - _glut_egl->init_time;
+ break;
+ default:
+ val = -1;
+ break;
+ }
+
+ return val;
+}
+
+void
+glutIdleFunc(GLUT_EGLidleCB func)
+{
+ _glut_egl->idle_cb = func;
+}
+
+void
+glutPostRedisplay(void)
+{
+ _glut_egl->redisplay = 1;
+}
+
+void
+glutMainLoop(void)
+{
+ struct glut_egl_window *win = _glut_egl->current;
+
+ if (!win)
+ _glut_eglFatal("no window is created\n");
+
+ if (win->reshape_cb)
+ win->reshape_cb(win->native.width, win->native.height);
+
+ _glut_eglNativeEventLoop();
+}
+
+static void
+_glut_eglFini(void)
+{
+ eglTerminate(_glut_egl->dpy);
+ _glut_eglNativeFiniDisplay();
+}
+
+void
+glutDestroyWindow(int win)
+{
+ struct glut_egl_window *window = _glut_egl->current;
+
+ if (window->index != win)
+ return;
+
+ /* XXX it causes some bug in st/egl KMS backend */
+ if ( _glut_egl->surface_type != EGL_SCREEN_BIT_MESA)
+ eglMakeCurrent(_glut_egl->dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+
+ _glut_eglDestroyWindow(_glut_egl->current);
+}
+
+static void
+_glut_eglDefaultKeyboard(unsigned char key)
+{
+ if (key == 27) {
+ if (_glut_egl->current)
+ glutDestroyWindow(_glut_egl->current->index);
+ _glut_eglFini();
+
+ exit(0);
+ }
+}
+
+int
+glutCreateWindow(const char *title)
+{
+ struct glut_egl_window *win;
+
+ win = _glut_eglCreateWindow(title, 0, 0,
+ _glut_egl->window_width, _glut_egl->window_height);
+
+ win->index = _glut_egl->num_windows++;
+ win->reshape_cb = NULL;
+ win->display_cb = NULL;
+ win->keyboard_cb = _glut_eglDefaultKeyboard;
+ win->special_cb = NULL;
+
+ if (!eglMakeCurrent(_glut_egl->dpy, win->surface, win->surface, win->context))
+ _glut_eglFatal("failed to make window current");
+ _glut_egl->current = win;
+
+ return win->index;
+}
+
+int
+glut_eglGetWindowWidth(void)
+{
+ struct glut_egl_window *win = _glut_egl->current;
+ return win->native.width;
+}
+
+int
+glut_eglGetWindowHeight(void)
+{
+ struct glut_egl_window *win = _glut_egl->current;
+ return win->native.height;
+}
+
+void
+glutDisplayFunc(GLUT_EGLdisplayCB func)
+{
+ struct glut_egl_window *win = _glut_egl->current;
+ win->display_cb = func;
+
+}
+
+void
+glutReshapeFunc(GLUT_EGLreshapeCB func)
+{
+ struct glut_egl_window *win = _glut_egl->current;
+ win->reshape_cb = func;
+}
+
+void
+glutKeyboardFunc(GLUT_EGLkeyboardCB func)
+{
+ struct glut_egl_window *win = _glut_egl->current;
+ win->keyboard_cb = func;
+}
+
+void
+glutSpecialFunc(GLUT_EGLspecialCB func)
+{
+ struct glut_egl_window *win = _glut_egl->current;
+ win->special_cb = func;
+}
+
+void
+glutSwapBuffers(void)
+{
+}
diff --git a/tests/util/glut_egl/glut_egl.h b/tests/util/glut_egl/glut_egl.h
new file mode 100644
index 0000000..83f0bca
--- /dev/null
+++ b/tests/util/glut_egl/glut_egl.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Chia-I Wu <olv at lunarg.com>
+ */
+
+#ifndef GLUT_EGL_H
+#define GLUT_EGL_H
+
+/* used by glut_eglInitAPIMask */
+enum {
+ GLUT_EGL_OPENGL_BIT = 0x1,
+ GLUT_EGL_OPENGL_ES1_BIT = 0x2,
+ GLUT_EGL_OPENGL_ES2_BIT = 0x4,
+ GLUT_EGL_OPENVG_BIT = 0x8
+};
+
+/* used by GLUT_EGLspecialCB */
+enum {
+ /* function keys */
+ GLUT_EGL_KEY_F1,
+ GLUT_EGL_KEY_F2,
+ GLUT_EGL_KEY_F3,
+ GLUT_EGL_KEY_F4,
+ GLUT_EGL_KEY_F5,
+ GLUT_EGL_KEY_F6,
+ GLUT_EGL_KEY_F7,
+ GLUT_EGL_KEY_F8,
+ GLUT_EGL_KEY_F9,
+ GLUT_EGL_KEY_F10,
+ GLUT_EGL_KEY_F11,
+ GLUT_EGL_KEY_F12,
+
+ /* directional keys */
+ GLUT_EGL_KEY_LEFT,
+ GLUT_EGL_KEY_UP,
+ GLUT_EGL_KEY_RIGHT,
+ GLUT_EGL_KEY_DOWN,
+};
+
+/* used by glutGet */
+enum {
+ GLUT_EGL_ELAPSED_TIME
+};
+
+typedef void (*GLUT_EGLidleCB)(void);
+typedef void (*GLUT_EGLreshapeCB)(int, int);
+typedef void (*GLUT_EGLdisplayCB)(void);
+typedef void (*GLUT_EGLkeyboardCB)(unsigned char);
+typedef void (*GLUT_EGLspecialCB)(int);
+
+void glut_eglInitAPIMask(int mask);
+void glutInitWindowSize(int width, int height);
+void glutInit(int argc, char **argv);
+
+int glutGet(int state);
+
+void glutIdleFunc(GLUT_EGLidleCB func);
+void glutPostRedisplay(void);
+
+void glutMainLoop(void);
+
+int glutCreateWindow(const char *title);
+void glutDestroyWindow(int win);
+
+int glut_eglGetWindowWidth(void);
+int glut_eglGetWindowHeight(void);
+
+void glutDisplayFunc(GLUT_EGLdisplayCB func);
+void glutReshapeFunc(GLUT_EGLreshapeCB func);
+void glutKeyboardFunc(GLUT_EGLkeyboardCB func);
+void glutSpecialFunc(GLUT_EGLspecialCB func);
+void glutSwapBuffers(void);
+
+#endif /* GLUT_EGL_H */
diff --git a/tests/util/glut_egl/glut_egl_x11.c b/tests/util/glut_egl/glut_egl_x11.c
new file mode 100644
index 0000000..a751958
--- /dev/null
+++ b/tests/util/glut_egl/glut_egl_x11.c
@@ -0,0 +1,245 @@
+/*
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Chia-I Wu <olv at lunarg.com>
+ */
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/keysym.h>
+
+#include "glut_eglint.h"
+
+void
+_glut_eglNativeInitDisplay(void)
+{
+ _glut_egl->native_dpy = XOpenDisplay(_glut_egl->display_name);
+ if (!_glut_egl->native_dpy)
+ _glut_eglFatal("failed to initialize native display");
+
+ _glut_egl->surface_type = EGL_WINDOW_BIT;
+}
+
+void
+_glut_eglNativeFiniDisplay(void)
+{
+ XCloseDisplay(_glut_egl->native_dpy);
+}
+
+void
+_glut_eglNativeInitWindow(struct glut_egl_window *win, const char *title,
+ int x, int y, int w, int h)
+{
+ XVisualInfo *visInfo, visTemplate;
+ int num_visuals;
+ Window root, xwin;
+ XSetWindowAttributes attr;
+ unsigned long mask;
+ EGLint vid;
+
+ if (!eglGetConfigAttrib(_glut_egl->dpy,
+ win->config, EGL_NATIVE_VISUAL_ID, &vid))
+ _glut_eglFatal("failed to get visual id");
+
+ /* The X window visual must match the EGL config */
+ visTemplate.visualid = vid;
+ visInfo = XGetVisualInfo(_glut_egl->native_dpy,
+ VisualIDMask, &visTemplate, &num_visuals);
+ if (!visInfo)
+ _glut_eglFatal("failed to get an visual of id 0x%x", vid);
+
+ root = RootWindow(_glut_egl->native_dpy, DefaultScreen(_glut_egl->native_dpy));
+
+ /* window attributes */
+ attr.background_pixel = 0;
+ attr.border_pixel = 0;
+ attr.colormap = XCreateColormap(_glut_egl->native_dpy,
+ root, visInfo->visual, AllocNone);
+ attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
+ mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
+
+ xwin = XCreateWindow(_glut_egl->native_dpy, root, x, y, w, h,
+ 0, visInfo->depth, InputOutput, visInfo->visual, mask, &attr);
+ if (!xwin)
+ _glut_eglFatal("failed to create a window");
+
+ XFree(visInfo);
+
+ /* set hints and properties */
+ {
+ XSizeHints sizehints;
+ sizehints.x = x;
+ sizehints.y = y;
+ sizehints.width = w;
+ sizehints.height = h;
+ sizehints.flags = USSize | USPosition;
+ XSetNormalHints(_glut_egl->native_dpy, xwin, &sizehints);
+ XSetStandardProperties(_glut_egl->native_dpy, xwin,
+ title, title, None, (char **) NULL, 0, &sizehints);
+ }
+
+ XMapWindow(_glut_egl->native_dpy, xwin);
+
+ win->native.u.window = xwin;
+ win->native.width = w;
+ win->native.height = h;
+}
+
+void
+_glut_eglNativeFiniWindow(struct glut_egl_window *win)
+{
+ XDestroyWindow(_glut_egl->native_dpy, win->native.u.window);
+}
+
+static int
+lookup_keysym(KeySym sym)
+{
+ int special;
+
+ switch (sym) {
+ case XK_F1:
+ special = GLUT_EGL_KEY_F1;
+ break;
+ case XK_F2:
+ special = GLUT_EGL_KEY_F2;
+ break;
+ case XK_F3:
+ special = GLUT_EGL_KEY_F3;
+ break;
+ case XK_F4:
+ special = GLUT_EGL_KEY_F4;
+ break;
+ case XK_F5:
+ special = GLUT_EGL_KEY_F5;
+ break;
+ case XK_F6:
+ special = GLUT_EGL_KEY_F6;
+ break;
+ case XK_F7:
+ special = GLUT_EGL_KEY_F7;
+ break;
+ case XK_F8:
+ special = GLUT_EGL_KEY_F8;
+ break;
+ case XK_F9:
+ special = GLUT_EGL_KEY_F9;
+ break;
+ case XK_F10:
+ special = GLUT_EGL_KEY_F10;
+ break;
+ case XK_F11:
+ special = GLUT_EGL_KEY_F11;
+ break;
+ case XK_F12:
+ special = GLUT_EGL_KEY_F12;
+ break;
+ case XK_KP_Left:
+ case XK_Left:
+ special = GLUT_EGL_KEY_LEFT;
+ break;
+ case XK_KP_Up:
+ case XK_Up:
+ special = GLUT_EGL_KEY_UP;
+ break;
+ case XK_KP_Right:
+ case XK_Right:
+ special = GLUT_EGL_KEY_RIGHT;
+ break;
+ case XK_KP_Down:
+ case XK_Down:
+ special = GLUT_EGL_KEY_DOWN;
+ break;
+ default:
+ special = -1;
+ break;
+ }
+
+ return special;
+}
+
+static void
+next_event(struct glut_egl_window *win)
+{
+ int redraw = 0;
+ XEvent event;
+
+ if (!XPending(_glut_egl->native_dpy)) {
+ if (_glut_egl->idle_cb)
+ _glut_egl->idle_cb();
+ return;
+ }
+
+ XNextEvent(_glut_egl->native_dpy, &event);
+
+ switch (event.type) {
+ case Expose:
+ redraw = 1;
+ break;
+ case ConfigureNotify:
+ win->native.width = event.xconfigure.width;
+ win->native.height = event.xconfigure.height;
+ if (win->reshape_cb)
+ win->reshape_cb(win->native.width, win->native.height);
+ break;
+ case KeyPress:
+ {
+ char buffer[1];
+ KeySym sym;
+ int r;
+
+ r = XLookupString(&event.xkey,
+ buffer, sizeof(buffer), &sym, NULL);
+ if (r && win->keyboard_cb) {
+ win->keyboard_cb(buffer[0]);
+ }
+ else if (!r && win->special_cb) {
+ r = lookup_keysym(sym);
+ if (r >= 0)
+ win->special_cb(r);
+ }
+ }
+ redraw = 1;
+ break;
+ default:
+ ; /*no-op*/
+ }
+
+ _glut_egl->redisplay = redraw;
+}
+
+void
+_glut_eglNativeEventLoop(void)
+{
+ while (1) {
+ struct glut_egl_window *win = _glut_egl->current;
+
+ next_event(win);
+
+ if (_glut_egl->redisplay) {
+ _glut_egl->redisplay = 0;
+
+ if (win->display_cb)
+ win->display_cb();
+ eglSwapBuffers(_glut_egl->dpy, win->surface);
+ }
+ }
+}
diff --git a/tests/util/glut_egl/glut_eglint.h b/tests/util/glut_egl/glut_eglint.h
new file mode 100644
index 0000000..6b5ae29
--- /dev/null
+++ b/tests/util/glut_egl/glut_eglint.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Chia-I Wu <olv at lunarg.com>
+ */
+
+#ifndef _GLUT_EGLINT_H_
+#define _GLUT_EGLINT_H_
+
+#include "EGL/egl.h"
+#include "glut_egl.h"
+
+struct glut_egl_window {
+ EGLConfig config;
+ EGLContext context;
+
+ /* initialized by native display */
+ struct {
+ union {
+ EGLNativeWindowType window;
+ EGLNativePixmapType pixmap;
+ EGLSurface surface; /* pbuffer or screen surface */
+ } u;
+ int width, height;
+ } native;
+
+ EGLSurface surface;
+
+ int index;
+
+ GLUT_EGLreshapeCB reshape_cb;
+ GLUT_EGLdisplayCB display_cb;
+ GLUT_EGLkeyboardCB keyboard_cb;
+ GLUT_EGLspecialCB special_cb;
+};
+
+struct glut_egl_state {
+ int api_mask;
+ int window_width, window_height;
+ const char *display_name;
+ int verbose;
+ int init_time;
+
+ GLUT_EGLidleCB idle_cb;
+
+ int num_windows;
+
+ /* initialized by native display */
+ EGLNativeDisplayType native_dpy;
+ EGLint surface_type;
+
+ EGLDisplay dpy;
+ EGLint major, minor;
+
+ struct glut_egl_window *current;
+
+ int redisplay;
+};
+
+extern struct glut_egl_state *_glut_egl;
+
+void
+_glut_eglFatal(char *format, ...);
+
+int
+_glut_eglNow(void);
+
+void
+_glut_eglNativeInitDisplay(void);
+
+void
+_glut_eglNativeFiniDisplay(void);
+
+void
+_glut_eglNativeInitWindow(struct glut_egl_window *win, const char *title,
+ int x, int y, int w, int h);
+
+void
+_glut_eglNativeFiniWindow(struct glut_egl_window *win);
+
+void
+_glut_eglNativeEventLoop(void);
+
+#endif /* _GLUT_EGLINT_H_ */
--
1.7.4.rc2.21.g8671.dirty
More information about the Piglit
mailing list