summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChad Versace <chad.versace@linux.intel.com>2013-09-18 23:23:54 -0700
committerChad Versace <chad.versace@linux.intel.com>2013-09-18 23:23:54 -0700
commit18c0ee01a926892e5815bfb6af478e777055fd27 (patch)
treebbf9c64de92ec36366eb987b8302312395ccb143
parent22195ff14cea3116f6c7af50dd600de702eaee2a (diff)
parent3ad77c648b3157d36977d0e7d56dc0c3af14aafb (diff)
Merge branch 'window-resize'
-rw-r--r--cmake/Modules/WaffleDefineCompilerFlags.cmake2
-rw-r--r--cmake/Modules/WaffleDefineVersion.cmake11
-rw-r--r--examples/gl_basic.c51
-rw-r--r--include/waffle/waffle.h16
-rw-r--r--man/html.cmake2
-rw-r--r--man/manpages.cmake2
-rw-r--r--man/waffle.7.xml6
-rw-r--r--man/waffle_config.3.xml8
-rw-r--r--man/waffle_feature_test_macros.7.xml104
-rw-r--r--src/waffle/CMakeLists.txt2
-rw-r--r--src/waffle/cgl/cgl_platform.m1
-rw-r--r--src/waffle/cgl/cgl_window.h4
-rw-r--r--src/waffle/cgl/cgl_window.m9
-rw-r--r--src/waffle/core/wcore_error.c39
-rw-r--r--src/waffle/core/wcore_error.h8
-rw-r--r--src/waffle/glx/glx_platform.c1
-rw-r--r--src/waffle/glx/glx_window.c7
-rw-r--r--src/waffle/glx/glx_window.h4
-rw-r--r--src/waffle/wayland/wayland_display.c17
-rw-r--r--src/waffle/wayland/wayland_display.h16
-rw-r--r--src/waffle/wayland/wayland_platform.c3
-rw-r--r--src/waffle/wayland/wayland_window.c44
-rw-r--r--src/waffle/wayland/wayland_window.h7
-rw-r--r--src/waffle/x11/x11_window.c22
-rw-r--r--src/waffle/x11/x11_window.h3
-rw-r--r--src/waffle/xegl/xegl_platform.c1
-rw-r--r--src/waffle/xegl/xegl_window.c7
-rw-r--r--src/waffle/xegl/xegl_window.h4
-rw-r--r--tests/CMakeLists.txt2
29 files changed, 381 insertions, 22 deletions
diff --git a/cmake/Modules/WaffleDefineCompilerFlags.cmake b/cmake/Modules/WaffleDefineCompilerFlags.cmake
index 0f4cdec..e800089 100644
--- a/cmake/Modules/WaffleDefineCompilerFlags.cmake
+++ b/cmake/Modules/WaffleDefineCompilerFlags.cmake
@@ -28,6 +28,8 @@ include(WaffleCheckThreadLocalStorage)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --std=c99")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror=implicit-function-declaration")
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror=incompatible-pointer-types")
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror=int-conversion")
if(waffle_on_linux)
# On MacOS, the SSE2 headers trigger this error.
diff --git a/cmake/Modules/WaffleDefineVersion.cmake b/cmake/Modules/WaffleDefineVersion.cmake
index a47c81d..43d2fc4 100644
--- a/cmake/Modules/WaffleDefineVersion.cmake
+++ b/cmake/Modules/WaffleDefineVersion.cmake
@@ -53,3 +53,14 @@ set(waffle_version "${waffle_major_version}.${waffle_minor_version}.${waffle_pat
#
set(waffle_libname "waffle-${waffle_major_version}")
set(waffle_soversion "0")
+
+
+#
+# API version.
+#
+# This gets bumped to x.(y+1) immediately after each waffle-x.y.0 release.
+#
+math(EXPR waffle_api_version "(${waffle_major_version} << 8) | ${waffle_minor_version}")
+if (waffle_patch_version GREATER 89)
+ math(EXPR waffle_api_version "${waffle_api_version} + 1")
+endif()
diff --git a/examples/gl_basic.c b/examples/gl_basic.c
index efdec8f..3c8445a 100644
--- a/examples/gl_basic.c
+++ b/examples/gl_basic.c
@@ -34,6 +34,7 @@
/// each buffer swap.
#define _POSIX_C_SOURCE 199309L // glibc feature macro for nanosleep.
+#define WAFFLE_API_VERSION 0x0103
#include <getopt.h>
#include <stdarg.h>
@@ -61,6 +62,7 @@ static const char *usage_message =
" [--profile=core|compat|none]\n"
" [--forward-compatible]\n"
" [--debug]\n"
+ " [--resize-window]\n"
"\n"
"examples:\n"
" gl_basic --platform=glx --api=gl\n"
@@ -76,6 +78,9 @@ static const char *usage_message =
"\n"
" --debug\n"
" Create a debug context.\n"
+ "\n"
+ " --resize-window\n"
+ " Resize the window between each draw call.\n"
;
enum {
@@ -85,6 +90,7 @@ enum {
OPT_PROFILE,
OPT_DEBUG,
OPT_FORWARD_COMPATIBLE,
+ OPT_RESIZE_WINDOW,
};
static const struct option get_opts[] = {
@@ -94,6 +100,7 @@ static const struct option get_opts[] = {
{ .name = "profile", .has_arg = required_argument, .val = OPT_PROFILE },
{ .name = "debug", .has_arg = no_argument, .val = OPT_DEBUG },
{ .name = "forward-compatible", .has_arg = no_argument, .val = OPT_FORWARD_COMPATIBLE },
+ { .name = "resize-window", .has_arg = no_argument, .val = OPT_RESIZE_WINDOW },
{ 0 },
};
@@ -187,6 +194,7 @@ static void (*glClear)(GLbitfield mask);
static void (*glGetIntegerv)(GLenum pname, GLint *params);
static void (*glReadPixels)(GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type, GLvoid* data);
+static void (*glViewport)(GLint x, GLint y, GLsizei width, GLsizei height);
/// @}
/// @defgroup Parsing Options
@@ -207,6 +215,8 @@ struct options {
bool context_forward_compatible;
bool context_debug;
+ bool resize_window;
+
/// @brief One of `WAFFLE_DL_*`.
int dl;
};
@@ -325,6 +335,9 @@ parse_args(int argc, char *argv[], struct options *opts)
case OPT_DEBUG:
opts->context_debug = true;
break;
+ case OPT_RESIZE_WINDOW:
+ opts->resize_window = true;
+ break;
default:
abort();
loop_get_opt = false;
@@ -364,10 +377,12 @@ error_unrecognized_arg:
/// @}
static bool
-draw(struct waffle_window *window)
+draw(struct waffle_window *window, bool resize)
{
bool ok;
unsigned char *colors;
+ int width = WINDOW_WIDTH;
+ int height = WINDOW_HEIGHT;
static const struct timespec sleep_time = {
// 0.5 sec
@@ -383,27 +398,41 @@ draw(struct waffle_window *window)
case 3: abort(); break;
}
+ if (resize) {
+ width = (i + 2) * 40;
+ height = width;
+ waffle_window_resize(window, width, height);
+ glViewport(0, 0, width, height);
+ }
+
glClear(GL_COLOR_BUFFER_BIT);
- colors = calloc(WINDOW_WIDTH * WINDOW_HEIGHT * 4, sizeof(*colors));
+ colors = calloc(width * height * 4, sizeof(*colors));
glReadPixels(0, 0,
- WINDOW_WIDTH, WINDOW_HEIGHT,
+ width, height,
GL_RGBA, GL_UNSIGNED_BYTE,
colors);
- for (int j = 0; j < WINDOW_WIDTH * WINDOW_HEIGHT * 4; j += 4) {
+ for (int j = 0; j < width * height * 4; j += 4) {
if ((colors[j] != (i == 0 ? 0xff : 0)) ||
(colors[j+1] != (i == 1 ? 0xff : 0)) ||
(colors[j+2] != (i == 2 ? 0xff : 0)) ||
(colors[j+3] != 0xff)) {
- free(colors);
- gl_basic_error("glReadPixels returned unexpected result");
+ fprintf(stderr, "glReadPixels returned unexpected result\n");
+ break;
}
}
free(colors);
+ if (i == 0) {
+ ok = waffle_window_show(window);
+ if (!ok)
+ return false;
+ }
+
ok = waffle_window_swap_buffers(window);
if (!ok)
return false;
+
nanosleep(&sleep_time, NULL);
}
@@ -523,6 +552,10 @@ main(int argc, char **argv)
if (!glReadPixels)
error_get_gl_symbol("glReadPixels");
+ glViewport = waffle_dl_sym(opts.dl, "glViewport");
+ if (!glViewport)
+ error_get_gl_symbol("glViewport");
+
i = 0;
config_attrib_list[i++] = WAFFLE_CONTEXT_API;
config_attrib_list[i++] = opts.context_api;
@@ -571,10 +604,6 @@ main(int argc, char **argv)
if (!window)
error_waffle();
- ok = waffle_window_show(window);
- if (!ok)
- error_waffle();
-
ok = waffle_make_current(dpy, window, ctx);
if (!ok)
error_waffle();
@@ -594,7 +623,7 @@ main(int argc, char **argv)
gl_basic_error("context is not a debug context");
}
- ok = draw(window);
+ ok = draw(window, opts.resize_window);
if (!ok)
error_waffle();
diff --git a/include/waffle/waffle.h b/include/waffle/waffle.h
index d3b1fc9..70815dc 100644
--- a/include/waffle/waffle.h
+++ b/include/waffle/waffle.h
@@ -139,8 +139,10 @@ enum waffle_enum {
WAFFLE_CONTEXT_CORE_PROFILE = 0x0211,
WAFFLE_CONTEXT_COMPATIBILITY_PROFILE = 0x0212,
+#if WAFFLE_API_VERSION >= 0x0103
WAFFLE_CONTEXT_FORWARD_COMPATIBLE = 0x0215,
WAFFLE_CONTEXT_DEBUG = 0x0216,
+#endif
WAFFLE_RED_SIZE = 0x0201,
WAFFLE_GREEN_SIZE = 0x0202,
@@ -249,17 +251,19 @@ WAFFLE_API bool
waffle_window_show(struct waffle_window *self);
WAFFLE_API bool
-waffle_window_resize(
- struct waffle_window *self,
- int32_t width,
- int32_t height);
-
-WAFFLE_API bool
waffle_window_swap_buffers(struct waffle_window *self);
WAFFLE_API union waffle_native_window*
waffle_window_get_native(struct waffle_window *self);
+#if WAFFLE_API_VERSION >= 0x0103
+WAFFLE_API bool
+waffle_window_resize(
+ struct waffle_window *self,
+ int32_t width,
+ int32_t height);
+#endif
+
// ---------------------------------------------------------------------------
// waffle_dl
// ---------------------------------------------------------------------------
diff --git a/man/html.cmake b/man/html.cmake
index dc6bb47..7005a71 100644
--- a/man/html.cmake
+++ b/man/html.cmake
@@ -46,6 +46,7 @@ set(html_outputs
${html_out_dir}/waffle_window.3.html
${html_out_dir}/waffle_x11_egl.3.html
${html_out_dir}/waffle.7.html
+ ${html_out_dir}/waffle_feature_test_macros.7.html
)
set(html_common_sources
@@ -82,6 +83,7 @@ waffle_add_html(3 waffle_wayland)
waffle_add_html(3 waffle_window)
waffle_add_html(3 waffle_x11_egl)
waffle_add_html(7 waffle)
+waffle_add_html(7 waffle_feature_test_macros)
add_custom_target(html
ALL
diff --git a/man/manpages.cmake b/man/manpages.cmake
index 90170fd..402bbbc 100644
--- a/man/manpages.cmake
+++ b/man/manpages.cmake
@@ -47,6 +47,7 @@ set(man_outputs
${man_out_dir}/man3/waffle_window.3
${man_out_dir}/man3/waffle_x11_egl.3
${man_out_dir}/man7/waffle.7
+ ${man_out_dir}/man7/waffle_feature_test_macros.7
)
set(man_common_sources
@@ -81,6 +82,7 @@ waffle_add_manpage(3 waffle_wayland)
waffle_add_manpage(3 waffle_window)
waffle_add_manpage(3 waffle_x11_egl)
waffle_add_manpage(7 waffle)
+waffle_add_manpage(7 waffle_feature_test_macros)
add_custom_target(man
ALL
diff --git a/man/waffle.7.xml b/man/waffle.7.xml
index d4ee215..ab116d5 100644
--- a/man/waffle.7.xml
+++ b/man/waffle.7.xml
@@ -92,6 +92,12 @@ Link with -lwaffle-1.
<para>
<simplelist>
+ <member><citerefentry><refentrytitle>waffle_feature_test_macros</refentrytitle><manvolnum>7</manvolnum></citerefentry></member>
+ </simplelist>
+ </para>
+
+ <para>
+ <simplelist>
<member><citerefentry><refentrytitle>waffle_attrib_list</refentrytitle><manvolnum>3</manvolnum></citerefentry>,</member>
<member><citerefentry><refentrytitle>waffle_config</refentrytitle><manvolnum>3</manvolnum></citerefentry>,</member>
<member><citerefentry><refentrytitle>waffle_context</refentrytitle><manvolnum>3</manvolnum></citerefentry>,</member>
diff --git a/man/waffle_config.3.xml b/man/waffle_config.3.xml
index 46b0aa2..479a3ce 100644
--- a/man/waffle_config.3.xml
+++ b/man/waffle_config.3.xml
@@ -347,6 +347,10 @@ struct waffle_config;
<term><constant>WAFFLE_CONTEXT_FORWARD_COMPATIBLE</constant></term>
<listitem>
<para>
+ Feature test macro: <code>WAFFLE_API_VERSION >= 0x0103</code>.
+ (See <citerefentry><refentrytitle>waffle_feature_test_macros</refentrytitle><manvolnum>7</manvolnum></citerefentry>).
+ </para>
+ <para>
This attribute, if true, instructs
<citerefentry><refentrytitle><function>waffle_context_create</function></refentrytitle><manvolnum>3</manvolnum></citerefentry>
to create a forward-compatible context.
@@ -379,6 +383,10 @@ struct waffle_config;
<term><constant>WAFFLE_CONTEXT_DEBUG</constant></term>
<listitem>
<para>
+ Feature test macro: <code>WAFFLE_API_VERSION >= 0x0103</code>.
+ (See <citerefentry><refentrytitle>waffle_feature_test_macros</refentrytitle><manvolnum>7</manvolnum></citerefentry>).
+ </para>
+ <para>
This attribute, if true, instructs
<citerefentry><refentrytitle><function>waffle_context_create</function></refentrytitle><manvolnum>3</manvolnum></citerefentry>
to create a debug context.
diff --git a/man/waffle_feature_test_macros.7.xml b/man/waffle_feature_test_macros.7.xml
new file mode 100644
index 0000000..4e4298c
--- /dev/null
+++ b/man/waffle_feature_test_macros.7.xml
@@ -0,0 +1,104 @@
+<?xml version='1.0'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+ Copyright Intel 2013
+
+ This manual page is licensed under the Creative Commons Attribution-ShareAlike 3.0 United States License (CC BY-SA 3.0
+ US). To view a copy of this license, visit http://creativecommons.org.license/by-sa/3.0/us.
+-->
+
+<refentry
+ id="waffle_feature_test_macros"
+ xmlns:xi="http://www.w3.org/2001/XInclude">
+
+ <!-- See http://www.docbook.org/tdg/en/html/refentry.html. -->
+
+ <refmeta>
+ <refentrytitle>waffle_feature_test_macros</refentrytitle>
+ <manvolnum>7</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>waffle_feature_test_macros</refname>
+ <refpurpose>Macros to control definitions exposed by Waffle's headers</refpurpose>
+ </refnamediv>
+
+ <refentryinfo>
+ <title>Waffle Manual</title>
+ <productname>waffle</productname>
+ <xi:include href="common/author-chad.versace.xml"/>
+ <xi:include href="common/copyright.xml"/>
+ <xi:include href="common/legalnotice.xml"/>
+ </refentryinfo>
+
+ <refsynopsisdiv>
+ <synopsis>
+<constant>WAFFLE_API_VERSION</constant>
+ </synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>
+ Waffle's feature test macros allow the programmer to control the definitions that are exposed by Waffle's headers
+ when a program is compiled.
+
+ Conversely, the macros allow the programmer to control which Waffle features a program's source relies on.
+ </para>
+ <para>
+ In order to be effective, a feature test macro must be defined before including any header files. This can be done
+ either in the compilation command (cc -DMACRO=value) or by defining the macro within the source code before including
+ any headers.
+ </para>
+ <refsect2>
+ <title>Specification of feature test macro requirements in manual pages</title>
+ <para>
+ When a function requires that a feature test macro be defined, the manual page docments it in the SYNOPSIS.
+
+ When an enum or macro requires that a feature test macro be defined, the manual page documents it either in the
+ SYNOPSIS or where the enum or macro first appears in the page.
+ </para>
+ </refsect2>
+ <refsect2>
+ <title>List of feature test macros</title>
+ <variablelist>
+ <varlistentry>
+ <term><constant>WAFFLE_API_VERSION</constant> (since waffle 1.3)</term>
+ <listitem>
+ <para>
+ This macro controls the API version exposed by Waffle's headers.
+
+ The value
+ <code>((<parameter>major</parameter> &lt;&lt; 8) | <parameter>minor</parameter>)</code>
+ exposes the API of
+ Waffle <parameter>major</parameter>.<parameter>minor</parameter>.
+
+ For example, the value 0x0103 exposes the API of Waffle 1.3.
+
+ If this macro is undefined, then the headers expose the API of Waffle 1.2.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect2>
+
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <para>
+ <simplelist>
+ <member><citerefentry><refentrytitle>waffle</refentrytitle><manvolnum>7</manvolnum></citerefentry></member>,
+ <member><citerefentry><refentrytitle>feature_test_macros</refentrytitle><manvolnum>7</manvolnum></citerefentry></member>
+ </simplelist>
+ </para>
+ </refsect1>
+
+</refentry>
+
+<!--
+vim:tw=120 et ts=2 sw=2:
+-->
diff --git a/src/waffle/CMakeLists.txt b/src/waffle/CMakeLists.txt
index a743096..b5641d3 100644
--- a/src/waffle/CMakeLists.txt
+++ b/src/waffle/CMakeLists.txt
@@ -2,6 +2,8 @@
# Applies to all targets in this CMakeLists.
# ----------------------------------------------------------------------------
+add_definitions(-DWAFFLE_API_VERSION=${waffle_api_version})
+
include_directories(
android
api
diff --git a/src/waffle/cgl/cgl_platform.m b/src/waffle/cgl/cgl_platform.m
index 044456d..ee3b7e7 100644
--- a/src/waffle/cgl/cgl_platform.m
+++ b/src/waffle/cgl/cgl_platform.m
@@ -182,6 +182,7 @@ static const struct wcore_platform_vtbl cgl_platform_vtbl = {
.create = cgl_window_create,
.destroy = cgl_window_destroy,
.show = cgl_window_show,
+ .resize = cgl_window_resize,
.swap_buffers = cgl_window_swap_buffers,
.get_native = NULL,
},
diff --git a/src/waffle/cgl/cgl_window.h b/src/waffle/cgl/cgl_window.h
index a192076..4038e09 100644
--- a/src/waffle/cgl/cgl_window.h
+++ b/src/waffle/cgl/cgl_window.h
@@ -58,6 +58,10 @@ bool
cgl_window_show(struct wcore_window *wc_self);
bool
+cgl_window_resize(struct wcore_window *wc_self,
+ int32_t width, int32_t height);
+
+bool
cgl_window_swap_buffers(struct wcore_window *wc_self);
union waffle_native_window*
diff --git a/src/waffle/cgl/cgl_window.m b/src/waffle/cgl/cgl_window.m
index 5e1944e..1c97590 100644
--- a/src/waffle/cgl/cgl_window.m
+++ b/src/waffle/cgl/cgl_window.m
@@ -132,6 +132,15 @@ cgl_window_show(struct wcore_window *wc_self)
}
bool
+cgl_window_resize(struct wcore_window *wc_self,
+ int32_t width, int32_t height)
+{
+ struct cgl_window *self = cgl_window(wc_self);
+ [self->ns_window setContentSize:(NSSize){width, height}];
+ return true;
+}
+
+bool
cgl_window_swap_buffers(struct wcore_window *wc_self)
{
struct cgl_window *self = cgl_window(wc_self);
diff --git a/src/waffle/core/wcore_error.c b/src/waffle/core/wcore_error.c
index 2a689b1..edcb821 100644
--- a/src/waffle/core/wcore_error.c
+++ b/src/waffle/core/wcore_error.c
@@ -28,6 +28,9 @@
/// @file
+#define _XOPEN_SOURCE 600 // for strerror_r
+
+#include <errno.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
@@ -137,6 +140,42 @@ wcore_errorf(int error, const char *format, ...)
}
void
+wcore_error_errno(const char *format, ...)
+{
+ int saved_errno = errno;
+
+ struct wcore_error_tinfo *t = wcore_tinfo_get()->error;
+ char *cur = t->message;
+ char *end = t->message + WCORE_ERROR_MESSAGE_BUFSIZE;
+ int printed;
+
+ if (!t->is_enabled)
+ return;
+
+ t->code = WAFFLE_ERROR_UNKNOWN;
+
+ if (format) {
+ va_list ap;
+
+ va_start(ap, format);
+ printed = vsnprintf(cur, end - cur, format, ap);
+ cur += printed;
+ va_end(ap);
+
+ if (printed < 0 || cur >= end)
+ return;
+
+ printed = snprintf(cur, end - cur, ": ");
+ cur += printed;
+
+ if (printed < 0 || cur >= end)
+ return;
+ }
+
+ strerror_r(saved_errno, cur, end - cur);
+}
+
+void
_wcore_error_internal(const char *file, int line, const char *format, ...)
{
struct wcore_error_tinfo *t = wcore_tinfo_get()->error;
diff --git a/src/waffle/core/wcore_error.h b/src/waffle/core/wcore_error.h
index 7b127b8..d466612 100644
--- a/src/waffle/core/wcore_error.h
+++ b/src/waffle/core/wcore_error.h
@@ -66,6 +66,14 @@ wcore_error(int error);
void
wcore_errorf(int error, const char *format, ...);
+/// @brief Emit error for errno.
+///
+/// Set error code to WAFFLE_ERROR_UNKNOWN and place the output of
+/// strerror() in the error message. If \a format is not null,
+/// then prepend the strerror() message with "${format}: ".
+void
+wcore_error_errno(const char *format, ...);
+
/// @brief Set error to WAFFLE_INTERNAL_ERROR with source location.
#define wcore_error_internal(format, ...) \
_wcore_error_internal(__FILE__, __LINE__, format, __VA_ARGS__)
diff --git a/src/waffle/glx/glx_platform.c b/src/waffle/glx/glx_platform.c
index 8ddcfcb..be710eb 100644
--- a/src/waffle/glx/glx_platform.c
+++ b/src/waffle/glx/glx_platform.c
@@ -150,6 +150,7 @@ static const struct wcore_platform_vtbl glx_platform_vtbl = {
.create = glx_window_create,
.destroy = glx_window_destroy,
.show = glx_window_show,
+ .resize = glx_window_resize,
.swap_buffers = glx_window_swap_buffers,
.get_native = glx_window_get_native,
},
diff --git a/src/waffle/glx/glx_window.c b/src/waffle/glx/glx_window.c
index 6519738..702ed3f 100644
--- a/src/waffle/glx/glx_window.c
+++ b/src/waffle/glx/glx_window.c
@@ -89,6 +89,13 @@ glx_window_show(struct wcore_window *wc_self)
}
bool
+glx_window_resize(struct wcore_window *wc_self,
+ int32_t width, int32_t height)
+{
+ return x11_window_resize(&glx_window(wc_self)->x11, width, height);
+}
+
+bool
glx_window_swap_buffers(struct wcore_window *wc_self)
{
struct glx_window *self = glx_window(wc_self);
diff --git a/src/waffle/glx/glx_window.h b/src/waffle/glx/glx_window.h
index 2a97a16..4cf44e3 100644
--- a/src/waffle/glx/glx_window.h
+++ b/src/waffle/glx/glx_window.h
@@ -58,6 +58,10 @@ bool
glx_window_show(struct wcore_window *wc_self);
bool
+glx_window_resize(struct wcore_window *wc_self,
+ int32_t width, int32_t height);
+
+bool
glx_window_swap_buffers(struct wcore_window *wc_self);
union waffle_native_window*
diff --git a/src/waffle/wayland/wayland_display.c b/src/waffle/wayland/wayland_display.c
index a6e8f56..ec9d336 100644
--- a/src/waffle/wayland/wayland_display.c
+++ b/src/waffle/wayland/wayland_display.c
@@ -117,11 +117,9 @@ wayland_display_connect(struct wcore_platform *wc_plat,
// has sent out pending events on all event queues. This should ensure
// that the registry listener has received announcement of the shell and
// compositor.
- error = wl_display_roundtrip(self->wl_display);
- if (error < 0) {
- wcore_errorf(WAFFLE_ERROR_UNKNOWN, "wl_display_roundtrip failed");
+ ok = wayland_display_sync(self);
+ if (!ok)
goto error;
- }
if (!self->wl_compositor) {
wcore_errorf(WAFFLE_ERROR_UNKNOWN, "failed to bind to the wayland "
@@ -170,3 +168,14 @@ wayland_display_get_native(struct wcore_display *wc_self)
return n_dpy;
}
+
+bool
+wayland_display_sync(struct wayland_display *dpy)
+{
+ if (wl_display_roundtrip(dpy->wl_display) == -1) {
+ wcore_error_errno("error on wl_display");
+ return false;
+ }
+
+ return true;
+}
diff --git a/src/waffle/wayland/wayland_display.h b/src/waffle/wayland/wayland_display.h
index 6a384c3..722e379 100644
--- a/src/waffle/wayland/wayland_display.h
+++ b/src/waffle/wayland/wayland_display.h
@@ -74,3 +74,19 @@ wayland_display_fill_native(struct wayland_display *self,
union waffle_native_display*
wayland_display_get_native(struct wcore_display *wc_self);
+
+/// @brief Synchronize with server.
+///
+/// Wayland has flushing requirements that differ from X, largely due to
+/// Wayland being agressively asyncrhonous. For example, according to
+/// wl_display(3), in event loops "the client should always call
+/// wl_display_dispatch_pending() and then wl_display_flush() prior to going
+/// back to sleep". Otherwise, all pending requests may not be dispatched to
+/// the server.
+///
+/// Waffle can't expect the client to be aware of Wayland's flushing
+/// requirements and to make the needed native Wayland calls before blocking.
+/// Instead, the only sensible solution (for now, at least) is to make the
+/// public entry points synchronous.
+bool
+wayland_display_sync(struct wayland_display *dpy);
diff --git a/src/waffle/wayland/wayland_platform.c b/src/waffle/wayland/wayland_platform.c
index 1d709bc..8ca30d4 100644
--- a/src/waffle/wayland/wayland_platform.c
+++ b/src/waffle/wayland/wayland_platform.c
@@ -174,7 +174,8 @@ static const struct wcore_platform_vtbl wayland_platform_vtbl = {
.create = wayland_window_create,
.destroy = wayland_window_destroy,
.show = wayland_window_show,
- .swap_buffers = wegl_window_swap_buffers,
+ .swap_buffers = wayland_window_swap_buffers,
+ .resize = wayland_window_resize,
.get_native = wayland_window_get_native,
},
};
diff --git a/src/waffle/wayland/wayland_window.c b/src/waffle/wayland/wayland_window.c
index 8d6d651..c8986bd 100644
--- a/src/waffle/wayland/wayland_window.c
+++ b/src/waffle/wayland/wayland_window.c
@@ -112,6 +112,10 @@ wayland_window_create(struct wcore_platform *wc_plat,
if (!ok)
goto error;
+ ok = wayland_display_sync(dpy);
+ if (!ok)
+ goto error;
+
return &self->wegl.wcore;
error:
@@ -124,13 +128,53 @@ bool
wayland_window_show(struct wcore_window *wc_self)
{
struct wayland_window *self = wayland_window(wc_self);
+ struct wayland_display *dpy = wayland_display(wc_self->display);
+ bool ok = true;
wl_shell_surface_set_toplevel(self->wl_shell_surface);
+ ok = wayland_display_sync(dpy);
+ if (!ok)
+ return false;
+
// FIXME: How to detect errors in Wayland?
return true;
}
+bool
+wayland_window_swap_buffers(struct wcore_window *wc_self)
+{
+ struct wayland_display *dpy = wayland_display(wc_self->display);
+ bool ok;
+
+ ok = wegl_window_swap_buffers(wc_self);
+ if (!ok)
+ return false;
+
+ ok = wayland_display_sync(dpy);
+ if (!ok)
+ return false;
+
+ return true;
+}
+
+bool
+wayland_window_resize(struct wcore_window *wc_self,
+ int32_t width, int32_t height)
+{
+ struct wayland_window *self = wayland_window(wc_self);
+ struct wayland_display *dpy = wayland_display(self->wegl.wcore.display);
+
+ wl_egl_window_resize(wayland_window(wc_self)->wl_window,
+ width, height, 0, 0);
+
+ if (!wayland_display_sync(dpy))
+ return false;
+
+ // FIXME: How to detect if the resize failed?
+ return true;
+}
+
union waffle_native_window*
wayland_window_get_native(struct wcore_window *wc_self)
{
diff --git a/src/waffle/wayland/wayland_window.h b/src/waffle/wayland/wayland_window.h
index 2f5a8c7..933e751 100644
--- a/src/waffle/wayland/wayland_window.h
+++ b/src/waffle/wayland/wayland_window.h
@@ -68,5 +68,12 @@ wayland_window_destroy(struct wcore_window *wc_self);
bool
wayland_window_show(struct wcore_window *wc_self);
+bool
+wayland_window_swap_buffers(struct wcore_window *wc_self);
+
+bool
+wayland_window_resize(struct wcore_window *wc_self,
+ int32_t width, int32_t height);
+
union waffle_native_window*
wayland_window_get_native(struct wcore_window *wc_self);
diff --git a/src/waffle/x11/x11_window.c b/src/waffle/x11/x11_window.c
index 4c5bfbb..582cc02 100644
--- a/src/waffle/x11/x11_window.c
+++ b/src/waffle/x11/x11_window.c
@@ -201,3 +201,25 @@ x11_window_show(struct x11_window *self)
return !error;
}
+
+bool
+x11_window_resize(struct x11_window *self, int32_t width, int32_t height)
+{
+ xcb_void_cookie_t cookie;
+ xcb_generic_error_t *error;
+
+ cookie = xcb_configure_window(
+ self->display->xcb, self->xcb,
+ XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT,
+ (uint32_t[]){width, height});
+
+ error = xcb_request_check(self->display->xcb, cookie);
+ if (error) {
+ wcore_errorf(WAFFLE_ERROR_UNKNOWN,
+ "xcb_configure_window() failed to resize width, "
+ "height: error=0x%x\n", error->error_code);
+ return false;
+ }
+
+ return true;
+}
diff --git a/src/waffle/x11/x11_window.h b/src/waffle/x11/x11_window.h
index e1308ad..812b146 100644
--- a/src/waffle/x11/x11_window.h
+++ b/src/waffle/x11/x11_window.h
@@ -48,3 +48,6 @@ x11_window_teardown(struct x11_window *self);
bool
x11_window_show(struct x11_window *self);
+
+bool
+x11_window_resize(struct x11_window *self, int32_t width, int32_t height);
diff --git a/src/waffle/xegl/xegl_platform.c b/src/waffle/xegl/xegl_platform.c
index fa5a768..71bf23c 100644
--- a/src/waffle/xegl/xegl_platform.c
+++ b/src/waffle/xegl/xegl_platform.c
@@ -171,6 +171,7 @@ static const struct wcore_platform_vtbl xegl_platform_vtbl = {
.create = xegl_window_create,
.destroy = xegl_window_destroy,
.show = xegl_window_show,
+ .resize = xegl_window_resize,
.swap_buffers = wegl_window_swap_buffers,
.get_native = xegl_window_get_native,
},
diff --git a/src/waffle/xegl/xegl_window.c b/src/waffle/xegl/xegl_window.c
index 4ddadc6..5fcadda 100644
--- a/src/waffle/xegl/xegl_window.c
+++ b/src/waffle/xegl/xegl_window.c
@@ -103,6 +103,13 @@ xegl_window_show(struct wcore_window *wc_self)
return x11_window_show(&xegl_window(wc_self)->x11);
}
+bool
+xegl_window_resize(struct wcore_window *wc_self,
+ int32_t width, int32_t height)
+{
+ return x11_window_resize(&xegl_window(wc_self)->x11, width, height);
+}
+
union waffle_native_window*
xegl_window_get_native(struct wcore_window *wc_self)
{
diff --git a/src/waffle/xegl/xegl_window.h b/src/waffle/xegl/xegl_window.h
index 52fdc71..1f963ba 100644
--- a/src/waffle/xegl/xegl_window.h
+++ b/src/waffle/xegl/xegl_window.h
@@ -65,5 +65,9 @@ xegl_window_destroy(struct wcore_window *wc_self);
bool
xegl_window_show(struct wcore_window *wc_self);
+bool
+xegl_window_resize(struct wcore_window *wc_self,
+ int32_t width, int32_t height);
+
union waffle_native_window*
xegl_window_get_native(struct wcore_window *wc_self);
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 7a9dd7e..42061a3 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -1,3 +1,5 @@
+add_definitions(-DWAFFLE_API_VERSION=${waffle_api_version})
+
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
add_subdirectory(waffle_test)