diff options
author | Uli Schlachter <psychon@znc.in> | 2015-03-18 21:43:05 +0100 |
---|---|---|
committer | Uli Schlachter <psychon@znc.in> | 2015-03-18 21:43:05 +0100 |
commit | 68cf24822c354be1e960ad9198cd187eba122e06 (patch) | |
tree | 6f3380e5c10a3ef5450b905870ef03175176c5a5 /src |
Initial version
This is an initial prototype on how this library might look like. All the parts
which should be auto-generated from XCB's XML protocol description are missing.
The C parts should work fine, but are completely untested.
Signed-off-by: Uli Schlachter <psychon@znc.in>
Diffstat (limited to 'src')
-rw-r--r-- | src/errors.h | 47 | ||||
-rw-r--r-- | src/static_tables.c | 73 | ||||
-rw-r--r-- | src/xcb_errors.c | 206 | ||||
-rw-r--r-- | src/xcb_errors.h | 116 |
4 files changed, 442 insertions, 0 deletions
diff --git a/src/errors.h b/src/errors.h new file mode 100644 index 0000000..c48cf81 --- /dev/null +++ b/src/errors.h @@ -0,0 +1,47 @@ +#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. + */ + +struct static_extension_info_t { + uint16_t num_minor; + uint8_t num_events; + uint8_t num_errors; + const char *strings_minor; + const char *strings_events; + const char *strings_errors; +}; + +extern const char *unknown_major_code[256]; +extern const char *unknown_error_code[256]; +extern const char *unknown_event_code[256]; + +const char *xproto_get_name_for_major_code(uint8_t major_code); +const char *xproto_get_name_for_event(uint8_t event_code); +const char *xproto_get_name_for_error(uint8_t error_code); +struct static_extension_info_t find_static_info_for_extension(const char *name); + +#endif /* __ERRORS_H__ */ diff --git a/src/static_tables.c b/src/static_tables.c new file mode 100644 index 0000000..67c9481 --- /dev/null +++ b/src/static_tables.c @@ -0,0 +1,73 @@ +/* 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" + +const char *unknown_major_code[256] = { +#define ENTRY(i) "Unknown major code " #i, +#include "static_tables.inc" +#undef ENTRY +}; + +const char *unknown_error_code[256] = { +#define ENTRY(i) "Unknown error " #i, +#include "static_tables.inc" +#undef ENTRY +}; + +const char *unknown_event_code[256] = { +#define ENTRY(i) "Unknown event " #i, +#include "static_tables.inc" +#undef ENTRY +}; + +#warning TODO: Implement these +const char *xproto_get_name_for_major_code(uint8_t major_code) { + (void) major_code; + return NULL; +} + +const char *xproto_get_name_for_event(uint8_t event_code) { + (void) event_code; + return NULL; +} + +const char *xproto_get_name_for_error(uint8_t error_code) { + (void) error_code; + return NULL; +} +struct static_extension_info_t find_static_info_for_extension(const char *name) { + struct static_extension_info_t info = { + .num_minor = 0, + .num_events = 0, + .num_errors = 0, + .strings_minor = NULL, + .strings_events = NULL, + .strings_errors = NULL + }; + (void) name; + return info; +} diff --git a/src/xcb_errors.c b/src/xcb_errors.c new file mode 100644 index 0000000..2842807 --- /dev/null +++ b/src/xcb_errors.c @@ -0,0 +1,206 @@ +/* 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 <stdlib.h> +#include <string.h> + +struct extension_info_t { + struct extension_info_t *next; + struct static_extension_info_t static_info; + uint8_t major_opcode; + uint8_t first_event; + uint8_t first_error; + char *name; +}; + +struct xcb_errors_context_t { + xcb_connection_t *conn; + 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; +} + +static int register_extension(xcb_errors_context_t *ctx, const char *ext) +{ + struct extension_info_t *info; + struct static_extension_info_t static_info; + xcb_query_extension_reply_t *reply; + char *ext_dup; + + ext_dup = strdup(ext); + info = calloc(1, sizeof(*info)); + reply = xcb_query_extension_reply(ctx->conn, + xcb_query_extension(ctx->conn, strlen(ext), ext), NULL); + static_info = find_static_info_for_extension(ext); + + if (!info || !reply || !ext_dup || !reply->present || (static_info.num_minor == 0)) { + free(info); + free(reply); + free(ext_dup); + /* This is used to indicate an unsupported extension */ + if (static_info.num_minor == 0) + return 0; + return -1; + } + + info->name = ext_dup; + 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; + xcb_list_extensions_reply_t *reply = NULL; + xcb_str_iterator_t iter; + + if ((*c = calloc(1, sizeof(*c))) == NULL) + goto error_out; + + ctx = *c; + ctx->conn = conn; + ctx->extensions = NULL; + + reply = xcb_list_extensions_reply(conn, + xcb_list_extensions(conn), NULL); + if (!reply) + goto error_out; + + iter = xcb_list_extensions_names_iterator(reply); + while (iter.rem > 0) { + int status = register_extension(ctx, xcb_str_name(iter.data)); + if (status < 0) + goto error_out; + xcb_str_next(&iter); + } + + return 0; + +error_out: + free(reply); + 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->name); + 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 = ctx->extensions; + const char *result = xproto_get_name_for_major_code(major_code); + if (result) + return result; + + while (info && info->major_opcode != major_code) + info = info->next; + + if (info == NULL) + return unknown_major_code[major_code]; + + return 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 = 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_event(xcb_errors_context_t *ctx, + uint8_t event_code) +{ + struct extension_info_t *info = ctx->extensions; + const char *result = xproto_get_name_for_event(event_code); + if (result) + return result; + + while (info && (info->first_event > event_code + || info->first_event + info->static_info.num_events <= event_code)) + info = info->next; + + if (info == NULL) + return unknown_event_code[event_code]; + + return get_strings_entry(info->static_info.strings_events, event_code - info->first_event); +} + +const char *xcb_errors_get_name_for_error(xcb_errors_context_t *ctx, + uint8_t error_code) +{ + struct extension_info_t *info = ctx->extensions; + const char *result = xproto_get_name_for_error(error_code); + if (result) + return result; + + while (info && (info->first_error > error_code + || info->first_error + info->static_info.num_errors <= error_code)) + info = info->next; + + if (info == NULL) + return unknown_error_code[error_code]; + + return get_strings_entry(info->static_info.strings_errors, error_code - info->first_error); +} diff --git a/src/xcb_errors.h b/src/xcb_errors.h new file mode 100644 index 0000000..a9c8d0d --- /dev/null +++ b/src/xcb_errors.h @@ -0,0 +1,116 @@ +#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 <xcb/xcb.h> + +#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, some other value otherwise. + */ +int xcb_errors_context_new(xcb_connection_t *conn, xcb_errors_context_t **ctx); + +/** + * Freed 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. + * + * @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 or NULL. + * + * @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. + */ +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 event. + * + * @param ctx An errors context, created with @ref xcb_errors_context_new () + * @param event_code The response_type of an event. + * @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_event(xcb_errors_context_t *ctx, + uint8_t event_code); + +/** + * 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. + * @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); + +#ifdef __cplusplus +} +#endif + +#endif /* __XCB_ERRORS_H__ */ |