aboutsummaryrefslogtreecommitdiff
path: root/src/waffle/core
diff options
context:
space:
mode:
authorChad Versace <chad.versace@linux.intel.com>2012-05-31 21:57:40 -0700
committerChad Versace <chad.versace@linux.intel.com>2012-06-03 16:29:43 -0700
commit602fc904b0b15d4841c7a40a27d50351e9147296 (patch)
tree1a6379a2302dc156462b2d4ffb778dee1c350b9b /src/waffle/core
parent50b0bca22427bf2890ac07cee2b61cfa4fcd8240 (diff)
downloadwaffle-602fc904b0b15d4841c7a40a27d50351e9147296.tar.gz
all: Replace tagged unions with a more traditional object model
This rewrites the bulk of Waffle's code. When I first began writing Waffle, I wanted to experiment with a non-traditional object model that used tagged unions. Very soon I began to abhor the "innovative" decision. This patch replaces the tagged-union model with a more traditional object model (as found in the Linux kernel [1], Google's NaCl, libdrm, and many other places) that uses vtables and embedded structures. [1] Neil Brown. LWN, 2011 June 1. Object-oriented design patterns in the kernel. (Part 1: http://lwn.net/Articles/444910/). (Part 2: http://lwn.net/Articles/446317/). As an example of the new object model, below is an outline of how waffle_window_swap_buffers() is now implemeneted. // file: waffle_window.c bool waffle_window_swap_buffers(struct waffle_window *self) { struct wcore_window *wc_self = wcore_window(self); // safe cast // Check preconditions ... return wc_self->vtbl->swap_buffers(wc_self); } // file: wcore_window.h struct wcore_window_vtbl { bool (*swap_buffers)(struct wcore_window *self); // More member functions ... }; struct wcore_window { const struct wcore_window_vtbl *vtbl; struct waffle_window {} wfl; // More members ... }; // file: glx_window.h struct glx_window { struct wcore_window wcore; // More members ... }; // file: glx_window.c static bool glx_window_swap_buffers(struct wcore_window *wc_self) { struct glx_window *self = glx_window(wc_self); // safe cast // Call glXSwapBuffers ... return true; } static const struct wcore_window_vtbl glx_window_wcore_vtbl = { .swap_buffers = glx_window_swap_buffers, // More members ... }; Signed-off-by: Chad Versace <chad.versace@linux.intel.com>
Diffstat (limited to 'src/waffle/core')
-rw-r--r--src/waffle/core/wcore_config.h76
-rw-r--r--src/waffle/core/wcore_context.h77
-rw-r--r--src/waffle/core/wcore_display.c57
-rw-r--r--src/waffle/core/wcore_display.h69
-rw-r--r--src/waffle/core/wcore_platform.c147
-rw-r--r--src/waffle/core/wcore_platform.h92
-rw-r--r--src/waffle/core/wcore_util.h50
-rw-r--r--src/waffle/core/wcore_window.h80
8 files changed, 479 insertions, 169 deletions
diff --git a/src/waffle/core/wcore_config.h b/src/waffle/core/wcore_config.h
new file mode 100644
index 0000000..abccdf8
--- /dev/null
+++ b/src/waffle/core/wcore_config.h
@@ -0,0 +1,76 @@
+// Copyright 2012 Intel Corporation
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// - Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// - Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#pragma once
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdlib.h>
+
+#include <waffle/api/api_object.h>
+
+#include "wcore_display.h"
+#include "wcore_util.h"
+
+struct wcore_config;
+
+struct wcore_config_vtbl {
+ bool
+ (*destroy)(struct wcore_config *self);
+};
+
+struct wcore_config {
+ const struct wcore_config_vtbl *vtbl;
+
+ struct waffle_config {} wfl;
+ struct api_object api;
+
+ struct wcore_display *display;
+};
+
+DEFINE_CONTAINER_CAST_FUNC(wcore_config,
+ struct wcore_config,
+ struct waffle_config,
+ wfl)
+
+static inline bool
+wcore_config_init(struct wcore_config *self,
+ struct wcore_display *display)
+{
+ assert(self);
+ assert(display);
+
+ self->api.display_id = display->api.display_id;
+ self->display = display;
+
+ return true;
+}
+
+static inline bool
+wcore_config_teardown(struct wcore_config *self)
+{
+ assert(self);
+ return true;
+}
diff --git a/src/waffle/core/wcore_context.h b/src/waffle/core/wcore_context.h
new file mode 100644
index 0000000..7d1163d
--- /dev/null
+++ b/src/waffle/core/wcore_context.h
@@ -0,0 +1,77 @@
+// Copyright 2012 Intel Corporation
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// - Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// - Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#pragma once
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdlib.h>
+
+#include <waffle/api/api_object.h>
+
+#include "wcore_config.h"
+#include "wcore_util.h"
+
+struct wcore_context;
+struct wcore_display;
+
+struct wcore_context_vtbl {
+ bool
+ (*destroy)(struct wcore_context *self);
+};
+
+struct wcore_context {
+ const struct wcore_context_vtbl *vtbl;
+
+ struct waffle_context {} wfl;
+ struct api_object api;
+
+ struct wcore_display *display;
+};
+
+DEFINE_CONTAINER_CAST_FUNC(wcore_context,
+ struct wcore_context,
+ struct waffle_context,
+ wfl)
+
+static inline bool
+wcore_context_init(struct wcore_context *self,
+ struct wcore_config *config)
+{
+ assert(self);
+ assert(config);
+
+ self->api.display_id = config->display->api.display_id;
+ self->display = config->display;
+
+ return true;
+}
+
+static inline bool
+wcore_context_teardown(struct wcore_context *self)
+{
+ assert(self);
+ return true;
+}
diff --git a/src/waffle/core/wcore_display.c b/src/waffle/core/wcore_display.c
new file mode 100644
index 0000000..0e42c96
--- /dev/null
+++ b/src/waffle/core/wcore_display.c
@@ -0,0 +1,57 @@
+// Copyright 2012 Intel Corporation
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// - Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// - Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "wcore_display.h"
+
+#include <assert.h>
+#include <stdio.h>
+
+bool
+wcore_display_init(struct wcore_display *self,
+ struct wcore_platform *platform)
+{
+ static size_t id_counter = 0;
+
+ assert(self);
+ assert(platform);
+
+ // FIXME: Not thread safe.
+ self->api.display_id = ++id_counter;
+ self->platform = platform;
+
+ if (self->api.display_id == 0) {
+ fprintf(stderr, "waffle: error: internal counter wrapped to 0\n");
+ abort();
+ }
+
+ return true;
+}
+
+bool
+wcore_display_teardown(struct wcore_display *self)
+{
+ assert(self);
+ return true;
+}
diff --git a/src/waffle/core/wcore_display.h b/src/waffle/core/wcore_display.h
new file mode 100644
index 0000000..d01a81a
--- /dev/null
+++ b/src/waffle/core/wcore_display.h
@@ -0,0 +1,69 @@
+// Copyright 2012 Intel Corporation
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// - Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// - Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#pragma once
+
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+#include <waffle/api/api_object.h>
+
+#include "wcore_util.h"
+
+struct wcore_display;
+struct wcore_platform;
+
+struct wcore_display_vtbl {
+ bool
+ (*destroy)(struct wcore_display *self);
+
+ bool
+ (*supports_context_api)(
+ struct wcore_display *self,
+ int32_t context_api);
+};
+
+struct wcore_display {
+ const struct wcore_display_vtbl *vtbl;
+
+ struct waffle_display {} wfl;
+ struct api_object api;
+
+ struct wcore_platform *platform;
+};
+
+DEFINE_CONTAINER_CAST_FUNC(wcore_display,
+ struct wcore_display,
+ struct waffle_display,
+ wfl)
+
+bool
+wcore_display_init(struct wcore_display *self,
+ struct wcore_platform *platform);
+
+
+bool
+wcore_display_teardown(struct wcore_display *self);
diff --git a/src/waffle/core/wcore_platform.c b/src/waffle/core/wcore_platform.c
deleted file mode 100644
index 22cd914..0000000
--- a/src/waffle/core/wcore_platform.c
+++ /dev/null
@@ -1,147 +0,0 @@
-// Copyright 2012 Intel Corporation
-//
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-// - Redistributions of source code must retain the above copyright notice, this
-// list of conditions and the following disclaimer.
-//
-// - Redistributions in binary form must reproduce the above copyright notice,
-// this list of conditions and the following disclaimer in the documentation
-// and/or other materials provided with the distribution.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-/// @addtogroup wcore_platform
-/// @{
-
-/// @file
-
-#include "wcore_platform.h"
-
-#include <stdbool.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <waffle/waffle_enum.h>
-#include <waffle/cgl/cgl_platform.h>
-#include <waffle/glx/glx_platform.h>
-#include <waffle/wayland/wayland_platform.h>
-#include <waffle/x11_egl/xegl_platform.h>
-
-#include "wcore_error.h"
-
-static uint64_t id_counter = 0;
-
-struct wcore_platform*
-wcore_platform_create(int platform)
-{
- struct wcore_platform *self;
-
- self = calloc(1, sizeof(*self));
- if (!self) {
- wcore_error(WAFFLE_OUT_OF_MEMORY);
- return NULL;
- }
-
- self->id = ++id_counter;
- if (self->id == 0) {
- fprintf(stderr, "waffle: error: internal counter wrapped around to 0");
- abort();
- }
-
- switch (platform) {
-#ifdef WAFFLE_HAS_CGL
- case WAFFLE_PLATFORM_CGL:
- self->native = cgl_platform_create(&self->dispatch);
- if (!self->native)
- goto error;
- break;
-#endif
-#ifdef WAFFLE_HAS_GLX
- case WAFFLE_PLATFORM_GLX:
- self->native = glx_platform_create(&self->dispatch);
- if (!self->native)
- goto error;
- break;
-#endif
-#ifdef WAFFLE_HAS_WAYLAND
- case WAFFLE_PLATFORM_WAYLAND:
- self->native = wayland_platform_create(&self->dispatch);
- if (!self->native)
- goto error;
- break;
-#endif
-#ifdef WAFFLE_HAS_X11_EGL
- case WAFFLE_PLATFORM_X11_EGL:
- self->native = xegl_platform_create(&self->dispatch);
- if (!self->native)
- goto error;
- break;
-#endif
- default:
- wcore_error_internal("bad value for platform (0x%x)", platform);
- goto error;
- }
-
- self->native_tag = platform;
-
- return self;
-
-error:
- wcore_platform_destroy(self);
- return NULL;
-}
-
-bool
-wcore_platform_destroy(struct wcore_platform *self)
-{
- bool ok = true;
-
- if (!self)
- return true;
-
- switch (self->native_tag) {
-#ifdef WAFFLE_HAS_CGL
- case WAFFLE_PLATFORM_CGL:
- ok &= cgl_platform_destroy(self->native);
- break;
-#endif
-#ifdef WAFFLE_HAS_GLX
- case WAFFLE_PLATFORM_GLX:
- ok &= glx_platform_destroy(self->native);
- break;
-#endif
-#ifdef WAFFLE_HAS_WAYLAND
- case WAFFLE_PLATFORM_WAYLAND:
- ok &= wayland_platform_destroy(self->native);
- break;
-#endif
-#ifdef WAFFLE_HAS_X11_EGL
- case WAFFLE_PLATFORM_X11_EGL:
- ok &= xegl_platform_destroy(self->native);
- break;
-#endif
- default:
- ok = false;
- wcore_error_internal("bad value for wcore_platform._native_tag "
- "(0x%x)", self->native_tag);
- break;
- }
-
- return ok;
-}
-
-/// @}
diff --git a/src/waffle/core/wcore_platform.h b/src/waffle/core/wcore_platform.h
index dbb9237..587b280 100644
--- a/src/waffle/core/wcore_platform.h
+++ b/src/waffle/core/wcore_platform.h
@@ -23,37 +23,85 @@
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-/// @defgroup wcore_platform wcore_platform
-/// @ingroup wcore
-///
-/// @brief Abstract native platform.
-/// @{
-
-/// @file
-
#pragma once
+#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
-struct native_dispatch;
-union native_platform;
+struct wcore_config;
+struct wcore_config_attrs;
+struct wcore_context;
+struct wcore_display;
+struct wcore_platform;
+struct wcore_window;
-struct wcore_platform {
- /// @brief Each instance has a unique id.
- uint64_t id;
+struct wcore_platform_vtbl {
+ bool
+ (*destroy)(struct wcore_platform *self);
+
+ struct wcore_display*
+ (*connect_to_display)(
+ struct wcore_platform *self,
+ const char *name);
+
+ struct wcore_config*
+ (*choose_config)(
+ struct wcore_platform *self,
+ struct wcore_display *dpy,
+ const struct wcore_config_attrs *attrs);
+
+ struct wcore_context*
+ (*create_context)(
+ struct wcore_platform *self,
+ struct wcore_config *config,
+ struct wcore_context *share_ctx);
- /// @brief One of WAFFLE_PLATFORM_*. Denotes type of `native`.
- int native_tag;
+ struct wcore_window*
+ (*create_window)(
+ struct wcore_platform *self,
+ struct wcore_config *config,
+ int width,
+ int height);
- union native_platform *native;
- const struct native_dispatch *dispatch;
+ bool
+ (*make_current)(
+ struct wcore_platform *self,
+ struct wcore_display *dpy,
+ struct wcore_window *window,
+ struct wcore_context *ctx);
+
+ void*
+ (*get_proc_address)(
+ struct wcore_platform *self,
+ const char *proc);
+
+ bool
+ (*dl_can_open)(
+ struct wcore_platform *self,
+ int32_t waffle_dl);
+
+ void*
+ (*dl_sym)(
+ struct wcore_platform *self,
+ int32_t waffle_dl,
+ const char *symbol);
};
-struct wcore_platform*
-wcore_platform_create(int platform);
+struct wcore_platform {
+ const struct wcore_platform_vtbl *vtbl;
+};
-bool
-wcore_platform_destroy(struct wcore_platform *self);
+static inline bool
+wcore_platform_init(struct wcore_platform *self)
+{
+ assert(self);
+ return true;
+}
-/// @}
+static inline bool
+wcore_platform_teardown(struct wcore_platform *self)
+{
+ assert(self);
+ return true;
+}
diff --git a/src/waffle/core/wcore_util.h b/src/waffle/core/wcore_util.h
new file mode 100644
index 0000000..ad5921e
--- /dev/null
+++ b/src/waffle/core/wcore_util.h
@@ -0,0 +1,50 @@
+// Copyright 2012 Intel Corporation
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// - Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// - Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#pragma once
+
+#include <stddef.h>
+
+#define container_of(ptr, type, member) ({ \
+ const __typeof__(((type *)0)->member ) *__mptr = (ptr); \
+ (type*)((void*)__mptr - offsetof(type, member)); \
+ })
+
+/// @brief Safe downcast using container_of().
+///
+/// If given a null pointer, return null.
+#define DEFINE_CONTAINER_CAST_FUNC(func_name, \
+ container_type, \
+ member_type, \
+ member) \
+ \
+ static inline container_type* \
+ func_name(member_type *member##_self) \
+ { \
+ if (member##_self) \
+ return container_of(member##_self, container_type, member); \
+ else \
+ return 0; \
+ }
diff --git a/src/waffle/core/wcore_window.h b/src/waffle/core/wcore_window.h
new file mode 100644
index 0000000..c642e80
--- /dev/null
+++ b/src/waffle/core/wcore_window.h
@@ -0,0 +1,80 @@
+// Copyright 2012 Intel Corporation
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// - Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// - Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#pragma once
+
+#include <stdbool.h>
+#include <stdlib.h>
+
+#include "wcore_config.h"
+#include "wcore_util.h"
+
+struct wcore_window;
+
+struct wcore_window_vtbl {
+ bool
+ (*destroy)(struct wcore_window *self);
+
+ bool
+ (*show)(struct wcore_window *self);
+
+ bool
+ (*swap_buffers)(struct wcore_window *self);
+};
+
+struct wcore_window {
+ const struct wcore_window_vtbl *vtbl;
+
+ struct waffle_window {} wfl;
+ struct api_object api;
+
+ struct wcore_display *display;
+};
+
+DEFINE_CONTAINER_CAST_FUNC(wcore_window,
+ struct wcore_window,
+ struct waffle_window,
+ wfl)
+
+
+static inline bool
+wcore_window_init(struct wcore_window *self,
+ struct wcore_config *config)
+{
+ assert(self);
+ assert(config);
+
+ self->api.display_id = config->display->api.display_id;
+ self->display = config->display;
+
+ return true;
+}
+
+static inline bool
+wcore_window_teardown(struct wcore_window *self)
+{
+ assert(self);
+ return true;
+}