Compare commits

...

73 Commits

Author SHA1 Message Date
Peter Samuelson
fa15e90993 Fix one additional typo in evdev.man (axis named BRAKE, not BREAK). 2007-10-11 07:27:30 +02:00
Peter Samuelson
12a27693b9 evdev.man minor fixes
* Use \- (ASCII dash) instead of - (hyphen), where appropriate
* Use a roff escape instead of a UTF-8 character.
* Consistent use of quote characters.
* Consistent use of typographic conventions:
  italic "n" in place of "<N>" or "integer" or "number",
  bold for option names, bit maps, etc.

Debian bug #446118
2007-10-11 00:09:40 +02:00
James Cloos
1c40c7db18 Add *~ to .gitignore to skip patch/emacs droppings 2007-09-03 05:52:08 -04:00
Daniel Stone
e2be2ffa47 Options: Accept differently-named options
Take some differently-named options for device and the XKB options.  These
should really be better-handled, but eh.
2007-08-07 15:44:33 +03:00
Brice Goglin
e86aab93c5 Multiple typos in evdev.man
Reported by "A. Costa" <agcosta@gis.net> in
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=432063
2007-07-26 18:31:58 +02:00
Tiago Vignatti
c69f4bd570 Clean up a little bit the code. 2007-06-15 01:35:29 -03:00
Tiago Vignatti
64677ecc76 Remove inotify things. 2007-06-15 01:33:49 -03:00
Zephaniah E. Hull
08a09682f5 Update version using PACKAGE_VERSION_*. 2007-06-13 11:05:07 -04:00
Zephaniah E. Hull
9c9a47210a Move the mode option handling to the Init stage.
(Sorta ugly placement wise, but the other segfaults.)
2007-06-12 11:59:16 -04:00
Zephaniah E. Hull
2d2c4804f9 evdev.c:
Set and use the X mode control, letting XInput see it properly.

    Kill some cruft.

evdev.h:

    Set and use the X mode control, letting XInput see it properly.

evdev_axes.c:

    Set and use the X mode control, letting XInput see it properly.

evdev_key.c:

    Remove some cruft, the bell func can be NULL now, so do so.

    Don't bother looking for keys above 0xF7 until we can actually do
    something with them.
2007-06-11 09:08:24 -04:00
Zephaniah E. Hull
6b97bf7a4e Handle default remapping around existing button targets better. 2007-06-06 05:00:29 -04:00
Zephaniah E. Hull
5c6b3dd86f Move MapButtons_t closer to where it's used. 2007-06-06 04:42:51 -04:00
Zephaniah E. Hull
f15636ac52 Wheel mice work again!
(Old configs don't.)

evdev.c:

    Add EvdevParseMapToButton and EvdevParseMapToButtons to evdev_map_parsers.

    Add EvdevParseMapOption to search through evdev_map_parsers.

    Fix up EvdevTokenize to handle the evdev_option_token_t changes.

    EvdevAxesNew0 after BtnNew0 instead of before now.
    (This isn't the right fix.)

evdev.h:

    EVDEV_MAXBUTTONS -> BTN_MAX.

    Redid evdevBtnRec with the new mapping goodness.

    Removed v_min and v_max from evdevAbsRec.

    Reworked evdev_option_token_t, no union, no is_chain.
    If it's a chain, it still has a string, but the chain pointer is set.

    EvdevParseMapToButton, EvdevParseMapToButtons, and EvdevParseMapOption.

evdev_axes.c:

    Kill off EvdevAxesMapButton, a variant lives in evdev_btn.c now.

    Changes for the evdev_option_token_t changes.

    Use EvdevParseMapOption instead of repeating the contents twice.

    Disable EV_ABS_V_INVERT for the moment. (Better fix maybe needed.)

evdev_btn.c:

    s/Ptr /Rec */g

    EvdevMapButton and parser.

    EvdevMapButtons and parser.

    Nuke EvdevBtnCalcRemap as a whole.

    Move everything but the alloc to New1 from New0.

    New mapping code, same guts os the axes mapping code even.
2007-06-06 04:41:54 -04:00
Zephaniah E. Hull
276685fa1d Fix REL mode.
Make buttons mostly work again. (Short term fix.)

NOTE: Wheel to button remapping is still missing!
2007-06-05 23:55:50 -04:00
Zephaniah E. Hull
27a86f8168 Update the copyright notices for me to include 2007.
Finish merging copyright notices. (evdev_key.c was missed.)
2007-06-05 23:19:59 -04:00
Zephaniah E. Hull
26dbf38041 Merge branch 'master' of git+ssh://git.freedesktop.org/git/xorg/driver/xf86-input-evdev
Conflicts:

	src/evdev.h
2007-06-05 23:14:46 -04:00
Zephaniah E. Hull
294355842b Alright, this is a really big commit that breaks stuff.
evdev.h:

    Switch to flags in the abs and rel structs.

    Add the axes struct, and defines.

    Rework the abs and rel structs, moving stuff to the axes struct and moving
    everything to the new mapping handling.

    Add the structs and function declarations for the new tokenization stuff,
    parsing stuff, and mapping stuff.

evdev.c: Add EvdevTokenize, and the evdev_map_parsers list.

evdev_axes.c:

    Basicly a full rewrite, big, messy.

    We now use a completely different mapping setup for axes, and mapping to
    buttons is currently missing.

    However we now handle ABS_CALIB and ABS_AREA, including rotation in both
    rel and abs modes.

evdev_btn.c:

    Disable lots of code and break things horribly, we compile but we don't
    work very well.

    Fixing this is next on my todo list.
2007-06-05 23:12:58 -04:00
Kristian Høgsberg
9eb546e0e0 Fix header file #ifdef guard. 2007-06-05 18:26:07 -04:00
Kristian Høgsberg
daf926081d Merge copyright notices. 2007-06-05 18:24:33 -04:00
Peter Hutterer
c22c955c48 Disable and remove the device when a read error occurs. 2007-04-24 23:20:43 +09:30
Zephaniah E. Hull
f87c44b90c Try harder to make unplugging work. 2007-04-24 07:44:26 -04:00
Zephaniah E. Hull
23309b334c Kill some more unused bits. 2007-04-24 07:34:53 -04:00
Zephaniah E. Hull
1716ec88bb Handle driver removal cleanly, we now xfree everything we Xcalloc.
NOTE: Someone needs to check for memory leaks, I'd be willing to bet
a fair bit that we've got tons in the mouse and xkb code, but.
2007-04-24 07:34:25 -04:00
Zephaniah E. Hull
246812bfbc Remove the evil xf86ActivateDevice declaration, don't need it anymore.
Fix the crash on device unplug.

NOTE: We still don't properly get rid of ourselves.
2007-04-24 07:01:54 -04:00
Zephaniah E. Hull
a0ea7363f5 Remove all of evdev_brain.c and all callers.
Remove the non-functional 2.4 kernel compiling compatibility.

Remove the XInput 1.4+ SendCoreEvents/DontSendCoreEvents define replacements.

Remove evdevDriver, some stuff from evdevDevice, all users.

NOTE: This WILL BREAK all existing configurations.

NOTE: Device read failure segfaults, don't unplug stuff.
2007-04-24 06:49:11 -04:00
Zephaniah E. Hull
3c4a96fbd8 Updated configure to 1.2.0, no changes yet.
This branch is the great xserver input-hotplug rewrite, consider it unstable
but usable with the 'current' (as of this commit) git xserver.

(Once it's more done that is.)

NOTE: This branch will _not_ remain source or binary compatable with
pre-input-hotplug xservers, you have been warned.
2007-04-24 06:12:14 -04:00
Peter Hutterer
ba65c34068 Remove driver from list if no device is associated any more.
This effectively stops the driver from hotplugging new devices. Devices have
to be added with the dbus hotplugging events.
2007-04-23 10:08:48 +09:30
Peter Hutterer
9644a4afbf Remove direct call to DEVICE_INIT, ActivateDevice() takes care of that. 2007-04-19 18:47:05 +09:30
Peter Hutterer
d37ba205bb Add some documentation to evdev.c and evdev_brain.c. 2007-04-19 18:46:57 +09:30
Peter Hutterer
9875e2f7f9 ActivateDevice() before EnableDevice() in EvdevNew. 2007-04-19 12:58:16 +09:30
Peter Hutterer
6db4a9fb84 Key: Remove duplicate of keycode 0x6f, remove index 0xf8 to get a
maxKeyCode of 255. This way keycode range is in sync with core keyboard range.
2007-03-25 15:40:47 +09:30
Daniel Stone
a9e87f29cc Key: Force maximum keycode to be 255
Even though we don't have keycodes for anything above 127, make sure our
map always covers up to 255.  This ensures that the keycode range never
changes.
2007-03-21 12:19:48 +02:00
Tiago Vignatti
b4a5a20476 Fix pointer crossing screen bug. Possibly the others input drivers must update
this on the same manner.
2007-02-14 19:23:21 -02:00
Philip Langdale
24f9e67a8f Stop caching the screen size for scaling.
Do be able to correctly scale absolute inputs, the actual
screen size must be used as this changes when the screen
resizes.
2007-02-10 22:17:01 -08:00
root
d8d8f114ca For reasons related to handling pathological remapping cases, and
differences between HID and X, pretend a middle button exists
whenever a right button exists.
2007-01-17 19:27:40 -05:00
root
ebb30a554f Fix a bug where we potentially wrote garbage events when LEDs change.
Support setting keyboard repeat rate/period.
2007-01-13 07:33:49 -05:00
root
3d8bb262e4 Handle swapping of right and middle buttons better in some odder cases. 2007-01-11 22:42:19 -05:00
root
987c6b1597 No more call to xf86OSRingBell in any cases,
maybe do some conditional stuff later.
2007-01-11 22:41:23 -05:00
root
8155e49e76 Pad out button_names so we can loop over things more sanely.
Support for ignoring the existance of buttons,
and for not telling X about them.

By default don't tell X about tools and touch as buttons.
TODO: Revisit this choice later.
2007-01-08 08:59:44 -05:00
Daniel Stone
e1fe72e7fe bump to 1.1.5 2006-12-16 01:42:18 +02:00
Daniel Stone
9f3be57929 Makefile.am: make ChangeLog hook safer
Make ChangeLog hook as safe as possible.
2006-12-06 18:50:15 +02:00
Daniel Stone
5a5457e69c bump to 1.1.4 2006-11-02 03:42:57 +02:00
Daniel Stone
3fc70342aa Merge branch 'input-hotplug' 2006-11-02 03:42:14 +02:00
Daniel Stone
1a8cea3dc4 Merge branch 'master' of git+ssh://git.freedesktop.org/git/xorg/driver/xf86-input-evdev 2006-11-02 03:42:13 +02:00
Daniel Stone
ef01c2ef65 key: use os bell-ringing function
Use the OS bell-ringing function to ding the bell.
2006-11-02 03:41:48 +02:00
Daniel Stone
036b457c1b support new DIX motion history API
Use the DIX motion history if we have ABI version 1 or higher.
2006-10-25 02:22:46 +03:00
Daniel Stone
79eb7dcac8 Merge branch 'input-hotplug' of git+ssh://git.freedesktop.org/git/xorg/driver/xf86-input-evdev into input-hotplug 2006-10-17 11:32:39 +03:00
Daniel Stone
d7f686bfa3 Merge branch 'master' of git+ssh://git.freedesktop.org/git/xorg/driver/xf86-input-evdev into input-hotplug 2006-10-17 11:31:58 +03:00
Daniel Stone
ec09e0d55d brain: call xf86DeleteInput when removing device
Call xf86DeleteInput from evdevRemoveDevice, so it also gets removed from
xf86InputDevs in the DDX.
2006-10-15 19:37:46 +03:00
Adam Jackson
4c72fb7b76 Bump to 1.1.3 2006-10-13 18:25:10 -04:00
Daniel Stone
77cbbc20b6 key: remove usage of OS keyboard layer for bell
Right now, bell is a no-op.
2006-10-08 16:14:12 +03:00
Drew Parsons
5c5ef3fbd6 m68k support (thanks Geert Uytterhoeven for the inotify codes). 2006-10-06 10:56:24 +10:00
Zephaniah E. Hull
a96b048e56 Make some debugging messages optional.
Correctly handle emulating relative mode from absolute data in the case where
we do not get X and Y data at the same time on touching.
2006-10-02 17:50:55 -04:00
Zephaniah E. Hull
d8ea40dc4a Use XORG_VERSION_CURRENT in the module version struct. 2006-10-02 17:49:20 -04:00
Zephaniah E. Hull
ab65184d47 Fix compilation. 2006-09-10 06:47:15 -04:00
Zephaniah E. Hull
63f7edf786 Merge branch 'master' of git+ssh://git.freedesktop.org/git/xorg/driver/xf86-input-evdev into input-hotplug 2006-07-25 16:00:44 -04:00
Zephaniah E. Hull
771eee9682 Replace the old two buffer approach to handling rel emulation of abs axes,
should help with some of the reported jitter problems.
2006-07-23 22:40:51 -04:00
Daniel Stone
e468150448 fix InitValuatorClassDeviceStruct call
I don't know how the last parameter got there.  Sorry.
2006-07-21 14:38:12 -04:00
Zephaniah E. Hull
fa03de438e Move the axis to button map code back into the rel code.
This might solve some problems, but should at least prevent some odd behavior.
2006-07-19 23:06:23 -04:00
Daniel Stone
7b91f9277a pass maxval correctly to xf86InitValuatorAxisDeviceStruct
Pass a maxval of -1 (i.e., fill this in appropriately), rather than 0 (0).
2006-07-19 19:45:27 -04:00
Daniel Stone
7defeb0aef pass number of axes to InitValuatorClassDeviceStruct
This is now required with the input-hotplug server.
2006-07-19 19:43:08 -04:00
Daniel Stone
1cb568c0a6 prune device list on DEVICE_CLOSE
Remove a device from the device list when we get DEVICE_CLOSE.
2006-07-19 19:41:54 -04:00
Zephaniah E. Hull
dc88668839 Split the New functions so that structs can be allocated and buttons
detected, and then stuff that depends on _other_ areas.
(Specificly, axes and btn have a circular dependency on which one has to
run first, this solves that.)

Add button names, and a way to get a button number from a name.

Add a function for checking to see if a button exists, takes the number from the previous function.

Change the (unused) state array of pointers in the button struct to an array of pointers to functions for callback.

Implemented the 'touch' feature, on by default if BTN_DIGI_TOUCH exists,
won't, in rel mode, process x/y data unless it's down, and is used to
try and make 'pick up stencil, move to other side of digitizer, set back
down' not jump to the other side of the screen in rel mode.
(This doesn't work as well as it could, but I'm fairly sure that it's
due to the quality of the absolute input device I'm using, but feedback
would be really nice.)

FIXME: Update the manpage for this.
2006-07-13 11:59:25 -04:00
Zephaniah E. Hull
090d43acf3 Update the .gitignore files to remove some more noise. 2006-07-11 16:47:15 -04:00
Zephaniah E. Hull
1b9a9599a4 Rename .cvsignore to .gitignore. 2006-07-11 16:44:43 -04:00
Zephaniah E. Hull
f7a9c74fbc Grab the ChangeLog generation rule from libX11. 2006-07-11 16:42:41 -04:00
Zephaniah E. Hull
9cb7c3dbad (Hope this works.)
Remove the ChangeLog file, as the entire contents can be gotten via 'git log'.
2006-07-11 12:48:10 -04:00
Zephaniah E. Hull
eba5ea8d5a Set pInfo->fd to -1 when we close it in EvdevProc. 2006-07-11 03:08:30 -04:00
Daniel Stone
51d21a3694 remove XFree86LOADER usage
Build evdevModuleData, et al, unconditionally.
2006-07-09 18:08:50 +01:00
Adam Jackson
4645247d45 MIPS support. (Joshua Kinard) 2006-06-22 21:16:44 +00:00
Adam Jackson
57a7f28441 Fix an obvious bogon to avoid crashing on absolute axis setup. 2006-06-02 19:39:52 +00:00
Zephaniah E. Hull
1b03250797 Hopefully fix the bitops stuff to actually _work_. 2006-05-15 22:47:23 +00:00
Zephaniah E. Hull
e9c60da89a Tweak credits and references.
Change the longs to unsigned longs in the bitfields.
Cleanup our includes.
Stop pulling in asm/types.h and asm/bitops.h.
Conditionally define the stuff that used to come from the above, including
    our own test_bit, set_bit and clear_bit.
Change the longs to unsigned longs in the bitfields.
Change the longs to unsigned longs in the bitfields.
Use the bitop defines in evdev.h properly.
Change the longs to unsigned longs in the bitfields.
Change the longs to unsigned longs in the bitfields.
Use the bitop defines in evdev.h properly.
Change the longs to unsigned longs in the bitfields.
Use the bitop defines in evdev.h properly.
Add HPPA/HPPA64 entries. (Thanks to Fabio M. Di Nitto
    <fabbione@ubuntu.com>)
2006-05-14 11:55:50 +00:00
16 changed files with 1628 additions and 1729 deletions

View File

@@ -1,9 +1,13 @@
Makefile
Makefile.in
ChangeLog
xf86-input-evdev-*.tar.bz2
xf86-input-evdev-*.tar.gz
*.la
*.lo
aclocal.m4
autom4te.cache
compile
config.guess
config.h
config.h.in
@@ -17,3 +21,5 @@ libtool
ltmain.sh
missing
stamp-h1
.*.swp
*~

319
ChangeLog
View File

@@ -1,319 +0,0 @@
2006-04-30 Zephaniah E. Hull <warp@aehallh.com>
* configure.ac:
xf86-input-evdev v1.1.2
* src/evdev_brain.c: (evdevControl):
Bugzilla #6734 <https://bugs.freedesktop.org/show_bug.cgi=6734>
Apply patch from Philip Langdale which causes us to make sure that
O_NONBLOCK is set on the inotify device.
2006-04-15 Zephaniah E. Hull <warp@aehallh.com>
* configure.ac:
* src/Makefile.am:
xf86-input-evdev v1.1.1
2006-04-14 Zephaniah E. Hull <warp@aehallh.com>
* src/evdev.h:
evdevAbsRec: Remove the scale bool, rename scale_x and scale_y
to scale[2].
evdevAxesRec: Make btnMap an int array instead of a Card8 array.
* src/evdev_axes.c: (EvdevAxesAbsSyn), (EvdevAxesAbsProcess),
(EvdevAxisAbsNew), (EvdevAxesInit):
Make abs support and non-core stuff actually work.
Relative emulation for abs mode is still a bit broken, but that's far
less critical.
* src/evdev_btn.c: (EvdevBtnInit):
How many buttons we've registered is configuration information, not an
error message.
2006-04-08 Zephaniah E. Hull <warp@aehallh.com>
* src/evdev.c: (EvdevCorePreInit):
Remove a debugging message.
* src/evdev_axes.c: (EvdevAxesNew), (EvdevAxesInit):
Actually, well, _work_.
Note, abs support still segfaults, I'll debug it after I've slept.
But I should get it tomorrow.
2006-04-08 Zephaniah E. Hull <warp@aehallh.com>
* configure.ac:
Dropped the xorg-xserver 1.0.99.901 requirement.
(Things were tweaked to mostly work for older servers again.)
* src/evdev.c: (EvdevReadInput):
Close the device properly on read errer.
* src/evdev_brain.c: (evdevReadInput), (evdevControl):
Minimal inotify support, not ideal yet, but...
* src/inotify-syscalls.h:
Minimal inotify support, not ideal yet, but...
* src/inotify.h:
Minimal inotify support, not ideal yet, but...
2006-04-08 Zephaniah E. Hull <warp@aehallh.com>
* src/Makefile.am:
Remove evdev_abs.c and evdev_rel.c.
Added evdev_axes.c.
* src/evdev.c: (EvdevReadInput), (EvdevProc), (EvdevNew),
(EvdevPtrCtrlProc):
Change the calls to refer to EvdevAxes instead of Abs and Rel.
Include mipointer.h. (Fixes a compile error.)
Remove an unused variable from EvdevReadInput.
* src/evdev.h:
Removed evdev_abs.c and evdev_rel.c, added evdev_axes.c.
Added count to rel and abs.
Moved btnMap from rel to the new axes.
Shuffle some includes, and include stdarg.h.
* src/evdev_abs.c:
Removed.
* src/evdev_axes.c: (EvdevConvert), (EvdevAxesRealSyn),
(EvdevAxesAbsSyn), (EvdevAxesRelSyn), (EvdevAxesSyn),
(EvdevAxesAbsProcess), (EvdevAxesRelProcess), (EvdevAxesOn),
(EvdevAxesOff), (EvdevAxisAbsNew), (EvdevAxisRelNew),
(EvdevAxesNew), (EvdevPtrCtrlProc), (EvdevAxesInit):
New, a mix of rel and abs that should actually work in the
rel case.
* src/evdev_btn.c: (EvdevBtnCalcRemap):
Rearrange include order.
btnMap was moved from being part of rel to being part of axes.
* src/evdev_rel.c:
Removed.
* src/evdev_brain.c:
Rearrange include order.
* src/evdev_key.c:
Rearrange include order.
NOTE: This commit has been compile tested, not run tested.
I have some other changes to make before I can do more heavy testing.
2006-04-06 Adam Jackson <ajax@freedesktop.org>
* configure.ac:
* src/evdev.c:
* src/evdev.h:
* src/evdev_abs.c:
* src/evdev_btn.c:
* src/evdev_key.c:
* src/evdev_rel.c:
Unlibcwrap. Bump server version requirement. Bump to 1.1.0.
2006-03-31 Zephaniah E. Hull <warp@aehallh.com>
* src/evdev_brain.c: (FillDevInfo), (evdevRescanDevices):
Fix the fd pointer leak reported by primer. (Not the same patch.)
* src/evdev_key.c: (EvdevKeyNew):
Disable the undocumented xkb guts options in the key driver.
(Requested by Daniel Stone.)
2006-03-16 Zephaniah E. Hull <warp@aehallh.com>
* src/evdev_brain.c: (MatchDriver):
Switch from my own globbing function to fnmatch.
* src/evdev_key.c: (EvdevKeyNew):
Detect keys numbered higher then buttons.
Remove the (depreciated since long before xkb support was added to
evdev) XkbKeymap option.
2006-03-16 Zephaniah E. Hull <warp@aehallh.com>
* man/evdev.man:
Update to include all the new device matching options.
2006-02-27 Zephaniah E. Hull <warp@aehallh.com>
* src/evdev_key.c: (EvdevKeyOff):
Don't leave keys in the down state when we get turned off.
(VT switching, getting unplugged, that sort of stuff.)
2006-02-27 Zephaniah E. Hull <warp@aehallh.com>
* src/evdev.c: (EvdevReadInput):
Better error reporting if the read fails.
* src/evdev_brain.c: (evdevNewDriver):
Work properly if we're defining entirely by capability maps.
2006-02-24 Zephaniah E. Hull <warp@aehallh.com>
* src/Makefile.am:
Compile with -Wall now.
Add evdev.h to the sources so that make distcheck gets it.
* src/evdev.h:
Bugzilla #5943 <https://bugs.freedesktop.org/show_bug.cgi=5943>
Make sure we include errno.h.
Reduce EVDEV_MAXBUTTONS to 96.
Split up evdevStateRec into a struct with pointers to new structs
for btn, abs, rel, and key.
New structure type for handling the device capability bitmaps.
Add device bits and struct input_id to evdevDeviceRec.
Add matching device bits, struct input_id, and pass number to
evdevDriverRec.
Prototype for evdevGetBits from evdev_brain.c.
* src/evdev.c: (EvdevProc), (EvdevSwitchMode), (EvdevNew),
(EvdevParseBits), (EvdevParseBitOption), (EvdevCorePreInit):
Conversion for the evdevStateRec split.
Remove the errno.h include, it's in evdev.h for now.
Move the bit getting from the drivers to here, into evdevDeviceRec.
Fix a rare case of fd leakage.
Add several new (and somewhat ugly) device matching options:
<map>Bits: Where map is one of ev, key, rel, abs, msc, led, snd, or
ff.
In the format of '+0 +3 -1-2 ~5-10', requires bits 0 and 3 be set,
bits 1 and 2 to not be set, and at least one bit in the range of 5 to
10 be set.
bustype, vendor, product, and version: Simple integer options for
matching the struct device_id fields, must be 0 (the default) or the
exact value you wish to match against.
pass: Bounded to 0-3, devices are matched to the first matching entry
found, order for multiple matching entries in the same pass is
undefined, but it starts with pass 0 and goes to pass 3.
* src/evdev_abs.c: (EvdevAbsSyn), (EvdevAbsProcess),
(EvdevAbsInit), (EvdevAbsNew):
Adaptation for the evdevStateRec split and the change in capability
bitmap handling.
* src/evdev_brain.c: (MatchAll), (MatchNot), (MatchAny),
(MatchDriver), (MatchDevice), (evdevScanDevice), (FillDevInfo),
(evdevRescanDevices), (evdevGetBits):
Add evdevGetBits to fill the new evdevBitsRec struct type.
Lots of somewhat ugly code for matching by capability bits.
Split out of evdevRescanDevices to smaller handling functions.
The new design should be better if I decide to handle arbitrary Device
fields again.
* src/evdev_btn.c: (EvdevBtnInit), (EvdevBtnOn),
(EvdevBtnCalcRemap), (EvdevBtnNew), (EvdevBtnProcess):
Adaptation for the evdevStateRec split and the change in capability
bitmap handling.
Handle all buttons, no button compression at this time, however we
reorder things so that BTN_MOUSE comes before BTN_MISC, somewhat
evily.
Support for the new btn->state[] array of int pointers.
* src/evdev_key.c: (EvdevKeyInit), (SetXkbOption), (EvdevKeyNew):
Adaptation for the evdevStateRec split and the change in capability
bitmap handling.
* src/evdev_rel.c: (EvdevRelSyn), (EvdevRelProcess),
(EvdevRelInit), (EvdevRelNew):
Adaptation for the evdevStateRec split and the change in capability
bitmap handling.
2006-02-20 Zephaniah E. Hull <warp@aehallh.com>
* src/evdev_btn.c: (EvdevBtnInit):
Bugzilla #5950 <https://bugs.freedesktop.org/show_bug.cgi=5950>
Possible (maybe) fix for bug #5950.
Though, I'm not convinced and still don't see how this bug could
be happening, especially if this doesn't do it.
2006-02-19 Zephaniah E. Hull <warp@aehallh.com>
* src/evdev_key.c: (EvdevKbdBell):
Add bell support.
2006-02-16 Zephaniah E. Hull <warp@aehallh.com>
* src/evdev_btn.c: (EvdevBtnCalcRemap):
Bugzilla #5914 <https://bugs.freedesktop.org/show_bug.cgi?id=5914>
Stupid little bug, properly handle wheels on 3 button mice.
2006-02-14 Zephaniah E. Hull <warp@aehallh.com>
* configure.ac:
* man/evdev.man:
* src/Makefile.am:
* src/evdev.c: (EvdevReadInput), (EvdevSigioReadInput),
(EvdevProc), (EvdevSwitchMode), (EvdevNew), (EvdevCorePreInit):
* src/evdev.h:
* src/evdev_abs.c: (EvdevPtrCtrlProc), (EvdevConvert),
(EvdevAbsSyn), (EvdevAbsProcess), (EvdevAbsInit), (EvdevAbsOn),
(EvdevAbsOff), (EvdevAbsNew):
* src/evdev_brain.c: (glob_match), (evdevGetFDForDevice),
(evdevRescanDevices), (evdevReadInput), (evdevControl),
(evdevStart), (evdevNewDriver):
* src/evdev_btn.c: (EvdevBtnPostFakeClicks), (EvdevBtnInit),
(EvdevBtnOn), (EvdevBtnOff), (EvdevBtnCalcRemap), (EvdevBtnNew),
(EvdevBtnProcess):
* src/evdev_key.c: (EvdevKbdBell), (EvdevKbdCtrl), (EvdevKeyInit),
(SetXkbOption), (EvdevKeyNew), (EvdevKeyOn), (EvdevKeyOff),
(EvdevKeyProcess):
* src/evdev_rel.c: (EvdevPtrCtrlProc), (EvdevConvert),
(EvdevRelSyn), (EvdevRelProcess), (EvdevRelInit), (EvdevRelOn),
(EvdevRelOff), (EvdevRelNew):
Bugzilla #5696 <https://bugs.freedesktop.org/show_bug.cgi?id=5696>
Slightly updated version of the patch listed.
Basicly a rewrite of the driver, with a few pieces of the old.
XKB support, proper device matching, basic absolute pointer support.
Lots more, will require some user config changes.
2006-01-09 David Nusinow,,, <set EMAIL_ADDRESS environment variable>
* man/Makefile.am:
* man/evdev.man:
Bugzilla #968 <https://bugs.freedesktop.org/show_bug.cgi?id=968>
Patch #4301 <https://bugs.freedesktop.org/attachment.cgi?id=4301>
Add evdev manpage
2005-12-20 Kevin E. Martin <kem-at-freedesktop-dot-org>
* configure.ac:
Update package version for X11R7 release.
2005-12-14 Kevin E. Martin <kem-at-freedesktop-dot-org>
* configure.ac:
Update package version number for final X11R7 release candidate.
2005-12-06 Kevin E. Martin <kem-at-freedesktop-dot-org>
* man/Makefile.am:
Change *man_SOURCES ==> *man_PRE to fix autotools warnings.
2005-12-03 Kevin E. Martin <kem-at-freedesktop-dot-org>
* configure.ac:
Update package version number for X11R7 RC3 release.
2005-12-01 Kevin E. Martin <kem-at-freedesktop-dot-org>
* configure.ac:
Remove extraneous AC_MSG_RESULT.
2005-11-29 Adam Jackson <ajax@freedesktop.org>
* configure.ac:
Only build dlloader modules by default.
2005-11-09 Kevin E. Martin <kem-at-freedesktop-dot-org>
* configure.ac:
Update package version number for X11R7 RC2 release.
2005-11-01 Kevin E. Martin <kem-at-freedesktop-dot-org>
* configure.ac:
Update pkgcheck dependencies to work with separate build roots.

View File

@@ -20,3 +20,14 @@
AUTOMAKE_OPTIONS = foreign
SUBDIRS = src man
EXTRA_DIST=ChangeLog
CLEANFILES=ChangeLog
.PHONY: ChangeLog
ChangeLog:
(GIT_DIR=$(top_srcdir)/.git git-log > .changelog.tmp && mv .changelog.tmp ChangeLog; rm -f .changelog.tmp) || (touch ChangeLog; echo 'git directory not found: installing possibly empty changelog.' >&2)
dist-hook: ChangeLog

View File

@@ -22,7 +22,7 @@
AC_PREREQ(2.57)
AC_INIT([xf86-input-evdev],
1.1.2,
1.2.0,
[https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
xf86-input-evdev)

View File

@@ -1,2 +1,3 @@
Makefile
Makefile.in
evdev.4

View File

@@ -14,7 +14,7 @@ evdev \- Generic Linux input driver
.fi
.SH DESCRIPTION
.B evdev
is an __xservername__ input driver for Linux\'s generic event devices. It
is an __xservername__ input driver for Linux's generic event devices. It
therefore supports all input devices that the kernel knows about, including
most mice and keyboards.
.PP
@@ -46,7 +46,7 @@ all QWERTY keyboards:
.BI " Identifier \*q" keyboard \*q
.B " Driver \*qevdev\*q"
.BI " Option \*qevBits\*q \*q" "+1" \*q
.BI " Option \*qkeyBits\*q \*q" "~1-255 ~352-511" \*q
.BI " Option \*qkeyBits\*q \*q" "~1\-255 ~352\-511" \*q
.BI " Option \*qPass\*q \*q" "3" \*q
\ \ ...
.B EndSection
@@ -58,9 +58,9 @@ And the following for all mice:
.B "Section \*qInputDevice\*q"
.BI " Identifier \*q" mouse \*q
.B " Driver \*qevdev\*q"
.BI " Option \*qevBits\*q \*q" "+1-2" \*q
.BI " Option \*qkeyBits\*q \*q" "~272-287" \*q
.BI " Option \*qrelBits\*q \*q" "~0-2 ~6 ~8" \*q
.BI " Option \*qevBits\*q \*q" "+1\-2" \*q
.BI " Option \*qkeyBits\*q \*q" "~272\-287" \*q
.BI " Option \*qrelBits\*q \*q" "~0\-2 ~6 ~8" \*q
.BI " Option \*qPass\*q \*q" "3" \*q
\ \ ...
.B EndSection
@@ -86,8 +86,11 @@ control what devices are accepted:
.TP 7
.BI "Option \*qDevice\*q \*q" string \*q
Specifies the device note through which the device can be accessed.
At this time ONLY /dev/input/event<N>, where <N> is an integer, are
matched against this this field.
At this time ONLY
.RI /dev/input/event n ,
where
.I n
is an integer, are matched against this this field.
.fi
This option uses globbing.
.fi
@@ -110,7 +113,7 @@ This option uses globbing.
.BI "Option \*qPhys\*q \*q" string \*q
Specifies the device phys string for the device you wish to use.
.fi
The phys string is generally consistant to the USB port a device is plugged
The phys string is generally consistent to the USB port a device is plugged
into.
.fi
A list of currently plugged in devices and associated device names can be
@@ -120,25 +123,29 @@ is the value you want for this option.
This option uses globbing.
.TP 7
.BI "Option \*q<map>Bits\*q \*q" "bit specifier" \*q
.BI "Option \*q" map "Bits\*q \*q" "bit specifier" \*q
Specifies device capability bits which must be set, possibly set, or unset.
.fi
<map>Bits: Where map is one of ev, key, rel, abs, msc, led, snd, or
ff.
.IR map "Bits: Where " map
is one of
.BR ev ", " key ", " rel ", " abs ,
.BR msc ", " led ", " snd ", or " ff .
.fi
The bit specifier format is a string consisting of +<n>, -<n>, and ~<n>
space sepirated specifiers, where <n> is a positive integer or integer range.
(The latter given in the format of 2-6.)
The bit specifier format is a string consisting of
.RI + n ", \-" n ", and ~" n
space-separated specifiers, where
.I n
is a positive integer or integer range. (The latter given in the format of 2\-6.)
.fi
+ specifies bits which must be set.
.fi
- specifies bits which must not be set.
\- specifies bits which must not be set.
.fi
~ is a little more complex, it specifies that at least one of the bits given
with ~ for the field in question must be set, but it doesn't matter how many
or which of the bits. (It is actually the most useful of the 3 specifiers.)
.fi
As an example '+0 +3 -1-2 ~5-10', requires bits 0 and 3 be set,
As an example, \*q+0 +3 \-1\-2 ~5\-10\*q requires bits 0 and 3 be set,
bits 1 and 2 to not be set, and at least one bit in the range of 5 to
10 be set.
.fi
@@ -148,20 +155,24 @@ by typing \*qcat /proc/bus/input/devices\*q, and
should contain the defines which declare what bits are what for each field.
.TP 7
.BI "Option \*qbustype\*q \*q" integer \*q
.BI "Option \*qbustype\*q \*q" n \*q
Specifies the bus ID for the device you wish to use.
.fi
This is either 0 (the default, matches anything), or the Bus=<n> field in
This is either 0 (the default, matches anything), or the
.BI Bus= n
field in
.B /proc/bus/input/devices
for your device.
.fi
This value depends on what type of bus your device is connected to.
.TP 7
.BI "Option \*qvendor\*q \*q" integer \*q
.BI "Option \*qvendor\*q \*q" n \*q
Specifies the vendor ID for the device you wish to use.
.fi
This is either 0 (the default, matches anything), or the Vendor=<n> field in
This is either 0 (the default, matches anything), or the
.BI Vendor= n
field in
.B /proc/bus/input/devices
for your device.
.fi
@@ -169,10 +180,12 @@ This value should remain constant barring perhaps firmware updates to the
device itself.
.TP 7
.BI "Option \*qversion\*q \*q" integer \*q
.BI "Option \*qversion\*q \*q" n \*q
Specifies the version for the device you wish to use.
.fi
This is either 0 (the default, matches anything), or the Version=<n> field in
This is either 0 (the default, matches anything), or the
.BI Version= n
field in
.B /proc/bus/input/devices
for your device.
.fi
@@ -180,10 +193,12 @@ This value should remain constant barring perhaps firmware updates to the
device itself.
.TP 7
.BI "Option \*qproduct\*q \*q" integer \*q
.BI "Option \*qproduct\*q \*q" n \*q
Specifies the product ID for the device you wish to use.
.fi
This is either 0 (the default, matches anything), or the Product=<n> field in
This is either 0 (the default, matches anything), or the
.BI Product= n
field in
.B /proc/bus/input/devices
for your device.
.fi
@@ -191,13 +206,13 @@ This value should remain constant barring perhaps firmware updates to the
device itself.
.TP 7
.BI "Option \*qPass\*q \*q" integer \*q
.BI "Option \*qPass\*q \*q" n \*q
Specifies the order in which evdev will scan for devices.
.fi
This is in the range of 0 to 3, and is used for the case
where more then one evdev inputsection matches the same device.
where more then one evdev input section matches the same device.
.fi
An inputsection with a lower pass number will always beat out
An input section with a lower pass number will always beat out
one with a higher pass number. Order when both sections are
the same number is undefined.
.fi
@@ -206,14 +221,14 @@ The default is 0.
.PP
.SS RELATIVE AXIS CONFIGURATION
The relative axis portion of this driver handle all reported relative axies.
The relative axis portion of this driver handle all reported relative axes.
.fi
The axies are named X, Y, Z, RX, RY, RZ, HWHEEL, DIAL, WHEEL, MISC, 10, 11,
The axes are named X, Y, Z, RX, RY, RZ, HWHEEL, DIAL, WHEEL, MISC, 10, 11,
12, 13, 14, and 15.
.fi
The axies are reported to X as valuators, with the default mapping of axies
to valuators being the first axies found to the first valuator, the second
found to the second valuator, and so on, so that if you have axies X, Y,
The axes are reported to X as valuators, with the default mapping of axes
to valuators being the first axes found to the first valuator, the second
found to the second valuator, and so on, so that if you have axes X, Y,
HWHEEL, and WHEEL, you would have X=0, Y=1, HWHEEL=2, WHEEL=3.
.fi
If the driver is reporting core events, valuators 0 and 1 are always mapped
@@ -223,28 +238,28 @@ The following driver
.B Options
control the relative axis portion of the driver:
.TP 7
.BI "Option \*q<axis>RelativeAxisMap\*q \*q" number \*q
.BI "Option \*q" axis "RelativeAxisMap\*q \*q" n \*q
This remaps the axis specified to the specified valuator.
.TP 7
.BI "Option \*q<axis>RelativeAxisButtons\*q \*q" number " number\*q
.BI "Option \*q" axis "RelativeAxisButtons\*q \*q" "n n" \*q
This remaps the axis specified to the specified buttons.
.fi
Note that the physical buttons are always remapped around 'fake' buttons
Note that the physical buttons are always remapped around \*qfake\*q buttons
created by this option, so that if you have physical buttons 1 2 3 4 5,
and map the Wheel axis to buttons 4 5, you get buttons 1 2 3
.B 4 5
6 7, with buttons 6 and 7 being physical buttons 4 and 5.
.PP
.SS ABSOLUTE AXIS CONFIGURATION
The relative axis portion of this driver handle all reported relative axies.
The relative axis portion of this driver handle all reported relative axes.
.fi
The axies are named X, Y, Z, RX, RY, RZ, THROTTLE, RUDDER, WHEEL, GAS, BREAK,
<11-15>, HAT0X, HAT0Y, HAT1X, HAT1Y, HAT2X, HAT2Y, HAT3X, HAT3Y, PRESSURE,
TILT_X, TILT_Y, TOOL_WIDTH, VOLUME, <29-39>, MISC, <41-62>.
The axes are named X, Y, Z, RX, RY, RZ, THROTTLE, RUDDER, WHEEL, GAS, BRAKE,
<11\-15>, HAT0X, HAT0Y, HAT1X, HAT1Y, HAT2X, HAT2Y, HAT3X, HAT3Y, PRESSURE,
TILT_X, TILT_Y, TOOL_WIDTH, VOLUME, <29\-39>, MISC, <41\-62>.
.fi
The axies are reported to X as valuators, with the default mapping of axies
to valuators being the first axies found to the first valuator, the second
found to the second valuator, and so on, so that if you have axies X, Y,
The axes are reported to X as valuators, with the default mapping of axes
to valuators being the first axes found to the first valuator, the second
found to the second valuator, and so on, so that if you have axes X, Y,
TILT_X, and TILT_Y, you would have X=0, Y=1, TILT_X=2, TILT_Y=3.
.fi
If the driver is reporting core events, valuators 0 and 1 are always mapped
@@ -254,21 +269,21 @@ The following driver
.B Options
control the relative axis portion of the driver:
.TP 7
.BI "Option \*q<axis>AbsoluteAxisMap\*q \*q" number \*q
.BI "Option \*q" axis "AbsoluteAxisMap\*q \*q" n \*q
This remaps the axis specified to the specified valuator.
.TP 7
.BI "Option \*qAbsoluteScreen\*q \*q" number \*q
.BI "Option \*qAbsoluteScreen\*q \*q" n \*q
This binds the device to a specific screen, scaling it to
the coordinate space of that screen.
.fi
The number can either be -1, or a valid screen number.
The number can either be \-1, or a valid screen number.
.fi
If -1 or if in relative mode no scaling or screen fixing is done.
If \-1 or if in relative mode no scaling or screen fixing is done.
.fi
This is of most use for digitizers, where the screen and the input
device are the same surface.
.TP 7
.BI "Option \*qMode\*q \*q" <mode>\*q
.BI "Option \*qMode\*q \*q" mode \*q
This selects the default mode for the device.
.fi
Valid values are \*qabsolute\*q and \*qrelative\*q.
@@ -277,9 +292,9 @@ This can be set at run time per actual device with the xinput utility.
.PP
.SS BUTTON CONFIGURATION
At the moment, the button portion of this driver only handles buttons
reported as mouse buttons, that is from BTN_MOUSE to BTN_JOYSTICK - 1.
reported as mouse buttons, that is from BTN_MOUSE to BTN_JOYSTICK \- 1.
.fi
At this time there are no configuration options for buttens.
At this time there are no configuration options for buttons.
.SS KEYBOARD CONFIGURATION
The keyboard portion of this driver handles all keys reported and requires
XKB support.
@@ -295,15 +310,15 @@ specifies which XKB rules file to use for interpreting the
.BR XkbVariant ,
and
.B XkbOptions
settings. Default: "xorg" for most platforms, but "xfree98" for the
settings. Default: \*qxorg\*q for most platforms, but \*qxfree98\*q for the
Japanese PC-98 platforms.
.TP 7
.BI "Option \*qXkbModel\*q \*q" modelname \*q
specifies the XKB keyboard model name. Default: "evdev".
specifies the XKB keyboard model name. Default: \*qevdev\*q.
.TP 7
.BI "Option \*qXkbLayout\*q \*q" layoutname \*q
specifies the XKB keyboard layout name. This is usually the country or
language type of the keyboard. Default: "us".
language type of the keyboard. Default: \*qus\*q.
.TP 7
.BI "Option \*qXkbVariant\*q \*q" variants \*q
specifies the XKB keyboard variant components. These can be used to
@@ -312,16 +327,11 @@ enhance the keyboard layout details. Default: not set.
.BI "Option \*qXkbOptions\*q \*q" options \*q
specifies the XKB keyboard option components. These can be used to
enhance the keyboard behaviour. Default: not set.
.PP
Some other XKB-related options are available, but they are incompatible
with the ones listed above and are not recommended, so they are not
documented here.
.TP 7
.PP
.SH AUTHORS
Kristian Høgsberg.
.fi
Zephaniah E. Hull.
.fi
Kristian H\(/ogsberg.
.SH "SEE ALSO"
__xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), xorgconfig(__appmansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__),
README.mouse.
__xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), xorgconfig(__appmansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__).

View File

View File

@@ -29,4 +29,4 @@
@DRIVER_NAME@_drv_la_CFLAGS = -Wall
@DRIVER_NAME@_drv_ladir = @inputdir@
@DRIVER_NAME@_drv_la_SOURCES = evdev.c evdev.h evdev_brain.c evdev_axes.c evdev_btn.c evdev_key.c inotify.h inotify-syscalls.h
@DRIVER_NAME@_drv_la_SOURCES = evdev.c evdev.h evdev_axes.c evdev_btn.c evdev_key.c

View File

@@ -1,5 +1,6 @@
/*
* Copyright © 2006 Zephaniah E. Hull
* Copyright © 2006-2007 Zephaniah E. Hull
* Copyright © 2004 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Soft-
@@ -26,31 +27,9 @@
* other dealings in this Software without prior written authorization of
* the copyright holder.
*
* Author: Zephaniah E. Hull (warp@aehallh.com)
*/
/*
* Copyright © 2004 Red Hat, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
* appear in supporting documentation, and that the name of Red Hat
* not be used in advertising or publicity pertaining to distribution
* of the software without specific, written prior permission. Red
* Hat makes no representations about the suitability of this software
* for any purpose. It is provided "as is" without express or implied
* warranty.
*
* RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL RED HAT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: Kristian Høgsberg (krh@redhat.com)
* Authors:
* Zephaniah E. Hull (warp@aehallh.com),
* Kristian Høgsberg (krh@redhat.com)
*/
#ifdef HAVE_CONFIG_H
@@ -61,24 +40,180 @@
#include <X11/XF86keysym.h>
#include <X11/extensions/XIproto.h>
#include <string.h>
#include "evdev.h"
#include <xf86.h>
#include <xf86Module.h>
#include <mipointer.h>
#include <xf86_OSlib.h>
#include <xf86_OSproc.h>
static int EvdevProc(DeviceIntPtr device, int what);
/**
* Obtain various information using ioctls on the given socket. This
* information is used to determine if a device has axis, buttons or keys.
*
* @return TRUE on success or FALSE on error.
*/
static Bool
evdevGetBits (int fd, evdevBitsPtr bits)
{
#define get_bitmask(fd, which, where) \
if (ioctl(fd, EVIOCGBIT(which, sizeof (where)), where) < 0) { \
xf86Msg(X_ERROR, "ioctl EVIOCGBIT %s failed: %s\n", #which, strerror(errno)); \
return FALSE; \
}
get_bitmask (fd, 0, bits->ev);
get_bitmask (fd, EV_KEY, bits->key);
get_bitmask (fd, EV_REL, bits->rel);
get_bitmask (fd, EV_ABS, bits->abs);
get_bitmask (fd, EV_MSC, bits->msc);
get_bitmask (fd, EV_LED, bits->led);
get_bitmask (fd, EV_SND, bits->snd);
get_bitmask (fd, EV_FF, bits->ff);
#undef get_bitmask
return TRUE;
}
/*
* FIXME: This should most definitely not be here.
* But I need it, even if it _is_ private.
* Evdev option handling stuff.
*
* We should probably move this all off to it's own file, but for now it lives
* hereish.
*/
void xf86ActivateDevice(InputInfoPtr pInfo);
evdev_map_parsers_t evdev_map_parsers[] = {
{
.name = "RelAxis",
.func = EvdevParseMapToRelAxis,
},
{
.name = "AbsAxis",
.func = EvdevParseMapToAbsAxis,
},
{
.name = "Button",
.func = EvdevParseMapToButton,
},
{
.name = "Buttons",
.func = EvdevParseMapToButtons,
},
{
.name = NULL,
.func = NULL,
}
};
Bool
EvdevParseMapOption (InputInfoRec *pInfo, char *option, char *def, void **map_data, evdev_map_func_f *map_func)
{
evdev_option_token_t *tokens;
const char *s;
int i;
s = xf86SetStrOption(pInfo->options, option, def);
tokens = EvdevTokenize (s, " =");
if (tokens->next) {
for (i = 0; evdev_map_parsers[i].name; i++) {
if (!strcasecmp (tokens->str, evdev_map_parsers[i].name)) {
if (!evdev_map_parsers[i].func (pInfo, option, tokens->next, map_data, map_func)) {
xf86Msg (X_ERROR, "%s: Unable to parse '%s' as a map specifier.\n", pInfo->name, s);
EvdevFreeTokens (tokens);
return 0;
}
return 1;
}
}
if (!evdev_map_parsers[i].name)
xf86Msg (X_ERROR, "%s: Unable to find parser for '%s' as a map specifier.\n", pInfo->name, s);
} else {
xf86Msg (X_ERROR, "%s: Unable to parse '%s' as a map specifier string.\n", pInfo->name, s);
}
EvdevFreeTokens (tokens);
return 0;
}
evdev_option_token_t *
EvdevTokenize (const char *option, const char *tokens)
{
evdev_option_token_t *head = NULL, *token = NULL, *prev = NULL;
const char *ctmp;
const char *first;
char *tmp = NULL;
int len;
first = strchr (option, tokens[0]);
while (1) {
if (first)
len = first - option;
else {
len = strlen(option);
if (!len)
break;
}
if (!len) {
option++;
first = strchr (option, tokens[0]);
continue;
}
token = calloc (1, sizeof(evdev_option_token_t));
if (!head)
head = token;
if (prev)
prev->next = token;
prev = token;
tmp = calloc(1, len + 1);
strncpy (tmp, option, len);
if (tokens[1]) {
ctmp = strchr (tmp, tokens[1]);
if (ctmp) {
token->chain = EvdevTokenize (ctmp+1, tokens + 1);
} else
token->str = tmp;
} else
token->str = tmp;
if (!first)
break;
option = first + 1;
first = strchr (option, tokens[0]);
}
return head;
}
void
EvdevFreeTokens (evdev_option_token_t *token)
{
evdev_option_token_t *next;
while (token) {
if (token->chain)
EvdevFreeTokens (token->chain);
free (token->str);
next = token->next;
free (token);
token = next;
}
}
static void
EvdevReadInput(InputInfoPtr pInfo)
@@ -91,13 +226,13 @@ EvdevReadInput(InputInfoPtr pInfo)
if (len != sizeof(ev)) {
/* The kernel promises that we always only read a complete
* event, so len != sizeof ev is an error. */
xf86Msg(X_ERROR, "Read error: %s (%d, %d != %ld)\n",
xf86Msg(X_ERROR, "Read error: %s (%d, %d != %zd)\n",
strerror(errno), errno, len, sizeof (ev));
if (len < 0) {
evdevDevicePtr pEvdev = pInfo->private;
pEvdev->callback(pEvdev->pInfo->dev, DEVICE_OFF);
pEvdev->seen--;
}
if (len < 0)
{
xf86DisableDevice(pInfo->dev, TRUE);
return;
}
break;
}
@@ -119,21 +254,19 @@ EvdevReadInput(InputInfoPtr pInfo)
case EV_SYN:
if (ev.code == SYN_REPORT) {
EvdevAxesSyn (pInfo);
/* EvdevBtnSyn (pInfo); */
/* EvdevKeySyn (pInfo); */
EvdevAxesSynRep (pInfo);
/* EvdevBtnSynRep (pInfo); */
/* EvdevKeySynRep (pInfo); */
} else if (ev.code == SYN_CONFIG) {
EvdevAxesSynCfg (pInfo);
/* EvdevBtnSynCfg (pInfo); */
/* EvdevKeySynCfg (pInfo); */
}
break;
}
}
}
static void
EvdevSigioReadInput (int fd, void *data)
{
EvdevReadInput ((InputInfoPtr) data);
}
static int
EvdevProc(DeviceIntPtr device, int what)
{
@@ -160,13 +293,10 @@ EvdevProc(DeviceIntPtr device, int what)
if (device->public.on)
break;
if ((pInfo->fd = evdevGetFDForDevice (pEvdev)) == -1) {
SYSCALL(pInfo->fd = open (pEvdev->device, O_RDWR | O_NONBLOCK));
if (pInfo->fd == -1) {
xf86Msg(X_ERROR, "%s: cannot open input device.\n", pInfo->name);
if (pEvdev->phys)
xfree(pEvdev->phys);
pEvdev->phys = NULL;
if (pEvdev->device)
xfree(pEvdev->device);
pEvdev->device = NULL;
@@ -179,8 +309,8 @@ EvdevProc(DeviceIntPtr device, int what)
xf86Msg(X_ERROR, "%s: Unable to grab device (%s).\n", pInfo->name, strerror(errno));
xf86FlushInput (pInfo->fd);
if (!xf86InstallSIGIOHandler (pInfo->fd, EvdevSigioReadInput, pInfo))
AddEnabledDevice (pInfo->fd);
xf86AddEnabledDevice(pInfo);
device->public.on = TRUE;
@@ -202,6 +332,7 @@ EvdevProc(DeviceIntPtr device, int what)
RemoveEnabledDevice (pInfo->fd);
xf86RemoveSIGIOHandler (pInfo->fd);
close (pInfo->fd);
pInfo->fd = -1;
if (pEvdev->state.axes)
EvdevAxesOff (device);
@@ -229,15 +360,10 @@ EvdevSwitchMode (ClientPtr client, DeviceIntPtr device, int mode)
{
case Absolute:
case Relative:
if (state->abs)
state->mode = mode;
else
xf86Msg(X_INFO, "%s: Switching mode to %d.\n", pInfo->name, mode);
if (!state->abs)
return !Success;
break;
case SendCoreEvents:
case DontSendCoreEvents:
xf86XInputSetSendCoreEvents (pInfo, (mode == SendCoreEvents));
break;
default:
return !Success;
}
@@ -245,64 +371,75 @@ EvdevSwitchMode (ClientPtr client, DeviceIntPtr device, int mode)
return Success;
}
static Bool
EvdevNew(evdevDriverPtr driver, evdevDevicePtr device)
InputInfoPtr
EvdevPreInit(InputDriverPtr drv, IDevPtr dev, int flags)
{
InputInfoPtr pInfo;
char name[512] = {0};
evdevDevicePtr pEvdev;
if (!(pInfo = xf86AllocateInput(driver->drv, 0)))
return 0;
if (!(pInfo = xf86AllocateInput(drv, 0)))
return NULL;
pEvdev = Xcalloc (sizeof (evdevDeviceRec));
if (!pEvdev) {
pInfo->private = NULL;
xf86DeleteInput (pInfo, 0);
return NULL;
}
/* Initialise the InputInfoRec. */
strncat (name, driver->dev->identifier, sizeof(name));
strncat (name, "-", sizeof(name));
strncat (name, device->phys, sizeof(name));
pInfo->name = xstrdup(name);
pInfo->name = xstrdup(dev->identifier);
pInfo->flags = 0;
pInfo->type_name = "UNKNOWN";
pInfo->device_control = EvdevProc;
pInfo->read_input = EvdevReadInput;
pInfo->switch_mode = EvdevSwitchMode;
pInfo->motion_history_proc = xf86GetMotionEvents;
pInfo->conf_idev = driver->dev;
pInfo->conf_idev = dev;
pInfo->private = device;
pInfo->private = pEvdev;
device->callback = EvdevProc;
device->pInfo = pInfo;
pEvdev->device = xf86CheckStrOption(dev->commonOptions, "path", NULL);
if (!pEvdev->device)
pEvdev->device = xf86CheckStrOption(dev->commonOptions, "Device", NULL);
xf86CollectInputOptions(pInfo, NULL, NULL);
xf86ProcessCommonOptions(pInfo, pInfo->options);
if ((pInfo->fd = evdevGetFDForDevice (device)) == -1) {
xf86Msg(X_ERROR, "%s: cannot open input device\n", pInfo->name);
SYSCALL(pInfo->fd = open (pEvdev->device, O_RDWR | O_NONBLOCK));
if (pInfo->fd == -1) {
xf86Msg(X_ERROR, "%s: cannot open input pEvdev\n", pInfo->name);
pInfo->private = NULL;
xfree(pEvdev);
xf86DeleteInput (pInfo, 0);
return 0;
return NULL;
}
if (!evdevGetBits (pInfo->fd, &device->bits)) {
if (!evdevGetBits (pInfo->fd, &pEvdev->bits)) {
xf86Msg(X_ERROR, "%s: cannot load bits\n", pInfo->name);
pInfo->private = NULL;
close (pInfo->fd);
xfree(pEvdev);
xf86DeleteInput (pInfo, 0);
return 0;
return NULL;
}
if (ioctl(pInfo->fd, EVIOCGRAB, (void *)1)) {
xf86Msg(X_INFO, "%s: Unable to grab device (%s). Cowardly refusing to check use as keyboard.\n", pInfo->name, strerror(errno));
device->state.can_grab = 0;
xf86Msg(X_INFO, "%s: Unable to grab pEvdev (%s). Cowardly refusing to check use as keyboard.\n", pInfo->name, strerror(errno));
pEvdev->state.can_grab = 0;
} else {
device->state.can_grab = 1;
pEvdev->state.can_grab = 1;
ioctl(pInfo->fd, EVIOCGRAB, (void *)0);
}
/* XXX: Note, the order of these is important. */
EvdevAxesNew (pInfo);
EvdevBtnNew (pInfo);
if (device->state.can_grab)
/* XXX: Note, the order of these is (maybe) still important. */
EvdevBtnNew0 (pInfo);
EvdevAxesNew0 (pInfo);
EvdevAxesNew1 (pInfo);
EvdevBtnNew1 (pInfo);
if (pEvdev->state.can_grab)
EvdevKeyNew (pInfo);
close (pInfo->fd);
@@ -310,149 +447,95 @@ EvdevNew(evdevDriverPtr driver, evdevDevicePtr device)
pInfo->flags |= XI86_OPEN_ON_INIT;
if (!(pInfo->flags & XI86_CONFIGURED)) {
xf86Msg(X_ERROR, "%s: Don't know how to use device.\n", pInfo->name);
xf86Msg(X_ERROR, "%s: Don't know how to use pEvdev.\n", pInfo->name);
pInfo->private = NULL;
close (pInfo->fd);
xfree(pEvdev);
xf86DeleteInput (pInfo, 0);
return 0;
}
if (driver->configured) {
xf86ActivateDevice (pInfo);
pInfo->dev->inited = (device->callback(device->pInfo->dev, DEVICE_INIT) == Success);
EnableDevice (pInfo->dev);
}
return 1;
}
static void
EvdevParseBits (char *in, long *out, int len)
{
unsigned long v[2];
int n, i, max_bits = len * BITS_PER_LONG;
n = sscanf (in, "%lu-%lu", &v[0], &v[1]);
if (!n)
return;
if (v[0] >= max_bits)
return;
if (n == 2) {
if (v[1] >= max_bits)
v[1] = max_bits - 1;
for (i = v[0]; i <= v[1]; i++)
set_bit (i, out);
} else
set_bit (v[0], out);
}
static void
EvdevParseBitOption (char *opt, long *all, long *not, long *any, int len)
{
char *cur, *next;
next = opt - 1;
while (next) {
cur = next + 1;
if ((next = strchr(cur, ' ')))
*next = '\0';
switch (cur[0]) {
case '+':
EvdevParseBits (cur + 1, all, len);
break;
case '-':
EvdevParseBits (cur + 1, not, len);
break;
case '~':
EvdevParseBits (cur + 1, any, len);
break;
}
}
}
static InputInfoPtr
EvdevCorePreInit(InputDriverPtr drv, IDevPtr dev, int flags)
{
evdevDriverPtr pEvdev;
char *opt, *tmp;
if (!(pEvdev = Xcalloc(sizeof(*pEvdev))))
return NULL;
pEvdev->name = xf86CheckStrOption(dev->commonOptions, "Name", NULL);
pEvdev->phys = xf86CheckStrOption(dev->commonOptions, "Phys", NULL);
pEvdev->device = xf86CheckStrOption(dev->commonOptions, "Device", NULL);
#define bitoption(field) \
opt = xf86CheckStrOption(dev->commonOptions, #field "Bits", NULL); \
if (opt) { \
tmp = strdup(opt); \
EvdevParseBitOption (tmp, pEvdev->all_bits.field, \
pEvdev->not_bits.field, \
pEvdev->any_bits.field, \
sizeof(pEvdev->not_bits.field) / sizeof (long)); \
free (tmp); \
}
bitoption(ev);
bitoption(key);
bitoption(rel);
bitoption(abs);
bitoption(msc);
bitoption(led);
bitoption(snd);
bitoption(ff);
#undef bitoption
pEvdev->id.bustype = xf86CheckIntOption(dev->commonOptions, "bustype", 0);
pEvdev->id.vendor = xf86CheckIntOption(dev->commonOptions, "vendor", 0);
pEvdev->id.product = xf86CheckIntOption(dev->commonOptions, "product", 0);
pEvdev->id.version = xf86CheckIntOption(dev->commonOptions, "version", 0);
pEvdev->pass = xf86CheckIntOption(dev->commonOptions, "Pass", 0);
if (pEvdev->pass > 3)
pEvdev->pass = 3;
else if (pEvdev->pass < 0)
pEvdev->pass = 0;
pEvdev->callback = EvdevNew;
pEvdev->dev = dev;
pEvdev->drv = drv;
if (!evdevStart (drv)) {
xf86Msg(X_ERROR, "%s: cannot start evdev brain.\n", dev->identifier);
xfree(pEvdev);
return NULL;
}
evdevNewDriver (pEvdev);
if (pEvdev->devices && pEvdev->devices->pInfo)
return pEvdev->devices->pInfo;
return NULL;
return pInfo;
}
static void
EvdevUnInit (InputDriverRec *drv, InputInfoRec *pInfo, int flags)
{
evdevDevicePtr pEvdev = pInfo->private;
evdevStatePtr state = &pEvdev->state;
if (pEvdev->device) {
xfree (pEvdev->device);
pEvdev->device = NULL;
}
if (state->btn) {
xfree (state->btn);
state->btn = NULL;
}
if (state->abs) {
xfree (state->abs);
state->abs = NULL;
}
if (state->rel) {
xfree (state->rel);
state->rel = NULL;
}
if (state->axes) {
xfree (state->axes);
state->axes = NULL;
}
if (state->key) {
evdevKeyRec *key = state->key;
if (key->xkb_rules) {
xfree (key->xkb_rules);
key->xkb_rules = NULL;
}
if (key->xkb_model) {
xfree (key->xkb_model);
key->xkb_model = NULL;
}
if (key->xkb_layout) {
xfree (key->xkb_layout);
key->xkb_layout = NULL;
}
if (key->xkb_variant) {
xfree (key->xkb_variant);
key->xkb_variant = NULL;
}
if (key->xkb_options) {
xfree (key->xkb_options);
key->xkb_options = NULL;
}
xfree (state->key);
state->key = NULL;
}
xf86DeleteInput (pInfo, 0);
}
_X_EXPORT InputDriverRec EVDEV = {
1,
"evdev",
NULL,
EvdevCorePreInit,
NULL,
EvdevPreInit,
EvdevUnInit,
NULL,
0
};
#ifdef XFree86LOADER
static void
EvdevUnplug(pointer p)
{
@@ -474,8 +557,8 @@ static XF86ModuleVersionInfo EvdevVersionRec =
MODULEVENDORSTRING,
MODINFOSTRING1,
MODINFOSTRING2,
0, /* Missing from SDK: XORG_VERSION_CURRENT, */
1, 1, 0,
XORG_VERSION_CURRENT,
PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCHLEVEL,
ABI_CLASS_XINPUT,
ABI_XINPUT_VERSION,
MOD_CLASS_XINPUT,
@@ -488,4 +571,3 @@ _X_EXPORT XF86ModuleData evdevModuleData =
EvdevPlug,
EvdevUnplug
};
#endif /* XFree86LOADER */

View File

@@ -1,5 +1,6 @@
/*
* Copyright © 2006 Zephaniah E. Hull
* Copyright © 2006-2007 Zephaniah E. Hull
* Copyright © 2004 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Soft-
@@ -26,35 +27,13 @@
* other dealings in this Software without prior written authorization of
* the copyright holder.
*
* Author: Zephaniah E. Hull (warp@aehallh.com)
*/
/*
* Copyright © 2004 Red Hat, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
* appear in supporting documentation, and that the name of Red Hat
* not be used in advertising or publicity pertaining to distribution
* of the software without specific, written prior permission. Red
* Hat makes no representations about the suitability of this software
* for any purpose. It is provided "as is" without express or implied
* warranty.
*
* RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL RED HAT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: Kristian Høgsberg (krh@redhat.com)
* Authors:
* Zephaniah E. Hull (warp@aehallh.com)
* Kristian Høgsberg (krh@redhat.com)
*/
#ifndef EVDEV_BRAIN_H_
#define EVDEV_BRAIN_H_
#ifndef __EVDEV_H
#define __EVDEV_H
#define _XF86_ANSIC_H
#define XF86_LIBC_H
@@ -72,102 +51,122 @@
#include <stdarg.h>
#include <xf86Xinput.h>
#define BITS_PER_LONG (sizeof(long) * 8)
#ifndef BITS_PER_LONG
#define BITS_PER_LONG (sizeof(unsigned long) * 8)
#endif
#define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1)
#define OFF(x) ((x)%BITS_PER_LONG)
#define LONG(x) ((x)/BITS_PER_LONG)
#define BIT(x) (1UL<<((x)%BITS_PER_LONG))
#define test_bit(bit, array) ((array[LONG(bit)] >> OFF(bit)) & 1)
#define MASK(x) (1UL << ((x) & (BITS_PER_LONG - 1)))
/* 2.4 compatibility */
#ifndef EVIOCGSW
#include <sys/time.h>
#include <sys/ioctl.h>
#include <asm/types.h>
#include <asm/bitops.h>
#define EVIOCGSW(len) _IOC(_IOC_READ, 'E', 0x1b, len) /* get all switch states */
#define EV_SW 0x05
#ifndef test_bit
#define test_bit(bit, array) (!!(array[LONG(bit)] & MASK(bit)))
#endif
#ifndef set_bit
#define set_bit(bit, array) (array[LONG(bit)] |= MASK(bit))
#endif
#ifndef clear_bit
#define clear_bit(bit, array) (array[LONG(bit)] &= ~MASK(bit))
#endif
#ifndef EVIOCGRAB
#define EVIOCGRAB _IOW('E', 0x90, int)
#endif
#ifndef BTN_TASK
#define BTN_TASK 0x117
#endif
#ifndef EV_SYN
#define EV_SYN EV_RST
#endif
/* end compat */
#include <X11/extensions/XKB.h>
#include <X11/extensions/XKBstr.h>
/*
* At the moment, ABS_MAX is larger then REL_MAX.
* As they are the only two providors of axes, ABS_MAX is it.
*/
#define AXES_MAX ABS_MAX
#define BTN_MAX 96
struct _evdevDevice;
/*
* Switch events
* FIXME: The mode option here is a kludge.
* It can be 0 (rel mode), 1 (abs mode), or -1 (input side has no clue).
*
* Worse, it arguably shouldn't even be the sender that decides here.
* And only the Axes targets and sources care at all right now.
*/
#define EV_SW_0 0x00
#define EV_SW_1 0x01
#define EV_SW_2 0x02
#define EV_SW_3 0x03
#define EV_SW_4 0x04
#define EV_SW_5 0x05
#define EV_SW_6 0x06
#define EV_SW_7 0x07
#define EV_SW_MAX 0x0f
#define EV_BUS_GSC 0x1A
#define EVDEV_MAXBUTTONS 96
typedef void (*evdev_map_func_f)(InputInfoPtr pInfo, int value, int mode, void *map_data);
typedef struct {
long ev[NBITS(EV_MAX)];
long key[NBITS(KEY_MAX)];
long rel[NBITS(REL_MAX)];
long abs[NBITS(ABS_MAX)];
long msc[NBITS(MSC_MAX)];
long led[NBITS(LED_MAX)];
long snd[NBITS(SND_MAX)];
long ff[NBITS(FF_MAX)];
unsigned long ev[NBITS(EV_MAX)];
unsigned long key[NBITS(KEY_MAX)];
unsigned long rel[NBITS(REL_MAX)];
unsigned long abs[NBITS(ABS_MAX)];
unsigned long msc[NBITS(MSC_MAX)];
unsigned long led[NBITS(LED_MAX)];
unsigned long snd[NBITS(SND_MAX)];
unsigned long ff[NBITS(FF_MAX)];
} evdevBitsRec, *evdevBitsPtr;
#define EV_BTN_B_PRESENT (1<<0)
typedef struct {
int real_buttons;
int buttons;
CARD8 map[EVDEV_MAXBUTTONS];
int *state[EVDEV_MAXBUTTONS];
int b_flags[BTN_MAX];
void *b_map_data[ABS_MAX];
evdev_map_func_f b_map[BTN_MAX];
void (*callback[BTN_MAX])(InputInfoPtr pInfo, int button, int value);
} evdevBtnRec, *evdevBtnPtr;
typedef struct {
int axes;
int n; /* Which abs_v is current, and which is previous. */
int v[2][ABS_MAX];
int count;
int min[ABS_MAX];
int max[ABS_MAX];
int map[ABS_MAX];
int scale[2];
int screen; /* Screen number for this device. */
} evdevAbsRec, *evdevAbsPtr;
#define EV_ABS_V_PRESENT (1<<0)
#define EV_ABS_V_M_AUTO (1<<1)
#define EV_ABS_V_M_REL (1<<2)
#define EV_ABS_V_INVERT (1<<3)
#define EV_ABS_V_RESET (1<<4)
#define EV_ABS_V_USE_TOUCH (1<<5)
typedef struct {
int axes;
int v[REL_MAX];
int count;
int map[REL_MAX];
} evdevRelRec, *evdevRelPtr;
#define EV_ABS_USE_TOUCH (1<<0)
#define EV_ABS_TOUCH (1<<1)
#define EV_ABS_UPDATED (1<<2)
typedef struct {
int flags;
int axes;
int v[ABS_MAX];
int btnMap[ABS_MAX][2];
int v_flags[ABS_MAX];
void *v_map_data[ABS_MAX];
evdev_map_func_f v_map[ABS_MAX];
} evdevAbsRec, *evdevAbsPtr;
#define EV_REL_V_PRESENT (1<<0)
#define EV_REL_V_INVERT (1<<1)
#define EV_REL_UPDATED (1<<0)
typedef struct {
int flags;
int v_flags[REL_MAX];
int v[REL_MAX];
int axes;
void *v_map_data[REL_MAX];
evdev_map_func_f v_map[REL_MAX];
} evdevRelRec, *evdevRelPtr;
#define EV_AXES_V_M_ABS (1<<0)
#define EV_AXES_V_M_REL (1<<1)
#define EV_AXES_V_PRESENT (1<<2)
#define EV_AXES_V_UPDATED (1<<3)
#define EV_AXES_V_M_MASK (EV_AXES_V_M_ABS | EV_AXES_V_M_REL)
#define EV_AXES_UPDATED (1<<0)
typedef struct {
int axes;
int flags;
int v_flags[AXES_MAX];
int v_min[AXES_MAX];
int v_max[AXES_MAX];
int v[AXES_MAX];
int rotation;
float rot_sin, rot_cos;
int x, y;
} evdevAxesRec, *evdevAxesPtr;
typedef struct {
@@ -182,7 +181,6 @@ typedef struct {
typedef struct _evdevState {
Bool can_grab;
Bool sync;
int mode; /* Either Absolute or Relative. */
evdevBtnPtr btn;
evdevAbsPtr abs;
@@ -192,63 +190,32 @@ typedef struct _evdevState {
} evdevStateRec, *evdevStatePtr;
typedef struct _evdevDevice {
const char *name;
const char *phys;
const char *device;
int seen;
InputInfoPtr pInfo;
int (*callback)(DeviceIntPtr cb_data, int what);
evdevBitsRec bits;
struct input_id id;
evdevStateRec state;
struct _evdevDevice *next;
} evdevDeviceRec, *evdevDevicePtr;
typedef struct _evdevDriver {
const char *name;
const char *phys;
const char *device;
evdevBitsRec all_bits;
evdevBitsRec not_bits;
evdevBitsRec any_bits;
struct input_id id;
int pass;
InputDriverPtr drv;
IDevPtr dev;
Bool (*callback)(struct _evdevDriver *driver, evdevDevicePtr device);
evdevDevicePtr devices;
Bool configured;
struct _evdevDriver *next;
} evdevDriverRec, *evdevDriverPtr;
int evdevGetFDForDevice (evdevDevicePtr driver);
Bool evdevStart (InputDriverPtr drv);
Bool evdevNewDriver (evdevDriverPtr driver);
Bool evdevGetBits (int fd, evdevBitsPtr bits);
int EvdevBtnInit (DeviceIntPtr device);
int EvdevBtnOn (DeviceIntPtr device);
int EvdevBtnOff (DeviceIntPtr device);
int EvdevBtnNew(InputInfoPtr pInfo);
int EvdevBtnNew0(InputInfoPtr pInfo);
int EvdevBtnNew1(InputInfoPtr pInfo);
void EvdevBtnProcess (InputInfoPtr pInfo, struct input_event *ev);
void EvdevBtnPostFakeClicks(InputInfoPtr pInfo, int button, int count);
int EvdevBtnFind (InputInfoPtr pInfo, const char *button);
int EvdevBtnExists (InputInfoPtr pInfo, int button);
int EvdevAxesInit (DeviceIntPtr device);
int EvdevAxesOn (DeviceIntPtr device);
int EvdevAxesOff (DeviceIntPtr device);
int EvdevAxesNew(InputInfoPtr pInfo);
int EvdevAxesNew0(InputInfoPtr pInfo);
int EvdevAxesNew1(InputInfoPtr pInfo);
void EvdevAxesAbsProcess (InputInfoPtr pInfo, struct input_event *ev);
void EvdevAxesRelProcess (InputInfoPtr pInfo, struct input_event *ev);
void EvdevAxesSyn (InputInfoPtr pInfo);
void EvdevAxesSynRep (InputInfoPtr pInfo);
void EvdevAxesSynCfg (InputInfoPtr pInfo);
int EvdevKeyInit (DeviceIntPtr device);
int EvdevKeyNew (InputInfoPtr pInfo);
@@ -256,4 +223,50 @@ int EvdevKeyOn (DeviceIntPtr device);
int EvdevKeyOff (DeviceIntPtr device);
void EvdevKeyProcess (InputInfoPtr pInfo, struct input_event *ev);
#endif /* LNX_EVDEV_H_ */
/*
* Option handling stuff.
*/
typedef struct evdev_option_token_s {
const char *str;
struct evdev_option_token_s *chain;
struct evdev_option_token_s *next;
} evdev_option_token_t;
typedef Bool (*evdev_parse_opt_func_f)(InputInfoPtr pInfo, const char *name, evdev_option_token_t *token, int *flags);
typedef Bool (*evdev_parse_map_func_f)(InputInfoPtr pInfo,
const char *name,
evdev_option_token_t *option,
void **map_data, evdev_map_func_f *map_func);
evdev_option_token_t *EvdevTokenize (const char *option, const char *tokens);
void EvdevFreeTokens (evdev_option_token_t *token);
Bool EvdevParseMapToRelAxis (InputInfoPtr pInfo,
const char *name,
evdev_option_token_t *option,
void **map_data, evdev_map_func_f *map_func);
Bool EvdevParseMapToAbsAxis (InputInfoPtr pInfo,
const char *name,
evdev_option_token_t *option,
void **map_data, evdev_map_func_f *map_func);
Bool
EvdevParseMapToButton (InputInfoRec *pInfo,
const char *name,
evdev_option_token_t *option,
void **map_data, evdev_map_func_f *map_func);
Bool
EvdevParseMapToButtons (InputInfoRec *pInfo,
const char *name,
evdev_option_token_t *option,
void **map_data, evdev_map_func_f *map_func);
typedef struct {
char *name;
evdev_parse_map_func_f func;
} evdev_map_parsers_t;
extern evdev_map_parsers_t evdev_map_parsers[];
Bool EvdevParseMapOption (InputInfoRec *pInfo, char *option, char *def, void **map_data, evdev_map_func_f *map_func);
#endif /* __EVDEV_H */

View File

@@ -1,5 +1,5 @@
/*
* Copyright © 2006 Zephaniah E. Hull
* Copyright © 2006-2007 Zephaniah E. Hull
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Soft-
@@ -49,13 +49,7 @@
#include <xf86_OSproc.h>
#define ArrayLength(a) (sizeof(a) / (sizeof((a)[0])))
#define BITS_PER_LONG (sizeof(long) * 8)
#define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1)
#define OFF(x) ((x)%BITS_PER_LONG)
#define LONG(x) ((x)/BITS_PER_LONG)
#define TestBit(bit, array) ((array[LONG(bit)] >> OFF(bit)) & 1)
#undef DEBUG
static char *rel_axis_names[] = {
"X",
@@ -144,6 +138,175 @@ static char *abs_axis_names[] = {
NULL
};
static void EvdevAxesTouchCallback (InputInfoPtr pInfo, int button, int value);
void
EvdevAxesMapAxis (InputInfoPtr pInfo, int value, int mode, void *map_data)
{
evdevDevicePtr pEvdev = pInfo->private;
evdevStatePtr state = &pEvdev->state;
evdevAxesPtr axes = state->axes;
long map = (long) map_data;
if (map >= AXES_MAX || !axes || !(axes->v_flags[map] & (EV_AXES_V_M_ABS | EV_AXES_V_M_REL)))
return;
axes->v[map] = value;
if (mode == 0) {
axes->v_flags[map] &= ~EV_AXES_V_M_ABS;
axes->v_flags[map] |= EV_AXES_V_M_REL;
} else if (mode == 1) {
axes->v_flags[map] &= ~EV_AXES_V_M_REL;
axes->v_flags[map] |= EV_AXES_V_M_ABS;
}
axes->v_flags[map] |= EV_AXES_V_UPDATED;
axes->flags |= EV_AXES_UPDATED;
}
static Bool
EvdevParseRelOptions (InputInfoPtr pInfo, const char *name, evdev_option_token_t *option, int *flags)
{
if (!option)
return 0;
for (; option; option = option->next) {
if (!strcasecmp (option->str, "invert"))
*flags |= EV_REL_V_INVERT;
else
xf86Msg(X_ERROR, "%s: %s unknown relative option '%s'.\n", pInfo->name, name, option->str);
}
*flags |= EV_REL_V_PRESENT;
return 1;
}
static Bool
EvdevParseAbsOptions (InputInfoPtr pInfo, const char *name, evdev_option_token_t *option, int *flags)
{
if (!option)
return 0;
for (; option; option = option->next) {
if (!strcasecmp (option->str, "invert"))
*flags |= EV_ABS_V_INVERT;
else if (!strcasecmp (option->str, "use_touch"))
*flags |= EV_ABS_V_USE_TOUCH;
else if (!strcasecmp (option->str, "mode_auto"))
*flags |= EV_ABS_V_M_AUTO;
else if (!strcasecmp (option->str, "mode_rel"))
*flags |= EV_ABS_V_M_REL;
else
xf86Msg(X_ERROR, "%s: %s unknown absolute option '%s'.\n", pInfo->name, name, option->str);
}
*flags |= EV_ABS_V_PRESENT;
return 1;
}
Bool
EvdevParseMapToRelAxis (InputInfoPtr pInfo,
const char *name,
evdev_option_token_t *option,
void **map_data, evdev_map_func_f *map_func)
{
evdevDevicePtr pEvdev = pInfo->private;
evdevStatePtr state = &pEvdev->state;
evdevAxesPtr axes = state->axes;
long i;
errno = 0;
i = strtol (option->str, NULL, 0);
if (errno) {
for (i = 0; rel_axis_names[i]; i++) {
if (!strcmp (option->str, rel_axis_names[i]))
break;
}
if (!rel_axis_names[i])
return 0;
}
if ((i < 0) || (i > AXES_MAX))
return 0;
if (axes->v_flags[i] & EV_AXES_V_PRESENT)
return 0;
axes->v_flags[i] = EV_AXES_V_M_REL | EV_AXES_V_PRESENT;
*map_data = (void *) i;
*map_func = EvdevAxesMapAxis;
return 1;
}
Bool
EvdevParseMapToAbsAxis (InputInfoPtr pInfo,
const char *name,
evdev_option_token_t *option,
void **map_data, evdev_map_func_f *map_func)
{
evdevDevicePtr pEvdev = pInfo->private;
evdevStatePtr state = &pEvdev->state;
evdevAxesPtr axes = state->axes;
long i;
errno = 0;
i = strtol (option->str, NULL, 0);
if (errno) {
for (i = 0; abs_axis_names[i]; i++) {
if (!strcmp (option->str, abs_axis_names[i]))
break;
}
if (!abs_axis_names[i]) {
xf86Msg (X_ERROR, "%s: %s: No axis named '%s'.\n", pInfo->name, name, option->str);
return 0;
}
}
if ((i < 0) || (i > AXES_MAX)) {
xf86Msg (X_ERROR, "%s: %s: Axis %ld out of range.\n", pInfo->name, name, i);
return 0;
}
if (axes->v_flags[i] & EV_AXES_V_PRESENT) {
xf86Msg (X_ERROR, "%s: %s: Axis %ld already claimed.\n", pInfo->name, name, i);
return 0;
}
option = option->next;
if (!option) {
xf86Msg (X_ERROR, "%s: %s: No min.\n", pInfo->name, name);
return 0;
}
errno = 0;
axes->v_min[i] = strtol (option->str, NULL, 0);
if (errno) {
xf86Msg (X_ERROR, "%s: %s: Unable to parse '%s' as min. (%s)\n", pInfo->name, name, option->str, strerror(errno));
return 0;
}
option = option->next;
if (!option) {
xf86Msg (X_ERROR, "%s: %s: No max.\n", pInfo->name, name);
return 0;
}
errno = 0;
axes->v_max[i] = strtol (option->str, NULL, 0);
if (errno) {
xf86Msg (X_ERROR, "%s: %s: Unable to parse '%s' as max. (%s)\n", pInfo->name, name, option->str, strerror(errno));
return 0;
}
axes->v_flags[i] = EV_AXES_V_M_ABS | EV_AXES_V_PRESENT;
*map_data = (void *) i;
*map_func = EvdevAxesMapAxis;
return 1;
}
static Bool
EvdevConvert(InputInfoPtr pInfo, int first, int num, int v0, int v1, int v2,
int v3, int v4, int v5, int *x, int *y)
@@ -156,107 +319,242 @@ EvdevConvert(InputInfoPtr pInfo, int first, int num, int v0, int v1, int v2,
return FALSE;
}
/*
* Rotation and rep code, this is a mess and much of it needs to live in mi/
* after a cleanup.
*/
static void
EvdevAxesRealSyn (InputInfoPtr pInfo, int absolute)
EvdevAxesDoRotation (InputInfoPtr pInfo)
{
evdevDevicePtr pEvdev = pInfo->private;
evdevStatePtr state = &pEvdev->state;
evdevAxesPtr axes = state->axes;
int i, btn;
DeviceIntPtr dev = pInfo->dev;
AbsoluteClassRec *dabs = dev->absolute;
for (i = 0; i < state->axes->axes; i++) {
if ((state->axes->v[i] > 0) && (btn = state->axes->btnMap[i][0]))
EvdevBtnPostFakeClicks (pInfo, btn, state->axes->v[i]);
else if ((state->axes->v[i] < 0) && (btn = state->axes->btnMap[i][1]))
EvdevBtnPostFakeClicks (pInfo, btn, -state->axes->v[i]);
/*
* Rotation.
* Cache the sine and cosine results so we're not doing it every time.
*/
if (dabs->rotation != axes->rotation || (axes->rot_cos == axes->rot_sin)) {
axes->rotation = dabs->rotation % 360;
axes->rot_cos = cos ( ((float) axes->rotation) * (M_PI/180));
axes->rot_sin = sin ( ((float) axes->rotation) * (M_PI/180));
}
xf86PostMotionEvent(pInfo->dev, absolute, 0,
state->axes->axes,
axes->v[0x00], axes->v[0x01], axes->v[0x02], axes->v[0x03],
axes->v[0x04], axes->v[0x05], axes->v[0x06], axes->v[0x07],
axes->v[0x08], axes->v[0x09], axes->v[0x0a], axes->v[0x0b],
axes->v[0x0c], axes->v[0x0d], axes->v[0x0e], axes->v[0x0f],
axes->v[0x10], axes->v[0x11], axes->v[0x12], axes->v[0x13],
axes->v[0x14], axes->v[0x15], axes->v[0x16], axes->v[0x17],
axes->v[0x18], axes->v[0x19], axes->v[0x1a], axes->v[0x1b],
axes->v[0x1c], axes->v[0x1d], axes->v[0x1e], axes->v[0x1f],
axes->v[0x20], axes->v[0x21], axes->v[0x22], axes->v[0x23],
axes->v[0x24], axes->v[0x25], axes->v[0x26], axes->v[0x27],
axes->v[0x28], axes->v[0x29], axes->v[0x2a], axes->v[0x2b],
axes->v[0x2c], axes->v[0x2d], axes->v[0x2e], axes->v[0x2f],
axes->v[0x30], axes->v[0x31], axes->v[0x32], axes->v[0x33],
axes->v[0x34], axes->v[0x35], axes->v[0x36], axes->v[0x37],
axes->v[0x38], axes->v[0x39], axes->v[0x3a], axes->v[0x3b],
axes->v[0x3c], axes->v[0x3d], axes->v[0x3e], axes->v[0x3f]);
if (axes->rotation) {
float x = axes->v[0], y = axes->v[1];
axes->v[0] = (x * axes->rot_cos) - (y * axes->rot_sin);
axes->v[1] = (y * axes->rot_cos) + (x * axes->rot_sin);
for (i = 0; i < ABS_MAX; i++)
state->axes->v[i] = 0;
axes->v_flags[0] |= EV_AXES_V_UPDATED;
axes->v_flags[1] |= EV_AXES_V_UPDATED;
#if DEBUG
xf86Msg(X_ERROR, "%s %d (%s): rotation=%d, cos=%f, sin=%f, x=%f, y=%f, v[0]=%d, v[1]=%d\n", __FILE__, __LINE__, __FUNCTION__,
axes->rotation, axes->rot_cos, axes->rot_sin, x, y, axes->v[0], axes->v[1]);
#endif
}
}
static void
EvdevAxesAbsSyn (InputInfoPtr pInfo)
/*
* Cx - raw data from touch screen
* Sxhigh - scaled highest dimension
* (remember, this is of rows - 1 because of 0 origin)
* Sxlow - scaled lowest dimension
* Rxhigh - highest raw value from touch screen calibration
* Rxlow - lowest raw value from touch screen calibration
*
* This function is the same for X or Y coordinates.
* You may have to reverse the high and low values to compensate for
* different orgins on the touch screen vs X.
*/
_X_EXPORT int
EvdevScaleAxis(int Cx,
int Sxlow,
int Sxhigh,
int Rxlow,
int Rxhigh)
{
evdevDevicePtr pEvdev = pInfo->private;
evdevStatePtr state = &pEvdev->state;
int i, n;
int X;
int dSx = Sxhigh - Sxlow;
int dRx = Rxhigh - Rxlow;
if (!state->axes || !state->abs || !state->abs->count)
return;
/* This is +, because Cx is negitive, so we're really subtracting. */
if (Cx < 0)
Cx = Rxhigh + Cx;
n = state->abs->n & 1;
state->abs->n++;
i = 0;
if (state->mode == Relative && state->abs->axes >= 2) {
for (i = 0; i < 2; i++)
state->axes->v[i] = state->abs->v[n][i] - state->abs->v[!n][i];
EvdevAxesRealSyn (pInfo, 0);
} else if (state->mode == Absolute && state->abs->screen >= 0 && state->abs->axes >= 2) {
int conv_x, conv_y;
for (i = 0; i < 2; i++)
state->axes->v[i] = xf86ScaleAxis (state->abs->v[n][i],
0, state->abs->scale[i],
state->abs->min[i], state->abs->max[i]);
EvdevConvert (pInfo, 0, 2, state->abs->v[n][0], state->abs->v[n][1],
0, 0, 0, 0, &conv_x, &conv_y);
xf86XInputSetScreen (pInfo, state->abs->screen, conv_x, conv_y);
dSx = Sxhigh - Sxlow;
if (dRx) {
X = ((dSx * (Cx - Rxlow)) / dRx) + Sxlow;
}
for (; i < ABS_MAX; i++)
state->axes->v[i] = state->abs->v[n][i];
EvdevAxesRealSyn (pInfo, 1);
state->abs->count = 0;
}
static void
EvdevAxesRelSyn (InputInfoPtr pInfo)
{
evdevDevicePtr pEvdev = pInfo->private;
evdevStatePtr state = &pEvdev->state;
int i;
if (!state->axes || !state->rel || !state->rel->count)
return;
for (i = 0; i < REL_MAX; i++) {
state->axes->v[i] = state->rel->v[i];
state->rel->v[i] = 0;
else {
X = 0;
ErrorF ("Divide by Zero in evdevScaleAxis");
}
if (X < Sxlow)
X = Sxlow;
if (X > Sxhigh)
X = Sxhigh;
EvdevAxesRealSyn (pInfo, 0);
state->rel->count = 0;
return (X);
}
void
EvdevAxesSyn (InputInfoPtr pInfo)
EvdevAxesSynRep (InputInfoPtr pInfo)
{
EvdevAxesAbsSyn (pInfo);
EvdevAxesRelSyn (pInfo);
evdevDevicePtr pEvdev = pInfo->private;
evdevStatePtr state = &pEvdev->state;
evdevAxesPtr axes = state->axes;
DeviceIntPtr dev = pInfo->dev;
AbsoluteClassRec *dabs = dev->absolute;
int i, start, run, mode;
if (!axes || !(axes->flags & EV_AXES_UPDATED))
return;
start = 0;
mode = 0;
run = 0;
/*
* This handles most, but not all, of the ABS_CALIB and ABS_AREA
* additions to XInput 1.0.
*
* Note, we do this if both X and Y are set to absolute, or a more
* limited subset if both X and Y are relative, we don't do anything
* if we lack X or Y, or if they are not both set to both be ABS or REL.
*/
if (axes->axes >= 2 && dabs) {
if ((axes->v_flags[0] & EV_AXES_V_M_ABS) &&
(axes->v_flags[1] & EV_AXES_V_M_ABS) &&
((axes->v_flags[0] & EV_AXES_V_UPDATED) ||
(axes->v_flags[1] & EV_AXES_V_UPDATED))
) {
int width, height, min_x, max_x, min_y, max_y;
if (axes->v_flags[0] & EV_AXES_V_UPDATED) axes->x = axes->v[0];
else axes->v[0] = axes->x;
if (axes->v_flags[1] & EV_AXES_V_UPDATED) axes->y = axes->v[1];
else axes->v[1] = axes->y;
if (dabs->width > 0)
width = dabs->width;
else
width = screenInfo.screens[dabs->screen]->width;
if (dabs->height > 0)
height = dabs->height;
else
height = screenInfo.screens[dabs->screen]->height;
if (dabs->flip_x)
axes->v[0] = dabs->max_x - axes->v[0];
if (dabs->flip_y)
axes->v[1] = dabs->max_y - axes->v[1];
/*
* In some cases we need to swap width and height.
* This depends on the rotation.
*/
if ( (axes->rotation >= 45 && axes->rotation < 135) ||
(axes->rotation >= 225 && axes->rotation < 315)) {
min_x = dabs->min_y;
max_x = dabs->max_y;
min_y = dabs->min_x;
max_y = dabs->max_x;
} else {
min_x = dabs->min_x;
max_x = dabs->max_x;
min_y = dabs->min_y;
max_y = dabs->max_y;
}
EvdevAxesDoRotation (pInfo);
axes->v[0] = EvdevScaleAxis (axes->v[0], 0, width, min_x, max_x);
axes->v[1] = EvdevScaleAxis (axes->v[1], 0, height, min_y, max_y);
axes->v[0] += dabs->offset_x;
axes->v[1] += dabs->offset_y;
xf86XInputSetScreen (pInfo, dabs->screen, axes->v[0], axes->v[1]);
} else if ((axes->v_flags[0] & EV_AXES_V_M_REL) &&
(axes->v_flags[1] & EV_AXES_V_M_REL) &&
((axes->v_flags[0] & EV_AXES_V_UPDATED) ||
(axes->v_flags[1] & EV_AXES_V_UPDATED))
) {
if (axes->v_flags[0] & EV_AXES_V_UPDATED) axes->x = axes->v[0];
else axes->v[0] = axes->x;
if (axes->v_flags[1] & EV_AXES_V_UPDATED) axes->y = axes->v[1];
else axes->v[1] = axes->y;
if (dabs->flip_x)
axes->v[0] = -axes->v[0];
if (dabs->flip_y)
axes->v[1] = -axes->v[1];
EvdevAxesDoRotation (pInfo);
}
}
#if DEBUG
xf86Msg(X_ERROR, "%s %d (%s): v[0]=%d%s%s, v[1]=%d%s%s, v[2]=%d%s%s\n", __FILE__, __LINE__, __FUNCTION__,
axes->v[0],
axes->v_flags[0] & EV_AXES_V_M_ABS ? "!" : "",
axes->v_flags[0] & EV_AXES_V_UPDATED ? "*" : "",
axes->v[1],
axes->v_flags[1] & EV_AXES_V_M_ABS ? "!" : "",
axes->v_flags[1] & EV_AXES_V_UPDATED ? "*" : "",
axes->v[2],
axes->v_flags[2] & EV_AXES_V_M_ABS ? "!" : "",
axes->v_flags[2] & EV_AXES_V_UPDATED ? "*" : "");
#endif
for (i = 0; i < axes->axes; i++) {
if (axes->v_flags[i] & EV_AXES_V_UPDATED) {
if (run) {
if (mode != (axes->v_flags[i] & EV_AXES_V_M_MASK)) {
mode = (mode == EV_AXES_V_M_ABS);
#if DEBUG
xf86Msg(X_ERROR, "%s %d (%s): mode=%d, start=%d, i - start=%d\n", __FILE__, __LINE__, __FUNCTION__,
mode, start, i - start);
#endif
xf86PostMotionEventP (pInfo->dev, mode, start, i - start, axes->v + start);
start = i;
mode = axes->v_flags[i] & EV_AXES_V_M_MASK;
}
} else {
start = i;
mode = axes->v_flags[i] & EV_AXES_V_M_MASK;
}
run = 1;
axes->v_flags[i] &= ~EV_AXES_V_UPDATED;
} else if (run) {
mode = (mode == EV_AXES_V_M_ABS);
xf86PostMotionEventP (pInfo->dev, mode, start, i - start, axes->v + start);
run = 0;
}
}
if (run) {
mode = (mode == EV_AXES_V_M_ABS);
xf86PostMotionEventP (pInfo->dev, mode, start, i - start, axes->v + start);
}
}
/*
* End rotation and rep code, this is a mess and much of it needs to live in mi/
* after a cleanup.
*/
void
EvdevAxesSynCfg (InputInfoPtr pInfo)
{
/* EvdevAxesAbsSynCfg (pInfo);*/
/* EvdevAxesRelSynCfg (pInfo);*/
}
void
@@ -264,23 +562,40 @@ EvdevAxesAbsProcess (InputInfoPtr pInfo, struct input_event *ev)
{
evdevDevicePtr pEvdev = pInfo->private;
evdevStatePtr state = &pEvdev->state;
int n = state->abs->n & 1;
int map;
evdevAbsRec *abs = state->abs;
int value, v_flags, is_rel;
if (ev->code >= ABS_MAX)
if (ev->code >= ABS_MAX || !abs->v_map[ev->code])
return;
/* FIXME: Handle inverted axes properly. */
map = state->abs->map[ev->code];
if (map >= 0)
state->abs->v[n][map] = ev->value;
value = ev->value;
v_flags = abs->v_flags[ev->code];
if ((v_flags & EV_ABS_V_USE_TOUCH) && !(state->abs->flags & EV_ABS_TOUCH))
return;
#if 0
if (v_flags & EV_ABS_V_INVERT)
value = -value;
#endif
if (v_flags & EV_ABS_V_M_REL)
is_rel = 1;
else if ((v_flags & EV_ABS_V_M_AUTO) && pInfo->dev->valuator->mode == Relative)
is_rel = 1;
else
state->abs->v[n][-map] = ev->value;
is_rel = 0;
state->abs->count++;
if (is_rel) {
if ((v_flags & EV_ABS_V_RESET) && value != abs->v[ev->code]) {
abs->v_flags[ev->code] &= ~EV_ABS_V_RESET;
} else
abs->v_map[ev->code](pInfo, value - abs->v[ev->code], 0, abs->v_map_data[ev->code]);
abs->v[ev->code] = value;
} else
abs->v_map[ev->code](pInfo, value, 1, abs->v_map_data[ev->code]);
if (!state->sync)
EvdevAxesAbsSyn (pInfo);
}
void
@@ -288,21 +603,19 @@ EvdevAxesRelProcess (InputInfoPtr pInfo, struct input_event *ev)
{
evdevDevicePtr pEvdev = pInfo->private;
evdevStatePtr state = &pEvdev->state;
int map;
evdevRelRec *rel = state->rel;
int value, v_flags;
if (ev->code >= REL_MAX)
if (ev->code >= REL_MAX || !rel->v_map[ev->code])
return;
map = state->rel->map[ev->code];
if (map >= 0)
state->rel->v[map] += ev->value;
else
state->rel->v[-map] -= ev->value;
value = ev->value;
v_flags = rel->v_flags[ev->code];
state->rel->count++;
if (v_flags & EV_REL_V_INVERT)
value = -value;
if (!state->sync)
EvdevAxesRelSyn (pInfo);
rel->v_map[ev->code](pInfo, value, 0, rel->v_map_data[ev->code]);
}
int
@@ -320,21 +633,24 @@ EvdevAxesOff (DeviceIntPtr device)
static int
EvdevAxisAbsNew(InputInfoPtr pInfo)
{
evdevDevicePtr pEvdev = pInfo->private;
evdevStatePtr state = &pEvdev->state;
evdevDeviceRec *pEvdev = pInfo->private;
evdevStateRec *state = &pEvdev->state;
evdevAbsRec *abs;
struct input_absinfo absinfo;
char *s, option[64];
int i, j, k = 0, real_axes;
char option[128], value[128];
const char *s;
int i, j, real_axes;
evdev_option_token_t *tokens;
real_axes = 0;
for (i = 0; i < ABS_MAX; i++)
if (TestBit (i, pEvdev->bits.abs))
if (test_bit (i, pEvdev->bits.abs))
real_axes++;
if (!real_axes)
return !Success;
state->abs = Xcalloc (sizeof (evdevAbsRec));
state->abs = abs = Xcalloc (sizeof (evdevAbsRec));
xf86Msg(X_INFO, "%s: Found %d absolute axes.\n", pInfo->name, real_axes);
xf86Msg(X_INFO, "%s: Configuring as pointer.\n", pInfo->name);
@@ -344,66 +660,72 @@ EvdevAxisAbsNew(InputInfoPtr pInfo)
pInfo->conversion_proc = EvdevConvert;
for (i = 0, j = 0; i < ABS_MAX; i++) {
if (!TestBit (i, pEvdev->bits.abs))
if (!test_bit (i, pEvdev->bits.abs))
continue;
snprintf(option, sizeof(option), "%sAbsoluteAxisMap", abs_axis_names[i]);
k = xf86SetIntOption(pInfo->options, option, -1);
if (k != -1)
state->abs->map[i] = k;
else
state->abs->map[i] = j;
if (k != -1)
xf86Msg(X_CONFIG, "%s: %s: %d.\n", pInfo->name, option, k);
if (ioctl (pInfo->fd, EVIOCGABS(i), &absinfo) < 0) {
xf86Msg(X_ERROR, "ioctl EVIOCGABS failed: %s\n", strerror(errno));
return !Success;
}
state->abs->min[state->abs->map[i]] = absinfo.minimum;
state->abs->max[state->abs->map[i]] = absinfo.maximum;
snprintf(option, sizeof(option), "Abs%sMapTo", abs_axis_names[i]);
snprintf(value, sizeof(value), "AbsAxis %d %d %d", j, absinfo.minimum, absinfo.maximum);
EvdevParseMapOption (pInfo, option, value, &abs->v_map_data[i], &abs->v_map[i]);
snprintf(option, sizeof(option), "Abs%sOptions", abs_axis_names[i]);
if (i == ABS_X || i == ABS_Y)
s = xf86SetStrOption(pInfo->options, option, "use_touch mode_auto");
else
s = xf86SetStrOption(pInfo->options, option, "");
if (s[0]) {
tokens = EvdevTokenize (s, " ");
if (!EvdevParseAbsOptions (pInfo, option, tokens, &abs->v_flags[i]))
xf86Msg (X_ERROR, "%s: Unable to parse '%s' as absolute options.\n", pInfo->name, s);
EvdevFreeTokens (tokens);
}
abs->v_flags[i] |= EV_ABS_V_PRESENT;
j++;
}
state->abs->axes = real_axes;
for (i = 0; i < ABS_MAX; i++) {
if (state->abs->map[i] > state->abs->axes)
state->abs->axes = state->abs->map[i];
return Success;
}
static int
EvdevAxisAbsNew1(InputInfoPtr pInfo)
{
evdevDevicePtr pEvdev = pInfo->private;
evdevStatePtr state = &pEvdev->state;
char *s;
if (!state->abs)
return !Success;
xf86Msg(X_CONFIG, "%s: Configuring %d absolute axes.\n", pInfo->name,
state->abs->axes);
{
int btn;
s = xf86SetStrOption(pInfo->options, "AbsoluteTouch", "DIGI_Touch");
btn = EvdevBtnFind (pInfo, s);
if (btn != -1) {
if (EvdevBtnExists (pInfo, btn)) {
state->abs->flags |= EV_ABS_USE_TOUCH;
xf86Msg(X_ERROR, "%s: Button: %d.\n", pInfo->name, btn);
xf86Msg(X_ERROR, "%s: state->btn: %p.\n", pInfo->name, state->btn);
state->btn->callback[btn] = &EvdevAxesTouchCallback;
} else {
xf86Msg(X_ERROR, "%s: AbsoluteTouch: '%s' does not exist.\n", pInfo->name, s);
}
} else {
xf86Msg(X_ERROR, "%s: AbsoluteTouch: '%s' is not a valid button name.\n", pInfo->name, s);
}
}
if (state->abs->axes != real_axes)
xf86Msg(X_CONFIG, "%s: Configuring %d absolute axes.\n", pInfo->name,
state->abs->axes);
s = xf86SetStrOption(pInfo->options, "Mode", "Absolute");
if (!strcasecmp(s, "Absolute")) {
state->mode = Absolute;
xf86Msg(X_CONFIG, "%s: Configuring in %s mode.\n", pInfo->name, s);
} else if (!strcasecmp(s, "Relative")) {
state->mode = Relative;
xf86Msg(X_CONFIG, "%s: Configuring in %s mode.\n", pInfo->name, s);
} else {
state->mode = Absolute;
xf86Msg(X_CONFIG, "%s: Unknown Mode: %s.\n", pInfo->name, s);
}
if (TestBit (ABS_X, pEvdev->bits.abs) && TestBit (ABS_Y, pEvdev->bits.abs))
k = xf86SetIntOption(pInfo->options, "AbsoluteScreen", 0);
else
k = xf86SetIntOption(pInfo->options, "AbsoluteScreen", -1);
if (k < screenInfo.numScreens) {
state->abs->screen = k;
xf86Msg(X_CONFIG, "%s: AbsoluteScreen: %d.\n", pInfo->name, k);
} else {
state->abs->screen = 0;
xf86Msg(X_CONFIG, "%s: AbsoluteScreen: %d is not a valid screen.\n", pInfo->name, k);
}
state->abs->scale[0] = screenInfo.screens[state->abs->screen]->width;
state->abs->scale[1] = screenInfo.screens[state->abs->screen]->height;
return Success;
}
@@ -412,18 +734,20 @@ EvdevAxisRelNew(InputInfoPtr pInfo)
{
evdevDevicePtr pEvdev = pInfo->private;
evdevStatePtr state = &pEvdev->state;
char *s, option[64];
int i, j, k = 0, real_axes;
evdevRelPtr rel;
char *s, option[128], value[128];
int i, j, real_axes;
evdev_option_token_t *tokens;
real_axes = 0;
for (i = 0; i < REL_MAX; i++)
if (TestBit (i, pEvdev->bits.rel))
if (test_bit (i, pEvdev->bits.rel))
real_axes++;
if (!real_axes && (!state->abs || state->abs->axes < 2))
return !Success;
state->rel = Xcalloc (sizeof (evdevRelRec));
state->rel = rel = Xcalloc (sizeof (evdevRelRec));
xf86Msg(X_INFO, "%s: Found %d relative axes.\n", pInfo->name,
real_axes);
@@ -434,58 +758,38 @@ EvdevAxisRelNew(InputInfoPtr pInfo)
pInfo->conversion_proc = EvdevConvert;
for (i = 0, j = 0; i < REL_MAX; i++) {
if (!TestBit (i, pEvdev->bits.rel))
if (!test_bit (i, pEvdev->bits.rel))
continue;
snprintf(option, sizeof(option), "%sRelativeAxisMap", rel_axis_names[i]);
s = xf86SetStrOption(pInfo->options, option, "0");
if (s && (k = strtol(s, NULL, 0)))
state->rel->map[i] = k;
else
state->rel->map[i] = j;
if (s && k)
xf86Msg(X_CONFIG, "%s: %s: %d.\n", pInfo->name, option, k);
snprintf(option, sizeof(option), "%sRelativeAxisButtons", rel_axis_names[i]);
snprintf(option, sizeof(option), "Rel%sMapTo", rel_axis_names[i]);
if (i == REL_WHEEL || i == REL_Z)
s = xf86SetStrOption(pInfo->options, option, "4 5");
snprintf(value, sizeof(value), "Buttons 4 5 1");
else if (i == REL_HWHEEL)
s = xf86SetStrOption(pInfo->options, option, "6 7");
snprintf(value, sizeof(value), "Buttons 6 7 1");
else
s = xf86SetStrOption(pInfo->options, option, "0 0");
snprintf(value, sizeof(value), "RelAxis %d", j);
k = state->rel->map[i];
EvdevParseMapOption (pInfo, option, value, &rel->v_map_data[i], &rel->v_map[i]);
if (!s || (sscanf(s, "%d %d", &state->axes->btnMap[k][0],
&state->axes->btnMap[k][1]) != 2))
state->axes->btnMap[k][0] = state->axes->btnMap[k][1] = 0;
snprintf(option, sizeof(option), "Rel%sOptions", rel_axis_names[i]);
s = xf86SetStrOption(pInfo->options, option, "");
if (s[0]) {
tokens = EvdevTokenize (s, " ");
if (!EvdevParseRelOptions (pInfo, option, tokens, &rel->v_flags[i]))
xf86Msg (X_ERROR, "%s: Unable to parse '%s' as relative options.\n", pInfo->name, s);
EvdevFreeTokens (tokens);
}
rel->v_flags[i] |= EV_REL_V_PRESENT;
if (state->axes->btnMap[k][0] || state->axes->btnMap[k][1])
xf86Msg(X_CONFIG, "%s: %s: %d %d.\n", pInfo->name, option,
state->axes->btnMap[k][0], state->axes->btnMap[k][1]);
j++;
}
state->rel->axes = real_axes;
for (i = 0; i < REL_MAX; i++)
if (state->rel->map[i] > state->rel->axes)
state->rel->axes = state->rel->map[i];
if (state->abs && (state->abs->axes >= 2) && (state->rel->axes < 2))
state->rel->axes = 2;
if (state->rel->axes != real_axes)
xf86Msg(X_CONFIG, "%s: Configuring %d relative axes.\n", pInfo->name,
state->rel->axes);
return Success;
}
int
EvdevAxesNew (InputInfoPtr pInfo)
EvdevAxesNew0 (InputInfoPtr pInfo)
{
evdevDevicePtr pEvdev = pInfo->private;
evdevStatePtr state = &pEvdev->state;
@@ -504,6 +808,31 @@ EvdevAxesNew (InputInfoPtr pInfo)
return ret;
}
int
EvdevAxesNew1 (InputInfoPtr pInfo)
{
evdevDeviceRec *pEvdev = pInfo->private;
evdevStateRec *state = &pEvdev->state;
evdevAxesRec *axes = state->axes;
int i, ret = Success;
if (!state->axes)
return ret;
for (i = 0; i < AXES_MAX; i++)
if (axes->v_flags[i] & EV_AXES_V_PRESENT)
axes->axes = i + 1;
if (EvdevAxisAbsNew1(pInfo) != Success)
ret = !Success;
if (!state->abs && !state->rel) {
Xfree (state->axes);
state->axes = NULL;
}
return ret;
}
static void
EvdevPtrCtrlProc(DeviceIntPtr device, PtrCtrl *ctrl)
@@ -517,35 +846,85 @@ EvdevAxesInit (DeviceIntPtr device)
InputInfoPtr pInfo = device->public.devicePrivate;
evdevDevicePtr pEvdev = pInfo->private;
evdevStatePtr state = &pEvdev->state;
int i, axes = 0;
evdevAxesRec *axes = state->axes;
AbsoluteClassRec *dev_abs;
int i;
const char *s;
if (state->abs && state->abs->axes > axes)
axes = state->abs->axes;
if (state->rel && state->rel->axes > axes)
axes = state->rel->axes;
state->axes->axes = axes;
xf86Msg(X_CONFIG, "%s: %d valuators.\n", pInfo->name,
axes);
if (!axes)
if (!axes || !axes->axes)
return Success;
if (!InitValuatorClassDeviceStruct(device, axes,
miPointerGetMotionEvents,
miPointerGetMotionBufferSize(), 0))
xf86Msg(X_CONFIG, "%s: %d valuators.\n", pInfo->name,
axes->axes);
if (!InitValuatorClassDeviceStruct(device, axes->axes,
GetMotionHistory,
GetMotionHistorySize(),
0))
return !Success;
for (i = 0; i < axes; i++) {
xf86InitValuatorAxisStruct(device, i, 0, 0, 0, 0, 1);
/*
* This has to go in Init, because until now there is no valuator struct
* allocated.
*/
s = xf86SetStrOption(pInfo->options, "Mode", "Absolute");
if (!strcasecmp(s, "Absolute")) {
pInfo->dev->valuator->mode = Absolute;
xf86Msg(X_CONFIG, "%s: Configuring in %s mode.\n", pInfo->name, s);
} else if (!strcasecmp(s, "Relative")) {
pInfo->dev->valuator->mode = Relative;
xf86Msg(X_CONFIG, "%s: Configuring in %s mode.\n", pInfo->name, s);
} else {
pInfo->dev->valuator->mode = Absolute;
xf86Msg(X_CONFIG, "%s: Unknown Mode: %s.\n", pInfo->name, s);
}
/*
* Yes, we want to do this for relative devices too.
* Some of the settings are useful for both.
*/
if ((axes->v_flags[0] & EV_AXES_V_PRESENT) &&
(axes->v_flags[1] & EV_AXES_V_PRESENT) &&
InitAbsoluteClassDeviceStruct (device)) {
dev_abs = device->absolute;
if (axes->v_min[0] != axes->v_max[1] && axes->v_min[1] != axes->v_max[1]) {
device->absolute->min_x = axes->v_min[0];
device->absolute->max_x = axes->v_max[0];
device->absolute->min_y = axes->v_min[1];
device->absolute->max_y = axes->v_max[1];
}
}
for (i = 0; i < axes->axes; i++) {
xf86InitValuatorAxisStruct(device, i, -1, -1, 1, 1, 1);
xf86InitValuatorDefaults(device, i);
}
if (!InitPtrFeedbackClassDeviceStruct(device, EvdevPtrCtrlProc))
return !Success;
xf86MotionHistoryAllocate (pInfo);
return Success;
}
static void
EvdevAxesTouchCallback (InputInfoPtr pInfo, int button, int value)
{
evdevDevicePtr pEvdev = pInfo->private;
evdevStatePtr state = &pEvdev->state;
int i;
#if DEBUG
xf86Msg(X_INFO, "%s: Touch callback; %d.\n", pInfo->name, value);
#endif
if (state->abs->flags & EV_ABS_USE_TOUCH) {
if (value) {
state->abs->flags |= EV_ABS_TOUCH;
for (i = 0; i < ABS_MAX; i++)
if (state->abs->v_flags[i] & EV_ABS_V_USE_TOUCH)
state->abs->v_flags[i] |= EV_ABS_V_RESET;
} else
state->abs->flags &= ~EV_ABS_TOUCH;
}
}

View File

@@ -1,487 +0,0 @@
/*
* Copyright © 2006 Zephaniah E. Hull
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Soft-
* ware"), to deal in the Software without restriction, including without
* limitation the rights to use, copy, modify, merge, publish, distribute,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, provided that the above copyright
* notice(s) and this permission notice appear in all copies of the Soft-
* ware and that both the above copyright notice(s) and this permission
* notice appear in supporting documentation.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
* ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
* RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN
* THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE-
* QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR-
* MANCE OF THIS SOFTWARE.
*
* Except as contained in this notice, the name of a copyright holder shall
* not be used in advertising or otherwise to promote the sale, use or
* other dealings in this Software without prior written authorization of
* the copyright holder.
*
* Author: Zephaniah E. Hull (warp@aehallh.com)
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "evdev.h"
#include "xf86_OSlib.h"
#include <xf86.h>
#include <fnmatch.h>
#include <sys/poll.h>
#include "inotify.h"
#include "inotify-syscalls.h"
#ifndef SYSCALL
#define SYSCALL(call) while(((call) == -1) && (errno == EINTR))
#endif
static Bool evdev_alive = FALSE;
static InputInfoPtr evdev_pInfo = NULL;
static evdevDriverPtr evdev_drivers = NULL;
static int evdev_seq;
static int evdev_inotify;
int
evdevGetFDForDevice (evdevDevicePtr device)
{
int fd;
if (!device)
return -1;
if (device->device) {
SYSCALL(fd = open (device->device, O_RDWR | O_NONBLOCK));
if (fd == -1)
xf86Msg(X_ERROR, "%s (%d): Open failed: %s\n", __FILE__, __LINE__, strerror(errno));
return fd;
} else
return -1;
}
#define device_add(driver,device) do { \
device->next = driver->devices; \
driver->devices = device; \
} while (0)
typedef struct {
evdevBitsRec bits;
char name[256];
char phys[256];
char dev[256];
struct input_id id;
} evdevDevInfoRec, *evdevDevInfoPtr;
static Bool
MatchAll (long *dev, long *match, int len)
{
int i;
for (i = 0; i < len; i++)
if ((dev[i] & match[i]) != match[i])
return FALSE;
return TRUE;
}
static Bool
MatchNot (long *dev, long *match, int len)
{
int i;
for (i = 0; i < len; i++)
if ((dev[i] & match[i]))
return FALSE;
return TRUE;
}
static Bool
MatchAny (long *dev, long *match, int len)
{
int i, found = 0;
for (i = 0; i < len; i++)
if (match[i]) {
found = 1;
if ((dev[i] & match[i]))
return TRUE;
}
if (found)
return FALSE;
else
return TRUE;
}
static Bool
MatchDriver (evdevDriverPtr driver, evdevDevInfoPtr info)
{
if (driver->name && fnmatch(driver->name, info->name, 0))
return FALSE;
if (driver->phys && fnmatch(driver->phys, info->phys, 0))
return FALSE;
if (driver->device && fnmatch(driver->device, info->dev, 0))
return FALSE;
if (driver->id.bustype && driver->id.bustype != info->id.bustype)
return FALSE;
if (driver->id.vendor && driver->id.vendor != info->id.vendor)
return FALSE;
if (driver->id.product && driver->id.product != info->id.product)
return FALSE;
if (driver->id.version && driver->id.version != info->id.version)
return FALSE;
#define match(which) \
if (!MatchAll(info->bits.which, driver->all_bits.which, \
sizeof(driver->all_bits.which) / \
sizeof(driver->all_bits.which[0]))) \
return FALSE; \
if (!MatchNot(info->bits.which, driver->not_bits.which, \
sizeof(driver->not_bits.which) / \
sizeof(driver->not_bits.which[0]))) \
return FALSE; \
if (!MatchAny(info->bits.which, driver->any_bits.which, \
sizeof(driver->any_bits.which) / \
sizeof(driver->any_bits.which[0]))) \
return FALSE;
match(ev)
match(key)
match(rel)
match(abs)
match(msc)
match(led)
match(snd)
match(ff)
#undef match
return TRUE;
}
static Bool
MatchDevice (evdevDevicePtr device, evdevDevInfoPtr info)
{
int i, len;
if (device->id.bustype != info->id.bustype)
return FALSE;
if (device->id.vendor != info->id.vendor)
return FALSE;
if (device->id.product != info->id.product)
return FALSE;
if (device->id.version != info->id.version)
return FALSE;
if (strcmp(device->name, info->name))
return FALSE;
len = sizeof(info->bits.ev) / sizeof(info->bits.ev[0]);
for (i = 0; i < len; i++)
if (device->bits.ev[i] != info->bits.ev[i])
return FALSE;
return TRUE;
}
static Bool
evdevScanDevice (evdevDriverPtr driver, evdevDevInfoPtr info)
{
evdevDevicePtr device;
int found;
if (!MatchDriver (driver, info))
return FALSE;
found = 0;
for (device = driver->devices; device; device = device->next) {
if (MatchDevice (device, info)) {
if (device->seen != (evdev_seq - 1)) {
device->device = xstrdup(info->dev);
device->phys = xstrdup(info->phys);
device->callback(device->pInfo->dev, DEVICE_ON);
}
device->seen = evdev_seq;
return TRUE;
}
}
device = Xcalloc (sizeof (evdevDeviceRec));
device->device = xstrdup(info->dev);
device->name = xstrdup(info->name);
device->phys = xstrdup(info->phys);
device->id.bustype = info->id.bustype;
device->id.vendor = info->id.vendor;
device->id.product = info->id.product;
device->id.version = info->id.version;
device->seen = evdev_seq;
device_add(driver, device);
driver->callback(driver, device);
return TRUE;
}
static Bool
FillDevInfo (char *dev, evdevDevInfoPtr info)
{
int fd;
SYSCALL(fd = open (dev, O_RDWR | O_NONBLOCK));
if (fd == -1)
return FALSE;
if (ioctl(fd, EVIOCGNAME(sizeof(info->name)), info->name) == -1)
info->name[0] = '\0';
if (ioctl(fd, EVIOCGPHYS(sizeof(info->phys)), info->phys) == -1)
info->phys[0] = '\0';
if (ioctl(fd, EVIOCGID, &info->id) == -1) {
close (fd);
return FALSE;
}
if (!evdevGetBits (fd, &info->bits)) {
close (fd);
return FALSE;
}
strncpy (info->dev, dev, sizeof(info->dev));
close (fd);
return TRUE;
}
static void
evdevRescanDevices (InputInfoPtr pInfo)
{
char dev[20];
int i, j, found;
evdevDriverPtr driver;
evdevDevicePtr device;
evdevDevInfoRec info;
evdev_seq++;
xf86Msg(X_INFO, "%s: Rescanning devices (%d).\n", pInfo->name, evdev_seq);
for (i = 0; i < 32; i++) {
snprintf(dev, sizeof(dev), "/dev/input/event%d", i);
if (!FillDevInfo (dev, &info))
continue;
found = 0;
for (j = 0; j <= 3 && !found; j++) {
for (driver = evdev_drivers; driver && !found; driver = driver->next) {
if ((driver->pass == j) && (found = evdevScanDevice (driver, &info)))
break;
}
}
}
for (driver = evdev_drivers; driver; driver = driver->next)
for (device = driver->devices; device; device = device->next)
if (device->seen == (evdev_seq - 1)) {
device->callback(device->pInfo->dev, DEVICE_OFF);
if (device->device)
xfree(device->device);
device->device = NULL;
if (device->phys)
xfree(device->phys);
device->phys = NULL;
}
}
static void
evdevReadInput (InputInfoPtr pInfo)
{
int scan = 0, i, len;
char buf[4096];
struct inotify_event *event;
if (evdev_inotify) {
while ((len = read (pInfo->fd, buf, sizeof(buf))) >= 0) {
for (i = 0; i < len; i += sizeof (struct inotify_event) + event->len) {
event = (struct inotify_event *) &buf[i];
if (!event->len)
continue;
if (event->mask & IN_ISDIR)
continue;
if (strncmp("event", event->name, 5))
continue;
scan = 1;
}
}
if (scan)
evdevRescanDevices (pInfo);
} else {
/*
* XXX: Freezing the server for a moment is not really friendly.
* But we need to wait until udev has actually created the device.
*/
usleep (500000);
evdevRescanDevices (pInfo);
}
}
static int
evdevControl(DeviceIntPtr pPointer, int what)
{
InputInfoPtr pInfo;
int i, flags;
pInfo = pPointer->public.devicePrivate;
switch (what) {
case DEVICE_INIT:
pPointer->public.on = FALSE;
break;
case DEVICE_ON:
/*
* XXX: We do /proc/bus/usb/devices instead of /proc/bus/input/devices
* because the only hotplug input devices at the moment are USB...
* And because the latter is useless to poll/select against.
* FIXME: Get a patch in the kernel which fixes the latter.
*/
evdev_inotify = 1;
SYSCALL(pInfo->fd = inotify_init());
if (pInfo->fd < 0) {
xf86Msg(X_ERROR, "%s: Unable to initialize inotify, using fallback. (errno: %d)\n", pInfo->name, errno);
evdev_inotify = 0;
}
SYSCALL (i = inotify_add_watch (pInfo->fd, "/dev/input/", IN_CREATE | IN_DELETE));
if (i < 0) {
xf86Msg(X_ERROR, "%s: Unable to initialize inotify, using fallback. (errno: %d)\n", pInfo->name, errno);
evdev_inotify = 0;
SYSCALL (close (pInfo->fd));
pInfo->fd = -1;
}
if ((flags = fcntl(pInfo->fd, F_GETFL)) < 0) {
xf86Msg(X_ERROR, "%s: Unable to NONBLOCK inotify, using fallback. "
"(errno: %d)\n", pInfo->name, errno);
evdev_inotify = 0;
SYSCALL (close (pInfo->fd));
pInfo->fd = -1;
} else if (fcntl(pInfo->fd, F_SETFL, flags | O_NONBLOCK) < 0) {
xf86Msg(X_ERROR, "%s: Unable to NONBLOCK inotify, using fallback. "
"(errno: %d)\n", pInfo->name, errno);
evdev_inotify = 0;
SYSCALL (close (pInfo->fd));
pInfo->fd = -1;
}
if (!evdev_inotify) {
SYSCALL (pInfo->fd = open ("/proc/bus/usb/devices", O_RDONLY));
if (pInfo->fd < 0) {
xf86Msg(X_ERROR, "%s: cannot open /proc/bus/usb/devices.\n", pInfo->name);
return BadRequest;
}
}
xf86FlushInput(pInfo->fd);
AddEnabledDevice(pInfo->fd);
pPointer->public.on = TRUE;
evdevRescanDevices (pInfo);
break;
case DEVICE_OFF:
case DEVICE_CLOSE:
if (pInfo->fd != -1) {
RemoveEnabledDevice(pInfo->fd);
SYSCALL (close (pInfo->fd));
pInfo->fd = -1;
}
pPointer->public.on = FALSE;
break;
}
return Success;
}
Bool
evdevStart (InputDriverPtr drv)
{
InputInfoRec *pInfo;
if (evdev_alive)
return TRUE;
if (!(pInfo = xf86AllocateInput(drv, 0)))
return FALSE;
evdev_alive = TRUE;
pInfo->name = "evdev brain";
pInfo->type_name = "evdev brain";
pInfo->device_control = evdevControl;
pInfo->read_input = evdevReadInput;
pInfo->fd = -1;
pInfo->flags = XI86_CONFIGURED | XI86_OPEN_ON_INIT;
evdev_pInfo = pInfo;
return TRUE;
}
Bool
evdevNewDriver (evdevDriverPtr driver)
{
if (!evdev_alive)
return FALSE;
/* FIXME: Make this check valid given all the ways to look. */
#if 0
if (!(driver->name || driver->phys || driver->device))
return FALSE;
#endif
if (!driver->callback)
return FALSE;
driver->next = evdev_drivers;
evdev_drivers = driver;
evdevRescanDevices (evdev_pInfo);
driver->configured = TRUE;
return TRUE;
}
Bool
evdevGetBits (int fd, evdevBitsPtr bits)
{
#define get_bitmask(fd, which, where) \
if (ioctl(fd, EVIOCGBIT(which, sizeof (where)), where) < 0) { \
xf86Msg(X_ERROR, "ioctl EVIOCGBIT %s failed: %s\n", #which, strerror(errno)); \
return FALSE; \
}
get_bitmask (fd, 0, bits->ev);
get_bitmask (fd, EV_KEY, bits->key);
get_bitmask (fd, EV_REL, bits->rel);
get_bitmask (fd, EV_ABS, bits->abs);
get_bitmask (fd, EV_MSC, bits->msc);
get_bitmask (fd, EV_LED, bits->led);
get_bitmask (fd, EV_SND, bits->snd);
get_bitmask (fd, EV_FF, bits->ff);
#undef get_bitmask
return TRUE;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright © 2006 Zephaniah E. Hull
* Copyright © 2006-2007 Zephaniah E. Hull
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Soft-
@@ -51,17 +51,107 @@
#include <xf86Module.h>
#define ArrayLength(a) (sizeof(a) / (sizeof((a)[0])))
#define BITS_PER_LONG (sizeof(long) * 8)
#define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1)
#define OFF(x) ((x)%BITS_PER_LONG)
#define LONG(x) ((x)/BITS_PER_LONG)
#define TestBit(bit, array) ((array[LONG(bit)] >> OFF(bit)) & 1)
static char *button_names[] = {
"MISC_0",
"MISC_1",
"MISC_2",
"MISC_3",
"MISC_4",
"MISC_5",
"MISC_6",
"MISC_7",
"MISC_8",
"MISC_9",
"MISC_10",
"MISC_11",
"MISC_12",
"MISC_13",
"MISC_14",
"MISC_15",
"MOUSE_LEFT",
"MOUSE_RIGHT",
"MOUSE_MIDDLE",
"MOUSE_SIDE",
"MOUSE_EXTRA",
"MOUSE_FORWARD",
"MOUSE_BACK",
"MOUSE_TASK",
"MOUSE_8",
"MOUSE_9",
"MOUSE_10",
"MOUSE_12",
"MOUSE_13",
"MOUSE_14",
"MOUSE_15",
"JOY_TRIGGER",
"JOY_THUMB",
"JOY_THUMB2",
"JOY_TOP",
"JOY_TOP2",
"JOY_PINKIE",
"JOY_BASE",
"JOY_BASE2",
"JOY_BASE3",
"JOY_BASE4",
"JOY_BASE5",
"JOY_BASE6",
"JOY_12",
"JOY_13",
"JOY_14",
"JOY_DEAD",
"GAME_A",
"GAME_B",
"GAME_C",
"GAME_X",
"GAME_Y",
"GAME_Z",
"GAME_TL",
"GAME_TR",
"GAME_TL2",
"GAME_TR2",
"GAME_SELECT",
"GAME_START",
"GAME_MODE",
"GAME_THUMBL",
"GAME_THUMBR",
"GAME_15",
"DIGI_TOOL_PEN",
"DIGI_TOOL_RUBBER",
"DIGI_TOOL_BRUSH",
"DIGI_TOOL_PENCIL",
"DIGI_TOOL_AIRBRUSH",
"DIGI_TOOL_FINGER",
"DIGI_TOOL_MOUSE",
"DIGI_TOOL_LENS",
"DIGI_8",
"DIGI_9",
"DIGI_TOUCH",
"DIGI_STYLUS",
"DIGI_STYLUS2",
"DIGI_TOOL_DOUBLETAP",
"DIGI_TOOL_TRIPLETAP",
"DIGI_15",
"WHEEL_GEAR_UP",
"WHEEL_GEAR_DOWN",
"WHEEL_2",
"WHEEL_3",
"WHEEL_4",
"WHEEL_5",
"WHEEL_6",
"WHEEL_7",
"WHEEL_8",
"WHEEL_9",
"WHEEL_10",
"WHEEL_11",
"WHEEL_12",
"WHEEL_13",
"WHEEL_14",
"WHEEL_15",
NULL
};
void
EvdevBtnPostFakeClicks(InputInfoPtr pInfo, int button, int count)
EvdevBtnPostFakeClicks(InputInfoRec *pInfo, int button, int count)
{
int i;
@@ -71,11 +161,140 @@ EvdevBtnPostFakeClicks(InputInfoPtr pInfo, int button, int count)
}
}
int
EvdevBtnInit (DeviceIntPtr device)
static void
EvdevMapButton (InputInfoRec *pInfo, int value, int mode, void *map_data)
{
InputInfoPtr pInfo = device->public.devicePrivate;
evdevDevicePtr pEvdev = pInfo->private;
long button = (long) map_data;
xf86PostButtonEvent (pInfo->dev, 0, button, value, 0, 0);
}
Bool
EvdevParseMapToButton (InputInfoRec *pInfo,
const char *name,
evdev_option_token_t *option,
void **map_data, evdev_map_func_f *map_func)
{
evdevDeviceRec *pEvdev = pInfo->private;
evdevStateRec *state = &pEvdev->state;
evdevBtnRec *btn = state->btn;
int button;
errno = 0;
button = strtol (option->str, NULL, 0);
if (errno)
button = EvdevBtnFind (pInfo, option->str);
if ((button < 0) || (button > BTN_MAX)) {
xf86Msg (X_ERROR, "%s: %s: Button %d out of range.\n", pInfo->name, name, button);
return 0;
}
if (btn->b_flags[button] & EV_BTN_B_PRESENT) {
xf86Msg (X_ERROR, "%s: %s: Button %d already claimed.\n", pInfo->name, name, button);
return 0;
}
btn->b_flags[button] = EV_BTN_B_PRESENT;
*map_data = (void *) button;
*map_func = EvdevMapButton;
return 1;
}
typedef struct {
int button_plus;
int button_minus;
int step;
int count;
} MapButtons_t;
static void
EvdevMapButtons (InputInfoRec *pInfo, int value, int mode, void *map_data)
{
MapButtons_t *map = map_data;
int i;
if (!map)
return;
map->count += value;
i = map->count / map->step;
if (i) {
map->count -= i * map->step;
if (i > 0)
EvdevBtnPostFakeClicks (pInfo, map->button_plus, i);
else
EvdevBtnPostFakeClicks (pInfo, map->button_minus, -i);
}
}
Bool
EvdevParseMapToButtons (InputInfoRec *pInfo,
const char *name,
evdev_option_token_t *option,
void **map_data, evdev_map_func_f *map_func)
{
evdevDeviceRec *pEvdev = pInfo->private;
evdevStateRec *state = &pEvdev->state;
evdevBtnRec *btn = state->btn;
int btn_plus, btn_minus;
MapButtons_t *map;
errno = 0;
btn_plus = strtol (option->str, NULL, 0);
if (errno)
btn_plus = EvdevBtnFind (pInfo, option->str);
if ((btn_plus < 0) || (btn_plus > BTN_MAX)) {
xf86Msg (X_ERROR, "%s: %s: Button %d out of range.\n", pInfo->name, name, btn_plus);
return 0;
}
if (btn->b_flags[btn_plus] & EV_BTN_B_PRESENT) {
xf86Msg (X_ERROR, "%s: %s: Button %d already claimed.\n", pInfo->name, name, btn_plus);
return 0;
}
option = option->next;
if (!option) {
xf86Msg (X_ERROR, "%s: %s: No button minus.\n", pInfo->name, name);
return 0;
}
errno = 0;
btn_minus = strtol (option->str, NULL, 0);
if (errno)
btn_minus = EvdevBtnFind (pInfo, option->str);
if ((btn_minus < 0) || (btn_minus > BTN_MAX)) {
xf86Msg (X_ERROR, "%s: %s: Button %d out of range.\n", pInfo->name, name, btn_minus);
return 0;
}
if (btn->b_flags[btn_minus] & EV_BTN_B_PRESENT) {
xf86Msg (X_ERROR, "%s: %s: Button %d already claimed.\n", pInfo->name, name, btn_minus);
return 0;
}
errno = 0;
btn->b_flags[btn_plus] = EV_BTN_B_PRESENT;
btn->b_flags[btn_minus] = EV_BTN_B_PRESENT;
map = calloc(1, sizeof (MapButtons_t));
map->button_plus = btn_plus;
map->button_minus = btn_minus;
map->step = 1;
*map_data = (void *) map;
*map_func = EvdevMapButtons;
return 1;
}
int
EvdevBtnInit (DeviceIntRec *device)
{
InputInfoRec *pInfo = device->public.devicePrivate;
evdevDeviceRec *pEvdev = pInfo->private;
CARD8 *map;
int i;
@@ -87,7 +306,7 @@ EvdevBtnInit (DeviceIntPtr device)
for (i = 0; i <= pEvdev->state.btn->buttons; i++)
map[i] = i;
xf86Msg(X_CONFIG, "%s (%d): Registering %d buttons.\n", __FILE__, __LINE__,
xf86Msg(X_CONFIG, "%s: Registering %d buttons.\n", pInfo->name,
pEvdev->state.btn->buttons);
if (!InitButtonClassDeviceStruct (device, pEvdev->state.btn->buttons, map)) {
pEvdev->state.btn->buttons = 0;
@@ -101,10 +320,10 @@ EvdevBtnInit (DeviceIntPtr device)
}
int
EvdevBtnOn (DeviceIntPtr device)
EvdevBtnOn (DeviceIntRec *device)
{
InputInfoPtr pInfo = device->public.devicePrivate;
evdevDevicePtr pEvdev = pInfo->private;
InputInfoRec *pInfo = device->public.devicePrivate;
evdevDeviceRec *pEvdev = pInfo->private;
int i, blocked;
if (!pEvdev->state.btn)
@@ -119,91 +338,82 @@ EvdevBtnOn (DeviceIntPtr device)
}
int
EvdevBtnOff (DeviceIntPtr device)
EvdevBtnOff (DeviceIntRec *device)
{
return Success;
}
/*
* Warning, evil lives here.
*/
static void
EvdevBtnCalcRemap (InputInfoPtr pInfo)
{
evdevDevicePtr pEvdev = pInfo->private;
evdevStatePtr state = &pEvdev->state;
int i, j, base, clear, fake;
for (i = 0, base = 1, fake = 0; i < pEvdev->state.btn->real_buttons; i++) {
if (state->rel) {
do {
clear = 1;
for (j = 0; j < REL_MAX; j++) {
if (state->axes->btnMap[j][0] == (i + base)) {
base++;
clear = 0;
break;
}
if (state->axes->btnMap[j][1] == (i + base)) {
base++;
clear = 0;
break;
}
}
} while (!clear);
}
if (!fake && base != 1)
fake = i;
state->btn->buttons = state->btn->map[i] = i + base;
}
if (state->btn->real_buttons >= 3 && (!fake || fake >= 3)) {
base = state->btn->map[1];
state->btn->map[1] = state->btn->map[2];
state->btn->map[2] = base;
}
if (state->rel) {
for (i = 0; i < REL_MAX; i++) {
if (state->axes->btnMap[i][0] > state->btn->buttons)
state->btn->buttons = state->axes->btnMap[i][0];
if (state->axes->btnMap[i][1] > state->btn->buttons)
state->btn->buttons = state->axes->btnMap[i][1];
}
}
}
int
EvdevBtnNew(InputInfoPtr pInfo)
EvdevBtnNew0(InputInfoRec *pInfo)
{
evdevDevicePtr pEvdev = pInfo->private;
evdevStatePtr state = &pEvdev->state;
int i, bit;
evdevDeviceRec *pEvdev = pInfo->private;
evdevStateRec *state = &pEvdev->state;
state->btn = Xcalloc (sizeof (evdevBtnRec));
for (i = BTN_MISC; i < (KEY_OK - 1); i++)
if (TestBit (i, pEvdev->bits.key)) {
bit = i;
if ((bit >= BTN_MOUSE) && (bit < BTN_JOYSTICK)) {
bit -= BTN_MOUSE - BTN_MISC;
} else if ((bit >= BTN_MISC) && (bit < BTN_MOUSE)) {
bit += BTN_MOUSE - BTN_MISC;
}
bit -= BTN_MISC;
state->btn->real_buttons = bit + 1;
return Success;
}
int
EvdevBtnNew1(InputInfoRec *pInfo)
{
evdevDeviceRec *pEvdev = pInfo->private;
evdevStateRec *state = &pEvdev->state;
evdevBtnRec *btn = state->btn;
char option[128], value[128];
int i, b, j, target;
if (!btn)
return !Success;
for (i = 0; i < BTN_MAX; i++) {
b = i + BTN_MISC;
if (!test_bit (b, pEvdev->bits.key))
continue;
btn->real_buttons++;
snprintf(option, sizeof(option), "Button%sMapTo", button_names[i]);
if (b >= BTN_DIGI && b < BTN_WHEEL)
target = -1;
else if (b == BTN_RIGHT)
target = 3;
else if (b == BTN_MIDDLE)
target = 2;
else if (b >= BTN_MOUSE && b < BTN_JOYSTICK)
target = 1 + i - (BTN_MOUSE - BTN_MISC);
else if (b >= BTN_MISC && b < BTN_MOUSE)
target = 1 + i + (BTN_MOUSE - BTN_MISC);
else
target = 1 + i;
if (btn->b_flags[target] & EV_BTN_B_PRESENT) {
for (j = target; j < BTN_MAX; j++)
if (!(btn->b_flags[j] & EV_BTN_B_PRESENT)) {
target = j;
break;
}
}
if (target > 0)
snprintf (value, sizeof (value), "Button %d", target);
else
snprintf (value, sizeof (value), "null");
EvdevParseMapOption (pInfo, option, value, &btn->b_map_data[i], &btn->b_map[i]);
}
if (state->btn->real_buttons)
xf86Msg(X_INFO, "%s: Found %d mouse buttons\n", pInfo->name, state->btn->real_buttons);
EvdevBtnCalcRemap (pInfo);
for (i = 0; i < BTN_MAX; i++)
if (btn->b_flags[i] & EV_BTN_B_PRESENT)
btn->buttons = i + 1;
if (state->btn->buttons)
xf86Msg(X_INFO, "%s: Configured %d mouse buttons\n", pInfo->name, state->btn->buttons);
xf86Msg(X_INFO, "%s: Configured %d mouse buttons.\n", pInfo->name, state->btn->buttons);
else {
Xfree (state->btn);
state->btn = NULL;
@@ -221,26 +431,47 @@ EvdevBtnNew(InputInfoPtr pInfo)
}
void
EvdevBtnProcess (InputInfoPtr pInfo, struct input_event *ev)
EvdevBtnProcess (InputInfoRec *pInfo, struct input_event *ev)
{
evdevDevicePtr pEvdev = pInfo->private;
evdevStatePtr state = &pEvdev->state;
evdevDeviceRec *pEvdev = pInfo->private;
evdevStateRec *state = &pEvdev->state;
int button;
if (!state->btn)
return;
button = ev->code - BTN_MISC;
button = ev->code;
if ((ev->code >= BTN_MOUSE) && (ev->code < BTN_JOYSTICK)) {
button -= BTN_MOUSE - BTN_MISC;
} else if ((ev->code >= BTN_MISC) && (ev->code < BTN_MOUSE)) {
button += BTN_MOUSE - BTN_MISC;
}
button -= BTN_MISC;
if (state->btn->state[button])
*state->btn->state[button] = ev->value;
if (state->btn->callback[button])
state->btn->callback[button](pInfo, button, ev->value);
button = state->btn->map[button];
xf86PostButtonEvent (pInfo->dev, 0, button, ev->value, 0, 0);
if (state->btn->b_map[button])
state->btn->b_map[button](pInfo, ev->value, -1, state->btn->b_map_data[button]);
}
int
EvdevBtnFind (InputInfoRec *pInfo, const char *button)
{
int i;
for (i = 0; button_names[i]; i++)
if (!strcasecmp(button, button_names[i]))
return i + 1;
return -1;
}
int
EvdevBtnExists (InputInfoRec *pInfo, int button)
{
evdevDeviceRec *pEvdev = pInfo->private;
xf86Msg(X_INFO, "%s: Checking button %s (%d)\n", pInfo->name, button_names[button], button);
button += BTN_MISC;
xf86Msg(X_INFO, "%s: Checking bit %d\n", pInfo->name, button);
return test_bit(button, pEvdev->bits.key);
}

View File

@@ -1,5 +1,6 @@
/*
* Copyright © 2006 Zephaniah E. Hull
* Copyright © 2006-2007 Zephaniah E. Hull
* Copyright © 2004 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Soft-
@@ -26,31 +27,9 @@
* other dealings in this Software without prior written authorization of
* the copyright holder.
*
* Author: Zephaniah E. Hull (warp@aehallh.com)
*/
/*
* Copyright © 2004 Red Hat, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
* appear in supporting documentation, and that the name of Red Hat
* not be used in advertising or publicity pertaining to distribution
* of the software without specific, written prior permission. Red
* Hat makes no representations about the suitability of this software
* for any purpose. It is provided "as is" without express or implied
* warranty.
*
* RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL RED HAT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: Kristian Høgsberg (krh@redhat.com)
* Authors:
* Zephaniah E. Hull (warp@aehallh.com),
* Kristian Høgsberg (krh@redhat.com)
*/
#ifdef HAVE_CONFIG_H
@@ -81,11 +60,6 @@
#define ArrayLength(a) (sizeof(a) / (sizeof((a)[0])))
#define BITS_PER_LONG (sizeof(long) * 8)
#define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1)
#define OFF(x) ((x)%BITS_PER_LONG)
#define LONG(x) ((x)/BITS_PER_LONG)
#define TestBit(bit, array) ((array[LONG(bit)] >> OFF(bit)) & 1)
#define MIN_KEYCODE 8
#define GLYPHS_PER_KEY 2
@@ -219,8 +193,7 @@ static KeySym map[] = {
/* 0x6d */ XK_Next, NoSymbol,
/* 0x6e */ XK_Insert, NoSymbol,
/* 0x6f */ XK_Delete, NoSymbol,
/* 0x6f */ NoSymbol, NoSymbol, /* KEY_MACRO */
/* 0x70 */ NoSymbol, NoSymbol,
/* 0x70 */ NoSymbol, NoSymbol, /* KEY_MACRO */
/* 0x71 */ NoSymbol, NoSymbol,
/* 0x72 */ NoSymbol, NoSymbol,
/* 0x73 */ NoSymbol, NoSymbol,
@@ -236,19 +209,128 @@ static KeySym map[] = {
/* 0x7d */ XK_Meta_L, NoSymbol,
/* 0x7e */ XK_Meta_R, NoSymbol,
/* 0x7f */ XK_Multi_key, NoSymbol,
/* 0x80 */ NoSymbol, NoSymbol,
/* 0x81 */ NoSymbol, NoSymbol,
/* 0x82 */ NoSymbol, NoSymbol,
/* 0x83 */ NoSymbol, NoSymbol,
/* 0x84 */ NoSymbol, NoSymbol,
/* 0x85 */ NoSymbol, NoSymbol,
/* 0x86 */ NoSymbol, NoSymbol,
/* 0x87 */ NoSymbol, NoSymbol,
/* 0x88 */ NoSymbol, NoSymbol,
/* 0x89 */ NoSymbol, NoSymbol,
/* 0x8a */ NoSymbol, NoSymbol,
/* 0x8b */ NoSymbol, NoSymbol,
/* 0x8c */ NoSymbol, NoSymbol,
/* 0x8d */ NoSymbol, NoSymbol,
/* 0x8e */ NoSymbol, NoSymbol,
/* 0x8f */ NoSymbol, NoSymbol,
/* 0x90 */ NoSymbol, NoSymbol,
/* 0x91 */ NoSymbol, NoSymbol,
/* 0x92 */ NoSymbol, NoSymbol,
/* 0x93 */ NoSymbol, NoSymbol,
/* 0x94 */ NoSymbol, NoSymbol,
/* 0x95 */ NoSymbol, NoSymbol,
/* 0x96 */ NoSymbol, NoSymbol,
/* 0x97 */ NoSymbol, NoSymbol,
/* 0x98 */ NoSymbol, NoSymbol,
/* 0x99 */ NoSymbol, NoSymbol,
/* 0x9a */ NoSymbol, NoSymbol,
/* 0x9b */ NoSymbol, NoSymbol,
/* 0x9c */ NoSymbol, NoSymbol,
/* 0x9d */ NoSymbol, NoSymbol,
/* 0x9e */ NoSymbol, NoSymbol,
/* 0x9f */ NoSymbol, NoSymbol,
/* 0xa0 */ NoSymbol, NoSymbol,
/* 0xa1 */ NoSymbol, NoSymbol,
/* 0xa2 */ NoSymbol, NoSymbol,
/* 0xa3 */ NoSymbol, NoSymbol,
/* 0xa4 */ NoSymbol, NoSymbol,
/* 0xa5 */ NoSymbol, NoSymbol,
/* 0xa6 */ NoSymbol, NoSymbol,
/* 0xa7 */ NoSymbol, NoSymbol,
/* 0xa8 */ NoSymbol, NoSymbol,
/* 0xa9 */ NoSymbol, NoSymbol,
/* 0xaa */ NoSymbol, NoSymbol,
/* 0xab */ NoSymbol, NoSymbol,
/* 0xac */ NoSymbol, NoSymbol,
/* 0xad */ NoSymbol, NoSymbol,
/* 0xae */ NoSymbol, NoSymbol,
/* 0xaf */ NoSymbol, NoSymbol,
/* 0xb0 */ NoSymbol, NoSymbol,
/* 0xb1 */ NoSymbol, NoSymbol,
/* 0xb2 */ NoSymbol, NoSymbol,
/* 0xb3 */ NoSymbol, NoSymbol,
/* 0xb4 */ NoSymbol, NoSymbol,
/* 0xb5 */ NoSymbol, NoSymbol,
/* 0xb6 */ NoSymbol, NoSymbol,
/* 0xb7 */ NoSymbol, NoSymbol,
/* 0xb8 */ NoSymbol, NoSymbol,
/* 0xb9 */ NoSymbol, NoSymbol,
/* 0xba */ NoSymbol, NoSymbol,
/* 0xbb */ NoSymbol, NoSymbol,
/* 0xbc */ NoSymbol, NoSymbol,
/* 0xbd */ NoSymbol, NoSymbol,
/* 0xbe */ NoSymbol, NoSymbol,
/* 0xbf */ NoSymbol, NoSymbol,
/* 0xc0 */ NoSymbol, NoSymbol,
/* 0xc1 */ NoSymbol, NoSymbol,
/* 0xc2 */ NoSymbol, NoSymbol,
/* 0xc3 */ NoSymbol, NoSymbol,
/* 0xc4 */ NoSymbol, NoSymbol,
/* 0xc5 */ NoSymbol, NoSymbol,
/* 0xc6 */ NoSymbol, NoSymbol,
/* 0xc7 */ NoSymbol, NoSymbol,
/* 0xc8 */ NoSymbol, NoSymbol,
/* 0xc9 */ NoSymbol, NoSymbol,
/* 0xca */ NoSymbol, NoSymbol,
/* 0xcb */ NoSymbol, NoSymbol,
/* 0xcc */ NoSymbol, NoSymbol,
/* 0xcd */ NoSymbol, NoSymbol,
/* 0xce */ NoSymbol, NoSymbol,
/* 0xcf */ NoSymbol, NoSymbol,
/* 0xd0 */ NoSymbol, NoSymbol,
/* 0xd1 */ NoSymbol, NoSymbol,
/* 0xd2 */ NoSymbol, NoSymbol,
/* 0xd3 */ NoSymbol, NoSymbol,
/* 0xd4 */ NoSymbol, NoSymbol,
/* 0xd5 */ NoSymbol, NoSymbol,
/* 0xd6 */ NoSymbol, NoSymbol,
/* 0xd7 */ NoSymbol, NoSymbol,
/* 0xd8 */ NoSymbol, NoSymbol,
/* 0xd9 */ NoSymbol, NoSymbol,
/* 0xda */ NoSymbol, NoSymbol,
/* 0xdb */ NoSymbol, NoSymbol,
/* 0xdc */ NoSymbol, NoSymbol,
/* 0xdd */ NoSymbol, NoSymbol,
/* 0xde */ NoSymbol, NoSymbol,
/* 0xdf */ NoSymbol, NoSymbol,
/* 0xe0 */ NoSymbol, NoSymbol,
/* 0xe1 */ NoSymbol, NoSymbol,
/* 0xe2 */ NoSymbol, NoSymbol,
/* 0xe3 */ NoSymbol, NoSymbol,
/* 0xe4 */ NoSymbol, NoSymbol,
/* 0xe5 */ NoSymbol, NoSymbol,
/* 0xe6 */ NoSymbol, NoSymbol,
/* 0xe7 */ NoSymbol, NoSymbol,
/* 0xe8 */ NoSymbol, NoSymbol,
/* 0xe9 */ NoSymbol, NoSymbol,
/* 0xea */ NoSymbol, NoSymbol,
/* 0xeb */ NoSymbol, NoSymbol,
/* 0xec */ NoSymbol, NoSymbol,
/* 0xed */ NoSymbol, NoSymbol,
/* 0xee */ NoSymbol, NoSymbol,
/* 0xef */ NoSymbol, NoSymbol,
/* 0xf0 */ NoSymbol, NoSymbol,
/* 0xf1 */ NoSymbol, NoSymbol,
/* 0xf2 */ NoSymbol, NoSymbol,
/* 0xf3 */ NoSymbol, NoSymbol,
/* 0xf4 */ NoSymbol, NoSymbol,
/* 0xf5 */ NoSymbol, NoSymbol,
/* 0xf6 */ NoSymbol, NoSymbol,
/* 0xf7 */ NoSymbol, NoSymbol,
};
/*
* FIXME: We have no way of ringing the bell ourselves.
* So use the system bell for now.
*/
static void
EvdevKbdBell (int percent, DeviceIntPtr device, pointer ctrl, int unused)
{
xf86SoundKbdBell(percent, ((KeybdCtrl*) ctrl)->bell_pitch,
((KeybdCtrl*) ctrl)->bell_duration);
}
static void
EvdevKbdCtrl(DeviceIntPtr device, KeybdCtrl *ctrl)
{
@@ -269,8 +351,22 @@ EvdevKbdCtrl(DeviceIntPtr device, KeybdCtrl *ctrl)
ev[i].type = EV_LED;
ev[i].code = bits[i].code;
ev[i].value = (ctrl->leds & bits[i].xbit) > 0;
}
write(pInfo->fd, ev, sizeof(ev));
write(pInfo->fd, ev, sizeof ev);
if (device->key && device->key->xkbInfo && device->key->xkbInfo->desc
&& device->key->xkbInfo->desc->ctrls) {
XkbControlsRec *ctrls = device->key->xkbInfo->desc->ctrls;
ev[0].type = EV_REP;
ev[0].code = REP_DELAY;
ev[0].value = ctrls->repeat_delay;
ev[1].type = EV_REP;
ev[1].code = REP_PERIOD;
ev[1].value = ctrls->repeat_interval;
write(pInfo->fd, ev, sizeof(ev[0]) * 2);
}
}
@@ -328,7 +424,7 @@ EvdevKeyInit (DeviceIntPtr device)
state->key->xkb_options);
XkbInitKeyboardDeviceStruct (device, &state->key->xkbnames, &keySyms, modMap,
EvdevKbdBell, EvdevKbdCtrl);
NULL, EvdevKbdCtrl);
return Success;
}
@@ -355,17 +451,11 @@ EvdevKeyNew (InputInfoPtr pInfo)
evdevStatePtr state = &pEvdev->state;
int i, keys = 0;
for (i = 0; i <= KEY_UNKNOWN; i++)
if (TestBit (i, pEvdev->bits.key)) {
for (i = 0; i <= 0xF7; i++)
if (test_bit (i, pEvdev->bits.key)) {
keys = 1;
break;
}
if (!keys)
for (i = KEY_OK; i <= KEY_MAX; i++)
if (TestBit (i, pEvdev->bits.key)) {
keys = 1;
break;
}
if (!keys)
return !Success;
@@ -376,19 +466,22 @@ EvdevKeyNew (InputInfoPtr pInfo)
pInfo->flags |= XI86_KEYBOARD_CAPABLE | XI86_CONFIGURED;
SetXkbOption (pInfo, "XkbRules", __XKBDEFRULES__, &state->key->xkb_rules);
SetXkbOption (pInfo, "XkbModel", "evdev", &state->key->xkb_model);
SetXkbOption (pInfo, "XkbLayout", "us", &state->key->xkb_layout);
SetXkbOption (pInfo, "XkbVariant", NULL, &state->key->xkb_variant);
SetXkbOption (pInfo, "XkbOptions", NULL, &state->key->xkb_options);
/*
SetXkbOption (pInfo, "XkbKeycodes", NULL, &state->key->xkbnames.keycodes);
SetXkbOption (pInfo, "XkbTypes", NULL, &state->key->xkbnames.types);
SetXkbOption (pInfo, "XkbCompat", NULL, &state->key->xkbnames.compat);
SetXkbOption (pInfo, "XkbSymbols", NULL, &state->key->xkbnames.symbols);
SetXkbOption (pInfo, "XkbGeometry", NULL, &state->key->xkbnames.geometry);
*/
SetXkbOption (pInfo, "xkb_rules", NULL, &state->key->xkb_rules);
if (!state->key->xkb_rules)
SetXkbOption (pInfo, "XkbRules", __XKBDEFRULES__,
&state->key->xkb_rules);
SetXkbOption (pInfo, "xkb_model", NULL, &state->key->xkb_model);
if (!state->key->xkb_model)
SetXkbOption (pInfo, "XkbModel", "evdev", &state->key->xkb_model);
SetXkbOption (pInfo, "xkb_layout", NULL, &state->key->xkb_layout);
if (!state->key->xkb_layout)
SetXkbOption (pInfo, "XkbLayout", "us", &state->key->xkb_layout);
SetXkbOption (pInfo, "xkb_variant", NULL, &state->key->xkb_variant);
if (!state->key->xkb_variant)
SetXkbOption (pInfo, "XkbVariant", NULL, &state->key->xkb_variant);
SetXkbOption (pInfo, "xkb_options", NULL, &state->key->xkb_options);
if (!state->key->xkb_options)
SetXkbOption (pInfo, "XkbOptions", NULL, &state->key->xkb_options);
return Success;
}

View File

@@ -1,61 +0,0 @@
#ifndef _LINUX_INOTIFY_SYSCALLS_H
#define _LINUX_INOTIFY_SYSCALLS_H
#include <sys/syscall.h>
#if defined(__i386__)
# define __NR_inotify_init 291
# define __NR_inotify_add_watch 292
# define __NR_inotify_rm_watch 293
#elif defined(__x86_64__)
# define __NR_inotify_init 253
# define __NR_inotify_add_watch 254
# define __NR_inotify_rm_watch 255
#elif defined(__powerpc__) || defined(__powerpc64__)
# define __NR_inotify_init 275
# define __NR_inotify_add_watch 276
# define __NR_inotify_rm_watch 277
#elif defined (__ia64__)
# define __NR_inotify_init 1277
# define __NR_inotify_add_watch 1278
# define __NR_inotify_rm_watch 1279
#elif defined (__s390__)
# define __NR_inotify_init 284
# define __NR_inotify_add_watch 285
# define __NR_inotify_rm_watch 286
#elif defined (__alpha__)
# define __NR_inotify_init 444
# define __NR_inotify_add_watch 445
# define __NR_inotify_rm_watch 446
#elif defined (__sparc__) || defined (__sparc64__)
# define __NR_inotify_init 151
# define __NR_inotify_add_watch 152
# define __NR_inotify_rm_watch 156
#elif defined (__arm__)
# define __NR_inotify_init 316
# define __NR_inotify_add_watch 317
# define __NR_inotify_rm_watch 318
#elif defined (__sh__)
# define __NR_inotify_init 290
# define __NR_inotify_add_watch 291
# define __NR_inotify_rm_watch 292
#else
# error "Unsupported architecture!"
#endif
static inline int inotify_init (void)
{
return syscall (__NR_inotify_init);
}
static inline int inotify_add_watch (int fd, const char *name, __u32 mask)
{
return syscall (__NR_inotify_add_watch, fd, name, mask);
}
static inline int inotify_rm_watch (int fd, __u32 wd)
{
return syscall (__NR_inotify_rm_watch, fd, wd);
}
#endif /* _LINUX_INOTIFY_SYSCALLS_H */

View File

@@ -1,60 +0,0 @@
/*
* Inode based directory notification for Linux
*
* Copyright (C) 2005 John McCutchan
*/
#ifndef _LINUX_INOTIFY_H
#define _LINUX_INOTIFY_H
#include <linux/types.h>
/*
* struct inotify_event - structure read from the inotify device for each event
*
* When you are watching a directory, you will receive the filename for events
* such as IN_CREATE, IN_DELETE, IN_OPEN, IN_CLOSE, ..., relative to the wd.
*/
struct inotify_event {
__s32 wd; /* watch descriptor */
__u32 mask; /* watch mask */
__u32 cookie; /* cookie to synchronize two events */
__u32 len; /* length (including nulls) of name */
char name[0]; /* stub for possible name */
};
/* the following are legal, implemented events that user-space can watch for */
#define IN_ACCESS 0x00000001 /* File was accessed */
#define IN_MODIFY 0x00000002 /* File was modified */
#define IN_ATTRIB 0x00000004 /* Metadata changed */
#define IN_CLOSE_WRITE 0x00000008 /* Writtable file was closed */
#define IN_CLOSE_NOWRITE 0x00000010 /* Unwrittable file closed */
#define IN_OPEN 0x00000020 /* File was opened */
#define IN_MOVED_FROM 0x00000040 /* File was moved from X */
#define IN_MOVED_TO 0x00000080 /* File was moved to Y */
#define IN_CREATE 0x00000100 /* Subfile was created */
#define IN_DELETE 0x00000200 /* Subfile was deleted */
#define IN_DELETE_SELF 0x00000400 /* Self was deleted */
/* the following are legal events. they are sent as needed to any watch */
#define IN_UNMOUNT 0x00002000 /* Backing fs was unmounted */
#define IN_Q_OVERFLOW 0x00004000 /* Event queued overflowed */
#define IN_IGNORED 0x00008000 /* File was ignored */
/* helper events */
#define IN_CLOSE (IN_CLOSE_WRITE | IN_CLOSE_NOWRITE) /* close */
#define IN_MOVE (IN_MOVED_FROM | IN_MOVED_TO) /* moves */
/* special flags */
#define IN_ISDIR 0x40000000 /* event occurred against dir */
#define IN_ONESHOT 0x80000000 /* only send event once */
/*
* All of the events - we build the list by hand so that we can add flags in
* the future and not break backward compatibility. Apps will get only the
* events that they originally wanted. Be sure to add new events here!
*/
#define IN_ALL_EVENTS (IN_ACCESS | IN_MODIFY | IN_ATTRIB | IN_CLOSE_WRITE | \
IN_CLOSE_NOWRITE | IN_OPEN | IN_MOVED_FROM | \
IN_MOVED_TO | IN_DELETE | IN_CREATE | IN_DELETE_SELF)
#endif /* _LINUX_INOTIFY_H */