From 1c7d6584a7811b7785ae5c1e378f14b5ba0971cf Mon Sep 17 00:00:00 2001 From: takeshi_hoshina Date: Mon, 2 Nov 2020 11:07:33 +0900 Subject: basesystem-jj recipes --- ...n-add-weston_debug-API-and-implementation.patch | 958 --------------------- 1 file changed, 958 deletions(-) delete mode 100644 bsp/meta-synopsys/recipes-graphics/wayland/weston/1006-libweston-add-weston_debug-API-and-implementation.patch (limited to 'bsp/meta-synopsys/recipes-graphics/wayland/weston/1006-libweston-add-weston_debug-API-and-implementation.patch') 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 -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 - -append the debug scope name along with the timestamp in -weston_debug_scope_timestamp API - -Signed-off-by: Maniraj Devadoss -Reviewed-by: Pekka Paalanen - -Add explicit advertisement of debug scope names. - -Signed-off-by: Daniel Stone -Reviewed-by: Emre Ucan ---- - 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 -+ * 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 -+#include -+#include -+#include -+#include -+#include -+ -+/** 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 -+ * -+ * 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 -+#include -+#include -+ -+#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 - -- cgit 1.2.3-korg