20 QThread(parent), features(
"N/A"), firmware(
"N/A"), pollrate(
"N/A"), monochrome(false),
21 devpath(path), cmdpath(path +
"/cmd"), notifyPath(path +
"/notify1"), macroPath(path +
"/notify2"),
22 _currentProfile(0), _currentMode(0),
_model(
KeyMap::NO_MODEL),
23 lastAutoSave(QDateTime::currentMSecsSinceEpoch()),
24 _hwProfile(0), prevProfile(0), prevMode(0),
25 cmd(cmdpath), notifyNumber(1), macroNumber(2), _needsSave(false)
31 QFile ftpath(path +
"/features"), mpath(path +
"/model"), spath(path +
"/serial"), fwpath(path +
"/fwversion"), ppath(path +
"/pollrate");
32 if(ftpath.open(QIODevice::ReadOnly)){
37 QStringList list =
features.split(
" ");
48 if(mpath.open(QIODevice::ReadOnly)){
50 usbModel =
usbModel.remove(
"Corsair").remove(
"Gaming").remove(
"Keyboard").remove(
"Mouse").remove(
"Bootloader").trimmed();
55 if(spath.open(QIODevice::ReadOnly)){
62 if(
features.contains(
"fwversion") && fwpath.open(QIODevice::ReadOnly)){
67 if(
features.contains(
"pollrate") && ppath.open(QIODevice::ReadOnly)){
78 int fd = open(
cmdpath.toLatin1().constData(), O_WRONLY | O_NONBLOCK);
79 if(!
cmd.open(fd, QIODevice::WriteOnly, QFileDevice::AutoCloseHandle))
85 for(
int i = 1; i < 10; i++){
86 QString notify = QString(path +
"/notify%1").arg(i);
87 if(!QFile::exists(notify) && !
notifyPaths.contains(notify)){
102 for(
int i = 1; i < 10; i++){
103 QString notify = QString(path +
"/notify%1").arg(i);
104 if(!QFile::exists(notify) && !
notifyPaths.contains(notify)){
114 cmd.write(QString(
"dither %1\n").arg(static_cast<int>(
_dither)).toLatin1());
115 cmd.write(QString(
"\ndelay %1\n").arg(
_delay?
"on" :
"off").toLatin1());
118 cmd.write(
"layout ");
121 cmd.write(QString(
"accel %1\n").arg(QString(
_mouseAccel ?
"on" :
"off")).toLatin1());
124 cmd.write(QString(
"\nactive\n@%1 get :hwprofileid").arg(
notifyNumber).toLatin1());
127 cmd.write(QString(
" mode %1 get :hwid").arg(i + 1).toLatin1());
131 cmd.write(
" get :i :keys\n");
158 cmd.write(QString(
"idle\nnotifyoff %1\n").arg(
notifyNumber).toLatin1());
172 kb->
cmd.write(QString(
"fps %1\n").arg(newFrameRate).toLatin1());
189 cmd.write(
"layout ");
210 kb->
cmd.write(QString(
"dither %1\n").arg(static_cast<int>(newDither)).toLatin1());
222 kb->
cmd.write(QString(
"accel %1\n").arg(QString(newAccel ?
"on" :
"off")).toLatin1());
235 kb->
cmd.write(QString(
"scrollspeed %1\n").arg(newSpeed).toLatin1());
248 QString
current = settings.
value(
"CurrentProfile").toString().trimmed().toUpper();
249 foreach(QString guid, settings.
value(
"Profiles").toString().split(
" ")){
250 guid = guid.trimmed().toUpper();
254 if(guid == current || !newCurrentProfile)
255 newCurrentProfile = profile;
258 if(newCurrentProfile)
262 QSettings demoSettings(
":/txt/demoprofile.conf", QSettings::IniFormat,
this);
278 QString guids, currentGuid;
283 profile->
save(settings);
285 settings.
setValue(
"CurrentProfile", currentGuid);
286 settings.
setValue(
"Profiles", guids.trimmed());
290 quint64 now = QDateTime::currentMSecsSinceEpoch();
316 cmd.write(QString(
"\nmode %1").arg(i + 1).toLatin1());
320 cmd.write(
" switch");
323 cmd.write(QUrl::toPercentEncoding(mode->
name()));
340 cmd.write(
"hwsave\n");
355 cmd.write(
"eraseprofile");
357 cmd.write(
" profilename ");
359 cmd.write(
" profileid ");
370 cmd.write(
"fwupdate ");
371 cmd.write(path.toLatin1());
389 bool changed =
false;
412 index = 3 + index % 3;
415 cmd.write(QString(
"mode %1 switch ").arg(index + 1).toLatin1());
449 QThread::usleep(100000);
450 if(!notify.open(QIODevice::ReadOnly)){
452 QThread::usleep(900000);
453 for(
int i = 1; i < 10; i++){
454 if(notify.open(QIODevice::ReadOnly))
463 while(notify.isOpen() && (line = notify.readLine()).length() > 0){
464 QString text = QString::fromUtf8(line);
465 metaObject()->invokeMethod(
this,
"readNotify", Qt::QueuedConnection, Q_ARG(QString, text));
472 QStringList components = line.trimmed().split(
" ");
473 if(components.count() < 2)
475 if(components[0] ==
"key"){
477 QString
key = components[1];
480 QString keyName = key.mid(1);
481 bool keyPressed = (key[0] ==
'+');
487 }
else if(components[0] ==
"i"){
489 QString i = components[1];
492 QString iName = i.mid(1);
493 bool on = (i[0] ==
'+');
496 else if(iName ==
"caps")
498 else if(iName ==
"scroll")
500 }
else if(components[0] ==
"hwprofileid"){
502 if(components.count() < 3)
505 QString guid = components[1];
506 QString modified = components[2];
509 if(profile->
id().
guid == guid){
510 newProfile = profile;
518 cmd.write(QString(
"@%1 get :hwprofilename\n").arg(
notifyNumber).toLatin1());
527 cmd.write(QString(
"@%1 get :hwprofilename\n").arg(
notifyNumber).toLatin1());
538 }
else if(components[0] ==
"hwprofilename"){
540 QString name = QUrl::fromPercentEncoding(components[1].toUtf8());
544 if(!(oldName.length() >= name.length() && oldName.left(name.length()) == name)){
549 }
else if(components[0] ==
"mode"){
551 if(components.count() < 4)
553 int mode = components[1].toInt() - 1;
554 if(components[2] ==
"hwid"){
558 QString guid = components[3];
559 QString modified = components[4];
562 bool isUpdated =
false;
564 if(kbMode->
id().
guid == guid){
595 if(mode < _hwProfile->modeCount() && index != mode)
598 cmd.write(QString(
"@%1 mode %2 get :hwname :hwrgb").arg(
notifyNumber).arg(mode + 1).toLatin1());
600 cmd.write(
" :hwdpi :hwdpisel :hwlift :hwsnap");
604 }
else if(components[2] ==
"hwname"){
609 QString name = QUrl::fromPercentEncoding(components[3].toUtf8());
610 QString oldName = hwMode->
name();
611 if(!(oldName.length() >= name.length() && oldName.left(name.length()) == name)){
617 }
else if(components[2] ==
"hwrgb"){
624 QColor lightColor = QColor();
625 for(
int i = 3; i < components.count(); i++){
626 QString comp = components[i];
627 if(comp.indexOf(
":") < 0){
630 int rgb = comp.toInt(&ok, 16);
632 light->
color(QColor::fromRgb((QRgb)rgb));
635 QStringList set = comp.split(
":");
637 int rgb = set[1].toInt(&ok, 16);
639 QColor color = QColor::fromRgb((QRgb)rgb);
641 QStringList keys = set[0].split(
",");
642 foreach(QString
key, keys){
646 if(key.startsWith(
"dpi") && key.length() > 3){
649 int index = key.mid(3).toInt(&ok);
654 light->
color(key, color);
659 if(lightColor.isValid()){
660 light->
color(
"mr", lightColor);
661 light->
color(
"m1", lightColor);
662 light->
color(
"m2", lightColor);
663 light->
color(
"m3", lightColor);
664 light->
color(
"lock", lightColor);
666 }
else if(components[2] ==
"hwdpi"){
672 foreach(QString comp, components.mid(3)){
673 QStringList dpi = comp.split(
':');
674 if(dpi.length() != 2)
676 QStringList xy = dpi[1].split(
',');
684 x = y = xy[0].toInt();
690 int index = dpi[0].toInt();
707 perf->
dpi(index, QPoint(x, y));
710 }
else if(components[2] ==
"hwdpisel"){
715 int idx = components[3].toInt();
721 }
else if(components[2] ==
"hwlift"){
727 }
else if(components[3] ==
"hwsnap"){
734 }
else if(components[0] ==
"fwupdate"){
736 if(components.count() < 3)
741 QString res = components[2];
742 if(res ==
"invalid" || res ==
"fail")
748 if(!res.contains(
"/"))
750 QStringList numbers = res.split(
"/");
791 kb->
cmd.write(QString(
"\ndelay %1\n").arg(flag?
"on" :
"off").toLatin1());
KbMode * currentMode() const
static KeyMap::Layout layout()
void setValue(const QString &key, const QVariant &value)
const ModeList & modes() const
void setCurrentMode(KbProfile *profile, KbMode *mode, bool spontaneous=true)
QString modifiedString() const
QList< KbProfile * > _profiles
void frameUpdate(QFile &cmd, bool monochrome=false)
bool dpiEnabled(int index) const
static QSet< QString > notifyPaths
QVariant value(const QString &key, const QVariant &defaultValue=QVariant()) const
void writeProfileHeader()
QColor dpiColor(int index) const
bool iState[KbPerf::HW_I_COUNT]
static Model getModel(const QString &name)
QString guidString() const
void save(CkbSettings &settings)
height liftHeight() const
static QSet< Kb * > activeDevices
void setCurrentProfile(KbProfile *profile, bool spontaneous=true)
void animKeypress(const QString &key, bool down)
void append(KbMode *newMode)
void fwUpdate(const QString &path)
QPoint dpi(int index) const
static const int HWMODE_MAX
static QMutex notifyPathMutex
static const int DPI_COUNT
void color(const QString &key, const QColor &newColor)
void update(QFile &cmd, bool force=false)
void keyEvent(const QString &key, bool down)
void update(QFile &cmd, int notifyNumber, bool force, bool saveCustomDpi)
const QString & name() const
const KeyMap & keyMap() const
void modeChanged(bool spontaneous)
void applyIndicators(int modeIndex, const bool indicatorState[HW_I_COUNT])
bool hwLoading[HWMODE_MAX+1]
void fwUpdateProgress(int current, int total)
void move(int from, int to)
static KeyMap::Layout _layout
void fwUpdateFinished(bool succeeded)
int indexOf(KbMode *mode) const
void base(QFile &cmd, bool ignoreDim=false, bool monochrome=false)
int notifyNumber
notifyNumber is the trailing number in the device path.
Kb(QObject *parent, const QString &path)
static void fps(int framerate)
KbProfile * _currentProfile
void readNotify(QString line)
QString hwModifiedString() const