Jou*_*eek 53 linux keyboard ubuntu razer-keyboard
我拿起了Razer BlackWidow Ultimate,它有额外的键,用于使用安装在 Windows 上的工具设置的宏。我假设这些不是一些花哨的 joojoo 键,应该像任何其他键一样发出扫描码。
首先,在 Linux 中是否有检查这些扫描码的标准方法?其次,如何设置这些键以在命令行和基于 X 的 Linux 设置中执行操作?我当前的 Linux 安装是 Xubuntu 10.10,但是一旦我修复了一些问题,我将切换到 Kubuntu。理想情况下,答案应该是通用的和系统范围的。
到目前为止我尝试过的事情:
showkeys 来自内置的 kbd 包(在单独的 vt 中)-未检测到宏键
xev - 未检测到宏键
这个ahk 脚本的输出表明 M 键没有输出 Windows 可检测的标准扫描码
我需要尝试的事情
史努比亲 + 逆向工程(哦,天哪)
Wireshark - 当我认为键盘受到监控并按下按键时,初步测试似乎表明没有发出扫描码。可能表明附加键是一个单独的设备或需要以某种方式初始化。
需要与 Linux 的 lsusb 输出交叉引用,在三种情况下:独立,传递到没有安装驱动程序的 Windows VM,以及相同。
LSUSB 仅在独立的 Linux 安装中检测到一个设备
检查鼠标是否使用相同的 Razer Synapse 驱动程序可能很有用,因为这意味着razercfg 的一些变化可能有效(未检测到,似乎只对鼠标有效)
我已经解决的事情:
在带有驱动程序的 Windows 系统中,键盘被视为键盘和指针设备。指点设备使用 - 除了沼泽标准鼠标驱动程序之外 - 一个称为 Razer Synapse 的驱动程序。
在Linux下看到的鼠标驱动程序evdev和lsusb也
显然是 OS X 下的单一设备,虽然我还没有尝试 lsusb过
使用驱动程序初始化后,键盘在 OS X 中进入脉冲背光模式。这应该可能表明在激活时有一些初始化序列发送到键盘。
事实上,它们是花哨的 joojoo 键。
稍微扩展一下这个问题:
我可以访问 Windows 系统,所以如果我需要使用任何工具来帮助回答问题,那很好。我也可以在有和没有配置实用程序的系统上尝试它。然而,预期的最终结果仍然是使这些密钥在 Linux 上可用。
我也意识到这是一个非常特殊的硬件系列。如果我有详细的说明,我愿意在 Linux 系统上测试任何有意义的东西 - 这应该向具有 Linux 技能但无法使用此键盘的人提出问题。
我要求的最低最终结果:
我需要检测到这些键,并在 任何当前图形主流 Ubuntu 变体上任何方式,并且自然必须与我的键盘一起使用。虚拟 cookie 和疯狂道具,如果它是普通用户很好地打包和使用的东西。
我需要编译的代码,将我的系统上工作,或者源,我可以编译(有说明,如果它比更复杂./configure,make,make install如果)不是在Ubuntu软件仓库当前LTS或时间标准桌面版本的其他软件答案。我还需要足够的信息来复制,并在我自己的系统上成功使用密钥。
小智 45
M1-M5 实际上是普通键——它们只需要在按下它们之前专门启用它们就会生成一个扫描码。tux_mark_5 开发了一个小型 Haskell 程序,该程序将正确的 SET_REPORT 消息发送到 Razer 键盘以启用这些键,并且 ex-parrot 将相同的代码移植到 Python。
在 Arch Linux 系统上,Python 端口已经打包,可从https://aur.archlinux.org/packages.php?ID=60518 获得。
在 Debian 或 Ubuntu 系统上,设置代码的 Python 端口相对容易。您需要安装 PyUSB 和 libusb(以 root 身份):
aptitude install python-usb
Run Code Online (Sandbox Code Playgroud)
然后blackwidow_enable.py从http://finch.am/projects/blackwidow/获取文件并执行它(也以 root 身份):
chmod +x blackwidow_enable.py
./blackwidow_enable.py
Run Code Online (Sandbox Code Playgroud)
这将启用按键,直到拔下键盘或重新启动机器。要使此永久调用脚本,请从您最喜欢的任何样式的启动脚本中调用该脚本。有关如何在 Debian 中进行设置的说明,请查看Debian 文档。
要使用 tux_mark_5 的 Haskell 代码,您需要安装 Haskell 并自己编译代码。这些说明适用于类似 Debian 的系统(包括 Ubuntu)。
安装 GHC、libusb-1.0-0-dev 和 cabal(作为 root):
aptitude install ghc libusb-1.0-0-dev cabal-install git pkg-config
Run Code Online (Sandbox Code Playgroud)获取包列表:
cabal update
Run Code Online (Sandbox Code Playgroud)为 Haskell 安装 USB 绑定(不需要 root):
cabal install usb
Run Code Online (Sandbox Code Playgroud)下载实用程序:
git clone git://github.com/tuxmark5/EnableRazer.git
Run Code Online (Sandbox Code Playgroud)构建实用程序:
cabal configure
cabal build
Run Code Online (Sandbox Code Playgroud)运行该实用程序(也以 root 身份):
./dist/build/EnableRazer/EnableRazer
Run Code Online (Sandbox Code Playgroud)在此之后,您可以将 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
Run Code Online (Sandbox Code Playgroud)
小智 24
如今,Razer 似乎正在强制所有用户使用基于云的 Synapse 2 配置器,同时将固件升级到版本 2.*。升级固件后,您将无法返回(如果您尝试使用旧固件刷新键盘,则键盘完全变砖)。
来自tux_mark_5 答案中Haskell 程序的“魔法字节”不适用于最新固件。相反,驱动程序在初始化序列期间发送这些字节:'0200 0403'。这些启用宏键,但键盘进入一种特殊模式,它发送 16 字节数据包而不是标准 HID 协议(大概是为了增加可以同时按下的键的数量)。Linux HID 系统无法完全解决这个问题,虽然大多数键按预期工作,但宏键仍然无法识别: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
Run Code Online (Sandbox Code Playgroud)
这是我用不太深奥的 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()
Run Code Online (Sandbox Code Playgroud)
小智 8
也许这可能会阐明这个问题(来自 showkey 联机帮助页):
在 2.6 内核原始模式或扫描码模式中,根本不是很原始。扫描码首先被转换为键码,当需要扫描码时,键码被转换回。涉及各种转换,并且根本无法保证最终结果与键盘硬件确实发送的内容相对应。所以,如果你想知道各种键发送的扫描码,最好启动一个 2.4 内核。从 2.6.9 开始,还有引导选项 atkbd.softraw=0 告诉 2.6 内核返回实际的扫描代码。
原始扫描码仅在 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]#
Run Code Online (Sandbox Code Playgroud)
但是,使用 dd 捕获原始输入适用于两个菱形鼠标、event-kbd 设备,但不适用于 BlackWidow 鼠标设备。
我猜也许他们不会产生任何输出,直到以某种方式被安装的驱动程序激活。然而,我对 Linux USB 了解不多,所以我什至不知道这是否有意义。也许他们需要先绑定?
好吧,所有三个黑寡妇设备都在 中注明/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]#
Run Code Online (Sandbox Code Playgroud)
我的解决方案适用于Razer BlackWidow 2013 机械游戏键盘(型号:RZ03-0039),并在 openSUSE 12.3 上进行了测试。
我在这个链接上使用了谷歌翻译。
基本上它使用@Sergey's answer的修改版本来解决这个问题,但做了简单的修改:
我的 PRODUCT_ID = 0x011b
在我的openSUSE 12.3,蟒蛇-USB不适用于Python 3中,所以我通过移除转换这个脚本的工作与Python 2bwcmd方法和确定的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()
Run Code Online (Sandbox Code Playgroud)
...而我的/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"
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
37999 次 |
| 最近记录: |