mirror of
https://github.com/X11Libre/xf86-input-evdev.git
synced 2026-04-14 11:44:16 +00:00
Compare commits
52 Commits
tracking/x
...
xf86-input
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f48abf89e4 | ||
|
|
87819fe86b | ||
|
|
ffa1fbc770 | ||
|
|
40bb3c69ce | ||
|
|
675218cbf5 | ||
|
|
ad834abd57 | ||
|
|
3549c3e5f0 | ||
|
|
5def56d2f4 | ||
|
|
b907c23d00 | ||
|
|
6c975917f8 | ||
|
|
ac421e536c | ||
|
|
bd55c2f021 | ||
|
|
11d506dce6 | ||
|
|
a34a2cd347 | ||
|
|
78c00bd77f | ||
|
|
760f1c6bb1 | ||
|
|
2db04ba3c3 | ||
|
|
363d0bdb9f | ||
|
|
16a26a1eca | ||
|
|
b879ae7351 | ||
|
|
53566b7d4d | ||
|
|
29c2765fc3 | ||
|
|
7ef4e2c5e1 | ||
|
|
dd0eeacc24 | ||
|
|
67c0ea6c94 | ||
|
|
6bcbbc0411 | ||
|
|
534a3734d0 | ||
|
|
215c230d5c | ||
|
|
8f96530449 | ||
|
|
4fb97edcd4 | ||
|
|
4e86393bc0 | ||
|
|
a64a78791f | ||
|
|
09b2a5e87b | ||
|
|
fa18a4a38d | ||
|
|
172523d745 | ||
|
|
8fb820ffaf | ||
|
|
c7893b212d | ||
|
|
e9dd721e2d | ||
|
|
cab104fd9e | ||
|
|
708eb34599 | ||
|
|
36a687796f | ||
|
|
26229df106 | ||
|
|
f4616d87fc | ||
|
|
2aa5ca8cdd | ||
|
|
39263dc65d | ||
|
|
57521e4e60 | ||
|
|
7da1522309 | ||
|
|
b4fcb825fc | ||
|
|
7c955ad050 | ||
|
|
4f80c0f2cb | ||
|
|
5070d64aa8 | ||
|
|
caacacf057 |
20
README
Normal file
20
README
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
xf86-input-evdev - Generic Linux input driver for the Xorg X server
|
||||||
|
|
||||||
|
Please submit bugs & patches to the Xorg bugzilla:
|
||||||
|
|
||||||
|
https://bugs.freedesktop.org/enter_bug.cgi?product=xorg
|
||||||
|
|
||||||
|
All questions regarding this software should be directed at the
|
||||||
|
Xorg mailing list:
|
||||||
|
|
||||||
|
http://lists.freedesktop.org/mailman/listinfo/xorg
|
||||||
|
|
||||||
|
The master development code repository can be found at:
|
||||||
|
|
||||||
|
git://anongit.freedesktop.org/git/xorg/driver/xf86-input-evdev
|
||||||
|
|
||||||
|
http://cgit.freedesktop.org/xorg/driver/xf86-input-evdev
|
||||||
|
|
||||||
|
For more information on the git code manager, see:
|
||||||
|
|
||||||
|
http://wiki.x.org/wiki/GitPage
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
AC_PREREQ(2.57)
|
AC_PREREQ(2.57)
|
||||||
AC_INIT([xf86-input-evdev],
|
AC_INIT([xf86-input-evdev],
|
||||||
2.0.99,
|
2.1.3,
|
||||||
[https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
|
[https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
|
||||||
xf86-input-evdev)
|
xf86-input-evdev)
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
/* Middle mouse button emulation */
|
/* Middle mouse button emulation */
|
||||||
/* BOOL */
|
/* BOOL */
|
||||||
#define EVDEV_PROP_MIDBUTTON "Evdev Middle Button Emulation"
|
#define EVDEV_PROP_MIDBUTTON "Evdev Middle Button Emulation"
|
||||||
/* CARD16 */
|
/* CARD32 */
|
||||||
#define EVDEV_PROP_MIDBUTTON_TIMEOUT "Evdev Middle Button Timeout"
|
#define EVDEV_PROP_MIDBUTTON_TIMEOUT "Evdev Middle Button Timeout"
|
||||||
|
|
||||||
/* Wheel emulation */
|
/* Wheel emulation */
|
||||||
@@ -54,4 +54,16 @@
|
|||||||
/* BOOL, 2 values [x, y], 1 inverts axis */
|
/* BOOL, 2 values [x, y], 1 inverts axis */
|
||||||
#define EVDEV_PROP_INVERT_AXES "Evdev Axis Inversion"
|
#define EVDEV_PROP_INVERT_AXES "Evdev Axis Inversion"
|
||||||
|
|
||||||
|
/* Reopen attempts. */
|
||||||
|
/* CARD8 */
|
||||||
|
#define EVDEV_PROP_REOPEN "Evdev Reopen Attempts"
|
||||||
|
|
||||||
|
/* Run-time calibration */
|
||||||
|
/* CARD32, 4 values [minx, maxx, miny, maxy], or no values for unset */
|
||||||
|
#define EVDEV_PROP_CALIBRATION "Evdev Axis Calibration"
|
||||||
|
|
||||||
|
/* Swap x and y axis. */
|
||||||
|
/* BOOL */
|
||||||
|
#define EVDEV_PROP_SWAP_AXES "Evdev Axes Swap"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ evdev \- Generic Linux input driver
|
|||||||
.BI " Option \*qDevice\*q \*q" devpath \*q
|
.BI " Option \*qDevice\*q \*q" devpath \*q
|
||||||
.BI " Option \*qEmulate3Buttons\*q \*q" True \*q
|
.BI " Option \*qEmulate3Buttons\*q \*q" True \*q
|
||||||
.BI " Option \*qEmulate3Timeout\*q \*q" 50 \*q
|
.BI " Option \*qEmulate3Timeout\*q \*q" 50 \*q
|
||||||
|
.BI " Option \*qGrabDevice\*q \*q" False \*q
|
||||||
\ \ ...
|
\ \ ...
|
||||||
.B EndSection
|
.B EndSection
|
||||||
.fi
|
.fi
|
||||||
@@ -52,12 +53,12 @@ The mapping from device node to hardware is system-dependent.
|
|||||||
Enable/disable the emulation of the third (middle) mouse button for mice
|
Enable/disable the emulation of the third (middle) mouse button for mice
|
||||||
which only have two physical buttons. The third button is emulated by
|
which only have two physical buttons. The third button is emulated by
|
||||||
pressing both buttons simultaneously. Default: on, until a middle mouse
|
pressing both buttons simultaneously. Default: on, until a middle mouse
|
||||||
button event is registered.
|
button event is registered. Property: "Evdev Middle Button Emulation".
|
||||||
.TP 7
|
.TP 7
|
||||||
.BI "Option \*qEmulate3Timeout\*q \*q" integer \*q
|
.BI "Option \*qEmulate3Timeout\*q \*q" integer \*q
|
||||||
Sets the timeout (in milliseconds) that the driver waits before deciding
|
Sets the timeout (in milliseconds) that the driver waits before deciding
|
||||||
if two buttons where pressed "simultaneously" when 3 button emulation is
|
if two buttons where pressed "simultaneously" when 3 button emulation is
|
||||||
enabled. Default: 50.
|
enabled. Default: 50. Property: "Evdev Middle Button Timeout".
|
||||||
.TP 7
|
.TP 7
|
||||||
.BI "Option \*qButtonMapping\*q \*q" string \*q
|
.BI "Option \*qButtonMapping\*q \*q" string \*q
|
||||||
Sets the button mapping for this device. The mapping is a space-separated list
|
Sets the button mapping for this device. The mapping is a space-separated list
|
||||||
@@ -74,12 +75,13 @@ Sets \*qdrag lock buttons\*q that simulate holding a button down, so
|
|||||||
that low dexterity people do not have to hold a button down at the
|
that low dexterity people do not have to hold a button down at the
|
||||||
same time they move a mouse cursor. Button numbers occur in pairs,
|
same time they move a mouse cursor. Button numbers occur in pairs,
|
||||||
with the lock button number occurring first, followed by the button
|
with the lock button number occurring first, followed by the button
|
||||||
number that is the target of the lock button.
|
number that is the target of the lock button. Property: "Evdev
|
||||||
|
Drag Lock Buttons".
|
||||||
.TP 7
|
.TP 7
|
||||||
.BI "Option \*qDragLockButtons\*q \*q" "M1" \*q
|
.BI "Option \*qDragLockButtons\*q \*q" "M1" \*q
|
||||||
Sets a \*qmaster drag lock button\*q that acts as a \*qMeta Key\*q
|
Sets a \*qmaster drag lock button\*q that acts as a \*qMeta Key\*q
|
||||||
indicating that the next button pressed is to be
|
indicating that the next button pressed is to be
|
||||||
\*qdrag locked\*q.
|
\*qdrag locked\*q. Property: "Evdev Drag Lock Buttons".
|
||||||
.TP 7
|
.TP 7
|
||||||
.BI "Option \*qEmulateWheel\*q \*q" boolean \*q
|
.BI "Option \*qEmulateWheel\*q \*q" boolean \*q
|
||||||
Enable/disable "wheel" emulation. Wheel emulation means emulating button
|
Enable/disable "wheel" emulation. Wheel emulation means emulating button
|
||||||
@@ -94,7 +96,7 @@ more buttons but no wheel. See the description of the
|
|||||||
.BR XAxisMapping ,
|
.BR XAxisMapping ,
|
||||||
and
|
and
|
||||||
.B YAxisMapping
|
.B YAxisMapping
|
||||||
options below. Default: off.
|
options below. Default: off. Property "Evdev Wheel Emulation".
|
||||||
.TP 7
|
.TP 7
|
||||||
.BI "Option \*qEmulateWheelButton\*q \*q" integer \*q
|
.BI "Option \*qEmulateWheelButton\*q \*q" integer \*q
|
||||||
Specifies which button must be held down to enable wheel emulation mode.
|
Specifies which button must be held down to enable wheel emulation mode.
|
||||||
@@ -103,11 +105,12 @@ press/release events as specified for the
|
|||||||
.B XAxisMapping
|
.B XAxisMapping
|
||||||
and
|
and
|
||||||
.B YAxisMapping
|
.B YAxisMapping
|
||||||
settings. Default: 4.
|
settings. Default: 4. Property: "Evdev Wheel Emulation Button".
|
||||||
.TP 7
|
.TP 7
|
||||||
.BI "Option \*qEmulateWheelInertia\*q \*q" integer \*q
|
.BI "Option \*qEmulateWheelInertia\*q \*q" integer \*q
|
||||||
Specifies how far (in pixels) the pointer must move to generate button
|
Specifies how far (in pixels) the pointer must move to generate button
|
||||||
press/release events in wheel emulation mode. Default: 10.
|
press/release events in wheel emulation mode. Default: 10. Property: "Evdev
|
||||||
|
Wheel Emulation Inertia".
|
||||||
.TP 7
|
.TP 7
|
||||||
.BI "Option \*qEmulateWheelTimeout\*q \*q" integer \*q
|
.BI "Option \*qEmulateWheelTimeout\*q \*q" integer \*q
|
||||||
Specifies the time in milliseconds the
|
Specifies the time in milliseconds the
|
||||||
@@ -115,7 +118,7 @@ Specifies the time in milliseconds the
|
|||||||
must be pressed before wheel emulation is started. If the
|
must be pressed before wheel emulation is started. If the
|
||||||
.BR EmulateWheelButton
|
.BR EmulateWheelButton
|
||||||
is released before this timeout, the original button press/release event
|
is released before this timeout, the original button press/release event
|
||||||
is sent. Default: 200.
|
is sent. Default: 200. Property: "Evdev Wheel Emulation Timeout".
|
||||||
.TP 7
|
.TP 7
|
||||||
.BI "Option \*qXAxisMapping\*q \*q" "N1 N2" \*q
|
.BI "Option \*qXAxisMapping\*q \*q" "N1 N2" \*q
|
||||||
Specifies which buttons are mapped to motion in the X direction in wheel
|
Specifies which buttons are mapped to motion in the X direction in wheel
|
||||||
@@ -123,7 +126,8 @@ emulation mode. Button number
|
|||||||
.I N1
|
.I N1
|
||||||
is mapped to the negative X axis motion and button number
|
is mapped to the negative X axis motion and button number
|
||||||
.I N2
|
.I N2
|
||||||
is mapped to the positive X axis motion. Default: no mapping.
|
is mapped to the positive X axis motion. Default: no mapping. Property:
|
||||||
|
"Evdev Wheel Emulation Axes".
|
||||||
.TP 7
|
.TP 7
|
||||||
.BI "Option \*qYAxisMapping\*q \*q" "N1 N2" \*q
|
.BI "Option \*qYAxisMapping\*q \*q" "N1 N2" \*q
|
||||||
Specifies which buttons are mapped to motion in the Y direction in wheel
|
Specifies which buttons are mapped to motion in the Y direction in wheel
|
||||||
@@ -131,14 +135,72 @@ emulation mode. Button number
|
|||||||
.I N1
|
.I N1
|
||||||
is mapped to the negative Y axis motion and button number
|
is mapped to the negative Y axis motion and button number
|
||||||
.I N2
|
.I N2
|
||||||
is mapped to the positive Y axis motion. Default: "4 5"
|
is mapped to the positive Y axis motion. Default: "4 5". Property:
|
||||||
|
"Evdev Wheel Emulation Axes".
|
||||||
.TP 7
|
.TP 7
|
||||||
.BI "Option \*qReopenAttempts\*q \*q" integer \*q
|
.BI "Option \*qReopenAttempts\*q \*q" integer \*q
|
||||||
Number of reopen attempts after a read error occurs on the device (e.g. after
|
Number of reopen attempts after a read error occurs on the device (e.g. after
|
||||||
waking up from suspend). In between each attempt is a 100ms wait. Default: 10.
|
waking up from suspend). In between each attempt is a 100ms wait. Default: 10.
|
||||||
|
.TP 7
|
||||||
|
.BI "Option \*qInvertX\*q \*q" Bool \*q
|
||||||
|
.TP 7
|
||||||
|
.BI "Option \*qInvertY\*q \*q" Bool \*q
|
||||||
|
Invert the given axis. Default: off. Property: "Evdev Axis Inversion".
|
||||||
|
.TP 7
|
||||||
|
.BI "Option \*qSwapAxes\*q \*q" Bool \*q
|
||||||
|
Swap x/y axes. Default: off. Property: "Evdev Axes Swap".
|
||||||
|
.TP 7
|
||||||
|
.BI "Option \*qGrabDevice\*q \*q" boolean \*q
|
||||||
|
Force a grab on the event device. Doing so will ensure that no other driver
|
||||||
|
can initialise the same device and it will also stop the device from sending
|
||||||
|
events to /dev/kbd or /dev/input/mice. Events from this device will not be
|
||||||
|
sent to virtual devices (e.g. rfkill or the Macintosh mouse button emulation).
|
||||||
|
Default: disabled.
|
||||||
|
|
||||||
|
.SH SUPPORTED PROPERTIES
|
||||||
|
The following properties are provided by the
|
||||||
|
.B evdev
|
||||||
|
driver.
|
||||||
|
.TP 7
|
||||||
|
.BI "Evdev Middle Button Emulation"
|
||||||
|
1 boolean value (8 bit, 0 or 1).
|
||||||
|
.TP 7
|
||||||
|
.BI "Evdev Middle Button Timeout"
|
||||||
|
1 16-bit positive value.
|
||||||
|
.TP 7
|
||||||
|
.BI "Evdev Wheel Emulation"
|
||||||
|
1 boolean value (8 bit, 0 or 1).
|
||||||
|
.TP 7
|
||||||
|
.BI "Evdev Wheel Emulation Axes"
|
||||||
|
4 8-bit values, order X up, X down, Y up, Y down. 0 disables a value.
|
||||||
|
.TP 7
|
||||||
|
.BI "Evdev Wheel Emulation Inertia"
|
||||||
|
1 16-bit positive value.
|
||||||
|
.TP 7
|
||||||
|
.BI "Evdev Wheel Emulation Timeout"
|
||||||
|
1 16-bit positive value.
|
||||||
|
.TP 7
|
||||||
|
.BI "Evdev Wheel Emulation Button"
|
||||||
|
1 8-bit value, allowed range 0-32, 0 disables the button.
|
||||||
|
.TP 7
|
||||||
|
.BI "Evdev Drag Lock Buttons"
|
||||||
|
8-bit. Either 1 value or pairs of values. Value range 0-32, 0 disables a
|
||||||
|
value.
|
||||||
|
.TP 7
|
||||||
|
.BI "Evdev Axis Inversion"
|
||||||
|
2 boolean values (8 bit, 0 or 1), order X, Y. 1 inverts the axis.
|
||||||
|
.TP 7
|
||||||
|
.BI "Evdev Axis Calibration"
|
||||||
|
4 32-bit values, order min-x, max-x, min-y, max-y or 0 values to disable
|
||||||
|
run-time axis calibration. This feature is required for devices that need to
|
||||||
|
scale to a different coordinate system than originally reported to the X
|
||||||
|
server, such as touchscreens that require run-time calibration.
|
||||||
|
.TP 7
|
||||||
|
.BI "Evdev Axis Swap"
|
||||||
|
1 boolean value (8 bit, 0 or 1). 1 swaps x/y axes.
|
||||||
|
|
||||||
.SH AUTHORS
|
.SH AUTHORS
|
||||||
Kristian Høgsberg.
|
Kristian Høgsberg.
|
||||||
.SH "SEE ALSO"
|
.SH "SEE ALSO"
|
||||||
__xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), xorgconfig(__appmansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__),
|
__xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__),
|
||||||
README.mouse.
|
README.mouse.
|
||||||
|
|||||||
137
src/draglock.c
137
src/draglock.c
@@ -53,7 +53,7 @@ void EvdevDragLockLockButton(InputInfoPtr pInfo, unsigned int button);
|
|||||||
|
|
||||||
/* Setup and configuration code */
|
/* Setup and configuration code */
|
||||||
void
|
void
|
||||||
EvdevDragLockInit(InputInfoPtr pInfo)
|
EvdevDragLockPreInit(InputInfoPtr pInfo)
|
||||||
{
|
{
|
||||||
EvdevPtr pEvdev = (EvdevPtr)pInfo->private;
|
EvdevPtr pEvdev = (EvdevPtr)pInfo->private;
|
||||||
char *option_string = NULL;
|
char *option_string = NULL;
|
||||||
@@ -210,6 +210,74 @@ EvdevDragLockFilterEvent(InputInfoPtr pInfo, unsigned int button, int value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_PROPERTIES
|
#ifdef HAVE_PROPERTIES
|
||||||
|
/**
|
||||||
|
* Set the drag lock property.
|
||||||
|
* If only one value is supplied, then this is used as the meta button.
|
||||||
|
* If more than one value is supplied, then each value is the drag lock button
|
||||||
|
* for the pair. 0 disables a pair.
|
||||||
|
* i.e. to set bt 3 to draglock button 1, supply 0,0,1
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
EvdevDragLockSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
|
||||||
|
BOOL checkonly)
|
||||||
|
{
|
||||||
|
InputInfoPtr pInfo = dev->public.devicePrivate;
|
||||||
|
EvdevPtr pEvdev = pInfo->private;
|
||||||
|
|
||||||
|
if (atom == prop_dlock)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (val->format != 8 || val->type != XA_INTEGER)
|
||||||
|
return BadMatch;
|
||||||
|
|
||||||
|
/* Don't allow changes while a lock is active */
|
||||||
|
if (pEvdev->dragLock.meta)
|
||||||
|
{
|
||||||
|
if (pEvdev->dragLock.meta_state)
|
||||||
|
return BadAccess;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
for (i = 0; i < EVDEV_MAXBUTTONS; i++)
|
||||||
|
if (pEvdev->dragLock.lock_state[i])
|
||||||
|
return BadValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (val->size == 0)
|
||||||
|
return BadMatch;
|
||||||
|
else if (val->size == 1)
|
||||||
|
{
|
||||||
|
int meta = *((CARD8*)val->data);
|
||||||
|
if (meta > EVDEV_MAXBUTTONS)
|
||||||
|
return BadValue;
|
||||||
|
|
||||||
|
if (!checkonly)
|
||||||
|
{
|
||||||
|
pEvdev->dragLock.meta = meta;
|
||||||
|
memset(pEvdev->dragLock.lock_pair, 0, sizeof(pEvdev->dragLock.lock_pair));
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
CARD8* vals = (CARD8*)val->data;
|
||||||
|
|
||||||
|
for (i = 0; i < val->size && i < EVDEV_MAXBUTTONS; i++)
|
||||||
|
if (vals[i] > EVDEV_MAXBUTTONS)
|
||||||
|
return BadValue;
|
||||||
|
|
||||||
|
if (!checkonly)
|
||||||
|
{
|
||||||
|
pEvdev->dragLock.meta = 0;
|
||||||
|
memset(pEvdev->dragLock.lock_pair, 0, sizeof(pEvdev->dragLock.lock_pair));
|
||||||
|
|
||||||
|
for (i = 0; i < val->size && i < EVDEV_MAXBUTTONS; i++)
|
||||||
|
pEvdev->dragLock.lock_pair[i] = vals[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Success;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialise property for drag lock buttons setting.
|
* Initialise property for drag lock buttons setting.
|
||||||
*/
|
*/
|
||||||
@@ -246,72 +314,7 @@ EvdevDragLockInitProperty(DeviceIntPtr dev)
|
|||||||
|
|
||||||
XISetDevicePropertyDeletable(dev, prop_dlock, FALSE);
|
XISetDevicePropertyDeletable(dev, prop_dlock, FALSE);
|
||||||
|
|
||||||
return;
|
XIRegisterPropertyHandler(dev, EvdevDragLockSetProperty, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the drag lock property.
|
|
||||||
* If only one value is supplied, then this is used as the meta button.
|
|
||||||
* If more than one value is supplied, then each value is the drag lock button
|
|
||||||
* for the pair. 0 disables a pair.
|
|
||||||
* i.e. to set bt 3 to draglock button 1, supply 0,0,1
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
EvdevDragLockSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
|
|
||||||
BOOL checkonly)
|
|
||||||
{
|
|
||||||
InputInfoPtr pInfo = dev->public.devicePrivate;
|
|
||||||
EvdevPtr pEvdev = pInfo->private;
|
|
||||||
|
|
||||||
if (atom == prop_dlock)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (val->format != 8 || val->type != XA_INTEGER)
|
|
||||||
return BadMatch;
|
|
||||||
|
|
||||||
/* Don't allow changes while a lock is active */
|
|
||||||
if (pEvdev->dragLock.meta)
|
|
||||||
{
|
|
||||||
if (pEvdev->dragLock.meta_state)
|
|
||||||
return BadAccess;
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
for (i = 0; i < EVDEV_MAXBUTTONS; i++)
|
|
||||||
if (pEvdev->dragLock.lock_state[i])
|
|
||||||
return BadValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (val->size == 1)
|
|
||||||
{
|
|
||||||
int meta = *((CARD8*)val->data);
|
|
||||||
if (meta > EVDEV_MAXBUTTONS)
|
|
||||||
return BadValue;
|
|
||||||
|
|
||||||
if (!checkonly)
|
|
||||||
{
|
|
||||||
pEvdev->dragLock.meta = meta;
|
|
||||||
memset(pEvdev->dragLock.lock_pair, 0, sizeof(pEvdev->dragLock.lock_pair));
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
CARD8* vals = (CARD8*)val->data;
|
|
||||||
|
|
||||||
for (i = 0; i < val->size && i < EVDEV_MAXBUTTONS; i++)
|
|
||||||
if (vals[i] > EVDEV_MAXBUTTONS)
|
|
||||||
return BadValue;
|
|
||||||
|
|
||||||
if (!checkonly)
|
|
||||||
{
|
|
||||||
pEvdev->dragLock.meta = 0;
|
|
||||||
memset(pEvdev->dragLock.lock_pair, 0, sizeof(pEvdev->dragLock.lock_pair));
|
|
||||||
|
|
||||||
for (i = 0; i < val->size && i < EVDEV_MAXBUTTONS; i++)
|
|
||||||
pEvdev->dragLock.lock_pair[i] = vals[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Success;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
77
src/emuMB.c
77
src/emuMB.c
@@ -231,6 +231,11 @@ EvdevMBEmuFilterEvent(InputInfoPtr pInfo, int button, BOOL press)
|
|||||||
if (!pEvdev->emulateMB.enabled)
|
if (!pEvdev->emulateMB.enabled)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
if (button == 2) {
|
||||||
|
EvdevMBEmuEnable(pInfo, FALSE);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/* don't care about other buttons */
|
/* don't care about other buttons */
|
||||||
if (button != 1 && button != 3)
|
if (button != 1 && button != 3)
|
||||||
return ret;
|
return ret;
|
||||||
@@ -311,24 +316,20 @@ EvdevMBEmuPreInit(InputInfoPtr pInfo)
|
|||||||
pEvdev->emulateMB.enabled = xf86SetBoolOption(pInfo->options,
|
pEvdev->emulateMB.enabled = xf86SetBoolOption(pInfo->options,
|
||||||
"Emulate3Buttons",
|
"Emulate3Buttons",
|
||||||
MBEMU_ENABLED);
|
MBEMU_ENABLED);
|
||||||
xf86Msg(X_INFO, "%s: Forcing middle mouse button emulation.\n",
|
xf86Msg(X_INFO, "%s: Forcing middle mouse button emulation %s.\n",
|
||||||
pInfo->name);
|
pInfo->name, (pEvdev->emulateMB.enabled) ? "on" : "off");
|
||||||
}
|
}
|
||||||
|
|
||||||
pEvdev->emulateMB.timeout = xf86SetIntOption(pInfo->options,
|
pEvdev->emulateMB.timeout = xf86SetIntOption(pInfo->options,
|
||||||
"Emulate3Timeout", 50);
|
"Emulate3Timeout", 50);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
EvdevMBEmuOn(InputInfoPtr pInfo)
|
||||||
|
{
|
||||||
RegisterBlockAndWakeupHandlers (EvdevMBEmuBlockHandler,
|
RegisterBlockAndWakeupHandlers (EvdevMBEmuBlockHandler,
|
||||||
EvdevMBEmuWakeupHandler,
|
EvdevMBEmuWakeupHandler,
|
||||||
(pointer)pInfo);
|
(pointer)pInfo);
|
||||||
|
|
||||||
#ifdef HAVE_PROPERTIES
|
|
||||||
XIChangeDeviceProperty(pInfo->dev, prop_mbemu, XA_INTEGER, 8,
|
|
||||||
PropModeReplace, 1, &pEvdev->emulateMB.enabled,
|
|
||||||
TRUE);
|
|
||||||
XIChangeDeviceProperty(pInfo->dev, prop_mbtimeout, XA_INTEGER, 16,
|
|
||||||
PropModeReplace, 1, &pEvdev->emulateMB.timeout,
|
|
||||||
TRUE);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -351,6 +352,32 @@ EvdevMBEmuEnable(InputInfoPtr pInfo, BOOL enable)
|
|||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_PROPERTIES
|
#ifdef HAVE_PROPERTIES
|
||||||
|
int
|
||||||
|
EvdevMBEmuSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
|
||||||
|
BOOL checkonly)
|
||||||
|
{
|
||||||
|
InputInfoPtr pInfo = dev->public.devicePrivate;
|
||||||
|
EvdevPtr pEvdev = pInfo->private;
|
||||||
|
|
||||||
|
if (atom == prop_mbemu)
|
||||||
|
{
|
||||||
|
if (val->format != 8 || val->size != 1 || val->type != XA_INTEGER)
|
||||||
|
return BadMatch;
|
||||||
|
|
||||||
|
if (!checkonly)
|
||||||
|
pEvdev->emulateMB.enabled = *((BOOL*)val->data);
|
||||||
|
} else if (atom == prop_mbtimeout)
|
||||||
|
{
|
||||||
|
if (val->format != 32 || val->size != 1 || val->type != XA_INTEGER)
|
||||||
|
return BadMatch;
|
||||||
|
|
||||||
|
if (!checkonly)
|
||||||
|
pEvdev->emulateMB.timeout = *((CARD32*)val->data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Success;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialise property for MB emulation on/off.
|
* Initialise property for MB emulation on/off.
|
||||||
*/
|
*/
|
||||||
@@ -376,37 +403,13 @@ EvdevMBEmuInitProperty(DeviceIntPtr dev)
|
|||||||
prop_mbtimeout = MakeAtom(EVDEV_PROP_MIDBUTTON_TIMEOUT,
|
prop_mbtimeout = MakeAtom(EVDEV_PROP_MIDBUTTON_TIMEOUT,
|
||||||
strlen(EVDEV_PROP_MIDBUTTON_TIMEOUT),
|
strlen(EVDEV_PROP_MIDBUTTON_TIMEOUT),
|
||||||
TRUE);
|
TRUE);
|
||||||
rc = XIChangeDeviceProperty(dev, prop_mbtimeout, XA_INTEGER, 16, PropModeReplace, 1,
|
rc = XIChangeDeviceProperty(dev, prop_mbtimeout, XA_INTEGER, 32, PropModeReplace, 1,
|
||||||
&pEvdev->emulateMB.timeout, FALSE);
|
&pEvdev->emulateMB.timeout, FALSE);
|
||||||
|
|
||||||
if (rc != Success)
|
if (rc != Success)
|
||||||
return;
|
return;
|
||||||
XISetDevicePropertyDeletable(dev, prop_mbtimeout, FALSE);
|
XISetDevicePropertyDeletable(dev, prop_mbtimeout, FALSE);
|
||||||
}
|
|
||||||
|
|
||||||
int
|
XIRegisterPropertyHandler(dev, EvdevMBEmuSetProperty, NULL, NULL);
|
||||||
EvdevMBEmuSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
|
|
||||||
BOOL checkonly)
|
|
||||||
{
|
|
||||||
InputInfoPtr pInfo = dev->public.devicePrivate;
|
|
||||||
EvdevPtr pEvdev = pInfo->private;
|
|
||||||
|
|
||||||
if (atom == prop_mbemu)
|
|
||||||
{
|
|
||||||
if (val->format != 8 || val->size != 1 || val->type != XA_INTEGER)
|
|
||||||
return BadMatch;
|
|
||||||
|
|
||||||
if (!checkonly)
|
|
||||||
pEvdev->emulateMB.enabled = *((BOOL*)val->data);
|
|
||||||
} else if (atom == prop_mbtimeout)
|
|
||||||
{
|
|
||||||
if (val->format != 16 || val->size != 1 || val->type != XA_INTEGER)
|
|
||||||
return BadMatch;
|
|
||||||
|
|
||||||
if (!checkonly)
|
|
||||||
pEvdev->emulateMB.timeout = *((INT16*)val->data);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Success;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
209
src/emuWheel.c
209
src/emuWheel.c
@@ -308,35 +308,111 @@ EvdevWheelEmuPreInit(InputInfoPtr pInfo)
|
|||||||
"EmulateWheelInertia: %d, "
|
"EmulateWheelInertia: %d, "
|
||||||
"EmulateWheelTimeout: %d\n",
|
"EmulateWheelTimeout: %d\n",
|
||||||
pInfo->name, pEvdev->emulateWheel.button, inertia, timeout);
|
pInfo->name, pEvdev->emulateWheel.button, inertia, timeout);
|
||||||
|
|
||||||
#ifdef HAVE_PROPERTIES
|
|
||||||
XIChangeDeviceProperty(pInfo->dev, prop_wheel_emu, XA_INTEGER, 8,
|
|
||||||
PropModeReplace, 1, &pEvdev->emulateWheel.enabled, TRUE);
|
|
||||||
XIChangeDeviceProperty(pInfo->dev, prop_wheel_button, XA_INTEGER, 8,
|
|
||||||
PropModeReplace, 1, &pEvdev->emulateWheel.button, TRUE);
|
|
||||||
XIChangeDeviceProperty(pInfo->dev, prop_wheel_inertia, XA_INTEGER, 8,
|
|
||||||
PropModeReplace, 1, &pEvdev->emulateWheel.inertia, TRUE);
|
|
||||||
XIChangeDeviceProperty(pInfo->dev, prop_wheel_timeout, XA_INTEGER, 16,
|
|
||||||
PropModeReplace, 1, &pEvdev->emulateWheel.timeout, TRUE);
|
|
||||||
|
|
||||||
val[0] = pEvdev->emulateWheel.X.up_button;
|
|
||||||
val[1] = pEvdev->emulateWheel.X.down_button;
|
|
||||||
val[2] = pEvdev->emulateWheel.Y.up_button;
|
|
||||||
val[3] = pEvdev->emulateWheel.Y.down_button;
|
|
||||||
XIChangeDeviceProperty(pInfo->dev, prop_wheel_axismap, XA_INTEGER, 8,
|
|
||||||
PropModeReplace, 4, val, TRUE);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_PROPERTIES
|
#ifdef HAVE_PROPERTIES
|
||||||
|
int
|
||||||
|
EvdevWheelEmuSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
|
||||||
|
BOOL checkonly)
|
||||||
|
{
|
||||||
|
InputInfoPtr pInfo = dev->public.devicePrivate;
|
||||||
|
EvdevPtr pEvdev = pInfo->private;
|
||||||
|
|
||||||
|
if (atom == prop_wheel_emu)
|
||||||
|
{
|
||||||
|
if (val->format != 8 || val->size != 1 || val->type != XA_INTEGER)
|
||||||
|
return BadMatch;
|
||||||
|
|
||||||
|
if (!checkonly)
|
||||||
|
{
|
||||||
|
pEvdev->emulateWheel.enabled = *((BOOL*)val->data);
|
||||||
|
/* Don't enable with zero inertia, otherwise we may get stuck in an
|
||||||
|
* infinite loop */
|
||||||
|
if (pEvdev->emulateWheel.inertia <= 0)
|
||||||
|
{
|
||||||
|
pEvdev->emulateWheel.inertia = 10;
|
||||||
|
/* We may get here before the property is actually enabled */
|
||||||
|
if (prop_wheel_inertia)
|
||||||
|
XIChangeDeviceProperty(dev, prop_wheel_inertia, XA_INTEGER,
|
||||||
|
16, PropModeReplace, 1,
|
||||||
|
&pEvdev->emulateWheel.inertia, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Don't enable with negative timeout */
|
||||||
|
if (pEvdev->emulateWheel.timeout < 0)
|
||||||
|
{
|
||||||
|
pEvdev->emulateWheel.timeout = 200;
|
||||||
|
XIChangeDeviceProperty(dev, prop_wheel_timeout, XA_INTEGER, 16,
|
||||||
|
PropModeReplace, 1,
|
||||||
|
&pEvdev->emulateWheel.timeout, TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (atom == prop_wheel_button)
|
||||||
|
{
|
||||||
|
int bt;
|
||||||
|
|
||||||
|
if (val->format != 8 || val->size != 1 || val->type != XA_INTEGER)
|
||||||
|
return BadMatch;
|
||||||
|
|
||||||
|
bt = *((CARD8*)val->data);
|
||||||
|
|
||||||
|
if (bt < 0 || bt >= EVDEV_MAXBUTTONS)
|
||||||
|
return BadValue;
|
||||||
|
|
||||||
|
if (!checkonly)
|
||||||
|
pEvdev->emulateWheel.button = bt;
|
||||||
|
} else if (atom == prop_wheel_axismap)
|
||||||
|
{
|
||||||
|
if (val->format != 8 || val->size != 4 || val->type != XA_INTEGER)
|
||||||
|
return BadMatch;
|
||||||
|
|
||||||
|
if (!checkonly)
|
||||||
|
{
|
||||||
|
pEvdev->emulateWheel.X.up_button = *((CARD8*)val->data);
|
||||||
|
pEvdev->emulateWheel.X.down_button = *(((CARD8*)val->data) + 1);
|
||||||
|
pEvdev->emulateWheel.Y.up_button = *(((CARD8*)val->data) + 2);
|
||||||
|
pEvdev->emulateWheel.Y.down_button = *(((CARD8*)val->data) + 3);
|
||||||
|
}
|
||||||
|
} else if (atom == prop_wheel_inertia)
|
||||||
|
{
|
||||||
|
int inertia;
|
||||||
|
|
||||||
|
if (val->format != 16 || val->size != 1 || val->type != XA_INTEGER)
|
||||||
|
return BadMatch;
|
||||||
|
|
||||||
|
inertia = *((CARD16*)val->data);
|
||||||
|
|
||||||
|
if (inertia < 0)
|
||||||
|
return BadValue;
|
||||||
|
|
||||||
|
if (!checkonly)
|
||||||
|
pEvdev->emulateWheel.inertia = inertia;
|
||||||
|
} else if (atom == prop_wheel_timeout)
|
||||||
|
{
|
||||||
|
int timeout;
|
||||||
|
|
||||||
|
if (val->format != 16 || val->size != 1 || val->type != XA_INTEGER)
|
||||||
|
return BadMatch;
|
||||||
|
|
||||||
|
timeout = *((CARD16*)val->data);
|
||||||
|
|
||||||
|
if (timeout < 0)
|
||||||
|
return BadValue;
|
||||||
|
|
||||||
|
if (!checkonly)
|
||||||
|
pEvdev->emulateWheel.timeout = timeout;
|
||||||
|
}
|
||||||
|
return Success;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
EvdevWheelEmuInitProperty(DeviceIntPtr dev)
|
EvdevWheelEmuInitProperty(DeviceIntPtr dev)
|
||||||
{
|
{
|
||||||
InputInfoPtr pInfo = dev->public.devicePrivate;
|
InputInfoPtr pInfo = dev->public.devicePrivate;
|
||||||
EvdevPtr pEvdev = pInfo->private;
|
EvdevPtr pEvdev = pInfo->private;
|
||||||
int rc = TRUE;
|
int rc = TRUE;
|
||||||
INT32 vals[4] = { TRUE, FALSE};
|
char vals[4];
|
||||||
|
|
||||||
if (!dev->button) /* don't init prop for keyboards */
|
if (!dev->button) /* don't init prop for keyboards */
|
||||||
return;
|
return;
|
||||||
@@ -390,96 +466,7 @@ EvdevWheelEmuInitProperty(DeviceIntPtr dev)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
XISetDevicePropertyDeletable(dev, prop_wheel_button, FALSE);
|
XISetDevicePropertyDeletable(dev, prop_wheel_button, FALSE);
|
||||||
|
|
||||||
|
XIRegisterPropertyHandler(dev, EvdevWheelEmuSetProperty, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
EvdevWheelEmuSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
|
|
||||||
BOOL checkonly)
|
|
||||||
{
|
|
||||||
InputInfoPtr pInfo = dev->public.devicePrivate;
|
|
||||||
EvdevPtr pEvdev = pInfo->private;
|
|
||||||
|
|
||||||
if (atom == prop_wheel_emu)
|
|
||||||
{
|
|
||||||
if (val->format != 8 || val->size != 1 || val->type != XA_INTEGER)
|
|
||||||
return BadMatch;
|
|
||||||
|
|
||||||
if (!checkonly)
|
|
||||||
{
|
|
||||||
pEvdev->emulateWheel.enabled = *((BOOL*)val->data);
|
|
||||||
/* Don't enable with zero inertia, otherwise we may get stuck in an
|
|
||||||
* infinite loop */
|
|
||||||
if (pEvdev->emulateWheel.inertia <= 0)
|
|
||||||
{
|
|
||||||
pEvdev->emulateWheel.inertia = 10;
|
|
||||||
/* We may get here before the property is actually enabled */
|
|
||||||
if (prop_wheel_inertia)
|
|
||||||
XIChangeDeviceProperty(dev, prop_wheel_inertia, XA_INTEGER,
|
|
||||||
16, PropModeReplace, 1,
|
|
||||||
&pEvdev->emulateWheel.inertia, TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Don't enable with negative timeout */
|
|
||||||
if (pEvdev->emulateWheel.timeout < 0)
|
|
||||||
{
|
|
||||||
pEvdev->emulateWheel.timeout = 200;
|
|
||||||
XIChangeDeviceProperty(dev, prop_wheel_timeout, XA_INTEGER, 16,
|
|
||||||
PropModeReplace, 1,
|
|
||||||
&pEvdev->emulateWheel.timeout, TRUE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (atom == prop_wheel_button)
|
|
||||||
{
|
|
||||||
int bt = *((CARD8*)val->data);
|
|
||||||
|
|
||||||
if (val->format != 8 || val->size != 1 || val->type != XA_INTEGER)
|
|
||||||
return BadMatch;
|
|
||||||
|
|
||||||
if (bt < 0 || bt >= EVDEV_MAXBUTTONS)
|
|
||||||
return BadValue;
|
|
||||||
|
|
||||||
if (!checkonly)
|
|
||||||
pEvdev->emulateWheel.button = bt;
|
|
||||||
} else if (atom == prop_wheel_axismap)
|
|
||||||
{
|
|
||||||
if (val->format != 8 || val->size != 4 || val->type != XA_INTEGER)
|
|
||||||
return BadMatch;
|
|
||||||
|
|
||||||
if (!checkonly)
|
|
||||||
{
|
|
||||||
pEvdev->emulateWheel.X.up_button = *((CARD8*)val->data);
|
|
||||||
pEvdev->emulateWheel.X.down_button = *(((CARD8*)val->data) + 1);
|
|
||||||
pEvdev->emulateWheel.Y.up_button = *(((CARD8*)val->data) + 2);
|
|
||||||
pEvdev->emulateWheel.Y.down_button = *(((CARD8*)val->data) + 3);
|
|
||||||
}
|
|
||||||
} else if (atom == prop_wheel_inertia)
|
|
||||||
{
|
|
||||||
int inertia = *((CARD16*)val->data);
|
|
||||||
|
|
||||||
if (val->format != 16 || val->size != 1 || val->type != XA_INTEGER)
|
|
||||||
return BadMatch;
|
|
||||||
|
|
||||||
if (inertia < 0)
|
|
||||||
return BadValue;
|
|
||||||
|
|
||||||
if (!checkonly)
|
|
||||||
pEvdev->emulateWheel.inertia = inertia;
|
|
||||||
} else if (atom == prop_wheel_timeout)
|
|
||||||
{
|
|
||||||
int timeout = *((CARD16*)val->data);
|
|
||||||
|
|
||||||
if (val->format != 16 || val->size != 1 || val->type != XA_INTEGER)
|
|
||||||
return BadMatch;
|
|
||||||
|
|
||||||
if (timeout < 0)
|
|
||||||
return BadValue;
|
|
||||||
|
|
||||||
if (!checkonly)
|
|
||||||
pEvdev->emulateWheel.timeout = timeout;
|
|
||||||
}
|
|
||||||
return Success;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
460
src/evdev.c
460
src/evdev.c
@@ -32,6 +32,7 @@
|
|||||||
|
|
||||||
#include <X11/keysym.h>
|
#include <X11/keysym.h>
|
||||||
|
|
||||||
|
#include <sys/stat.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
@@ -51,6 +52,10 @@
|
|||||||
#include <evdev-properties.h>
|
#include <evdev-properties.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef MAXDEVICES
|
||||||
|
#include <inputstr.h> /* for MAX_DEVICES */
|
||||||
|
#define MAXDEVICES MAX_DEVICES
|
||||||
|
#endif
|
||||||
|
|
||||||
/* 2.4 compatibility */
|
/* 2.4 compatibility */
|
||||||
#ifndef EVIOCGRAB
|
#ifndef EVIOCGRAB
|
||||||
@@ -75,6 +80,8 @@
|
|||||||
#define EVDEV_ABSOLUTE_EVENTS (1 << 3)
|
#define EVDEV_ABSOLUTE_EVENTS (1 << 3)
|
||||||
#define EVDEV_TOUCHPAD (1 << 4)
|
#define EVDEV_TOUCHPAD (1 << 4)
|
||||||
#define EVDEV_INITIALIZED (1 << 5) /* WheelInit etc. called already? */
|
#define EVDEV_INITIALIZED (1 << 5) /* WheelInit etc. called already? */
|
||||||
|
#define EVDEV_TOUCHSCREEN (1 << 6)
|
||||||
|
#define EVDEV_CALIBRATED (1 << 7) /* run-time calibrated? */
|
||||||
|
|
||||||
#define MIN_KEYCODE 8
|
#define MIN_KEYCODE 8
|
||||||
#define GLYPHS_PER_KEY 2
|
#define GLYPHS_PER_KEY 2
|
||||||
@@ -105,8 +112,93 @@ static void EvdevInitProperty(DeviceIntPtr dev);
|
|||||||
static int EvdevSetProperty(DeviceIntPtr dev, Atom atom,
|
static int EvdevSetProperty(DeviceIntPtr dev, Atom atom,
|
||||||
XIPropertyValuePtr val, BOOL checkonly);
|
XIPropertyValuePtr val, BOOL checkonly);
|
||||||
static Atom prop_invert = 0;
|
static Atom prop_invert = 0;
|
||||||
|
static Atom prop_reopen = 0;
|
||||||
|
static Atom prop_calibration = 0;
|
||||||
|
static Atom prop_swap = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* All devices the evdev driver has allocated and knows about.
|
||||||
|
* MAXDEVICES is safe as null-terminated array, as two devices (VCP and VCK)
|
||||||
|
* cannot be used by evdev, leaving us with a space of 2 at the end. */
|
||||||
|
static EvdevPtr evdev_devices[MAXDEVICES] = {0};
|
||||||
|
|
||||||
|
static int
|
||||||
|
EvdevGetMajorMinor(InputInfoPtr pInfo)
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
if (fstat(pInfo->fd, &st) == -1)
|
||||||
|
{
|
||||||
|
xf86Msg(X_ERROR, "%s: stat failed (%s). cannot check for duplicates.\n",
|
||||||
|
pInfo->name, strerror(errno));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return st.st_rdev;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return TRUE if one of the devices we know about has the same min/maj
|
||||||
|
* number.
|
||||||
|
*/
|
||||||
|
static BOOL
|
||||||
|
EvdevIsDuplicate(InputInfoPtr pInfo)
|
||||||
|
{
|
||||||
|
EvdevPtr pEvdev = pInfo->private;
|
||||||
|
EvdevPtr* dev = evdev_devices;
|
||||||
|
|
||||||
|
if (pEvdev->min_maj)
|
||||||
|
{
|
||||||
|
while(*dev)
|
||||||
|
{
|
||||||
|
if ((*dev) != pEvdev &&
|
||||||
|
(*dev)->min_maj &&
|
||||||
|
(*dev)->min_maj == pEvdev->min_maj)
|
||||||
|
return TRUE;
|
||||||
|
dev++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add to internal device list.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
EvdevAddDevice(InputInfoPtr pInfo)
|
||||||
|
{
|
||||||
|
EvdevPtr pEvdev = pInfo->private;
|
||||||
|
EvdevPtr* dev = evdev_devices;
|
||||||
|
|
||||||
|
while(*dev)
|
||||||
|
dev++;
|
||||||
|
|
||||||
|
*dev = pEvdev;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove from internal device list.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
EvdevRemoveDevice(InputInfoPtr pInfo)
|
||||||
|
{
|
||||||
|
EvdevPtr pEvdev = pInfo->private;
|
||||||
|
EvdevPtr *dev = evdev_devices;
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
while(*dev)
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
if (*dev == pEvdev)
|
||||||
|
{
|
||||||
|
memmove(dev, dev + 1,
|
||||||
|
sizeof(evdev_devices) - (count * sizeof(EvdevPtr)));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
dev++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
SetXkbOption(InputInfoPtr pInfo, char *name, char **option)
|
SetXkbOption(InputInfoPtr pInfo, char *name, char **option)
|
||||||
@@ -119,7 +211,6 @@ SetXkbOption(InputInfoPtr pInfo, char *name, char **option)
|
|||||||
*option = NULL;
|
*option = NULL;
|
||||||
} else {
|
} else {
|
||||||
*option = s;
|
*option = s;
|
||||||
xf86Msg(X_CONFIG, "%s: %s: \"%s\"\n", pInfo->name, name, s);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -144,7 +235,7 @@ static void
|
|||||||
PostKbdEvent(InputInfoPtr pInfo, struct input_event *ev, int value)
|
PostKbdEvent(InputInfoPtr pInfo, struct input_event *ev, int value)
|
||||||
{
|
{
|
||||||
int code = ev->code + MIN_KEYCODE;
|
int code = ev->code + MIN_KEYCODE;
|
||||||
static char warned[KEY_MAX];
|
static char warned[KEY_CNT];
|
||||||
|
|
||||||
/* filter repeat events for chording keys */
|
/* filter repeat events for chording keys */
|
||||||
if (value == 2 &&
|
if (value == 2 &&
|
||||||
@@ -156,13 +247,17 @@ PostKbdEvent(InputInfoPtr pInfo, struct input_event *ev, int value)
|
|||||||
ev->code == KEY_SCROLLLOCK)) /* XXX windows keys? */
|
ev->code == KEY_SCROLLLOCK)) /* XXX windows keys? */
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (code > 255 && ev->code < KEY_MAX) {
|
if (code > 255 && ev->code <= KEY_MAX) {
|
||||||
if (!warned[ev->code])
|
if (!warned[ev->code])
|
||||||
xf86Msg(X_WARNING, "%s: unable to handle keycode %d\n",
|
xf86Msg(X_WARNING, "%s: unable to handle keycode %d\n",
|
||||||
pInfo->name, ev->code);
|
pInfo->name, ev->code);
|
||||||
warned[ev->code] = 1;
|
warned[ev->code] = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The X server can't handle keycodes > 255 anyway, just drop them. */
|
||||||
|
if (code > 255)
|
||||||
|
return;
|
||||||
|
|
||||||
xf86PostKeyboardEvent(pInfo->dev, code, value);
|
xf86PostKeyboardEvent(pInfo->dev, code, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,12 +279,10 @@ EvdevReopenTimer(OsTimerPtr timer, CARD32 time, pointer arg)
|
|||||||
|
|
||||||
if (pInfo->fd != -1)
|
if (pInfo->fd != -1)
|
||||||
{
|
{
|
||||||
pEvdev->reopen_left = 0;
|
|
||||||
|
|
||||||
if (EvdevCacheCompare(pInfo, TRUE) == Success)
|
if (EvdevCacheCompare(pInfo, TRUE) == Success)
|
||||||
{
|
{
|
||||||
xf86Msg(X_INFO, "%s: Device reopened after %d attempts.\n", pInfo->name,
|
xf86Msg(X_INFO, "%s: Device reopened after %d attempts.\n", pInfo->name,
|
||||||
pEvdev->reopen_attempts - pEvdev->reopen_left);
|
pEvdev->reopen_attempts - pEvdev->reopen_left + 1);
|
||||||
EvdevOn(pInfo->dev);
|
EvdevOn(pInfo->dev);
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
@@ -198,7 +291,9 @@ EvdevReopenTimer(OsTimerPtr timer, CARD32 time, pointer arg)
|
|||||||
DisableDevice(pInfo->dev);
|
DisableDevice(pInfo->dev);
|
||||||
close(pInfo->fd);
|
close(pInfo->fd);
|
||||||
pInfo->fd = -1;
|
pInfo->fd = -1;
|
||||||
|
pEvdev->min_maj = 0; /* don't hog the device */
|
||||||
}
|
}
|
||||||
|
pEvdev->reopen_left = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,6 +304,7 @@ EvdevReopenTimer(OsTimerPtr timer, CARD32 time, pointer arg)
|
|||||||
xf86Msg(X_ERROR, "%s: Failed to reopen device after %d attempts.\n",
|
xf86Msg(X_ERROR, "%s: Failed to reopen device after %d attempts.\n",
|
||||||
pInfo->name, pEvdev->reopen_attempts);
|
pInfo->name, pEvdev->reopen_attempts);
|
||||||
DisableDevice(pInfo->dev);
|
DisableDevice(pInfo->dev);
|
||||||
|
pEvdev->min_maj = 0; /* don't hog the device */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -220,13 +316,14 @@ EvdevReadInput(InputInfoPtr pInfo)
|
|||||||
{
|
{
|
||||||
struct input_event ev;
|
struct input_event ev;
|
||||||
int len, value;
|
int len, value;
|
||||||
int dx, dy;
|
int dx, dy, tmp;
|
||||||
unsigned int abs;
|
unsigned int abs;
|
||||||
unsigned int button;
|
unsigned int button;
|
||||||
EvdevPtr pEvdev = pInfo->private;
|
EvdevPtr pEvdev = pInfo->private;
|
||||||
|
|
||||||
dx = 0;
|
dx = 0;
|
||||||
dy = 0;
|
dy = 0;
|
||||||
|
tmp = 0;
|
||||||
abs = 0;
|
abs = 0;
|
||||||
|
|
||||||
while (xf86WaitForInput (pInfo->fd, 0) > 0) {
|
while (xf86WaitForInput (pInfo->fd, 0) > 0) {
|
||||||
@@ -313,10 +410,15 @@ EvdevReadInput(InputInfoPtr pInfo)
|
|||||||
case BTN_TOOL_MOUSE:
|
case BTN_TOOL_MOUSE:
|
||||||
case BTN_TOOL_LENS:
|
case BTN_TOOL_LENS:
|
||||||
pEvdev->tool = value ? ev.code : 0;
|
pEvdev->tool = value ? ev.code : 0;
|
||||||
break;
|
if (!(pEvdev->flags & EVDEV_TOUCHSCREEN))
|
||||||
|
break;
|
||||||
|
/* Treat BTN_TOUCH from devices that only have BTN_TOUCH as
|
||||||
|
* BTN_LEFT. */
|
||||||
|
ev.code = BTN_LEFT;
|
||||||
|
/* Intentional fallthrough! */
|
||||||
|
|
||||||
default:
|
default:
|
||||||
button = EvdevUtilButtonEventToButtonNumber(ev.code);
|
button = EvdevUtilButtonEventToButtonNumber(pEvdev, ev.code);
|
||||||
|
|
||||||
/* Handle drag lock */
|
/* Handle drag lock */
|
||||||
if (EvdevDragLockFilterEvent(pInfo, button, value))
|
if (EvdevDragLockFilterEvent(pInfo, button, value))
|
||||||
@@ -357,6 +459,11 @@ EvdevReadInput(InputInfoPtr pInfo)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (dx != 0 || dy != 0) {
|
if (dx != 0 || dy != 0) {
|
||||||
|
if (pEvdev->swap_axes) {
|
||||||
|
tmp = dx;
|
||||||
|
dx = dy;
|
||||||
|
dy = tmp;
|
||||||
|
}
|
||||||
if (pEvdev->invert_x)
|
if (pEvdev->invert_x)
|
||||||
dx *= -1;
|
dx *= -1;
|
||||||
if (pEvdev->invert_y)
|
if (pEvdev->invert_y)
|
||||||
@@ -375,18 +482,29 @@ EvdevReadInput(InputInfoPtr pInfo)
|
|||||||
*/
|
*/
|
||||||
if (abs && pEvdev->tool) {
|
if (abs && pEvdev->tool) {
|
||||||
int abs_x, abs_y;
|
int abs_x, abs_y;
|
||||||
abs_x = pEvdev->abs_x;
|
abs_x = (pEvdev->swap_axes) ? pEvdev->abs_y : pEvdev->abs_x;
|
||||||
abs_y = pEvdev->abs_y;
|
abs_y = (pEvdev->swap_axes) ? pEvdev->abs_x : pEvdev->abs_y;
|
||||||
|
|
||||||
|
if (pEvdev->flags & EVDEV_CALIBRATED)
|
||||||
|
{
|
||||||
|
abs_x = xf86ScaleAxis(abs_x,
|
||||||
|
pEvdev->max_x, pEvdev->min_x,
|
||||||
|
pEvdev->calibration.max_x, pEvdev->calibration.min_x);
|
||||||
|
abs_y = xf86ScaleAxis(abs_y,
|
||||||
|
pEvdev->max_y, pEvdev->min_y,
|
||||||
|
pEvdev->calibration.max_y, pEvdev->calibration.min_y);
|
||||||
|
}
|
||||||
|
|
||||||
if (pEvdev->invert_x)
|
if (pEvdev->invert_x)
|
||||||
abs_x = pEvdev->max_x - abs_x;
|
abs_x = pEvdev->max_x - (abs_x - pEvdev->min_x);
|
||||||
if (pEvdev->invert_y)
|
if (pEvdev->invert_y)
|
||||||
abs_y = pEvdev->max_y - abs_y;
|
abs_y = pEvdev->max_y - (abs_y - pEvdev->min_y);
|
||||||
|
|
||||||
xf86PostMotionEvent(pInfo->dev, TRUE, 0, 2, abs_x, abs_y);
|
xf86PostMotionEvent(pInfo->dev, TRUE, 0, 2, abs_x, abs_y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define TestBit(bit, array) (array[(bit) / LONG_BITS]) & (1 << ((bit) % LONG_BITS))
|
#define TestBit(bit, array) (array[(bit) / LONG_BITS]) & (1L << ((bit) % LONG_BITS))
|
||||||
|
|
||||||
static void
|
static void
|
||||||
EvdevPtrCtrlProc(DeviceIntPtr device, PtrCtrl *ctrl)
|
EvdevPtrCtrlProc(DeviceIntPtr device, PtrCtrl *ctrl)
|
||||||
@@ -394,9 +512,6 @@ EvdevPtrCtrlProc(DeviceIntPtr device, PtrCtrl *ctrl)
|
|||||||
/* Nothing to do, dix handles all settings */
|
/* Nothing to do, dix handles all settings */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: this map works with evdev keyboards, but all the xkb maps
|
|
||||||
* probably don't. The easiest is to remap the event keycodes. */
|
|
||||||
|
|
||||||
static KeySym map[] = {
|
static KeySym map[] = {
|
||||||
/* 0x00 */ NoSymbol, NoSymbol,
|
/* 0x00 */ NoSymbol, NoSymbol,
|
||||||
/* 0x01 */ XK_Escape, NoSymbol,
|
/* 0x01 */ XK_Escape, NoSymbol,
|
||||||
@@ -665,6 +780,8 @@ EvdevKbdCtrl(DeviceIntPtr device, KeybdCtrl *ctrl)
|
|||||||
struct input_event ev[ArrayLength(bits)];
|
struct input_event ev[ArrayLength(bits)];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
memset(ev, 0, sizeof(ev));
|
||||||
|
|
||||||
pInfo = device->public.devicePrivate;
|
pInfo = device->public.devicePrivate;
|
||||||
for (i = 0; i < ArrayLength(bits); i++) {
|
for (i = 0; i < ArrayLength(bits); i++) {
|
||||||
ev[i].type = EV_LED;
|
ev[i].type = EV_LED;
|
||||||
@@ -736,7 +853,7 @@ EvdevAddKeyClass(DeviceIntPtr device)
|
|||||||
SetXkbOption(pInfo, "xkb_rules", &pEvdev->xkb_rules);
|
SetXkbOption(pInfo, "xkb_rules", &pEvdev->xkb_rules);
|
||||||
SetXkbOption(pInfo, "xkb_model", &pEvdev->xkb_model);
|
SetXkbOption(pInfo, "xkb_model", &pEvdev->xkb_model);
|
||||||
if (!pEvdev->xkb_model)
|
if (!pEvdev->xkb_model)
|
||||||
SetXkbOption(pInfo, "XkbModel", &pEvdev->xkb_rules);
|
SetXkbOption(pInfo, "XkbModel", &pEvdev->xkb_model);
|
||||||
SetXkbOption(pInfo, "xkb_layout", &pEvdev->xkb_layout);
|
SetXkbOption(pInfo, "xkb_layout", &pEvdev->xkb_layout);
|
||||||
if (!pEvdev->xkb_layout)
|
if (!pEvdev->xkb_layout)
|
||||||
SetXkbOption(pInfo, "XkbLayout", &pEvdev->xkb_layout);
|
SetXkbOption(pInfo, "XkbLayout", &pEvdev->xkb_layout);
|
||||||
@@ -774,13 +891,13 @@ EvdevAddAbsClass(DeviceIntPtr device)
|
|||||||
|
|
||||||
if (ioctl(pInfo->fd,
|
if (ioctl(pInfo->fd,
|
||||||
EVIOCGABS(ABS_X), &absinfo_x) < 0) {
|
EVIOCGABS(ABS_X), &absinfo_x) < 0) {
|
||||||
xf86Msg(X_ERROR, "ioctl EVIOCGABS failed: %s\n", strerror(errno));
|
xf86Msg(X_ERROR, "ioctl EVIOCGABS ABS_X failed: %s\n", strerror(errno));
|
||||||
return !Success;
|
return !Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ioctl(pInfo->fd,
|
if (ioctl(pInfo->fd,
|
||||||
EVIOCGABS(ABS_Y), &absinfo_y) < 0) {
|
EVIOCGABS(ABS_Y), &absinfo_y) < 0) {
|
||||||
xf86Msg(X_ERROR, "ioctl EVIOCGABS failed: %s\n", strerror(errno));
|
xf86Msg(X_ERROR, "ioctl EVIOCGABS ABS_Y failed: %s\n", strerror(errno));
|
||||||
return !Success;
|
return !Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -949,9 +1066,6 @@ EvdevInit(DeviceIntPtr device)
|
|||||||
/* We drop the return value, the only time we ever want the handlers to
|
/* We drop the return value, the only time we ever want the handlers to
|
||||||
* unregister is when the device dies. In which case we don't have to
|
* unregister is when the device dies. In which case we don't have to
|
||||||
* unregister anyway */
|
* unregister anyway */
|
||||||
XIRegisterPropertyHandler(device, EvdevMBEmuSetProperty, NULL, NULL);
|
|
||||||
XIRegisterPropertyHandler(device, EvdevWheelEmuSetProperty, NULL, NULL);
|
|
||||||
XIRegisterPropertyHandler(device, EvdevDragLockSetProperty, NULL, NULL);
|
|
||||||
XIRegisterPropertyHandler(device, EvdevSetProperty, NULL, NULL);
|
XIRegisterPropertyHandler(device, EvdevSetProperty, NULL, NULL);
|
||||||
EvdevInitProperty(device);
|
EvdevInitProperty(device);
|
||||||
EvdevMBEmuInitProperty(device);
|
EvdevMBEmuInitProperty(device);
|
||||||
@@ -978,7 +1092,7 @@ EvdevOn(DeviceIntPtr device)
|
|||||||
pInfo = device->public.devicePrivate;
|
pInfo = device->public.devicePrivate;
|
||||||
pEvdev = pInfo->private;
|
pEvdev = pInfo->private;
|
||||||
|
|
||||||
if (pInfo->fd != -1 && !pEvdev->kernel24 &&
|
if (pInfo->fd != -1 && pEvdev->grabDevice &&
|
||||||
(rc = ioctl(pInfo->fd, EVIOCGRAB, (void *)1)))
|
(rc = ioctl(pInfo->fd, EVIOCGRAB, (void *)1)))
|
||||||
{
|
{
|
||||||
xf86Msg(X_WARNING, "%s: Grab failed (%s)\n", pInfo->name,
|
xf86Msg(X_WARNING, "%s: Grab failed (%s)\n", pInfo->name,
|
||||||
@@ -998,14 +1112,17 @@ EvdevOn(DeviceIntPtr device)
|
|||||||
pEvdev->reopen_timer = TimerSet(NULL, 0, 100, EvdevReopenTimer, pInfo);
|
pEvdev->reopen_timer = TimerSet(NULL, 0, 100, EvdevReopenTimer, pInfo);
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
xf86AddEnabledDevice(pInfo);
|
pEvdev->min_maj = EvdevGetMajorMinor(pInfo);
|
||||||
if ((pEvdev->flags & EVDEV_BUTTON_EVENTS) &&
|
if (EvdevIsDuplicate(pInfo))
|
||||||
!(pEvdev->flags & EVDEV_INITIALIZED))
|
|
||||||
{
|
{
|
||||||
EvdevMBEmuPreInit(pInfo);
|
xf86Msg(X_WARNING, "%s: Refusing to enable duplicate device.\n",
|
||||||
EvdevWheelEmuPreInit(pInfo);
|
pInfo->name);
|
||||||
EvdevDragLockInit(pInfo);
|
return !Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xf86FlushInput(pInfo->fd);
|
||||||
|
xf86AddEnabledDevice(pInfo);
|
||||||
|
EvdevMBEmuOn(pInfo);
|
||||||
pEvdev->flags |= EVDEV_INITIALIZED;
|
pEvdev->flags |= EVDEV_INITIALIZED;
|
||||||
device->public.on = TRUE;
|
device->public.on = TRUE;
|
||||||
}
|
}
|
||||||
@@ -1032,17 +1149,18 @@ EvdevProc(DeviceIntPtr device, int what)
|
|||||||
return EvdevOn(device);
|
return EvdevOn(device);
|
||||||
|
|
||||||
case DEVICE_OFF:
|
case DEVICE_OFF:
|
||||||
|
if (pEvdev->flags & EVDEV_INITIALIZED)
|
||||||
|
EvdevMBEmuFinalize(pInfo);
|
||||||
if (pInfo->fd != -1)
|
if (pInfo->fd != -1)
|
||||||
{
|
{
|
||||||
if (!pEvdev->kernel24 && ioctl(pInfo->fd, EVIOCGRAB, (void *)0))
|
if (pEvdev->grabDevice && ioctl(pInfo->fd, EVIOCGRAB, (void *)0))
|
||||||
xf86Msg(X_WARNING, "%s: Release failed (%s)\n", pInfo->name,
|
xf86Msg(X_WARNING, "%s: Release failed (%s)\n", pInfo->name,
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
xf86RemoveEnabledDevice(pInfo);
|
xf86RemoveEnabledDevice(pInfo);
|
||||||
close(pInfo->fd);
|
close(pInfo->fd);
|
||||||
pInfo->fd = -1;
|
pInfo->fd = -1;
|
||||||
}
|
}
|
||||||
if (pEvdev->flags & EVDEV_INITIALIZED)
|
pEvdev->min_maj = 0;
|
||||||
EvdevMBEmuFinalize(pInfo);
|
|
||||||
pEvdev->flags &= ~EVDEV_INITIALIZED;
|
pEvdev->flags &= ~EVDEV_INITIALIZED;
|
||||||
device->public.on = FALSE;
|
device->public.on = FALSE;
|
||||||
if (pEvdev->reopen_timer)
|
if (pEvdev->reopen_timer)
|
||||||
@@ -1058,6 +1176,8 @@ EvdevProc(DeviceIntPtr device, int what)
|
|||||||
close(pInfo->fd);
|
close(pInfo->fd);
|
||||||
pInfo->fd = -1;
|
pInfo->fd = -1;
|
||||||
}
|
}
|
||||||
|
EvdevRemoveDevice(pInfo);
|
||||||
|
pEvdev->min_maj = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1079,12 +1199,12 @@ EvdevCacheCompare(InputInfoPtr pInfo, BOOL compare)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
char name[1024] = {0};
|
char name[1024] = {0};
|
||||||
long bitmask[NBITS(EV_MAX)] = {0};
|
long bitmask[NLONGS(EV_CNT)] = {0};
|
||||||
long key_bitmask[NBITS(KEY_MAX)] = {0};
|
long key_bitmask[NLONGS(KEY_CNT)] = {0};
|
||||||
long rel_bitmask[NBITS(REL_MAX)] = {0};
|
long rel_bitmask[NLONGS(REL_CNT)] = {0};
|
||||||
long abs_bitmask[NBITS(ABS_MAX)] = {0};
|
long abs_bitmask[NLONGS(ABS_CNT)] = {0};
|
||||||
long led_bitmask[NBITS(LED_MAX)] = {0};
|
long led_bitmask[NLONGS(LED_CNT)] = {0};
|
||||||
struct input_absinfo absinfo[ABS_MAX];
|
struct input_absinfo absinfo[ABS_CNT];
|
||||||
|
|
||||||
if (ioctl(pInfo->fd,
|
if (ioctl(pInfo->fd,
|
||||||
EVIOCGNAME(sizeof(name) - 1), name) < 0) {
|
EVIOCGNAME(sizeof(name) - 1), name) < 0) {
|
||||||
@@ -1092,70 +1212,86 @@ EvdevCacheCompare(InputInfoPtr pInfo, BOOL compare)
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (compare && strcmp(pEvdev->name, name))
|
if (compare && strcmp(pEvdev->name, name)) {
|
||||||
goto error;
|
xf86Msg(X_ERROR, "%s: device name changed: %s != %s\n", pInfo->name, pEvdev->name, name);
|
||||||
|
|
||||||
if (ioctl(pInfo->fd,
|
|
||||||
EVIOCGBIT(0, sizeof(bitmask)), bitmask) < 0) {
|
|
||||||
xf86Msg(X_ERROR, "ioctl EVIOCGNAME failed: %s\n", strerror(errno));
|
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (compare && memcmp(pEvdev->bitmask, bitmask, sizeof(bitmask)))
|
if (ioctl(pInfo->fd,
|
||||||
|
EVIOCGBIT(0, sizeof(bitmask)), bitmask) < 0) {
|
||||||
|
xf86Msg(X_ERROR, "%s: ioctl EVIOCGBIT failed: %s\n", pInfo->name, strerror(errno));
|
||||||
goto error;
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (compare && memcmp(pEvdev->bitmask, bitmask, sizeof(bitmask))) {
|
||||||
|
xf86Msg(X_ERROR, "%s: device bitmask has changed\n", pInfo->name);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (ioctl(pInfo->fd,
|
if (ioctl(pInfo->fd,
|
||||||
EVIOCGBIT(EV_REL, sizeof(rel_bitmask)), rel_bitmask) < 0) {
|
EVIOCGBIT(EV_REL, sizeof(rel_bitmask)), rel_bitmask) < 0) {
|
||||||
xf86Msg(X_ERROR, "ioctl EVIOCGBIT failed: %s\n", strerror(errno));
|
xf86Msg(X_ERROR, "%s: ioctl EVIOCGBIT failed: %s\n", pInfo->name, strerror(errno));
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (compare && memcmp(pEvdev->rel_bitmask, rel_bitmask, sizeof(rel_bitmask)))
|
if (compare && memcmp(pEvdev->rel_bitmask, rel_bitmask, sizeof(rel_bitmask))) {
|
||||||
|
xf86Msg(X_ERROR, "%s: device rel_bitmask has changed\n", pInfo->name);
|
||||||
goto error;
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
if (ioctl(pInfo->fd,
|
if (ioctl(pInfo->fd,
|
||||||
EVIOCGBIT(EV_ABS, sizeof(abs_bitmask)), abs_bitmask) < 0) {
|
EVIOCGBIT(EV_ABS, sizeof(abs_bitmask)), abs_bitmask) < 0) {
|
||||||
xf86Msg(X_ERROR, "ioctl EVIOCGBIT failed: %s\n", strerror(errno));
|
xf86Msg(X_ERROR, "%s: ioctl EVIOCGBIT failed: %s\n", pInfo->name, strerror(errno));
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (compare && memcmp(pEvdev->abs_bitmask, abs_bitmask, sizeof(abs_bitmask)))
|
if (compare && memcmp(pEvdev->abs_bitmask, abs_bitmask, sizeof(abs_bitmask))) {
|
||||||
|
xf86Msg(X_ERROR, "%s: device abs_bitmask has changed\n", pInfo->name);
|
||||||
goto error;
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
if (ioctl(pInfo->fd,
|
if (ioctl(pInfo->fd,
|
||||||
EVIOCGBIT(EV_KEY, sizeof(key_bitmask)), key_bitmask) < 0) {
|
EVIOCGBIT(EV_KEY, sizeof(key_bitmask)), key_bitmask) < 0) {
|
||||||
xf86Msg(X_ERROR, "ioctl EVIOCGBIT failed: %s\n", strerror(errno));
|
xf86Msg(X_ERROR, "%s: ioctl EVIOCGBIT failed: %s\n", pInfo->name, strerror(errno));
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (compare && memcmp(pEvdev->key_bitmask, key_bitmask, sizeof(key_bitmask)))
|
if (compare && memcmp(pEvdev->key_bitmask, key_bitmask, sizeof(key_bitmask))) {
|
||||||
|
xf86Msg(X_ERROR, "%s: device key_bitmask has changed\n", pInfo->name);
|
||||||
goto error;
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
if (ioctl(pInfo->fd,
|
if (ioctl(pInfo->fd,
|
||||||
EVIOCGBIT(EV_LED, sizeof(led_bitmask)), led_bitmask) < 0) {
|
EVIOCGBIT(EV_LED, sizeof(led_bitmask)), led_bitmask) < 0) {
|
||||||
xf86Msg(X_ERROR, "ioctl EVIOCGBIT failed: %s\n", strerror(errno));
|
xf86Msg(X_ERROR, "%s: ioctl EVIOCGBIT failed: %s\n", pInfo->name, strerror(errno));
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (compare && memcmp(pEvdev->led_bitmask, led_bitmask, sizeof(led_bitmask)))
|
if (compare && memcmp(pEvdev->led_bitmask, led_bitmask, sizeof(led_bitmask))) {
|
||||||
|
xf86Msg(X_ERROR, "%s: device led_bitmask has changed\n", pInfo->name);
|
||||||
goto error;
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
memset(absinfo, 0, sizeof(absinfo));
|
memset(absinfo, 0, sizeof(absinfo));
|
||||||
|
|
||||||
for (i = 0; i < ABS_MAX; i++)
|
for (i = ABS_X; i <= ABS_MAX; i++)
|
||||||
{
|
{
|
||||||
if (TestBit(i, abs_bitmask))
|
if (TestBit(i, abs_bitmask))
|
||||||
{
|
{
|
||||||
if (ioctl(pInfo->fd, EVIOCGABS(i), &absinfo[i]) < 0) {
|
if (ioctl(pInfo->fd, EVIOCGABS(i), &absinfo[i]) < 0) {
|
||||||
xf86Msg(X_ERROR, "ioctl EVIOCGABS failed: %s\n", strerror(errno));
|
xf86Msg(X_ERROR, "%s: ioctl EVIOCGABS failed: %s\n", pInfo->name, strerror(errno));
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
/* ignore current position (value) in comparison (bug #19819) */
|
||||||
|
absinfo[i].value = pEvdev->absinfo[i].value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (compare && memcmp(pEvdev->absinfo, absinfo, sizeof(absinfo)))
|
if (compare && memcmp(pEvdev->absinfo, absinfo, sizeof(absinfo))) {
|
||||||
goto error;
|
xf86Msg(X_ERROR, "%s: device absinfo has changed\n", pInfo->name);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
/* cache info */
|
/* cache info */
|
||||||
if (!compare)
|
if (!compare)
|
||||||
@@ -1179,21 +1315,23 @@ error:
|
|||||||
static int
|
static int
|
||||||
EvdevProbe(InputInfoPtr pInfo)
|
EvdevProbe(InputInfoPtr pInfo)
|
||||||
{
|
{
|
||||||
long key_bitmask[NBITS(KEY_MAX)];
|
long key_bitmask[NLONGS(KEY_CNT)] = {0};
|
||||||
long rel_bitmask[NBITS(REL_MAX)];
|
long rel_bitmask[NLONGS(REL_CNT)] = {0};
|
||||||
long abs_bitmask[NBITS(ABS_MAX)];
|
long abs_bitmask[NLONGS(ABS_CNT)] = {0};
|
||||||
int i, has_axes, has_keys, num_buttons;
|
int i, has_axes, has_keys, num_buttons;
|
||||||
|
int kernel24 = 0;
|
||||||
EvdevPtr pEvdev = pInfo->private;
|
EvdevPtr pEvdev = pInfo->private;
|
||||||
|
|
||||||
if (ioctl(pInfo->fd, EVIOCGRAB, (void *)1)) {
|
if (pEvdev->grabDevice && ioctl(pInfo->fd, EVIOCGRAB, (void *)1)) {
|
||||||
if (errno == EINVAL) {
|
if (errno == EINVAL) {
|
||||||
/* keyboards are unsafe in 2.4 */
|
/* keyboards are unsafe in 2.4 */
|
||||||
pEvdev->kernel24 = 1;
|
kernel24 = 1;
|
||||||
|
pEvdev->grabDevice = 0;
|
||||||
} else {
|
} else {
|
||||||
xf86Msg(X_ERROR, "Grab failed. Device already configured?\n");
|
xf86Msg(X_ERROR, "Grab failed. Device already configured?\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else if (pEvdev->grabDevice) {
|
||||||
ioctl(pInfo->fd, EVIOCGRAB, (void *)0);
|
ioctl(pInfo->fd, EVIOCGRAB, (void *)0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1219,23 +1357,6 @@ EvdevProbe(InputInfoPtr pInfo)
|
|||||||
has_keys = FALSE;
|
has_keys = FALSE;
|
||||||
num_buttons = 0;
|
num_buttons = 0;
|
||||||
|
|
||||||
if (TestBit(REL_X, rel_bitmask) && TestBit(REL_Y, rel_bitmask)) {
|
|
||||||
xf86Msg(X_INFO, "%s: Found x and y relative axes\n", pInfo->name);
|
|
||||||
pEvdev->flags |= EVDEV_RELATIVE_EVENTS;
|
|
||||||
has_axes = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TestBit(ABS_X, abs_bitmask) && TestBit(ABS_Y, abs_bitmask)) {
|
|
||||||
xf86Msg(X_INFO, "%s: Found x and y absolute axes\n", pInfo->name);
|
|
||||||
pEvdev->flags |= EVDEV_ABSOLUTE_EVENTS;
|
|
||||||
if (TestBit(BTN_TOUCH, key_bitmask)) {
|
|
||||||
xf86Msg(X_INFO, "%s: Found absolute touchpad\n", pInfo->name);
|
|
||||||
pEvdev->flags |= EVDEV_TOUCHPAD;
|
|
||||||
pEvdev->old_x = pEvdev->old_y = -1;
|
|
||||||
}
|
|
||||||
has_axes = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* count all buttons */
|
/* count all buttons */
|
||||||
for (i = BTN_MISC; i < BTN_JOYSTICK; i++)
|
for (i = BTN_MISC; i < BTN_JOYSTICK; i++)
|
||||||
{
|
{
|
||||||
@@ -1251,6 +1372,29 @@ EvdevProbe(InputInfoPtr pInfo)
|
|||||||
num_buttons);
|
num_buttons);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (TestBit(REL_X, rel_bitmask) && TestBit(REL_Y, rel_bitmask)) {
|
||||||
|
xf86Msg(X_INFO, "%s: Found x and y relative axes\n", pInfo->name);
|
||||||
|
pEvdev->flags |= EVDEV_RELATIVE_EVENTS;
|
||||||
|
has_axes = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TestBit(ABS_X, abs_bitmask) && TestBit(ABS_Y, abs_bitmask)) {
|
||||||
|
xf86Msg(X_INFO, "%s: Found x and y absolute axes\n", pInfo->name);
|
||||||
|
pEvdev->flags |= EVDEV_ABSOLUTE_EVENTS;
|
||||||
|
if (TestBit(BTN_TOUCH, key_bitmask)) {
|
||||||
|
if (num_buttons) {
|
||||||
|
xf86Msg(X_INFO, "%s: Found absolute touchpad\n", pInfo->name);
|
||||||
|
pEvdev->flags |= EVDEV_TOUCHPAD;
|
||||||
|
pEvdev->old_x = pEvdev->old_y = -1;
|
||||||
|
} else {
|
||||||
|
xf86Msg(X_INFO, "%s: Found absolute touchscreen\n", pInfo->name);
|
||||||
|
pEvdev->flags |= EVDEV_TOUCHSCREEN;
|
||||||
|
pEvdev->flags |= EVDEV_BUTTON_EVENTS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
has_axes = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < BTN_MISC; i++)
|
for (i = 0; i < BTN_MISC; i++)
|
||||||
if (TestBit(i, key_bitmask))
|
if (TestBit(i, key_bitmask))
|
||||||
break;
|
break;
|
||||||
@@ -1268,8 +1412,15 @@ EvdevProbe(InputInfoPtr pInfo)
|
|||||||
pInfo->type_name = XI_MOUSE;
|
pInfo->type_name = XI_MOUSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pEvdev->flags & EVDEV_TOUCHSCREEN) {
|
||||||
|
xf86Msg(X_INFO, "%s: Configuring as touchscreen\n", pInfo->name);
|
||||||
|
pInfo->type_name = XI_TOUCHSCREEN;
|
||||||
|
pInfo->flags |= XI86_POINTER_CAPABLE | XI86_SEND_DRAG_EVENTS |
|
||||||
|
XI86_CONFIGURED;
|
||||||
|
}
|
||||||
|
|
||||||
if (has_keys) {
|
if (has_keys) {
|
||||||
if (pEvdev->kernel24) {
|
if (kernel24) {
|
||||||
xf86Msg(X_INFO, "%s: Kernel < 2.6 is too old, ignoring keyboard\n",
|
xf86Msg(X_INFO, "%s: Kernel < 2.6 is too old, ignoring keyboard\n",
|
||||||
pInfo->name);
|
pInfo->name);
|
||||||
} else {
|
} else {
|
||||||
@@ -1293,7 +1444,6 @@ static InputInfoPtr
|
|||||||
EvdevPreInit(InputDriverPtr drv, IDevPtr dev, int flags)
|
EvdevPreInit(InputDriverPtr drv, IDevPtr dev, int flags)
|
||||||
{
|
{
|
||||||
InputInfoPtr pInfo;
|
InputInfoPtr pInfo;
|
||||||
MessageType deviceFrom = X_CONFIG;
|
|
||||||
const char *device;
|
const char *device;
|
||||||
EvdevPtr pEvdev;
|
EvdevPtr pEvdev;
|
||||||
|
|
||||||
@@ -1340,7 +1490,7 @@ EvdevPreInit(InputDriverPtr drv, IDevPtr dev, int flags)
|
|||||||
|
|
||||||
pEvdev->device = device;
|
pEvdev->device = device;
|
||||||
|
|
||||||
xf86Msg(deviceFrom, "%s: Device: \"%s\"\n", pInfo->name, device);
|
xf86Msg(X_CONFIG, "%s: Device: \"%s\"\n", pInfo->name, device);
|
||||||
do {
|
do {
|
||||||
pInfo->fd = open(device, O_RDWR, 0);
|
pInfo->fd = open(device, O_RDWR, 0);
|
||||||
} while (pInfo->fd < 0 && errno == EINTR);
|
} while (pInfo->fd < 0 && errno == EINTR);
|
||||||
@@ -1351,9 +1501,26 @@ EvdevPreInit(InputDriverPtr drv, IDevPtr dev, int flags)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check major/minor of device node to avoid adding duplicate devices. */
|
||||||
|
pEvdev->min_maj = EvdevGetMajorMinor(pInfo);
|
||||||
|
if (EvdevIsDuplicate(pInfo))
|
||||||
|
{
|
||||||
|
xf86Msg(X_WARNING, "%s: device file already in use. Ignoring.\n",
|
||||||
|
pInfo->name);
|
||||||
|
close(pInfo->fd);
|
||||||
|
xf86DeleteInput(pInfo, 0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
pEvdev->reopen_attempts = xf86SetIntOption(pInfo->options, "ReopenAttempts", 10);
|
pEvdev->reopen_attempts = xf86SetIntOption(pInfo->options, "ReopenAttempts", 10);
|
||||||
pEvdev->invert_x = xf86SetBoolOption(pInfo->options, "InvertX", FALSE);
|
pEvdev->invert_x = xf86SetBoolOption(pInfo->options, "InvertX", FALSE);
|
||||||
pEvdev->invert_y = xf86SetBoolOption(pInfo->options, "InvertY", FALSE);
|
pEvdev->invert_y = xf86SetBoolOption(pInfo->options, "InvertY", FALSE);
|
||||||
|
pEvdev->swap_axes = xf86SetBoolOption(pInfo->options, "SwapAxes", FALSE);
|
||||||
|
|
||||||
|
/* Grabbing the event device stops in-kernel event forwarding. In other
|
||||||
|
words, it disables rfkill and the "Macintosh mouse button emulation".
|
||||||
|
Note that this needs a server that sets the console to RAW mode. */
|
||||||
|
pEvdev->grabDevice = xf86CheckBoolOption(dev->commonOptions, "GrabDevice", 0);
|
||||||
|
|
||||||
pEvdev->noXkb = noXkbExtension; /* parse the XKB options during kbd setup */
|
pEvdev->noXkb = noXkbExtension; /* parse the XKB options during kbd setup */
|
||||||
|
|
||||||
@@ -1366,6 +1533,14 @@ EvdevPreInit(InputDriverPtr drv, IDevPtr dev, int flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
EvdevCacheCompare(pInfo, FALSE); /* cache device data */
|
EvdevCacheCompare(pInfo, FALSE); /* cache device data */
|
||||||
|
EvdevAddDevice(pInfo);
|
||||||
|
|
||||||
|
if (pEvdev->flags & EVDEV_BUTTON_EVENTS)
|
||||||
|
{
|
||||||
|
EvdevMBEmuPreInit(pInfo);
|
||||||
|
EvdevWheelEmuPreInit(pInfo);
|
||||||
|
EvdevDragLockPreInit(pInfo);
|
||||||
|
}
|
||||||
|
|
||||||
return pInfo;
|
return pInfo;
|
||||||
}
|
}
|
||||||
@@ -1421,7 +1596,7 @@ _X_EXPORT XF86ModuleData evdevModuleData =
|
|||||||
* returns 0 on non-button event.
|
* returns 0 on non-button event.
|
||||||
*/
|
*/
|
||||||
unsigned int
|
unsigned int
|
||||||
EvdevUtilButtonEventToButtonNumber(int code)
|
EvdevUtilButtonEventToButtonNumber(EvdevPtr pEvdev, int code)
|
||||||
{
|
{
|
||||||
unsigned int button = 0;
|
unsigned int button = 0;
|
||||||
|
|
||||||
@@ -1438,6 +1613,21 @@ EvdevUtilButtonEventToButtonNumber(int code)
|
|||||||
button = 2;
|
button = 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/* Treat BTN_[0-2] as LMR buttons on devices that do not advertise
|
||||||
|
BTN_LEFT, BTN_MIDDLE, BTN_RIGHT.
|
||||||
|
Otherwise, treat BTN_[0+n] as button 5+n.
|
||||||
|
XXX: This causes duplicate mappings for BTN_0 + n and BTN_SIDE + n
|
||||||
|
*/
|
||||||
|
case BTN_0:
|
||||||
|
button = (TestBit(BTN_LEFT, pEvdev->key_bitmask)) ? 8 : 1;
|
||||||
|
break;
|
||||||
|
case BTN_1:
|
||||||
|
button = (TestBit(BTN_MIDDLE, pEvdev->key_bitmask)) ? 9 : 2;
|
||||||
|
break;
|
||||||
|
case BTN_2:
|
||||||
|
button = (TestBit(BTN_RIGHT, pEvdev->key_bitmask)) ? 10 : 3;
|
||||||
|
break;
|
||||||
|
|
||||||
case BTN_SIDE:
|
case BTN_SIDE:
|
||||||
case BTN_EXTRA:
|
case BTN_EXTRA:
|
||||||
case BTN_FORWARD:
|
case BTN_FORWARD:
|
||||||
@@ -1448,8 +1638,12 @@ EvdevUtilButtonEventToButtonNumber(int code)
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
if ((code > BTN_TASK) && (code < KEY_OK)) {
|
if ((code > BTN_TASK) && (code < KEY_OK)) {
|
||||||
if (code < BTN_JOYSTICK)
|
if (code < BTN_JOYSTICK) {
|
||||||
button = (code - BTN_LEFT + 5);
|
if (code < BTN_MOUSE)
|
||||||
|
button = (code - BTN_0 + 5);
|
||||||
|
else
|
||||||
|
button = (code - BTN_LEFT + 5);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1467,19 +1661,54 @@ EvdevInitProperty(DeviceIntPtr dev)
|
|||||||
EvdevPtr pEvdev = pInfo->private;
|
EvdevPtr pEvdev = pInfo->private;
|
||||||
int rc;
|
int rc;
|
||||||
BOOL invert[2];
|
BOOL invert[2];
|
||||||
|
char reopen;
|
||||||
|
|
||||||
invert[0] = pEvdev->invert_x;
|
prop_reopen = MakeAtom(EVDEV_PROP_REOPEN, strlen(EVDEV_PROP_REOPEN),
|
||||||
invert[1] = pEvdev->invert_y;
|
TRUE);
|
||||||
|
|
||||||
prop_invert = MakeAtom(EVDEV_PROP_INVERT_AXES, strlen(EVDEV_PROP_INVERT_AXES), TRUE);
|
reopen = pEvdev->reopen_attempts;
|
||||||
|
rc = XIChangeDeviceProperty(dev, prop_reopen, XA_INTEGER, 8,
|
||||||
rc = XIChangeDeviceProperty(dev, prop_invert, XA_INTEGER, 8,
|
PropModeReplace, 1, &reopen, FALSE);
|
||||||
PropModeReplace, 2,
|
|
||||||
invert, FALSE);
|
|
||||||
if (rc != Success)
|
if (rc != Success)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
XISetDevicePropertyDeletable(dev, prop_invert, FALSE);
|
XISetDevicePropertyDeletable(dev, prop_reopen, FALSE);
|
||||||
|
|
||||||
|
if (pEvdev->flags & (EVDEV_RELATIVE_EVENTS | EVDEV_ABSOLUTE_EVENTS))
|
||||||
|
{
|
||||||
|
invert[0] = pEvdev->invert_x;
|
||||||
|
invert[1] = pEvdev->invert_y;
|
||||||
|
|
||||||
|
prop_invert = MakeAtom(EVDEV_PROP_INVERT_AXES, strlen(EVDEV_PROP_INVERT_AXES), TRUE);
|
||||||
|
|
||||||
|
rc = XIChangeDeviceProperty(dev, prop_invert, XA_INTEGER, 8,
|
||||||
|
PropModeReplace, 2,
|
||||||
|
invert, FALSE);
|
||||||
|
if (rc != Success)
|
||||||
|
return;
|
||||||
|
|
||||||
|
XISetDevicePropertyDeletable(dev, prop_invert, FALSE);
|
||||||
|
|
||||||
|
prop_calibration = MakeAtom(EVDEV_PROP_CALIBRATION,
|
||||||
|
strlen(EVDEV_PROP_CALIBRATION), TRUE);
|
||||||
|
rc = XIChangeDeviceProperty(dev, prop_calibration, XA_INTEGER, 32,
|
||||||
|
PropModeReplace, 0, NULL, FALSE);
|
||||||
|
if (rc != Success)
|
||||||
|
return;
|
||||||
|
|
||||||
|
XISetDevicePropertyDeletable(dev, prop_calibration, FALSE);
|
||||||
|
|
||||||
|
prop_swap = MakeAtom(EVDEV_PROP_SWAP_AXES,
|
||||||
|
strlen(EVDEV_PROP_SWAP_AXES), TRUE);
|
||||||
|
|
||||||
|
rc = XIChangeDeviceProperty(dev, prop_swap, XA_INTEGER, 8,
|
||||||
|
PropModeReplace, 1, &pEvdev->swap_axes, FALSE);
|
||||||
|
if (rc != Success)
|
||||||
|
return;
|
||||||
|
|
||||||
|
XISetDevicePropertyDeletable(dev, prop_swap, FALSE);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -1501,6 +1730,47 @@ EvdevSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
|
|||||||
pEvdev->invert_x = data[0];
|
pEvdev->invert_x = data[0];
|
||||||
pEvdev->invert_y = data[1];
|
pEvdev->invert_y = data[1];
|
||||||
}
|
}
|
||||||
|
} else if (atom == prop_reopen)
|
||||||
|
{
|
||||||
|
if (val->format != 8 || val->size != 1 || val->type != XA_INTEGER)
|
||||||
|
return BadMatch;
|
||||||
|
|
||||||
|
if (!checkonly)
|
||||||
|
pEvdev->reopen_attempts = *((CARD8*)val->data);
|
||||||
|
} else if (atom == prop_calibration)
|
||||||
|
{
|
||||||
|
if (val->format != 32 || val->type != XA_INTEGER)
|
||||||
|
return BadMatch;
|
||||||
|
if (val->size != 4 && val->size != 0)
|
||||||
|
return BadMatch;
|
||||||
|
|
||||||
|
if (!checkonly)
|
||||||
|
{
|
||||||
|
if (val->size == 0)
|
||||||
|
{
|
||||||
|
pEvdev->flags &= ~EVDEV_CALIBRATED;
|
||||||
|
pEvdev->calibration.min_x = 0;
|
||||||
|
pEvdev->calibration.max_x = 0;
|
||||||
|
pEvdev->calibration.min_y = 0;
|
||||||
|
pEvdev->calibration.max_y = 0;
|
||||||
|
} else if (val->size == 4)
|
||||||
|
{
|
||||||
|
CARD32 *vals = (CARD32*)val->data;
|
||||||
|
|
||||||
|
pEvdev->flags |= EVDEV_CALIBRATED;
|
||||||
|
pEvdev->calibration.min_x = vals[0];
|
||||||
|
pEvdev->calibration.max_x = vals[1];
|
||||||
|
pEvdev->calibration.min_y = vals[2];
|
||||||
|
pEvdev->calibration.max_y = vals[3];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (atom == prop_swap)
|
||||||
|
{
|
||||||
|
if (val->format != 8 || val->type != XA_INTEGER || val->size != 1)
|
||||||
|
return BadMatch;
|
||||||
|
|
||||||
|
if (!checkonly)
|
||||||
|
pEvdev->swap_axes = *((BOOL*)val->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Success;
|
return Success;
|
||||||
|
|||||||
75
src/evdev.h
75
src/evdev.h
@@ -31,13 +31,29 @@
|
|||||||
#define EVDEV_H
|
#define EVDEV_H
|
||||||
|
|
||||||
#include <linux/input.h>
|
#include <linux/input.h>
|
||||||
|
#include <linux/types.h>
|
||||||
|
|
||||||
#include <xf86Xinput.h>
|
#include <xf86Xinput.h>
|
||||||
#include <xf86_OSproc.h>
|
#include <xf86_OSproc.h>
|
||||||
|
|
||||||
#if defined(XKB)
|
#ifdef XKB
|
||||||
/* XXX VERY WRONG. this is a client side header. */
|
#include <xkbstr.h>
|
||||||
#include <X11/extensions/XKBstr.h>
|
#endif
|
||||||
|
|
||||||
|
#ifndef EV_CNT /* linux 2.4 kernels and earlier lack _CNT defines */
|
||||||
|
#define EV_CNT (EV_MAX+1)
|
||||||
|
#endif
|
||||||
|
#ifndef KEY_CNT
|
||||||
|
#define KEY_CNT (KEY_MAX+1)
|
||||||
|
#endif
|
||||||
|
#ifndef REL_CNT
|
||||||
|
#define REL_CNT (REL_MAX+1)
|
||||||
|
#endif
|
||||||
|
#ifndef ABS_CNT
|
||||||
|
#define ABS_CNT (ABS_MAX+1)
|
||||||
|
#endif
|
||||||
|
#ifndef LED_CNT
|
||||||
|
#define LED_CNT (LED_MAX+1)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define EVDEV_MAXBUTTONS 32
|
#define EVDEV_MAXBUTTONS 32
|
||||||
@@ -47,7 +63,9 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define LONG_BITS (sizeof(long) * 8)
|
#define LONG_BITS (sizeof(long) * 8)
|
||||||
#define NBITS(x) (((x) + LONG_BITS - 1) / LONG_BITS)
|
|
||||||
|
/* Number of longs needed to hold the given number of bits */
|
||||||
|
#define NLONGS(x) (((x) + LONG_BITS - 1) / LONG_BITS)
|
||||||
|
|
||||||
/* axis specific data for wheel emulation */
|
/* axis specific data for wheel emulation */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -58,13 +76,14 @@ typedef struct {
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const char *device;
|
const char *device;
|
||||||
int kernel24;
|
int grabDevice; /* grab the event device? */
|
||||||
int screen;
|
int screen;
|
||||||
int min_x, min_y, max_x, max_y;
|
int min_x, min_y, max_x, max_y;
|
||||||
int abs_x, abs_y, old_x, old_y;
|
int abs_x, abs_y, old_x, old_y;
|
||||||
int flags;
|
int flags;
|
||||||
int tool;
|
int tool;
|
||||||
int buttons; /* number of buttons */
|
int buttons; /* number of buttons */
|
||||||
|
BOOL swap_axes;
|
||||||
BOOL invert_x;
|
BOOL invert_x;
|
||||||
BOOL invert_y;
|
BOOL invert_y;
|
||||||
|
|
||||||
@@ -103,6 +122,13 @@ typedef struct {
|
|||||||
Time expires; /* time of expiry */
|
Time expires; /* time of expiry */
|
||||||
Time timeout;
|
Time timeout;
|
||||||
} emulateWheel;
|
} emulateWheel;
|
||||||
|
/* run-time calibration */
|
||||||
|
struct {
|
||||||
|
int min_x;
|
||||||
|
int max_x;
|
||||||
|
int min_y;
|
||||||
|
int max_y;
|
||||||
|
} calibration;
|
||||||
|
|
||||||
unsigned char btnmap[32]; /* config-file specified button mapping */
|
unsigned char btnmap[32]; /* config-file specified button mapping */
|
||||||
|
|
||||||
@@ -112,42 +138,41 @@ typedef struct {
|
|||||||
|
|
||||||
/* Cached info from device. */
|
/* Cached info from device. */
|
||||||
char name[1024];
|
char name[1024];
|
||||||
long bitmask[NBITS(EV_MAX)];
|
long bitmask[NLONGS(EV_CNT)];
|
||||||
long key_bitmask[NBITS(KEY_MAX)];
|
long key_bitmask[NLONGS(KEY_CNT)];
|
||||||
long rel_bitmask[NBITS(REL_MAX)];
|
long rel_bitmask[NLONGS(REL_CNT)];
|
||||||
long abs_bitmask[NBITS(ABS_MAX)];
|
long abs_bitmask[NLONGS(ABS_CNT)];
|
||||||
long led_bitmask[NBITS(LED_MAX)];
|
long led_bitmask[NLONGS(LED_CNT)];
|
||||||
struct input_absinfo absinfo[ABS_MAX];
|
struct input_absinfo absinfo[ABS_CNT];
|
||||||
|
|
||||||
|
/* minor/major number */
|
||||||
|
dev_t min_maj;
|
||||||
} EvdevRec, *EvdevPtr;
|
} EvdevRec, *EvdevPtr;
|
||||||
|
|
||||||
|
unsigned int EvdevUtilButtonEventToButtonNumber(EvdevPtr pEvdev, int code);
|
||||||
|
|
||||||
/* Middle Button emulation */
|
/* Middle Button emulation */
|
||||||
int EvdevMBEmuTimer(InputInfoPtr);
|
int EvdevMBEmuTimer(InputInfoPtr);
|
||||||
BOOL EvdevMBEmuFilterEvent(InputInfoPtr, int, BOOL);
|
BOOL EvdevMBEmuFilterEvent(InputInfoPtr, int, BOOL);
|
||||||
void EvdevMBEmuWakeupHandler(pointer, int, pointer);
|
void EvdevMBEmuWakeupHandler(pointer, int, pointer);
|
||||||
void EvdevMBEmuBlockHandler(pointer, struct timeval**, pointer);
|
void EvdevMBEmuBlockHandler(pointer, struct timeval**, pointer);
|
||||||
void EvdevMBEmuPreInit(InputInfoPtr);
|
void EvdevMBEmuPreInit(InputInfoPtr);
|
||||||
|
void EvdevMBEmuOn(InputInfoPtr);
|
||||||
void EvdevMBEmuFinalize(InputInfoPtr);
|
void EvdevMBEmuFinalize(InputInfoPtr);
|
||||||
void EvdevMBEmuEnable(InputInfoPtr, BOOL);
|
void EvdevMBEmuEnable(InputInfoPtr, BOOL);
|
||||||
|
|
||||||
unsigned int EvdevUtilButtonEventToButtonNumber(int code);
|
|
||||||
|
|
||||||
#ifdef HAVE_PROPERTIES
|
|
||||||
void EvdevMBEmuInitProperty(DeviceIntPtr);
|
|
||||||
int EvdevMBEmuSetProperty(DeviceIntPtr, Atom, XIPropertyValuePtr, BOOL);
|
|
||||||
|
|
||||||
void EvdevWheelEmuInitProperty(DeviceIntPtr);
|
|
||||||
int EvdevWheelEmuSetProperty(DeviceIntPtr, Atom, XIPropertyValuePtr, BOOL);
|
|
||||||
|
|
||||||
void EvdevDragLockInitProperty(DeviceIntPtr);
|
|
||||||
int EvdevDragLockSetProperty(DeviceIntPtr, Atom, XIPropertyValuePtr, BOOL);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Mouse Wheel emulation */
|
/* Mouse Wheel emulation */
|
||||||
void EvdevWheelEmuPreInit(InputInfoPtr pInfo);
|
void EvdevWheelEmuPreInit(InputInfoPtr pInfo);
|
||||||
BOOL EvdevWheelEmuFilterButton(InputInfoPtr pInfo, unsigned int button, int value);
|
BOOL EvdevWheelEmuFilterButton(InputInfoPtr pInfo, unsigned int button, int value);
|
||||||
BOOL EvdevWheelEmuFilterMotion(InputInfoPtr pInfo, struct input_event *pEv);
|
BOOL EvdevWheelEmuFilterMotion(InputInfoPtr pInfo, struct input_event *pEv);
|
||||||
|
|
||||||
/* Draglock code */
|
/* Draglock code */
|
||||||
void EvdevDragLockInit(InputInfoPtr pInfo);
|
void EvdevDragLockPreInit(InputInfoPtr pInfo);
|
||||||
BOOL EvdevDragLockFilterEvent(InputInfoPtr pInfo, unsigned int button, int value);
|
BOOL EvdevDragLockFilterEvent(InputInfoPtr pInfo, unsigned int button, int value);
|
||||||
|
|
||||||
|
#ifdef HAVE_PROPERTIES
|
||||||
|
void EvdevMBEmuInitProperty(DeviceIntPtr);
|
||||||
|
void EvdevWheelEmuInitProperty(DeviceIntPtr);
|
||||||
|
void EvdevDragLockInitProperty(DeviceIntPtr);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user