Beispiel #1
0
  /**
   * Query for the XKB extension
   */
  void query_extension(connection& conn) {
    conn.xkb().use_extension(XCB_XKB_MAJOR_VERSION, XCB_XKB_MINOR_VERSION);

    if (!conn.extension<xpp::xkb::extension>()->present) {
      throw application_error("Missing X extension: XKb");
    }
  }
Beispiel #2
0
  /**
   * Get keyboard indicators
   */
  map<keyboard::indicator::type, keyboard::indicator> get_indicators(connection& conn, xcb_xkb_device_spec_t device) {
    map<keyboard::indicator::type, keyboard::indicator> results;

    unsigned int mask{XCB_XKB_NAME_DETAIL_INDICATOR_NAMES};
    auto reply = xcb_xkb_get_names_reply(conn, xcb_xkb_get_names(conn, device, mask), nullptr);

    if (reply == nullptr) {
      return results;
    }

    xcb_xkb_get_names_value_list_t values{};
    void* buffer = xcb_xkb_get_names_value_list(reply);
    xcb_xkb_get_names_value_list_unpack(buffer, reply->nTypes, reply->indicators, reply->virtualMods, reply->groupNames,
        reply->nKeys, reply->nKeyAliases, reply->nRadioGroups, reply->which, &values);

    using get_atom_name_reply = xpp::x::reply::checked::get_atom_name<connection&>;
    map<xcb_atom_t, get_atom_name_reply> entries;
    for (int i = 0; i < xcb_xkb_get_names_value_list_indicator_names_length(reply, &values); i++) {
      entries.emplace(values.indicatorNames[i], xpp::x::get_atom_name(conn, values.indicatorNames[i]));
    }

    for (const auto& entry : entries) {
      auto name = static_cast<get_atom_name_reply>(entry.second).name();
      auto type = keyboard::indicator::type::NONE;

      if (string_util::compare(name, "caps lock")) {
        type = keyboard::indicator::type::CAPS_LOCK;
      } else if (string_util::compare(name, "num lock")) {
        type = keyboard::indicator::type::NUM_LOCK;
      } else {
        continue;
      }

      auto data = conn.xkb().get_named_indicator(device, 0, 0, entry.first);
      auto mask = (*conn.xkb().get_indicator_map(device, 1 << data->ndx).maps().begin()).mods;
      auto enabled = static_cast<bool>(data->on);

      results.emplace(type, keyboard::indicator{entry.first, mask, name, enabled});
    }

    free(reply);

    return results;
  }