Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
uhidd [2010/03/07 00:48] – KaiWanguhidd [2019/09/18 02:39] (current) – Replace external image URL with local attachment KubilayKocak
Line 15: Line 15:
 ''%%uhidd%%'' also provide support for multimedia keys found on USB keyboard, a multimedia keymap needs ''%%uhidd%%'' also provide support for multimedia keys found on USB keyboard, a multimedia keymap needs
 to be created to make it function. See the examples section below. to be created to make it function. See the examples section below.
 +
 +====== News ======
 +
 +[2012-10-15] uhidd 0.2.1 released:
 +
 +  * Support for kernel driver detach
 +  * Support for mouse tilt wheel
 +  * Support for linear Volume control found on some keyboard
 +  * Support for cuse4bsd-based virtual device
  
 ====== Download & Install ====== ====== Download & Install ======
-The latest release tarball is [[http://people.freebsd.org/~kaiw/distfiles/uhidd-0.2.0.tar.gz|uhidd-0.2.0.tar.gz]]+The latest release tarball is [[https://people.freebsd.org/~kaiw/distfiles/uhidd-0.2.1.tar.gz|uhidd-0.2.1.tar.gz]]
  
-You could also fetch the latest source code from googlecode SVN:+You could also fetch the latest source code from github:
  
 <code> <code>
-% svn checkout http://uhidd.googlecode.com/svn/trunk/ uhidd+% git clone https://github.com/kaiwang27/uhidd.git
 </code> </code>
  
-The recommended way to install uhidd is through the ports system instead of compiling the source by yourself.+The recommended way to install ''%%uhidd%%'' is through the ports system instead of compiling the source by yourself.
  
 <code> <code>
-# cd /usr/ports/sysutils/uhidd +# pkg install uhidd
-# make install clean+
 </code> </code>
  
Line 39: Line 47:
 there is no kernel HID device driver attached to that device. You could either remove ''%%'device ukbd'%%'', there is no kernel HID device driver attached to that device. You could either remove ''%%'device ukbd'%%'',
 ''%%'device ums'%%'' and ''%%'device uhid'%%'' from your kernel config file and recomplie the kernel, or if these ''%%'device ums'%%'' and ''%%'device uhid'%%'' from your kernel config file and recomplie the kernel, or if these
-drivers are loaded as kernel modules, ''%%kldunload(8)%%'' them. However, ''%%uhidd%%''+drivers are loaded as kernel modules, ''%%kldunload(8)%%'' them. The relevant ''%%devd(8)%%'' rules for 
 +those kernel modules in ''%%/etc/devd/usb.conf%%'' also needs to be removed to prevent them from loading automatically 
 +by ''%%devd(8)%%''. However, ''%%uhidd%%''
 could be also used together with kernel drivers, for example ''%%uhidd%%'' and a kernel driver can each attach could be also used together with kernel drivers, for example ''%%uhidd%%'' and a kernel driver can each attach
 to one interface of the same device. See the Examples section below for details. to one interface of the same device. See the Examples section below for details.
Line 64: Line 74:
  
 <code> <code>
-# /usr/local/etc/rc.d/uhidd start /dev/ugen2.+# /usr/local/etc/rc.d/uhidd start /dev/ugen2.2
 </code> </code>
  
Line 90: Line 100:
  
 <code> <code>
-attach 0 { +notify 0 { 
-        match "device-name" "ugen[0-9]+.[0-9]+"; +        match "subsystem" "DEVICE"; 
-        action "/usr/local/etc/rc.d/uhidd start /dev/$device-name";+        match "type" "ATTACH"; 
 +        match "cdev" "ugen[0-9]+.[0-9]+"; 
 +        action "env LD_PRELOAD=/usr/local/lib/libcuse4bsd.so /usr/local/etc/rc.d/uhidd start /dev/$cdev";
 }; };
 </code> </code>
Line 98: Line 110:
 Note that ''%%uhidd%%'' will ignore ''%%ugenX.Y%%'' device that does not have USB HID interfaces, so it is safe Note that ''%%uhidd%%'' will ignore ''%%ugenX.Y%%'' device that does not have USB HID interfaces, so it is safe
 to "try" attaching ''%%uhidd%%'' on any ''%%ugenX.Y%%'' device. to "try" attaching ''%%uhidd%%'' on any ''%%ugenX.Y%%'' device.
 +
 +====== Coexists/Conflicts with kernel drivers ======
 +
 +  * If ''%%uhidd%%'' daemon and the kernel driver attaches to different interfaces of a device, they can coexist without problems.
 +  * If ''%%uhidd%%'' daemon finds out that a kernel driver is active on a device and the command line option ''%%-u%%'' is not specified, it will abort.
 +  * If ''%%uhidd%%'' daemon finds out that a kernel driver is active on a device and the command line option ''%%-u%%'' is specified, it will first attempt to detach the kernel driver, then attach itself to the device. In this way ''%%uhidd%%'' can be used without recompiling the kernel. <del>HOWEVER, it appears that the kernel driver detaching function is NOT always reliable. Sometimes (tested on %%FreeBSD%% 9.0) it will cause the USB stack to deadlock!--)</del>
 +
 +The recommanded way to use ''%%uhidd%%'' is:
 +  * Use the GENERIC kernel or a kernel compiled in USB drivers.
 +  * Use ''%%uhidd%%'' option ''%%-u%%'' to detach kernel driver when needed.
 +
 +Note that if you have USB kernel drivers(''%%ukbd(4)%%'',''%%ums(4)%%'' and ''%%uhid(4)%%'') compiled as modules, it's possible that ''%%uhidd%%'' and USB kernel drivers attach to the device at the same time and cause strange behaviors like mouse cursor jumping, keyboard key repeating etc. It's better to remove the relevant ''%%devd(8)%%'' rules from ''%%/etc/devd/usb.conf%%'' in this case. To recover from such issues, you can restart ''%%uhidd%%'' by ''%%/usr/local/etc/rc.d uhidd restart%%''.
  
 ====== How does it work ====== ====== How does it work ======
Line 111: Line 135:
   * Mouse: The mouse class driver will open the ''%%/dev/consolectl%%'' special character device and pass the data (mouse events) to it. It works just like the ''%%moused(8)%%'' daemon.   * Mouse: The mouse class driver will open the ''%%/dev/consolectl%%'' special character device and pass the data (mouse events) to it. It works just like the ''%%moused(8)%%'' daemon.
   * Consumer Control: The Consumer Control class driver is basically a special keyboard driver that handles multimedia keys found on USB keyboard. This driver translate multimedia key usages to key codes and then an application can handle the key event the same way as any other normal key. See the Multimedia Keys section below for details.   * Consumer Control: The Consumer Control class driver is basically a special keyboard driver that handles multimedia keys found on USB keyboard. This driver translate multimedia key usages to key codes and then an application can handle the key event the same way as any other normal key. See the Multimedia Keys section below for details.
-  * Generic HID: Application collections that don't have a specific class driver can be attached by the Generic HID driver. The driver will create a virtual generic hid device using the ''%%uvhid(4)%%'' interface. The virtual ''%%uvhid(4)%%'' interface behaves quite similar to the ''%%uhid(4)%%'' interface, except that the data is not generated from a real hid hardware but instead from a userland application. USB hid application like ''%%usbhidctl(1)%%'' and ''%%usbhidaction(1)%%'' can access the virtual generic device through ''%%/dev/uvhid<N>%%'' nodes.+  * Generic HID: Application collections that don't have a specific class driver can be attached by the Generic HID driver. The driver will create a virtual generic hid device using the ''%%cuse4bsd(3)%%'' library. The virtual HID interface behaves quite similar to the ''%%uhid(4)%%'' interface, except that the data is not generated from a real hid hardware but instead from a userland application. USB hid application like ''%%usbhidctl(1)%%'' and ''%%usbhidaction(1)%%'' can access the virtual generic device through ''%%/dev/uvhid<N>%%'' nodes. (Note that the nodes can be renamed using a configuration option.)
  
 ====== Multimedia Keys ====== ====== Multimedia Keys ======
Line 129: Line 153:
 The convertor can support two PS2 hand controls. Below is the appearance of the device. The convertor can support two PS2 hand controls. Below is the appearance of the device.
  
-{{http://people.freebsd.org/~kaiw/uhj/huijia.jpg}}+{{uhidd/playstation.2.hand.controller.to.usb.converter.jpg|PlayStation 2 Hand Controller to USB converter}}
  
 When connected to the PC under %%FreeBSD%% with in-kernel ''%%uhid(4)%%'' driver active, it will When connected to the PC under %%FreeBSD%% with in-kernel ''%%uhid(4)%%'' driver active, it will
Line 155: Line 179:
  
 ''%%uhidd%%'' daemon on the other hand can handle this device properly. It will attach those two joystick application collections as two generic hid child devices ''%%uhidd%%'' daemon on the other hand can handle this device properly. It will attach those two joystick application collections as two generic hid child devices
-and creates two ''%%uvhid(4)%%'' device nodes. The use ''%%uhidd%%'' daemon with this device, first you need deactivate the in-kernel ''%%uhid(4)%%''+and creates two virtual HID device nodes. The use ''%%uhidd%%'' daemon with this device, first you need deactivate the in-kernel ''%%uhid(4)%%''
 driver, then execute: driver, then execute:
  
Line 166: Line 190:
 each get a part of the hid data. (and there won't be any warning/error messages.) each get a part of the hid data. (and there won't be any warning/error messages.)
  
-At this point, you should find two newly created ''%%uvhid<X>%%'' nodes under ''%%/dev%%''. You will probably need to create two symbolic links, in case the application/library has hard-coded ''%%/dev/uhidX%%'' in its source code:+At this point, you should find two newly created ''%%uvhid<X>%%'' (or any other name specified in the configuration option) nodes under ''%%/dev%%''. If you use the defualt ''%%uvhid<X>%%'' names, you will probably need to create two symbolic links, in case the application/library has hard-coded ''%%/dev/uhidX%%'' in its source code:
  
 <code> <code>
Line 182: Line 206:
 multimedia keys won't work.) multimedia keys won't work.)
  
-Below is the report descriptor of the combos (only top-level collections showed). Note that there are little difference between +Below is the report descriptor of the combos:
-combo models, wrt to the descriptor.+
  
 <code> <code>
-Bus /dev/usb Device /dev/ugen1.5: +[interface:0]
-[config:0, interface:0] +
-[#0 report descriptor size: 63] +
-USAGE PAGE Generic Desktop(0x1)+
 USAGE Keyboard(0x6)[Generic Desktop(0x1)] USAGE Keyboard(0x6)[Generic Desktop(0x1)]
 COLLECTION Application(1) COLLECTION Application(1)
-    ...... 
     ...... (omitted)     ...... (omitted)
-    ...... 
 END COLLECTION END COLLECTION
  
-[config:0, interface:1] +[interface:1]
-[#0 report descriptor size: 556] +
-USAGE PAGE Consumer(0xc)+
 USAGE Consumer Control(0x1)[Consumer(0xc)] USAGE Consumer Control(0x1)[Consumer(0xc)]
 COLLECTION Application(1) COLLECTION Application(1)
-    ...... 
-    ...... 
     ......     ......
 END COLLECTION END COLLECTION
- 
-USAGE PAGE Generic Desktop(0x1) 
 USAGE Mouse(0x2)[Generic Desktop(0x1)] USAGE Mouse(0x2)[Generic Desktop(0x1)]
 COLLECTION Application(1) COLLECTION Application(1)
-    ...... 
-    ...... 
     ......     ......
 END COLLECTION END COLLECTION
- 
-USAGE PAGE Consumer(0xc) 
 USAGE Consumer Control(0x1)[Consumer(0xc)] USAGE Consumer Control(0x1)[Consumer(0xc)]
 COLLECTION Application(1) COLLECTION Application(1)
-    ...... 
-    ...... 
     ......     ......
 END COLLECTION END COLLECTION
- 
-USAGE PAGE Generic Desktop(0x1) 
 USAGE System Control(0x80)[Generic Desktop(0x1)] USAGE System Control(0x80)[Generic Desktop(0x1)]
 COLLECTION Application(1) COLLECTION Application(1)
-    ...... 
-    ...... 
     ......     ......
 END COLLECTION END COLLECTION
 </code> </code>
  
-To use ''%%uhidd%%'' daemon with the combo, first you need to deactiveate in-kernel ''%%uhid(4)%%'', ''%%ukbd(4)%%'' and ''%%ums(4)%%'' driver+To use ''%%uhidd%%'' daemon with the combo, first you need to deactivate in-kernel ''%%uhid(4)%%'', ''%%ukbd(4)%%'' and ''%%ums(4)%%'' driver
 and then execute: and then execute:
  
 <code> <code>
-# uhidd -kmh /dev/ugenX.Y+# uhidd -kmo /dev/ugenX.Y
 </code> </code>
  
-''%%-k%%'' tells the daemon to attach the keyboard and ''%%-m%%'' to attach the mouse.+''%%-k%%'' tells the daemon to attach the keyboard, ''%%-m%%'' to attach the mouse and ''%%-o%%'' to attach the consumer control driver to handle multimedia keys.
  
 Since the keyboard collection is on a separate interface and is the only child device of that interface, it is possible Since the keyboard collection is on a separate interface and is the only child device of that interface, it is possible
-to let the kernel ''%%ukbd(4)%%'' driver handle the keyboard interface, while ''%%uhidd%%'' handles the rest.+to let the kernel ''%%ukbd(4)%%'' driver handle the keyboard interface, while ''%%uhidd%%'' handles the mouse and multimedia keys.
  
 <code> <code>
 # kldload ukbd.ko # kldload ukbd.ko
-# uhidd -mh /dev/ugenX.Y+# uhidd -mo /dev/ugenX.Y
 </code> </code>
  
 Letting kernel ''%%ukbd(4)%%'' driver handle the keyboard interface makes it possible to use ''%%ddb(4)%%'' with this keyboard/mouse combo. Letting kernel ''%%ukbd(4)%%'' driver handle the keyboard interface makes it possible to use ''%%ddb(4)%%'' with this keyboard/mouse combo.
  
-The ''%%uhidd%%'' daemon is confirmed working with ''%%MICROSOFT WIRELESS LASER DESKTOP 5000 USB%%'' and +At this point, the mouse should work just fine, while additional work is needed to make the multimedia keys work. First you can 
-''%%MICROSOFT WIRELESS OPTICAL DESKTOP 1000 USB%%'', and it should work with other models as well.+just press the multimedia keys on the keyboard, at least once for each key. Then check if you can find a keymap file 
 +''%%/var/run/uhidd.ugen.X.Y/cc_keymap%%'' created by the ''%%uhidd%%'' daemon. What you need to do is to copy paste the content of this file to your uhidd configuration file (usually ''%%/usr/local/etc/uhidd.conf%%'', create a new one if you need) and restart ''%%uhidd%%'' daemon. The daemon 
 +will then load the provided keymap and translate keys according to the bindings defined in it. Note that if you do not copy the keymap to configuration file for this keyboard, ''%%uhidd%%'' will try to generate a new keymap (probably different bindings) again the next time it restarts.
  
-===== Logitech diNovo Edge ===== +Example multimedia keymap for Microsoft Wiress Desktop 1000:
-I don't have this Logitech keyboard/mouse combo myself but ''%%uhidd%%'' daemon should work fine with it.+
  
 <code> <code>
-[report desc size=59] +# 0x045e is the vendor id and 0x009d is the product id. 
-USAGE PAGE Generic Desktop(0x1) +# See `uhidd.conf(5)` manual page for details about configuration file. 
-USAGE Keyboard(0x6)[Generic Desktop(0x1)] +0x045e:0x009d={ 
-COLLECTION Application(1) +        cc_keymap={ 
-  USAGE PAGE Keyboard(0x7) +                Help="0x7F" 
-  USAGE MINIMUM Keyboard LeftControl(224) +                Scan_Next_Track="0x62" 
-  USAGE MAXIMUM Keyboard Right GUI(231) +                Scan_Previous_Track="0x60" 
-  LOGICAL MINIMUM 0 +                Stop="0x70" 
-  LOGICAL MAXIMUM 1 +                Play/Pause="0x54" 
-  REPORT SIZE 1 +                Mute="0x63" 
-  REPORT COUNT 8 +                Volume_Increment="0x5A" 
-  INPUT ( Data Variable Absolute ) (2) +                Volume_Decrement="0x5F" 
-  INPUT ( Const Variable Absolute ) (3) +                AL_Consumer_Control_Configuration="0x74" 
-  REPORT COUNT 5 +                AL_Email_Reader="0x75" 
-  USAGE PAGE LEDs(0x8) +                AL_Calculator="0x76" 
-  USAGE MINIMUM Num Lock(1) +                AL_Network_Chat="0x7C" 
-  USAGE MAXIMUM Kana(5) +                AL_Logoff="0x73" 
-  OUTPUT ( Data Variable Absolute ) (2) +                AL_Documents="0x6F" 
-  REPORT COUNT 1 +                AL_Spell_Check="0x6C" 
-  REPORT SIZE 3 +                AL_Image_Browser="0x71" 
-  OUTPUT ( Const Array Absolute ) (1) +                AL_Audio_Browser="0x72" 
-  REPORT COUNT 6 +                AC_New="0x66" 
-  REPORT SIZE 8 +                AC_Open="0x67" 
-  LOGICAL MINIMUM 0 +                AC_Close="0x68" 
-  LOGICAL MAXIMUM 164 +                AC_Save="0x6D" 
-  USAGE PAGE Keyboard(0x7) +                AC_Print="0x6E" 
-  USAGE MINIMUM Reserved (no event indicated)(0) +                AC_Undo="0x64" 
-  USAGE MAXIMUM Keyboard ExSel(164) +                AC_Home="0x7A" 
-  INPUT ( Data Array Absolute ) +                AC_Redo/Repeat="0x65" 
-END COLLECTION+                AC_Reply="0x69" 
 +                AC_Forward_Msg="0x6A" 
 +                AC_Send="0x6B" 
 +        } 
 +} 
 +</code>
  
-[report desc size=301] +Now you can confirm this multimedia key translation works by observing key events under ''%%xev(1)%%'', assuming you are using X. It is working if ''%%xev(1)%%'' generate something when you press the multimedia keys. To make the keycodes work under KDE/Gnome you need to create a Xmodmap that additionally translates the keycodes reported by ''%%xev(1)%%'' to X key events. Below is a example Xmodmap for Wireless Desktop 1000:
-USAGE PAGE Generic Desktop(0x1) +
-USAGE Mouse(0x2)[Generic Desktop(0x1)] +
-COLLECTION Application(1) (0) +
-    ...... +
-    ...... +
-    ...... +
-END COLLECTION+
  
-USAGE PAGE Generic Desktop(0x1) +<code> 
-USAGE Mouse(0x2)[Generic Desktop(0x1)] +keycode 170 = XF86AudioRaiseVolume 
-COLLECTION Application(1) +keycode 184 = XF86AudioLowerVolume 
-    ...... +keycode 190 = XF86AudioMute 
-    ...... +...... 
-    ...... +</code>
-END COLLECTION+
  
-USAGE PAGE Consumer(0xc) +It can be loaded by execute:
-USAGE Consumer Control(0x1)[Consumer(0xc)] +
-COLLECTION Application(1) +
-    ...... +
-    ...... +
-    ...... +
-END COLLECTION+
  
-USAGE PAGE Microsoft(0xff00) +<code> 
-USAGE Unknown Usage(0x2)[Microsoft(0xff00)] +xmodmap .Xmodmap
-COLLECTION Application(1) +
-    ...... +
-    ...... +
-    ...... +
-END COLLECTION +
- +
-USAGE PAGE Microsoft(0xff00) +
-USAGE Unknown Usage(0x3)[Microsoft(0xff00)] +
-COLLECTION Application(1) +
-    ...... +
-    ...... +
-    ...... +
-END COLLECTION+
 </code> </code>
  
-Quite similar with the M$ combo, this Logitech combo also has two interfaces, one for the keyboard, another one for the mouse and several vendor-specific +You can put this line into your X initialization file.
-application collections. The tricky part of this combo is that the second interface has defined two mice while the combo's got only one mouse. (It is unclear +
-why two mice is defined but my guess is that two slightly different diNovo models probably share the same report descriptor) +
-The kernel ''%%ums(4)%%'' driver is unable to handle situation like this since it can not tell which mouse collection is actually in use. A workaround would +
-be hard-coding the positions of X, Y axes and buttons in the driver, but it is not a general solution. See [[http://lists.freebsd.org/pipermail/freebsd-usb/2008-May/004950.html|this post]] for more details.+
  
-You can use following commands to test if ''%%uhidd%%'' is working with this combo:+For most multimedia keyboards, the basic keyboard part and the multimedia keys are on separate interfaces. So it's 
 +perfectly OK to let ''%%ukbd(4)%%'' handle the basic keyboard, and let ''%%uhidd%%'' deal with the multimedia keys.
  
-<code> +The ''%%uhidd%%'' daemon is confirmed working with ''%%MICROSOFT WIRELESS LASER DESKTOP 5000 USB%%'' and 
-# uhidd -v -kmh /dev/ugenX.Y +''%%MICROSOFT WIRELESS OPTICAL DESKTOP 1000 USB%%'', and it should work with other models in the series as well.
-</code> +
- +
-''%%-v%%'' tells the daemon to run in foreground and emits verbose debugging output. You should see the message ''%%"*MOUSE FOUND*"%%'' twice if it is attached correctly.+
  
-====== Report Bugs ======+====== Debugging and Report Bugs ======
  
-Normally ''%%uhidd%%'' runs in daemon mode in background. Command line ''%%-d%%'' makes it run in foreground. ''%%-v%%'' makes it output debugging information and multiple ''%%-v%%'' +Normally ''%%uhidd%%'' runs in daemon mode in background. Command line option ''%%-d%%'' makes it run in foreground. ''%%-v%%'' makes it output debugging information and multiple ''%%-v%%'' specified in the command line will increase the level of verbosity. ''%%-D%%'' makes the daemon dump the report descriptor.
-specified in the command line will increase the level of verbosity.+
  
 If you are having problems using ''%%uhidd%%'' with your USB hid device, send the output of the following command to kaiw@%%FreeBSD%%.org If you are having problems using ''%%uhidd%%'' with your USB hid device, send the output of the following command to kaiw@%%FreeBSD%%.org
  
 <code> <code>
-# uhidd -vvv -kmh /dev/ugenX.Y        # remember to unload the ukbd, ums and uhid kernel moduels first if need.+# uhidd -dD -vvv -kmohu /dev/ugenX.Y
 </code> </code>
  
  • uhidd.1267922920.txt.gz
  • Last modified: 2010/03/07 00:48
  • by KaiWang