web-dev-qa-db-ja.com

Linuxで動作するようにRazer BlackWidowからマクロキーを取得する

Razer BlackWidow Ultimate を取得しました。これには、 Windowsにインストールされているツール を使用して設定されたマクロ用の追加キーがあります。これらは一部の空想的なjoojooキーではなく、他のキーと同様にスキャンコードを発行する必要があると想定しています。

まず、Linuxでこれらのスキャンコードをチェックする標準的な方法はありますか?次に、コマンドラインやXベースのLinuxセットアップでこれらのキーを設定するにはどうすればよいですか?私の現在のLinuxインストールはXubuntu 10.10ですが、いくつかの修正が完了したら、Kubuntuに切り替えます。理想的には、答えは一般的でシステム全体にわたるものである必要があります。

これまでに試したこと:

私が試す必要があるもの

  • snoopy pro +リバースエンジニアリング(ああ)

  • Wireshark-予備的な混乱は、キーボードが監視され、キーが押されていると私が思うように思われるときにスキャンコードが出力されないことを示しているようです。追加のキーが別のデバイスであるか、何らかの方法で初期化する必要があることを示す場合があります。

  • Linuxからのlsusb出力と相互参照する必要があります。3つのシナリオ:スタンドアロン、Windowsに渡されるVMドライバーがインストールされていない、および同じです。

  • LSUSBはスタンドアロンのLinuxインストールで1つのデバイスのみを検出します

  • razercfg の一部のバリエーションが機能する可能性があるため、マウスが同じRazer Synapseドライバーを使用しているかどうかを確認すると役立つ場合があります(検出されず、マウスでのみ機能するようです)

私が解決したこと:

  • ドライバのあるWindowsシステムでは、キーボードはキーボードおよびポインティングデバイスとして表示されます。ポインティングデバイスは、沼地の標準マウスドライバーに加えて、Razer Synapseと呼ばれるもののドライバーを使用します。

  • Linuxでevdevおよびlsusbの下にも表示されるマウスドライバー

  • OS Xでは単一のデバイスのようですが、これについてはまだlsusb相当のものを試していません

  • ドライバで初期化すると、キーボードはOS Xでパルスバックライトモードになります。これはおそらく、起動時にキーボードに送信される初期化シーケンスがあることを示しているはずです。

  • 彼らは、実際には、空想家joojooキーです。

この質問を少し拡張します:

私はWindowsシステムにアクセスできるので、その上でツールを使用して質問に答える必要がある場合は問題ありません。また、configユーティリティがあるシステムとないシステムでも試してみることができます。予想される最終結果は、これらのキーをLinuxで使用できるようにすることです。

また、これは非常に特殊なハードウェアファミリであることも理解しています。詳細な手順があれば、Linuxシステムで意味のあることなら何でもテストするつもりです。これにより、Linuxのスキルはあるがこのキーボードにアクセスできない人に質問が開かれるはずです。

必要な最小の最終結果:

これらのキーを検出し、現在のグラフィカルなメインストリームUbuntuバリアントのいずれかでanyの方法で使用できるようにする必要があります。当然、キーボードで操作する必要があります。仮想Cookieと狂った小道具(パッケージ化されていて、平均的なユーザーが使用できるもの)。

システムで機能するコンパイル済みコード、またはコンパイル可能なソース(./configuremakemake installよりも複雑な場合の指示付き)が必要です回答時の現在のLTSまたは標準デスクトップリリースのUbuntuリポジトリ。複製し、自分のシステムでキーを正常に使用するには、十分な情報も必要です。

50
Journeyman Geek

M1-M5は実際には通常のキーです。これらのキーを押すとスキャンコードが生成される前に、特別に有効にする必要があります。 Tux_mark_5は、正しいSET_REPORTメッセージをRazerキーボードに送信してこれらのキーを有効にする小さなHaskellプログラムを開発し、元オウムは同じコードをPythonに移植しました。

Arch Linuxシステムでは、Pythonポートがパッケージ化されており、 https://aur.archlinux.org/packages.php?ID=60518 から入手できます。

DebianまたはUbuntuシステムでは、コードのPythonポートのセットアップは比較的簡単です。ルートとしてPyUSBとlibusbをインストールする必要があります。

    aptitude install python-usb

次に、blackwidow_enable.pyファイル http://finch.am/projects/blackwidow/ から実行し、(ルートとしても)実行します。

    chmod +x blackwidow_enable.py
    ./blackwidow_enable.py

これにより、キーボードが外されるか、マシンが再起動されるまで、キーが有効になります。これを永続的にするために、最も好きなスタイルの起動スクリプトからスクリプトを呼び出します。 Debianでこれを設定する方法については、 Debianのドキュメント を参照してください。

Tux_mark_5のHaskellコードを使用するには、Haskellをインストールして自分でコードをコンパイルする必要があります。これらの手順は、Debianのようなシステム(Ubuntuを含む)を対象としています。

  1. GHC、libusb-1.0-0-devおよびcabal(ルートとして)をインストールします。

    aptitude install ghc libusb-1.0-0-dev cabal-install git pkg-config
    
  2. パッケージのリストを取得します。

    cabal update
    
  3. HaskellのUSBバインディングをインストールします(rootは必要ありません):

    cabal install usb
    
  4. ユーティリティをダウンロードします。

    git clone git://github.com/tuxmark5/EnableRazer.git
    
  5. ユーティリティをビルドします。

    cabal configure
    cabal build
    
  6. ユーティリティを実行します(ルートとしても):

    ./dist/build/EnableRazer/EnableRazer
    

この後、EnableRazerバイナリを任意の場所にコピーして、起動時に実行できます。

実行直後、XサーバーはM1をXF86Tools、M2をXF86Launch5、M3をXF86Launch6、M4をXF86Launch7、M5をXF86Launch8として認識します。 FNのイベントも発行されます。

これらのキーは、xbindkeysまたはKDEのシステム設定内で任意のアクションにバインドできます。

キーボードが異なる場合があるため、Main.hs行64の製品IDを変更する必要がある場合があります。

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

Razerは現在、すべてのユーザーにクラウドベースのSynapse 2コンフィギュレーターを強制しているようで、それに伴ってファームウェアがバージョン2. *にアップグレードされています。ファームウェアをアップグレードすると、元に戻すことはできません(古いファームウェアでフラッシュしようとすると、キーボードが完全に壊れてしまいます)。

Tux_mark_5の回答 のHaskellプログラムからの「マジックバイト」は、最新のファームウェアでは動作しません。代わりに、ドライバーは初期化シーケンス中に「0200 0403」のバイトを送信します。これらはマクロキーを有効にしますが、キーボードは標準のHIDプロトコルの代わりに16バイトのパケットを送信する(おそらく同時に押すことができるキーの数を増やすため)独特のモードに入ります。 Linux HIDシステムはこれに完全に対応できず、ほとんどのキーは期待どおりに機能しますが、マクロキーは認識されないままです。

キーボードをレガシーモードにするには(マクロキーがXF86Launch *キーコードを送信し、FNキーがキーコード202を送信する)、次のバイトを送信します:0200 0402。

完全なパケットは次のようになります。

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

これは、タスクを実行するために私がそれほど難解でないPython 3で作成した、非常にラフで汚いプログラムです。 Blackwidow.bwcmd()でRazer制御パケットを生成するコードと、ボーナスとしてRazerロゴのLEDコマンドに注意してください:)

#!/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()
23
Sergey

たぶん、これはこの問題に光を当てるかもしれません(showkeyマンページから):

2.6カーネルでは、rawモード、またはスキャンコードモードは、まったくrawではありません。スキャンコードは最初にキーコードに変換されます。スキャンコードが必要な場合は、キーコードが変換されます。さまざまな変換が行われ、最終的な結果がキーボードハードウェアが送信したものに対応しているという保証はまったくありません。したがって、さまざまなキーによって送信されたスキャンコードを知りたい場合は、2.4カーネルを起動することをお勧めします。 2.6.9以降、2.6カーネルに実際のスキャンコードを返すように指示するブートオプションatkbd.softraw = 0もあります。

未加工のスキャンコードはATおよびPS/2キーボードでのみ使用でき、atkbd.softraw = 0カーネルパラメータが使用されていない限り無効になります。未加工のスキャンコードが使用できない場合、カーネルは固定組み込みテーブルを使用してキーコードからスキャンコードを生成するため、setkeycodes(8)はスキャンコードダンプモードでのshowkeyの出力に影響を与える可能性があります。

この起動オプションが設定された後、showkeyがマクロキーで何かをダンプするかどうかを確認しようとしています。

編集:再起動後、成功しませんでしたが、USBデバイス自体からの生の入力をキャプチャすることを検討していました。おもしろいことに、次のことに気づきました(Razer Diamondbackと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]#

ただし、生の入力をキャプチャするためにddを使用すると、両方のdiamondbackマウス、event-kbdデバイスで機能しますが、BlackWidowマウスデバイスでは機能しません。

インストールされているドライバーによって何らかの方法でアクティブ化されるまで、出力が生成されないのではないかと思います。 Linux USBについてはあまり詳しくないので、これが理にかなっているかどうかもわかりません。おそらく最初にバインドする必要がありますか?

まあ、3つの黒いWidowデバイスはすべて/proc/bus/input/devicesで示されていますが、lsusbまたは/proc/bus/usb/devicesに列挙されていないようです。これらのデバイスにアクセスして、それらをバインドしたり、何らかの方法でそれらとインターフェースしたりする方法を知りません。

event4は、実際のキーボードevent6とマクロキーに対応しているようですが、それでも入力をキャプチャできません。すべてがお役に立てば幸いです。

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

私の解決策はRazer BlackWidow 2013メカニカルゲーミングキーボード(モデル番号:RZ03-0039)で、openSUSE 12.3でテストされています。

このリンク でGoogle翻訳を使用しました。

基本的に、この質問には @ Sergey's answer の変更されたバージョンを使用しますが、簡単な変更が加えられています。

  1. ぼくの PRODUCT_ID = 0x011b

  2. 私のopenSUSE 12.3では、Python 3でpython-usbを使用できないため、このスクリプトをPython 2で動作するように変換し、bwcmdメソッドとUSB_BUFFER = ...リンク@ Tux_mark_5の回答 のように。


便宜上、ここに私の/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()

... と私 /etc/udev/rules.d/99-razer-balckwidow.rulesは:

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

多分このドキュメントはあなたを助けるでしょう:

LinuxキーボードとコンソールのHOWTO便利なプログラム

2
ascobol

LinuxのRazer Key Mapperを参照してください。

これは、コードを変更した場合、すべてのRazerデバイスのマクロで機能します。それでも解決策がなく、デバイスがリストにない場合は、デバイスの構成とサポートされているリストへの追加をお手伝いさせていただきます。

1
Camille Guay