From bc5a4cf5fcc70e30028ff8fa91dca075896b2764 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Wed, 13 Dec 2023 20:17:13 +0100 Subject: Include all libxcb utils (wm, util, image, errors, cursor) --- depends/libxcb-errors/xcb/errors.h | 50 ++++++ depends/libxcb-errors/xcb/xcb_errors.c | 291 +++++++++++++++++++++++++++++++++ depends/libxcb-errors/xcb/xcb_errors.h | 157 ++++++++++++++++++ 3 files changed, 498 insertions(+) create mode 100644 depends/libxcb-errors/xcb/errors.h create mode 100644 depends/libxcb-errors/xcb/xcb_errors.c create mode 100644 depends/libxcb-errors/xcb/xcb_errors.h (limited to 'depends/libxcb-errors') diff --git a/depends/libxcb-errors/xcb/errors.h b/depends/libxcb-errors/xcb/errors.h new file mode 100644 index 0000000..ec4fe88 --- /dev/null +++ b/depends/libxcb-errors/xcb/errors.h @@ -0,0 +1,50 @@ +#ifndef __ERRORS_H__ +#define __ERRORS_H__ + +/* Copyright © 2015 Uli Schlachter + * + * 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 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 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. + * + * Except as contained in this notice, the names of the authors or their + * institutions shall not be used in advertising or otherwise to promote the + * sale, use or other dealings in this Software without prior written + * authorization from the authors. + */ + +#include "xcb_errors.h" + +struct static_extension_info_t { + uint16_t num_minor; + uint16_t num_xge_events; + uint8_t num_events; + uint8_t num_errors; + const char *strings_minor; + const char *strings_xge_events; + const char *strings_events; + const char *strings_errors; + const char *name; +}; + +extern const struct static_extension_info_t xproto_info; + +int register_extensions(xcb_errors_context_t *ctx, xcb_connection_t *conn); +int register_extension(xcb_errors_context_t *ctx, xcb_connection_t *conn, + xcb_query_extension_cookie_t cookie, + const struct static_extension_info_t *static_info); + +#endif /* __ERRORS_H__ */ diff --git a/depends/libxcb-errors/xcb/xcb_errors.c b/depends/libxcb-errors/xcb/xcb_errors.c new file mode 100644 index 0000000..2eedc34 --- /dev/null +++ b/depends/libxcb-errors/xcb/xcb_errors.c @@ -0,0 +1,291 @@ +/* Copyright © 2015 Uli Schlachter + * + * 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 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 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. + * + * Except as contained in this notice, the names of the authors or their + * institutions shall not be used in advertising or otherwise to promote the + * sale, use or other dealings in this Software without prior written + * authorization from the authors. + */ + +#include "xcb_errors.h" +#include "errors.h" +#include +#include + +#define CHECK_CONTEXT(ctx) do { \ + if ((ctx) == NULL) \ + return "xcb-errors API misuse: context argument is NULL"; \ +} while (0) + +struct extension_info_t { + struct extension_info_t *next; + const struct static_extension_info_t *static_info; + uint8_t major_opcode; + uint8_t first_event; + uint8_t first_error; +}; + +struct xcb_errors_context_t { + struct extension_info_t *extensions; +}; + +static const char *get_strings_entry(const char *strings, unsigned int index) { + while (index-- > 0) + strings += strlen(strings) + 1; + return strings; +} + +int register_extension(xcb_errors_context_t *ctx, xcb_connection_t *conn, + xcb_query_extension_cookie_t cookie, + const struct static_extension_info_t *static_info) +{ + struct extension_info_t *info; + xcb_query_extension_reply_t *reply; + + info = calloc(1, sizeof(*info)); + reply = xcb_query_extension_reply(conn, cookie, NULL); + + if (!info || !reply || !reply->present) { + int not_present = reply && !reply->present; + free(info); + free(reply); + if (not_present) + return 0; + return -1; + } + + info->static_info = static_info; + info->major_opcode = reply->major_opcode; + info->first_event = reply->first_event; + info->first_error = reply->first_error; + + info->next = ctx->extensions; + ctx->extensions = info; + free(reply); + + return 0; +} + +int xcb_errors_context_new(xcb_connection_t *conn, xcb_errors_context_t **c) +{ + xcb_errors_context_t *ctx = NULL; + + if ((*c = calloc(1, sizeof(*c))) == NULL) + goto error_out; + + ctx = *c; + ctx->extensions = NULL; + + if (register_extensions(ctx, conn) != 0) + goto error_out; + + return 0; + +error_out: + xcb_errors_context_free(ctx); + *c = NULL; + return -1; +} + +void xcb_errors_context_free(xcb_errors_context_t *ctx) +{ + struct extension_info_t *info; + + if (ctx == NULL) + return; + + info = ctx->extensions; + while (info) { + struct extension_info_t *prev = info; + info = info->next; + free(prev); + } + + free(ctx); +} + +const char *xcb_errors_get_name_for_major_code(xcb_errors_context_t *ctx, + uint8_t major_code) +{ + struct extension_info_t *info; + + CHECK_CONTEXT(ctx); + + info = ctx->extensions; + while (info && info->major_opcode != major_code) + info = info->next; + + if (info == NULL) + return get_strings_entry(xproto_info.strings_minor, major_code); + + return info->static_info->name; +} + +const char *xcb_errors_get_name_for_minor_code(xcb_errors_context_t *ctx, + uint8_t major_code, + uint16_t minor_code) +{ + struct extension_info_t *info; + + CHECK_CONTEXT(ctx); + + info = ctx->extensions; + while (info && info->major_opcode != major_code) + info = info->next; + + if (info == NULL || minor_code >= info->static_info->num_minor) + return NULL; + + return get_strings_entry(info->static_info->strings_minor, minor_code); +} + +const char *xcb_errors_get_name_for_xge_event(xcb_errors_context_t *ctx, + uint8_t major_code, uint16_t event_type) +{ + struct extension_info_t *info; + + CHECK_CONTEXT(ctx); + + info = ctx->extensions; + while (info && info->major_opcode != major_code) + info = info->next; + + if (info == NULL || event_type >= info->static_info->num_xge_events) + return NULL; + + return get_strings_entry(info->static_info->strings_xge_events, event_type); +} + +const char *xcb_errors_get_name_for_core_event(xcb_errors_context_t *ctx, + uint8_t event_code, const char **extension) +{ + struct extension_info_t *best = NULL; + struct extension_info_t *next; + + event_code &= 0x7f; + if (extension) + *extension = NULL; + + CHECK_CONTEXT(ctx); + + /* Find the extension with the largest first_event <= event_code. Thanks + * to this we do the right thing if the server only supports an older + * version of some extension which had less events. + */ + next = ctx->extensions; + while (next) { + struct extension_info_t *current = next; + next = next->next; + + if (current->first_event > event_code) + continue; + if (best != NULL && best->first_event > current->first_event) + continue; + best = current; + } + + if (best == NULL || best->first_event == 0 + || event_code - best->first_event >= best->static_info->num_events) { + /* Nothing found */ + return get_strings_entry(xproto_info.strings_events, event_code); + } + + if (extension) + *extension = best->static_info->name; + return get_strings_entry(best->static_info->strings_events, event_code - best->first_event); +} + +const char *xcb_errors_get_name_for_error(xcb_errors_context_t *ctx, + uint8_t error_code, const char **extension) +{ + struct extension_info_t *best = NULL; + struct extension_info_t *next; + + if (extension) + *extension = NULL; + + CHECK_CONTEXT(ctx); + + /* Find the extension with the largest first_error <= error_code. Thanks + * to this we do the right thing if the server only supports an older + * version of some extension which had less events. + */ + next = ctx->extensions; + while (next) { + struct extension_info_t *current = next; + next = next->next; + + if (current->first_error > error_code) + continue; + if (best != NULL && best->first_error > current->first_error) + continue; + best = current; + } + + if (best == NULL || best->first_error == 0 + || error_code - best->first_error >= best->static_info->num_errors) { + /* Nothing found */ + return get_strings_entry(xproto_info.strings_errors, error_code); + } + + if (extension) + *extension = best->static_info->name; + return get_strings_entry(best->static_info->strings_errors, error_code - best->first_error); +} + +const char *xcb_errors_get_name_for_xcb_event(xcb_errors_context_t *ctx, + xcb_generic_event_t *event, const char **extension) +{ + struct extension_info_t *xkb; + uint8_t response_type; + + if (extension) + *extension = NULL; + + CHECK_CONTEXT(ctx); + + /* Find the xkb extension, if present */ + xkb = ctx->extensions; + while (xkb != NULL && strcmp(xkb->static_info->name, "xkb") != 0) + xkb = xkb->next; + + response_type = event->response_type & 0x7f; + if (response_type == XCB_GE_GENERIC) { + /* XGE offers extension's major code and event sub-type. */ + xcb_ge_generic_event_t *ge = (void *) event; + if (extension) + *extension = xcb_errors_get_name_for_major_code(ctx, + ge->extension); + return xcb_errors_get_name_for_xge_event(ctx, + ge->extension, ge->event_type); + } + if (xkb != NULL && xkb->first_event != 0 + && response_type == xkb->first_event) { + /* There is no nice struct that defines the common fields for + * XKB events, but the event type is always in the second byte. + * In xcb_generic_event_t, this is the pad0 field. + */ + if (extension) + *extension = xkb->static_info->name; + return xcb_errors_get_name_for_xge_event(ctx, + xkb->major_opcode, event->pad0); + } + /* Generic case, decide only based on the response_type. */ + return xcb_errors_get_name_for_core_event(ctx, response_type, extension); +} diff --git a/depends/libxcb-errors/xcb/xcb_errors.h b/depends/libxcb-errors/xcb/xcb_errors.h new file mode 100644 index 0000000..baa0ec6 --- /dev/null +++ b/depends/libxcb-errors/xcb/xcb_errors.h @@ -0,0 +1,157 @@ +#ifndef __XCB_ERRORS_H__ +#define __XCB_ERRORS_H__ + +/* Copyright © 2015 Uli Schlachter + * + * 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 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 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. + * + * Except as contained in this notice, the names of the authors or their + * institutions shall not be used in advertising or otherwise to promote the + * sale, use or other dealings in this Software without prior written + * authorization from the authors. + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * A context for using this library. + * + * Create a context with @ref xcb_errors_context_new () and destroy it with @ref + * xcb_errors_context_free (). Except for @ref xcb_errors_context_free (), all + * functions in this library are thread-safe and can be called from multiple + * threads at the same time, even on the same context. + */ +typedef struct xcb_errors_context_t xcb_errors_context_t; + +/** + * Create a new @ref xcb_errors_context_t. + * + * @param conn A XCB connection which will be used until you destroy the context + * with @ref xcb_errors_context_free (). + * @param ctx A pointer to an xcb_cursor_context_t* which will be modified to + * refer to the newly created context. + * @return 0 on success, -1 otherwise. This function may fail due to memory + * allocation failures or if the connection ends up in an error state. + */ +int xcb_errors_context_new(xcb_connection_t *conn, xcb_errors_context_t **ctx); + +/** + * Free the @ref xcb_cursor_context_t. + * + * @param ctx The context to free. + */ +void xcb_errors_context_free(xcb_errors_context_t *ctx); + +/** + * Get the name corresponding to some major code. This is either the name of + * some core request or the name of the extension that owns this major code. + * + * @param ctx An errors context, created with @ref xcb_errors_context_new () + * @param major_code The major code + * @return A string allocated in static storage that contains a name for this + * major code. This will never return NULL, but other functions in this library + * may. + */ +const char *xcb_errors_get_name_for_major_code(xcb_errors_context_t *ctx, + uint8_t major_code); + +/** + * Get the name corresponding to some minor code. When the major_code does not + * belong to any extension or the minor_code is not assigned inside this + * extension, NULL is returned. + * + * @param ctx An errors context, created with @ref xcb_errors_context_new () + * @param major_code The major code under which to look up the minor code + * @param major_code The minor code + * @return A string allocated in static storage that contains a name for this + * major code or NULL for unknown codes. + */ +const char *xcb_errors_get_name_for_minor_code(xcb_errors_context_t *ctx, + uint8_t major_code, + uint16_t minor_code); + +/** + * Get the name corresponding to some core event code. If possible, you should + * use @ref xcb_errors_get_name_for_xcb_event instead. + * + * @param ctx An errors context, created with @ref xcb_errors_context_new () + * @param event_code The response_type of an event. + * @param extension Will be set to the name of the extension that generated this + * event or NULL for unknown events or core X11 events. This argument may be + * NULL. + * @return A string allocated in static storage that contains a name for this + * major code. This will never return NULL, but other functions in this library + * may. + */ +const char *xcb_errors_get_name_for_core_event(xcb_errors_context_t *ctx, + uint8_t event_code, const char **extension); + +/** + * Get the name corresponding to some XGE or XKB event. XKB does not actually + * use the X generic event extension, but implements its own event multiplexing. + * This function also handles XKB's xkbType events as a event_type. + * + * If possible, you should use @ref xcb_errors_get_name_for_xcb_event instead. + * + * @param ctx An errors context, created with @ref xcb_errors_context_new () + * @param major_code The extension's major code + * @param event_type The type of the event in that extension. + * @return A string allocated in static storage that contains a name for this + * event or NULL for unknown event types. + */ +const char *xcb_errors_get_name_for_xge_event(xcb_errors_context_t *ctx, + uint8_t major_code, uint16_t event_type); + +/** + * Get a human printable name describing the type of some event. + * + * @param ctx An errors context, created with @ref xcb_errors_context_new () + * @param event The event to investigate. + * @param extension Will be set to the name of the extension that generated this + * event or NULL for unknown events or core X11 events. This argument may be + * NULL. + * @return A string allocated in static storage that contains a name for this + * event or NULL for unknown event types. + */ +const char *xcb_errors_get_name_for_xcb_event(xcb_errors_context_t *ctx, + xcb_generic_event_t *event, const char **extension); + +/** + * Get the name corresponding to some error. + * + * @param ctx An errors context, created with @ref xcb_errors_context_new () + * @param error_code The error_code of an error reply. + * @param extension Will be set to the name of the extension that generated this + * event or NULL for unknown errors or core X11 errors. This argument may be + * NULL. + * @return A string allocated in static storage that contains a name for this + * major code. This will never return NULL, but other functions in this library + * may. + */ +const char *xcb_errors_get_name_for_error(xcb_errors_context_t *ctx, + uint8_t error_code, const char **extension); + +#ifdef __cplusplus +} +#endif + +#endif /* __XCB_ERRORS_H__ */ -- cgit v1.2.3