-
Notifications
You must be signed in to change notification settings - Fork 1
/
keyboard.cpp
160 lines (132 loc) · 3.64 KB
/
keyboard.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
//
// Created by Valerij Primachenko on 20-06-20.
//
#include <numeric>
#include <vector>
#include <bitset>
#include "keyboard.h"
#include "hid.h"
#include "DAS4Q.h"
#include <optional>
#include <iostream>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <mutex>
DAS::Command::~Command() noexcept = default;
std::shared_ptr<DAS::Keyboard> DAS::findKeyboard() {
using namespace DAS::HID4Q;
auto path = find_keyboard_4q();
start_keyboard(*path);
return std::make_shared<DAS4Q>();
}
std::optional<EffectConfig> find_config(const KeyConfig& config, std::bitset<5> currentState) {
currentState.flip();
auto candidate = std::find_if(config.crbegin(), config.crend(), [&](const auto& a) {
return (a.first & currentState) == 0;
});
if (candidate != config.crend()) {
return candidate->second;
} else {
return std::nullopt;
}
}
void DAS::Keyboard::first_update() {
lastState[0] = GetKeyState(VK_NUMLOCK) & 0x1;
lastState[1] = GetKeyState(VK_CAPITAL) & 0x1;
lastState[2] = GetAsyncKeyState(VK_CONTROL) < 0;
lastState[3] = GetAsyncKeyState(VK_MENU) < 0;
lastState[4] = GetAsyncKeyState(VK_SHIFT) < 0;
for (const auto&[key, config] : configs) {
{
auto cc = find_config(config.passive, lastState);
if (cc.has_value()) {
auto fx = cc.value();
createEffect(fx.fx, key, fx.r, fx.g, fx.b)->execute();
Sleep(1);
}
}
{
auto cc = find_config(config.active, lastState);
if (cc.has_value()) {
auto fx = cc.value();
createEffect(fx.fx, key, fx.r, fx.g, fx.b)->execute();
Sleep(1);
}
}
}
Flush()->execute();
Sleep(1);
}
std::mutex update_lock;
void DAS::Keyboard::update() {
if (!update_lock.try_lock()) return;
currentState[0] = GetKeyState(VK_NUMLOCK) & 0x1;
currentState[1] = GetKeyState(VK_CAPITAL) & 0x1;
currentState[2] = GetAsyncKeyState(VK_CONTROL) < 0;
currentState[3] = GetAsyncKeyState(VK_MENU) < 0;
currentState[4] = GetAsyncKeyState(VK_SHIFT) < 0;
if (currentState != lastState) {
for (const auto&[key, config] : configs) {
{
auto cc = find_config(config.active, currentState);
auto lastcc = find_config(config.active, lastState);
if (cc.has_value() && cc != lastcc) {
auto fx = cc.value();
createEffect(fx.fx, key, fx.r, fx.g, fx.b)->execute();
Sleep(1);
}
}
{
if (overrides.contains(key)) continue;
auto cc = find_config(config.passive, currentState);
auto lastcc = find_config(config.passive, lastState);
if (cc.has_value() && cc != lastcc) {
auto fx = cc.value();
createEffect(fx.fx, key, fx.r, fx.g, fx.b)->execute();
Sleep(1);
}
}
}
Flush()->execute();
Sleep(1);
}
lastState = currentState;
update_lock.unlock();
}
void DAS::Keyboard::read_config(const nlohmann::json &j) {
configs = parse_config(j);
first_update();
}
bool DAS::Keyboard::add_override(const std::string& pid, const Key &key, const EffectConfig &fx) {
if (createEffect(fx.fx, key, fx.r, fx.g, fx.b)->execute()) {
Sleep(1);
Flush()->execute();
Sleep(1);
overrides[key] = pid;
return true;
}
return false;
}
bool DAS::Keyboard::remove_override(const std::string& pid) {
auto needle = std::find_if(overrides.begin(), overrides.end(), [&](auto pair) {
return pair.second == pid;
});
if (needle == overrides.end()) { return false; }
const auto key = needle->first;
if (configs.contains(needle->first)) {
auto lastcc = find_config(configs[key].passive, lastState);
if(lastcc.has_value()) {
auto fx = lastcc.value();
createEffect(fx.fx, key, fx.r, fx.g, fx.b)->execute();
} else {
Wipe(key)->execute();
}
Sleep(1);
} else {
Wipe(key)->execute();
}
Flush()->execute();
Sleep(1);
overrides.erase(needle);
return true;
}