GNU/Linux >> Linux Esercitazione >  >> Linux

Far funzionare le chiavi macro da una Razer BlackWidow su Linux

M1-M5 sono in realtà tasti normali:devono solo essere abilitati in modo specifico prima che premendoli generino uno scancode. tux_mark_5 ha sviluppato un piccolo programma Haskell che invia il messaggio SET_REPORT corretto alle tastiere Razer per abilitare questi tasti, e l'ex-parrot ha portato lo stesso codice su Python.

Sui sistemi Arch Linux il port Python è stato impacchettato ed è disponibile da https://aur.archlinux.org/packages.php?ID=60518.

Sui sistemi Debian o Ubuntu la configurazione del port Python del codice è relativamente semplice. Devi installare PyUSB e libusb (come root):

    aptitude install python-usb

Quindi prendi il blackwidow_enable.py file da http://finch.am/projects/blackwidow/ ed eseguilo (anche come root):

    chmod +x blackwidow_enable.py
    ./blackwidow_enable.py

Ciò abiliterà i tasti fino a quando la tastiera non viene scollegata o la macchina viene riavviata. Per rendere questo permanente chiama lo script da qualsiasi stile di script di avvio che preferisci. Per istruzioni su come configurarlo in Debian dai un'occhiata alla documentazione di Debian.

Per utilizzare il codice Haskell di tux_mark_5 dovrai installare Haskell e compilare tu stesso il codice. Queste istruzioni sono per un sistema simile a Debian (incluso Ubuntu).

  1. Installa GHC, libusb-1.0-0-dev e cabal (come root):

    aptitude install ghc libusb-1.0-0-dev cabal-install git pkg-config
    
  2. Recupera l'elenco dei pacchetti:

    cabal update
    
  3. Installa i collegamenti USB per Haskell (non è necessario il root):

    cabal install usb
    
  4. Scarica l'utilità:

    git clone git://github.com/tuxmark5/EnableRazer.git
    
  5. Crea l'utility:

    cabal configure
    cabal build
    
  6. Eseguire l'utility (anche come root):

    ./dist/build/EnableRazer/EnableRazer
    

Successivamente puoi copiare il binario EnableRazer ovunque tu voglia ed eseguirlo all'avvio.

Immediatamente dopo l'esecuzione, il server X dovrebbe vedere M1 come XF86Tools, M2 come XF86Launch5, M3 come XF86Launch6, M4 come XF86Launch7 e M5 come XF86Launch8. Vengono emessi anche eventi per FN.

Queste chiavi possono essere vincolate all'interno di xbindkeys o delle impostazioni di sistema di KDE ad azioni arbitrarie.

Poiché la tastiera potrebbe essere diversa, potrebbe essere necessario modificare l'ID prodotto nella riga 64 di Main.hs:

withDevice 0x1532 0x<HERE GOES YOUR KEYBOARD's PRODUCT ID> $ \dev -> do

Razer sembra imporre il proprio configuratore Synapse 2 basato su cloud a tutti gli utenti al giorno d'oggi, con l'aggiornamento del firmware alla versione 2.*. Una volta aggiornato il firmware, non puoi tornare indietro (la tastiera è completamente bloccata se provi a eseguire il flashing con un firmware precedente).

I "byte magici" del programma Haskell nella risposta di tux_mark_5 non funzioneranno con il firmware più recente. Invece, il driver invia questi byte durante la sequenza di inizializzazione:"0200 0403". Questi abilitano i tasti macro, ma la tastiera entra in una modalità peculiare in cui al posto del protocollo HID standard invia pacchetti da 16 byte (presumibilmente per aumentare il numero di tasti che possono essere premuti contemporaneamente). Il sistema Linux HID non è in grado di far fronte a questo problema e, sebbene la maggior parte dei tasti funzioni come previsto, i tasti macro non vengono riconosciuti:il driver HID non invia alcun dato al livello di input quando vengono premuti.

Per fare in modo che la tua tastiera entri in modalità legacy (in cui i tasti macro inviano i codici chiave XF86Launch* e il tasto FN invia il codice chiave 202), invia questi byte:0200 0402.

Il pacchetto completo sarà:

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

Ecco un programma molto approssimativo e sporco che ho scritto in Python 3 meno esoterico per eseguire l'operazione. Nota il codice per generare i pacchetti di controllo Razer in blackwidow.bwcmd() e i comandi LED del logo Razer come 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()

Forse questo potrebbe far luce sul problema (dalla manpage di showkey):

Nei kernel 2.6 la modalità raw, o modalità scancode, non è affatto molto grezza. I codici di scansione vengono prima tradotti in codici chiave e, quando si desiderano codici di scansione, i codici chiave vengono nuovamente tradotti. Sono coinvolte varie trasformazioni e non vi è alcuna garanzia che il risultato finale corrisponda a ciò che l'hardware della tastiera ha inviato. Quindi, se vuoi conoscere i codici di scansione inviati dalle varie chiavi è meglio avviare un kernel 2.4. Dal 2.6.9 c'è anche l'opzione di avvio atkbd.softraw=0 che dice al kernel 2.6 di restituire i codici di scansione effettivi.

I codici di scansione non elaborati sono disponibili solo su tastiere AT e PS/2 e anche in questo caso sono disabilitati a meno che non venga utilizzato il parametro del kernel atkbd.softraw=0. Quando i codici di scansione non elaborati non sono disponibili, il kernel utilizza una tabella incorporata fissa per produrre codici di scansione dai codici chiave. Pertanto, setkeycodes(8) può influenzare l'output di showkey in modalità scan code dump.

Sto per vedere se showkey scaricherà qualcosa con i tasti macro dopo aver impostato questa opzione di avvio.

EDIT:Dopo il riavvio, nessun successo, ma stavo cercando di acquisire l'input non elaborato dai dispositivi USB stessi. Ho notato quanto segue, in modo interessante (ho un Razer Diamondback così come 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]#

Tuttavia, l'utilizzo di dd per acquisire l'input non elaborato funziona su entrambi i mouse diamondback, sul dispositivo event-kbd, ma non sui dispositivi mouse BlackWidow.

Immagino che forse non generino alcun output fino a quando non vengono attivati ​​in qualche modo dai driver installati. Tuttavia, non so molto di Linux USB, quindi non so nemmeno se abbia senso. Forse devono prima essere legati?

Bene, tutti e tre i dispositivi vedova nera sono indicati in /proc/bus/input/devices , tuttavia non sembrano essere enumerati in lsusb o /proc/bus/usb/devices . Non sono sicuro di come accedere a questi dispositivi per tentare di associarli o interfacciarsi con loro in alcun modo.

event4 sembra corrispondere alla tastiera effettiva, event6 con i tasti macro, ma non riesco ancora a catturare alcun input da essi. Spero che tutto sia stato d'aiuto.

   [[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]# 

Linux
  1. Iniziare con PostgreSQL su Linux

  2. Linux:come eseguire un bootloader da Linux?

  3. Come funziona internamente copy_from_user dal kernel di Linux?

  4. Come installare TBB dal sorgente su Linux e farlo funzionare

  5. macro IS_ERR() in Linux

Iniziare con Etcher.io

Passaggio da Windows a Linux

Installa Linux Mint da USB

Eliminazione di .rbenv da Linux

Posso avviare Linux da un VHD?

Visualizzazione dello schermo GNU + da stucco