Bug 21457

Summary: evdev-2 doesn't support Griffin Powermate USB knob
Product: xorg Reporter: Phil Endecott <spam_from_freedesktop_bugzilla>
Component: Server/Input/CoreAssignee: Peter Hutterer <peter.hutterer>
Status: RESOLVED FIXED QA Contact: Xorg Project Team <xorg-team>
Severity: normal    
Priority: medium Keywords: regression
Version: 7.3 (2007.09)   
Hardware: x86 (IA32)   
OS: Linux (All)   
Whiteboard:
i915 platform: i915 features:
Attachments:
Description Flags
Two patches to enable the griffin powermate
none
0001-Count-REL_DIAL-as-a-scrollwheel-during-EvdevProbe-21.patch none

Description Phil Endecott 2009-04-28 02:31:07 UTC
The Griffin Powermate (http://www.griffintechnology.com/products/powermate/) is a USB knob that can be used as e.g. a volume control, to move back and forth in video and audio editors, or simply to scroll windows like a mouse's scroll wheel.

It worked fine with the old evdev driver (in my case configured with Option "DIALRelativeAxisButtons" "4 5"), but the current evdev complains "Don't know how to use device".

The output of evtest is as follows:

Input driver version is 1.0.0
Input device ID: bus 0x3 vendor 0x77d product 0x410 version 0x400
Input device name: "Griffin PowerMate"
Supported events:
  Event type 0 (Sync)
  Event type 1 (Key)
    Event code 256 (Btn0)
  Event type 2 (Relative)
    Event code 7 (Dial)
  Event type 4 (Misc)
    Event code 1 (Pulseled)
Grab succeeded, ungrabbing.
Testing ... (interrupt to exit)
Event: time 1240909108.341856, type 2 (Relative), code 7 (Dial), value -1
Event: time 1240909108.341878, -------------- Report Sync ------------
Event: time 1240909108.773822, type 2 (Relative), code 7 (Dial), value -1
Event: time 1240909108.773838, -------------- Report Sync ------------
Event: time 1240909109.029820, type 2 (Relative), code 7 (Dial), value -1
Event: time 1240909109.029836, -------------- Report Sync ------------
Event: time 1240909109.149823, type 2 (Relative), code 7 (Dial), value -1
Event: time 1240909109.149839, -------------- Report Sync ------------
Event: time 1240909109.357821, type 2 (Relative), code 7 (Dial), value 1
Event: time 1240909109.357837, -------------- Report Sync ------------
Event: time 1240909109.445820, type 2 (Relative), code 7 (Dial), value -1
Event: time 1240909109.445837, -------------- Report Sync ------------
Event: time 1240909109.509826, type 2 (Relative), code 7 (Dial), value -1
Event: time 1240909109.509843, -------------- Report Sync ------------
Event: time 1240909109.565820, type 2 (Relative), code 7 (Dial), value -1
Event: time 1240909109.565836, -------------- Report Sync ------------
Event: time 1240909109.629825, type 2 (Relative), code 7 (Dial), value -1
Event: time 1240909109.629841, -------------- Report Sync ------------
Event: time 1240909110.213829, type 2 (Relative), code 7 (Dial), value 1
Event: time 1240909110.213844, -------------- Report Sync ------------
Event: time 1240909110.253823, type 2 (Relative), code 7 (Dial), value 1
Event: time 1240909110.253839, -------------- Report Sync ------------
Event: time 1240909110.309823, type 2 (Relative), code 7 (Dial), value 1
Event: time 1240909110.309839, -------------- Report Sync ------------
Event: time 1240909110.381825, type 2 (Relative), code 7 (Dial), value 1
Event: time 1240909110.381842, -------------- Report Sync ------------
Event: time 1240909110.485828, type 2 (Relative), code 7 (Dial), value 1
Event: time 1240909110.485845, -------------- Report Sync ------------
Event: time 1240909110.573827, type 2 (Relative), code 7 (Dial), value 1
Event: time 1240909110.573842, -------------- Report Sync ------------
Event: time 1240909110.653830, type 2 (Relative), code 7 (Dial), value 1
Event: time 1240909110.653847, -------------- Report Sync ------------
Event: time 1240909112.125830, type 1 (Key), code 256 (Btn0), value 1
Event: time 1240909112.125847, -------------- Report Sync ------------
Event: time 1240909112.381823, type 1 (Key), code 256 (Btn0), value 0
Event: time 1240909112.381838, -------------- Report Sync ------------
Event: time 1240909112.789830, type 2 (Relative), code 7 (Dial), value 1
Event: time 1240909112.789845, -------------- Report Sync ------------
Event: time 1240909112.893831, type 1 (Key), code 256 (Btn0), value 1
Event: time 1240909112.893848, -------------- Report Sync ------------
Event: time 1240909113.141823, type 1 (Key), code 256 (Btn0), value 0
Event: time 1240909113.141838, -------------- Report Sync ------------

It would be great to get back support for this device.  Having some way to map from dial movement to buttons (like the old DIALRelativeAxisButtons) is pretty important too since most applications won't know what to do with dial axis events.

Please contact me if you need any help testing.  See also this mailing list thread:  http://thread.gmane.org/gmane.comp.freedesktop.xorg/38676

Thanks,  Phil.
Comment 1 Peter Hutterer 2009-04-29 01:36:54 UTC
Created attachment 25252 [details] [review]
Two patches to enable the griffin powermate

Two patches in one file (needs review + better testing) that should enable the powermate. Note that the axis by default is X (it's axis 0 after all) so you must set up the EmulateWheel feature if you want it to scroll.
Comment 2 Phil Endecott 2009-04-29 11:44:40 UTC
Thanks Peter; I'll try to test this as soon as I can.  That may not be until next week though, since I have since found some more serious problems to fix...
Comment 3 Phil Endecott 2009-05-10 08:07:28 UTC
This isn't yet working for me though there's a good chance that I have done something wrong.

My main X packages are the current Debian unstable ones (i.e. xserver-xorg-core 2:1.6.1-1).  I installed various -dev packages and got the evdev source from git; it seemed to configure and build OK.  Keyboard and mouse seem to function correctly so the driver must be basically correct.  I've hacked the HAL fdi files so that the Powermate has input.x11_driver=evdev.  Here's what the log reports for the Powermate:

(II) config/hal: Adding input device Griffin PowerMate
(**) Griffin PowerMate: always reports core events
(**) Griffin PowerMate: Device: "/dev/input/event1"
(II) Griffin PowerMate: Found 1 mouse buttons
(II) Griffin PowerMate: found relative axes
(II) Griffin PowerMate: Configuring as mouse
(**) Griffin PowerMate: YAxisMapping: buttons 4 and 5
(**) Griffin PowerMate: EmulateWheelButton: 4, EmulateWheelInertia: 10, EmulateWheelTimeout: 200

That looks OK as long as it treats the DIAL events as Y.

However, xev reports only:

LeaveNotify event, serial 27, synthetic NO, window 0xc00001,
    root 0x6c, subw 0x0, time 23918005, (250,103), root:(1599,126),
    mode NotifyNormal, detail NotifyAncestor, same_screen YES,
    focus YES, state 0

I get the same thing for rotation in both directions and pressing the button.  The pointer doesn't move immediately but as soon as I move the mouse it appears at the right edge of the screen.  So it looks as if the Powermate event has somehow been interpreted as (+lots,0) movement and all that xev sees is LeaveNotify.

Any clues?
Comment 4 Peter Hutterer 2009-05-10 17:58:04 UTC
(In reply to comment #3)
> 
> (II) config/hal: Adding input device Griffin PowerMate
> (**) Griffin PowerMate: always reports core events
> (**) Griffin PowerMate: Device: "/dev/input/event1"
> (II) Griffin PowerMate: Found 1 mouse buttons
> (II) Griffin PowerMate: found relative axes
> (II) Griffin PowerMate: Configuring as mouse
> (**) Griffin PowerMate: YAxisMapping: buttons 4 and 5
> (**) Griffin PowerMate: EmulateWheelButton: 4, EmulateWheelInertia: 10,
> EmulateWheelTimeout: 200

weird. works fine here with a software emulation device [1] and the dial comes through as buttons 6/7 and the btn0 as button 1. this is with the same event sequence as you posted.
Please give the testdevice a try too. If that doesn't work, there may be an issue with the server (i'm testing on master here).

[1] git://people.freedesktop.org/~whot/testdevices.git
 
Comment 5 Phil Endecott 2009-05-11 14:20:13 UTC
The test device works  --- and now the real device works too, intermittently.

I was about to write an apologetic comment saying "I must have been doing something stupid before", but then I decided to test the button action by pointing at one of the other text fields on this web page and pressing it - and the pointer jumped to the right edge of the screen, like before.

Prior to that it was working reliably for long enough for me to look at xev and "od -x /dev/input/eventN" and it does exactly the same things as the test device, except for the missing SYN events.

To be useful I need it to map to buttons 4&5 like the scrollwheel.  I can do this in the HAL FDI rules I guess, unless you think this should be the default behaviour.

I'll see if I can work out what causes the intermittent behaviour.  Do you have any thoughts about what would cause xev to see only the LeaveNotify, without any prior Motion events?
Comment 6 Phil Endecott 2009-05-11 14:27:49 UTC
And now, intermittently, the test device triggers the moving-the-mouse-to-the-edge behaviour.
Comment 7 Phil Endecott 2009-05-14 13:58:41 UTC
I have been gdb-ing through the evdev driver after pressing or turning the powermate knob and I can't see any obvious problems.

When I saw it enter the middle button emulation code a thought occurred to me: is it possible that there's some code somewhere that expects devices to have >=2 buttons, and does some sort of out-of-bounds access if there is only one?

I did try disabling button 2 emulation and it did work for a while after that, but I think it was only co-incidence.

I'm still unsure what I'm supposed to do in the configuration to get button 4 and 5 for rotation: whatever I do, I seem to get 6 and 7.
Comment 8 Peter Hutterer 2009-05-14 15:15:27 UTC
> --- Comment #7 from Phil Endecott <spam_from_freedesktop_bugzilla@chezphil.org>  2009-05-14 13:58:41 PST ---
> I have been gdb-ing through the evdev driver after pressing or turning the
> powermate knob and I can't see any obvious problems.
> 
> When I saw it enter the middle button emulation code a thought occurred to me:
> is it possible that there's some code somewhere that expects devices to have
> >=2 buttons, and does some sort of out-of-bounds access if there is only one?

first thought is no, the MB emulation has a timeout so it passes the button
on if the second hasn't been pressed anyway. I think the problem you're
seeing is actually in the server, DeepCopyDeviceClasses to be more precise.
Haven't had the time to look at it yet though.
 
> I'm still unsure what I'm supposed to do in the configuration to get button 4
> and 5 for rotation: whatever I do, I seem to get 6 and 7.

xinput --set-button-map "devicename" 1 2 3 0 0 4 5
should do it. this way you're mapping buttons 6/7 in the server to 4/5.
button mapping is a server feature, we don't have a driver option for it.
Comment 9 Peter Hutterer 2009-05-20 22:31:16 UTC
Does this device ever spit out different values than -1 and 1?
Comment 10 Peter Hutterer 2009-05-20 22:51:19 UTC
Created attachment 26048 [details] [review]
0001-Count-REL_DIAL-as-a-scrollwheel-during-EvdevProbe-21.patch

different patch, applies to current git master. The previous patch (the second one) was wrong as it would count REL_DIAL as an axis but still post the events as scroll wheel buttons.
This patch now counts REL_DIAL as scrollwheel and lets the driver post the events accordingly.

Appears to work fine here, but I'm using a software emulation for the device and I'm running development xserver and evdev branches.
Comment 11 Phil Endecott 2009-05-21 02:51:00 UTC
> Does this device ever spit out different values than -1 and 1?

Yes, if I turn the knob quickly I get values up to maybe +/- 5.
Comment 12 Peter Hutterer 2009-05-27 15:53:34 UTC
Phil, have you had a chance to test the above patch yet?
Comment 13 Phil Endecott 2009-05-27 16:03:28 UTC
Soory, I've been distracted.  I'll look at it tomorrow.
Comment 14 Phil Endecott 2009-05-28 16:17:15 UTC
No change with that patch; the pointer is warped to the edge of the screen as soon as I do anything with the powermate.
Comment 15 Phil Endecott 2009-05-30 05:03:48 UTC
Furthermore, the new version makes my mouse's right button stop working.  That's unlikely to be a result of that patch I guess; more likely something else that has happened since I last compiled it.  OK OK, not this bug...
Comment 16 Peter Hutterer 2009-07-19 15:51:41 UTC
Pushed the patch as dcca28a59ce0a2f8a06c559eed493ca43afc20cb. 
I'm pretty sure the coordinate jump is in the server somewhere and with current git I don't see it.
Comment 17 Peter Hutterer 2009-08-06 22:46:30 UTC
Short update: the evdev driver itself now supports the powermate and posts the events accordingly.

Since the axis is used as scrollwheel it doesn't show up as an axis in the device. This means the powermate doesn't have any axes at all and the server isn't set up for this. So while the driver posts the events, they get dumped by a couple of checks in the server.

Comment 18 Peter Hutterer 2010-12-07 21:00:06 UTC
Moving to server.

http://lists.freedesktop.org/archives/xorg-devel/2010-December/016864.html

note, this is a series of 3 patches.
Comment 19 Jeremy Huddleston Sequoia 2011-10-11 11:01:11 UTC
commit 0d440a1c6e219cd39dbddd2b7e813c6431aac6ea
Author: Peter Hutterer <peter.hutterer@who-t.net>
Date:   Wed Dec 8 14:52:19 2010 +1000

    dix: allow for button-only input devices (#21457)
    
    Add a few checks for the existence of a valuator class on the device to
    avoid null-pointer dereferences for button events from devices without a
    valuator class.
    
    X.Org Bug 21457 <http://bugs.freedesktop.org/show_bug.cgi?id=21457>
    
    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
    Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
    Reviewed-by: Daniel Stone <daniel@fooishbar.org>

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.