summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUli Schlachter <psychon@znc.in>2015-04-05 13:49:07 +0200
committerUli Schlachter <psychon@znc.in>2015-04-05 13:49:07 +0200
commit964a2b53500ed9af63528375d48d6805c5c11998 (patch)
tree02fe66bd363d632ad5947a99eab79fe53c7a1790
parent63ca7f6c8814ee4974a1ae784ab06eca01e6dff2 (diff)
Add a function for figuring out information about an event struct
Signed-off-by: Uli Schlachter <psychon@znc.in>
-rw-r--r--src/xcb_errors.c33
-rw-r--r--src/xcb_errors.h14
-rw-r--r--tests/test.c102
3 files changed, 134 insertions, 15 deletions
diff --git a/src/xcb_errors.c b/src/xcb_errors.c
index 266159d..b796ae4 100644
--- a/src/xcb_errors.c
+++ b/src/xcb_errors.c
@@ -223,3 +223,36 @@ const char *xcb_errors_get_name_for_error(xcb_errors_context_t *ctx,
*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 = ctx->extensions;
+
+ /* Find the xkb extension, if present */
+ while (xkb != NULL && strcmp(xkb->static_info->name, "xkb") != 0)
+ xkb = xkb->next;
+
+ if (event->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
+ && event->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_event(ctx, event->response_type, extension);
+}
diff --git a/src/xcb_errors.h b/src/xcb_errors.h
index 1c8b66a..378913b 100644
--- a/src/xcb_errors.h
+++ b/src/xcb_errors.h
@@ -116,6 +116,20 @@ 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 ()
diff --git a/tests/test.c b/tests/test.c
index 7d7614b..15f1f4f 100644
--- a/tests/test.c
+++ b/tests/test.c
@@ -102,16 +102,88 @@ static int check_event(xcb_errors_context_t *ctx, uint8_t event,
ret |= check_strings(actual, tmp,
"For event %d: Passing NULL made a difference: %s vs %s\n",
event, actual, tmp);
+
+ /* The wire_event we construct isn't a proper GE event */
+ if (event != XCB_GE_GENERIC) {
+ xcb_generic_event_t wire_event = {
+ .response_type = event
+ };
+
+ actual = xcb_errors_get_name_for_xcb_event(ctx, &wire_event, &actual_extension);
+ ret |= check_strings(expected_extension, actual_extension,
+ "For xcb wire event %d: Expected ext %s, got %s\n",
+ event, expected_extension, actual_extension);
+ ret |= check_strings(expected, actual,
+ "For xcb wire event %d: Expected %s, got %s\n",
+ event, expected, actual);
+
+ tmp = xcb_errors_get_name_for_xcb_event(ctx, &wire_event, NULL);
+ ret |= check_strings(actual, tmp,
+ "For xcb wire event %d: Passing NULL made a difference: %s vs %s\n",
+ event, actual, tmp);
+ }
return ret;
}
static int check_xge_event(xcb_errors_context_t *ctx, uint8_t major_code,
- uint16_t event_type, const char *expected)
+ uint16_t event_type, const char *expected, const char *expected_extension)
{
- const char *actual = xcb_errors_get_name_for_xge_event(ctx, major_code, event_type);
- return check_strings(expected, actual,
+ xcb_ge_generic_event_t wire_event = {
+ .response_type = XCB_GE_GENERIC,
+ .extension = major_code,
+ .event_type = event_type
+ };
+ const char *actual, *actual_extension, *tmp;
+ int ret = 0;
+
+ actual = xcb_errors_get_name_for_xge_event(ctx, major_code, event_type);
+ ret |= check_strings(expected, actual,
"For xge event (%d, %d): Expected %s, got %s\n",
major_code, event_type, expected, actual);
+
+ actual = xcb_errors_get_name_for_xcb_event(ctx, (void *) &wire_event, &actual_extension);
+ ret |= check_strings(expected_extension, actual_extension,
+ "For xcb xge wire event %d: Expected ext %s, got %s\n",
+ event_type, expected_extension, actual_extension);
+ ret |= check_strings(expected, actual,
+ "For xcb xge wire event %d: Expected %s, got %s\n",
+ event_type, expected, actual);
+
+ tmp = xcb_errors_get_name_for_xcb_event(ctx, (void *) &wire_event, NULL);
+ ret |= check_strings(actual, tmp,
+ "For xcb xge wire event %d: Passing NULL made a difference: %s vs %s\n",
+ event_type, actual, tmp);
+ return ret;
+}
+
+static int check_xkb_event(xcb_errors_context_t *ctx, uint8_t major_code, uint8_t first_event,
+ uint16_t event_type, const char *expected)
+{
+ xcb_generic_event_t wire_event = {
+ .response_type = first_event,
+ .pad0 = event_type
+ };
+ const char *actual, *actual_extension, *tmp;
+ int ret = 0;
+
+ actual = xcb_errors_get_name_for_xge_event(ctx, major_code, event_type);
+ ret |= check_strings(expected, actual,
+ "For xkb event (%d, %d): Expected %s, got %s\n",
+ major_code, event_type, expected, actual);
+
+ actual = xcb_errors_get_name_for_xcb_event(ctx, &wire_event, &actual_extension);
+ ret |= check_strings("xkb", actual_extension,
+ "For xcb xkb wire event %d: Expected ext xkb, got %s\n",
+ event_type, actual_extension);
+ ret |= check_strings(expected, actual,
+ "For xcb xkb wire event %d: Expected %s, got %s\n",
+ event_type, expected, actual);
+
+ tmp = xcb_errors_get_name_for_xcb_event(ctx, &wire_event, NULL);
+ ret |= check_strings(actual, tmp,
+ "For xcb xkb wire event %d: Passing NULL made a difference: %s vs %s\n",
+ event_type, actual, tmp);
+ return ret;
}
static int check_minor(xcb_errors_context_t *ctx, uint8_t major, uint16_t minor, const char *expected)
@@ -191,12 +263,12 @@ static int test_xinput(xcb_connection_t *c, xcb_errors_context_t *ctx)
err |= check_error(ctx, reply->first_error + 4, "Class", "Input");
err |= check_event(ctx, reply->first_event + 0, "DeviceValuator", "Input");
err |= check_event(ctx, reply->first_event + 16, "DevicePropertyNotify", "Input");
- err |= check_xge_event(ctx, reply->major_opcode, 0, "Unknown (0)");
- err |= check_xge_event(ctx, reply->major_opcode, 1, "DeviceChanged");
- err |= check_xge_event(ctx, reply->major_opcode, 26, "BarrierLeave");
- err |= check_xge_event(ctx, reply->major_opcode, 27, NULL);
- err |= check_xge_event(ctx, reply->major_opcode, 1337, NULL);
- err |= check_xge_event(ctx, reply->major_opcode, 0xffff, NULL);
+ err |= check_xge_event(ctx, reply->major_opcode, 0, "Unknown (0)", "Input");
+ err |= check_xge_event(ctx, reply->major_opcode, 1, "DeviceChanged", "Input");
+ err |= check_xge_event(ctx, reply->major_opcode, 26, "BarrierLeave", "Input");
+ err |= check_xge_event(ctx, reply->major_opcode, 27, NULL, "Input");
+ err |= check_xge_event(ctx, reply->major_opcode, 1337, NULL, "Input");
+ err |= check_xge_event(ctx, reply->major_opcode, 0xffff, NULL, "Input");
err |= check_minor(ctx, reply->major_opcode, 0, "Unknown (0)");
err |= check_minor(ctx, reply->major_opcode, 1, "GetExtensionVersion");
err |= check_minor(ctx, reply->major_opcode, 47, "XIQueryVersion");
@@ -224,12 +296,12 @@ static int test_xkb(xcb_connection_t *c, xcb_errors_context_t *ctx)
err |= check_request(ctx, reply->major_opcode, "xkb");
err |= check_error(ctx, reply->first_error + 0, "Keyboard", "xkb");
- err |= check_xge_event(ctx, reply->major_opcode, 0, "NewKeyboardNotify");
- err |= check_xge_event(ctx, reply->major_opcode, 1, "MapNotify");
- err |= check_xge_event(ctx, reply->major_opcode, 11, "ExtensionDeviceNotify");
- err |= check_xge_event(ctx, reply->major_opcode, 12, NULL);
- err |= check_xge_event(ctx, reply->major_opcode, 1337, NULL);
- err |= check_xge_event(ctx, reply->major_opcode, 0xffff, NULL);
+ err |= check_xkb_event(ctx, reply->major_opcode, reply->first_event, 0, "NewKeyboardNotify");
+ err |= check_xkb_event(ctx, reply->major_opcode, reply->first_event, 1, "MapNotify");
+ err |= check_xkb_event(ctx, reply->major_opcode, reply->first_event, 11, "ExtensionDeviceNotify");
+ err |= check_xkb_event(ctx, reply->major_opcode, reply->first_event, 12, NULL);
+ err |= check_xkb_event(ctx, reply->major_opcode, reply->first_event, 1337, NULL);
+ err |= check_xkb_event(ctx, reply->major_opcode, reply->first_event, 0xffff, NULL);
free(reply);
return err;