forked from denis/a811
Begin Macros and Battery
This commit is contained in:
parent
1808515221
commit
2cf36eb16e
|
|
@ -8,3 +8,6 @@ do make udev rule
|
||||||
write a nixos module that also sets udev rules
|
write a nixos module that also sets udev rules
|
||||||
|
|
||||||
install udev rule that automatically runs driver when you plug in the device??
|
install udev rule that automatically runs driver when you plug in the device??
|
||||||
|
|
||||||
|
irgendwie hab ich ne zeit lang timout beim config writen bekommen nachdem des config restored wurde bzw wo ich immer mal wireless und wire geswitched habe
|
||||||
|
nach reboot und write von original software gehts aber wieder
|
||||||
50
Untitled-1
Normal file
50
Untitled-1
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
GET_REPORT_RESPONSE
|
||||||
|
on batt; 40%
|
||||||
|
0000 00 0f ab 85 bd 9b ff ff 43 02 80 06 03 00 2d 00 ........C.....-.
|
||||||
|
0010 14 e2 d0 66 00 00 00 00 c5 39 00 00 00 00 00 00 ...f.....9......
|
||||||
|
0020 08 00 00 00 08 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
0030 00 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 ................
|
||||||
|
0040 05 90 11 30 00 00 00 00 ...0....
|
||||||
|
|
||||||
|
batt; 50%
|
||||||
|
0000 40 c2 9e 89 b9 9b ff ff 43 02 80 08 03 00 2d 00 @.......C.....-.
|
||||||
|
0010 a1 e8 d0 66 00 00 00 00 df 6b 0e 00 00 00 00 00 ...f.....k......
|
||||||
|
0020 08 00 00 00 08 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
0030 00 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 ................
|
||||||
|
0040 05 90 11 33 00 00 00 00 ...3....
|
||||||
|
|
||||||
|
|
||||||
|
cable, 40%?
|
||||||
|
0000 40 c8 9e 89 b9 9b ff ff 43 02 80 07 03 00 2d 00 @.......C.....-.
|
||||||
|
0010 ec e2 d0 66 00 00 00 00 eb 5e 0e 00 00 00 00 00 ...f.....^......
|
||||||
|
0020 08 00 00 00 08 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
0030 00 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 ................
|
||||||
|
0040 05 90 10 01 00 00 00 00 ........
|
||||||
|
|
||||||
|
50 90 11 52 bei 80% ein get report davor wars aber iwie 50 90 11 64
|
||||||
|
|
||||||
|
64 hex ist 100 dec what a coincidence lel guess it takes some time to figure out the voltage or w/e
|
||||||
|
|
||||||
|
50 90 11 61 bei 90% kein plan ob das wirklich 61 war
|
||||||
|
|
||||||
|
50 90 11 5f bei 90%
|
||||||
|
|
||||||
|
50 90 11 63 bei 90%
|
||||||
|
|
||||||
|
50 90 10 02 wenn maus voll und angesteckt
|
||||||
|
|
||||||
|
50 90 11 64 wenn wireless und 100%
|
||||||
|
|
||||||
|
50 90 10 01 wenn wired and loading
|
||||||
|
|
||||||
|
50 90 11 63 dann schon wird 90% angezeigt in software lol, wer weiß viellicht geht die maus bei 10 % aus
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
SET_REPORT
|
||||||
|
0000 80 50 68 0c b9 9b ff ff 53 02 00 09 03 00 00 00 .Ph.....S.......
|
||||||
|
0010 75 eb d0 66 00 00 00 00 ea bc 05 00 8d ff ff ff u..f............
|
||||||
|
0020 08 00 00 00 08 00 00 00 21 09 05 03 01 00 08 00 ........!.......
|
||||||
|
0030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
0040 05 40 01 00 00 00 00 00 .@......
|
||||||
|
restore
|
||||||
|
|
@ -229,6 +229,37 @@ Macros
|
||||||
wenn macro wird ein extra dingens an data geschrieben mit 0x08 0x30 am anfang
|
wenn macro wird ein extra dingens an data geschrieben mit 0x08 0x30 am anfang
|
||||||
für jedes Macro wird ein extra data geschrieben
|
für jedes Macro wird ein extra data geschrieben
|
||||||
|
|
||||||
|
wenn man versucht ein nicht existierendes bzw vorher gelöschtes zu schreiben wird resetet auf das was davor auf taste war
|
||||||
|
wird schon vor dem schreiben zurückgesetzt wenn man das macro aus der liste löscht instant
|
||||||
|
|
||||||
|
delays werden zusammengelegt wenn nacheinander inserted event# byte nr.3 is keycode, byt nr.1+2 für delay nach keyevent
|
||||||
|
das ist lustig die ersten 4 bit von byte 1 stehen für den down bzw up wenn 5 dann down event wenn d dann up event?
|
||||||
|
max delay 4095 bzw. 0xfff
|
||||||
|
|
||||||
|
Maximal 0xa8 (168) events (keyup or down)
|
||||||
|
|
||||||
|
Macros bleiben auf der maus bis sie überschrieben werden
|
||||||
|
|
||||||
|
-> so it is 3 bytes per key
|
||||||
|
|
||||||
|
GET_REPORT req 0x05 0x31 0xmacronr
|
||||||
|
|
||||||
|
0x00-0x03 -> 0x08 0x30 0x02 -> write macro SET_REPORT req
|
||||||
|
0x05-0x08 ? zeros
|
||||||
|
0x09 macro nummer,
|
||||||
|
aufsteigend nach reihenfolge wie in der liste wo man makros anlegt,
|
||||||
|
nach der erstellungsreihenfolge?, nach der tastenbelegungsreihenfolge!
|
||||||
|
0xa anzahl der key events
|
||||||
|
0xb key up down first four bits 5 for down d for up
|
||||||
|
0xc delay maybe not as ez
|
||||||
|
0xd keycode
|
||||||
|
|
||||||
|
0x9delay 0xdelay 0x01 für mouse up links
|
||||||
|
0x9delay 0xdelay 0x02 für mouse up rechts
|
||||||
|
0x1delay 0xdelay 0x01 für mouse down links
|
||||||
|
0x1delay 0xdelay 0x01 für mouse down rechts
|
||||||
|
|
||||||
|
|
||||||
So schaut ein get config von maus aus (GET_REPORT response)
|
So schaut ein get config von maus aus (GET_REPORT response)
|
||||||
für teil eins mit licht und so und nicht tasten
|
für teil eins mit licht und so und nicht tasten
|
||||||
|
|
||||||
|
|
@ -264,3 +295,5 @@ SET_REPORT request for getting the number 2 config
|
||||||
0020 08 00 00 00 08 00 00 00 21 09 05 03 01 00 08 00
|
0020 08 00 00 00 08 00 00 00 21 09 05 03 01 00 08 00
|
||||||
0030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
0030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||||
->0040 05 12 00 00 00 00 00 00
|
->0040 05 12 00 00 00 00 00 00
|
||||||
|
|
||||||
|
GET_REPORT req 0x05 0x80 -> get idle status 0x00 0x01 -> idle, 0x01 0x01 -> not idle,
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ target_sources(kirigami-hello
|
||||||
PRIVATE
|
PRIVATE
|
||||||
main.cpp
|
main.cpp
|
||||||
conf.cpp conf.h
|
conf.cpp conf.h
|
||||||
|
usb_thingy.cpp usb_thingy.h
|
||||||
)
|
)
|
||||||
|
|
||||||
ecm_target_qml_sources(kirigami-hello
|
ecm_target_qml_sources(kirigami-hello
|
||||||
|
|
|
||||||
103
src/Main.qml
103
src/Main.qml
|
|
@ -26,9 +26,33 @@ Kirigami.ApplicationWindow {
|
||||||
actions: [
|
actions: [
|
||||||
Kirigami.Action {
|
Kirigami.Action {
|
||||||
text: "fff"
|
text: "fff"
|
||||||
icon.name: "gtk-quit"
|
icon.name: "application-exit"
|
||||||
shortcut: StandardKey.Quit
|
shortcut: StandardKey.Quit
|
||||||
onTriggered: Conf.deviceConfig()
|
onTriggered: Conf.deviceConfig
|
||||||
|
},
|
||||||
|
Kirigami.Action {
|
||||||
|
text: "Save config"
|
||||||
|
icon.name: "document-save"
|
||||||
|
shortcut: StandardKey.Quit
|
||||||
|
onTriggered: Conf.writeConfigToFile()
|
||||||
|
},
|
||||||
|
Kirigami.Action {
|
||||||
|
text: "Open config"
|
||||||
|
icon.name: "document-open"
|
||||||
|
shortcut: StandardKey.Quit
|
||||||
|
onTriggered: Conf.readConfigFromFile()
|
||||||
|
},
|
||||||
|
Kirigami.Action {
|
||||||
|
text: "Reset Configuration"
|
||||||
|
icon.name: "edit-undo"
|
||||||
|
shortcut: StandardKey.Quit
|
||||||
|
onTriggered: Conf.restoreConfigs()
|
||||||
|
},
|
||||||
|
Kirigami.Action {
|
||||||
|
text: "Read Battery Status"
|
||||||
|
icon.name: "battery"
|
||||||
|
shortcut: StandardKey.Quit
|
||||||
|
onTriggered: Conf.batteryStatus()
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
@ -37,23 +61,68 @@ Kirigami.ApplicationWindow {
|
||||||
// This can also be set to an id of a Kirigami.Page
|
// This can also be set to an id of a Kirigami.Page
|
||||||
pageStack.initialPage: Kirigami.Page {
|
pageStack.initialPage: Kirigami.Page {
|
||||||
id: main
|
id: main
|
||||||
Controls.Label {
|
Kirigami.AbstractCard {
|
||||||
// Center label horizontally and vertically within parent object
|
Controls.Label {
|
||||||
anchors.centerIn: parent
|
// Center label horizontally and vertically within parent object
|
||||||
text: i18n("Hello World!")
|
anchors.centerIn: parent
|
||||||
}
|
text: i18n("Hello World!")
|
||||||
Controls.TextField {
|
|
||||||
placeholderText: qsTr("Enter name")
|
|
||||||
}
|
|
||||||
Component {
|
|
||||||
id: nameDelegate
|
|
||||||
Text {
|
|
||||||
text: model.display
|
|
||||||
font.pixelSize: 32
|
|
||||||
}
|
}
|
||||||
|
Controls.TextField {
|
||||||
|
placeholderText: qsTr("Enter name")
|
||||||
|
}
|
||||||
|
Component {
|
||||||
|
id: nameDelegate
|
||||||
|
Text {
|
||||||
|
text: model.display
|
||||||
|
font.pixelSize: 32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Controls.ProgressBar {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
from: 0
|
||||||
|
to: 100
|
||||||
|
value: Conf.batteryStatus
|
||||||
|
indeterminate: false
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
actions: [
|
actions: [
|
||||||
|
Kirigami.Action {
|
||||||
]
|
text: "test"
|
||||||
|
icon.name: "gtk-quit"
|
||||||
|
shortcut: StandardKey.Quit
|
||||||
|
onTriggered: Conf.readMacrosFromDevice()
|
||||||
|
},
|
||||||
|
Kirigami.Action {
|
||||||
|
text: "1"
|
||||||
|
icon.name: "gtk-quit"
|
||||||
|
shortcut: StandardKey.Quit
|
||||||
|
onTriggered: Conf.setLightMode(1)
|
||||||
|
},
|
||||||
|
Kirigami.Action {
|
||||||
|
text: "2"
|
||||||
|
icon.name: "gtk-quit"
|
||||||
|
shortcut: StandardKey.Quit
|
||||||
|
onTriggered: Conf.setLightMode(2)
|
||||||
|
},
|
||||||
|
Kirigami.Action {
|
||||||
|
text: "3"
|
||||||
|
icon.name: "gtk-quit"
|
||||||
|
shortcut: StandardKey.Quit
|
||||||
|
onTriggered: Conf.setLightMode(3)
|
||||||
|
},
|
||||||
|
Kirigami.Action {
|
||||||
|
text: "Apply Config %1".arg(Conf.lightMode)
|
||||||
|
icon.name: "gtk-quit"
|
||||||
|
shortcut: StandardKey.Quit
|
||||||
|
onTriggered: Conf.setDeviceConfig(1)
|
||||||
|
}
|
||||||
|
]
|
||||||
|
Connections {
|
||||||
|
target: Conf
|
||||||
|
onDeviceConfigChanged: {
|
||||||
|
showPassiveNotification("Device config applied."); // Show the notification
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
317
src/conf.cpp
317
src/conf.cpp
|
|
@ -1,11 +1,15 @@
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <qfiledialog.h>
|
||||||
|
#include <klocalizedstring.h>
|
||||||
|
|
||||||
Conf::Conf(QObject *parent) : QObject(parent)
|
Conf::Conf(QObject *parent) : QObject(parent)
|
||||||
{
|
{
|
||||||
m_conf1 = (conf_1 *)malloc(sizeof(conf_1));
|
m_conf1 = (conf_1 *)malloc(sizeof(conf_1));
|
||||||
m_conf2 = (conf_2 *)malloc(sizeof(conf_2));
|
m_conf2 = (conf_2 *)malloc(sizeof(conf_2));
|
||||||
|
memset(m_conf1, 0, 520);
|
||||||
|
memset(m_conf2, 0, 520);
|
||||||
|
|
||||||
int r = libusb_init(&m_ctx);
|
int r = libusb_init(&m_ctx);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
|
@ -22,66 +26,152 @@ Conf::Conf(QObject *parent) : QObject(parent)
|
||||||
m_device = device;
|
m_device = device;
|
||||||
libusb_device_descriptor desc;
|
libusb_device_descriptor desc;
|
||||||
libusb_get_device_descriptor(m_device, &desc);
|
libusb_get_device_descriptor(m_device, &desc);
|
||||||
if (desc.idProduct == 0x2f && desc.idVendor == 0x258a)
|
if ((desc.idProduct == 0x2f || desc.idProduct == 0x2e) && desc.idVendor == 0x258a)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//read initial config from device
|
// read initial config from device
|
||||||
readConfigFromDevice(m_conf1);
|
readConfigFromDevice(m_conf1);
|
||||||
readConfigFromDevice(m_conf2);
|
readConfigFromDevice(m_conf2);
|
||||||
|
|
||||||
libusb_free_device_list(list, 1);
|
libusb_free_device_list(list, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t Conf::lightMode(){
|
int Conf::lightMode()
|
||||||
|
{
|
||||||
return m_conf1->light_mode;
|
return m_conf1->light_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Conf::setLightMode(ssize_t mode){
|
void Conf::setLightMode(int mode)
|
||||||
m_conf1->light_mode = mode;
|
{
|
||||||
|
m_conf1->light_mode = (unsigned char)mode;
|
||||||
|
std::cout << (int)m_conf1->light_mode << std::endl;
|
||||||
Q_EMIT lightModeChanged();
|
Q_EMIT lightModeChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ssize_t Conf::restoreConfigs()
|
||||||
|
{
|
||||||
|
unsigned char send_data0[8];
|
||||||
|
memset(send_data0, 0, 8 * sizeof(unsigned char));
|
||||||
|
|
||||||
|
send_data0[0] = 0x05;
|
||||||
|
send_data0[1] = 0x40;
|
||||||
|
send_data0[2] = 0x01; // restore
|
||||||
|
|
||||||
|
int r = 0;
|
||||||
|
libusb_device_handle *handle;
|
||||||
|
if ((r = libusb_open(m_device, &handle)) < 0)
|
||||||
|
std::cout << "libusb_open: " << libusb_error_name(r) << std::endl;
|
||||||
|
|
||||||
|
if ((r = libusb_detach_kernel_driver(handle, 1)) < 0)
|
||||||
|
std::cout << "libusb_detach_kernel_driver: " << libusb_error_name(r) << std::endl;
|
||||||
|
if ((r = libusb_claim_interface(handle, 1)) < 0)
|
||||||
|
std::cout << "libusb_claim_interface: " << libusb_error_name(r) << std::endl;
|
||||||
|
|
||||||
|
if ((r = libusb_control_transfer(handle, 0x21, 0x09, 0x0305, 1, send_data0, 8, 5000)) < 0)
|
||||||
|
std::cout << "libusb_control_transfer3: " << libusb_error_name(r) << std::endl;
|
||||||
|
|
||||||
|
if ((r = libusb_release_interface(handle, 1)) < 0)
|
||||||
|
std::cout << "libusb_release_interface: " << libusb_error_name(r) << std::endl;
|
||||||
|
if ((r = libusb_attach_kernel_driver(handle, 1)) < 0)
|
||||||
|
std::cout << "libusb_attach_kernel_driver: " << libusb_error_name(r) << std::endl;
|
||||||
|
|
||||||
|
libusb_close(handle);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
ssize_t Conf::deviceConfig()
|
ssize_t Conf::deviceConfig()
|
||||||
{
|
{
|
||||||
conf_1 *conf = (conf_1 *)malloc(sizeof(conf_1));
|
unsigned char dat[520];
|
||||||
conf_2 *conf2 = (conf_2 *)malloc(sizeof(conf_2));
|
unsigned char send_data0[8];
|
||||||
|
memset(send_data0, 0, 8 * sizeof(unsigned char));
|
||||||
|
memset(dat, 0, 520 * sizeof(unsigned char));
|
||||||
|
send_data0[0] = 0x05;
|
||||||
|
send_data0[1] = 0x90; // conf 2, wireless
|
||||||
|
|
||||||
writeConfigToDevice(m_conf1);
|
// get config before write new config
|
||||||
|
// conf_1
|
||||||
|
int r = 0;
|
||||||
|
libusb_device_handle *handle;
|
||||||
|
if ((r = libusb_open(m_device, &handle)) < 0)
|
||||||
|
std::cout << "libusb_open: " << libusb_error_name(r) << std::endl;
|
||||||
|
|
||||||
// readConfigFromDevice(conf);
|
if ((r = libusb_detach_kernel_driver(handle, 1)) < 0)
|
||||||
readConfigFromFile("conf1.bin", conf);
|
std::cout << "libusb_detach_kernel_driver: " << libusb_error_name(r) << std::endl;
|
||||||
readConfigFromDevice(conf2);
|
if ((r = libusb_claim_interface(handle, 1)) < 0)
|
||||||
|
std::cout << "libusb_claim_interface: " << libusb_error_name(r) << std::endl;
|
||||||
|
|
||||||
// edit data
|
// conf_2
|
||||||
conf->light_mode = 0x1;
|
if ((r = libusb_control_transfer(handle, 0x21, 0x09, 0x0305, 1, send_data0, 8, 5000)) < 0)
|
||||||
conf->req_type = 0x92;
|
std::cout << "libusb_control_transfer3: " << libusb_error_name(r) << std::endl;
|
||||||
conf->st_brightness_colnr = {0x16};
|
if ((r = libusb_control_transfer(handle, 0xa1, 0x01, 0x0305, 1, (unsigned char *)dat, 8, 5000)) < 0)
|
||||||
conf->col_steady[18] = 0x00;
|
std::cout << "libusb_control_transfer4: " << libusb_error_name(r) << std::endl;
|
||||||
conf->col_steady[19] = 0xff;
|
|
||||||
conf->col_steady[20] = 0xff;
|
|
||||||
conf->col_breathing[0] = 0xff;
|
|
||||||
conf->col_breathing[1] = 0xff;
|
|
||||||
conf->col_breathing[2] = 0x00;
|
|
||||||
|
|
||||||
writeConfigToDevice(conf);
|
if ((r = libusb_release_interface(handle, 1)) < 0)
|
||||||
writeConfigToDevice(conf2);
|
std::cout << "libusb_release_interface: " << libusb_error_name(r) << std::endl;
|
||||||
|
if ((r = libusb_attach_kernel_driver(handle, 1)) < 0)
|
||||||
|
std::cout << "libusb_attach_kernel_driver: " << libusb_error_name(r) << std::endl;
|
||||||
|
|
||||||
writeConfigToFile(conf, "conf1.bin");
|
for (int i = 0; i < 16; i++)
|
||||||
writeConfigToFile(conf2, "conf2.bin");
|
{
|
||||||
|
std::cout << std::hex << (int)dat[i] << "\t";
|
||||||
|
}
|
||||||
|
std::cout << std::endl;
|
||||||
|
|
||||||
|
libusb_close(handle);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Conf::setDeviceConfig(ssize_t stat)
|
void Conf::setDeviceConfig(ssize_t stat)
|
||||||
{
|
{
|
||||||
|
std::cout << "Setting new conf" << std::endl;
|
||||||
|
writeConfigToDevice(m_conf1);
|
||||||
|
writeConfigToDevice(m_conf2);
|
||||||
Q_EMIT deviceConfigChanged();
|
Q_EMIT deviceConfigChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ssize_t Conf::writeConfigToFile(const char *filePath)
|
||||||
|
{
|
||||||
|
FILE *outfile;
|
||||||
|
outfile = fopen(filePath, "wb");
|
||||||
|
if (outfile == NULL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "\nError opened file\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
// write struct to file
|
||||||
|
int flag = 0;
|
||||||
|
flag = fwrite(m_conf1, sizeof(struct conf_1), 1, outfile);
|
||||||
|
|
||||||
|
if (flag)
|
||||||
|
{
|
||||||
|
printf("Contents of conf1 written "
|
||||||
|
"successfully %d\n",
|
||||||
|
flag);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
printf("Error Writing to File!\n");
|
||||||
|
|
||||||
|
flag = fwrite(m_conf2, sizeof(struct conf_2), 1, outfile);
|
||||||
|
|
||||||
|
if (flag)
|
||||||
|
{
|
||||||
|
printf("Contents of conf2 written "
|
||||||
|
"successfully %d\n",
|
||||||
|
flag);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
printf("Error Writing to File!\n");
|
||||||
|
|
||||||
|
fclose(outfile);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
ssize_t Conf::writeConfigToDevice(conf_2 *conf)
|
ssize_t Conf::writeConfigToDevice(conf_2 *conf)
|
||||||
{
|
{
|
||||||
int r = 0;
|
int r = 0;
|
||||||
|
|
@ -94,8 +184,9 @@ ssize_t Conf::writeConfigToDevice(conf_2 *conf)
|
||||||
if ((r = libusb_claim_interface(handle, 1)) < 0)
|
if ((r = libusb_claim_interface(handle, 1)) < 0)
|
||||||
std::cout << "libusb_claim_interface: " << libusb_error_name(r) << std::endl;
|
std::cout << "libusb_claim_interface: " << libusb_error_name(r) << std::endl;
|
||||||
|
|
||||||
// conf_1
|
// conf_2
|
||||||
if ((r = libusb_control_transfer(handle, 0x21, 0x09, 0x0308, 1, (unsigned char *)conf, 520, 5000)) < 0)
|
conf->req_type = 0x50;
|
||||||
|
if ((r = libusb_control_transfer(handle, 0x21, 0x09, 0x0308, 1, (unsigned char *)conf, 520, 1000)) < 0)
|
||||||
std::cout << "libusb_control_transfer5: " << libusb_error_name(r) << std::endl;
|
std::cout << "libusb_control_transfer5: " << libusb_error_name(r) << std::endl;
|
||||||
|
|
||||||
if ((r = libusb_release_interface(handle, 1)) < 0)
|
if ((r = libusb_release_interface(handle, 1)) < 0)
|
||||||
|
|
@ -121,7 +212,8 @@ ssize_t Conf::writeConfigToDevice(conf_1 *conf)
|
||||||
std::cout << "libusb_claim_interface: " << libusb_error_name(r) << std::endl;
|
std::cout << "libusb_claim_interface: " << libusb_error_name(r) << std::endl;
|
||||||
|
|
||||||
// conf_1
|
// conf_1
|
||||||
if ((r = libusb_control_transfer(handle, 0x21, 0x09, 0x0308, 1, (unsigned char *)conf, 520, 5000)) < 0)
|
conf->req_type = 0x92;
|
||||||
|
if ((r = libusb_control_transfer(handle, 0x21, 0x09, 0x0308, 1, (unsigned char *)conf, 520, 1000)) < 0)
|
||||||
std::cout << "libusb_control_transfer5: " << libusb_error_name(r) << std::endl;
|
std::cout << "libusb_control_transfer5: " << libusb_error_name(r) << std::endl;
|
||||||
|
|
||||||
if ((r = libusb_release_interface(handle, 1)) < 0)
|
if ((r = libusb_release_interface(handle, 1)) < 0)
|
||||||
|
|
@ -169,6 +261,114 @@ ssize_t Conf::readConfigFromDevice(conf_2 *conf)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ssize_t Conf::batteryStatus()
|
||||||
|
{
|
||||||
|
unsigned char dat[520];
|
||||||
|
unsigned char send_data0[8];
|
||||||
|
memset(send_data0, 0, 8 * sizeof(unsigned char));
|
||||||
|
memset(dat, 0, 520 * sizeof(unsigned char));
|
||||||
|
send_data0[0] = 0x05;
|
||||||
|
send_data0[1] = 0x90; // get battery status, wireless
|
||||||
|
|
||||||
|
// get config before write new config
|
||||||
|
// conf_1
|
||||||
|
int r = 0;
|
||||||
|
libusb_device_handle *handle;
|
||||||
|
if ((r = libusb_open(m_device, &handle)) < 0)
|
||||||
|
std::cout << "libusb_open: " << libusb_error_name(r) << std::endl;
|
||||||
|
|
||||||
|
if ((r = libusb_detach_kernel_driver(handle, 1)) < 0)
|
||||||
|
std::cout << "libusb_detach_kernel_driver: " << libusb_error_name(r) << std::endl;
|
||||||
|
if ((r = libusb_claim_interface(handle, 1)) < 0)
|
||||||
|
std::cout << "libusb_claim_interface: " << libusb_error_name(r) << std::endl;
|
||||||
|
|
||||||
|
// conf_2
|
||||||
|
if ((r = libusb_control_transfer(handle, 0x21, 0x09, 0x0305, 1, send_data0, 8, 5000)) < 0)
|
||||||
|
std::cout << "libusb_control_transfer3: " << libusb_error_name(r) << std::endl;
|
||||||
|
if ((r = libusb_control_transfer(handle, 0xa1, 0x01, 0x0305, 1, (unsigned char *)dat, 8, 5000)) < 0)
|
||||||
|
std::cout << "libusb_control_transfer4: " << libusb_error_name(r) << std::endl;
|
||||||
|
|
||||||
|
if ((r = libusb_release_interface(handle, 1)) < 0)
|
||||||
|
std::cout << "libusb_release_interface: " << libusb_error_name(r) << std::endl;
|
||||||
|
if ((r = libusb_attach_kernel_driver(handle, 1)) < 0)
|
||||||
|
std::cout << "libusb_attach_kernel_driver: " << libusb_error_name(r) << std::endl;
|
||||||
|
|
||||||
|
for (int i = 0; i < 16; i++)
|
||||||
|
{
|
||||||
|
std::cout << std::hex << (int)dat[i] << "\t";
|
||||||
|
}
|
||||||
|
std::cout << std::endl;
|
||||||
|
|
||||||
|
libusb_close(handle);
|
||||||
|
|
||||||
|
if (dat[2] == 0x10 && dat[3] == 0x01)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return (int)dat[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Conf::setBatteryStatus(ssize_t bat)
|
||||||
|
{
|
||||||
|
m_bat = batteryStatus();
|
||||||
|
Q_EMIT batteryStatusChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t Conf::readAssignedMacrosFromDevice()
|
||||||
|
{
|
||||||
|
// check all the keys for macro mod
|
||||||
|
int macroCnt = 0;
|
||||||
|
for (int i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
if (m_conf2->side[i].pref == 0x70 || (m_conf2->mouse_buttons[i].pref == 0x70 && i < 6))
|
||||||
|
macroCnt++;
|
||||||
|
}
|
||||||
|
std::cout << macroCnt << std::endl;
|
||||||
|
|
||||||
|
unsigned char conf[520];
|
||||||
|
unsigned char send_data0[8];
|
||||||
|
memset(send_data0, 0, 8 * sizeof(unsigned char));
|
||||||
|
send_data0[0] = 0x05;
|
||||||
|
send_data0[1] = 0x31; // macro, wireless
|
||||||
|
send_data0[2] = 0x01; // macro nr
|
||||||
|
|
||||||
|
int r = 0;
|
||||||
|
|
||||||
|
libusb_device_handle *handle;
|
||||||
|
if ((r = libusb_open(m_device, &handle)) < 0)
|
||||||
|
std::cout << "libusb_open: " << libusb_error_name(r) << std::endl;
|
||||||
|
|
||||||
|
if ((r = libusb_detach_kernel_driver(handle, 1)) < 0)
|
||||||
|
std::cout << "libusb_detach_kernel_driver: " << libusb_error_name(r) << std::endl;
|
||||||
|
if ((r = libusb_claim_interface(handle, 1)) < 0)
|
||||||
|
std::cout << "libusb_claim_interface: " << libusb_error_name(r) << std::endl;
|
||||||
|
|
||||||
|
for (int i = 0; i < macroCnt; i++)
|
||||||
|
{
|
||||||
|
send_data0[2] = i;
|
||||||
|
// get macro
|
||||||
|
|
||||||
|
if ((r = libusb_control_transfer(handle, 0x21, 0x09, 0x0305, 1, send_data0, 8, 5000)) < 0)
|
||||||
|
std::cout << "libusb_control_transfer3: " << libusb_error_name(r) << std::endl;
|
||||||
|
if ((r = libusb_control_transfer(handle, 0xa1, 0x01, 0x0308, 1, (unsigned char *)conf, 520, 5000)) < 0)
|
||||||
|
std::cout << "libusb_control_transfer4: " << libusb_error_name(r) << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((r = libusb_release_interface(handle, 1)) < 0)
|
||||||
|
std::cout << "libusb_release_interface: " << libusb_error_name(r) << std::endl;
|
||||||
|
if ((r = libusb_attach_kernel_driver(handle, 1)) < 0)
|
||||||
|
std::cout << "libusb_attach_kernel_driver: " << libusb_error_name(r) << std::endl;
|
||||||
|
|
||||||
|
for (int i = 0; i < 520; i++)
|
||||||
|
{
|
||||||
|
std::cout << std::hex << (int)conf[i] << "\t";
|
||||||
|
}
|
||||||
|
std::cout << std::endl;
|
||||||
|
|
||||||
|
libusb_close(handle);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
ssize_t Conf::readConfigFromDevice(conf_1 *conf)
|
ssize_t Conf::readConfigFromDevice(conf_1 *conf)
|
||||||
{
|
{
|
||||||
unsigned char send_data0[8];
|
unsigned char send_data0[8];
|
||||||
|
|
@ -205,30 +405,10 @@ ssize_t Conf::readConfigFromDevice(conf_1 *conf)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t Conf::writeConfigToFile(conf_1 *conf, const char *filePath)
|
ssize_t Conf::writeConfigToFile()
|
||||||
{
|
{
|
||||||
FILE *outfile;
|
QString path = QFileDialog::getSaveFileName(nullptr, i18n("Save File As"));
|
||||||
outfile = fopen(filePath, "wb");
|
writeConfigToFile(path.toUtf8().constData());
|
||||||
if (outfile == NULL)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "\nError opened file\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
// write struct to file
|
|
||||||
int flag = 0;
|
|
||||||
flag = fwrite(conf, sizeof(struct conf_1), 1, outfile);
|
|
||||||
|
|
||||||
if (flag)
|
|
||||||
{
|
|
||||||
printf("Contents of the structure written "
|
|
||||||
"successfully %d\n",
|
|
||||||
flag);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
printf("Error Writing to File!\n");
|
|
||||||
|
|
||||||
fclose(outfile);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -281,6 +461,7 @@ ssize_t Conf::readConfigFromFile(const char *filePath, conf_1 *conf)
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t Conf::readConfigFromFile(const char *filePath, conf_2 *conf)
|
ssize_t Conf::readConfigFromFile(const char *filePath, conf_2 *conf)
|
||||||
|
|
||||||
{
|
{
|
||||||
FILE *infile;
|
FILE *infile;
|
||||||
|
|
||||||
|
|
@ -300,3 +481,33 @@ ssize_t Conf::readConfigFromFile(const char *filePath, conf_2 *conf)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ssize_t Conf::readConfigFromFile(const char *filePath)
|
||||||
|
{
|
||||||
|
FILE *infile;
|
||||||
|
|
||||||
|
infile = fopen(filePath, "rb");
|
||||||
|
if (infile == NULL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "\nError opening file\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
fread(m_conf1, sizeof(struct conf_1), 1, infile);
|
||||||
|
fread(m_conf2, sizeof(struct conf_2), 1, infile);
|
||||||
|
|
||||||
|
fclose(infile);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t Conf::readConfigFromFile()
|
||||||
|
{
|
||||||
|
QFileDialog dialog(nullptr);
|
||||||
|
dialog.setFileMode(QFileDialog::AnyFile);
|
||||||
|
dialog.setNameFilter(tr("Images (*.bin *.xpm *.jpg)"));
|
||||||
|
dialog.setAcceptMode(QFileDialog::AcceptOpen);
|
||||||
|
QString path = dialog.getOpenFileName(nullptr, i18n("Select Configuration"));
|
||||||
|
readConfigFromFile(path.toUtf8().constData());
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
35
src/conf.h
35
src/conf.h
|
|
@ -13,6 +13,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "structs.h"
|
#include "structs.h"
|
||||||
#include <libusb-1.0/libusb.h>
|
#include <libusb-1.0/libusb.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#define CONF_FILE "conf.bin"
|
#define CONF_FILE "conf.bin"
|
||||||
|
|
||||||
|
|
@ -20,7 +21,8 @@ class Conf : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(ssize_t deviceConfig READ deviceConfig WRITE setDeviceConfig NOTIFY deviceConfigChanged)
|
Q_PROPERTY(ssize_t deviceConfig READ deviceConfig WRITE setDeviceConfig NOTIFY deviceConfigChanged)
|
||||||
Q_PROPERTY(ssize_t lightMode READ lightMode WRITE setLightMode NOTIFY lightModeChanged)
|
Q_PROPERTY(int lightMode READ lightMode WRITE setLightMode NOTIFY lightModeChanged)
|
||||||
|
Q_PROPERTY(ssize_t batteryStatus READ batteryStatus WRITE setBatteryStatus NOTIFY batteryStatusChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Conf(QObject *parent = nullptr);
|
explicit Conf(QObject *parent = nullptr);
|
||||||
|
|
@ -28,10 +30,18 @@ public:
|
||||||
Q_INVOKABLE void setDeviceConfig(ssize_t stat);
|
Q_INVOKABLE void setDeviceConfig(ssize_t stat);
|
||||||
Q_SIGNAL void deviceConfigChanged();
|
Q_SIGNAL void deviceConfigChanged();
|
||||||
|
|
||||||
ssize_t lightMode();
|
int lightMode();
|
||||||
Q_INVOKABLE void setLightMode(ssize_t mode);
|
Q_INVOKABLE void setLightMode(int mode);
|
||||||
Q_SIGNAL void lightModeChanged();
|
Q_SIGNAL void lightModeChanged();
|
||||||
|
|
||||||
|
Q_INVOKABLE ssize_t restoreConfigs();
|
||||||
|
|
||||||
|
Q_INVOKABLE ssize_t writeConfigToFile();
|
||||||
|
ssize_t writeConfigToFile(const char* filePath);
|
||||||
|
Q_INVOKABLE ssize_t readConfigFromFile();
|
||||||
|
ssize_t readConfigFromFile(const char* filePath);
|
||||||
|
|
||||||
|
//all the config should be in a single file
|
||||||
ssize_t writeConfigToFile(conf_1 *conf, const char *filePath);
|
ssize_t writeConfigToFile(conf_1 *conf, const char *filePath);
|
||||||
ssize_t writeConfigToFile(conf_2 *conf, const char *filePath);
|
ssize_t writeConfigToFile(conf_2 *conf, const char *filePath);
|
||||||
ssize_t readConfigFromFile(const char *filePath, conf_1 *conf);
|
ssize_t readConfigFromFile(const char *filePath, conf_1 *conf);
|
||||||
|
|
@ -41,15 +51,24 @@ public:
|
||||||
ssize_t readConfigFromDevice(conf_1 *conf);
|
ssize_t readConfigFromDevice(conf_1 *conf);
|
||||||
ssize_t readConfigFromDevice(conf_2 *conf);
|
ssize_t readConfigFromDevice(conf_2 *conf);
|
||||||
|
|
||||||
|
Q_INVOKABLE ssize_t readAssignedMacrosFromDevice();
|
||||||
|
|
||||||
|
ssize_t batteryStatus();
|
||||||
|
Q_INVOKABLE void setBatteryStatus(ssize_t bat);
|
||||||
|
Q_SIGNAL void batteryStatusChanged();
|
||||||
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ssize_t m_stat;
|
ssize_t m_stat;
|
||||||
ssize_t m_lightMode;
|
ssize_t m_bat;
|
||||||
conf_1* m_conf1;
|
int m_lightMode;
|
||||||
conf_2* m_conf2;
|
conf_1 *m_conf1;
|
||||||
libusb_device* m_device = NULL;
|
conf_2 *m_conf2;
|
||||||
libusb_context* m_ctx = NULL;
|
libusb_device *m_device = NULL;
|
||||||
|
libusb_context *m_ctx = NULL;
|
||||||
|
QString m_fileName;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -40,28 +40,31 @@ struct key_conf
|
||||||
|
|
||||||
struct conf_2
|
struct conf_2
|
||||||
{
|
{
|
||||||
uint8_t __u1; // 0x00 0x08
|
uint8_t __u1; // 0x00 0x08
|
||||||
uint8_t con; // wireless 22 wired 12
|
uint8_t con; // wireless 22 wired 12
|
||||||
uint8_t __u2; // 0x02 zero
|
uint8_t __u2; // 0x02 zero
|
||||||
uint8_t req_type; // 0x92, 0x50 maybe for if write or read 0x00
|
uint8_t req_type; // 0x92, 0x50 maybe for if write or read 0x00
|
||||||
uint8_t __u3[0x8 - 0x4]; // 0x04-0x07 zeroes
|
uint8_t __u3[0x8 - 0x4]; // 0x04-0x07 zeroes
|
||||||
key_conf l_mouse; // 0x08-0x0b 4 Byte für linke Maustaste
|
key_conf mouse_buttons[6];
|
||||||
|
/*key_conf l_mouse; // 0x08-0x0b 4 Byte für linke Maustaste
|
||||||
key_conf r_mouse; // 0x0c-0x0f 4 Byte für rechte Maustaste
|
key_conf r_mouse; // 0x0c-0x0f 4 Byte für rechte Maustaste
|
||||||
key_conf m_mouse; // 0x10-0x13 4 Byte für Mausrad taste
|
key_conf m_mouse; // 0x10-0x13 4 Byte für Mausrad taste
|
||||||
key_conf b_mouse; // 0x14-0x17 4 Byte für taste 13, Zurück Taste, über taste 5,6
|
key_conf b_mouse; // 0x14-0x17 4 Byte für taste 13, Zurück Taste, über taste 5,6
|
||||||
key_conf f_mouse; // 0x18-0x1b 4 Byte für taste 12, Forward Taste, über taste 2,4
|
key_conf f_mouse; // 0x18-0x1b 4 Byte für taste 12, Forward Taste, über taste 2,4
|
||||||
key_conf m_mouse_1; // 0x1c-0x1f 4 Byte für taste 14, 1. über mausrad
|
key_conf m_mouse_1; // 0x1c-0x1f 4 Byte für taste 14, 1. über mausrad
|
||||||
key_conf m_mouse_2; // 0x20-0x23 4 Byte für taste 15, 2. über mausrad
|
key_conf m_mouse_2;*/
|
||||||
|
// 0x20-0x23 4 Byte für taste 15, 2. über mausrad
|
||||||
uint8_t __u4[4]; // 0x24-0x27 zeros
|
uint8_t __u4[4]; // 0x24-0x27 zeros
|
||||||
key_conf side[8]; // Jeweils 4 Byte (3 Sicher) für die Belegung der Tasten 1-8 an der Seite
|
key_conf side[8]; // Jeweils 4 Byte (3 Sicher) für die Belegung der Tasten 1-8 an der Seite
|
||||||
uint8_t __u5[0x207 - 0x47]; // 0x48-0x58 ?? 0x58-end zeros
|
uint8_t __u5[0x207 - 0x47]; // 0x48-0x58 ?? 0x58-end zeros
|
||||||
};
|
};
|
||||||
|
|
||||||
struct macro {
|
struct macro
|
||||||
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
struct conf_12 {
|
struct conf_12
|
||||||
|
{
|
||||||
conf_1 c1;
|
conf_1 c1;
|
||||||
conf_2 c2;
|
conf_2 c2;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
25
src/usb_thingy.cpp
Normal file
25
src/usb_thingy.cpp
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
/*S::S()
|
||||||
|
{
|
||||||
|
int r = libusb_init(&ctx);
|
||||||
|
if (r < 0)
|
||||||
|
{
|
||||||
|
std::cout << libusb_error_name(r) << std::endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
libusb_device **list;
|
||||||
|
ssize_t cnt = libusb_get_device_list(ctx, &list);
|
||||||
|
|
||||||
|
for (ssize_t i = 0; i < cnt; i++)
|
||||||
|
{
|
||||||
|
libusb_device *device = list[i];
|
||||||
|
libusb_device_descriptor desc;
|
||||||
|
libusb_get_device_descriptor(device, &desc);
|
||||||
|
if ((desc.idProduct == 0x2f || desc.idProduct == 0x2e) && desc.idVendor == 0x258a)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}*/
|
||||||
34
src/usb_thingy.h
Normal file
34
src/usb_thingy.h
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
class S
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static S& getInstance()
|
||||||
|
{
|
||||||
|
static S instance; // Guaranteed to be destroyed.
|
||||||
|
// Instantiated on first use.
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
S() {} // Constructor? (the {} brackets) are needed here.
|
||||||
|
|
||||||
|
// C++ 03
|
||||||
|
// ========
|
||||||
|
// Don't forget to declare these two. You want to make sure they
|
||||||
|
// are inaccessible(especially from outside), otherwise, you may accidentally get copies of
|
||||||
|
// your singleton appearing.
|
||||||
|
S(S const&); // Don't Implement
|
||||||
|
void operator=(S const&); // Don't implement
|
||||||
|
|
||||||
|
// C++ 11
|
||||||
|
// =======
|
||||||
|
// We can use the better technique of deleting the methods
|
||||||
|
// we don't want.
|
||||||
|
public:
|
||||||
|
S(S const&) = delete;
|
||||||
|
void operator=(S const&) = delete;
|
||||||
|
|
||||||
|
// Note: Scott Meyers mentions in his Effective Modern
|
||||||
|
// C++ book, that deleted functions should generally
|
||||||
|
// be public as it results in better error messages
|
||||||
|
// due to the compilers behavior to check accessibility
|
||||||
|
// before deleted status
|
||||||
|
};
|
||||||
Loading…
Reference in a new issue