Parent directory

keyboard_report_util.cpp

3262 bytes
  1/* Copyright 2017 Fred Sundvik
  2 *
  3 * This program is free software: you can redistribute it and/or modify
  4 * it under the terms of the GNU General Public License as published by
  5 * the Free Software Foundation, either version 2 of the License, or
  6 * (at your option) any later version.
  7 *
  8 * This program is distributed in the hope that it will be useful,
  9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 11 * GNU General Public License for more details.
 12 *
 13 * You should have received a copy of the GNU General Public License
 14 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 15 */
 16
 17#include "keyboard_report_util.hpp"
 18#include <cstdint>
 19#include <vector>
 20#include <algorithm>
 21
 22using namespace testing;
 23
 24extern std::map<uint16_t, std::string> KEYCODE_ID_TABLE;
 25
 26namespace {
 27
 28std::vector<uint8_t> get_keys(const report_keyboard_t& report) {
 29    std::vector<uint8_t> result;
 30#if defined(NKRO_ENABLE)
 31#    error NKRO support not implemented yet
 32#else
 33    for (size_t i = 0; i < KEYBOARD_REPORT_KEYS; i++) {
 34        if (report.keys[i]) {
 35            result.emplace_back(report.keys[i]);
 36        }
 37    }
 38#endif
 39    std::sort(result.begin(), result.end());
 40    return result;
 41}
 42
 43std::vector<uint8_t> get_mods(const report_keyboard_t& report) {
 44    std::vector<uint8_t> result;
 45    for (size_t i = 0; i < 8; i++) {
 46        if (report.mods & (1 << i)) {
 47            uint8_t code = KC_LEFT_CTRL + i;
 48            result.emplace_back(code);
 49        }
 50    }
 51    std::sort(result.begin(), result.end());
 52    return result;
 53}
 54
 55} // namespace
 56
 57bool operator==(const report_keyboard_t& lhs, const report_keyboard_t& rhs) {
 58    auto lhskeys = get_keys(lhs);
 59    auto rhskeys = get_keys(rhs);
 60    return lhs.mods == rhs.mods && lhskeys == rhskeys;
 61}
 62
 63std::ostream& operator<<(std::ostream& os, const report_keyboard_t& report) {
 64    auto keys = get_keys(report);
 65    auto mods = get_mods(report);
 66
 67    os << std::setw(10) << std::left << "report: ";
 68
 69    if (!keys.size() && !mods.size()) {
 70        return os << "empty" << std::endl;
 71    }
 72
 73    os << "(";
 74    for (auto key = keys.cbegin(); key != keys.cend();) {
 75        os << KEYCODE_ID_TABLE.at(*key);
 76        key++;
 77        if (key != keys.cend()) {
 78            os << ", ";
 79        }
 80    }
 81
 82    os << ") [";
 83
 84    for (auto mod = mods.cbegin(); mod != mods.cend();) {
 85        os << KEYCODE_ID_TABLE.at(*mod);
 86        mod++;
 87        if (mod != mods.cend()) {
 88            os << ", ";
 89        }
 90    }
 91
 92    return os << "]" << std::endl;
 93}
 94
 95KeyboardReportMatcher::KeyboardReportMatcher(const std::vector<uint8_t>& keys) {
 96    memset(&m_report, 0, sizeof(report_keyboard_t));
 97    for (auto k : keys) {
 98        if (IS_MODIFIER_KEYCODE(k)) {
 99            m_report.mods |= MOD_BIT(k);
100        } else {
101            add_key_byte(&m_report, k);
102        }
103    }
104}
105
106bool KeyboardReportMatcher::MatchAndExplain(report_keyboard_t& report, MatchResultListener* listener) const {
107    return m_report == report;
108}
109
110void KeyboardReportMatcher::DescribeTo(::std::ostream* os) const {
111    *os << "is equal to " << m_report;
112}
113
114void KeyboardReportMatcher::DescribeNegationTo(::std::ostream* os) const {
115    *os << "is not equal to " << m_report;
116}