Compare commits

...

30 Commits

Author SHA1 Message Date
Peter Hutterer
7ef4e2c5e1 evdev 2.1 RC 3
That's it, no more new features. Now it's down to bugfixing only.
2008-11-03 13:47:15 +10:30
Peter Hutterer
dd0eeacc24 Add support for axes swapping.
New option: SwapAxes (boolean)
New property: EVDEV_PROP_SWAP_AXES.

Actual swapping code written by Donnie Berkholz.

Signed-off-by: Peter Hutterer <peter.hutterer@redhat.com>
(cherry picked from commit 4826969f23)
2008-11-03 13:46:40 +10:30
Peter Hutterer
67c0ea6c94 Add support for run-time calibration.
Some devices require run-time axis calibration. We can't change the min/max
ranges once we've initialised the valuator structs though, so in-driver
run-time calibration is required.

If the property is set, the driver scales from the calibrated range to the
values reported to the X server (which then may scale to screen coordinates).
If the property is not set (i.e. zero items) no scaling is performed.
(cherry picked from commit 33eb36f266)
2008-11-03 13:46:39 +10:30
Peter Hutterer
6bcbbc0411 Treat BTN_[0-2] as LMR buttons if necessary.
Treat BTN_[0-2] as LMR buttons on devices that do not advertise BTN_LEFT,
BTN_MIDDLE, BTN_RIGHT (e.g. 3Dconnexion SpaceNavigator).

Otherwise, treat BTN_[0+n] as button 5+n. Note: This causes duplicate
mappings for BTN_0 + n and  BTN_SIDE + n.

This also fixes a bug where we could end up with negative button numbers after
trying to map BTN_0.

Signed-off-by: Peter Hutterer <peter.hutterer@redhat.com>
(cherry picked from commit 64554e4799)
2008-11-03 13:46:35 +10:30
Peter Hutterer
534a3734d0 Remove obsolete FIXME
xkeyboard-config's maps are perfectly able to cope with evdev now.

Signed-off-by: Peter Hutterer <peter.hutterer@redhat.com>
(cherry picked from commit b77f939857)
2008-11-03 13:46:35 +10:30
Peter Hutterer
215c230d5c Flush input after re-opening the fd.
Suggested by Julien Cristau.

Signed-off-by: Peter Hutterer <peter.hutterer@redhat.com>
(cherry picked from commit a43ab4999b)
2008-11-03 13:46:33 +10:30
Peter Hutterer
8f96530449 emuMB: add EvdevMBEmuOn and call from EvdevOn to register wakeup handlers.
This got broken in b0737bdbd1, when the
EmuMBPreInit call was removed from EvdevOn. As a result, VT switching away and
back wouldn't restore the wakeup handlers and mouse button presses
disappeared.
(cherry picked from commit af096e8c5d)
2008-11-03 13:46:31 +10:30
Peter Hutterer
4fb97edcd4 Fix axis inversion for absolute coordinates.
If min_x/y was not equal to 0, the inverted calculated range was off and leads
to inaccessible or out-of-range areas.
(cherry picked from commit 12498042fc)
2008-11-03 13:46:25 +10:30
Peter Hutterer
4e86393bc0 emulate MB: fix confusing log message.
If we're forcing MB emulation behaviour as per config, then at least state
whether we're forcing it off or on.

Found by Michel Dänzer.
(cherry picked from commit 0f8fcfccb3)
2008-11-03 13:46:17 +10:30
Peter Hutterer
a64a78791f evdev 2.1 RC 2 2008-10-23 17:16:36 +10:30
Peter Hutterer
09b2a5e87b Silence compiler warning by memsetting the struct properly.
(cherry picked from commit 0ab4c09e50)
2008-10-23 17:15:32 +10:30
Peter Hutterer
fa18a4a38d MB emulation timeout is stored as Time, make the property 32-bit too.
(cherry picked from commit d348eb8ce7)
2008-10-23 17:15:30 +10:30
Peter Hutterer
172523d745 Init ioctl bitmasks to 0, shuts up valgrind too.
(cherry picked from commit 2c1698fa61)
2008-10-23 17:15:28 +10:30
Søren Hauberg
8fb820ffaf Add touchscreen support.
Touchscreens are devices that do not have buttons and only advertise
BTN_TOUCH. Add a new flag to note the device type.

If BTN_TOUCH is detected, change it to BTN_LEFT and process it normally.
(cherry picked from commit 8c39302594)
2008-10-23 17:15:25 +10:30
Julien Cristau
c7893b212d Fix TestBit() on 64bit
Reported by Albert Damen <albrt@gmx.net>
X.Org Bug#18150 <http://bugs.freedesktop.org/show_bug.cgi?id=18150>
(cherry picked from commit f57e8face9)
2008-10-23 17:14:52 +10:30
Peter Hutterer
e9dd721e2d Add option "GrabDevice", don't grab the device by default.
We now have the matching code in the server to set the console to RAW mode and
don't need to grab the devices anymore.

This is an updated version of e8534d47c8, which
was reverted in 6dc4199155.
(cherry picked from commit 4912e2aa7f)
2008-10-23 17:14:49 +10:30
Peter Hutterer
cab104fd9e Don't post keycodes > 255.
If we only have keys > 255 we don't set up a key class rec, so don't post
them. It makes the server unhappy.

Signed-off-by: Julien Cristau <jcristau@debian.org>
(cherry picked from commit 7243116f55)
2008-10-23 17:14:45 +10:30
Peter Hutterer
708eb34599 evdev 2.1 RC 1. 2008-10-14 17:19:58 +10:30
Peter Hutterer
36a687796f Fix "Device reopened after N attempts" message.
(cherry picked from commit 0089d931ac)
2008-10-14 17:18:08 +10:30
Peter Hutterer
26229df106 Don't init draglock, etc. if we don't have the required capabilities.
(cherry picked from commit 0f5a5ac09e)
2008-10-14 17:18:07 +10:30
Peter Hutterer
f4616d87fc 8-bit properties should use 8-bit storage types...
(cherry picked from commit 36d68b006d)
2008-10-14 17:18:07 +10:30
Peter Hutterer
2aa5ca8cdd Don't include the client-side header anymore. xkbstr.h is server SDK.
(cherry picked from commit bb1f421687)
2008-10-14 17:18:07 +10:30
Peter Hutterer
39263dc65d Tidy up evdev.h
This includes shuffling some functions around so we don't need the prototypes
in evdev.h.
(cherry picked from commit 0405f7b17f)
2008-10-14 17:18:07 +10:30
Peter Hutterer
57521e4e60 Rename DragLockInit to DragLockPreInit, remove superfluous "return".
(cherry picked from commit 088e0a175a)
2008-10-14 17:18:07 +10:30
Peter Hutterer
7da1522309 Register property handler from within the modules, not the main evdev file.
(cherry picked from commit cefedeb205)
2008-10-14 17:18:07 +10:30
Peter Hutterer
b4fcb825fc Clean up program flow - don't call PreInit for "modules" on DEVICE_INIT.
Call the PreInit functions for MB Emulation, wheel emu, and draglock during
PreInit, not on DEVICE_INIT. This way, we only parse the options once and
don't overwrite with defaults when coming back from a VT switch.
(cherry picked from commit b0737bdbd1)
2008-10-14 17:18:07 +10:30
Peter Hutterer
7c955ad050 Janitor: clean up xf86Msg use, might as well use X_CONFIG directly.
(cherry picked from commit 5f2c8a2dcd)
2008-10-14 17:18:07 +10:30
Peter Hutterer
4f80c0f2cb Add property support for ReopenAttempts option.
(cherry picked from commit ff783fce65)
2008-10-14 17:18:07 +10:30
Peter Hutterer
5070d64aa8 Document properties in man page.
(cherry picked from commit c638aa4a88)
2008-10-14 17:18:07 +10:30
Peter Hutterer
caacacf057 Document InvertX/Y options.
(cherry picked from commit b46677e346)
2008-10-14 17:18:07 +10:30
8 changed files with 451 additions and 251 deletions

View File

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

View File

@@ -31,7 +31,7 @@
/* Middle mouse button emulation */
/* BOOL */
#define EVDEV_PROP_MIDBUTTON "Evdev Middle Button Emulation"
/* CARD16 */
/* CARD32 */
#define EVDEV_PROP_MIDBUTTON_TIMEOUT "Evdev Middle Button Timeout"
/* Wheel emulation */
@@ -54,4 +54,16 @@
/* BOOL, 2 values [x, y], 1 inverts axis */
#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

View File

@@ -11,6 +11,7 @@ evdev \- Generic Linux input driver
.BI " Option \*qDevice\*q \*q" devpath \*q
.BI " Option \*qEmulate3Buttons\*q \*q" True \*q
.BI " Option \*qEmulate3Timeout\*q \*q" 50 \*q
.BI " Option \*qGrabDevice\*q \*q" False \*q
\ \ ...
.B EndSection
.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
which only have two physical buttons. The third button is emulated by
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
.BI "Option \*qEmulate3Timeout\*q \*q" integer \*q
Sets the timeout (in milliseconds) that the driver waits before deciding
if two buttons where pressed "simultaneously" when 3 button emulation is
enabled. Default: 50.
enabled. Default: 50. Property: "Evdev Middle Button Timeout".
.TP 7
.BI "Option \*qButtonMapping\*q \*q" string \*q
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
same time they move a mouse cursor. Button numbers occur in pairs,
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
.BI "Option \*qDragLockButtons\*q \*q" "M1" \*q
Sets a \*qmaster drag lock button\*q that acts as a \*qMeta Key\*q
indicating that the next button pressed is to be
\*qdrag locked\*q.
\*qdrag locked\*q. Property: "Evdev Drag Lock Buttons".
.TP 7
.BI "Option \*qEmulateWheel\*q \*q" boolean \*q
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 ,
and
.B YAxisMapping
options below. Default: off.
options below. Default: off. Property "Evdev Wheel Emulation".
.TP 7
.BI "Option \*qEmulateWheelButton\*q \*q" integer \*q
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
and
.B YAxisMapping
settings. Default: 4.
settings. Default: 4. Property: "Evdev Wheel Emulation Button".
.TP 7
.BI "Option \*qEmulateWheelInertia\*q \*q" integer \*q
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
.BI "Option \*qEmulateWheelTimeout\*q \*q" integer \*q
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
.BR EmulateWheelButton
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
.BI "Option \*qXAxisMapping\*q \*q" "N1 N2" \*q
Specifies which buttons are mapped to motion in the X direction in wheel
@@ -123,7 +126,8 @@ emulation mode. Button number
.I N1
is mapped to the negative X axis motion and button number
.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
.BI "Option \*qYAxisMapping\*q \*q" "N1 N2" \*q
Specifies which buttons are mapped to motion in the Y direction in wheel
@@ -131,11 +135,68 @@ emulation mode. Button number
.I N1
is mapped to the negative Y axis motion and button number
.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
.BI "Option \*qReopenAttempts\*q \*q" integer \*q
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.
.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.
.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 values (8 bit, 0 or 1). 1 swaps x/y axes.
.SH AUTHORS
Kristian Høgsberg.

View File

@@ -53,7 +53,7 @@ void EvdevDragLockLockButton(InputInfoPtr pInfo, unsigned int button);
/* Setup and configuration code */
void
EvdevDragLockInit(InputInfoPtr pInfo)
EvdevDragLockPreInit(InputInfoPtr pInfo)
{
EvdevPtr pEvdev = (EvdevPtr)pInfo->private;
char *option_string = NULL;
@@ -210,45 +210,6 @@ EvdevDragLockFilterEvent(InputInfoPtr pInfo, unsigned int button, int value)
}
#ifdef HAVE_PROPERTIES
/**
* Initialise property for drag lock buttons setting.
*/
void
EvdevDragLockInitProperty(DeviceIntPtr dev)
{
InputInfoPtr pInfo = dev->public.devicePrivate;
EvdevPtr pEvdev = pInfo->private;
if (!dev->button) /* don't init prop for keyboards */
return;
prop_dlock = MakeAtom(EVDEV_PROP_DRAGLOCK, strlen(EVDEV_PROP_DRAGLOCK), TRUE);
if (pEvdev->dragLock.meta)
{
XIChangeDeviceProperty(dev, prop_dlock, XA_INTEGER, 8,
PropModeReplace, 1, &pEvdev->dragLock.meta,
FALSE);
} else {
int highest = 0;
int i;
CARD8 pair[EVDEV_MAXBUTTONS] = {0};
for (i = 0; i < EVDEV_MAXBUTTONS; i++)
{
if (pEvdev->dragLock.lock_pair[i])
highest = i;
pair[i] = pEvdev->dragLock.lock_pair[i];
}
XIChangeDeviceProperty(dev, prop_dlock, XA_INTEGER, 8, PropModeReplace,
highest + 1, pair, FALSE);
}
XISetDevicePropertyDeletable(dev, prop_dlock, FALSE);
return;
}
/**
* Set the drag lock property.
* If only one value is supplied, then this is used as the meta button.
@@ -314,4 +275,44 @@ EvdevDragLockSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
return Success;
}
/**
* Initialise property for drag lock buttons setting.
*/
void
EvdevDragLockInitProperty(DeviceIntPtr dev)
{
InputInfoPtr pInfo = dev->public.devicePrivate;
EvdevPtr pEvdev = pInfo->private;
if (!dev->button) /* don't init prop for keyboards */
return;
prop_dlock = MakeAtom(EVDEV_PROP_DRAGLOCK, strlen(EVDEV_PROP_DRAGLOCK), TRUE);
if (pEvdev->dragLock.meta)
{
XIChangeDeviceProperty(dev, prop_dlock, XA_INTEGER, 8,
PropModeReplace, 1, &pEvdev->dragLock.meta,
FALSE);
} else {
int highest = 0;
int i;
CARD8 pair[EVDEV_MAXBUTTONS] = {0};
for (i = 0; i < EVDEV_MAXBUTTONS; i++)
{
if (pEvdev->dragLock.lock_pair[i])
highest = i;
pair[i] = pEvdev->dragLock.lock_pair[i];
}
XIChangeDeviceProperty(dev, prop_dlock, XA_INTEGER, 8, PropModeReplace,
highest + 1, pair, FALSE);
}
XISetDevicePropertyDeletable(dev, prop_dlock, FALSE);
XIRegisterPropertyHandler(dev, EvdevDragLockSetProperty, NULL, NULL);
}
#endif

View File

@@ -311,24 +311,20 @@ EvdevMBEmuPreInit(InputInfoPtr pInfo)
pEvdev->emulateMB.enabled = xf86SetBoolOption(pInfo->options,
"Emulate3Buttons",
MBEMU_ENABLED);
xf86Msg(X_INFO, "%s: Forcing middle mouse button emulation.\n",
pInfo->name);
xf86Msg(X_INFO, "%s: Forcing middle mouse button emulation %s.\n",
pInfo->name, (pEvdev->emulateMB.enabled) ? "on" : "off");
}
pEvdev->emulateMB.timeout = xf86SetIntOption(pInfo->options,
"Emulate3Timeout", 50);
}
void
EvdevMBEmuOn(InputInfoPtr pInfo)
{
RegisterBlockAndWakeupHandlers (EvdevMBEmuBlockHandler,
EvdevMBEmuWakeupHandler,
(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
@@ -351,6 +347,32 @@ EvdevMBEmuEnable(InputInfoPtr pInfo, BOOL enable)
#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.
*/
@@ -376,37 +398,13 @@ EvdevMBEmuInitProperty(DeviceIntPtr dev)
prop_mbtimeout = MakeAtom(EVDEV_PROP_MIDBUTTON_TIMEOUT,
strlen(EVDEV_PROP_MIDBUTTON_TIMEOUT),
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);
if (rc != Success)
return;
XISetDevicePropertyDeletable(dev, prop_mbtimeout, FALSE);
}
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 != 16 || val->size != 1 || val->type != XA_INTEGER)
return BadMatch;
if (!checkonly)
pEvdev->emulateMB.timeout = *((INT16*)val->data);
}
return Success;
XIRegisterPropertyHandler(dev, EvdevMBEmuSetProperty, NULL, NULL);
}
#endif

View File

@@ -308,91 +308,9 @@ EvdevWheelEmuPreInit(InputInfoPtr pInfo)
"EmulateWheelInertia: %d, "
"EmulateWheelTimeout: %d\n",
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
void
EvdevWheelEmuInitProperty(DeviceIntPtr dev)
{
InputInfoPtr pInfo = dev->public.devicePrivate;
EvdevPtr pEvdev = pInfo->private;
int rc = TRUE;
INT32 vals[4] = { TRUE, FALSE};
if (!dev->button) /* don't init prop for keyboards */
return;
prop_wheel_emu = MakeAtom(EVDEV_PROP_WHEEL, strlen(EVDEV_PROP_WHEEL), TRUE);
rc = XIChangeDeviceProperty(dev, prop_wheel_emu, XA_INTEGER, 8,
PropModeReplace, 1,
&pEvdev->emulateWheel.enabled, FALSE);
if (rc != Success)
return;
XISetDevicePropertyDeletable(dev, prop_wheel_emu, FALSE);
vals[0] = pEvdev->emulateWheel.X.up_button;
vals[1] = pEvdev->emulateWheel.X.down_button;
vals[2] = pEvdev->emulateWheel.Y.up_button;
vals[3] = pEvdev->emulateWheel.Y.down_button;
prop_wheel_axismap = MakeAtom(EVDEV_PROP_WHEEL_AXES, strlen(EVDEV_PROP_WHEEL_AXES), TRUE);
rc = XIChangeDeviceProperty(dev, prop_wheel_axismap, XA_INTEGER, 8,
PropModeReplace, 4, vals, FALSE);
if (rc != Success)
return;
XISetDevicePropertyDeletable(dev, prop_wheel_axismap, FALSE);
prop_wheel_inertia = MakeAtom(EVDEV_PROP_WHEEL_INERTIA, strlen(EVDEV_PROP_WHEEL_INERTIA), TRUE);
rc = XIChangeDeviceProperty(dev, prop_wheel_inertia, XA_INTEGER, 16,
PropModeReplace, 1,
&pEvdev->emulateWheel.inertia, FALSE);
if (rc != Success)
return;
XISetDevicePropertyDeletable(dev, prop_wheel_inertia, FALSE);
prop_wheel_timeout = MakeAtom(EVDEV_PROP_WHEEL_TIMEOUT, strlen(EVDEV_PROP_WHEEL_TIMEOUT), TRUE);
rc = XIChangeDeviceProperty(dev, prop_wheel_timeout, XA_INTEGER, 16,
PropModeReplace, 1,
&pEvdev->emulateWheel.timeout, FALSE);
if (rc != Success)
return;
XISetDevicePropertyDeletable(dev, prop_wheel_timeout, FALSE);
prop_wheel_button = MakeAtom(EVDEV_PROP_WHEEL_BUTTON, strlen(EVDEV_PROP_WHEEL_BUTTON), TRUE);
rc = XIChangeDeviceProperty(dev, prop_wheel_button, XA_INTEGER, 8,
PropModeReplace, 1,
&pEvdev->emulateWheel.button, FALSE);
if (rc != Success)
return;
XISetDevicePropertyDeletable(dev, prop_wheel_button, FALSE);
}
int
EvdevWheelEmuSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
BOOL checkonly)
@@ -482,4 +400,67 @@ EvdevWheelEmuSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
return Success;
}
void
EvdevWheelEmuInitProperty(DeviceIntPtr dev)
{
InputInfoPtr pInfo = dev->public.devicePrivate;
EvdevPtr pEvdev = pInfo->private;
int rc = TRUE;
char vals[4];
if (!dev->button) /* don't init prop for keyboards */
return;
prop_wheel_emu = MakeAtom(EVDEV_PROP_WHEEL, strlen(EVDEV_PROP_WHEEL), TRUE);
rc = XIChangeDeviceProperty(dev, prop_wheel_emu, XA_INTEGER, 8,
PropModeReplace, 1,
&pEvdev->emulateWheel.enabled, FALSE);
if (rc != Success)
return;
XISetDevicePropertyDeletable(dev, prop_wheel_emu, FALSE);
vals[0] = pEvdev->emulateWheel.X.up_button;
vals[1] = pEvdev->emulateWheel.X.down_button;
vals[2] = pEvdev->emulateWheel.Y.up_button;
vals[3] = pEvdev->emulateWheel.Y.down_button;
prop_wheel_axismap = MakeAtom(EVDEV_PROP_WHEEL_AXES, strlen(EVDEV_PROP_WHEEL_AXES), TRUE);
rc = XIChangeDeviceProperty(dev, prop_wheel_axismap, XA_INTEGER, 8,
PropModeReplace, 4, vals, FALSE);
if (rc != Success)
return;
XISetDevicePropertyDeletable(dev, prop_wheel_axismap, FALSE);
prop_wheel_inertia = MakeAtom(EVDEV_PROP_WHEEL_INERTIA, strlen(EVDEV_PROP_WHEEL_INERTIA), TRUE);
rc = XIChangeDeviceProperty(dev, prop_wheel_inertia, XA_INTEGER, 16,
PropModeReplace, 1,
&pEvdev->emulateWheel.inertia, FALSE);
if (rc != Success)
return;
XISetDevicePropertyDeletable(dev, prop_wheel_inertia, FALSE);
prop_wheel_timeout = MakeAtom(EVDEV_PROP_WHEEL_TIMEOUT, strlen(EVDEV_PROP_WHEEL_TIMEOUT), TRUE);
rc = XIChangeDeviceProperty(dev, prop_wheel_timeout, XA_INTEGER, 16,
PropModeReplace, 1,
&pEvdev->emulateWheel.timeout, FALSE);
if (rc != Success)
return;
XISetDevicePropertyDeletable(dev, prop_wheel_timeout, FALSE);
prop_wheel_button = MakeAtom(EVDEV_PROP_WHEEL_BUTTON, strlen(EVDEV_PROP_WHEEL_BUTTON), TRUE);
rc = XIChangeDeviceProperty(dev, prop_wheel_button, XA_INTEGER, 8,
PropModeReplace, 1,
&pEvdev->emulateWheel.button, FALSE);
if (rc != Success)
return;
XISetDevicePropertyDeletable(dev, prop_wheel_button, FALSE);
XIRegisterPropertyHandler(dev, EvdevWheelEmuSetProperty, NULL, NULL);
}
#endif

View File

@@ -75,6 +75,8 @@
#define EVDEV_ABSOLUTE_EVENTS (1 << 3)
#define EVDEV_TOUCHPAD (1 << 4)
#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 GLYPHS_PER_KEY 2
@@ -105,6 +107,9 @@ static void EvdevInitProperty(DeviceIntPtr dev);
static int EvdevSetProperty(DeviceIntPtr dev, Atom atom,
XIPropertyValuePtr val, BOOL checkonly);
static Atom prop_invert = 0;
static Atom prop_reopen = 0;
static Atom prop_calibration = 0;
static Atom prop_swap = 0;
#endif
@@ -163,6 +168,10 @@ PostKbdEvent(InputInfoPtr pInfo, struct input_event *ev, int value)
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);
}
@@ -184,12 +193,10 @@ EvdevReopenTimer(OsTimerPtr timer, CARD32 time, pointer arg)
if (pInfo->fd != -1)
{
pEvdev->reopen_left = 0;
if (EvdevCacheCompare(pInfo, TRUE) == Success)
{
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);
} else
{
@@ -199,6 +206,7 @@ EvdevReopenTimer(OsTimerPtr timer, CARD32 time, pointer arg)
close(pInfo->fd);
pInfo->fd = -1;
}
pEvdev->reopen_left = 0;
return 0;
}
@@ -220,13 +228,14 @@ EvdevReadInput(InputInfoPtr pInfo)
{
struct input_event ev;
int len, value;
int dx, dy;
int dx, dy, tmp;
unsigned int abs;
unsigned int button;
EvdevPtr pEvdev = pInfo->private;
dx = 0;
dy = 0;
tmp = 0;
abs = 0;
while (xf86WaitForInput (pInfo->fd, 0) > 0) {
@@ -313,10 +322,15 @@ EvdevReadInput(InputInfoPtr pInfo)
case BTN_TOOL_MOUSE:
case BTN_TOOL_LENS:
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:
button = EvdevUtilButtonEventToButtonNumber(ev.code);
button = EvdevUtilButtonEventToButtonNumber(pEvdev, ev.code);
/* Handle drag lock */
if (EvdevDragLockFilterEvent(pInfo, button, value))
@@ -357,6 +371,11 @@ EvdevReadInput(InputInfoPtr pInfo)
}
if (dx != 0 || dy != 0) {
if (pEvdev->swap_axes) {
tmp = dx;
dx = dy;
dy = tmp;
}
if (pEvdev->invert_x)
dx *= -1;
if (pEvdev->invert_y)
@@ -375,18 +394,29 @@ EvdevReadInput(InputInfoPtr pInfo)
*/
if (abs && pEvdev->tool) {
int abs_x, abs_y;
abs_x = pEvdev->abs_x;
abs_y = pEvdev->abs_y;
abs_x = (pEvdev->swap_axes) ? pEvdev->abs_y : pEvdev->abs_x;
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)
abs_x = pEvdev->max_x - abs_x;
abs_x = pEvdev->max_x - (abs_x - pEvdev->min_x);
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);
}
}
#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
EvdevPtrCtrlProc(DeviceIntPtr device, PtrCtrl *ctrl)
@@ -394,9 +424,6 @@ EvdevPtrCtrlProc(DeviceIntPtr device, PtrCtrl *ctrl)
/* 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[] = {
/* 0x00 */ NoSymbol, NoSymbol,
/* 0x01 */ XK_Escape, NoSymbol,
@@ -665,6 +692,8 @@ EvdevKbdCtrl(DeviceIntPtr device, KeybdCtrl *ctrl)
struct input_event ev[ArrayLength(bits)];
int i;
memset(ev, 0, sizeof(ev));
pInfo = device->public.devicePrivate;
for (i = 0; i < ArrayLength(bits); i++) {
ev[i].type = EV_LED;
@@ -949,9 +978,6 @@ EvdevInit(DeviceIntPtr device)
/* 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 anyway */
XIRegisterPropertyHandler(device, EvdevMBEmuSetProperty, NULL, NULL);
XIRegisterPropertyHandler(device, EvdevWheelEmuSetProperty, NULL, NULL);
XIRegisterPropertyHandler(device, EvdevDragLockSetProperty, NULL, NULL);
XIRegisterPropertyHandler(device, EvdevSetProperty, NULL, NULL);
EvdevInitProperty(device);
EvdevMBEmuInitProperty(device);
@@ -978,7 +1004,7 @@ EvdevOn(DeviceIntPtr device)
pInfo = device->public.devicePrivate;
pEvdev = pInfo->private;
if (pInfo->fd != -1 && !pEvdev->kernel24 &&
if (pInfo->fd != -1 && pEvdev->grabDevice &&
(rc = ioctl(pInfo->fd, EVIOCGRAB, (void *)1)))
{
xf86Msg(X_WARNING, "%s: Grab failed (%s)\n", pInfo->name,
@@ -998,14 +1024,9 @@ EvdevOn(DeviceIntPtr device)
pEvdev->reopen_timer = TimerSet(NULL, 0, 100, EvdevReopenTimer, pInfo);
} else
{
xf86FlushInput(pInfo->fd);
xf86AddEnabledDevice(pInfo);
if ((pEvdev->flags & EVDEV_BUTTON_EVENTS) &&
!(pEvdev->flags & EVDEV_INITIALIZED))
{
EvdevMBEmuPreInit(pInfo);
EvdevWheelEmuPreInit(pInfo);
EvdevDragLockInit(pInfo);
}
EvdevMBEmuOn(pInfo);
pEvdev->flags |= EVDEV_INITIALIZED;
device->public.on = TRUE;
}
@@ -1034,7 +1055,7 @@ EvdevProc(DeviceIntPtr device, int what)
case DEVICE_OFF:
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,
strerror(errno));
xf86RemoveEnabledDevice(pInfo);
@@ -1179,21 +1200,23 @@ error:
static int
EvdevProbe(InputInfoPtr pInfo)
{
long key_bitmask[NBITS(KEY_MAX)];
long rel_bitmask[NBITS(REL_MAX)];
long abs_bitmask[NBITS(ABS_MAX)];
long key_bitmask[NBITS(KEY_MAX)] = {0};
long rel_bitmask[NBITS(REL_MAX)] = {0};
long abs_bitmask[NBITS(ABS_MAX)] = {0};
int i, has_axes, has_keys, num_buttons;
int kernel24 = 0;
EvdevPtr pEvdev = pInfo->private;
if (ioctl(pInfo->fd, EVIOCGRAB, (void *)1)) {
if (pEvdev->grabDevice && ioctl(pInfo->fd, EVIOCGRAB, (void *)1)) {
if (errno == EINVAL) {
/* keyboards are unsafe in 2.4 */
pEvdev->kernel24 = 1;
kernel24 = 1;
pEvdev->grabDevice = 0;
} else {
xf86Msg(X_ERROR, "Grab failed. Device already configured?\n");
return 1;
}
} else {
} else if (pEvdev->grabDevice) {
ioctl(pInfo->fd, EVIOCGRAB, (void *)0);
}
@@ -1219,23 +1242,6 @@ EvdevProbe(InputInfoPtr pInfo)
has_keys = FALSE;
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 */
for (i = BTN_MISC; i < BTN_JOYSTICK; i++)
{
@@ -1251,6 +1257,29 @@ EvdevProbe(InputInfoPtr pInfo)
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++)
if (TestBit(i, key_bitmask))
break;
@@ -1268,8 +1297,15 @@ EvdevProbe(InputInfoPtr pInfo)
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 (pEvdev->kernel24) {
if (kernel24) {
xf86Msg(X_INFO, "%s: Kernel < 2.6 is too old, ignoring keyboard\n",
pInfo->name);
} else {
@@ -1293,7 +1329,6 @@ static InputInfoPtr
EvdevPreInit(InputDriverPtr drv, IDevPtr dev, int flags)
{
InputInfoPtr pInfo;
MessageType deviceFrom = X_CONFIG;
const char *device;
EvdevPtr pEvdev;
@@ -1340,7 +1375,7 @@ EvdevPreInit(InputDriverPtr drv, IDevPtr dev, int flags)
pEvdev->device = device;
xf86Msg(deviceFrom, "%s: Device: \"%s\"\n", pInfo->name, device);
xf86Msg(X_CONFIG, "%s: Device: \"%s\"\n", pInfo->name, device);
do {
pInfo->fd = open(device, O_RDWR, 0);
} while (pInfo->fd < 0 && errno == EINTR);
@@ -1354,6 +1389,12 @@ EvdevPreInit(InputDriverPtr drv, IDevPtr dev, int flags)
pEvdev->reopen_attempts = xf86SetIntOption(pInfo->options, "ReopenAttempts", 10);
pEvdev->invert_x = xf86SetBoolOption(pInfo->options, "InvertX", 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 */
@@ -1367,6 +1408,13 @@ EvdevPreInit(InputDriverPtr drv, IDevPtr dev, int flags)
EvdevCacheCompare(pInfo, FALSE); /* cache device data */
if (pEvdev->flags & EVDEV_BUTTON_EVENTS)
{
EvdevMBEmuPreInit(pInfo);
EvdevWheelEmuPreInit(pInfo);
EvdevDragLockPreInit(pInfo);
}
return pInfo;
}
@@ -1421,7 +1469,7 @@ _X_EXPORT XF86ModuleData evdevModuleData =
* returns 0 on non-button event.
*/
unsigned int
EvdevUtilButtonEventToButtonNumber(int code)
EvdevUtilButtonEventToButtonNumber(EvdevPtr pEvdev, int code)
{
unsigned int button = 0;
@@ -1438,6 +1486,21 @@ EvdevUtilButtonEventToButtonNumber(int code)
button = 2;
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_EXTRA:
case BTN_FORWARD:
@@ -1448,8 +1511,12 @@ EvdevUtilButtonEventToButtonNumber(int code)
default:
if ((code > BTN_TASK) && (code < KEY_OK)) {
if (code < BTN_JOYSTICK)
button = (code - BTN_LEFT + 5);
if (code < BTN_JOYSTICK) {
if (code < BTN_MOUSE)
button = (code - BTN_0 + 5);
else
button = (code - BTN_LEFT + 5);
}
}
}
@@ -1467,19 +1534,55 @@ EvdevInitProperty(DeviceIntPtr dev)
EvdevPtr pEvdev = pInfo->private;
int rc;
BOOL invert[2];
char reopen;
invert[0] = pEvdev->invert_x;
invert[1] = pEvdev->invert_y;
prop_invert = MakeAtom(EVDEV_PROP_INVERT_AXES, strlen(EVDEV_PROP_INVERT_AXES), TRUE);
if (pEvdev->flags & (EVDEV_RELATIVE_EVENTS | EVDEV_ABSOLUTE_EVENTS))
{
invert[0] = pEvdev->invert_x;
invert[1] = pEvdev->invert_y;
rc = XIChangeDeviceProperty(dev, prop_invert, XA_INTEGER, 8,
PropModeReplace, 2,
invert, FALSE);
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_reopen = MakeAtom(EVDEV_PROP_REOPEN, strlen(EVDEV_PROP_REOPEN),
TRUE);
reopen = pEvdev->reopen_attempts;
rc = XIChangeDeviceProperty(dev, prop_reopen, XA_INTEGER, 8,
PropModeReplace, 1, &reopen, FALSE);
if (rc != Success)
return;
XISetDevicePropertyDeletable(dev, prop_invert, FALSE);
XISetDevicePropertyDeletable(dev, prop_reopen, 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
@@ -1501,6 +1604,47 @@ EvdevSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
pEvdev->invert_x = data[0];
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;

View File

@@ -35,9 +35,8 @@
#include <xf86Xinput.h>
#include <xf86_OSproc.h>
#if defined(XKB)
/* XXX VERY WRONG. this is a client side header. */
#include <X11/extensions/XKBstr.h>
#ifdef XKB
#include <xkbstr.h>
#endif
#define EVDEV_MAXBUTTONS 32
@@ -58,13 +57,14 @@ typedef struct {
typedef struct {
const char *device;
int kernel24;
int grabDevice; /* grab the event device? */
int screen;
int min_x, min_y, max_x, max_y;
int abs_x, abs_y, old_x, old_y;
int flags;
int tool;
int buttons; /* number of buttons */
BOOL swap_axes;
BOOL invert_x;
BOOL invert_y;
@@ -103,6 +103,13 @@ typedef struct {
Time expires; /* time of expiry */
Time timeout;
} 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 */
@@ -120,34 +127,30 @@ typedef struct {
struct input_absinfo absinfo[ABS_MAX];
} EvdevRec, *EvdevPtr;
unsigned int EvdevUtilButtonEventToButtonNumber(EvdevPtr pEvdev, int code);
/* Middle Button emulation */
int EvdevMBEmuTimer(InputInfoPtr);
BOOL EvdevMBEmuFilterEvent(InputInfoPtr, int, BOOL);
void EvdevMBEmuWakeupHandler(pointer, int, pointer);
void EvdevMBEmuBlockHandler(pointer, struct timeval**, pointer);
void EvdevMBEmuPreInit(InputInfoPtr);
void EvdevMBEmuOn(InputInfoPtr);
void EvdevMBEmuFinalize(InputInfoPtr);
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 */
void EvdevWheelEmuPreInit(InputInfoPtr pInfo);
BOOL EvdevWheelEmuFilterButton(InputInfoPtr pInfo, unsigned int button, int value);
BOOL EvdevWheelEmuFilterMotion(InputInfoPtr pInfo, struct input_event *pEv);
/* Draglock code */
void EvdevDragLockInit(InputInfoPtr pInfo);
void EvdevDragLockPreInit(InputInfoPtr pInfo);
BOOL EvdevDragLockFilterEvent(InputInfoPtr pInfo, unsigned int button, int value);
#ifdef HAVE_PROPERTIES
void EvdevMBEmuInitProperty(DeviceIntPtr);
void EvdevWheelEmuInitProperty(DeviceIntPtr);
void EvdevDragLockInitProperty(DeviceIntPtr);
#endif
#endif