diff options
author | Chad Versace <chad.versace@linux.intel.com> | 2013-09-18 23:23:54 -0700 |
---|---|---|
committer | Chad Versace <chad.versace@linux.intel.com> | 2013-09-18 23:23:54 -0700 |
commit | 18c0ee01a926892e5815bfb6af478e777055fd27 (patch) | |
tree | bbf9c64de92ec36366eb987b8302312395ccb143 | |
parent | 22195ff14cea3116f6c7af50dd600de702eaee2a (diff) | |
parent | 3ad77c648b3157d36977d0e7d56dc0c3af14aafb (diff) |
Merge branch 'window-resize'
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> << 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) |