mirror of
https://github.com/X11Libre/xf86-input-evdev.git
synced 2026-04-14 11:44:16 +00:00
Compare commits
56 Commits
xf86-input
...
xf86-input
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fa15e90993 | ||
|
|
12a27693b9 | ||
|
|
1c40c7db18 | ||
|
|
e2be2ffa47 | ||
|
|
e86aab93c5 | ||
|
|
c69f4bd570 | ||
|
|
64677ecc76 | ||
|
|
08a09682f5 | ||
|
|
9c9a47210a | ||
|
|
2d2c4804f9 | ||
|
|
6b97bf7a4e | ||
|
|
5c6b3dd86f | ||
|
|
f15636ac52 | ||
|
|
276685fa1d | ||
|
|
27a86f8168 | ||
|
|
26dbf38041 | ||
|
|
294355842b | ||
|
|
9eb546e0e0 | ||
|
|
daf926081d | ||
|
|
c22c955c48 | ||
|
|
f87c44b90c | ||
|
|
23309b334c | ||
|
|
1716ec88bb | ||
|
|
246812bfbc | ||
|
|
a0ea7363f5 | ||
|
|
3c4a96fbd8 | ||
|
|
ba65c34068 | ||
|
|
9644a4afbf | ||
|
|
d37ba205bb | ||
|
|
9875e2f7f9 | ||
|
|
6db4a9fb84 | ||
|
|
a9e87f29cc | ||
|
|
b4a5a20476 | ||
|
|
24f9e67a8f | ||
|
|
d8d8f114ca | ||
|
|
ebb30a554f | ||
|
|
3d8bb262e4 | ||
|
|
987c6b1597 | ||
|
|
8155e49e76 | ||
|
|
e1fe72e7fe | ||
|
|
9f3be57929 | ||
|
|
5a5457e69c | ||
|
|
3fc70342aa | ||
|
|
1a8cea3dc4 | ||
|
|
ef01c2ef65 | ||
|
|
036b457c1b | ||
|
|
79eb7dcac8 | ||
|
|
d7f686bfa3 | ||
|
|
ec09e0d55d | ||
|
|
77cbbc20b6 | ||
|
|
63f7edf786 | ||
|
|
e468150448 | ||
|
|
7b91f9277a | ||
|
|
7defeb0aef | ||
|
|
1cb568c0a6 | ||
|
|
51d21a3694 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -22,3 +22,4 @@ ltmain.sh
|
||||
missing
|
||||
stamp-h1
|
||||
.*.swp
|
||||
*~
|
||||
|
||||
@@ -28,6 +28,6 @@ CLEANFILES=ChangeLog
|
||||
.PHONY: ChangeLog
|
||||
|
||||
ChangeLog:
|
||||
git-log > 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
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
AC_PREREQ(2.57)
|
||||
AC_INIT([xf86-input-evdev],
|
||||
1.1.3,
|
||||
1.2.0,
|
||||
[https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
|
||||
xf86-input-evdev)
|
||||
|
||||
|
||||
121
man/evdev.man
121
man/evdev.man
@@ -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
|
||||
@@ -317,6 +332,6 @@ enhance the keyboard behaviour. Default: not set.
|
||||
.SH AUTHORS
|
||||
Zephaniah E. Hull.
|
||||
.fi
|
||||
Kristian Høgsberg.
|
||||
Kristian H\(/ogsberg.
|
||||
.SH "SEE ALSO"
|
||||
__xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), xorgconfig(__appmansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__).
|
||||
|
||||
@@ -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
|
||||
|
||||
486
src/evdev.c
486
src/evdev.c
@@ -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
|
||||
@@ -67,16 +46,174 @@
|
||||
|
||||
#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)
|
||||
@@ -89,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;
|
||||
}
|
||||
|
||||
@@ -130,12 +267,6 @@ EvdevReadInput(InputInfoPtr pInfo)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
EvdevSigioReadInput (int fd, void *data)
|
||||
{
|
||||
EvdevReadInput ((InputInfoPtr) data);
|
||||
}
|
||||
|
||||
static int
|
||||
EvdevProc(DeviceIntPtr device, int what)
|
||||
{
|
||||
@@ -162,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;
|
||||
@@ -181,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;
|
||||
|
||||
@@ -233,15 +361,9 @@ EvdevSwitchMode (ClientPtr client, DeviceIntPtr device, int mode)
|
||||
case Absolute:
|
||||
case Relative:
|
||||
xf86Msg(X_INFO, "%s: Switching mode to %d.\n", pInfo->name, mode);
|
||||
if (state->abs)
|
||||
state->mode = mode;
|
||||
else
|
||||
if (!state->abs)
|
||||
return !Success;
|
||||
break;
|
||||
case SendCoreEvents:
|
||||
case DontSendCoreEvents:
|
||||
xf86XInputSetSendCoreEvents (pInfo, (mode == SendCoreEvents));
|
||||
break;
|
||||
default:
|
||||
return !Success;
|
||||
}
|
||||
@@ -249,68 +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 (maybe) still important. */
|
||||
EvdevAxesNew0 (pInfo);
|
||||
EvdevBtnNew0 (pInfo);
|
||||
EvdevAxesNew0 (pInfo);
|
||||
|
||||
EvdevAxesNew1 (pInfo);
|
||||
EvdevBtnNew1 (pInfo);
|
||||
|
||||
if (device->state.can_grab)
|
||||
if (pEvdev->state.can_grab)
|
||||
EvdevKeyNew (pInfo);
|
||||
|
||||
close (pInfo->fd);
|
||||
@@ -318,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, unsigned 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, unsigned long *all, unsigned long *not, unsigned 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 (unsigned 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)
|
||||
{
|
||||
@@ -483,7 +558,7 @@ static XF86ModuleVersionInfo EvdevVersionRec =
|
||||
MODINFOSTRING1,
|
||||
MODINFOSTRING2,
|
||||
XORG_VERSION_CURRENT,
|
||||
1, 1, 0,
|
||||
PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCHLEVEL,
|
||||
ABI_CLASS_XINPUT,
|
||||
ABI_XINPUT_VERSION,
|
||||
MOD_CLASS_XINPUT,
|
||||
@@ -496,4 +571,3 @@ _X_EXPORT XF86ModuleData evdevModuleData =
|
||||
EvdevPlug,
|
||||
EvdevUnplug
|
||||
};
|
||||
#endif /* XFree86LOADER */
|
||||
|
||||
242
src/evdev.h
242
src/evdev.h
@@ -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
|
||||
@@ -90,57 +69,29 @@
|
||||
#define clear_bit(bit, array) (array[LONG(bit)] &= ~MASK(bit))
|
||||
#endif
|
||||
|
||||
/* 2.4 compatibility */
|
||||
#ifndef EVIOCGSW
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#define EVIOCGSW(len) _IOC(_IOC_READ, 'E', 0x1b, len) /* get all switch states */
|
||||
|
||||
#define EV_SW 0x05
|
||||
#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>
|
||||
|
||||
/* XInput 1.4+ compatability. */
|
||||
#ifndef SendCoreEvents
|
||||
#define SendCoreEvents 59
|
||||
#define DontSendCoreEvents 60
|
||||
#endif
|
||||
/*
|
||||
* 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 {
|
||||
unsigned long ev[NBITS(EV_MAX)];
|
||||
@@ -153,39 +104,69 @@ typedef struct {
|
||||
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];
|
||||
void (*callback[EVDEV_MAXBUTTONS])(InputInfoPtr pInfo, int button, int value);
|
||||
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;
|
||||
|
||||
#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)
|
||||
|
||||
#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 old_x, old_y;
|
||||
int count;
|
||||
int min[ABS_MAX];
|
||||
int max[ABS_MAX];
|
||||
int map[ABS_MAX];
|
||||
int scale[2];
|
||||
int screen; /* Screen number for this device. */
|
||||
Bool use_touch;
|
||||
Bool touch;
|
||||
Bool reset_x, reset_y;
|
||||
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 axes;
|
||||
int flags;
|
||||
int v_flags[REL_MAX];
|
||||
int v[REL_MAX];
|
||||
int count;
|
||||
int map[REL_MAX];
|
||||
int btnMap[REL_MAX][2];
|
||||
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 v[ABS_MAX];
|
||||
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 {
|
||||
@@ -200,7 +181,6 @@ typedef struct {
|
||||
typedef struct _evdevState {
|
||||
Bool can_grab;
|
||||
Bool sync;
|
||||
int mode; /* Either Absolute or Relative. */
|
||||
|
||||
evdevBtnPtr btn;
|
||||
evdevAbsPtr abs;
|
||||
@@ -210,49 +190,13 @@ 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);
|
||||
@@ -279,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 */
|
||||
|
||||
838
src/evdev_axes.c
838
src/evdev_axes.c
File diff suppressed because it is too large
Load Diff
@@ -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 (unsigned long *dev, unsigned 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 (unsigned long *dev, unsigned long *match, int len)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
if ((dev[i] & match[i]))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
MatchAny (unsigned long *dev, unsigned 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;
|
||||
}
|
||||
|
||||
334
src/evdev_btn.c
334
src/evdev_btn.c
@@ -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-
|
||||
@@ -133,11 +133,25 @@ static char *button_names[] = {
|
||||
"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;
|
||||
|
||||
@@ -147,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;
|
||||
|
||||
@@ -163,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;
|
||||
@@ -177,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)
|
||||
@@ -195,103 +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->rel->btnMap[j][0] == (i + base)) {
|
||||
base++;
|
||||
clear = 0;
|
||||
break;
|
||||
}
|
||||
if (state->rel->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->rel->btnMap[i][0] > state->btn->buttons)
|
||||
state->btn->buttons = state->rel->btnMap[i][0];
|
||||
if (state->rel->btnMap[i][1] > state->btn->buttons)
|
||||
state->btn->buttons = state->rel->btnMap[i][1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
EvdevBtnNew0(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 (test_bit (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);
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
int
|
||||
EvdevBtnNew1(InputInfoPtr pInfo)
|
||||
{
|
||||
evdevDevicePtr pEvdev = pInfo->private;
|
||||
evdevStatePtr state = &pEvdev->state;
|
||||
|
||||
if (!state->btn)
|
||||
return !Success;
|
||||
|
||||
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;
|
||||
@@ -309,10 +431,10 @@ EvdevBtnNew1(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)
|
||||
@@ -320,23 +442,17 @@ EvdevBtnProcess (InputInfoPtr pInfo, struct input_event *ev)
|
||||
|
||||
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->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 (InputInfoPtr pInfo, const char *button)
|
||||
EvdevBtnFind (InputInfoRec *pInfo, const char *button)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -348,20 +464,14 @@ EvdevBtnFind (InputInfoPtr pInfo, const char *button)
|
||||
}
|
||||
|
||||
int
|
||||
EvdevBtnExists (InputInfoPtr pInfo, int button)
|
||||
EvdevBtnExists (InputInfoRec *pInfo, int button)
|
||||
{
|
||||
evdevDevicePtr pEvdev = pInfo->private;
|
||||
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 button %s (%d)\n", pInfo->name, button_names[button - BTN_MISC], button);
|
||||
|
||||
if ((button >= BTN_MOUSE) && (button < BTN_JOYSTICK)) {
|
||||
button -= BTN_MOUSE - BTN_MISC;
|
||||
} else if ((button >= BTN_MISC) && (button < BTN_MOUSE)) {
|
||||
button += BTN_MOUSE - BTN_MISC;
|
||||
}
|
||||
|
||||
xf86Msg(X_INFO, "%s: Checking bit %d\n", pInfo->name, button);
|
||||
return test_bit(button, pEvdev->bits.key);
|
||||
}
|
||||
|
||||
220
src/evdev_key.c
220
src/evdev_key.c
@@ -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
|
||||
@@ -214,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,
|
||||
@@ -231,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)
|
||||
{
|
||||
@@ -264,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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -323,7 +424,7 @@ EvdevKeyInit (DeviceIntPtr device)
|
||||
state->key->xkb_options);
|
||||
|
||||
XkbInitKeyboardDeviceStruct (device, &state->key->xkbnames, &keySyms, modMap,
|
||||
EvdevKbdBell, EvdevKbdCtrl);
|
||||
NULL, EvdevKbdCtrl);
|
||||
|
||||
return Success;
|
||||
}
|
||||
@@ -350,17 +451,11 @@ EvdevKeyNew (InputInfoPtr pInfo)
|
||||
evdevStatePtr state = &pEvdev->state;
|
||||
int i, keys = 0;
|
||||
|
||||
for (i = 0; i <= KEY_UNKNOWN; i++)
|
||||
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 (test_bit (i, pEvdev->bits.key)) {
|
||||
keys = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!keys)
|
||||
return !Success;
|
||||
@@ -371,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;
|
||||
}
|
||||
|
||||
@@ -1,83 +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
|
||||
#elif defined (__hppa__) || defined (__hppa64__)
|
||||
# define __NR_inotify_init 269
|
||||
# define __NR_inotify_add_watch 270
|
||||
# define __NR_inotify_rm_watch 271
|
||||
#elif defined (__mips__)
|
||||
# if _MIPS_SIM == _MIPS_SIM_ABI32
|
||||
# define __NR_inotify_init 4284
|
||||
# define __NR_inotify_add_watch 4285
|
||||
# define __NR_inotify_rm_watch 4286
|
||||
# elif _MIPS_SIM == _MIPS_SIM_NABI32
|
||||
# define __NR_inotify_init 6247
|
||||
# define __NR_inotify_add_watch 6248
|
||||
# define __NR_inotify_rm_watch 6249
|
||||
# elif _MIPS_SIM == _MIPS_SIM_ABI64
|
||||
# define __NR_inotify_init 5243
|
||||
# define __NR_inotify_add_watch 5244
|
||||
# define __NR_inotify_rm_watch 5245
|
||||
# endif
|
||||
#elif defined (__mc68000__)
|
||||
# define __NR_inotify_init 284
|
||||
# define __NR_inotify_add_watch 285
|
||||
# define __NR_inotify_rm_watch 286
|
||||
#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 */
|
||||
@@ -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 */
|
||||
Reference in New Issue
Block a user