M1-M5 jsou ve skutečnosti běžné klávesy – jen je třeba je specificky aktivovat, než jejich stisknutí vygeneruje skenovací kód. tux_mark_5 vyvinul malý program Haskell, který posílá správnou zprávu SET_REPORT na klávesnice Razer, aby tyto klávesy povolil, a ex-parrot přenesl stejný kód do Pythonu.
Na systémech Arch Linux byl port Python zabalen a je dostupný na https://aur.archlinux.org/packages.php?ID=60518.
Na systémech Debian nebo Ubuntu je nastavení portu Python kódu relativně snadné. Musíte nainstalovat PyUSB a libusb (jako root):
aptitude install python-usb
Poté uchopte blackwidow_enable.py
soubor z http://finch.am/projects/blackwidow/ a spusťte jej (také jako root):
chmod +x blackwidow_enable.py
./blackwidow_enable.py
To povolí klávesy, dokud neodpojíte klávesnici nebo nerestartujete počítač. Aby to bylo trvalé, zavolejte skript z jakéhokoli stylu spouštěcího skriptu, který vám nejvíce vyhovuje. Pokyny, jak to nastavit v Debianu, najdete v dokumentaci k Debianu.
Chcete-li použít kód Haskell tux_mark_5, budete muset nainstalovat Haskell a zkompilovat kód sami. Tyto pokyny jsou pro systém podobný Debianu (včetně Ubuntu).
-
Nainstalujte GHC, libusb-1.0-0-dev a cabal (jako root):
aptitude install ghc libusb-1.0-0-dev cabal-install git pkg-config
-
Získejte seznam balíčků:
cabal update
-
Nainstalujte USB vazby pro Haskell (nepotřebujete root):
cabal install usb
-
Stáhněte si nástroj:
git clone git://github.com/tuxmark5/EnableRazer.git
-
Sestavte nástroj:
cabal configure cabal build
-
Spusťte nástroj (také jako root):
./dist/build/EnableRazer/EnableRazer
Poté můžete binární EnableRazer zkopírovat kamkoli chcete a spustit jej při spuštění.
Ihned po spuštění by X server měl vidět M1 jako XF86Tools, M2 jako XF86Launch5, M3 jako XF86Launch6, M4 jako XF86Launch7 a M5 jako XF86Launch8. Události pro FN jsou vysílány také.
Tyto klíče mohou být v rámci xbindkeys nebo systémových nastavení KDE svázány s libovolnými akcemi.
Protože se vaše klávesnice může lišit, možná budete muset změnit ID produktu v Main.hs řádku 64:
withDevice 0x1532 0x<HERE GOES YOUR KEYBOARD's PRODUCT ID> $ \dev -> do
Zdá se, že Razer dnes všem uživatelům vnucuje svůj cloudový konfigurátor Synapse 2 s doprovodným upgradem firmwaru na verzi 2.*. Jakmile upgradujete firmware, nemůžete se vrátit zpět (klávesnice je zcela zazděná, pokud se ji pokusíte flashovat se starším firmwarem).
„Magické bajty“ z programu Haskell v odpovědi tux_mark_5 nebudou fungovat s nejnovějším firmwarem. Místo toho ovladač během inicializační sekvence odešle tyto bajty:„0200 0403“. Ty povolí makro klávesy, ale klávesnice přejde do zvláštního režimu, ve kterém místo standardního HID protokolu posílá 16bajtové pakety (pravděpodobně pro zvýšení počtu kláves, které lze stisknout současně). Linuxový HID systém si s tím nedokáže docela poradit, a přestože většina kláves funguje podle očekávání, makro klávesy zůstávají nerozpoznané:ovladač HID nepodává žádná data do vstupní vrstvy, když jsou stisknuty.
Chcete-li, aby vaše klávesnice vstoupila do staršího režimu (ve kterém makro klávesy odesílají kódy kláves XF86Launch* a klávesa FN posílá kód klávesy 202), odešlete tyto bajty:0200 0402.
Celý balíček bude:
00000000 00020004 02000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 0400
Zde je velmi hrubý a špinavý program, který jsem napsal v méně esoterickém Pythonu 3, abych provedl tento úkol. Poznamenejte si kód pro generování ovládacích paketů Razer v blackwidow.bwcmd() a příkazy LED loga Razer jako bonus :)
#!/usr/bin/python3
import usb
import sys
VENDOR_ID = 0x1532 # Razer
PRODUCT_ID = 0x010e # BlackWidow / BlackWidow Ultimate
USB_REQUEST_TYPE = 0x21 # Host To Device | Class | Interface
USB_REQUEST = 0x09 # SET_REPORT
USB_VALUE = 0x0300
USB_INDEX = 0x2
USB_INTERFACE = 2
LOG = sys.stderr.write
class blackwidow(object):
kernel_driver_detached = False
def __init__(self):
self.device = usb.core.find(idVendor=VENDOR_ID, idProduct=PRODUCT_ID)
if self.device is None:
raise ValueError("Device {}:{} not found\n".format(VENDOR_ID, PRODUCT_ID))
else:
LOG("Found device {}:{}\n".format(VENDOR_ID, PRODUCT_ID))
if self.device.is_kernel_driver_active(USB_INTERFACE):
LOG("Kernel driver active. Detaching it.\n")
self.device.detach_kernel_driver(USB_INTERFACE)
self.kernel_driver_detached = True
LOG("Claiming interface\n")
usb.util.claim_interface(self.device, USB_INTERFACE)
def __del__(self):
LOG("Releasing claimed interface\n")
usb.util.release_interface(self.device, USB_INTERFACE)
if self.kernel_driver_detached:
LOG("Reattaching the kernel driver\n")
self.device.attach_kernel_driver(USB_INTERFACE)
LOG("Done.\n")
def bwcmd(self, c):
from functools import reduce
c1 = bytes.fromhex(c)
c2 = [ reduce(int.__xor__, c1) ]
b = [0] * 90
b[5: 5+len(c1)] = c1
b[-2: -1] = c2
return bytes(b)
def send(self, c):
def _send(msg):
USB_BUFFER = self.bwcmd(msg)
result = 0
try:
result = self.device.ctrl_transfer(USB_REQUEST_TYPE, USB_REQUEST, wValue=USB_VALUE, wIndex=USB_INDEX, data_or_wLength=USB_BUFFER)
except:
sys.stderr.write("Could not send data.\n")
if result == len(USB_BUFFER):
LOG("Data sent successfully.\n")
return result
if isinstance(c, list):
#import time
for i in c:
print(' >> {}\n'.format(i))
_send(i)
#time.sleep(.05)
elif isinstance(c, str):
_send(c)
###############################################################################
def main():
init_new = '0200 0403'
init_old = '0200 0402'
pulsate = '0303 0201 0402'
bright = '0303 0301 04ff'
normal = '0303 0301 04a8'
dim = '0303 0301 0454'
off = '0303 0301 0400'
bw = blackwidow()
bw.send(init_old)
if __name__ == '__main__':
main()
Možná by to mohlo vnést trochu světla do problému (z manuálové stránky showkey):
V jádrech 2.6 není syrový režim nebo režim skenovacího kódu vůbec příliš syrový. Skenovací kódy jsou nejprve přeloženy na klíčové kódy, a když jsou požadovány skenovací kódy, jsou kódy klíče přeloženy zpět. Jde o různé transformace a není vůbec zaručeno, že konečný výsledek odpovídá tomu, co hardware klávesnice poslal. Pokud tedy chcete znát skenovací kódy odesílané různými klíči, je lepší zavést jádro 2.4. Od verze 2.6.9 existuje také zaváděcí volba atkbd.softraw=0, která říká jádru 2.6, aby vrátilo skutečné skenovací kódy.
Nezpracované kódy skenování jsou k dispozici pouze na klávesnicích AT a PS/2 a i tehdy jsou zakázány, pokud není použit parametr jádra atkbd.softraw=0. Když nejsou k dispozici nezpracované skenovací kódy, jádro používá pevnou vestavěnou tabulku k vytváření skenovacích kódů z kódů klíčů. Setkeycodes(8) tedy může ovlivnit výstup showkey v režimu skenování kódu.
Chystám se zjistit, zda showkey po nastavení této možnosti spouštění vypíše něco pomocí makro kláves.
EDIT:Po restartu bez úspěchu, ale díval jsem se na zachycení nezpracovaného vstupu ze samotných zařízení USB. Zajímavě jsem si všiml následujícího (mám Razer Diamondback i BlackWidow):
[[email protected] by-id]# pwd
/dev/input/by-id
[[email protected] by-id]# ls
usb-Razer_Razer_BlackWidow_Ultimate-event-kbd usb-Razer_Razer_Diamondback_Optical_Mouse-event-mouse
usb-Razer_Razer_BlackWidow_Ultimate-event-mouse usb-Razer_Razer_Diamondback_Optical_Mouse-mouse
usb-Razer_Razer_BlackWidow_Ultimate-mouse
[[email protected] by-id]#
Použití dd k zachycení nezpracovaného vstupu však funguje na obou myších diamondback, na zařízení event-kbd, ale ne na myších BlackWidow.
Hádám, že možná negenerují žádný výstup, dokud nejsou nějak aktivovány nainstalovanými ovladači. Nicméně o Linuxu USB toho moc nevím, takže ani nevím, jestli to má smysl. Možná je třeba je nejprve svázat?
Všechna tři zařízení Black Widow jsou uvedena v /proc/bus/input/devices
, ale nezdá se, že by byly uvedeny v lsusb
nebo /proc/bus/usb/devices
. Nejsem si jistý, jak k těmto zařízením přistupovat, abych se je pokusil svázat nebo s nimi jakýmkoli způsobem komunikovat.
event4
Zdá se, že odpovídá skutečné klávesnici, event6 s makro klávesami, ale stále z nich nemohu zachytit žádný vstup. Doufám, že to vše pomohlo.
[[email protected] input]# ls
devices handlers
[[email protected] input]# cat handlers
N: Number=0 Name=kbd
N: Number=1 Name=mousedev Minor=32
N: Number=2 Name=evdev Minor=64
N: Number=3 Name=rfkill
[[email protected] input]# pwd
/proc/bus/input
[[email protected] input]# cat devices
I: Bus=0019 Vendor=0000 Product=0001 Version=0000
N: Name="Power Button"
P: Phys=PNP0C0C/button/input0
S: Sysfs=/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0C0C:00/input/input0
U: Uniq=
H: Handlers=kbd event0
B: EV=3
B: KEY=10000000000000 0
I: Bus=0019 Vendor=0000 Product=0001 Version=0000
N: Name="Power Button"
P: Phys=LNXPWRBN/button/input0
S: Sysfs=/devices/LNXSYSTM:00/LNXPWRBN:00/input/input1
U: Uniq=
H: Handlers=kbd event1
B: EV=3
B: KEY=10000000000000 0
I: Bus=0017 Vendor=0001 Product=0001 Version=0100
N: Name="Macintosh mouse button emulation"
P: Phys=
S: Sysfs=/devices/virtual/input/input2
U: Uniq=
H: Handlers=mouse0 event2
B: EV=7
B: KEY=70000 0 0 0 0
B: REL=3
I: Bus=0003 Vendor=1532 Product=010d Version=0111
N: Name="Razer Razer BlackWidow Ultimate"
P: Phys=usb-0000:00:12.1-3/input0
S: Sysfs=/devices/pci0000:00/0000:00:12.1/usb4/4-3/4-3:1.0/input/input4
U: Uniq=
H: Handlers=kbd event4
B: EV=120013
B: KEY=1000000000007 ff9f207ac14057ff febeffdfffefffff fffffffffffffffe
B: MSC=10
B: LED=7
I: Bus=0003 Vendor=1532 Product=010d Version=0111
N: Name="Razer Razer BlackWidow Ultimate"
P: Phys=usb-0000:00:12.1-3/input1
S: Sysfs=/devices/pci0000:00/0000:00:12.1/usb4/4-3/4-3:1.1/input/input5
U: Uniq=
H: Handlers=kbd event5
B: EV=1f
B: KEY=837fff002c3027 bf00444400000000 1 c040a27c000 267bfad941dfed 9e000000000000 0
B: REL=40
B: ABS=100000000
B: MSC=10
I: Bus=0003 Vendor=1532 Product=010d Version=0111
N: Name="Razer Razer BlackWidow Ultimate"
P: Phys=usb-0000:00:12.1-3/input2
S: Sysfs=/devices/pci0000:00/0000:00:12.1/usb4/4-3/4-3:1.2/input/input6
U: Uniq=
H: Handlers=mouse2 event6
B: EV=17
B: KEY=70000 0 0 0 0
B: REL=103
B: MSC=10
I: Bus=0003 Vendor=1532 Product=0002 Version=0110
N: Name="Razer Razer Diamondback Optical Mouse"
P: Phys=usb-0000:00:12.1-2/input0
S: Sysfs=/devices/pci0000:00/0000:00:12.1/usb4/4-2/4-2:1.0/input/input9
U: Uniq=
H: Handlers=mouse1 event3
B: EV=17
B: KEY=7f0000 0 0 0 0
B: REL=103
B: MSC=10
[[email protected] input]#