Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
KeyboardState.cpp
00001 #include "kbd_mgr/KeyboardState.h" 00002 00003 #include <algorithm> 00004 #include <iomanip> 00005 00006 namespace kbd_mgr { 00007 00008 KeyboardState::KeyboardState() : 00009 numRows(0), numKeysPerRow(0), rowMask(0), numRowsPerWord(0), numKeysPerWord(0), numWords(0), data(0) 00010 { } 00011 00012 KeyboardState::KeyboardState(std::size_t numRows, std::size_t numKeysPerRow) : 00013 numRows(numRows), numKeysPerRow(numKeysPerRow), rowMask((1 << numKeysPerRow) -1), 00014 numRowsPerWord((sizeof(int) * 8) / numKeysPerRow), numKeysPerWord(numRowsPerWord * numKeysPerRow), 00015 numWords((numRows + (numRowsPerWord-1)) / numRowsPerWord), 00016 data(numWords, 0) 00017 { } 00018 00019 void KeyboardState::clear() { 00020 std::fill(this->data.begin(), this->data.end(), 0); 00021 } 00022 00023 int KeyboardState::getRowInfo(std::size_t row, std::size_t &wordIndex, std::size_t &rowShift, int &rowMask) const 00024 { 00025 std::size_t rowInWord = row % numRowsPerWord; 00026 wordIndex = row / numRowsPerWord; 00027 rowShift = numKeysPerRow * rowInWord; 00028 rowMask = this->rowMask << rowShift; 00029 00030 return this->data[wordIndex]; 00031 } 00032 00033 void KeyboardState::setRowState(std::size_t row, int rowState) { 00034 std::size_t wordIndex; 00035 std::size_t rowShift; 00036 int rowMask; 00037 int v = getRowInfo(row, wordIndex, rowShift, rowMask); 00038 v = (v & ~rowMask) | ((rowState & this->rowMask) << rowShift); 00039 this->data[wordIndex] = v; 00040 } 00041 00042 int KeyboardState::getRowState(std::size_t row) const { 00043 std::size_t wordIndex; 00044 std::size_t rowShift; 00045 int rowMask; 00046 int v = getRowInfo(row, wordIndex, rowShift, rowMask); 00047 return (v & rowMask) >> rowShift; 00048 } 00049 00050 bool KeyboardState::getKeyState(std::size_t key) const { 00051 std::size_t row = key / this->numKeysPerRow; 00052 std::size_t keyInRow = key % this->numKeysPerRow; 00053 int keyMask = 1 << keyInRow; 00054 00055 return (getRowState(row) & keyMask) != 0; 00056 } 00057 00058 KeyboardState KeyboardState::operator&(const KeyboardState &other) const { 00059 KeyboardState result(this->numRows, this->numKeysPerRow); 00060 00061 typedef Data::const_iterator SourceIterator; 00062 typedef Data::iterator TargetIterator; 00063 00064 SourceIterator a = this->data.begin(); 00065 SourceIterator b = other.data.begin(); 00066 TargetIterator t = result.data.begin(); 00067 while (a != this->data.end() && b != other.data.end() && t != result.data.end()) 00068 { 00069 *t = *a & *b; 00070 ++a; ++b; ++t; 00071 } 00072 00073 return result; 00074 } 00075 00076 bool KeyboardState::operator==(const KeyboardState &other) const { 00077 if (this == &other) { 00078 return true; 00079 } 00080 00081 if (this->numRows != other.numRows || this->numKeysPerRow != other.numKeysPerRow) 00082 return false; 00083 00084 Data::const_iterator p = this->data.begin(); 00085 Data::const_iterator q = other.data.begin(); 00086 while (p != this->data.end() && q != other.data.end()) { 00087 if (*p != *q) { 00088 return false; 00089 } 00090 ++p; ++q; 00091 } 00092 00093 return true; 00094 } 00095 00096 bool KeyboardState::empty() const { 00097 for(Data::const_iterator p = this->data.begin(); p != this->data.end(); ++p) { 00098 if (*p != 0) { 00099 return false; 00100 } 00101 } 00102 00103 return true; 00104 } 00105 00106 namespace { 00107 int getBitNumber(int v) 00108 { 00109 if (v == 0) { 00110 return -1; 00111 } 00112 00113 int key = 0; 00114 while (v != 1) { 00115 key++; 00116 v >>= 1; 00117 } 00118 00119 return key; 00120 } 00121 } 00122 00123 KeyboardState::KeyPressType KeyboardState::getKeyPressType(int *key) const 00124 { 00125 if (key) { 00126 *key = -1; 00127 } 00128 00129 Data::const_iterator p = this->data.begin(); 00130 std::size_t wordIndex = 0; 00131 while (p != this->data.end() && *p == 0) { 00132 ++p; 00133 ++wordIndex; 00134 } 00135 if (p != this->data.end()) { 00136 int v = *p; 00137 if (v != (v & -v)) { 00138 return MultiKeyPress; 00139 } 00140 int k = getBitNumber(v) + wordIndex * this->numKeysPerWord; 00141 ++p; 00142 while (p != this->data.end() && *p == 0) { 00143 ++p; 00144 } 00145 if (p == this->data.end()) { 00146 if (key) { 00147 *key = k; 00148 } 00149 return SingleKeyPress; 00150 } 00151 else { 00152 return MultiKeyPress; 00153 } 00154 } 00155 else { 00156 return Idle; 00157 } 00158 } 00159 00160 void KeyboardState::streamTo(std::ostream &out) const { 00161 using namespace std; 00162 std::size_t width = (this->numKeysPerWord + 3) / 4; 00163 ios_base::fmtflags f = out.flags(); 00164 for(Data::const_reverse_iterator p = this->data.rbegin(); p != this->data.rend(); ++p) { 00165 out << hex << setw(width) << setfill('0') << *p; 00166 } 00167 out.flags(f); 00168 } 00169 00170 } // kbd_mgr
Generated on Wed Jul 13 2022 16:23:43 by
1.7.2