summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChad Versace <chad.versace@linux.intel.com>2012-04-09 15:53:04 -0700
committerChad Versace <chad.versace@linux.intel.com>2012-04-11 16:46:27 -0700
commit818624ab661d2467a82db87122be0f0d27acc4b0 (patch)
treeba9b238b379abd7c7e99670d2492621532bf0639
parent9a49354781170aa7d33f4741c24699b40ec10a49 (diff)
glx: Add glx module
Implement functions for glx_platform: glx_platform_create glx_platform_destroy Implement all functions in native dispatch table: glx_display_connect glx_display_disconnect glx_config_choose glx_config_destroy glx_context_create glx_context_destroy glx_window_create glx_window_destroy glx_make_current glx_get_proc_address glx_dlsym_gl Signed-off-by: Chad Versace <chad.versace@linux.intel.com>
-rw-r--r--src/waffle/CMakeLists.txt11
-rw-r--r--src/waffle/glx/glx_config.c127
-rw-r--r--src/waffle/glx/glx_config.h30
-rw-r--r--src/waffle/glx/glx_context.c70
-rw-r--r--src/waffle/glx/glx_context.h28
-rw-r--r--src/waffle/glx/glx_display.c69
-rw-r--r--src/waffle/glx/glx_display.h28
-rw-r--r--src/waffle/glx/glx_gl_misc.c48
-rw-r--r--src/waffle/glx/glx_gl_misc.h38
-rw-r--r--src/waffle/glx/glx_platform.c110
-rw-r--r--src/waffle/glx/glx_platform.h28
-rw-r--r--src/waffle/glx/glx_priv_types.h58
-rw-r--r--src/waffle/glx/glx_window.c99
-rw-r--r--src/waffle/glx/glx_window.h33
14 files changed, 777 insertions, 0 deletions
diff --git a/src/waffle/CMakeLists.txt b/src/waffle/CMakeLists.txt
index e162398..bbf899b 100644
--- a/src/waffle/CMakeLists.txt
+++ b/src/waffle/CMakeLists.txt
@@ -24,6 +24,17 @@ if(waffle_has_egl)
)
endif(waffle_has_egl)
+if(waffle_has_glx)
+ list(APPEND waffle_sources
+ glx/glx_config.c
+ glx/glx_context.c
+ glx/glx_display.c
+ glx/glx_gl_misc.c
+ glx/glx_platform.c
+ glx/glx_window.c
+ )
+endif(waffle_has_glx)
+
if(waffle_has_x11)
list(APPEND waffle_sources
x11/x11.c
diff --git a/src/waffle/glx/glx_config.c b/src/waffle/glx/glx_config.c
new file mode 100644
index 0000000..6e1c832
--- /dev/null
+++ b/src/waffle/glx/glx_config.c
@@ -0,0 +1,127 @@
+// Copyright 2012 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "glx_config.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <waffle/native.h>
+#include <waffle/waffle_enum.h>
+#include <waffle/core/wcore_config_attrs.h>
+#include <waffle/core/wcore_error.h>
+
+#include "glx_priv_types.h"
+
+union native_config*
+glx_config_choose(
+ union native_display *dpy,
+ const struct wcore_config_attrs *attrs)
+{
+ bool ok = true;
+
+ GLXFBConfig *configs = NULL;
+ int num_configs;
+ XVisualInfo *vi = NULL;
+
+ int attrib_list[] = {
+ GLX_BUFFER_SIZE, attrs->color_buffer_size,
+ GLX_RED_SIZE, attrs->red_size,
+ GLX_GREEN_SIZE, attrs->green_size,
+ GLX_BLUE_SIZE, attrs->blue_size,
+ GLX_ALPHA_SIZE, attrs->alpha_size,
+
+ GLX_DEPTH_SIZE, attrs->depth_size,
+ GLX_STENCIL_SIZE, attrs->stencil_size,
+
+ GLX_SAMPLE_BUFFERS, attrs->sample_buffers,
+ GLX_SAMPLES, attrs->samples,
+
+ GLX_DOUBLEBUFFER, attrs->double_buffered,
+
+ // According to the GLX 1.4 spec Table 3.4, the default value of
+ // GLX_DRAWABLE_TYPE is GLX_WINDOW_BIT. Explicitly set the default
+ // here for the sake of self-documentation.
+ GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
+
+ 0,
+ };
+
+ union native_config *self;
+ NATIVE_ALLOC(self, glx);
+ if (!self) {
+ wcore_error(WAFFLE_OUT_OF_MEMORY);
+ return NULL;
+ }
+
+ self->glx->display = dpy;
+
+ // Set glx_fbconfig.
+ configs = glXChooseFBConfig(dpy->glx->xlib_display,
+ DefaultScreen(dpy->glx->xlib_display),
+ attrib_list,
+ &num_configs);
+ if (!configs || num_configs == 0) {
+ wcore_errorf(WAFFLE_UNKNOWN_ERROR,
+ "glXChooseFBConfig returned no matching configs");
+ goto error;
+ }
+ // Simply take the first.
+ self->glx->glx_fbconfig = configs[0];
+
+ // Set glx_fbconfig_id.
+ ok = !glXGetFBConfigAttrib(dpy->glx->xlib_display,
+ self->glx->glx_fbconfig,
+ GLX_FBCONFIG_ID,
+ &self->glx->glx_fbconfig_id);
+ if (!ok) {
+ wcore_errorf(WAFFLE_UNKNOWN_ERROR, "glxGetFBConfigAttrib failed");
+ goto error;
+ }
+
+ // Set xcb_visual_id.
+ vi = glXGetVisualFromFBConfig(dpy->glx->xlib_display,
+ self->glx->glx_fbconfig);
+ if (!vi) {
+ wcore_errorf(WAFFLE_UNKNOWN_ERROR,
+ "glXGetVisualInfoFromFBConfig failed with "
+ "GLXFBConfigID=0x%x\n", self->glx->glx_fbconfig_id);
+ goto error;
+ }
+ self->glx->xcb_visual_id = vi->visualid;
+
+ goto end;
+
+error:
+ WCORE_ERROR_DISABLED({
+ glx_config_destroy(self);
+ self = NULL;
+ });
+
+end:
+ if (configs)
+ XFree(configs);
+ if (vi)
+ XFree(vi);
+
+ return self;
+
+}
+
+bool
+glx_config_destroy(union native_config *self)
+{
+ free(self);
+ return true;
+}
diff --git a/src/waffle/glx/glx_config.h b/src/waffle/glx/glx_config.h
new file mode 100644
index 0000000..9269274
--- /dev/null
+++ b/src/waffle/glx/glx_config.h
@@ -0,0 +1,30 @@
+// Copyright 2012 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#pragma once
+
+#include <stdbool.h>
+#include <stdint.h>
+
+struct wcore_config_attrs;
+union native_config;
+union native_display;
+
+union native_config*
+glx_config_choose(
+ union native_display *dpy,
+ const struct wcore_config_attrs *attrs);
+
+bool
+glx_config_destroy(union native_config *self);
diff --git a/src/waffle/glx/glx_context.c b/src/waffle/glx/glx_context.c
new file mode 100644
index 0000000..14a682c
--- /dev/null
+++ b/src/waffle/glx/glx_context.c
@@ -0,0 +1,70 @@
+// Copyright 2012 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "glx_context.h"
+
+#include <stdlib.h>
+
+#include <waffle/native.h>
+#include <waffle/core/wcore_error.h>
+
+#include "glx_priv_types.h"
+
+union native_context*
+glx_context_create(
+ union native_config *config,
+ union native_context *share_ctx)
+{
+ union native_display *dpy = config->glx->display;
+
+ union native_context *self;
+ NATIVE_ALLOC(self, glx);
+ if (!self) {
+ wcore_error(WAFFLE_OUT_OF_MEMORY);
+ return NULL;
+ }
+
+ self->glx->display = config->glx->display;
+ self->glx->glx_context = glXCreateNewContext(dpy->glx->xlib_display,
+ config->glx->glx_fbconfig,
+ GLX_RGBA_TYPE,
+ share_ctx
+ ? share_ctx->glx->glx_context
+ : NULL,
+ true /*direct?*/);
+
+ if (!self->glx->glx_context) {
+ wcore_errorf(WAFFLE_UNKNOWN_ERROR, "glXCreateContext failed");
+ free(self);
+ return NULL;
+ }
+
+ return self;
+}
+
+bool
+glx_context_destroy(union native_context *self)
+{
+ if (!self)
+ return true;
+
+ union native_display *dpy = self->glx->display;
+
+ if (self->glx->glx_context)
+ glXDestroyContext(dpy->glx->xlib_display,
+ self->glx->glx_context);
+
+ free(self);
+ return true;
+}
diff --git a/src/waffle/glx/glx_context.h b/src/waffle/glx/glx_context.h
new file mode 100644
index 0000000..c75d693
--- /dev/null
+++ b/src/waffle/glx/glx_context.h
@@ -0,0 +1,28 @@
+// Copyright 2012 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#pragma once
+
+#include <stdbool.h>
+
+union native_context;
+union native_config;
+
+union native_context*
+glx_context_create(
+ union native_config *config,
+ union native_context *share_ctx);
+
+bool
+glx_context_destroy(union native_context *self); \ No newline at end of file
diff --git a/src/waffle/glx/glx_display.c b/src/waffle/glx/glx_display.c
new file mode 100644
index 0000000..38634d2
--- /dev/null
+++ b/src/waffle/glx/glx_display.c
@@ -0,0 +1,69 @@
+// Copyright 2012 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "glx_display.h"
+
+#include <stdlib.h>
+
+#include <waffle/native.h>
+#include <waffle/core/wcore_error.h>
+#include <waffle/x11/x11.h>
+
+#include "glx_priv_types.h"
+
+union native_display*
+glx_display_connect(
+ union native_platform *platform,
+ const char *name)
+{
+ bool ok = true;
+
+ union native_display *self;
+ NATIVE_ALLOC(self, glx);
+ if (!self) {
+ wcore_error(WAFFLE_OUT_OF_MEMORY);
+ return NULL;
+ }
+
+ self->glx->platform = platform;
+
+ ok &= x11_display_connect(name,
+ &self->glx->xlib_display,
+ &self->glx->xcb_connection);
+ if (!ok)
+ goto error;
+
+ return self;
+
+error:
+ WCORE_ERROR_DISABLED({
+ glx_display_disconnect(self);
+ });
+ return NULL;
+}
+
+bool
+glx_display_disconnect(union native_display *self)
+{
+ bool ok = true;
+
+ if (!self)
+ return true;
+
+ if (self->glx->xlib_display)
+ ok &= x11_display_disconnect(self->glx->xlib_display);
+
+ free(self);
+ return ok;
+}
diff --git a/src/waffle/glx/glx_display.h b/src/waffle/glx/glx_display.h
new file mode 100644
index 0000000..803ae4a
--- /dev/null
+++ b/src/waffle/glx/glx_display.h
@@ -0,0 +1,28 @@
+// Copyright 2012 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#pragma once
+
+#include <stdbool.h>
+
+union native_display;
+union native_platform;
+
+union native_display*
+glx_display_connect(
+ union native_platform *platform,
+ const char *name);
+
+bool
+glx_display_disconnect(union native_display *self);
diff --git a/src/waffle/glx/glx_gl_misc.c b/src/waffle/glx/glx_gl_misc.c
new file mode 100644
index 0000000..f4b3dd3
--- /dev/null
+++ b/src/waffle/glx/glx_gl_misc.c
@@ -0,0 +1,48 @@
+// Copyright 2012 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "glx_gl_misc.h"
+
+#include <dlfcn.h>
+
+#include <waffle/native.h>
+
+#include "glx_priv_types.h"
+
+bool
+glx_make_current(
+ union native_display *dpy,
+ union native_window *window,
+ union native_context *ctx)
+{
+ return glXMakeCurrent(dpy->glx->xlib_display,
+ window ? window->glx->glx_window : 0,
+ ctx ? ctx->glx->glx_context : 0);
+}
+
+void*
+glx_get_proc_address(
+ union native_platform *native,
+ const char *name)
+{
+ return glXGetProcAddress((const uint8_t*) name);
+}
+
+void*
+glx_dlsym_gl(
+ union native_platform *native,
+ const char *name)
+{
+ return dlsym(native->glx->libgl, name);
+}
diff --git a/src/waffle/glx/glx_gl_misc.h b/src/waffle/glx/glx_gl_misc.h
new file mode 100644
index 0000000..2e502a5
--- /dev/null
+++ b/src/waffle/glx/glx_gl_misc.h
@@ -0,0 +1,38 @@
+// Copyright 2012 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#pragma once
+
+#include <stdbool.h>
+
+union native_platform;
+union native_display;
+union native_window;
+union native_context;
+
+bool
+glx_make_current(
+ union native_display *dpy,
+ union native_window *window,
+ union native_context *ctx);
+
+void*
+glx_get_proc_address(
+ union native_platform *native,
+ const char *name);
+
+void*
+glx_dlsym_gl(
+ union native_platform *native,
+ const char *name);
diff --git a/src/waffle/glx/glx_platform.c b/src/waffle/glx/glx_platform.c
new file mode 100644
index 0000000..d508886
--- /dev/null
+++ b/src/waffle/glx/glx_platform.c
@@ -0,0 +1,110 @@
+// Copyright 2012 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "glx_platform.h"
+
+#include <dlfcn.h>
+#include <stdlib.h>
+
+#include <waffle/native.h>
+#include <waffle/waffle_enum.h>
+#include <waffle/core/wcore_error.h>
+
+#include "glx_config.h"
+#include "glx_context.h"
+#include "glx_display.h"
+#include "glx_gl_misc.h"
+#include "glx_priv_types.h"
+#include "glx_window.h"
+
+static const struct native_dispatch glx_dispatch = {
+ .display_connect = glx_display_connect,
+ .display_disconnect = glx_display_disconnect,
+ .config_choose = glx_config_choose,
+ .config_destroy = glx_config_destroy,
+ .context_create = glx_context_create,
+ .context_destroy = glx_context_destroy,
+ .window_create = glx_window_create,
+ .window_destroy = glx_window_destroy,
+ .window_swap_buffers = glx_window_swap_buffers,
+ .make_current = glx_make_current,
+ .get_proc_address = glx_get_proc_address,
+ .dlsym_gl = glx_dlsym_gl,
+};
+
+union native_platform*
+glx_platform_create(
+ int gl_api,
+ const struct native_dispatch **dispatch)
+{
+ union native_platform *self;
+ NATIVE_ALLOC(self, glx);
+ if (!self) {
+ wcore_error(WAFFLE_OUT_OF_MEMORY);
+ return NULL;
+ }
+
+ self->glx->gl_api = gl_api;
+
+ switch (gl_api) {
+ case WAFFLE_OPENGL:
+ self->glx->libgl_name = "libGL.so";
+ break;
+ case WAFFLE_OPENGL_ES1:
+ case WAFFLE_OPENGL_ES2:
+ wcore_errorf(WAFFLE_BAD_ATTRIBUTE,
+ "GLX does not yet support %s",
+ waffle_enum_to_string(gl_api));
+ goto error;
+ default:
+ wcore_error_internal("gl_api has bad value 0x%x", gl_api);
+ goto error;
+ }
+
+ self->glx->libgl = dlopen(self->glx->libgl_name, RTLD_LAZY);
+ if (!self->glx->libgl) {
+ wcore_errorf(WAFFLE_UNKNOWN_ERROR,
+ "dlopen(\"%s\") failed", self->glx->libgl_name);
+ goto error;
+ }
+
+ *dispatch = &glx_dispatch;
+ return self;
+
+error:
+ WCORE_ERROR_DISABLED({
+ glx_platform_destroy(self);
+ });
+ return NULL;
+}
+
+bool
+glx_platform_destroy(union native_platform *self)
+{
+ int error = 0;
+
+ if (!self)
+ return true;
+
+ if (self->glx->libgl) {
+ error |= dlclose(self->glx->libgl);
+ if (error) {
+ wcore_errorf(WAFFLE_UNKNOWN_ERROR, "dlclose() failed on \"%s\"",
+ self->glx->libgl_name);
+ }
+ }
+
+ free(self);
+ return !error;
+}
diff --git a/src/waffle/glx/glx_platform.h b/src/waffle/glx/glx_platform.h
new file mode 100644
index 0000000..4c381a6
--- /dev/null
+++ b/src/waffle/glx/glx_platform.h
@@ -0,0 +1,28 @@
+// Copyright 2012 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#pragma once
+
+#include <stdbool.h>
+
+struct native_dispatch;
+union native_platform;
+
+union native_platform*
+glx_platform_create(
+ int gl_api,
+ const struct native_dispatch **dispatch);
+
+bool
+glx_platform_destroy(union native_platform *self);
diff --git a/src/waffle/glx/glx_priv_types.h b/src/waffle/glx/glx_priv_types.h
new file mode 100644
index 0000000..6c5d828
--- /dev/null
+++ b/src/waffle/glx/glx_priv_types.h
@@ -0,0 +1,58 @@
+// Copyright 2012 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#pragma once
+
+#include <GL/glx.h>
+#include <X11/Xlib.h>
+#include <xcb/xcb.h>
+
+union native_display;
+union native_platform;
+
+struct glx_platform {
+ /// @brief One of WAFFLE_{GL,GLES1,GLES2}.
+ int gl_api;
+
+ /// @brief The GL library obtained with dlopen().
+ void *libgl;
+
+ /// @brief For example, "libGLESv2.so".
+ const char *libgl_name;
+};
+
+struct glx_display {
+ union native_platform *platform;
+ Display *xlib_display;
+ xcb_connection_t *xcb_connection;
+ int screen;
+};
+
+struct glx_config {
+ union native_display *display;
+ GLXFBConfig glx_fbconfig;
+ int32_t glx_fbconfig_id;
+ xcb_visualid_t xcb_visual_id;
+};
+
+struct glx_context {
+ union native_display *display;
+ GLXContext glx_context;
+};
+
+struct glx_window {
+ union native_display *display;
+ xcb_window_t xcb_window;
+ GLXWindow glx_window;
+};
diff --git a/src/waffle/glx/glx_window.c b/src/waffle/glx/glx_window.c
new file mode 100644
index 0000000..cf069ad
--- /dev/null
+++ b/src/waffle/glx/glx_window.c
@@ -0,0 +1,99 @@
+// Copyright 2012 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "glx_window.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <waffle/native.h>
+#include <waffle/core/wcore_error.h>
+#include <waffle/x11/x11.h>
+
+#include "glx_priv_types.h"
+
+union native_window*
+glx_window_create(
+ union native_config *config,
+ int width,
+ int height)
+{
+ union native_display *display = config->glx->display;
+
+ union native_window *self;
+ NATIVE_ALLOC(self, glx);
+ if (!self) {
+ wcore_error(WAFFLE_OUT_OF_MEMORY);
+ return NULL;
+ }
+
+ self->glx->display = display;
+ self->glx->xcb_window = x11_window_create(
+ display->glx->xcb_connection,
+ config->glx->xcb_visual_id,
+ width,
+ height);
+ if (!self->glx->xcb_window)
+ goto error;
+
+ // From the GLX 1.4 spec:
+ // Currently no attributes are recognized, so attrib list must be
+ // NULL or empty (first attribute of None).
+ self->glx->glx_window = glXCreateWindow(display->glx->xlib_display,
+ config->glx->glx_fbconfig,
+ self->glx->xcb_window,
+ NULL /*attrib_list*/);
+ if (!self->glx->glx_window) {
+ wcore_errorf(WAFFLE_UNKNOWN_ERROR, "glXCreateWindow failed");
+ goto error;
+ }
+
+ return self;
+
+error:
+ WCORE_ERROR_DISABLED({
+ glx_window_destroy(self);
+ });
+ return NULL;
+}
+
+bool
+glx_window_destroy(union native_window *self)
+{
+ if (!self)
+ return true;
+
+ bool ok = true;
+ union native_display *dpy = self->glx->display;
+
+ if (self->glx->glx_window)
+ glXDestroyWindow(dpy->glx->xlib_display,
+ self->glx->glx_window);
+
+ if (self->glx->xcb_window)
+ ok &= x11_window_destroy(dpy->glx->xcb_connection,
+ self->glx->xcb_window);
+
+ free(self);
+ return ok;
+}
+
+
+bool
+glx_window_swap_buffers(union native_window *self)
+{
+ union native_display *dpy = self->glx->display;
+ glXSwapBuffers(dpy->glx->xlib_display, self->glx->glx_window);
+ return true;
+}
diff --git a/src/waffle/glx/glx_window.h b/src/waffle/glx/glx_window.h
new file mode 100644
index 0000000..36c2c5b
--- /dev/null
+++ b/src/waffle/glx/glx_window.h
@@ -0,0 +1,33 @@
+// Copyright 2012 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#pragma once
+
+#include <stdbool.h>
+
+union native_config;
+union native_display;
+union native_window;
+
+union native_window*
+glx_window_create(
+ union native_config *config,
+ int width,
+ int height);
+
+bool
+glx_window_destroy(union native_window *self);
+
+bool
+glx_window_swap_buffers(union native_window *self);