Pobieranie kluczy makr z Razer BlackWidow do pracy w systemie Linux

49

Podniosłem Razer BlackWidow Ultimate, który ma dodatkowe klucze przeznaczone dla makr ustawianych za pomocą narzędzia zainstalowanego w systemie Windows . Zakładam, że to nie są jakieś fantazyjne klucze joojoo i powinny emitować skancody jak każdy inny klucz.

Po pierwsze, czy istnieje standardowy sposób sprawdzania tych scancodes w systemie Linux? Po drugie, jak ustawić te klucze, aby działały w ustawieniach Linuksa i X-Linuksa? Moja obecna instalacja Linuksa to Xubuntu 10.10, ale przejdę na Kubuntu, gdy tylko będę miał kilka rzeczy naprawionych. Idealnie byłoby, gdyby odpowiedź była ogólna i obejmowała cały system.

Rzeczy, których do tej pory próbowałem:

Rzeczy, które muszę spróbować

  • Snoopy pro + inżynieria odwrotna (o kochanie)

  • Wireshark - wstępne wyczekiwanie wydaje się wskazywać, że nie są emitowane skancody, gdy wydaje mi się, że klawiatura jest monitorowana i naciskane są klawisze. Może to oznaczać, że dodatkowe klucze są oddzielnym urządzeniem lub wymagają jakiejś inicjalizacji.

  • Trzeba powiązać to z wyjściem lsusb z Linuksa, w trzech scenariuszach: samodzielny, przeszedł na maszynę wirtualną z systemem Windows bez zainstalowanych sterowników i to samo z.

  • LSUSB wykrywa tylko jedno urządzenie w samodzielnej instalacji systemu Linux

  • Przydatne może być sprawdzenie, czy myszy używają tego samego sterownika Razer Synapse, ponieważ oznacza to, że niektóre warianty Razercfg mogą działać (nie wykryto, wydaje się, że działa tylko na myszy)

Rzeczy, które wypracowałem:

  • W systemie Windows ze sterownikiem klawiatura jest postrzegana jako klawiatura i urządzenie wskazujące. Urządzenie wskazujące wykorzystuje - oprócz standardowych sterowników myszy - także sterownik czegoś, co nazywa się Razer Synapse.

  • Kierowca widział mysz pod Linuksem evdev, a lsusbtakże

  • Najwyraźniej pojedyncze urządzenie w systemie OS X, choć muszę jeszcze wypróbować lsusbrównoważne rozwiązanie

  • Klawiatura przechodzi w tryb pulsacyjnego podświetlenia w OS X po inicjalizacji ze sterownikiem. Prawdopodobnie powinno to oznaczać, że podczas aktywacji wysłano do klawiatury sekwencję inicjalizacji.

  • Są to w rzeczywistości fantazyjne klucze joojoo.

Rozszerzając to pytanie trochę:

Mam dostęp do systemu Windows, więc jeśli muszę skorzystać z jakichkolwiek narzędzi, aby odpowiedzieć na pytanie, to w porządku. Mogę również wypróbować go w systemach z narzędziem konfiguracyjnym i bez niego. Oczekiwanym rezultatem końcowym jest jednak uczynienie tych kluczy użytecznymi w systemie Linux.

Zdaję sobie również sprawę, że jest to bardzo specyficzna rodzina sprzętu. Byłbym skłonny przetestować wszystko, co ma sens w systemie Linux, jeśli mam szczegółowe instrukcje - to powinno otworzyć pytanie dla ludzi, którzy mają umiejętności w Linuksie, ale nie mają dostępu do tej klawiatury.

Wymagany minimalny wynik końcowy:

Potrzebuję tych kluczy do wykrycia i używania ich w dowolny sposób na dowolnym z obecnych wariantów głównego nurtu graficznego Ubuntu i oczywiście muszę pracować z moją klawiaturą. Wirtualne ciasteczka i szalone rekwizyty, jeśli jest to coś ładnie zapakowanego i użytecznego dla przeciętnego użytkownika.

Będę wymagać skompilowany kod, który będzie działał w moim systemie, lub źródła, które mogę skompilować (z instrukcjami, jeśli jest to bardziej skomplikowane niż ./configure, make, make install) czy dodatkowe oprogramowanie nie na repozytoriach Ubuntu dla bieżącego LTS lub standardowym wydaniu stacjonarnym w czasie odpowiedź. Potrzebuję również wystarczających informacji do replikacji i skutecznego używania kluczy w moim systemie.

Journeyman Geek
źródło
zaktualizuj o wszelkie rozwiązania, chciałbym osiągnąć to samo!
Jonathan Day
Naprawdę nie miałem ostatnio czasu nad tym popracować, ale będę aktualizował to pytanie za pomocą wszystkiego, co zrobiłem, dopóki nie otrzymam odpowiedzi.
Journeyman Geek
Może edytuj, aby wymienić 500 powtórzeń dużą czcionką? W przeciwnym razie proklamacja nie ma większego sensu (biorąc pod uwagę nagrodę w wysokości 50 powtórzeń zarejestrowaną w systemie)
Daniel Beck
Czy to nadal działa dla Ciebie? (Mówię o najnowszym oprogramowaniu wymienionym poniżej przez Siergieja)
Adonis K. Kakoulidis
Obawiam się, że go nie testowałem. Chciałem wypróbować rozwiązanie Siergieja, aby sprawdzić, czy to działa, ale w ciągu ostatnich kilku miesięcy korzystałem z systemu Windows do celów szkolnych. Jeśli tak, opublikuję komentarz na ten temat
Journeyman Geek

Odpowiedzi:

44

M1-M5 są w rzeczywistości zwykłymi klawiszami - po prostu trzeba je specjalnie włączyć, zanim ich naciśnięcie wygeneruje scancode. tux_mark_5 opracował mały program Haskell, który wysyła prawidłowy komunikat SET_REPORT do klawiatur Razer, aby włączyć te klucze, i była papuga przeniosła ten sam kod do Pythona.

W systemach Arch Linux port Python został spakowany i jest dostępny na stronie https://aur.archlinux.org/packages.php?ID=60518 .

W systemach Debian lub Ubuntu konfiguracja portu Python kodu jest stosunkowo łatwa. Musisz zainstalować PyUSB i libusb (jako root):

    aptitude install python-usb

Następnie pobierz blackwidow_enable.pyplik z http://finch.am/projects/blackwidow/ i uruchom go (także jako root):

    chmod +x blackwidow_enable.py
    ./blackwidow_enable.py

Umożliwi to klawisze do momentu odłączenia klawiatury lub ponownego uruchomienia komputera. Aby to na stałe wywołać skrypt z dowolnego stylu skryptu uruchamiania, który najbardziej preferujesz. Aby dowiedzieć się, jak to ustawić w Debianie, zajrzyj do dokumentacji Debiana .

Aby użyć kodu Haskell tux_mark_5, musisz zainstalować Haskell i sam go skompilować. Te instrukcje dotyczą systemu podobnego do Debiana (w tym Ubuntu).

  1. Zainstaluj GHC, libusb-1.0-0-dev i cabal (jako root):

    aptitude install ghc libusb-1.0-0-dev cabal-install git pkg-config
    
  2. Pobierz listę pakietów:

    cabal update
    
  3. Zainstaluj powiązania USB dla Haskell (bez potrzeby rootowania):

    cabal install usb
    
  4. Pobierz narzędzie:

    git clone git://github.com/tuxmark5/EnableRazer.git
    
  5. Zbuduj narzędzie:

    cabal configure
    cabal build
    
  6. Uruchom narzędzie (także jako root):

    ./dist/build/EnableRazer/EnableRazer
    

Następnie możesz skopiować plik binarny EnableRazer w dowolne miejsce i uruchomić go podczas uruchamiania.

Natychmiast po wykonaniu serwer X powinien zobaczyć M1 jako XF86Tools, M2 jako XF86Launch5, M3 jako XF86Launch6, M4 jako XF86Launch7 i M5 jako XF86Launch8. Emitowane są również zdarzenia dla FN.

Te klucze można powiązać w ramach klawiszy xbindkeys lub ustawień systemowych KDE z dowolnymi działaniami.

Ponieważ klawiatura może być inna, konieczna może być zmiana identyfikatora produktu w linii 64. Main.hs:

withDevice 0x1532 0x<HERE GOES YOUR KEYBOARD's PRODUCT ID> $ \dev -> do
tux_mark_5
źródło
To działa, dobrze idzie. Dostaniesz 500 powtórzeń dziennie lub dwa, gdy system mi na to pozwoli. Pozwoliłem sobie na dodanie pkg-config, który był potrzebny do zainstalowania wymagań wstępnych pakietu USB Haskell na liście wymagań wstępnych. Oprogramowanie działa bez żadnych modyfikacji na moim standardowym urządzeniu Blackwidow Ultimate o identyfikatorze produktu 1532: 010d według lsusb. Klucze są wykrywane podczas evtest i wydają się użyteczne, więc idealnie spełniło wymagania pytania.
Journeyman Geek
ponadto wydaje się, że kde nie ma opcji wiązania klucza, wydaje się, że xbindkeys działa
Journeyman Geek
z ID 10e działa z moim standardowym blackwidow (non-ultimate). Polecam dodać regułę udev, aby uruchamiała się automatycznie, bez problemów, np. Stwórz plik 99-enable-razer-keyboard.rules int /etc/udev/rules.d z SUBSYSTEM=="usb", ACTION=="add", ATTR{idVendor}=="1532", ATTR{idProduct}=="010e", RUN+="/root/EnableRazer"nim (tutaj może być konieczne zmodyfikowanie ścieżka i identyfikator jeszcze raz)
flolo
Najwyraźniej narzędzie, które napisałem, działa również z Razerem Anansim. Oto post na blogu kogoś, kto to zrobił
tux_mark_5
1
Mam Razer BlackWidow 2013 (nie najlepszy), kiedy wykonuję skrypt blackwidow_enable.py (z rootem i bez), pojawia się komunikat „Nie znaleziono Blackwidow”. Czy możesz mi pomóc w debugowaniu tego? Jestem na UbuntuGnome 13.04. Wygląda na to, że identyfikator_produktu jest inny i po zmianie identyfikatora produktu Could not select configuration endpoint.
pojawia
22

Wydaje się, że Razer narzuca obecnie wszystkim użytkownikom konfigurację Synapse 2 opartą na chmurze, wraz z aktualizacją oprogramowania do wersji 2. *. Po uaktualnieniu oprogramowania nie można wrócić (klawiatura jest całkowicie zamurowana, jeśli spróbujesz sflashować ją starszym oprogramowaniem).

„Magiczne bajty” z programu Haskell w odpowiedzi tux_mark_5 nie będą działać z najnowszym oprogramowaniem. Zamiast tego sterownik wysyła te bajty podczas sekwencji inicjowania: „0200 0403”. Umożliwiają one klawisze makr, ale klawiatura wchodzi w osobliwy tryb, w którym zamiast standardowego protokołu HID wysyła 16-bajtowe pakiety (prawdopodobnie w celu zwiększenia liczby klawiszy, które można nacisnąć jednocześnie). System Linux HID nie może sobie z tym poradzić i chociaż większość klawiszy działa zgodnie z oczekiwaniami, klucze makr pozostają nierozpoznane: sterownik HID nie podaje żadnych danych do warstwy wejściowej po ich naciśnięciu.

Aby wprowadzić klawiaturę do trybu starszego typu (w którym klawisze makr wysyłają kody XF86Launch *, a klawisz FN wysyła kod 202), wyślij te bajty: 0200 0402.

Pełny pakiet będzie:

00000000 00020004 02000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 0400

Oto bardzo szorstki i brudny program, który napisałem w mniej ezoterycznym Pythonie 3 do wykonania tego zadania. Zanotuj kod do generowania pakietów kontrolnych Razer w blackwidow.bwcmd () i polecenia LED logo 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()
Siergiej
źródło
moja klawiatura została zaktualizowana i jeszcze jej nie próbowałem. Dam mu szansę, gdy znów będę mieć odpowiedni system Linux. Niestety nie mogę dać za to kolejnej nagrody - częściowo ze względu na sposób działania systemu nagród. I będzie prawdopodobnie przełączyć poprawnej odpowiedzi do Ciebie, jeśli nie tho.
Journeyman Geek
najwyraźniej brakuje modułu usb w moim systemie, więc to nie działa: /
Journeyman Geek
Moduł USB jest prawdopodobnie w pakiecie pyusb (lub python-usb lub coś podobnego, w zależności od dystrybucji).
Siergiej
2
Siergiej bardzo dziękuję, działa nawet z nowszym Razerem BlackWidow 2013 z PRODUCT_ID = 0x011b. Nie próbowałem jeszcze ustawiać żadnych makr, ale widzę zdarzenia pochodzące z / dev / input / by-id / usb-Razer_Razer_BlackWidow_2013-event-kbd, a także w xev :).
binary_runner
Dziękuję, to świetnie. Używam go od kilku lat bez żadnych problemów (wreszcie mam reputację do komentowania :)). Jeden komentarz do pyusb: Ponieważ Ubuntu nadal nie dostarcza pyusb dla Pythona 3, musiałem zainstalować go ręcznie ze źródła, używającsudo python3 setup.py install
luator
8

Być może może to rzucić nieco światła na ten problem (ze strony podręcznika programu):

W jądrze 2.6 tryb raw lub tryb scancode wcale nie jest bardzo surowy. Kody skanowania są najpierw tłumaczone na kody kluczy, a gdy potrzebne są skancody, kody kluczy są tłumaczone z powrotem. W grę wchodzą różne transformacje i nie ma żadnej gwarancji, że końcowy wynik odpowiada temu, co wysłał sprzęt klawiatury. Jeśli więc chcesz znać kody skanowania wysyłane przez różne klucze, lepiej jest uruchomić jądro 2.4. Od wersji 2.6.9 dostępna jest również opcja rozruchu atkbd.softraw = 0, która informuje jądro 2.6 o zwróceniu rzeczywistych kodów skanowania.

Surowe kody skanowania są dostępne tylko na klawiaturach AT i PS / 2, a nawet wtedy są wyłączone, chyba że użyty zostanie parametr jądra atkbd.softraw = 0. Kiedy surowe kody skanowania nie są dostępne, jądro używa stałej wbudowanej tabeli do generowania kodów skanowania z kodów klawiszy. Zatem setkeycodes (8) może wpływać na wyjście showkey w trybie zrzutu kodu skanowania.

Zaraz zobaczę, czy showkey zrzuci cokolwiek za pomocą klawiszy makr po ustawieniu tej opcji uruchamiania.

EDYCJA: Po ponownym uruchomieniu komputera nie powiodło się, ale chciałem przechwycić nieprzetworzone dane wejściowe z samych urządzeń USB. Co ciekawe, zauważyłem następujące (mam Razer Diamondback oraz BlackWidow):

[root@kestrel by-id]# pwd
/dev/input/by-id
[root@kestrel 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
[root@kestrel by-id]#

Jednak użycie dd do przechwytywania surowych danych wejściowych działa na obu myszach diamentowych na urządzeniu event-kbd, ale nie na urządzeniach myszy BlackWidow.

Domyślam się, że może nie generują żadnych danych wyjściowych, dopóki nie zostaną aktywowane przez zainstalowane sterowniki. Jednak niewiele wiem o Linux USB, więc nawet nie wiem, czy to ma sens. Być może trzeba je najpierw związać?

Cóż, wszystkie trzy urządzenia czarnej wdowy są odnotowane w /proc/bus/input/devices, jednak nie wydają się być wyliczone w lsusblub /proc/bus/usb/devices. Nie jestem pewien, jak uzyskać dostęp do tych urządzeń, aby spróbować je powiązać lub w jakikolwiek sposób połączyć z nimi.

event4wydaje się odpowiadać rzeczywistej klawiaturze, event6 z klawiszami makr, ale nadal nie mogę przechwytywać z nich żadnych danych wejściowych. Mam nadzieję, że to wszystko pomogło.

   [root@kestrel input]# ls
devices  handlers
[root@kestrel 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
[root@kestrel input]# pwd
/proc/bus/input
[root@kestrel 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

[root@kestrel input]# 
srmaddox
źródło
Domyślam się, że system musi komunikować się z klawiaturą, aby je zainicjować - w OS X moja klawiatura przechodzi w tryb pulsującego światła. Prawdopodobnie wymagana jest inicjalizacja przed uruchomieniem klawiszy makr klawiatury
Journeyman Geek
Zastanawiam się, jak wysłać te informacje do myszy i urządzeń myszy zdarzeń. wydaje się, że mysz-zdarzenia jest odpowiedzialna, ponieważ jest powiązana z obsługą zdarzeń klawiatury. Teoretycznie wszystko, co trzeba będzie zrobić, to zainicjowanie urządzenia i skonfigurowanie odpowiedniej mapy scancode-> kodu klucza za pomocą setkeycode i pobranie zdarzeń w normalny sposób.
srmaddox,
Być może mogę po prostu otworzyć zaćmienie i napisać program, który zezwala na surowe wejście / wyjście do / z urządzenia. Wtedy mogą wystąpić próby i błędy.
srmaddox,
jespersaur.com/drupal/book/export/html/21 powinno to być interesujące w miarę procesu. To daleko poza moje umiejętności.
Journeyman Geek
7

Moje rozwiązanie dotyczy mechanicznej klawiatury do gier Razer BlackWidow 2013 (numer modelu: RZ03-0039) i zostało przetestowane na openSUSE 12.3.

Użyłem Tłumacza Google pod tym linkiem .

Zasadniczo używa zmodyfikowanej wersji odpowiedzi @ Sergey na to pytanie, ale z prostymi modyfikacjami:

  1. Mój PRODUCT_ID = 0x011b

  2. W moim openSUSE 12.3 python-usb nie jest dostępny dla Pythona 3, więc przekonwertowałem ten skrypt do pracy z Pythonem 2, usuwając bwcmdmetodę i zdefiniowałem USB_BUFFER = ...jak w linku z odpowiedzi @ tux_mark_5 .


Dla wygody oto treść mojego /usr/local/sbin/init_blackwidow.py:

#!/usr/bin/python

"""This is a patched version of Sergey's code form
https://superuser.com/a/474595/8647

It worked for my Razer BlackWidow 2013 Mechanical Gaming Keyboard
(Model Number: RZ03-0039).

"""
import usb
import sys

VENDOR_ID = 0x1532       # Razer
PRODUCT_ID = 0x011b      # BlackWidow 2013 Mechanical Gaming Keyboard

USB_REQUEST_TYPE = 0x21  # Host To Device | Class | Interface
USB_REQUEST = 0x09       # SET_REPORT

USB_VALUE = 0x0300
USB_INDEX = 0x2
USB_INTERFACE = 2

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"

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 send(self, c):
        def _send(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):
            for i in c:
                print(' >> {}\n'.format(i))
                _send(i)
        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()

... a moim /etc/udev/rules.d/99-razer-balckwidow.rulesjest:

SUBSYSTEM=="usb", ACTION=="add", ATTR{idVendor}=="1532", ATTR{idProduct}=="011b", RUN+="/usr/local/sbin/init_blackwidow.py"
Chen Levy
źródło
Gdzie znalazłeś kopię pyusb usb.util?
KayEss,
@KayEss, używam python-usb-1.0.0-21.1.noarch.rpm. IIRC jest częścią repozytoriów stadard w 0penSUSE 12.3. Według rpm -qi, źródło znajduje się na sourceforge.net/projects/pyusb, a źródło pakietu na obs: //build.opensuse.org/devel: języki: python
Chen Levy
Jestem na Ubuntu i nie ma na nim żadnej wersji dla Python3. Miałem wtedy trochę problemów z połączeniem wszystkich sudo, python3, pip i virtualenv w linii, ale teraz jest to posortowane i widzę kody dla klawiszy makr.
KayEss,
1
@KayEss, dla Ubuntu 14.04, skorzystałem z instrukcji z: github.com/walac/pyusb . W szczególności: sudo apt-get install python libusb-1.0-0sudoipip install pyusb --pre
Chen Levy
2

Może ten dokument pomoże ci:

Klawiatura i konsola Linux HOWTO , Przydatne programy

askobol
źródło
jest to początek i warte pochwały. Co ciekawe, klawisze makr w ogóle nie pojawiają się na klawiszach
Journeyman Geek
może ten klawisz makra emituje scancode tylko w połączeniu z innym kluczem. Jak scancode dla makro-1 itp.?
askobol
1
Wydają się działać niezależnie po skonfigurowaniu w systemie Windows. Być może będę musiał rozważyć podejście niższego poziomu. Domyślam się, że istnieje wsparcie dla myszy tej samej firmy, która używa razercfg przy użyciu niestandardowych skancodów. heh Gdyby to było łatwe, przypuszczam, że bym to znalazł;)
Journeyman Geek
Ten dokument nie był aktualizowany od 2002 roku. Czy nadal jest aktualny?
Peter Mortensen,
1

Zobacz Razer Key Mapper dla systemu Linux .

Działa to ze wszystkimi makrami urządzeń Razer, z pewnymi modyfikacjami kodu. Jeśli nadal nie masz rozwiązania, a Twojego urządzenia nie ma na liście, chętnie pomogę Ci skonfigurować urządzenie i dodać je do mojej listy obsługiwanych.

Camille Guay
źródło
Jak to jest lepsze niż zaakceptowana odpowiedź?
Toto
1
Chyba prostsze. Gotowe. Pozostało tylko wypełnić pliki konfiguracyjne.
Camille Guay