at master 120 lines 3.3 kB view raw
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 22extern "C" { 23#include "keycode_string.h" 24} 25 26using namespace testing; 27 28extern std::map<uint16_t, std::string> KEYCODE_ID_TABLE; 29 30namespace { 31 32std::vector<uint8_t> get_keys(const report_keyboard_t& report) { 33 std::vector<uint8_t> result; 34#if defined(NKRO_ENABLE) 35# error NKRO support not implemented yet 36#else 37 for (size_t i = 0; i < KEYBOARD_REPORT_KEYS; i++) { 38 if (report.keys[i]) { 39 result.emplace_back(report.keys[i]); 40 } 41 } 42#endif 43 std::sort(result.begin(), result.end()); 44 return result; 45} 46 47std::vector<uint8_t> get_mods(const report_keyboard_t& report) { 48 std::vector<uint8_t> result; 49 for (size_t i = 0; i < 8; i++) { 50 if (report.mods & (1 << i)) { 51 uint8_t code = KC_LEFT_CTRL + i; 52 result.emplace_back(code); 53 } 54 } 55 std::sort(result.begin(), result.end()); 56 return result; 57} 58 59} // namespace 60 61bool operator==(const report_keyboard_t& lhs, const report_keyboard_t& rhs) { 62 auto lhskeys = get_keys(lhs); 63 auto rhskeys = get_keys(rhs); 64 return lhs.mods == rhs.mods && lhskeys == rhskeys; 65} 66 67std::ostream& operator<<(std::ostream& os, const report_keyboard_t& report) { 68 auto keys = get_keys(report); 69 auto mods = get_mods(report); 70 71 os << std::setw(10) << std::left << "report: "; 72 73 if (!keys.size() && !mods.size()) { 74 return os << "empty" << std::endl; 75 } 76 77 os << "("; 78 for (auto key = keys.cbegin(); key != keys.cend();) { 79 os << get_keycode_string(*key); 80 key++; 81 if (key != keys.cend()) { 82 os << ", "; 83 } 84 } 85 86 os << ") ["; 87 88 for (auto mod = mods.cbegin(); mod != mods.cend();) { 89 os << get_keycode_string(*mod); 90 mod++; 91 if (mod != mods.cend()) { 92 os << ", "; 93 } 94 } 95 96 return os << "]" << std::endl; 97} 98 99KeyboardReportMatcher::KeyboardReportMatcher(const std::vector<uint8_t>& keys) { 100 memset(&m_report, 0, sizeof(report_keyboard_t)); 101 for (auto k : keys) { 102 if (IS_MODIFIER_KEYCODE(k)) { 103 m_report.mods |= MOD_BIT(k); 104 } else { 105 add_key_byte(&m_report, k); 106 } 107 } 108} 109 110bool KeyboardReportMatcher::MatchAndExplain(report_keyboard_t& report, MatchResultListener* listener) const { 111 return m_report == report; 112} 113 114void KeyboardReportMatcher::DescribeTo(::std::ostream* os) const { 115 *os << "is equal to " << m_report; 116} 117 118void KeyboardReportMatcher::DescribeNegationTo(::std::ostream* os) const { 119 *os << "is not equal to " << m_report; 120}