qmk_firmware

QMK firmware for my keyboards (Corne, Sweep Ferris) and trackball (Ploopy Adept)
Log | Files | Refs | Submodules | LICENSE

keyboard_report_util.cpp (3304B)


      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 
     22 extern "C" {
     23 #include "keycode_string.h"
     24 }
     25 
     26 using namespace testing;
     27 
     28 extern std::map<uint16_t, std::string> KEYCODE_ID_TABLE;
     29 
     30 namespace {
     31 
     32 std::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 
     47 std::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 
     61 bool 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 
     67 std::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 
     99 KeyboardReportMatcher::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 
    110 bool KeyboardReportMatcher::MatchAndExplain(report_keyboard_t& report, MatchResultListener* listener) const {
    111     return m_report == report;
    112 }
    113 
    114 void KeyboardReportMatcher::DescribeTo(::std::ostream* os) const {
    115     *os << "is equal to " << m_report;
    116 }
    117 
    118 void KeyboardReportMatcher::DescribeNegationTo(::std::ostream* os) const {
    119     *os << "is not equal to " << m_report;
    120 }