GNU/Linux >> Tutoriels Linux >  >> Linux

Obtenir des clés de macro d'un Razer BlackWidow pour fonctionner sous Linux

M1-M5 sont en fait des touches normales - elles doivent simplement être spécifiquement activées avant d'appuyer dessus pour générer un scancode. tux_mark_5 a développé un petit programme Haskell qui envoie le bon message SET_REPORT aux claviers Razer pour activer ces touches, et ex-parrot a porté le même code sur Python.

Sur les systèmes Arch Linux, le port Python a été empaqueté et est disponible sur https://aur.archlinux.org/packages.php?ID=60518.

Sur les systèmes Debian ou Ubuntu, la configuration du port Python du code est relativement facile. Vous devez installer PyUSB et libusb (en tant que root) :

    aptitude install python-usb

Saisissez ensuite le blackwidow_enable.py fichier depuis http://finch.am/projects/blackwidow/ et exécutez-le (également en tant que root) :

    chmod +x blackwidow_enable.py
    ./blackwidow_enable.py

Cela activera les touches jusqu'à ce que le clavier soit débranché ou que la machine soit redémarrée. Pour rendre cela permanent, appelez le script à partir du style de script de démarrage que vous préférez. Pour savoir comment le configurer dans Debian, consultez la documentation Debian.

Pour utiliser le code Haskell de tux_mark_5, vous devrez installer Haskell et compiler le code vous-même. Ces instructions concernent un système de type Debian (y compris Ubuntu).

  1. Installez GHC, libusb-1.0-0-dev et cabal (en tant que root) :

    aptitude install ghc libusb-1.0-0-dev cabal-install git pkg-config
    
  2. Récupérer la liste des packages :

    cabal update
    
  3. Installez les liaisons USB pour Haskell (pas besoin de racine) :

    cabal install usb
    
  4. Téléchargez l'utilitaire :

    git clone git://github.com/tuxmark5/EnableRazer.git
    
  5. Construisez l'utilitaire :

    cabal configure
    cabal build
    
  6. Exécutez l'utilitaire (également en tant que root) :

    ./dist/build/EnableRazer/EnableRazer
    

Après cela, vous pouvez copier le binaire EnableRazer où vous voulez et l'exécuter au démarrage.

Immédiatement après l'exécution, le serveur X devrait voir M1 comme XF86Tools, M2 comme XF86Launch5, M3 comme XF86Launch6, M4 comme XF86Launch7 et M5 comme XF86Launch8. Les événements pour FN sont également émis.

Ces clés peuvent être liées dans xbindkeys ou les paramètres système de KDE à des actions arbitraires.

Étant donné que votre clavier peut être différent, vous devrez peut-être modifier l'ID de produit dans Main.hs ligne 64 :

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

Razer semble imposer son configurateur Synapse 2 basé sur le cloud à tous les utilisateurs de nos jours, avec la mise à jour du micrologiciel vers la version 2.*. Une fois que vous avez mis à jour le micrologiciel, vous ne pouvez pas revenir en arrière (le clavier est complètement bloqué si vous essayez de le flasher avec un micrologiciel plus ancien).

Les "octets magiques" du programme Haskell dans la réponse de tux_mark_5 ne fonctionneront pas avec le dernier firmware. Au lieu de cela, le pilote envoie ces octets lors de la séquence d'initialisation :"0200 0403". Celles-ci activent les touches macro, mais le clavier entre dans un mode particulier dans lequel, au lieu du protocole HID standard, il envoie des paquets de 16 octets (probablement pour augmenter le nombre de touches pouvant être enfoncées simultanément). Le système Linux HID ne peut pas tout à fait faire face à cela, et bien que la plupart des touches fonctionnent comme prévu, les touches de macro ne sont pas reconnues :le pilote HID ne transmet aucune donnée à la couche d'entrée lorsqu'elles sont enfoncées.

Pour que votre clavier passe en mode hérité (dans lequel les touches macro envoient les codes clés XF86Launch* et la touche FN envoie le code clé 202), envoyez ces octets :0200 0402.

Le paquet complet sera :

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

Voici un programme très grossier et sale que j'ai écrit en Python 3 moins ésotérique pour effectuer la tâche. Notez le code pour générer les paquets de contrôle Razer dans blackwidow.bwcmd() et les commandes LED du logo Razer en 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()

Peut-être que cela pourrait éclairer le problème (à partir de la page de manuel de showkey) :

Dans les noyaux 2.6, le mode brut, ou mode scancode, n'est pas du tout très brut. Les codes de numérisation sont d'abord traduits en codes de clé, et lorsque des codes de numérisation sont souhaités, les codes de clé sont retraduits. Diverses transformations sont impliquées, et il n'y a aucune garantie que le résultat final corresponde à ce que le matériel du clavier a envoyé. Donc, si vous voulez connaître les codes de balayage envoyés par différentes clés, il est préférable de démarrer un noyau 2.4. Depuis la version 2.6.9, il existe également l'option de démarrage atkbd.softraw=0 qui indique au noyau 2.6 de renvoyer les codes de numérisation réels.

Les codes de balayage bruts ne sont disponibles que sur les claviers AT et PS/2, et même dans ce cas, ils sont désactivés à moins que le paramètre de noyau atkbd.softraw=0 ne soit utilisé. Lorsque les codes d'analyse bruts ne sont pas disponibles, le noyau utilise une table intégrée fixe pour produire des codes d'analyse à partir des codes clés. Ainsi, setkeycodes(8) peut affecter la sortie de showkey en mode scan code dump.

Je suis sur le point de voir si showkey videra quoi que ce soit avec les touches de macro après la définition de cette option de démarrage.

EDIT :Après le redémarrage, pas de succès, mais je cherchais à capturer l'entrée brute des périphériques USB eux-mêmes. J'ai noté ce qui suit, de manière intéressante (j'ai un Razer Diamondback ainsi qu'un 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]#

Cependant, l'utilisation de dd pour capturer l'entrée brute fonctionne sur les deux souris diamondback, sur le périphérique event-kbd, mais pas sur les souris BlackWidow.

Je suppose qu'ils ne génèrent peut-être aucune sortie tant qu'ils ne sont pas activés par les pilotes installés. Cependant, je ne connais pas grand-chose à Linux USB, donc je ne sais même pas si cela a du sens. Peut-être doivent-ils d'abord être liés?

Eh bien, les trois appareils de veuve noire sont notés dans /proc/bus/input/devices , cependant ils ne semblent pas être énumérés dans lsusb ou /proc/bus/usb/devices . Je ne sais pas comment accéder à ces appareils pour tenter de les lier ou de s'interfacer avec eux de quelque manière que ce soit.

event4 semble correspondre au clavier réel, event6 avec les touches de macro, mais je ne peux toujours pas capturer d'entrée de leur part. J'espère que tout a aidé.

   [[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. Linux - Obtenir des informations sur le matériel d'une machine sous Linux ?

  2. Installer Apache 2 à partir de la source sur Linux

  3. Comment fonctionne copy_from_user du noyau Linux en interne ?

  4. Comment installer TBB à partir de la source sur Linux et le faire fonctionner

  5. Affichage de l'écran GNU + du mastic

Premiers pas avec Etcher.io

Passer de Windows à Linux

Linux - Obtenir les capacités du lecteur de CD/DVD lorsque les appareils Wodim ne fonctionnent pas ?

Linux - Comment exécuter un chargeur de démarrage à partir de Linux ?

Le Razer Kiyo fonctionne-t-il sous Linux ?

Installer Linux Mint à partir d'une clé USB