[Piglit] [PATCH 5/5] glut_waffle: Add input support for X11
Brian Paul
brianp at vmware.com
Thu Aug 30 06:57:11 PDT 2012
On 08/30/2012 12:16 AM, Chad Versace wrote:
> Add support for input when using glut_waffle's GLX and
> X11/EGL backends. Tested with fbo-clean-formats; I cycled through the
> tests with the keyboard and then quit with the escape key.
>
> Signed-off-by: Chad Versace<chad.versace at linux.intel.com>
> ---
> CMakeLists.txt | 1 +
> src/glut_waffle/CMakeLists.no_api.txt | 6 ++-
> src/glut_waffle/glut_waffle.c | 71 ++++++++++++++++++++++++----
> src/glut_waffle/priv/common.h | 11 +++++
> src/glut_waffle/priv/x11.c | 89 +++++++++++++++++++++++++++++++++++
> src/glut_waffle/priv/x11.h | 31 ++++++++++++
> 6 files changed, 200 insertions(+), 9 deletions(-)
> create mode 100644 src/glut_waffle/priv/x11.c
> create mode 100644 src/glut_waffle/priv/x11.h
>
> diff --git a/CMakeLists.txt b/CMakeLists.txt
> index a717b84..a1cb4fb 100644
> --- a/CMakeLists.txt
> +++ b/CMakeLists.txt
> @@ -37,6 +37,7 @@ if(BUILD_GLES2_TESTS AND NOT USE_WAFFLE)
> endif(BUILD_GLES2_TESTS AND NOT USE_WAFFLE)
>
> IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
> + add_definitions(-DPIGLIT_HAS_X11)
> option(BUILD_GLX_TESTS "Build tests that require GLX" ON)
> ELSE()
> option(BUILD_GLX_TESTS "Build tests that require GLX" OFF)
> diff --git a/src/glut_waffle/CMakeLists.no_api.txt b/src/glut_waffle/CMakeLists.no_api.txt
> index 63a2e19..780f01a 100644
> --- a/src/glut_waffle/CMakeLists.no_api.txt
> +++ b/src/glut_waffle/CMakeLists.no_api.txt
> @@ -1,7 +1,11 @@
> -link_libraries(${WAFFLE_LIBRARIES})
> +link_libraries(
> + ${WAFFLE_LIBRARIES}
> + X11
> + )
>
> add_library(glut_waffle SHARED
> glut_waffle.c
>
> priv/common.c
> + priv/x11.c
> )
> diff --git a/src/glut_waffle/glut_waffle.c b/src/glut_waffle/glut_waffle.c
> index 1c3b812..5837b49 100644
> --- a/src/glut_waffle/glut_waffle.c
> +++ b/src/glut_waffle/glut_waffle.c
> @@ -21,6 +21,7 @@
> * DEALINGS IN THE SOFTWARE.
> */
>
> +#include<assert.h>
> #include<stdarg.h>
> #include<stdbool.h>
> #include<stdio.h>
> @@ -28,8 +29,15 @@
> #include<string.h>
> #include<unistd.h>
>
> +#include<waffle_glx.h>
> +#include<waffle_x11_egl.h>
> +
> #include "priv/common.h"
>
> +#ifdef PIGLIT_HAS_X11
> +# include "priv/x11.h"
> +#endif
> +
> void
> glutInitAPIMask(int mask)
> {
> @@ -86,6 +94,12 @@ glutInit(int *argcp, char **argv)
> "value \"%s\"", piglit_platform);
> }
>
> +#ifndef PIGLIT_HAS_X11
> + if (_glut->waffle_platform == WAFFLE_PLATFORM_GLX ||
> + _glut->waffle_platform == WAFFLE_PLATFORM_X11_EGL)
> + glutFatal("piglit was built without x11 support");
> +#endif
> +
> waffle_init_attrib_list[1] = _glut->waffle_platform;
> ok = waffle_init(waffle_init_attrib_list);
> if (!ok)
> @@ -181,6 +195,7 @@ glutCreateWindow(const char *title)
> {
> bool ok = true;
> struct waffle_config *config = NULL;
> + union waffle_native_window *n_window = NULL;
>
> if (_glut->window)
> glutFatal("cannot create window; one already exists");
> @@ -201,6 +216,30 @@ glutCreateWindow(const char *title)
> if (!_glut->window->waffle)
> glutFatal("waffle_window_create() failed");
>
> + n_window = waffle_window_get_native(_glut->window->waffle);
> + if (!n_window)
> + glutFatal("waffle_window_get_window() failed");
> +
> + switch (_glut->waffle_platform) {
> +#ifdef PIGLIT_HAS_X11
> + case WAFFLE_PLATFORM_GLX:
> + _glut->window->x11.display = n_window->glx->xlib_display;
> + _glut->window->x11.window = n_window->glx->xlib_window;
> + break;
> + case WAFFLE_PLATFORM_X11_EGL:
> + _glut->window->x11.display = n_window->x11_egl->display.xlib_display;
> + _glut->window->x11.window = n_window->x11_egl->xlib_window;
> + break;
> +#endif
> + case WAFFLE_PLATFORM_WAYLAND:
> + printf("glut_waffle: warning: input is not yet "
> + "implemented for Wayland\n");
> + break;
> + default:
> + assert(0);
> + break;
> + }
> +
> ok = waffle_make_current(_glut->display, _glut->window->waffle,
> _glut->context);
> if (!ok)
> @@ -278,14 +317,30 @@ glutMainLoop(void)
> if (_glut->window->display_cb)
> _glut->window->display_cb();
>
> - // FIXME: Tests run without -auto require basic input.
> -
> - // Workaround for input:
> - // Since glut_waffle doesn't handle input yet, it sleeps in order to
> - // give the user a chance to see the test output. If the user wishes
> - // the test to sleep for a shorter or longer time, he can use Ctrl-C
> - // or Ctrl-Z.
> - sleep(20);
> + switch (_glut->waffle_platform) {
> +#ifdef PIGLIT_HAS_X11
> + case WAFFLE_PLATFORM_GLX:
> + case WAFFLE_PLATFORM_X11_EGL:
> + x11_event_loop();
> + break;
> +#endif
> + case WAFFLE_PLATFORM_WAYLAND:
> + /* The Wayland window fails to appear on the first call to
> + * swapBuffers (which occured in display_cb above). This is
> + * likely due to swapBuffers being called before receiving an
> + * expose event. Until piglit has proper Wayland support,
> + * call swapBuffers again as a workaround.
> + */
> + if (_glut->window->display_cb)
> + _glut->window->display_cb();
> +
> + /* FINISHME: Write event loop for Wayland. */
> + sleep(20);
> + break;
> + default:
> + assert(0);
> + break;
> + }
> }
>
> void
> diff --git a/src/glut_waffle/priv/common.h b/src/glut_waffle/priv/common.h
> index 2b3ebca..1ee28a4 100644
> --- a/src/glut_waffle/priv/common.h
> +++ b/src/glut_waffle/priv/common.h
> @@ -24,11 +24,22 @@
>
> #include<waffle.h>
>
> +#ifdef PIGLIT_HAS_X11
> +# include<X11/Xlib.h>
> +#endif
> +
> #include "glut_waffle.h"
>
> struct glut_window {
> struct waffle_window *waffle;
>
> +#ifdef PIGLIT_HAS_X11
> + struct {
> + Display *display;
> + Window window;
> + } x11;
> +#endif
> +
> int id;
>
> GLUT_EGLreshapeCB reshape_cb;
> diff --git a/src/glut_waffle/priv/x11.c b/src/glut_waffle/priv/x11.c
> new file mode 100644
> index 0000000..dc39b35
> --- /dev/null
> +++ b/src/glut_waffle/priv/x11.c
> @@ -0,0 +1,89 @@
> +/*
> + * Copyright 2012 Intel Corporation
> + *
> + * 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.
> + */
> +
> +#include<X11/Xlib.h>
> +#include<X11/Xutil.h>
> +#include<X11/keysym.h>
> +
> +#include "common.h"
> +
> +static void
> +x11_process_next_event(void)
> +{
> + struct glut_window *gwin = _glut->window;
> + Display *xdpy = gwin->x11.display;
> +
> + bool redraw = false;
> + XEvent event;
> +
> + if (!XPending(xdpy))
> + return;
> +
> + XNextEvent(xdpy,&event);
> +
> + switch (event.type) {
> + case Expose:
> + redraw = true;
> + break;
> + case ConfigureNotify:
> + if (gwin->reshape_cb)
> + gwin->reshape_cb(event.xconfigure.width,
> + event.xconfigure.height);
> + break;
> + case KeyPress: {
> + char buffer[1];
> + KeySym sym;
> + int n;
> +
> + redraw = true;
> + n = XLookupString(&event.xkey,
> + buffer,
> + sizeof(buffer),&sym, NULL);
> +
> + if (n> 0&& gwin->keyboard_cb)
> + gwin->keyboard_cb(buffer[0],
> + event.xkey.x, event.xkey.y);
> + break;
> + }
> + default:
> + break;
> + }
> +
> + _glut->redisplay = redraw;
> +}
> +
> +void
> +x11_event_loop(void)
> +{
> + while (true) {
> + x11_process_next_event();
> +
> + if (!_glut->redisplay)
> + continue;
> + _glut->redisplay = 0;
> +
> + if (_glut->window->display_cb)
> + _glut->window->display_cb();
> +
> + waffle_window_swap_buffers(_glut->window->waffle);
> + }
Just a nit, but I'd opt to implement that without the continue statement:
while (true) {
x11_process_next_event();
if (_glut->redisplay) {
_glut->redisplay = 0;
if (_glut->window->display_cb)
_glut->window->display_cb();
waffle_window_swap_buffers(_glut->window->waffle);
}
}
I find that a little quicker to follow.
And you've probably explained this before, but what exactly is
glut-waffle? I get the impression that it's a glut-like API over
waffle. Is that correct?
-Brina
More information about the Piglit
mailing list