it-swarm.com.de

Makrotasten von einem Razer BlackWidow für Linux verwenden

Ich habe ein Razer BlackWidow Ultimate mit zusätzlichen Schlüsseln für Makros gefunden, die mit einem installierten Tool erstellt wurden Windows . Ich gehe mal davon aus, dass dies keine Fancypants-Joojoo-Keys sind und Scancodes wie alle anderen Keys ausgeben sollten.

Erstens, gibt es eine Standardmethode, um diese Scancodes unter Linux zu überprüfen? Zweitens, wie stelle ich diese Schlüssel so ein, dass sie in Befehlszeilen- und X-basierten Linux-Setups verwendet werden? Meine aktuelle Linux-Installation ist Xubuntu 10.10, aber ich werde zu Kubuntu wechseln, sobald ein paar Dinge behoben sind. Idealerweise sollte die Antwort generisch und systemweit sein.

Dinge, die ich bisher versucht habe:

Dinge, die ich versuchen muss

  • Snoopy Pro + Reverse Engineering (oh je)

  • Wireshark - vorläufiges Herumfummeln scheint darauf hinzudeuten, dass keine Scancodes ausgegeben wurden, wenn meines Erachtens die Tastatur überwacht und Tasten gedrückt werden. Kann bedeuten, dass zusätzliche Tasten ein separates Gerät sind oder auf irgendeine Weise initialisiert werden müssen.

  • In drei Szenarien muss dies mit der lsusb-Ausgabe von Linux verglichen werden: Standalone, Übergabe an ein Windows VM ohne installierte Treiber und dasselbe mit.

  • LSUSB erkennt nur ein Gerät bei einer eigenständigen Linux-Installation

  • Es kann nützlich sein, zu überprüfen, ob die Mäuse denselben Razer Synapse-Treiber verwenden, da dies bedeutet, dass eine Variation von razercfg möglicherweise funktioniert (nicht erkannt, scheint nur zu funktionieren) Arbeit für Mäuse)

Dinge, die ich ausgearbeitet habe:

  • In einem Windows-System mit dem Treiber wird die Tastatur als Tastatur und als Zeigegerät angesehen. Das Zeigegerät verwendet - zusätzlich zu Ihren Standardmaus-Treibern - einen Treiber für etwas, das als Razer Synapse bezeichnet wird.

  • Maustreiber unter Linux auch unter evdev und lsusb zu sehen

  • Einzelgerät unter OS X anscheinend, obwohl ich lsusb gleichwertig noch nicht ausprobiert habe

  • Die Tastatur wechselt in OS X nach der Initialisierung mit dem Treiber in den pulsierenden Hintergrundbeleuchtungsmodus. Dies sollte wahrscheinlich darauf hinweisen, dass beim Aktivieren eine Initialisierungssequenz an die Tastatur gesendet wird.

  • Sie sind in der Tat Fancypants Joojoo-Schlüssel.

Diese Frage ein wenig erweitern:

Ich habe Zugriff auf ein Windows-System. Wenn ich also Tools verwenden muss, um die Frage zu beantworten, ist dies in Ordnung. Ich kann es auch auf Systemen mit und ohne das Konfigurationsdienstprogramm versuchen. Das erwartete Endergebnis ist jedoch, diese Schlüssel unter Linux nutzbar zu machen.

Mir ist auch klar, dass dies eine sehr spezielle Hardwarefamilie ist. Ich würde gerne alles testen, was auf einem Linux-System Sinn macht, wenn ich detaillierte Anweisungen habe - dies sollte die Frage für Leute öffnen, die über Linux-Kenntnisse verfügen, aber keinen Zugriff auf diese Tastatur haben.

Das minimale Endergebnis, das ich benötige:

Ich muss diese Tasten erkannt haben und in jeder Art und Weise auf einer der aktuellen grafischen Ubuntu-Hauptvarianten verwendbar sein und muss natürlich mit meiner Tastatur arbeiten. Virtuelle Kekse und verrückte Requisiten, wenn sie gut verpackt sind und vom durchschnittlichen Benutzer verwendet werden können.

Ich benötige kompilierten Code, der auf meinem System funktioniert, oder eine Quelle, die ich kompilieren kann (mit Anweisungen, wenn sie komplexer ist als ./configure, make, make install), wenn sich keine zusätzliche Software auf den Ubuntu-Repositories für das aktuelle LTS oder die Standard-Desktop-Version unter befindet die Zeit der Antwort. Ich benötige auch ausreichende Informationen, um die Schlüssel auf meinem eigenen System zu replizieren und erfolgreich zu verwenden.

49
Journeyman Geek

M1-M5 sind in der Tat normale Tasten - sie müssen nur speziell aktiviert werden, bevor sie gedrückt werden, um einen Scancode zu generieren. Tux_mark_5 entwickelte ein kleines Haskell-Programm, das die richtige SET_REPORT-Nachricht an Razer-Tastaturen sendet, um diese Tasten zu aktivieren, und Ex-Parrot portierte denselben Code nach Python.

Auf Arch Linux-Systemen wurde der Python-Port gepackt und ist unter https://aur.archlinux.org/packages.php?ID=60518 verfügbar.

Auf Debian- oder Ubuntu-Systemen ist es relativ einfach, den Python-Port des Codes einzurichten. Sie müssen PyUSB und libusb (als root) installieren:

    aptitude install python-usb

Dann nimm die blackwidow_enable.py Datei von http://finch.am/projects/blackwidow/ und führe sie aus (auch als root):

    chmod +x blackwidow_enable.py
    ./blackwidow_enable.py

Dadurch werden die Tasten aktiviert, bis die Tastatur ausgesteckt oder der Computer neu gestartet wird. Um dies dauerhaft zu machen, rufen Sie das Skript aus einem beliebigen Startskript auf, das Sie am meisten bevorzugen. Anweisungen zum Einrichten in Debian finden Sie in der Debian-Dokumentation .

Um den Haskell-Code von Tux_mark_5 zu verwenden, müssen Sie Haskell installieren und den Code selbst kompilieren. Diese Anweisungen gelten für ein Debian-ähnliches System (einschließlich Ubuntu).

  1. Installieren Sie GHC, libusb-1.0-0-dev und cabal (als root):

    aptitude install ghc libusb-1.0-0-dev cabal-install git pkg-config
    
  2. Holen Sie sich die Liste der Pakete:

    cabal update
    
  3. Installieren Sie USB-Bindungen für Haskell (kein Root erforderlich):

    cabal install usb
    
  4. Laden Sie das Dienstprogramm herunter:

    git clone git://github.com/tuxmark5/EnableRazer.git
    
  5. Erstellen Sie das Dienstprogramm:

    cabal configure
    cabal build
    
  6. Führen Sie das Dienstprogramm aus (auch als root):

    ./dist/build/EnableRazer/EnableRazer
    

Danach können Sie die EnableRazer-Binärdatei an eine beliebige Stelle kopieren und beim Start ausführen.

Unmittelbar nach der Ausführung sollte X Server M1 als XF86Tools, M2 als XF86Launch5, M3 als XF86Launch6, M4 als XF86Launch7 und M5 als XF86Launch8 anzeigen. Events für FN werden ebenfalls ausgegeben.

Diese Schlüssel können in xbindkeys oder in den KDE-Systemeinstellungen an beliebige Aktionen gebunden werden.

Da sich Ihre Tastatur möglicherweise unterscheidet, müssen Sie möglicherweise die Produkt-ID in Zeile 64 von Main.hs ändern:

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

Razer scheint heutzutage seinen Cloud-basierten Synapse 2-Konfigurator auf alle Benutzer auszudehnen, mit begleitendem Firmware-Upgrade auf Version 2. *. Sobald Sie die Firmware aktualisiert haben, können Sie nicht mehr zurückkehren (die Tastatur ist vollständig blockiert, wenn Sie versuchen, sie mit einer älteren Firmware zu flashen).

Die "magischen Bytes" aus dem Haskell-Programm in Tux_mark_5s Antwort funktionieren nicht mit der neuesten Firmware. Stattdessen sendet der Treiber diese Bytes während der Initialisierungssequenz: "0200 0403". Diese aktivieren die Makrotasten, aber die Tastatur wechselt in einen bestimmten Modus, in dem anstelle des Standard-HID-Protokolls 16-Byte-Pakete gesendet werden (vermutlich, um die Anzahl der Tasten zu erhöhen, die gleichzeitig gedrückt werden können). Linux HID-System kann das nicht ganz bewältigen, und während die meisten Tasten wie erwartet funktionieren, werden die Makrotasten nicht erkannt: Der HID-Treiber gibt beim Drücken keine Daten an die Eingabeebene weiter.

Um Ihre Tastatur in den Legacy-Modus zu versetzen (in dem die Makrotasten den XF86Launch * -Tastencode und die FN-Taste den Tastencode 202 senden), senden Sie die folgenden Bytes: 0200 0402.

Das vollständige Paket lautet:

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

Hier ist ein sehr raues und schmutziges Programm, das ich in weniger esoterischem Python 3 geschrieben habe, um die Aufgabe auszuführen. Beachten Sie den Code zum Generieren der Razer-Steuerpakete in blackwidow.bwcmd () und die LED-Befehle für das Razer-Logo als 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 __== '__main__':
    main()
22
Sergey

Vielleicht bringt dies etwas Licht in das Thema (aus der Showkey-Manpage):

In 2.6-Kerneln ist der Raw-Modus oder der Scancode-Modus überhaupt nicht sehr raw. Scan-Codes werden zuerst in Schlüsselcodes übersetzt, und wenn Scancodes gewünscht werden, werden die Schlüsselcodes zurückübersetzt. Es gibt verschiedene Transformationen, und es gibt keinerlei Garantie dafür, dass das Endergebnis dem entspricht, was die Tastaturhardware gesendet hat. Wenn Sie also die von verschiedenen Schlüsseln gesendeten Scan-Codes kennen möchten, ist es besser, einen 2.4-Kernel zu booten. Seit 2.6.9 gibt es auch die Boot-Option atkbd.softraw = 0, die den 2.6-Kernel anweist, die tatsächlichen Scan-Codes zurückzugeben.

Die unformatierten Scan-Codes sind nur auf AT - und PS/2-Tastaturen verfügbar. Sie sind auch dann deaktiviert, wenn nicht der Kernelparameter atkbd.softraw = 0 verwendet wird. Wenn die unformatierten Scan-Codes nicht verfügbar sind, verwendet der Kernel eine fest eingebaute Tabelle, um aus den Schlüsselcodes Scan-Codes zu erstellen. Setkeycodes (8) können daher die Ausgabe von showkey im Scan-Code-Dump-Modus beeinflussen.

Ich bin dabei zu sehen, ob showkey irgendetwas mit den Makrotasten ausgeben wird, nachdem diese Startoption gesetzt wurde.

BEARBEITEN: Nach dem Neustart kein Erfolg, aber ich wollte Rohdaten von den USB-Geräten selbst erfassen. Interessanterweise habe ich Folgendes bemerkt (ich habe einen Razer Diamondback sowie 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]#

Die Verwendung von dd zum Erfassen der unformatierten Eingabe funktioniert jedoch auf beiden Diamondback-Mäusen, auf dem event-kbd-Gerät, jedoch nicht auf den BlackWidow-Mausgeräten.

Ich vermute, dass sie keine Ausgabe generieren, bis sie irgendwie von den installierten Treibern aktiviert werden. Ich weiß jedoch nicht viel über Linux USB, daher weiß ich nicht einmal, ob dies Sinn macht. Vielleicht müssen sie zuerst gebunden werden?

Nun, alle drei Black Widow-Geräte sind in /proc/bus/input/devices vermerkt, scheinen jedoch nicht in lsusb oder /proc/bus/usb/devices aufgeführt zu sein. Ich bin nicht sicher, wie ich auf diese Geräte zugreifen soll, um zu versuchen, sie zu binden oder in irgendeiner Weise eine Schnittstelle zu ihnen herzustellen.

event4 scheint der tatsächlichen Tastatur zu entsprechen, event6 mit den Makrotasten, aber ich kann immer noch keine Eingaben von ihnen erfassen. Hoffe, dass alle geholfen haben.

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

Meine Lösung ist für Razer BlackWidow 2013 Mechanical Gaming Keyboard (Modellnummer: RZ03-0039) und wurde unter openSUSE 12.3 getestet.

Ich habe Google Translate für diesen Link verwendet .

Grundsätzlich wird die modifizierte Version von @ Sergeys Antwort für diese Frage verwendet, jedoch mit einfachen Modifikationen:

  1. Mein PRODUCT_ID = 0x011b

  2. Unter openSUSE 12.3 ist Python-usb für Python 3 nicht verfügbar. Daher habe ich dieses Skript so konvertiert, dass es mit Python 2 funktioniert, indem ich die Methode bwcmd entferne und den USB_BUFFER = ... wie im Link definiert habe aus @ Tux_mark_5s Antwort .


Der Einfachheit halber ist hier der Inhalt meines /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 __== '__main__':
    main()

... und mein /etc/udev/rules.d/99-razer-balckwidow.rules ist:

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

Vielleicht hilft Ihnen dieses Dokument:

Das Linux-HOWTO für Tastatur und Konsole, Nützliche Programme

2
ascobol

Siehe Razer Key Mapper für Linux.

Dies funktioniert mit allen Makros des Razer-Geräts, sofern der Code geändert wurde. Wenn Sie immer noch keine Lösung haben und Ihr Gerät nicht aufgeführt ist, kann ich Ihnen gerne helfen, Ihr Gerät zu konfigurieren und es meiner Liste der unterstützten Geräte hinzuzufügen.

1
Camille Guay