SHOW:
|
|
- or go back to the newest paste.
1 | // | |
2 | // Simple hack to change dpi on Logitech G400s | |
3 | // G400s only support: 400, 800, 1600, 2000 and 4000 dpi, all other are interpolate by software | |
4 | // | |
5 | // Based on g400_hack from Przemek Aksamit | |
6 | // https://bitbucket.org/extaliones/g400_hack/src | |
7 | // | |
8 | // gcc -lusb-1.0 -o g400s_hack g400s_hack.c | |
9 | // | |
10 | ||
11 | #include <stdio.h> | |
12 | #include <stdlib.h> | |
13 | #include <string.h> | |
14 | #include <libusb-1.0/libusb.h> | |
15 | ||
16 | #define G400S_VENDOR_ID 0x046d | |
17 | #define G400S_PRODUCT_ID 0xc24c | |
18 | ||
19 | #define EXIT_SUCCESS 0 | |
20 | #define EXIT_ERROR_ARGS 1 | |
21 | #define EXIT_ERROR_DEVICE 2 | |
22 | #define EXIT_ERROR_KERNEL 3 | |
23 | #define EXIT_ERROR_CLAIM 4 | |
24 | #define EXIT_ERROR_WRITE 5 | |
25 | ||
26 | ||
27 | libusb_context *ctx = NULL; | |
28 | libusb_device_handle *handle = NULL; | |
29 | ||
30 | int detached = 0; | |
31 | int claimed = 0; | |
32 | ||
33 | ||
34 | void usage() | |
35 | { | |
36 | - | printf("Usage: ./g400s_hack ( -400 | -800 | -1600 | -2000 | -4000 )\n"); |
36 | + | printf("Usage: ./g400s_hack ( -400 | -800 | -1600 | -2000 | -4000 | -d | -n)\n"); |
37 | printf("Highly experimental, use with caution.\n"); | |
38 | } | |
39 | ||
40 | void cleanup() | |
41 | { | |
42 | if (claimed) | |
43 | libusb_release_interface(handle, 1); | |
44 | ||
45 | if (detached) | |
46 | libusb_attach_kernel_driver(handle, 1); | |
47 | ||
48 | libusb_close(handle); | |
49 | libusb_exit(ctx); | |
50 | } | |
51 | ||
52 | int main(int argc, char **argv) | |
53 | { | |
54 | if (argc != 2 || argv[1][0] != '-') { | |
55 | usage(); | |
56 | return EXIT_ERROR_ARGS; | |
57 | } | |
58 | ||
59 | //131 => 400dpi, 132 => 800dpi, 133 => 1600dpi, 134 => 2000dpi, 135 => 4000dpi | |
60 | uint16_t dpi_idx = 131; | |
61 | if (strcmp(&argv[1][1], "400" ) == 0) | |
62 | dpi_idx += 0; | |
63 | else if (strcmp(&argv[1][1], "800" ) == 0) | |
64 | dpi_idx += 1; | |
65 | else if (strcmp(&argv[1][1], "1600") == 0) | |
66 | dpi_idx += 2; | |
67 | else if (strcmp(&argv[1][1], "2000") == 0) | |
68 | dpi_idx += 3; | |
69 | else if (strcmp(&argv[1][1], "4000") == 0) | |
70 | dpi_idx += 4; | |
71 | else if (strcmp(&argv[1][1], "d") == 0) | |
72 | dpi_idx = 0; | |
73 | else if (strcmp(&argv[1][1], "n") == 0) | |
74 | dpi_idx = 4; | |
75 | else { | |
76 | - | printf("Set new DPI: %s (index %i)\n", &argv[1][1], dpi_idx); |
76 | + | |
77 | return EXIT_ERROR_ARGS; | |
78 | } | |
79 | ||
80 | if (dpi_idx >= 131) { | |
81 | printf("Set new DPI: %s (index %i)\n", &argv[1][1], dpi_idx); | |
82 | } | |
83 | else { | |
84 | printf("Set Driver/Native mode: %s (index %i)\n", &argv[1][1], dpi_idx); | |
85 | } | |
86 | ||
87 | libusb_init(&ctx); | |
88 | ||
89 | handle = libusb_open_device_with_vid_pid(ctx, G400S_VENDOR_ID, G400S_PRODUCT_ID); | |
90 | libusb_set_debug(ctx, 3); | |
91 | ||
92 | if (!handle) { | |
93 | fprintf(stderr, "Logitech G400s not found! (Do you have usb rights? Try with sudo?)\n"); | |
94 | cleanup(); | |
95 | return EXIT_ERROR_DEVICE; | |
96 | } | |
97 | ||
98 | if (libusb_kernel_driver_active(handle, 1) == 1) { | |
99 | if (libusb_detach_kernel_driver(handle, 1) != 0) { | |
100 | fprintf(stderr, "Can't detach kernel driver.\n"); | |
101 | cleanup(); | |
102 | return EXIT_ERROR_KERNEL; | |
103 | } | |
104 | ||
105 | detached = 1; | |
106 | } | |
107 | ||
108 | if (libusb_claim_interface(handle, 1) != 0) { | |
109 | fprintf(stderr, "Failed to claim interface.\n"); | |
110 | cleanup(); | |
111 | return EXIT_ERROR_CLAIM; | |
112 | } | |
113 | ||
114 | claimed = 1; | |
115 | ||
116 | if (dpi_idx == 0) { | |
117 | // Set driver mode, then DPI to 400 | |
118 | char data[2]; | |
119 | data[0] = 0x20; data[1] = 0x01; | |
120 | int result = libusb_control_transfer (handle, 0x21, 9, 0x0320, 1, data, 2, 1000); | |
121 | if (result != 2) { | |
122 | fprintf(stderr, "Error writing to USB device (%d).\n", result); | |
123 | cleanup(); | |
124 | return EXIT_ERROR_WRITE; | |
125 | } | |
126 | dpi_idx = 131; | |
127 | } | |
128 | ||
129 | if (libusb_control_transfer (handle, 0x40, 2, 0x008e, dpi_idx, NULL, 0, 1000) != 0) { | |
130 | fprintf(stderr, "Error writing to USB device.\n"); | |
131 | cleanup(); | |
132 | return EXIT_ERROR_WRITE; | |
133 | } | |
134 | ||
135 | cleanup(); | |
136 | printf("Finished.\n"); | |
137 | return EXIT_SUCCESS; | |
138 | } |