目的:マウスとしてエミュレートするホワイトボードがあります。したがって、ホワイトボードをクリックしてドラッグすると、カーソルが移動します。 Ubuntuでホワイトボードを動作させたいのですが、Windowsでも動作します。デバイス情報:デバイス情報を含むcat /proc/bus/input
の出力
I: Bus=0003 Vendor=4623 Product=011a Version=0111
N: Name="Hite Board-XXXXXXXX"
P: Phys=usb-0000:00:14.0-1/input0
S: Sysfs=/devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1:1.0/
U: Uniq=
H: Handlers=mouse2 event13
B: PROP=2
B: EV=b
B: KEY=400 0 0 0 0 0
B: ABS=260800000000003
abhishek@vaio:~$ lsusb -d 4623:011a -v
Bus 001 Device 012: ID 4623:011a
Couldn't open device, some information will be missing
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x4623
idProduct 0x011a
bcdDevice 0.01
iManufacturer 1
iProduct 2
iSerial 0
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 73
bNumInterfaces 2
bConfigurationValue 1
iConfiguration 0
bmAttributes 0x80
(Bus Powered)
MaxPower 150mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 3 Human Interface Device
bInterfaceSubClass 0 No Subclass
bInterfaceProtocol 0 None
iInterface 0
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.11
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 429
Report Descriptors:
** UNAVAILABLE **
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 8
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x01 EP 1 OUT
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 1
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 3 Human Interface Device
bInterfaceSubClass 0 No Subclass
bInterfaceProtocol 0 None
iInterface 6
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.10
bCountryCode 33 US
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 91
Report Descriptors:
** UNAVAILABLE **
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 1
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x02 EP 2 OUT
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 1
bInterfaceProtocol
はNoneであるため、Linuxはそれをマウス入力デバイスとして認識しません。
WindowsからリバースエンジニアリングしてLinuxで動作させるための理想的なアプローチは何ですか。
Windowsデバイスマネージャーのデバイス:
編集1:
abhishek@vaio:~/dev_work/whiteboard/pyusbwhiteboard$ usb-devices | grep -A5 'Vendor=4623 ProdID=011a' | grep Driver
I: If#= 0 Alt= 0 #EPs= 2 Cls=03(HID ) Sub=00 Prot=00 Driver=usbfs
I: If#= 1 Alt= 0 #EPs= 2 Cls=03(HID ) Sub=00 Prot=00 Driver=usbhid
dmesg出力: http://codepad.org/fFtwryw6
私は仕事をすることができるスクリプトを書きました。しかし、デバイスからの入力の意味を理解する必要がありました。
import sys,pdb
import usb.core
import usb.util
from pymouse import PyMouse
# whiteboard coordinates axis computed by checking the output against strokes
white_board_x_min=(1<<8)+1
white_board_x_max=(127<<8)+255
white_board_y_min=(1<<8)+1
white_board_y_max=(127<<8)+255
white_board_x_diff=white_board_x_max-white_board_x_min
white_board_y_diff=white_board_y_max-white_board_y_min
# mouse handler
m = PyMouse()
x_screen, y_screen = m.screen_size()
# decimal vendor and product values
dev = usb.core.find(idVendor=17955, idProduct=282)
# first endpoint
interface = 0
endpoint = dev[0][(0,0)][0]
# if the OS kernel already claimed the device, which is most likely true
# thanks to http://stackoverflow.com/questions/8218683/pyusb-cannot-set-configuration
if dev.is_kernel_driver_active(interface) is True:
# tell the kernel to detach
dev.detach_kernel_driver(interface)
# claim the device
usb.util.claim_interface(dev, interface)
mouse_down_event=False
try:
while True :
try:
data = dev.read(endpoint.bEndpointAddress,endpoint.wMaxPacketSize)
# click value
click=data[1] # if it is 7 mouse down else if it is 4 it is mouse up
# get the coordinates
xcor,ycor,dec_x_binary,dec_y_binary=data[4],data[6],data[3],data[5]
# convert to decimal
xcor_dec=(xcor<<8)+dec_x_binary
ycor_dec=(ycor<<8)+dec_y_binary
# convert to relative screen coordinates
screen_xcor=int(round((float(xcor_dec-white_board_x_min)/float(white_board_x_diff)) * x_screen))
screen_ycor=int(round((float(ycor_dec-white_board_y_min)/float(white_board_y_diff)) * y_screen))
#print "%d, %d"%(xcor_dec,ycor_dec)
#print "%d, %d"%(screen_xcor,screen_ycor)
# check if it is valid event
if xcor_dec!=0 and ycor_dec!=0:
# move mouse
if click==7:
# mean mouse down event
if mouse_down_event:
# drag event
# draw a line from previous coordinates
m.drag(screen_xcor, screen_ycor)
else:
# first button press event
m.click(screen_xcor, screen_ycor, 1)
mouse_down_event=True
else:
# mouse up event
# set event type in mouse_down_event
# first button press and drag
mouse_down_event=False
except usb.core.USBError as e:
data = None
if e.args == ('Operation timed out',):
continue
finally:
# release the device
usb.util.release_interface(dev, interface)
# reattach the device to the OS kernel
dev.attach_kernel_driver(interface)