fix(xkb): Memory leaks

This commit is contained in:
Michael Carlberg 2016-12-14 06:53:40 +01:00
parent 357e95335a
commit 4606c41577

View File

@ -75,29 +75,41 @@ namespace xkb_util {
* Get current group number * Get current group number
*/ */
uint8_t get_current_group(connection& conn, xcb_xkb_device_spec_t device) { uint8_t get_current_group(connection& conn, xcb_xkb_device_spec_t device) {
auto reply = xcb_xkb_get_state_reply(conn, xcb_xkb_get_state(conn, device), nullptr); uint8_t result{0};
return reply ? reply->group : 0; xcb_xkb_get_state_cookie_t cookie{xcb_xkb_get_state(conn, device)};
xcb_xkb_get_state_reply_t* reply{xcb_xkb_get_state_reply(conn, cookie, nullptr)};
if (reply != nullptr) {
result = reply->group;
free(reply);
}
return result;
} }
/** /**
* Get keyboard layouts * Get keyboard layouts
*/ */
vector<keyboard::layout> get_layouts(connection& conn, xcb_xkb_device_spec_t device) { vector<keyboard::layout> get_layouts(connection& conn, xcb_xkb_device_spec_t device) {
auto mask = XCB_XKB_NAME_DETAIL_GROUP_NAMES | XCB_XKB_NAME_DETAIL_SYMBOLS; vector<keyboard::layout> results;
auto reply = xcb_xkb_get_names_reply(conn, xcb_xkb_get_names(conn, device, mask), nullptr);
uint32_t mask{XCB_XKB_NAME_DETAIL_GROUP_NAMES | XCB_XKB_NAME_DETAIL_SYMBOLS};
xcb_xkb_get_names_cookie_t cookie{xcb_xkb_get_names(conn, device, mask)};
xcb_xkb_get_names_reply_t* reply{xcb_xkb_get_names_reply(conn, cookie, nullptr)};
if (reply == nullptr) {
return results;
}
xcb_xkb_get_names_value_list_t values; xcb_xkb_get_names_value_list_t values;
xcb_xkb_get_names_value_list_unpack(xcb_xkb_get_names_value_list(reply), reply->nTypes, reply->indicators, 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, reply->virtualMods, reply->groupNames, reply->nKeys, reply->nKeyAliases, reply->nRadioGroups, reply->which,
&values); &values);
auto len = xcb_xkb_get_names_value_list_groups_length(reply, &values);
free(reply);
vector<reply::get_atom_name> replies; vector<reply::get_atom_name> replies;
for (int i = 0; i < len; i++) { for (int i = 0; i < xcb_xkb_get_names_value_list_groups_length(reply, &values); i++) {
replies.emplace_back(xpp::x::get_atom_name(conn, values.groups[i])); replies.emplace_back(xpp::x::get_atom_name(conn, values.groups[i]));
} }
vector<keyboard::layout> results;
for (const auto& reply : replies) { for (const auto& reply : replies) {
vector<string> sym_names; vector<string> sym_names;
@ -110,6 +122,8 @@ namespace xkb_util {
results.emplace_back(keyboard::layout{static_cast<reply::get_atom_name>(reply).name(), sym_names}); results.emplace_back(keyboard::layout{static_cast<reply::get_atom_name>(reply).name(), sym_names});
} }
free(reply);
return results; return results;
} }
@ -117,21 +131,27 @@ namespace xkb_util {
* Get keyboard indicators * 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> get_indicators(connection& conn, xcb_xkb_device_spec_t device) {
auto mask = XCB_XKB_NAME_DETAIL_INDICATOR_NAMES; map<keyboard::indicator::type, keyboard::indicator> results;
auto reply = xcb_xkb_get_names_reply(conn, xcb_xkb_get_names(conn, device, mask), nullptr);
uint32_t mask{XCB_XKB_NAME_DETAIL_INDICATOR_NAMES};
xcb_xkb_get_names_cookie_t cookie{xcb_xkb_get_names(conn, device, mask)};
xcb_xkb_get_names_reply_t* reply{xcb_xkb_get_names_reply(conn, cookie, nullptr)};
if (reply == nullptr) {
return results;
}
xcb_xkb_get_names_value_list_t values; xcb_xkb_get_names_value_list_t values;
xcb_xkb_get_names_value_list_unpack(xcb_xkb_get_names_value_list(reply), reply->nTypes, reply->indicators, 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, reply->virtualMods, reply->groupNames, reply->nKeys, reply->nKeyAliases, reply->nRadioGroups, reply->which,
&values); &values);
auto len = xcb_xkb_get_names_value_list_indicator_names_length(reply, &values);
free(reply);
map<xcb_atom_t, reply::get_atom_name> entries; map<xcb_atom_t, reply::get_atom_name> entries;
for (int i = 0; i < len; i++) { 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])); entries.emplace(values.indicatorNames[i], xpp::x::get_atom_name(conn, values.indicatorNames[i]));
} }
map<keyboard::indicator::type, keyboard::indicator> results;
for (const auto& entry : entries) { for (const auto& entry : entries) {
auto name = static_cast<reply::get_atom_name>(entry.second).name(); auto name = static_cast<reply::get_atom_name>(entry.second).name();
auto type = keyboard::indicator::type::NONE; auto type = keyboard::indicator::type::NONE;
@ -151,6 +171,8 @@ namespace xkb_util {
results.emplace(type, keyboard::indicator{entry.first, mask, name, enabled}); results.emplace(type, keyboard::indicator{entry.first, mask, name, enabled});
} }
free(reply);
return results; return results;
} }