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
*/
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);
return reply ? reply->group : 0;
uint8_t result{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
*/
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;
auto reply = xcb_xkb_get_names_reply(conn, xcb_xkb_get_names(conn, device, mask), nullptr);
vector<keyboard::layout> results;
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_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,
&values);
auto len = xcb_xkb_get_names_value_list_groups_length(reply, &values);
free(reply);
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]));
}
vector<keyboard::layout> results;
for (const auto& reply : replies) {
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});
}
free(reply);
return results;
}
@ -117,21 +131,27 @@ namespace xkb_util {
* Get keyboard indicators
*/
map<keyboard::indicator::type, keyboard::indicator> get_indicators(connection& conn, xcb_xkb_device_spec_t device) {
auto mask = XCB_XKB_NAME_DETAIL_INDICATOR_NAMES;
auto reply = xcb_xkb_get_names_reply(conn, xcb_xkb_get_names(conn, device, mask), nullptr);
map<keyboard::indicator::type, keyboard::indicator> results;
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_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,
&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;
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]));
}
map<keyboard::indicator::type, keyboard::indicator> results;
for (const auto& entry : entries) {
auto name = static_cast<reply::get_atom_name>(entry.second).name();
auto type = keyboard::indicator::type::NONE;
@ -151,6 +171,8 @@ namespace xkb_util {
results.emplace(type, keyboard::indicator{entry.first, mask, name, enabled});
}
free(reply);
return results;
}