Created
December 20, 2013 12:36
-
-
Save MatejLach/8054226 to your computer and use it in GitHub Desktop.
Razer BlackWidow keyboard - enable macro keys on Linux - updated for the 2013 Ultimate version.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python2 | |
# blackwidow_enable.py | |
# | |
# Enables the M1-5 and FN keys to send scancodes on the Razer BlackWidow | |
# and BlackWidow Ultimate keyboards. | |
# | |
# You can use 'xev' and 'xbindkeys' to assign actions to the macro keys. | |
# | |
# Requires the PyUSB library. | |
# | |
# By Michael Fincham <[email protected]> 2012-03-05 | |
# This code is released in to the public domain. | |
import sys | |
import usb | |
USB_VENDOR = 0x1532 # Razer | |
USB_PRODUCT = 0x011a # BlackWidow Ultimate 2013 // try '0x011b' if it doesn't work for you... | |
# These values are from the USB HID 1.11 spec section 7.2. | |
# <http://www.usb.org/developers/devclass_docs/HID1_11.pdf> | |
USB_REQUEST_TYPE = 0x21 # Host To Device | Class | Interface | |
USB_REQUEST = 0x09 # SET_REPORT | |
# These values are from the manufacturer's driver. | |
USB_VALUE = 0x0300 | |
USB_INDEX = 0x2 | |
USB_INTERFACE = 2 | |
# These magic bytes are also from the manufacturer's driver. | |
USB_BUFFER = b"\x00\x00\x00\x00\x00\x02\x00\x04\x02\x00\x00\x00\x00\x00\ | |
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ | |
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ | |
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ | |
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00" | |
def find_keyboard_device(): | |
for bus in usb.busses(): | |
for device in bus.devices: | |
if device.idVendor == USB_VENDOR and \ | |
device.idProduct == USB_PRODUCT: | |
return device | |
def main(): | |
device = find_keyboard_device() | |
if device == None: | |
sys.stderr.write("BlackWidow not found.\n") | |
sys.exit(1) | |
try: | |
handle = device.open() | |
interface = device.configurations[0].interfaces[USB_INTERFACE][0] | |
endpoint = interface.endpoints[0] | |
except: | |
sys.stderr.write("Could not select configuration endpoint.\n") | |
sys.exit(1) | |
try: | |
handle.detachKernelDriver(interface) | |
except usb.USBError: | |
pass # This is usually because the enabler was run before and the kernel is still detached | |
except Exception: | |
sys.stderr.write("A very unusual error happened trying to detch the kernel driver.\n") | |
sys.exit(1) | |
try: | |
handle.claimInterface(interface) | |
except: | |
sys.stderr.write("Unable to claim the configuration interface. Do you have the appropriate privileges?\n") | |
sys.exit(1) | |
result = 0 | |
try: | |
result = handle.controlMsg(requestType=USB_REQUEST_TYPE, | |
request=USB_REQUEST, | |
value=USB_VALUE, | |
index=USB_INDEX, | |
buffer=USB_BUFFER) | |
except: | |
sys.stderr.write("Could not write the magic bytes to the BlackWidow.\n") | |
if result == len(USB_BUFFER): | |
sys.stderr.write("Configured BlackWidow.\n") | |
try: | |
handle.releaseInterface() | |
except: | |
sys.stderr.write("Unable to release interface.\n") | |
sys.exit(1) | |
sys.exit(0) | |
if __name__ == "__main__": | |
main() |
I can confirm that device.configurations[0].interfaces
is this kind of array
[
[
<usb.legacy.Interface object at 0x7f5ca120f710>,
<usb.legacy.Interface object at 0x7f5ca120f668>,
<usb.legacy.Interface object at 0x7f5ca120f6d8>
]
]
There is fork with fix https://gist.github.com/r-moiseev/7df5e86377c131ce28a32be9839c626e#file-razer-bwu13-macro-py
I can confirm that
device.configurations[0].interfaces
is this kind of array[ [ <usb.legacy.Interface object at 0x7f5ca120f710>, <usb.legacy.Interface object at 0x7f5ca120f668>, <usb.legacy.Interface object at 0x7f5ca120f6d8> ] ]
There is fork with fix https://gist.github.com/r-moiseev/7df5e86377c131ce28a32be9839c626e#file-razer-bwu13-macro-py
This works, thanks
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I solved the "Could not select configuration endpoint" problem by changing line 56
to
The exception that was caught was simply an IndexError.
interfaces
(for me) was a list with a single list inside, which, in turn, hadInterface
objects, which we needed.Please don't use a single
except
without a specific exception. It's making it harder to determine where the problem is.