Messages: merge macros with and without message code
[platform/upstream/libxkbcommon.git] / src / x11 / keymap.c
index f3f179e..72f6639 100644 (file)
  * We try not to trust the server too much and be paranoid. If we get
  * something which we definitely shouldn't, we fail.
  */
-#define STRINGIFY(expr) #expr
 #define FAIL_UNLESS(expr) do {                                          \
     if (!(expr)) {                                                      \
-        log_err(keymap->ctx,                                            \
+        log_err(keymap->ctx, XKB_LOG_MESSAGE_NO_ID,                                            \
                 "x11: failed to get keymap from X server: unmet condition in %s(): %s\n", \
                 __func__, STRINGIFY(expr));                             \
         goto fail;                                                      \
@@ -73,7 +72,7 @@
 
 #define FAIL_IF_BAD_REPLY(reply, request_name) do {                     \
     if (!reply) {                                                       \
-        log_err(keymap->ctx,                                            \
+        log_err(keymap->ctx, XKB_LOG_MESSAGE_NO_ID,                                            \
                 "x11: failed to get keymap from X server: %s request failed\n", \
                 (request_name));                                        \
         goto fail;                                                      \
     }                                                                   \
 } while (0)
 
+static const xcb_xkb_map_part_t get_map_required_components =
+    (XCB_XKB_MAP_PART_KEY_TYPES |
+     XCB_XKB_MAP_PART_KEY_SYMS |
+     XCB_XKB_MAP_PART_MODIFIER_MAP |
+     XCB_XKB_MAP_PART_EXPLICIT_COMPONENTS |
+     XCB_XKB_MAP_PART_KEY_ACTIONS |
+     XCB_XKB_MAP_PART_VIRTUAL_MODS |
+     XCB_XKB_MAP_PART_VIRTUAL_MOD_MAP);
+
+static const xcb_xkb_name_detail_t get_names_wanted =
+    (XCB_XKB_NAME_DETAIL_KEYCODES |
+     XCB_XKB_NAME_DETAIL_SYMBOLS |
+     XCB_XKB_NAME_DETAIL_TYPES |
+     XCB_XKB_NAME_DETAIL_COMPAT |
+     XCB_XKB_NAME_DETAIL_KEY_TYPE_NAMES |
+     XCB_XKB_NAME_DETAIL_KT_LEVEL_NAMES |
+     XCB_XKB_NAME_DETAIL_INDICATOR_NAMES |
+     XCB_XKB_NAME_DETAIL_KEY_NAMES |
+     XCB_XKB_NAME_DETAIL_KEY_ALIASES |
+     XCB_XKB_NAME_DETAIL_VIRTUAL_MOD_NAMES |
+     XCB_XKB_NAME_DETAIL_GROUP_NAMES);
+static const xcb_xkb_name_detail_t get_names_required =
+    (XCB_XKB_NAME_DETAIL_KEY_TYPE_NAMES |
+     XCB_XKB_NAME_DETAIL_KT_LEVEL_NAMES |
+     XCB_XKB_NAME_DETAIL_KEY_NAMES |
+     XCB_XKB_NAME_DETAIL_VIRTUAL_MOD_NAMES);
+
 
 static xkb_mod_mask_t
 translate_mods(uint8_t rmods, uint16_t vmods_low, uint16_t vmods_high)
@@ -645,26 +671,15 @@ fail:
 }
 
 static bool
-get_map(struct xkb_keymap *keymap, xcb_connection_t *conn, uint16_t device_id)
+get_map(struct xkb_keymap *keymap, xcb_connection_t *conn,
+        xcb_xkb_get_map_cookie_t cookie)
 {
-    static const xcb_xkb_map_part_t required_components =
-        (XCB_XKB_MAP_PART_KEY_TYPES |
-         XCB_XKB_MAP_PART_KEY_SYMS |
-         XCB_XKB_MAP_PART_MODIFIER_MAP |
-         XCB_XKB_MAP_PART_EXPLICIT_COMPONENTS |
-         XCB_XKB_MAP_PART_KEY_ACTIONS |
-         XCB_XKB_MAP_PART_VIRTUAL_MODS |
-         XCB_XKB_MAP_PART_VIRTUAL_MOD_MAP);
-
-    xcb_xkb_get_map_cookie_t cookie =
-        xcb_xkb_get_map(conn, device_id, required_components,
-                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
     xcb_xkb_get_map_reply_t *reply = xcb_xkb_get_map_reply(conn, cookie, NULL);
     xcb_xkb_get_map_map_t map;
 
     FAIL_IF_BAD_REPLY(reply, "XkbGetMap");
 
-    if ((reply->present & required_components) != required_components)
+    if ((reply->present & get_map_required_components) != get_map_required_components)
         goto fail;
 
     xcb_xkb_get_map_map_unpack(xcb_xkb_get_map_map(reply),
@@ -877,8 +892,10 @@ get_type_names(struct xkb_keymap *keymap, struct x11_atom_interner *interner,
         ALLOC_OR_FAIL(type->level_names, type->num_levels);
 
         x11_atom_interner_adopt_atom(interner, wire_type_name, &type->name);
-        x11_atom_interner_adopt_atoms(interner, kt_level_names_iter,
-                                     type->level_names, wire_num_levels);
+        for (size_t j = 0; j < wire_num_levels; j++) {
+            x11_atom_interner_adopt_atom(interner, kt_level_names_iter[j],
+                                         &type->level_names[j]);
+        }
 
         type->num_level_names = type->num_levels;
         kt_level_names_iter += wire_num_levels;
@@ -959,7 +976,10 @@ get_group_names(struct xkb_keymap *keymap, struct x11_atom_interner *interner,
     keymap->num_group_names = msb_pos(reply->groupNames);
     ALLOC_OR_FAIL(keymap->group_names, keymap->num_group_names);
 
-    x11_atom_interner_adopt_atoms(interner, iter, keymap->group_names, length);
+    for (int i = 0; i < length; i++) {
+        x11_atom_interner_adopt_atom(interner, iter[i],
+                                     &keymap->group_names[i]);
+    }
 
     return true;
 
@@ -1041,36 +1061,16 @@ fail:
 
 static bool
 get_names(struct xkb_keymap *keymap, struct x11_atom_interner *interner,
-          uint16_t device_id)
+          xcb_xkb_get_names_cookie_t cookie)
 {
-    static const xcb_xkb_name_detail_t wanted =
-        (XCB_XKB_NAME_DETAIL_KEYCODES |
-         XCB_XKB_NAME_DETAIL_SYMBOLS |
-         XCB_XKB_NAME_DETAIL_TYPES |
-         XCB_XKB_NAME_DETAIL_COMPAT |
-         XCB_XKB_NAME_DETAIL_KEY_TYPE_NAMES |
-         XCB_XKB_NAME_DETAIL_KT_LEVEL_NAMES |
-         XCB_XKB_NAME_DETAIL_INDICATOR_NAMES |
-         XCB_XKB_NAME_DETAIL_KEY_NAMES |
-         XCB_XKB_NAME_DETAIL_KEY_ALIASES |
-         XCB_XKB_NAME_DETAIL_VIRTUAL_MOD_NAMES |
-         XCB_XKB_NAME_DETAIL_GROUP_NAMES);
-    static const xcb_xkb_name_detail_t required =
-        (XCB_XKB_NAME_DETAIL_KEY_TYPE_NAMES |
-         XCB_XKB_NAME_DETAIL_KT_LEVEL_NAMES |
-         XCB_XKB_NAME_DETAIL_KEY_NAMES |
-         XCB_XKB_NAME_DETAIL_VIRTUAL_MOD_NAMES);
-
     xcb_connection_t *conn = interner->conn;
-    xcb_xkb_get_names_cookie_t cookie =
-        xcb_xkb_get_names(conn, device_id, wanted);
     xcb_xkb_get_names_reply_t *reply =
         xcb_xkb_get_names_reply(conn, cookie, NULL);
     xcb_xkb_get_names_value_list_t list;
 
     FAIL_IF_BAD_REPLY(reply, "XkbGetNames");
 
-    FAIL_UNLESS((reply->which & required) == required);
+    FAIL_UNLESS((reply->which & get_names_required) == get_names_required);
 
     xcb_xkb_get_names_value_list_unpack(xcb_xkb_get_names_value_list(reply),
                                         reply->nTypes,
@@ -1083,25 +1083,15 @@ get_names(struct xkb_keymap *keymap, struct x11_atom_interner *interner,
                                         reply->which,
                                         &list);
 
-    xcb_get_atom_name_cookie_t cookies[4];
-    get_atom_name(conn, list.keycodesName, &cookies[0]);
-    get_atom_name(conn, list.symbolsName, &cookies[1]);
-    get_atom_name(conn, list.typesName, &cookies[2]);
-    get_atom_name(conn, list.compatName, &cookies[3]);
-
-    /* We need to ensure all replies are collected and thus no short-circuit */
-    bool atom_success = true;
-    atom_success &= get_atom_name_reply(conn, list.keycodesName, cookies[0],
-                                        &keymap->keycodes_section_name);
-    atom_success &= get_atom_name_reply(conn, list.symbolsName, cookies[1],
-                                        &keymap->symbols_section_name);
-    atom_success &= get_atom_name_reply(conn, list.typesName, cookies[2],
-                                        &keymap->types_section_name);
-    atom_success &= get_atom_name_reply(conn, list.compatName, cookies[3],
-                                        &keymap->compat_section_name);
-
-    if (!atom_success ||
-        !get_type_names(keymap, interner, reply, &list) ||
+    x11_atom_interner_get_escaped_atom_name(interner, list.keycodesName,
+                                            &keymap->keycodes_section_name);
+    x11_atom_interner_get_escaped_atom_name(interner, list.symbolsName,
+                                            &keymap->symbols_section_name);
+    x11_atom_interner_get_escaped_atom_name(interner, list.typesName,
+                                            &keymap->types_section_name);
+    x11_atom_interner_get_escaped_atom_name(interner, list.compatName,
+                                            &keymap->compat_section_name);
+    if (!get_type_names(keymap, interner, reply, &list) ||
         !get_indicator_names(keymap, interner, reply, &list) ||
         !get_vmod_names(keymap, interner, reply, &list) ||
         !get_group_names(keymap, interner, reply, &list) ||
@@ -1109,11 +1099,6 @@ get_names(struct xkb_keymap *keymap, struct x11_atom_interner *interner,
         !get_aliases(keymap, conn, reply, &list))
         goto fail;
 
-    XkbEscapeMapName(keymap->keycodes_section_name);
-    XkbEscapeMapName(keymap->symbols_section_name);
-    XkbEscapeMapName(keymap->types_section_name);
-    XkbEscapeMapName(keymap->compat_section_name);
-
     free(reply);
     return true;
 
@@ -1174,26 +1159,49 @@ xkb_x11_keymap_new_from_device(struct xkb_context *ctx,
     struct x11_atom_interner interner;
     x11_atom_interner_init(&interner, ctx, conn);
 
+    /*
+     * Send all requests together so only one roundtrip is needed
+     * to get the replies.
+     */
+    xcb_xkb_get_map_cookie_t map_cookie =
+        xcb_xkb_get_map(conn, device_id, get_map_required_components,
+                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
     xcb_xkb_get_indicator_map_cookie_t indicator_map_cookie =
         xcb_xkb_get_indicator_map(conn, device_id, ALL_INDICATORS_MASK);
     xcb_xkb_get_compat_map_cookie_t compat_map_cookie =
         xcb_xkb_get_compat_map(conn, device_id, 0, true, 0, 0);
-    xcb_xkb_get_controls_cookie_t get_controls_cookie =
+    xcb_xkb_get_names_cookie_t names_cookie =
+        xcb_xkb_get_names(conn, device_id, get_names_wanted);
+    xcb_xkb_get_controls_cookie_t controls_cookie =
         xcb_xkb_get_controls(conn, device_id);
 
-    bool had_error = false;
-    had_error |= !get_map(keymap, conn, device_id);
-    had_error |= !get_indicator_map(keymap, conn, indicator_map_cookie);
-    had_error |= !get_compat_map(keymap, conn, compat_map_cookie);
-    had_error |= !get_names(keymap, &interner, device_id);
-    had_error |= !get_controls(keymap, conn, get_controls_cookie);
-
+    if (!get_map(keymap, conn, map_cookie))
+        goto err_map;
+    if (!get_indicator_map(keymap, conn, indicator_map_cookie))
+        goto err_indicator_map;
+    if (!get_compat_map(keymap, conn, compat_map_cookie))
+        goto err_compat_map;
+    if (!get_names(keymap, &interner, names_cookie))
+        goto err_names;
+    if (!get_controls(keymap, conn, controls_cookie))
+        goto err_controls;
     x11_atom_interner_round_trip(&interner);
-    had_error |= interner.had_error;
-    if (had_error) {
-        xkb_keymap_unref(keymap);
-        return NULL;
-    }
+    if (interner.had_error)
+        goto err_interner;
 
     return keymap;
+
+err_map:
+    xcb_discard_reply(conn, indicator_map_cookie.sequence);
+err_indicator_map:
+    xcb_discard_reply(conn, compat_map_cookie.sequence);
+err_compat_map:
+    xcb_discard_reply(conn, names_cookie.sequence);
+err_names:
+    xcb_discard_reply(conn, controls_cookie.sequence);
+err_controls:
+    x11_atom_interner_round_trip(&interner);
+err_interner:
+    xkb_keymap_unref(keymap);
+    return NULL;
 }