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

J'ai pris un Razer BlackWidow Ultimate qui a des clés supplémentaires pour les macros définies à l'aide d'un outil installé sur Windows . Je suppose que ce ne sont pas des clés joojoo de fancypans et devraient émettre des scancodes comme n'importe quelle autre clé.

Tout d'abord, existe-t-il un moyen standard de vérifier ces scancodes sous Linux? Deuxièmement, comment configurer ces clés pour faire des choses en ligne de commande et des configurations Linux basées sur X? Mon installation Linux actuelle est Xubuntu 10.10, mais je vais passer à Kubuntu une fois que j'ai réparé certaines choses. Idéalement, la réponse devrait être générique et à l'échelle du système.

Les choses que j'ai essayé jusqu'à présent:

  • showkeys partir du paquet kbd intégré (dans un showkeys ) – les touches macro n'ont pas été détectées

  • xev – macro keys not detected

  • Contenu de / dev / input / by-path ainsi que sortie lsusb et evdev

  • La sortie de ce script ahk suggère que les touches M ne produisent pas de scannodes standard détectables par Windows

Ce qu'il faut essayer

  • Snoopy pro + reverse engineering (oh cher)

  • Wireshark – l'avant-projet préliminaire semble indiquer qu'aucun scancode n'est émis lorsque l'on pense que le clavier est surveillé et que les touches sont pressées. Peut indiquer que les clés supplémentaires sont un périphérique distinct ou doivent être initialisées en quelque sorte.

  • Il faut faire référence à la sortie de lsusb à partir de Linux, dans trois scénarios: autonome, transmis à une machine virtuelle Windows sans que les pilotes soient installés et les mêmes.

  • LSUSB détecte uniquement un périphérique sur une installation Linux autonome

  • Il pourrait être utile de vérifier si les souris utilisent le même pilote Razer Synapse, car cela signifie que certaines variantes de razercfg pourraient fonctionner (non détectées, ne semble que fonctionner pour les souris)

Les choses que j'ai analysées:

  • Dans un système Windows avec le pilote, le clavier est considéré comme un clavier et un périphérique de pointage. Le périphérique de pointage utilise – en plus de vos pilotes de souris standard – un pilote pour quelque chose appelé Razer Synapse.

  • Pilote de la souris vu sous Linux sous evdev et lsusb aussi

  • Dispositif unique sous OS X apparemment, même si je n'ai pas encore essayé lsusb équivalent à cela

  • Le clavier passe en mode de rétro-éclairage pulsé dans OS X lors de l'initialisation avec le pilote. Cela devrait probablement indiquer qu'il y a une séquence d'initialisation envoyée au clavier lors de l'activation.

  • Ce sont, en fait, des clés joojoo de fancypes.

Extension de cette question un peu:

J'ai accès à un système Windows, donc, si j'ai besoin d'utiliser des outils pour répondre à la question, c'est très bien. Je peux également l'essayer sur des systèmes avec et sans l'utilitaire de configuration. Le résultat final attendu est encore de rendre ces clés utilisables sur Linux cependant.

Je me rends compte aussi que c'est une famille de matériel très spécifique. Je serais prêt à tester tout ce qui a du sens sur un système Linux si j'ai des instructions détaillées – cela devrait ouvrir la question aux personnes ayant des compétences Linux, mais pas à ce clavier.

Le résultat final minimum dont j'ai besoin:

J'ai besoin de ces touches détectées et utilisables de n'importe quelle manière sur l'une des variantes graphiques actuelles actuelles d'Ubuntu, et je dois naturellement travailler avec mon clavier. Cookie virtuel et accessoires fou si c'est quelque chose bien emballé et utilisable par l'utilisateur moyen.

Je vais exiger un code compilé qui fonctionnera sur mon système, ou une source que je peux compiler (avec des instructions si c'est plus complexe que ./configure , make , make install ) si un logiciel supplémentaire ne se trouve pas dans les dépôts Ubuntu pour le LTS actuel ou standard Sortie de bureau au moment de la réponse. Je demanderai également des informations suffisantes pour répliquer et utiliser avec succès les clés sur mon propre système.

6 Solutions collect form web for “Obtenir des clés macro d'un Razer BlackWidow pour fonctionner sous Linux”

M1-M5 sont en fait des clés régulières – ils doivent être activés spécifiquement avant de les presser, ils généreront un scancode. Tux_mark_5 a développé un petit programme Haskell qui envoie le message SET_REPORT correct aux claviers Razer pour activer ces clés, et ex-parrot a porté le même code sur Python.

Sur les systèmes linux Arc, le port Python a été emballé et est disponible à partir de https://aur.archlinux.org/packages.php?ID=60518 .

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

  aptitude install python-usb 

Ensuite, prenez le fichier blackwidow_enable.py à partir de http://finch.am/projects/blackwidow/ et exécutez-le (également en tant que root):

  chmod +x blackwidow_enable.py ./blackwidow_enable.py 

Cela permettra aux touches jusqu'à ce que le clavier soit débranché ou que la machine soit redémarré. Pour faire de cet appel permanent le script de n'importe quel style de script de démarrage que vous préférez le plus. Pour obtenir des instructions sur la configuration de Debian, consultez la documentation Debian .

Pour utiliser le code Haskell de tux_mark_5, vous devez 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. Recherchez la liste des paquets:

     cabal update 
  3. Installez les liaisons USB pour haskell (pas besoin de root):

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

     git clone git://github.com/tuxmark5/EnableRazer.git 
  5. Construire l'utilité:

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

     ./dist/build/EnableRazer/EnableRazer 

Après cela, vous pouvez copier EnableRazer binary partout où vous le souhaitez 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. Des événements pour FN sont également émis. Ces touches peuvent être liées à des actions arbitraires dans xbindkeys ou les paramètres système de KDE.

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

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

Razer semble obliger son configurateur Synapse 2 basé sur le cloud sur tous les utilisateurs de nos jours, avec la mise à jour du firmware qui l'accompagne à la version 2. *. Une fois que vous avez mis à niveau le firmware, vous ne pouvez pas revenir en arrière (le clavier est complètement brique si vous essayez de le faire passer avec un ancien firmware).

Les «octets magiques» du programme haskell ci-dessus ne fonctionneront pas avec le dernier microprogramme. Au lieu de cela, le pilote envoie ces octets lors de la séquence d'initialisation: '0200 0403'. Ceux-ci permettent 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 pressé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 macro restent non reconnues: le pilote HID ne contient aucune donnée sur le calque d'entrée lorsqu'ils sont pressés.

Pour que votre clavier entre dans le mode hérité (dans lequel les touches Macro envoient les codes-clés XF86Launch * et la touche FN envoie le code de 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 rugueux et sale que j'ai écrit dans Python3 moins esotherique pour effectuer la tâche. Notez le code pour générer les paquets de contrôle Razer en blackwidow.bwcmd () et les commandes LED du logo Razer en prime 🙂

 #!/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 showkey):

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

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

Je suis sur le point de voir si Showkey va décharger 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, intéressant (j'ai un Razer Diamondback ainsi que 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]# 

Cependant, en utilisant dd pour capturer les entrées brutes sur les deux souris Diamondback, sur le périphérique événement kbd, mais pas sur les périphériques de souris BlackWidow.

Je devine peut-être qu'ils ne génèrent aucune sortie jusqu'à ce qu'ils soient activés par les pilotes installés. Je ne connais pas beaucoup de Linux USB, alors je ne sais même pas si cela a du sens. Peut-être qu'ils doivent d'abord être liés?

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

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

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

Ma solution est pour le clavier de jeu mécanique Razer BlackWidow 2013 (numéro de modèle: RZ03-0039) et a été testé sur openSUSE 12.3.

J'ai utilisé Google translate sur ce lien

Fondamentalement, il utilise la version modifiée de la réponse de @ Sergey pour cette question, mais avec des modifications simples:

  1. Mon PRODUCT_ID = 0x011b

  2. Sur mon openSUSE 12.3, python-usb n'est pas disponible pour Python 3, donc j'ai converti ce script pour fonctionner avec Python 2 en supprimant la méthode bwcmd et USB_BUFFER = ... défini USB_BUFFER = ... comme dans le lien à partir de la réponse @ tux_mark_5 .


Pour plus de commodité, voici le contenu de mon /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 Mecanical 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() 

… et mon /etc/udev/rules.d/99-razer-balckwidow.rules est:

 SUBSYSTEM=="usb", ACTION=="add", ATTR{idVendor}=="1532", ATTR{idProduct}=="011b", RUN+="/usr/local/sbin/init_blackwidow.py" 

En tant qu'observation d'une personne qui travaille à faire tourner la magie de la série G de Logitech à nouveau sur Linux (Travaillant, bien que lentement, sur une nouvelle tentative de démarrage pour implémenter Gnome15 à partir d'une perspective d'ardoise propre …), vous devriez probablement regarder ce que l'OS Vous le dit. C'est un périphérique HID avec des bords HID personnalisés, tout comme les G15 / G510s / G13 / G19. Certaines des astuces que vous faites sont de demander au clavier de fournir, par un bordereau non officiel, une génération d'événements clés mappée que les pilotes HID sous Linux comprennent et émettent des événements clés appropriés. Cela va être «brisé» à chaque fois qu'ils décident de faire une mise à jour du firmware et de modifier le comportement.

Tout comme avec les choses de Logitech, il est très probable que vous soyez cohérent lorsque vous travaillez avec le bord HID, parce qu'ils n'ont pas autant de variances, et qu'ils ne veulent pas coder Synapse sur chaque variante visqueuse qui pourrait être leur façon.

Heh … budget autorisant, je vais acheter un de ces jouets chers et faire le même type de magie / effort pour le combiner à un système utilisable. Nous devons soit obtenir des mappages appropriés définis comme un pilote supplémentaire pour la couche HID ou exécuter un service "G15Daemon" qui capture les événements HID et effectue le mappage. Je me penche vers le démon parce que vous avez l'envoi de l'affichage, etc., que l'infrastructure du conducteur HID n'est pas encadrée et qu'il faudrait une révision pour supporter correctement les écrans HID (valide …) et similaires. En fin de compte, il se peut que nous voulions des pilotes du noyau, mais l'API HID et l'interface HID base et base vous donnent assez pour faire un démon une fois que vous avez inversé les codes d'événement de l'appareil.

  • Windows 7: partition du système déplacé, besoin de mettre à jour la partition de démarrage
  • Pourquoi l'invite "mot de passe" prend-elle une éternité lorsque je SSH dans mon serveur Ubuntu 9.05?
  • Ajouter les entrées de démarrage de Windows après l'installation d'Ubuntu?
  • Quel est l'équivalent de la commande apt-get d'Ubuntu sur un Mac
  • Supprimer GRUB Loader
  • Modifiez la page de code par défaut de latin1 à utf8 sur une machine linux
  • Comment copier quelque chose sur le www-directory d'Apache en utilisant une interface graphique?
  • Comment savoir si le matériel de mon ordinateur est compatible avec Ubuntu?
  • SSH ne fonctionne pas sur Ubuntu
  • Taille de police des emacs dans ubuntu
  • Effacer le terminal à l'aide du raccourci clavier
  • Soyons le génie de l'ordinateur et du réseau.