mirror of
https://github.com/X11Libre/xf86-input-evdev.git
synced 2026-04-14 11:44:16 +00:00
Compare commits
23 Commits
xf86-input
...
xf86-input
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f1ee12b9a3 | ||
|
|
74690817fc | ||
|
|
b2cbbb178e | ||
|
|
7d91fc7bfc | ||
|
|
09987eab9a | ||
|
|
8af0e6f1eb | ||
|
|
56e9a7a248 | ||
|
|
7df6523774 | ||
|
|
f4e76a4c53 | ||
|
|
ac772cde94 | ||
|
|
7749159241 | ||
|
|
833fc517d7 | ||
|
|
4d698d8ece | ||
|
|
76b1d58a97 | ||
|
|
224a28de25 | ||
|
|
bc2f01ab83 | ||
|
|
9d9c9870c8 | ||
|
|
5c5b2c8db8 | ||
|
|
854df75f49 | ||
|
|
8c55e94a6a | ||
|
|
965338e9d0 | ||
|
|
0075da20d6 | ||
|
|
009ac94a8e |
@@ -23,7 +23,7 @@
|
||||
# Initialize Autoconf
|
||||
AC_PREREQ([2.60])
|
||||
AC_INIT([xf86-input-evdev],
|
||||
[2.6.99.901],
|
||||
[2.7.2],
|
||||
[https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
|
||||
[xf86-input-evdev])
|
||||
AC_CONFIG_SRCDIR([Makefile.am])
|
||||
@@ -46,7 +46,7 @@ XORG_DEFAULT_OPTIONS
|
||||
|
||||
# Obtain compiler/linker options from server and required extensions
|
||||
PKG_CHECK_MODULES(XORG, [xorg-server >= 1.10] xproto inputproto)
|
||||
PKG_CHECK_MODULES(UDEV, udev)
|
||||
PKG_CHECK_MODULES(UDEV, libudev)
|
||||
|
||||
PKG_CHECK_MODULES(XI22, [inputproto >= 2.1.99.3] [xorg-server >= 1.11.99.901], HAVE_XI22="yes", HAVE_XI22="no")
|
||||
|
||||
|
||||
@@ -51,7 +51,6 @@ static Atom prop_wheel_timeout = 0;
|
||||
static Atom prop_wheel_button = 0;
|
||||
|
||||
/* Local Funciton Prototypes */
|
||||
static BOOL EvdevWheelEmuHandleButtonMap(InputInfoPtr pInfo, WheelAxisPtr pAxis, char *axis_name);
|
||||
static int EvdevWheelEmuInertia(InputInfoPtr pInfo, WheelAxisPtr axis, int value);
|
||||
|
||||
/* Filter mouse button events */
|
||||
@@ -197,7 +196,8 @@ EvdevWheelEmuInertia(InputInfoPtr pInfo, WheelAxisPtr axis, int value)
|
||||
/* Handle button mapping here to avoid code duplication,
|
||||
returns true if a button mapping was found. */
|
||||
static BOOL
|
||||
EvdevWheelEmuHandleButtonMap(InputInfoPtr pInfo, WheelAxisPtr pAxis, char* axis_name)
|
||||
EvdevWheelEmuHandleButtonMap(InputInfoPtr pInfo, WheelAxisPtr pAxis,
|
||||
const char *axis_name)
|
||||
{
|
||||
EvdevPtr pEvdev = (EvdevPtr)pInfo->private;
|
||||
char *option_string;
|
||||
|
||||
279
src/evdev.c
279
src/evdev.c
@@ -93,7 +93,7 @@
|
||||
#define ABS_MT_TRACKING_ID 0x39
|
||||
#endif
|
||||
|
||||
static char *evdevDefaults[] = {
|
||||
static const char *evdevDefaults[] = {
|
||||
"XkbRules", "evdev",
|
||||
"XkbModel", "evdev",
|
||||
"XkbLayout", "us",
|
||||
@@ -119,8 +119,9 @@ static int EvdevSwitchMode(ClientPtr client, DeviceIntPtr device, int mode);
|
||||
static BOOL EvdevGrabDevice(InputInfoPtr pInfo, int grab, int ungrab);
|
||||
static void EvdevSetCalibration(InputInfoPtr pInfo, int num_calibration, int calibration[4]);
|
||||
static int EvdevOpenDevice(InputInfoPtr pInfo);
|
||||
static void EvdevCloseDevice(InputInfoPtr pInfo);
|
||||
|
||||
static void EvdevInitAxesLabels(EvdevPtr pEvdev, int natoms, Atom *atoms);
|
||||
static void EvdevInitAxesLabels(EvdevPtr pEvdev, int mode, int natoms, Atom *atoms);
|
||||
static void EvdevInitButtonLabels(EvdevPtr pEvdev, int natoms, Atom *atoms);
|
||||
static void EvdevInitProperty(DeviceIntPtr dev);
|
||||
static int EvdevSetProperty(DeviceIntPtr dev, Atom atom,
|
||||
@@ -277,7 +278,7 @@ EvdevRemoveDevice(InputInfoPtr pInfo)
|
||||
|
||||
|
||||
static void
|
||||
SetXkbOption(InputInfoPtr pInfo, char *name, char **option)
|
||||
SetXkbOption(InputInfoPtr pInfo, const char *name, char **option)
|
||||
{
|
||||
char *s;
|
||||
|
||||
@@ -746,6 +747,24 @@ EvdevProcessTouch(InputInfoPtr pInfo)
|
||||
valuator_mask_zero(pEvdev->mt_mask);
|
||||
}
|
||||
|
||||
static int
|
||||
num_slots(EvdevPtr pEvdev)
|
||||
{
|
||||
int value = pEvdev->absinfo[ABS_MT_SLOT].maximum -
|
||||
pEvdev->absinfo[ABS_MT_SLOT].minimum + 1;
|
||||
|
||||
/* If we don't know how many slots there are, assume at least 10 */
|
||||
return value > 1 ? value : 10;
|
||||
}
|
||||
|
||||
static int
|
||||
last_mt_vals_slot(EvdevPtr pEvdev)
|
||||
{
|
||||
int value = pEvdev->cur_slot - pEvdev->absinfo[ABS_MT_SLOT].minimum;
|
||||
|
||||
return value < num_slots(pEvdev) ? value : -1;
|
||||
}
|
||||
|
||||
static void
|
||||
EvdevProcessTouchEvent(InputInfoPtr pInfo, struct input_event *ev)
|
||||
{
|
||||
@@ -757,16 +776,29 @@ EvdevProcessTouchEvent(InputInfoPtr pInfo, struct input_event *ev)
|
||||
pEvdev->cur_slot = ev->value;
|
||||
} else
|
||||
{
|
||||
int slot_index = last_mt_vals_slot(pEvdev);
|
||||
|
||||
if (pEvdev->slot_state == SLOTSTATE_EMPTY)
|
||||
pEvdev->slot_state = SLOTSTATE_UPDATE;
|
||||
if (ev->code == ABS_MT_TRACKING_ID) {
|
||||
if (ev->value >= 0)
|
||||
pEvdev->slot_state = SLOTSTATE_OPEN;
|
||||
else
|
||||
pEvdev->slot_state = SLOTSTATE_CLOSE;
|
||||
if (ev->value >= 0) {
|
||||
pEvdev->slot_state = SLOTSTATE_OPEN;
|
||||
|
||||
if (slot_index >= 0)
|
||||
valuator_mask_copy(pEvdev->mt_mask,
|
||||
pEvdev->last_mt_vals[slot_index]);
|
||||
else
|
||||
xf86IDrvMsg(pInfo, X_WARNING,
|
||||
"Attempted to copy values from out-of-range "
|
||||
"slot, touch events may be incorrect.\n");
|
||||
} else
|
||||
pEvdev->slot_state = SLOTSTATE_CLOSE;
|
||||
} else {
|
||||
map = pEvdev->axis_map[ev->code];
|
||||
valuator_mask_set(pEvdev->mt_mask, map, ev->value);
|
||||
if (slot_index >= 0)
|
||||
valuator_mask_set(pEvdev->last_mt_vals[slot_index], map,
|
||||
ev->value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1027,6 +1059,30 @@ EvdevProcessEvent(InputInfoPtr pInfo, struct input_event *ev)
|
||||
#undef ABS_Y_VALUE
|
||||
#undef ABS_VALUE
|
||||
|
||||
static void
|
||||
EvdevFreeMasks(EvdevPtr pEvdev)
|
||||
{
|
||||
#ifdef MULTITOUCH
|
||||
int i;
|
||||
#endif
|
||||
|
||||
valuator_mask_free(&pEvdev->vals);
|
||||
valuator_mask_free(&pEvdev->old_vals);
|
||||
valuator_mask_free(&pEvdev->prox);
|
||||
#ifdef MULTITOUCH
|
||||
valuator_mask_free(&pEvdev->mt_mask);
|
||||
if (pEvdev->last_mt_vals)
|
||||
{
|
||||
for (i = 0; i < num_slots(pEvdev); i++)
|
||||
valuator_mask_free(&pEvdev->last_mt_vals[i]);
|
||||
free(pEvdev->last_mt_vals);
|
||||
pEvdev->last_mt_vals = NULL;
|
||||
}
|
||||
for (i = 0; i < EVDEV_MAXQUEUE; i++)
|
||||
valuator_mask_free(&pEvdev->queue[i].touchMask);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* just a magic number to reduce the number of reads */
|
||||
#define NUM_EVENTS 16
|
||||
|
||||
@@ -1055,8 +1111,7 @@ EvdevReadInput(InputInfoPtr pInfo)
|
||||
EvdevMBEmuFinalize(pInfo);
|
||||
Evdev3BEmuFinalize(pInfo);
|
||||
xf86RemoveEnabledDevice(pInfo);
|
||||
close(pInfo->fd);
|
||||
pInfo->fd = -1;
|
||||
EvdevCloseDevice(pInfo);
|
||||
} else if (errno != EAGAIN)
|
||||
{
|
||||
/* We use X_NONE here because it doesn't alloc */
|
||||
@@ -1143,6 +1198,7 @@ EvdevAddKeyClass(DeviceIntPtr device)
|
||||
return Success;
|
||||
}
|
||||
|
||||
#ifdef MULTITOUCH
|
||||
/* MT axes are counted twice - once as ABS_X (which the kernel keeps for
|
||||
* backwards compatibility), once as ABS_MT_POSITION_X. So we need to keep a
|
||||
* mapping of those axes to make sure we only count them once
|
||||
@@ -1160,6 +1216,7 @@ static struct mt_axis_mappings mt_axis_mappings[] = {
|
||||
{ABS_MT_PRESSURE, ABS_PRESSURE},
|
||||
{ABS_MT_DISTANCE, ABS_DISTANCE},
|
||||
};
|
||||
#endif
|
||||
|
||||
/**
|
||||
* return TRUE if the axis is not one we should count as true axis
|
||||
@@ -1249,6 +1306,7 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device)
|
||||
}
|
||||
#ifdef MULTITOUCH
|
||||
if (num_mt_axes_total > 0) {
|
||||
pEvdev->num_mt_vals = num_mt_axes_total;
|
||||
pEvdev->mt_mask = valuator_mask_new(num_mt_axes_total);
|
||||
if (!pEvdev->mt_mask) {
|
||||
xf86Msg(X_ERROR, "%s: failed to allocate MT valuator mask.\n",
|
||||
@@ -1256,6 +1314,24 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device)
|
||||
goto out;
|
||||
}
|
||||
|
||||
pEvdev->last_mt_vals = calloc(num_slots(pEvdev), sizeof(ValuatorMask *));
|
||||
if (!pEvdev->last_mt_vals) {
|
||||
xf86IDrvMsg(pInfo, X_ERROR,
|
||||
"%s: failed to allocate MT last values mask array.\n",
|
||||
device->name);
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_slots(pEvdev); i++) {
|
||||
pEvdev->last_mt_vals[i] = valuator_mask_new(num_mt_axes_total);
|
||||
if (!pEvdev->last_mt_vals[i]) {
|
||||
xf86IDrvMsg(pInfo, X_ERROR,
|
||||
"%s: failed to allocate MT last values mask.\n",
|
||||
device->name);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < EVDEV_MAXQUEUE; i++) {
|
||||
pEvdev->queue[i].touchMask =
|
||||
valuator_mask_new(num_mt_axes_total);
|
||||
@@ -1271,7 +1347,9 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device)
|
||||
|
||||
i = 0;
|
||||
for (axis = ABS_X; i < MAX_VALUATORS && axis <= ABS_MAX; axis++) {
|
||||
#ifdef MULTITOUCH
|
||||
int j;
|
||||
#endif
|
||||
int mapping;
|
||||
pEvdev->axis_map[axis] = -1;
|
||||
if (!EvdevBitIsSet(pEvdev->abs_bitmask, axis) ||
|
||||
@@ -1280,6 +1358,7 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device)
|
||||
|
||||
mapping = i;
|
||||
|
||||
#ifdef MULTITOUCH
|
||||
for (j = 0; j < ArrayLength(mt_axis_mappings); j++)
|
||||
{
|
||||
if (mt_axis_mappings[j].code == axis)
|
||||
@@ -1288,13 +1367,13 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device)
|
||||
mt_axis_mappings[j].needs_mapping)
|
||||
mapping = mt_axis_mappings[j].mapping;
|
||||
}
|
||||
|
||||
#endif
|
||||
pEvdev->axis_map[axis] = mapping;
|
||||
if (mapping == i)
|
||||
i++;
|
||||
}
|
||||
|
||||
EvdevInitAxesLabels(pEvdev, pEvdev->num_vals + num_mt_axes, atoms);
|
||||
EvdevInitAxesLabels(pEvdev, Absolute, pEvdev->num_vals + num_mt_axes, atoms);
|
||||
|
||||
if (!InitValuatorClassDeviceStruct(device, num_axes + num_mt_axes, atoms,
|
||||
GetMotionHistorySize(), Absolute)) {
|
||||
@@ -1310,7 +1389,8 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device)
|
||||
XIDependentTouch : XIDirectTouch;
|
||||
|
||||
if (pEvdev->mtdev->caps.slot.maximum > 0)
|
||||
num_touches = pEvdev->mtdev->caps.slot.maximum;
|
||||
num_touches = pEvdev->mtdev->caps.slot.maximum -
|
||||
pEvdev->mtdev->caps.slot.minimum + 1;
|
||||
|
||||
if (!InitTouchClassDeviceStruct(device, num_touches, mode,
|
||||
num_mt_axes_total)) {
|
||||
@@ -1318,12 +1398,23 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device)
|
||||
device->name);
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_slots(pEvdev); i++) {
|
||||
for (axis = ABS_MT_TOUCH_MAJOR; axis < ABS_MAX; axis++) {
|
||||
if (pEvdev->axis_map[axis] >= 0) {
|
||||
/* XXX: read initial values from mtdev when it adds support
|
||||
* for doing so. */
|
||||
valuator_mask_set(pEvdev->last_mt_vals[i],
|
||||
pEvdev->axis_map[axis], 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
for (axis = ABS_X; axis < ABS_MT_SLOT; axis++) {
|
||||
int axnum = pEvdev->axis_map[axis];
|
||||
int resolution = 10000;
|
||||
int resolution = 0;
|
||||
|
||||
if (axnum == -1)
|
||||
continue;
|
||||
@@ -1345,7 +1436,7 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device)
|
||||
#ifdef MULTITOUCH
|
||||
for (axis = ABS_MT_TOUCH_MAJOR; axis <= ABS_MAX; axis++) {
|
||||
int axnum = pEvdev->axis_map[axis];
|
||||
int resolution = 10000;
|
||||
int resolution = 0;
|
||||
int j;
|
||||
BOOL skip = FALSE;
|
||||
|
||||
@@ -1423,14 +1514,7 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device)
|
||||
return Success;
|
||||
|
||||
out:
|
||||
valuator_mask_free(&pEvdev->vals);
|
||||
valuator_mask_free(&pEvdev->old_vals);
|
||||
valuator_mask_free(&pEvdev->prox);
|
||||
#ifdef MULTITOUCH
|
||||
valuator_mask_free(&pEvdev->mt_mask);
|
||||
for (i = 0; i < EVDEV_MAXQUEUE; i++)
|
||||
valuator_mask_free(&pEvdev->queue[i].touchMask);
|
||||
#endif
|
||||
EvdevFreeMasks(pEvdev);
|
||||
return !Success;
|
||||
}
|
||||
|
||||
@@ -1493,7 +1577,7 @@ EvdevAddRelValuatorClass(DeviceIntPtr device)
|
||||
i++;
|
||||
}
|
||||
|
||||
EvdevInitAxesLabels(pEvdev, pEvdev->num_vals, atoms);
|
||||
EvdevInitAxesLabels(pEvdev, Relative, pEvdev->num_vals, atoms);
|
||||
|
||||
if (!InitValuatorClassDeviceStruct(device, num_axes, atoms,
|
||||
GetMotionHistorySize(), Relative)) {
|
||||
@@ -1522,7 +1606,7 @@ EvdevAddRelValuatorClass(DeviceIntPtr device)
|
||||
else if (axis == REL_DIAL)
|
||||
SetScrollValuator(device, axnum, SCROLL_TYPE_VERTICAL, -1.0, SCROLL_FLAG_NONE);
|
||||
else if (axis == REL_HWHEEL)
|
||||
SetScrollValuator(device, axnum, SCROLL_TYPE_HORIZONTAL, -1.0, SCROLL_FLAG_NONE);
|
||||
SetScrollValuator(device, axnum, SCROLL_TYPE_HORIZONTAL, 1.0, SCROLL_FLAG_NONE);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1580,7 +1664,7 @@ EvdevInitButtonMapping(InputInfoPtr pInfo)
|
||||
/* Check for user-defined button mapping */
|
||||
if ((mapping = xf86CheckStrOption(pInfo->options, "ButtonMapping", NULL)))
|
||||
{
|
||||
char *map, *s = " ";
|
||||
char *map, *s = NULL;
|
||||
int btn = 0;
|
||||
|
||||
xf86IDrvMsg(pInfo, X_CONFIG, "ButtonMapping '%s'\n", mapping);
|
||||
@@ -1764,9 +1848,6 @@ EvdevProc(DeviceIntPtr device, int what)
|
||||
{
|
||||
InputInfoPtr pInfo;
|
||||
EvdevPtr pEvdev;
|
||||
#ifdef MULTITOUCH
|
||||
int i;
|
||||
#endif
|
||||
|
||||
pInfo = device->public.devicePrivate;
|
||||
pEvdev = pInfo->private;
|
||||
@@ -1789,8 +1870,7 @@ EvdevProc(DeviceIntPtr device, int what)
|
||||
{
|
||||
EvdevGrabDevice(pInfo, 0, 1);
|
||||
xf86RemoveEnabledDevice(pInfo);
|
||||
close(pInfo->fd);
|
||||
pInfo->fd = -1;
|
||||
EvdevCloseDevice(pInfo);
|
||||
}
|
||||
pEvdev->min_maj = 0;
|
||||
pEvdev->flags &= ~EVDEV_INITIALIZED;
|
||||
@@ -1799,20 +1879,8 @@ EvdevProc(DeviceIntPtr device, int what)
|
||||
|
||||
case DEVICE_CLOSE:
|
||||
xf86IDrvMsg(pInfo, X_INFO, "Close\n");
|
||||
if (pInfo->fd != -1) {
|
||||
close(pInfo->fd);
|
||||
pInfo->fd = -1;
|
||||
}
|
||||
valuator_mask_free(&pEvdev->vals);
|
||||
valuator_mask_free(&pEvdev->old_vals);
|
||||
valuator_mask_free(&pEvdev->prox);
|
||||
#ifdef MULTITOUCH
|
||||
valuator_mask_free(&pEvdev->mt_mask);
|
||||
for (i = 0; i < EVDEV_MAXQUEUE; i++)
|
||||
valuator_mask_free(&pEvdev->queue[i].touchMask);
|
||||
if (pEvdev->mtdev)
|
||||
mtdev_close(pEvdev->mtdev);
|
||||
#endif
|
||||
EvdevCloseDevice(pInfo);
|
||||
EvdevFreeMasks(pEvdev);
|
||||
EvdevRemoveDevice(pInfo);
|
||||
pEvdev->min_maj = 0;
|
||||
break;
|
||||
@@ -1955,6 +2023,38 @@ EvdevGrabDevice(InputInfoPtr pInfo, int grab, int ungrab)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Some devices only have other axes (e.g. wheels), but we
|
||||
* still need x/y for these. The server relies on devices having
|
||||
* x/y as axes 0/1 and core/XI 1.x clients expect it too (#44655)
|
||||
*/
|
||||
static void
|
||||
EvdevForceXY(InputInfoPtr pInfo, int mode)
|
||||
{
|
||||
EvdevPtr pEvdev = pInfo->private;
|
||||
|
||||
xf86IDrvMsg(pInfo, X_INFO, "Forcing %s x/y axes to exist.\n",
|
||||
(mode == Relative) ? "relative" : "absolute");
|
||||
|
||||
if (mode == Relative)
|
||||
{
|
||||
EvdevSetBit(pEvdev->rel_bitmask, REL_X);
|
||||
EvdevSetBit(pEvdev->rel_bitmask, REL_Y);
|
||||
} else if (mode == Absolute)
|
||||
{
|
||||
EvdevSetBit(pEvdev->abs_bitmask, ABS_X);
|
||||
EvdevSetBit(pEvdev->abs_bitmask, ABS_Y);
|
||||
pEvdev->absinfo[ABS_X].minimum = 0;
|
||||
pEvdev->absinfo[ABS_X].maximum = 1000;
|
||||
pEvdev->absinfo[ABS_X].value = 0;
|
||||
pEvdev->absinfo[ABS_X].resolution = 0;
|
||||
pEvdev->absinfo[ABS_Y].minimum = 0;
|
||||
pEvdev->absinfo[ABS_Y].maximum = 1000;
|
||||
pEvdev->absinfo[ABS_Y].value = 0;
|
||||
pEvdev->absinfo[ABS_Y].resolution = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
EvdevProbe(InputInfoPtr pInfo)
|
||||
{
|
||||
@@ -2048,7 +2148,9 @@ EvdevProbe(InputInfoPtr pInfo)
|
||||
if (EvdevBitIsSet(pEvdev->rel_bitmask, REL_X) &&
|
||||
EvdevBitIsSet(pEvdev->rel_bitmask, REL_Y)) {
|
||||
xf86IDrvMsg(pInfo, X_PROBED, "Found x and y relative axes\n");
|
||||
}
|
||||
} else if (!EvdevBitIsSet(pEvdev->abs_bitmask, ABS_X) ||
|
||||
!EvdevBitIsSet(pEvdev->abs_bitmask, ABS_Y))
|
||||
EvdevForceXY(pInfo, Relative);
|
||||
} else {
|
||||
xf86IDrvMsg(pInfo, X_INFO, "Relative axes present but ignored.\n");
|
||||
has_rel_axes = FALSE;
|
||||
@@ -2113,7 +2215,16 @@ EvdevProbe(InputInfoPtr pInfo)
|
||||
pEvdev->flags |= EVDEV_TOUCHSCREEN;
|
||||
pEvdev->flags |= EVDEV_BUTTON_EVENTS;
|
||||
}
|
||||
} else {
|
||||
#ifdef MULTITOUCH
|
||||
if (!EvdevBitIsSet(pEvdev->abs_bitmask, ABS_MT_POSITION_X) ||
|
||||
!EvdevBitIsSet(pEvdev->abs_bitmask, ABS_MT_POSITION_Y))
|
||||
#endif
|
||||
EvdevForceXY(pInfo, Absolute);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
for (i = 0; i < BTN_MISC; i++) {
|
||||
@@ -2162,6 +2273,9 @@ EvdevProbe(InputInfoPtr pInfo)
|
||||
xf86IDrvMsg(pInfo, X_INFO, "Configuring as touchscreen\n");
|
||||
pInfo->type_name = XI_TOUCHSCREEN;
|
||||
} else {
|
||||
if (!EvdevBitIsSet(pEvdev->rel_bitmask, REL_X) ||
|
||||
!EvdevBitIsSet(pEvdev->rel_bitmask, REL_Y))
|
||||
EvdevForceXY(pInfo, Relative);
|
||||
xf86IDrvMsg(pInfo, X_INFO, "Configuring as mouse\n");
|
||||
pInfo->type_name = XI_MOUSE;
|
||||
}
|
||||
@@ -2240,13 +2354,16 @@ EvdevOpenDevice(InputInfoPtr pInfo)
|
||||
}
|
||||
|
||||
#ifdef MULTITOUCH
|
||||
pEvdev->mtdev = mtdev_new_open(pInfo->fd);
|
||||
if (!pEvdev->mtdev) { /* after PreInit mtdev is still valid */
|
||||
pEvdev->mtdev = mtdev_new_open(pInfo->fd);
|
||||
if (!pEvdev->mtdev) {
|
||||
xf86Msg(X_ERROR, "%s: Couldn't open mtdev device\n", pInfo->name);
|
||||
EvdevCloseDevice(pInfo);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
if (pEvdev->mtdev)
|
||||
pEvdev->cur_slot = pEvdev->mtdev->caps.slot.value;
|
||||
else {
|
||||
xf86Msg(X_ERROR, "%s: Couldn't open mtdev device\n", pInfo->name);
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Check major/minor of device node to avoid adding duplicate devices. */
|
||||
@@ -2254,17 +2371,34 @@ EvdevOpenDevice(InputInfoPtr pInfo)
|
||||
if (EvdevIsDuplicate(pInfo))
|
||||
{
|
||||
xf86IDrvMsg(pInfo, X_WARNING, "device file is duplicate. Ignoring.\n");
|
||||
close(pInfo->fd);
|
||||
#ifdef MULTITOUCH
|
||||
mtdev_close_delete(pEvdev->mtdev);
|
||||
pEvdev->mtdev = NULL;
|
||||
#endif
|
||||
EvdevCloseDevice(pInfo);
|
||||
return BadMatch;
|
||||
}
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
static void
|
||||
EvdevCloseDevice(InputInfoPtr pInfo)
|
||||
{
|
||||
EvdevPtr pEvdev = pInfo->private;
|
||||
if (pInfo->fd >= 0)
|
||||
{
|
||||
close(pInfo->fd);
|
||||
pInfo->fd = -1;
|
||||
}
|
||||
|
||||
#ifdef MULTITOUCH
|
||||
if (pEvdev->mtdev)
|
||||
{
|
||||
mtdev_close_delete(pEvdev->mtdev);
|
||||
pEvdev->mtdev = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
EvdevUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
|
||||
{
|
||||
@@ -2345,8 +2479,7 @@ EvdevPreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
|
||||
return Success;
|
||||
|
||||
error:
|
||||
if (pInfo->fd >= 0)
|
||||
close(pInfo->fd);
|
||||
EvdevCloseDevice(pInfo);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -2435,7 +2568,7 @@ EvdevUtilButtonEventToButtonNumber(EvdevPtr pEvdev, int code)
|
||||
/* Aligned with linux/input.h.
|
||||
Note that there are holes in the ABS_ range, these are simply replaced with
|
||||
MISC here */
|
||||
static char* abs_labels[] = {
|
||||
static const char *abs_labels[] = {
|
||||
AXIS_LABEL_PROP_ABS_X, /* 0x00 */
|
||||
AXIS_LABEL_PROP_ABS_Y, /* 0x01 */
|
||||
AXIS_LABEL_PROP_ABS_Z, /* 0x02 */
|
||||
@@ -2498,7 +2631,7 @@ static char* abs_labels[] = {
|
||||
AXIS_LABEL_PROP_ABS_MT_PRESSURE, /* 0x3a */
|
||||
};
|
||||
|
||||
static char* rel_labels[] = {
|
||||
static const char *rel_labels[] = {
|
||||
AXIS_LABEL_PROP_REL_X,
|
||||
AXIS_LABEL_PROP_REL_Y,
|
||||
AXIS_LABEL_PROP_REL_Z,
|
||||
@@ -2511,7 +2644,7 @@ static char* rel_labels[] = {
|
||||
AXIS_LABEL_PROP_REL_MISC
|
||||
};
|
||||
|
||||
static char* btn_labels[][16] = {
|
||||
static const char *btn_labels[][16] = {
|
||||
{ /* BTN_MISC group offset 0x100*/
|
||||
BTN_LABEL_PROP_BTN_0, /* 0x00 */
|
||||
BTN_LABEL_PROP_BTN_1, /* 0x01 */
|
||||
@@ -2592,18 +2725,18 @@ static char* btn_labels[][16] = {
|
||||
}
|
||||
};
|
||||
|
||||
static void EvdevInitAxesLabels(EvdevPtr pEvdev, int natoms, Atom *atoms)
|
||||
static void EvdevInitAxesLabels(EvdevPtr pEvdev, int mode, int natoms, Atom *atoms)
|
||||
{
|
||||
Atom atom;
|
||||
int axis;
|
||||
char **labels;
|
||||
const char **labels;
|
||||
int labels_len = 0;
|
||||
|
||||
if (pEvdev->flags & EVDEV_ABSOLUTE_EVENTS)
|
||||
if (mode == Absolute)
|
||||
{
|
||||
labels = abs_labels;
|
||||
labels_len = ArrayLength(abs_labels);
|
||||
} else if ((pEvdev->flags & EVDEV_RELATIVE_EVENTS))
|
||||
} else if (mode == Relative)
|
||||
{
|
||||
labels = rel_labels;
|
||||
labels_len = ArrayLength(rel_labels);
|
||||
@@ -2765,10 +2898,22 @@ EvdevInitProperty(DeviceIntPtr dev)
|
||||
/* Axis labelling */
|
||||
if ((pEvdev->num_vals > 0) && (prop_axis_label = XIGetKnownProperty(AXIS_LABEL_PROP)))
|
||||
{
|
||||
Atom atoms[pEvdev->num_vals];
|
||||
EvdevInitAxesLabels(pEvdev, pEvdev->num_vals, atoms);
|
||||
int mode;
|
||||
int num_axes = pEvdev->num_vals + pEvdev->num_mt_vals;
|
||||
Atom atoms[num_axes];
|
||||
|
||||
if (pEvdev->flags & EVDEV_ABSOLUTE_EVENTS)
|
||||
mode = Absolute;
|
||||
else if (pEvdev->flags & EVDEV_RELATIVE_EVENTS)
|
||||
mode = Relative;
|
||||
else {
|
||||
xf86IDrvMsg(pInfo, X_ERROR, "BUG: mode is neither absolute nor relative\n");
|
||||
mode = Absolute;
|
||||
}
|
||||
|
||||
EvdevInitAxesLabels(pEvdev, mode, num_axes, atoms);
|
||||
XIChangeDeviceProperty(dev, prop_axis_label, XA_ATOM, 32,
|
||||
PropModeReplace, pEvdev->num_vals, atoms, FALSE);
|
||||
PropModeReplace, num_axes, atoms, FALSE);
|
||||
XISetDevicePropertyDeletable(dev, prop_axis_label, FALSE);
|
||||
}
|
||||
/* Button labelling */
|
||||
|
||||
@@ -153,11 +153,13 @@ typedef struct {
|
||||
int grabDevice; /* grab the event device? */
|
||||
|
||||
int num_vals; /* number of valuators */
|
||||
int num_mt_vals; /* number of multitouch valuators */
|
||||
int axis_map[max(ABS_CNT, REL_CNT)]; /* Map evdev <axis> to index */
|
||||
ValuatorMask *vals; /* new values coming in */
|
||||
ValuatorMask *old_vals; /* old values for calculating relative motion */
|
||||
ValuatorMask *prox; /* last values set while not in proximity */
|
||||
ValuatorMask *mt_mask;
|
||||
ValuatorMask **last_mt_vals;
|
||||
int cur_slot;
|
||||
enum SlotState slot_state;
|
||||
#ifdef MULTITOUCH
|
||||
@@ -278,7 +280,6 @@ void EvdevMBEmuFinalize(InputInfoPtr);
|
||||
CARD32 Evdev3BEmuTimer(OsTimerPtr timer, CARD32 time, pointer arg);
|
||||
BOOL Evdev3BEmuFilterEvent(InputInfoPtr, int, BOOL);
|
||||
void Evdev3BEmuPreInit(InputInfoPtr pInfo);
|
||||
void Evdev3BEmuPreInit(InputInfoPtr);
|
||||
void Evdev3BEmuOn(InputInfoPtr);
|
||||
void Evdev3BEmuFinalize(InputInfoPtr);
|
||||
void Evdev3BEmuProcessRelMotion(InputInfoPtr pInfo, int dx, int dy);
|
||||
|
||||
69
src/udev.c
69
src/udev.c
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2011 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software
|
||||
* and its documentation for any purpose is hereby granted without
|
||||
* fee, provided that the above copyright notice appear in all copies
|
||||
* and that both that copyright notice and this permission notice
|
||||
* appear in supporting documentation, and that the name of Red Hat
|
||||
* not be used in advertising or publicity pertaining to distribution
|
||||
* of the software without specific, written prior permission. Red
|
||||
* Hat makes no representations about the suitability of this software
|
||||
* for any purpose. It is provided "as is" without express or implied
|
||||
* warranty.
|
||||
*
|
||||
* THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
|
||||
* NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
||||
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Authors:
|
||||
* Peter Hutterer (peter.hutterer@redhat.com)
|
||||
*/
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "evdev.h"
|
||||
|
||||
#include <libudev.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
Bool
|
||||
udev_device_is_virtual(const char* devicenode)
|
||||
{
|
||||
struct udev *udev = NULL;
|
||||
struct udev_device *device = NULL;
|
||||
struct stat st;
|
||||
int rc = FALSE;
|
||||
const char *devpath;
|
||||
|
||||
udev = udev_new();
|
||||
if (!udev)
|
||||
goto out;
|
||||
|
||||
stat(devicenode, &st);
|
||||
device = udev_device_new_from_devnum(udev, 'c', st.st_rdev);
|
||||
|
||||
if (!device)
|
||||
goto out;
|
||||
|
||||
|
||||
devpath = udev_device_get_devpath(device);
|
||||
if (!devpath)
|
||||
goto out;
|
||||
|
||||
if (strstr(devpath, "LNXSYSTM"))
|
||||
rc = TRUE;
|
||||
|
||||
out:
|
||||
udev_device_unref(device);
|
||||
udev_unref(udev);
|
||||
return rc;
|
||||
}
|
||||
Reference in New Issue
Block a user