ckb-next  v0.2.8 at branch master
ckb-next driver for corsair devices
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
kbperf.cpp
Go to the documentation of this file.
1 #include "kbperf.h"
2 #include "kbmode.h"
3 #include "kb.h"
4 #include "media.h"
5 #include <cmath>
6 
7 #if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0)
8 #define map_last(map) ((map).last())
9 #else
10 #define map_last(map) ((map).value((map).keys().last()))
11 #endif
12 
14  QObject(parent), runningPushIdx(1),
15  _iOpacity(1.f), _dpiIndicator(true), _liftHeight(MEDIUM), _angleSnap(false),
16  _needsUpdate(true), _needsSave(true) {
17  // Default DPI settings
18  dpiX[0] = dpiY[0] = 400;
19  dpiX[1] = dpiY[1] = 450;
20  dpiX[2] = dpiY[2] = 800;
21  dpiX[3] = dpiY[3] = 1500;
22  dpiX[4] = dpiY[4] = 3000;
23  dpiX[5] = dpiY[5] = 6000;
24  dpiClr[0] = QColor(255, 0, 0);
25  dpiClr[1] = QColor(255, 192, 0);
26  dpiClr[2] = QColor(255, 255, 0);
27  dpiClr[3] = QColor(0, 255, 0);
28  dpiClr[4] = QColor(0, 255, 255);
29  dpiClr[5] = QColor(255, 255, 255);
30  dpiClr[6] = QColor(192, 192, 192);
31  for(int i = 0; i < DPI_COUNT; i++)
32  dpiOn[i] = true;
33  dpiBaseIdx = 3;
36  // Default indicators
37  iColor[NUM][0] = iColor[CAPS][0] = iColor[SCROLL][0] = QColor(0, 255, 0); // Lock lights: on = green, off = black
38  iColor[NUM][1] = iColor[CAPS][1] = iColor[SCROLL][1] = QColor(0, 0, 0);
39  iColor[MACRO][0] = QColor(255, 0, 0); // Macro: on = red, off = black
40  iColor[LOCK][0] = QColor(255, 255, 255); // Win lock: on = white, off = black
41  iColor[MODE][0] = iColor[MUTE][0] = QColor(255, 255, 255, 0); // Mode, mute: on = transparent, off = black
42  iColor[MODE][1] = iColor[MACRO][1] = iColor[LOCK][1] = iColor[MUTE][1] = muteNAColor = QColor(0, 0, 0);
43  iColor[LIGHT][0] = QColor(255, 0, 0); // Brightness: red, yellow, white
44  iColor[LIGHT][1] = QColor(255, 255, 0);
45  light100Color = QColor(255, 255, 255);
46  for(int i = 0; i < HW_I_COUNT; i++){
47  // Set all lock lights to HW mode
48  iEnable[i] = false;
49  hwIType[i] = NORMAL;
50  }
51  for(int i = HW_I_COUNT; i < I_COUNT; i++){
52  // Turn all other indicators on
53  iEnable[i] = true;
54  }
55 }
56 
57 KbPerf::KbPerf(KbMode* parent, const KbPerf& other) :
58  QObject(parent), dpiCurX(other.dpiCurX), dpiCurY(other.dpiCurY), dpiBaseIdx(other.dpiBaseIdx), runningPushIdx(1),
59  _iOpacity(other._iOpacity), light100Color(other.light100Color), muteNAColor(other.muteNAColor), _dpiIndicator(other._dpiIndicator),
60  _liftHeight(other._liftHeight), _angleSnap(other._angleSnap),
61  _needsUpdate(true), _needsSave(true) {
62  memcpy(dpiX, other.dpiX, sizeof(dpiX));
63  memcpy(dpiY, other.dpiY, sizeof(dpiY));
64  for(int i = 0; i < DPI_COUNT + 1; i++)
65  dpiClr[i] = other.dpiClr[i];
66  memcpy(dpiOn, other.dpiOn, sizeof(dpiOn));
67  for(int i = 0; i < I_COUNT; i++){
68  iColor[i][0] = other.iColor[i][0];
69  iColor[i][1] = other.iColor[i][1];
70  }
71  memcpy(iEnable, other.iEnable, sizeof(iEnable));
72  memcpy(hwIType, other.hwIType, sizeof(hwIType));
73  // Don't copy pushed DPI states. If the other mode has any, restore the original DPI
75 }
76 
77 const KbPerf& KbPerf::operator= (const KbPerf& other){
78  dpiCurX = other.dpiCurX; dpiCurY = other.dpiCurY; dpiBaseIdx = other.dpiBaseIdx; runningPushIdx = 1;
81  _needsUpdate = true; _needsSave = true;
82  memcpy(dpiX, other.dpiX, sizeof(dpiX));
83  memcpy(dpiY, other.dpiY, sizeof(dpiY));
84  for(int i = 0; i < DPI_COUNT + 1; i++)
85  dpiClr[i] = other.dpiClr[i];
86  memcpy(dpiOn, other.dpiOn, sizeof(dpiOn));
87  for(int i = 0; i < I_COUNT; i++){
88  iColor[i][0] = other.iColor[i][0];
89  iColor[i][1] = other.iColor[i][1];
90  }
91  memcpy(iEnable, other.iEnable, sizeof(iEnable));
92  memcpy(hwIType, other.hwIType, sizeof(hwIType));
93  // Don't copy pushed DPI states. If the other mode has any, restore the original DPI
95  return other;
96 }
97 
98 KbBind* KbPerf::bind() const {
99  return modeParent()->bind();
100 }
101 
103  return modeParent()->light();
104 }
105 
106 void KbPerf::load(CkbSettings& settings){
107  pushedDpis.clear();
108  runningPushIdx = 1;
109  _needsSave = false;
110  bool readIndicators = true;
111  if(!settings.containsGroup("Performance/Indicators")){
112  // Read old indicator settings from the lighting group, if present
113  // (ckb <= v0.2.0)
114  SGroup group(settings, "Lighting");
115  if(settings.contains("InactiveIndicators")){
116  bool inOk = false;
117  int inactive = settings.value("InactiveIndicators").toInt(&inOk);
118  if(!inOk || inactive > 2)
119  inactive = 2;
120  if(inactive == 1)
121  _iOpacity = 0.75f;
122  else if(inactive == 0)
123  _iOpacity = 0.5f;
124  else if(inactive < 0){
125  // Indicators disabled
126  iEnable[MODE] = iEnable[MACRO] = iEnable[LIGHT] = iEnable[LOCK] = iEnable[MUTE] = false;
127  }
128  bool showMute = (settings.value("ShowMute").toInt(&inOk) != 0);
129  if(inOk && !showMute)
130  iEnable[MUTE] = false;
131  readIndicators = false;
132  }
133  }
134  SGroup group(settings, "Performance");
135  // Read DPI settings
136  {
137  SGroup group(settings, "DPI");
138  for(int i = 0; i < DPI_COUNT; i++){
139  QString iStr = QString::number(i);
140  QPoint value = settings.value(iStr).toPoint();
141  if(value.isNull())
142  continue;
143  dpiX[i] = value.x(); dpiY[i] = value.y();
144  QColor color = settings.value(iStr + "RGB").toString();
145  if(color.isValid())
146  dpiClr[i] = color;
147  if(i != 0)
148  dpiOn[i] = !settings.value(iStr + "Disabled").toBool();
149  }
150  QColor color = settings.value("6RGB").toString();
151  if(color.isValid())
152  dpiClr[OTHER] = color;
153  if (settings.contains("CurIdx")) {
154  dpiBaseIdx = settings.value("CurIdx").toInt();
155  } else {
156  // If there isn't a setting for current DPI stage, pick the first
157  // enabled one. Failing that just pick stage 1.
158  dpiBaseIdx = 1;
159  for (int i = 1; i < DPI_COUNT; i++) {
160  if (dpiOn[i]) {
161  dpiBaseIdx = i;
162  break;
163  }
164  }
165  }
167  }
168  // Read misc. mouse settings
169  _liftHeight = (height)settings.value("LiftHeight").toInt();
170  if(_liftHeight < LOW || _liftHeight > HIGH)
172  _angleSnap = settings.value("AngleSnap").toBool();
173  if(settings.contains("NoIndicator")){
174  // ckb <= v0.2.0
175  _dpiIndicator = !settings.value("NoIndicator").toBool();
176  } else {
177  _dpiIndicator = settings.value("Indicators/DPI", true).toBool();
178  }
179  // Read indicator settings
180  if(readIndicators){
181  SGroup group(settings, "Indicators");
182  _iOpacity = settings.value("Opacity", 100).toInt() / 100.f;
183  for(int i = 0; i < I_COUNT; i++){
184  SGroup group(settings, QString::number(i));
185  QColor color = settings.value("RGB0").toString();
186  if(color.isValid())
187  iColor[i][0] = color;
188  color = settings.value("RGB1").toString();
189  if(color.isValid())
190  iColor[i][1] = color;
191  if(i == LIGHT){
192  color = settings.value("RGB2").toString();
193  if(color.isValid())
194  light100Color = color;
195  } else if(i == MUTE){
196  color = settings.value("RGB2").toString();
197  if(color.isValid())
198  muteNAColor = color;
199  }
200  if(i <= HW_IMAX){
201  iEnable[i] = settings.value("Enable", false).toBool();
202  hwIType[i] = (i_hw)settings.value("Hardware", (int)NORMAL).toInt();
203  } else {
204  iEnable[i] = settings.value("Enable", true).toBool();
205  }
206  }
207  }
208  emit didLoad();
209 }
210 
211 void KbPerf::save(CkbSettings& settings){
212  _needsSave = false;
213  SGroup group(settings, "Performance");
214  {
215  SGroup group(settings, "DPI");
216  for(int i = 0; i < DPI_COUNT; i++){
217  QString iStr = QString::number(i);
218  settings.setValue(iStr, QPoint(dpiX[i], dpiY[i]));
219  settings.setValue(iStr + "RGB", dpiClr[i].name(QColor::HexArgb));
220  if(i != 0)
221  settings.setValue(iStr + "Disabled", !dpiOn[i]);
222  }
223  settings.setValue("6RGB", dpiClr[OTHER].name(QColor::HexArgb));
224  // Ignore pushed modes when saving current DPI.
225  settings.setValue("CurIdx", dpiBaseIdx);
226  }
227  settings.setValue("LiftHeight", _liftHeight);
228  settings.setValue("AngleSnap", _angleSnap);
229  {
230  SGroup group(settings, "Indicators");
231  settings.setValue("DPI", _dpiIndicator);
232  for(int i = 0; i < I_COUNT; i++){
233  SGroup group(settings, QString::number(i));
234  settings.setValue("RGB0", iColor[i][0].name(QColor::HexArgb));
235  settings.setValue("RGB1", iColor[i][1].name(QColor::HexArgb));
236  if(i == LIGHT)
237  settings.setValue("RGB2", light100Color.name(QColor::HexArgb));
238  else if(i == MUTE)
239  settings.setValue("RGB2", muteNAColor.name(QColor::HexArgb));
240  settings.setValue("Enable", iEnable[i]);
241  if(i <= HW_IMAX)
242  settings.setValue("Hardware", (int)hwIType[i]);
243  }
244  }
245 }
246 
247 void KbPerf::dpi(int index, const QPoint& newValue){
248  if(index < 0 || index >= DPI_COUNT)
249  return;
250  dpiX[index] = newValue.x();
251  dpiY[index] = newValue.y();
252  // Update current DPI if needed
253  if(dpiBaseIdx == index && pushedDpis.isEmpty()) {
254  _curDpi(QPoint(dpiX[index], dpiY[index]));
255  }
256  _needsUpdate = _needsSave = true;
257 }
258 
259 void KbPerf::_curDpi(const QPoint& newDpi) {
260  dpiCurX = newDpi.x();
261  dpiCurY = newDpi.y();
262  _needsUpdate = _needsSave = true;
263 }
264 
265 void KbPerf::baseDpiIdx(int newIdx) {
266  if (pushedDpis.isEmpty() && dpiBaseIdx == newIdx)
267  return;
268  pushedDpis.clear();
269  dpiBaseIdx = newIdx;
271  _needsUpdate = _needsSave = true;
272 }
273 
274 quint64 KbPerf::pushDpi(const QPoint& newDpi){
275  quint64 index = runningPushIdx++;
276  pushedDpis[index] = newDpi;
277  _curDpi(newDpi);
278  return index;
279 }
280 
281 void KbPerf::popDpi(quint64 pushIdx){
282  if(!pushedDpis.contains(pushIdx)) {
283  return;
284  }
285  pushedDpis.remove(pushIdx);
286  if (pushedDpis.isEmpty()) {
288  } else {
289  // Set the DPI to the last-pushed value still on the stack
291  }
292  _needsUpdate = _needsSave = true;
293 }
294 
296  // Scroll past disabled DPIs and choose the next one up
297  int idx = baseDpiIdx();
298  do {
299  idx++;
300  if(idx >= DPI_COUNT)
301  return;
302  } while(!dpiOn[idx]);
303  baseDpiIdx(idx);
304 }
305 
307  int idx = baseDpiIdx();
308  do {
309  idx--;
310  if(idx <= SNIPER)
311  return;
312  } while(!dpiOn[idx]);
313  baseDpiIdx(idx);
314 }
315 
316 // dpiCycleUp will loop to lowest setting after passing the highest.
318  int idx = baseDpiIdx();
319  do {
320  idx++;
321  if(idx >= DPI_COUNT)
322  idx = SNIPER + 1;
323  if(idx == baseDpiIdx())
324  return;
325  } while(!dpiOn[idx]);
326  baseDpiIdx(idx);
327 }
328 
330  int idx = baseDpiIdx();
331  do {
332  idx--;
333  if(idx <= SNIPER)
334  idx = DPI_COUNT - 1;
335  if(idx == baseDpiIdx())
336  return;
337  } while(!dpiOn[idx]);
338  baseDpiIdx(idx);
339 }
340 
341 void KbPerf::getIndicator(indicator index, QColor& color1, QColor& color2, QColor& color3, bool& software_enable, i_hw& hardware_enable){
342  if(index < 0 || index >= I_COUNT)
343  return;
344  color1 = iColor[index][0];
345  color2 = iColor[index][1];
346  if(index == LIGHT)
347  color3 = light100Color;
348  else if(index == MUTE)
349  color3 = muteNAColor;
350  else
351  color3 = QColor();
352  software_enable = iEnable[index];
353  hardware_enable = (index <= HW_IMAX ? hwIType[index] : NONE);
354 }
355 
356 void KbPerf::setIndicator(indicator index, const QColor& color1, const QColor& color2, const QColor& color3, bool software_enable, i_hw hardware_enable){
357  if(index < 0 || index >= I_COUNT)
358  return;
359  iColor[index][0] = color1;
360  iColor[index][1] = color2;
361  if(index == LIGHT)
362  light100Color = color3;
363  else if(index == MUTE)
364  muteNAColor = color3;
365  iEnable[index] = software_enable;
366  if(hardware_enable == NONE)
367  hardware_enable = NORMAL;
368  if(index <= HW_IMAX)
369  hwIType[index] = hardware_enable;
370  _needsUpdate = _needsSave = true;
371 }
372 
373 void KbPerf::liftHeight(height newHeight){
374  if(newHeight < LOW || newHeight > HIGH)
375  return;
376  _liftHeight = newHeight;
377  _needsUpdate = _needsSave = true;
378 }
379 
380 void KbPerf::angleSnap(bool newAngleSnap){
381  _angleSnap = newAngleSnap;
382  _needsUpdate = _needsSave = true;
383 }
384 
385 void KbPerf::update(QFile& cmd, int notifyNumber, bool force, bool saveCustomDpi){
386  if(!force && !_needsUpdate)
387  return;
388  emit settingsUpdated();
389  _needsUpdate = false;
390  // Save DPI stage 0 (sniper)
391  // If the mouse is set to a custom DPI, save it in stage 0
392  int stage = pushedDpis.isEmpty() ? dpiBaseIdx : 0;
393  if(!pushedDpis.isEmpty() && saveCustomDpi) {
394  cmd.write(QString("dpi 0:%1,%2").arg(dpiCurX).arg(dpiCurY).toLatin1());
395  } else {
396  // Otherwise, save stage 0 normally
397  cmd.write(QString("dpi 0:%1,%2").arg(dpiX[0]).arg(dpiY[0]).toLatin1());
398  }
399  // Save stages 1 - 5
400  for(int i = 1; i < DPI_COUNT; i++){
401  if(!dpiOn[i] && stage != i)
402  cmd.write(QString(" %1:off").arg(i).toLatin1());
403  else
404  cmd.write(QString(" %1:%2,%3").arg(i).arg(dpiX[i]).arg(dpiY[i]).toLatin1());
405  }
406  // Save stage selection, lift height, and angle snap
407  cmd.write(QString(" dpisel %1 lift %2 snap %3").arg(stage).arg(_liftHeight).arg(_angleSnap ? "on" : "off").toLatin1());
408  // Save DPI colors
409  cmd.write(" rgb");
410  for(int i = 0; i < DPI_COUNT; i++){
411  QColor color = dpiColor(i);
412  cmd.write(" dpi");
413  char output[9];
414  snprintf(output, sizeof(output), "%1d:%02x%02x%02x", i, color.red(), color.green(), color.blue());
415  cmd.write(output);
416  }
417  // Enable indicator notifications
418  cmd.write(QString("\n@%1 inotify all").arg(notifyNumber).toLatin1());
419  // Set indicator state
420  const char* iNames[HW_I_COUNT] = { "num", "caps", "scroll" };
421  for(int i = 0; i < HW_I_COUNT; i++){
422  if(hwIType[i] == ON)
423  cmd.write(" ion ");
424  else if(hwIType[i] == OFF)
425  cmd.write(" ioff ");
426  else
427  cmd.write(" iauto ");
428  cmd.write(iNames[i]);
429  }
430 }
431 
432 void KbPerf::lightIndicator(const char* name, QRgb rgba){
433  int a = round(qAlpha(rgba) * _iOpacity);
434  if(a <= 0)
435  return;
436  light()->setIndicator(name, qRgba(qRed(rgba), qGreen(rgba), qBlue(rgba), a));
437 }
438 
439 void KbPerf::applyIndicators(int modeIndex, const bool indicatorState[]){
440  light()->resetIndicators();
441  if(_iOpacity <= 0.f)
442  return;
443  if(_dpiIndicator){
444  // Set DPI indicator according to index
445  int index = baseDpiIdx();
446  if(index == -1 || index > OTHER)
447  index = OTHER;
448  lightIndicator("dpi", dpiClr[index].rgba());
449  }
450  // KB indicators
451  if(iEnable[MODE]){
452  for(int i = 0; i < Kb::HWMODE_MAX; i++){
453  char name[4];
454  snprintf(name, sizeof(name), "m%d", i + 1);
455  if(modeIndex == i)
456  lightIndicator(name, iColor[MODE][0].rgba());
457  else
458  lightIndicator(name, iColor[MODE][1].rgba());
459  }
460  }
461  if(iEnable[MACRO])
462  lightIndicator("mr", iColor[MUTE][1].rgba());
463  if(iEnable[LIGHT]){
464  switch(light()->dimming()){
465  case 0: // 100%
466  lightIndicator("light", light100Color.rgba());
467  break;
468  case 1: // 67%
469  lightIndicator("light", iColor[LIGHT][1].rgba());
470  break;
471  case 2: // 33%
472  case 3: // light off
473  lightIndicator("light", iColor[LIGHT][0].rgba());
474  break;
475  }
476  }
477  if(iEnable[LOCK]){
478  if(bind()->winLock())
479  lightIndicator("lock", iColor[LOCK][0].rgba());
480  else
481  lightIndicator("lock", iColor[LOCK][1].rgba());
482  }
483  if(iEnable[MUTE]){
484  switch(getMuteState()){
485  case MUTED:
486  lightIndicator("mute", iColor[MUTE][0].rgba());
487  break;
488  case UNMUTED:
489  lightIndicator("mute", iColor[MUTE][1].rgba());
490  break;
491  default:
492  lightIndicator("mute", muteNAColor.rgba());
493  break;
494  }
495  }
496  // Lock lights
497  if(iEnable[NUM])
498  lightIndicator("numlock", indicatorState[0] ? iColor[NUM][0].rgba() : iColor[NUM][1].rgba());
499  if(iEnable[CAPS])
500  lightIndicator("caps", indicatorState[1] ? iColor[CAPS][0].rgba() : iColor[CAPS][1].rgba());
501  if(iEnable[SCROLL])
502  lightIndicator("scroll", indicatorState[2] ? iColor[SCROLL][0].rgba() : iColor[SCROLL][1].rgba());
503 }
504 
static const int HW_I_COUNT
Definition: kbperf.h:107
void setValue(const QString &key, const QVariant &value)
void dpiCycleUp()
Definition: kbperf.cpp:317
indicator
Definition: kbperf.h:88
bool _needsUpdate
Definition: kbperf.h:166
KbBind * bind()
Definition: kbmode.h:61
KbBind * bind() const
Definition: kbperf.cpp:98
void _curDpi(const QPoint &newDpi)
Definition: kbperf.cpp:259
int dpiBaseIdx
Definition: kbperf.h:142
int dpiCurY
Definition: kbperf.h:138
QColor light100Color
Definition: kbperf.h:157
QVariant value(const QString &key, const QVariant &defaultValue=QVariant()) const
cmd
Definition: command.h:7
uint runningPushIdx
Definition: kbperf.h:149
bool iEnable[I_COUNT]
Definition: kbperf.h:158
QColor dpiColor(int index) const
Definition: kbperf.h:85
#define map_last(map)
Definition: kbperf.cpp:8
bool contains(const QString &key) const
KbLight * light()
Definition: kbmode.h:60
void dpiCycleDown()
Definition: kbperf.cpp:329
bool dpiOn[DPI_COUNT]
Definition: kbperf.h:144
i_hw hwIType[HW_I_COUNT]
Definition: kbperf.h:159
void dpiDown()
Definition: kbperf.cpp:306
QMap< quint64, QPoint > pushedDpis
Definition: kbperf.h:148
height liftHeight() const
Definition: kbperf.h:38
float _iOpacity
Definition: kbperf.h:155
height _liftHeight
Definition: kbperf.h:163
void popDpi(quint64 pushIdx)
Definition: kbperf.cpp:281
KbMode * modeParent() const
Definition: kbperf.h:127
quint64 pushDpi(const QPoint &newDpi)
Definition: kbperf.cpp:274
KbPerf(KbMode *parent)
Definition: kbperf.cpp:13
bool containsGroup(const QString &group)
height
Definition: kbperf.h:31
void didLoad()
Definition: moc_kbperf.cpp:134
QPoint dpi(int index) const
Definition: kbperf.h:50
Definition: kbmode.h:36
void resetIndicators()
Definition: kblight.cpp:254
bool _needsSave
Definition: kbperf.h:166
static const int HWMODE_MAX
Definition: kb.h:50
Definition: kbperf.h:15
static const int DPI_COUNT
Definition: kbperf.h:46
Definition: kbbind.h:20
QColor muteNAColor
Definition: kbperf.h:157
bool _angleSnap
Definition: kbperf.h:164
bool angleSnap() const
Definition: kbperf.h:42
void setIndicator(indicator index, const QColor &color1, const QColor &color2, const QColor &color3=QColor(), bool software_enable=true, i_hw hardware_enable=NORMAL)
Definition: kbperf.cpp:356
void getIndicator(indicator index, QColor &color1, QColor &color2, QColor &color3, bool &software_enable, i_hw &hardware_enable)
Definition: kbperf.cpp:341
muteState getMuteState()
void update(QFile &cmd, int notifyNumber, bool force, bool saveCustomDpi)
Definition: kbperf.cpp:385
int dpiY[DPI_COUNT]
Definition: kbperf.h:136
int dpiCurX
Definition: kbperf.h:138
Definition: media.h:21
void setIndicator(const char *name, QRgb argb)
Definition: kblight.cpp:259
int baseDpiIdx() const
Definition: kbperf.h:61
void dpiUp()
Definition: kbperf.cpp:295
QColor dpiClr[DPI_COUNT+1]
Definition: kbperf.h:143
QColor iColor[I_COUNT][2]
Definition: kbperf.h:156
Definition: media.h:22
const KbPerf & operator=(const KbPerf &rhs)
Definition: kbperf.cpp:77
void lightIndicator(const char *name, QRgb rgba)
Definition: kbperf.cpp:432
void applyIndicators(int modeIndex, const bool indicatorState[HW_I_COUNT])
Definition: kbperf.cpp:439
void settingsUpdated()
Definition: moc_kbperf.cpp:140
i_hw
Definition: kbperf.h:101
int dpiX[DPI_COUNT]
Definition: kbperf.h:135
void save(CkbSettings &settings)
Definition: kbperf.cpp:211
KbLight * light() const
Definition: kbperf.cpp:102
static const int SNIPER
Definition: kbperf.h:46
static const int OTHER
Definition: kbperf.h:84
void load(CkbSettings &settings)
Definition: kbperf.cpp:106
bool _dpiIndicator
Definition: kbperf.h:160
static const int I_COUNT
Definition: kbperf.h:107