summaryrefslogtreecommitdiffstats
path: root/bsp/meta-synopsys/recipes-graphics/wayland/weston/1006-libweston-add-weston_debug-API-and-implementation.patch
diff options
context:
space:
mode:
Diffstat (limited to 'bsp/meta-synopsys/recipes-graphics/wayland/weston/1006-libweston-add-weston_debug-API-and-implementation.patch')
-rw-r--r--bsp/meta-synopsys/recipes-graphics/wayland/weston/1006-libweston-add-weston_debug-API-and-implementation.patch958
1 files changed, 0 insertions, 958 deletions
diff --git a/bsp/meta-synopsys/recipes-graphics/wayland/weston/1006-libweston-add-weston_debug-API-and-implementation.patch b/bsp/meta-synopsys/recipes-graphics/wayland/weston/1006-libweston-add-weston_debug-API-and-implementation.patch
deleted file mode 100644
index 83887c66..00000000
--- a/bsp/meta-synopsys/recipes-graphics/wayland/weston/1006-libweston-add-weston_debug-API-and-implementation.patch
+++ /dev/null
@@ -1,958 +0,0 @@
-From a5630eafec4f139adf1da4a5ba54894715d7b50f Mon Sep 17 00:00:00 2001
-From: Pekka Paalanen <pq@iki.fi>
-Date: Thu, 12 Oct 2017 13:13:42 +0200
-Subject: [PATCH 06/46] libweston: add weston_debug API and implementation
-
-weston_debug is both a libweston API for relaying debugging messages,
-and the compositor-debug wayland protocol implementation for accessing those
-debug messages from a Wayland client.
-
-weston_debug_compositor_{create,destroy}() are private API, hence not
-exported.
-
-Signed-off-by: Pekka Paalanen <pq@iki.fi>
-
-append the debug scope name along with the timestamp in
-weston_debug_scope_timestamp API
-
-Signed-off-by: Maniraj Devadoss <Maniraj.Devadoss@in.bosch.com>
-Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
-
-Add explicit advertisement of debug scope names.
-
-Signed-off-by: Daniel Stone <daniels@collabora.com>
-Reviewed-by: Emre Ucan <eucan@de.adit-jv.com>
----
- Makefile.am | 2 +
- libweston/compositor.c | 5 +
- libweston/compositor.h | 9 +
- libweston/weston-debug.c | 732 +++++++++++++++++++++++++++++++++++++++++++++++
- libweston/weston-debug.h | 107 +++++++
- 5 files changed, 855 insertions(+)
- create mode 100644 libweston/weston-debug.c
- create mode 100644 libweston/weston-debug.h
-
-diff --git a/Makefile.am b/Makefile.am
-index e38ac009..d5ed3e58 100644
---- a/Makefile.am
-+++ b/Makefile.am
-@@ -96,6 +96,8 @@ libweston_@LIBWESTON_MAJOR@_la_SOURCES = \
- libweston/linux-dmabuf.h \
- libweston/pixel-formats.c \
- libweston/pixel-formats.h \
-+ libweston/weston-debug.c \
-+ libweston/weston-debug.h \
- shared/helpers.h \
- shared/matrix.c \
- shared/matrix.h \
-diff --git a/libweston/compositor.c b/libweston/compositor.c
-index 9deb7817..01616550 100644
---- a/libweston/compositor.c
-+++ b/libweston/compositor.c
-@@ -6361,6 +6361,9 @@ weston_compositor_create(struct wl_display *display, void *user_data)
- ec, bind_presentation))
- goto fail;
-
-+ if (weston_debug_compositor_create(ec) < 0)
-+ goto fail;
-+
- if (weston_input_init(ec) != 0)
- goto fail;
-
-@@ -6702,6 +6705,8 @@ weston_compositor_destroy(struct weston_compositor *compositor)
- if (compositor->heads_changed_source)
- wl_event_source_remove(compositor->heads_changed_source);
-
-+ weston_debug_compositor_destroy(compositor);
-+
- free(compositor);
- }
-
-diff --git a/libweston/compositor.h b/libweston/compositor.h
-index 8b7a1020..33f02b18 100644
---- a/libweston/compositor.h
-+++ b/libweston/compositor.h
-@@ -1048,6 +1048,7 @@ struct weston_touch_calibrator;
-
- struct weston_desktop_xwayland;
- struct weston_desktop_xwayland_interface;
-+struct weston_debug_compositor;
-
- struct weston_compositor {
- struct wl_signal destroy_signal;
-@@ -1160,6 +1161,8 @@ struct weston_compositor {
- weston_touch_calibration_save_func touch_calibration_save;
- struct weston_layer calibrator_layer;
- struct weston_touch_calibrator *touch_calibrator;
-+
-+ struct weston_debug_compositor *weston_debug;
- };
-
- struct weston_buffer {
-@@ -2318,6 +2321,12 @@ int
- weston_compositor_enable_touch_calibrator(struct weston_compositor *compositor,
- weston_touch_calibration_save_func save);
-
-+int
-+weston_debug_compositor_create(struct weston_compositor *compositor);
-+
-+void
-+weston_debug_compositor_destroy(struct weston_compositor *compositor);
-+
- #ifdef __cplusplus
- }
- #endif
-diff --git a/libweston/weston-debug.c b/libweston/weston-debug.c
-new file mode 100644
-index 00000000..04895ad5
---- /dev/null
-+++ b/libweston/weston-debug.c
-@@ -0,0 +1,732 @@
-+/*
-+ * Copyright © 2017 Pekka Paalanen <pq@iki.fi>
-+ * Copyright © 2018 Zodiac Inflight Innovations
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining
-+ * a copy of this software and associated documentation files (the
-+ * "Software"), to deal in the Software without restriction, including
-+ * without limitation the rights to use, copy, modify, merge, publish,
-+ * distribute, sublicense, and/or sell copies of the Software, and to
-+ * permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ *
-+ * The above copyright notice and this permission notice (including the
-+ * next paragraph) shall be included in all copies or substantial
-+ * portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
-+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
-+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-+ * SOFTWARE.
-+ */
-+
-+#include "config.h"
-+
-+#include "weston-debug.h"
-+#include "helpers.h"
-+#include "compositor.h"
-+
-+#include "weston-debug-server-protocol.h"
-+
-+#include <assert.h>
-+#include <unistd.h>
-+#include <stdarg.h>
-+#include <string.h>
-+#include <errno.h>
-+#include <sys/time.h>
-+
-+/** Main weston-debug context
-+ *
-+ * One per weston_compositor.
-+ *
-+ * \internal
-+ */
-+struct weston_debug_compositor {
-+ struct weston_compositor *compositor;
-+ struct wl_listener compositor_destroy_listener;
-+ struct wl_global *global;
-+ struct wl_list scope_list; /**< weston_debug_scope::compositor_link */
-+};
-+
-+/** weston-debug message scope
-+ *
-+ * This is used for scoping debugging messages. Clients can subscribe to
-+ * only the scopes they are interested in. A scope is identified by its name
-+ * (also referred to as debug stream name).
-+ */
-+struct weston_debug_scope {
-+ char *name;
-+ char *desc;
-+ weston_debug_scope_cb begin_cb;
-+ void *user_data;
-+ struct wl_list stream_list; /**< weston_debug_stream::scope_link */
-+ struct wl_list compositor_link;
-+};
-+
-+/** A debug stream created by a client
-+ *
-+ * A client provides a file descriptor for the server to write debug
-+ * messages into. A weston_debug_stream is associated to one
-+ * weston_debug_scope via the scope name, and the scope provides the messages.
-+ * There can be several streams for the same scope, all streams getting the
-+ * same messages.
-+ */
-+struct weston_debug_stream {
-+ int fd; /**< client provided fd */
-+ struct wl_resource *resource; /**< weston_debug_stream_v1 object */
-+ struct wl_list scope_link;
-+};
-+
-+static struct weston_debug_scope *
-+get_scope(struct weston_debug_compositor *wdc, const char *name)
-+{
-+ struct weston_debug_scope *scope;
-+
-+ wl_list_for_each(scope, &wdc->scope_list, compositor_link)
-+ if (strcmp(name, scope->name) == 0)
-+ return scope;
-+
-+ return NULL;
-+}
-+
-+static void
-+stream_close_unlink(struct weston_debug_stream *stream)
-+{
-+ if (stream->fd != -1)
-+ close(stream->fd);
-+ stream->fd = -1;
-+
-+ wl_list_remove(&stream->scope_link);
-+ wl_list_init(&stream->scope_link);
-+}
-+
-+static void WL_PRINTF(2, 3)
-+stream_close_on_failure(struct weston_debug_stream *stream,
-+ const char *fmt, ...)
-+{
-+ char *msg;
-+ va_list ap;
-+ int ret;
-+
-+ stream_close_unlink(stream);
-+
-+ va_start(ap, fmt);
-+ ret = vasprintf(&msg, fmt, ap);
-+ va_end(ap);
-+
-+ if (ret > 0) {
-+ weston_debug_stream_v1_send_failure(stream->resource, msg);
-+ free(msg);
-+ } else {
-+ weston_debug_stream_v1_send_failure(stream->resource,
-+ "MEMFAIL");
-+ }
-+}
-+
-+static struct weston_debug_stream *
-+stream_create(struct weston_debug_compositor *wdc, const char *name,
-+ int32_t streamfd, struct wl_resource *stream_resource)
-+{
-+ struct weston_debug_stream *stream;
-+ struct weston_debug_scope *scope;
-+
-+ stream = zalloc(sizeof *stream);
-+ if (!stream)
-+ return NULL;
-+
-+ stream->fd = streamfd;
-+ stream->resource = stream_resource;
-+
-+ scope = get_scope(wdc, name);
-+ if (scope) {
-+ wl_list_insert(&scope->stream_list, &stream->scope_link);
-+
-+ if (scope->begin_cb)
-+ scope->begin_cb(stream, scope->user_data);
-+ } else {
-+ wl_list_init(&stream->scope_link);
-+ stream_close_on_failure(stream,
-+ "Debug stream name '%s' is unknown.",
-+ name);
-+ }
-+
-+ return stream;
-+}
-+
-+static void
-+stream_destroy(struct wl_resource *stream_resource)
-+{
-+ struct weston_debug_stream *stream;
-+
-+ stream = wl_resource_get_user_data(stream_resource);
-+
-+ if (stream->fd != -1)
-+ close(stream->fd);
-+ wl_list_remove(&stream->scope_link);
-+ free(stream);
-+}
-+
-+static void
-+weston_debug_stream_destroy(struct wl_client *client,
-+ struct wl_resource *stream_resource)
-+{
-+ wl_resource_destroy(stream_resource);
-+}
-+
-+static const struct weston_debug_stream_v1_interface
-+ weston_debug_stream_impl = {
-+ weston_debug_stream_destroy
-+};
-+
-+static void
-+weston_debug_destroy(struct wl_client *client,
-+ struct wl_resource *global_resource)
-+{
-+ wl_resource_destroy(global_resource);
-+}
-+
-+static void
-+weston_debug_subscribe(struct wl_client *client,
-+ struct wl_resource *global_resource,
-+ const char *name,
-+ int32_t streamfd,
-+ uint32_t new_stream_id)
-+{
-+ struct weston_debug_compositor *wdc;
-+ struct wl_resource *stream_resource;
-+ uint32_t version;
-+ struct weston_debug_stream *stream;
-+
-+ wdc = wl_resource_get_user_data(global_resource);
-+ version = wl_resource_get_version(global_resource);
-+
-+ stream_resource = wl_resource_create(client,
-+ &weston_debug_stream_v1_interface,
-+ version, new_stream_id);
-+ if (!stream_resource)
-+ goto fail;
-+
-+ stream = stream_create(wdc, name, streamfd, stream_resource);
-+ if (!stream)
-+ goto fail;
-+
-+ wl_resource_set_implementation(stream_resource,
-+ &weston_debug_stream_impl,
-+ stream, stream_destroy);
-+ return;
-+
-+fail:
-+ close(streamfd);
-+ wl_client_post_no_memory(client);
-+}
-+
-+static const struct weston_debug_v1_interface weston_debug_impl = {
-+ weston_debug_destroy,
-+ weston_debug_subscribe
-+};
-+
-+static void
-+bind_weston_debug(struct wl_client *client,
-+ void *data, uint32_t version, uint32_t id)
-+{
-+ struct weston_debug_compositor *wdc = data;
-+ struct weston_debug_scope *scope;
-+ struct wl_resource *resource;
-+
-+ resource = wl_resource_create(client,
-+ &weston_debug_v1_interface,
-+ version, id);
-+ if (!resource) {
-+ wl_client_post_no_memory(client);
-+ return;
-+ }
-+ wl_resource_set_implementation(resource, &weston_debug_impl,
-+ wdc, NULL);
-+
-+ wl_list_for_each(scope, &wdc->scope_list, compositor_link) {
-+ weston_debug_v1_send_available(resource, scope->name,
-+ scope->desc);
-+ }
-+}
-+
-+/** Initialize weston-debug structure
-+ *
-+ * \param compositor The libweston compositor.
-+ * \return 0 on success, -1 on failure.
-+ *
-+ * weston_debug_compositor is a singleton for each weston_compositor.
-+ *
-+ * Sets weston_compositor::weston_debug.
-+ *
-+ * \internal
-+ */
-+int
-+weston_debug_compositor_create(struct weston_compositor *compositor)
-+{
-+ struct weston_debug_compositor *wdc;
-+
-+ if (compositor->weston_debug)
-+ return -1;
-+
-+ wdc = zalloc(sizeof *wdc);
-+ if (!wdc)
-+ return -1;
-+
-+ wdc->compositor = compositor;
-+ wl_list_init(&wdc->scope_list);
-+
-+ compositor->weston_debug = wdc;
-+
-+ return 0;
-+}
-+
-+/** Destroy weston_debug_compositor structure
-+ *
-+ * \param compositor The libweston compositor whose weston-debug to tear down.
-+ *
-+ * Clears weston_compositor::weston_debug.
-+ *
-+ * \internal
-+ */
-+void
-+weston_debug_compositor_destroy(struct weston_compositor *compositor)
-+{
-+ struct weston_debug_compositor *wdc = compositor->weston_debug;
-+ struct weston_debug_scope *scope;
-+
-+ if (wdc->global)
-+ wl_global_destroy(wdc->global);
-+
-+ wl_list_for_each(scope, &wdc->scope_list, compositor_link)
-+ weston_log("Internal warning: debug scope '%s' has not been destroyed.\n",
-+ scope->name);
-+
-+ /* Remove head to not crash if scope removed later. */
-+ wl_list_remove(&wdc->scope_list);
-+
-+ free(wdc);
-+
-+ compositor->weston_debug = NULL;
-+}
-+
-+/** Enable weston-debug protocol extension
-+ *
-+ * \param compositor The libweston compositor where to enable.
-+ *
-+ * This enables the weston_debug_v1 Wayland protocol extension which any client
-+ * can use to get debug messsages from the compositor.
-+ *
-+ * WARNING: This feature should not be used in production. If a client
-+ * provides a file descriptor that blocks writes, it will block the whole
-+ * compositor indefinitely.
-+ *
-+ * There is no control on which client is allowed to subscribe to debug
-+ * messages. Any and all clients are allowed.
-+ *
-+ * The debug extension is disabled by default, and once enabled, cannot be
-+ * disabled again.
-+ */
-+WL_EXPORT void
-+weston_compositor_enable_debug_protocol(struct weston_compositor *compositor)
-+{
-+ struct weston_debug_compositor *wdc = compositor->weston_debug;
-+
-+ assert(wdc);
-+ if (wdc->global)
-+ return;
-+
-+ wdc->global = wl_global_create(compositor->wl_display,
-+ &weston_debug_v1_interface, 1,
-+ wdc, bind_weston_debug);
-+ if (!wdc->global)
-+ return;
-+
-+ weston_log("WARNING: debug protocol has been enabled. "
-+ "This is a potential denial-of-service attack vector and "
-+ "information leak.\n");
-+}
-+
-+/** Register a new debug stream name, creating a debug scope
-+ *
-+ * \param compositor The libweston compositor where to add.
-+ * \param name The debug stream/scope name; must not be NULL.
-+ * \param desc The debug scope description for humans; must not be NULL.
-+ * \param begin_cb Optional callback when a client subscribes to this scope.
-+ * \param user_data Optional user data pointer for the callback.
-+ * \return A valid pointer on success, NULL on failure.
-+ *
-+ * This function is used to create a debug scope. All debug message printing
-+ * happens for a scope, which allows clients to subscribe to the kind of
-+ * debug messages they want by \c name.
-+ *
-+ * \c name must be unique in the \c weston_compositor instance. \c name and
-+ * \c description must both be provided. The description is printed when a
-+ * client asks for a list of supported debug scopes.
-+ *
-+ * \c begin_cb, if not NULL, is called when a client subscribes to the
-+ * debug scope creating a debug stream. This is for debug scopes that need
-+ * to print messages as a response to a client appearing, e.g. printing a
-+ * list of windows on demand or a static preamble. The argument \c user_data
-+ * is passed in to the callback and is otherwise unused.
-+ *
-+ * For one-shot debug streams, \c begin_cb should finally call
-+ * weston_debug_stream_complete() to close the stream and tell the client
-+ * the printing is complete. Otherwise the client expects more to be written
-+ * to its file descriptor.
-+ *
-+ * The debug scope must be destroyed before destroying the
-+ * \c weston_compositor.
-+ *
-+ * \memberof weston_debug_scope
-+ * \sa weston_debug_stream, weston_debug_scope_cb
-+ */
-+WL_EXPORT struct weston_debug_scope *
-+weston_compositor_add_debug_scope(struct weston_compositor *compositor,
-+ const char *name,
-+ const char *description,
-+ weston_debug_scope_cb begin_cb,
-+ void *user_data)
-+{
-+ struct weston_debug_compositor *wdc;
-+ struct weston_debug_scope *scope;
-+
-+ if (!compositor || !name || !description) {
-+ weston_log("Error: cannot add a debug scope without name or description.\n");
-+ return NULL;
-+ }
-+
-+ wdc = compositor->weston_debug;
-+ if (!wdc) {
-+ weston_log("Error: cannot add debug scope '%s', infra not initialized.\n",
-+ name);
-+ return NULL;
-+ }
-+
-+ if (get_scope(wdc, name)){
-+ weston_log("Error: debug scope named '%s' is already registered.\n",
-+ name);
-+ return NULL;
-+ }
-+
-+ scope = zalloc(sizeof *scope);
-+ if (!scope) {
-+ weston_log("Error adding debug scope '%s': out of memory.\n",
-+ name);
-+ return NULL;
-+ }
-+
-+ scope->name = strdup(name);
-+ scope->desc = strdup(description);
-+ scope->begin_cb = begin_cb;
-+ scope->user_data = user_data;
-+ wl_list_init(&scope->stream_list);
-+
-+ if (!scope->name || !scope->desc) {
-+ weston_log("Error adding debug scope '%s': out of memory.\n",
-+ name);
-+ free(scope->name);
-+ free(scope->desc);
-+ free(scope);
-+ return NULL;
-+ }
-+
-+ wl_list_insert(wdc->scope_list.prev, &scope->compositor_link);
-+
-+ return scope;
-+}
-+
-+/** Destroy a debug scope
-+ *
-+ * \param scope The debug scope to destroy; may be NULL.
-+ *
-+ * Destroys the debug scope, closing all open streams subscribed to it and
-+ * sending them each a \c weston_debug_stream_v1.failure event.
-+ *
-+ * \memberof weston_debug_scope
-+ */
-+WL_EXPORT void
-+weston_debug_scope_destroy(struct weston_debug_scope *scope)
-+{
-+ struct weston_debug_stream *stream;
-+
-+ if (!scope)
-+ return;
-+
-+ while (!wl_list_empty(&scope->stream_list)) {
-+ stream = wl_container_of(scope->stream_list.prev,
-+ stream, scope_link);
-+
-+ stream_close_on_failure(stream, "debug name removed");
-+ }
-+
-+ wl_list_remove(&scope->compositor_link);
-+ free(scope->name);
-+ free(scope->desc);
-+ free(scope);
-+}
-+
-+/** Are there any active subscriptions to the scope?
-+ *
-+ * \param scope The debug scope to check; may be NULL.
-+ * \return True if any streams are open for this scope, false otherwise.
-+ *
-+ * As printing some debugging messages may be relatively expensive, one
-+ * can use this function to determine if there is a need to gather the
-+ * debugging information at all. If this function returns false, all
-+ * printing for this scope is dropped, so gathering the information is
-+ * pointless.
-+ *
-+ * The return value of this function should not be stored, as new clients
-+ * may subscribe to the debug scope later.
-+ *
-+ * If the given scope is NULL, this function will always return false,
-+ * making it safe to use in teardown or destroy code, provided the
-+ * scope is initialized to NULL before creation and set to NULL after
-+ * destruction.
-+ *
-+ * \memberof weston_debug_scope
-+ */
-+WL_EXPORT bool
-+weston_debug_scope_is_enabled(struct weston_debug_scope *scope)
-+{
-+ if (!scope)
-+ return false;
-+
-+ return !wl_list_empty(&scope->stream_list);
-+}
-+
-+/** Write data into a specific debug stream
-+ *
-+ * \param stream The debug stream to write into; must not be NULL.
-+ * \param data[in] Pointer to the data to write.
-+ * \param len Number of bytes to write.
-+ *
-+ * Writes the given data (binary verbatim) into the debug stream.
-+ * If \c len is zero or negative, the write is silently dropped.
-+ *
-+ * Writing is continued until all data has been written or
-+ * a write fails. If the write fails due to a signal, it is re-tried.
-+ * Otherwise on failure, the stream is closed and
-+ * \c weston_debug_stream_v1.failure event is sent to the client.
-+ *
-+ * \memberof weston_debug_stream
-+ */
-+WL_EXPORT void
-+weston_debug_stream_write(struct weston_debug_stream *stream,
-+ const char *data, size_t len)
-+{
-+ ssize_t len_ = len;
-+ ssize_t ret;
-+ int e;
-+
-+ if (stream->fd == -1)
-+ return;
-+
-+ while (len_ > 0) {
-+ ret = write(stream->fd, data, len_);
-+ e = errno;
-+ if (ret < 0) {
-+ if (e == EINTR)
-+ continue;
-+
-+ stream_close_on_failure(stream,
-+ "Error writing %zd bytes: %s (%d)",
-+ len_, strerror(e), e);
-+ break;
-+ }
-+
-+ len_ -= ret;
-+ data += ret;
-+ }
-+}
-+
-+/** Write a formatted string into a specific debug stream (varargs)
-+ *
-+ * \param stream The debug stream to write into.
-+ * \param fmt Printf-style format string.
-+ * \param ap Formatting arguments.
-+ *
-+ * The behavioral details are the same as for weston_debug_stream_write().
-+ *
-+ * \memberof weston_debug_stream
-+ */
-+WL_EXPORT void
-+weston_debug_stream_vprintf(struct weston_debug_stream *stream,
-+ const char *fmt, va_list ap)
-+{
-+ char *str;
-+ int len;
-+
-+ len = vasprintf(&str, fmt, ap);
-+ if (len >= 0) {
-+ weston_debug_stream_write(stream, str, len);
-+ free(str);
-+ } else {
-+ stream_close_on_failure(stream, "Out of memory");
-+ }
-+}
-+
-+/** Write a formatted string into a specific debug stream
-+ *
-+ * \param stream The debug stream to write into.
-+ * \param fmt Printf-style format string and arguments.
-+ *
-+ * The behavioral details are the same as for weston_debug_stream_write().
-+ *
-+ * \memberof weston_debug_stream
-+ */
-+WL_EXPORT void
-+weston_debug_stream_printf(struct weston_debug_stream *stream,
-+ const char *fmt, ...)
-+{
-+ va_list ap;
-+
-+ va_start(ap, fmt);
-+ weston_debug_stream_vprintf(stream, fmt, ap);
-+ va_end(ap);
-+}
-+
-+/** Close the debug stream and send success event
-+ *
-+ * \param stream The debug stream to close.
-+ *
-+ * Closes the debug stream and sends \c weston_debug_stream_v1.complete
-+ * event to the client. This tells the client the debug information dump
-+ * is complete.
-+ *
-+ * \memberof weston_debug_stream
-+ */
-+WL_EXPORT void
-+weston_debug_stream_complete(struct weston_debug_stream *stream)
-+{
-+ stream_close_unlink(stream);
-+ weston_debug_stream_v1_send_complete(stream->resource);
-+}
-+
-+/** Write debug data for a scope
-+ *
-+ * \param scope The debug scope to write for; may be NULL, in which case
-+ * nothing will be written.
-+ * \param data[in] Pointer to the data to write.
-+ * \param len Number of bytes to write.
-+ *
-+ * Writes the given data to all subscribed clients' streams.
-+ *
-+ * The behavioral details for each stream are the same as for
-+ * weston_debug_stream_write().
-+ *
-+ * \memberof weston_debug_scope
-+ */
-+WL_EXPORT void
-+weston_debug_scope_write(struct weston_debug_scope *scope,
-+ const char *data, size_t len)
-+{
-+ struct weston_debug_stream *stream;
-+
-+ if (!scope)
-+ return;
-+
-+ wl_list_for_each(stream, &scope->stream_list, scope_link)
-+ weston_debug_stream_write(stream, data, len);
-+}
-+
-+/** Write a formatted string for a scope (varargs)
-+ *
-+ * \param scope The debug scope to write for; may be NULL, in which case
-+ * nothing will be written.
-+ * \param fmt Printf-style format string.
-+ * \param ap Formatting arguments.
-+ *
-+ * Writes to formatted string to all subscribed clients' streams.
-+ *
-+ * The behavioral details for each stream are the same as for
-+ * weston_debug_stream_write().
-+ *
-+ * \memberof weston_debug_scope
-+ */
-+WL_EXPORT void
-+weston_debug_scope_vprintf(struct weston_debug_scope *scope,
-+ const char *fmt, va_list ap)
-+{
-+ static const char oom[] = "Out of memory";
-+ char *str;
-+ int len;
-+
-+ if (!weston_debug_scope_is_enabled(scope))
-+ return;
-+
-+ len = vasprintf(&str, fmt, ap);
-+ if (len >= 0) {
-+ weston_debug_scope_write(scope, str, len);
-+ free(str);
-+ } else {
-+ weston_debug_scope_write(scope, oom, sizeof oom - 1);
-+ }
-+}
-+
-+/** Write a formatted string for a scope
-+ *
-+ * \param scope The debug scope to write for; may be NULL, in which case
-+ * nothing will be written.
-+ * \param fmt Printf-style format string and arguments.
-+ *
-+ * Writes to formatted string to all subscribed clients' streams.
-+ *
-+ * The behavioral details for each stream are the same as for
-+ * weston_debug_stream_write().
-+ *
-+ * \memberof weston_debug_scope
-+ */
-+WL_EXPORT void
-+weston_debug_scope_printf(struct weston_debug_scope *scope,
-+ const char *fmt, ...)
-+{
-+ va_list ap;
-+
-+ va_start(ap, fmt);
-+ weston_debug_scope_vprintf(scope, fmt, ap);
-+ va_end(ap);
-+}
-+
-+/** Write debug scope name and current time into string
-+ *
-+ * \param scope[in] debug scope; may be NULL
-+ * \param buf[out] Buffer to store the string.
-+ * \param len Available size in the buffer in bytes.
-+ * \return \c buf
-+ *
-+ * Reads the current local wall-clock time and formats it into a string.
-+ * and append the debug scope name to it, if a scope is available.
-+ * The string is NUL-terminated, even if truncated.
-+ */
-+WL_EXPORT char *
-+weston_debug_scope_timestamp(struct weston_debug_scope *scope,
-+ char *buf, size_t len)
-+{
-+ struct timeval tv;
-+ struct tm *bdt;
-+ char string[128];
-+ size_t ret = 0;
-+
-+ gettimeofday(&tv, NULL);
-+
-+ bdt = localtime(&tv.tv_sec);
-+ if (bdt)
-+ ret = strftime(string, sizeof string,
-+ "%Y-%m-%d %H:%M:%S", bdt);
-+
-+ if (ret > 0) {
-+ snprintf(buf, len, "[%s.%03ld][%s]", string,
-+ tv.tv_usec / 1000,
-+ (scope) ? scope->name : "no scope");
-+ } else {
-+ snprintf(buf, len, "[?][%s]",
-+ (scope) ? scope->name : "no scope");
-+ }
-+
-+ return buf;
-+}
-diff --git a/libweston/weston-debug.h b/libweston/weston-debug.h
-new file mode 100644
-index 00000000..c76cec85
---- /dev/null
-+++ b/libweston/weston-debug.h
-@@ -0,0 +1,107 @@
-+/*
-+ * Copyright © 2017 Pekka Paalanen <pq@iki.fi>
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining
-+ * a copy of this software and associated documentation files (the
-+ * "Software"), to deal in the Software without restriction, including
-+ * without limitation the rights to use, copy, modify, merge, publish,
-+ * distribute, sublicense, and/or sell copies of the Software, and to
-+ * permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ *
-+ * The above copyright notice and this permission notice (including the
-+ * next paragraph) shall be included in all copies or substantial
-+ * portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
-+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
-+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-+ * SOFTWARE.
-+ */
-+
-+#ifndef WESTON_DEBUG_H
-+#define WESTON_DEBUG_H
-+
-+#include <stdbool.h>
-+#include <stdlib.h>
-+#include <stdarg.h>
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+struct weston_compositor;
-+
-+void
-+weston_compositor_enable_debug_protocol(struct weston_compositor *);
-+
-+struct weston_debug_scope;
-+struct weston_debug_stream;
-+
-+/** weston_debug_scope callback
-+ *
-+ * \param stream The debug stream.
-+ * \param user_data The \c user_data argument given to
-+ * weston_compositor_add_debug_scope()
-+ *
-+ * \memberof weston_debug_scope
-+ * \sa weston_debug_stream
-+ */
-+typedef void (*weston_debug_scope_cb)(struct weston_debug_stream *stream,
-+ void *user_data);
-+
-+struct weston_debug_scope *
-+weston_compositor_add_debug_scope(struct weston_compositor *compositor,
-+ const char *name,
-+ const char *description,
-+ weston_debug_scope_cb begin_cb,
-+ void *user_data);
-+
-+void
-+weston_debug_scope_destroy(struct weston_debug_scope *scope);
-+
-+bool
-+weston_debug_scope_is_enabled(struct weston_debug_scope *scope);
-+
-+void
-+weston_debug_scope_write(struct weston_debug_scope *scope,
-+ const char *data, size_t len);
-+
-+void
-+weston_debug_scope_vprintf(struct weston_debug_scope *scope,
-+ const char *fmt, va_list ap);
-+
-+void
-+weston_debug_scope_printf(struct weston_debug_scope *scope,
-+ const char *fmt, ...)
-+ __attribute__ ((format (printf, 2, 3)));
-+
-+void
-+weston_debug_stream_write(struct weston_debug_stream *stream,
-+ const char *data, size_t len);
-+
-+void
-+weston_debug_stream_vprintf(struct weston_debug_stream *stream,
-+ const char *fmt, va_list ap);
-+
-+void
-+weston_debug_stream_printf(struct weston_debug_stream *stream,
-+ const char *fmt, ...)
-+ __attribute__ ((format (printf, 2, 3)));
-+
-+void
-+weston_debug_stream_complete(struct weston_debug_stream *stream);
-+
-+char *
-+weston_debug_scope_timestamp(struct weston_debug_scope *scope,
-+ char *buf, size_t len);
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif /* WESTON_DEBUG_H */
---
-2.16.2
-