Skip to content

Commit 8eac65d

Browse files
Replace libusb with libhidapi to get MSI SteelSeries 3-zone laptop keyboards working in Linux
1 parent 5650ac2 commit 8eac65d

File tree

9 files changed

+52
-86
lines changed

9 files changed

+52
-86
lines changed

KeyboardVisualizer.pro

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,17 @@ greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
1111
TARGET = KeyboardVisualizer
1212
TEMPLATE = app
1313

14-
LIBS += -lopenal -lusb
14+
LIBS += -lopenal
15+
16+
packagesExist(hidapi-libusb) {
17+
unix:LIBS += -lhidapi-libusb
18+
} else {
19+
packagesExist(hidapi) {
20+
unix:LIBS += -lhidapi
21+
} else {
22+
unix:LIBS += -lhidapi-libusb
23+
}
24+
}
1525

1626
DISTFILES +=
1727

KeyboardVisualizerCommon/CorsairCKBLinux.cpp

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,14 @@
66
#include <string.h>
77
#include <unistd.h>
88

9-
const static int led_matrix_c[7][22]
10-
{//Col Pos: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
11-
/*Row 0*/ { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 137, 8, 255, 255, 20, 255, 255 },
12-
/*Row 1*/ { 255, 0, 255, 12, 24, 36, 48, 60, 72, 84, 96, 108, 120, 132, 6, 18, 30, 42, 32, 44, 56, 68 }, //68
13-
/*Row 2*/ { 255, 1, 13, 25, 37, 49, 61, 73, 85, 97, 109, 121, 133, 7, 31, 54, 66, 78, 80, 92, 104, 116 }, //116
14-
/*Row 3*/ { 255, 2, 14, 26, 38, 50, 62, 74, 86, 98, 110, 122, 134, 90, 102, 43, 55, 67, 9, 21, 33, 128 }, //128
15-
/*Row 4*/ { 255, 3, 15, 27, 39, 51, 63, 75, 87, 99, 111, 123, 135, 114, 126, 255, 255, 255, 57, 69, 81, 128 },
16-
/*Row 5*/ { 255, 4, 16, 28, 40, 52, 64, 76, 88, 100, 112, 124, 136, 255, 79, 255, 103, 255, 93, 105, 117, 140 },
17-
/*Row 6*/ { 255, 5, 17, 29, 255, 255, 255, 53, 255, 255, 255, 89, 101, 113, 91, 115, 127, 139, 255, 129, 141, 140 }
18-
};
19-
209
CorsairCKB::CorsairCKB()
2110
{
2211

2312
}
2413

2514
void CorsairCKB::Initialize()
2615
{
16+
/*
2717
char activate_cmd[] = "activate\n";
2818
char dither_cmd[] = "dither 1\n";
2919
@@ -34,6 +24,7 @@ void CorsairCKB::Initialize()
3424
write(corsair_fd, activate_cmd, strlen(activate_cmd));
3525
write(corsair_fd, dither_cmd, strlen(dither_cmd));
3626
}
27+
*/
3728
}
3829

3930
bool CorsairCKB::SetLEDs(COLORREF pixels[64][256])

KeyboardVisualizerCommon/MSIKeyboard.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ bool MSIKeyboard::SetLEDs(COLORREF pixels[64][256])
3939
//Shout out to bparker06 for reverse engineering the MSI keyboard USB protocol!
4040
// https://github.com/bparker06/msi-keyboard/blob/master/keyboard.cpp for original implementation
4141

42+
if(!init_ok)
43+
{
44+
return false;
45+
}
46+
4247
unsigned char buf[8] = { 0 };
4348

4449
buf[0] = 1;

KeyboardVisualizerCommon/RazerChromaLinux.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ void RazerChroma::Initialize()
8484

8585
if(dir == NULL)
8686
{
87+
driver_to_read++;
8788
continue;
8889
}
8990

KeyboardVisualizerCommon/UsbDevice.cpp

Lines changed: 10 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
//Helper functions for native Windows USB
44
//These functions courtesy of http://www.reddit.com/user/chrisgzy
5-
#if defined(WIN32) && !defined(LIBUSB)
5+
#if defined(WIN32) && !defined(HIDAPI)
66
#pragma comment(lib, "hid.lib")
77
#pragma comment(lib, "setupapi.lib")
88

@@ -94,32 +94,6 @@ HANDLE GetDeviceHandle(unsigned int uiVID, unsigned int uiPID, unsigned int uiMI
9494

9595
return hReturn;
9696
}
97-
#elif defined(LIBUSB)
98-
static struct usb_device *find_device(uint16_t vendor, uint16_t product)
99-
{
100-
struct usb_bus *bus;
101-
struct usb_device *dev;
102-
struct usb_bus *busses;
103-
104-
usb_init();
105-
usb_find_busses();
106-
usb_find_devices();
107-
108-
busses = usb_get_busses();
109-
110-
for (bus = busses; bus; bus = bus->next)
111-
{
112-
for (dev = bus->devices; dev; dev = dev->next)
113-
{
114-
if ((dev->descriptor.idVendor == vendor) && (dev->descriptor.idProduct == product))
115-
{
116-
return dev;
117-
}
118-
}
119-
}
120-
121-
return NULL;
122-
}
12397
#endif
12498

12599
UsbDevice::UsbDevice()
@@ -129,48 +103,31 @@ UsbDevice::UsbDevice()
129103

130104
bool UsbDevice::OpenDevice(unsigned short vendor, unsigned short product, unsigned int MI)
131105
{
132-
#ifdef LIBUSB
133-
device = find_device(vendor, product);
106+
#ifdef HIDAPI
107+
device = hid_open(vendor, product, 0);
134108

135109
if (device == NULL)
136110
{
137-
return FALSE;
138-
}
139-
140-
handle = usb_open(device);
141-
142-
if (handle == NULL)
143-
{
144-
return FALSE;
145-
}
146-
147-
#ifndef WIN32
148-
status = usb_claim_interface(handle, MI);
149-
status = usb_detach_kernel_driver_np(handle, MI);
150-
151-
if (status != 0)
152-
{
153-
return FALSE;
111+
return false;
154112
}
155-
#endif //WIN32
156113

157-
return TRUE;
114+
return true;
158115
#elif defined(WIN32)
159116
handle = GetDeviceHandle(vendor, product, MI);
160117

161118
if (handle == NULL)
162119
{
163-
return FALSE;
120+
return false;
164121
}
165122
#endif
166123
}
167124

168125
bool UsbDevice::SendToDevice(unsigned char* data, unsigned int length)
169126
{
170-
#ifdef LIBUSB
171-
usb_control_msg(handle, 0x21, 0x09 0x0300, 0x03, data, length, 1000);
172-
return TRUE;
127+
#ifdef HIDAPI
128+
hid_send_feature_report(device, data, length);
129+
return true;
173130
#elif defined(WIN32)
174131
return(HidD_SetFeature(handle, data, length));
175132
#endif
176-
}
133+
}

KeyboardVisualizerCommon/UsbDevice.h

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
#ifndef USB_DEVICE_H
22
#define USB_DEVICE_H
33

4-
#ifdef LIBUSB
5-
#include <usb.h>
4+
#define HIDAPI
5+
6+
#include <cstdio>
7+
#ifdef HIDAPI
8+
#include <hidapi/hidapi.h>
69
#elif defined(WIN32)
710
#include <sstream>
811
#include <wchar.h>
@@ -26,12 +29,11 @@ class UsbDevice
2629
bool SendToDevice(unsigned char* data, unsigned int length);
2730

2831
private:
29-
#ifdef LIBUSB
30-
struct usb_device* device
31-
struct usb_device_handle* handle;
32+
#ifdef HIDAPI
33+
hid_device* device;
3234
#elif defined(WIN32)
33-
HANDLE handle;
35+
HANDLE handle;
3436
#endif
3537

3638
};
37-
#endif
39+
#endif

KeyboardVisualizerCommon/Visualizer.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
//Includes for devices supported only under Linux
2929
#else
3030
#include "RazerChromaLinux.h"
31-
//#include "CorsairCKBLinux.h"
31+
#include "CorsairCKBLinux.h"
3232
#endif
3333

3434
//Includes for devices supported on both Windows and Linux
@@ -43,7 +43,7 @@ CmKeyboard cmkb;
4343

4444
//Devices supported only under Linux
4545
#else
46-
//CorsairCKB ckb;
46+
CorsairCKB ckb;
4747
#endif
4848

4949
//Devices supported on both Windows and Linux
@@ -218,7 +218,7 @@ void Visualizer::Initialize()
218218

219219
//Initialize devices supported by both Windows and Linux
220220
rkb.Initialize();
221-
//ckb.Initialize();
221+
ckb.Initialize();
222222
skb.Initialize();
223223
mkb.Initialize();
224224

KeyboardVisualizerQT/KeyboardVisDlg.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,43 +29,43 @@ void KeyboardVisDlg::show()
2929
ui->lineEdit_Decay->setText(QString::number(vis_ptr->decay));
3030
ui->lineEdit_Delay->setText(QString::number(vis_ptr->delay));
3131

32-
ui->comboBox_FFT_Window_Mode->blockSignals(TRUE);
32+
ui->comboBox_FFT_Window_Mode->blockSignals(true);
3333
ui->comboBox_FFT_Window_Mode->addItem("None");
3434
ui->comboBox_FFT_Window_Mode->addItem("Hanning");
3535
ui->comboBox_FFT_Window_Mode->addItem("Hamming");
3636
ui->comboBox_FFT_Window_Mode->addItem("Blackman");
3737
ui->comboBox_FFT_Window_Mode->setCurrentIndex(vis_ptr->window_mode);
38-
ui->comboBox_FFT_Window_Mode->blockSignals(FALSE);
38+
ui->comboBox_FFT_Window_Mode->blockSignals(false);
3939

40-
ui->comboBox_Background_Mode->blockSignals(TRUE);
40+
ui->comboBox_Background_Mode->blockSignals(true);
4141
for(int i = 0; i < VISUALIZER_NUM_PATTERNS; i++)
4242
{
4343
ui->comboBox_Background_Mode->addItem(visualizer_pattern_labels[i]);
4444
}
4545
ui->comboBox_Background_Mode->setCurrentIndex(vis_ptr->bkgd_mode);
46-
ui->comboBox_Background_Mode->blockSignals(FALSE);
46+
ui->comboBox_Background_Mode->blockSignals(false);
4747

48-
ui->comboBox_Foreground_Mode->blockSignals(TRUE);
48+
ui->comboBox_Foreground_Mode->blockSignals(true);
4949
for(int i = 0; i < VISUALIZER_NUM_PATTERNS; i++)
5050
{
5151
ui->comboBox_Foreground_Mode->addItem(visualizer_pattern_labels[i]);
5252
}
5353
ui->comboBox_Foreground_Mode->setCurrentIndex(vis_ptr->frgd_mode);
54-
ui->comboBox_Foreground_Mode->blockSignals(FALSE);
54+
ui->comboBox_Foreground_Mode->blockSignals(false);
5555

56-
ui->comboBox_Single_Color_Mode->blockSignals(TRUE);
56+
ui->comboBox_Single_Color_Mode->blockSignals(true);
5757
for(int i = 0; i < VISUALIZER_NUM_SINGLE_COLOR; i++)
5858
{
5959
ui->comboBox_Single_Color_Mode->addItem(visualizer_single_color_labels[i]);
6060
}
6161
ui->comboBox_Single_Color_Mode->setCurrentIndex(vis_ptr->single_color_mode);
62-
ui->comboBox_Single_Color_Mode->blockSignals(FALSE);
62+
ui->comboBox_Single_Color_Mode->blockSignals(false);
6363

64-
ui->comboBox_Average_Mode->blockSignals(TRUE);
64+
ui->comboBox_Average_Mode->blockSignals(true);
6565
ui->comboBox_Average_Mode->addItem("Binning");
6666
ui->comboBox_Average_Mode->addItem("Low Pass");
6767
ui->comboBox_Average_Mode->setCurrentIndex(vis_ptr->avg_mode);
68-
ui->comboBox_Average_Mode->blockSignals(FALSE);
68+
ui->comboBox_Average_Mode->blockSignals(false);
6969

7070
timer = new QTimer(this);
7171
connect(timer, SIGNAL(timeout()), this, SLOT(update()));

KeyboardVisualizerQT/main.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ void parse_argument_string(char * argument, char * value)
1515
{
1616
if (strcmp(argument, "startminimized") == 0)
1717
{
18-
startminimized = TRUE;
18+
startminimized = true;
1919
}
2020

2121
if (strcmp(argument, "amplitude") == 0)

0 commit comments

Comments
 (0)