diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/emuWheel.c | 2 | ||||
-rw-r--r-- | src/evdev.c | 188 | ||||
-rw-r--r-- | src/evdev.h | 3 |
3 files changed, 136 insertions, 57 deletions
diff --git a/src/emuWheel.c b/src/emuWheel.c index db989c5..5774930 100644 --- a/src/emuWheel.c +++ b/src/emuWheel.c @@ -117,7 +117,7 @@ EvdevWheelEmuFilterMotion(InputInfoPtr pInfo, struct input_event *pEv) /* We don't want to intercept real mouse wheel events */ if(pEv->type == EV_ABS) { - int axis = pEvdev->axis_map[pEv->code]; + int axis = pEvdev->abs_axis_map[pEv->code]; oldValue = valuator_mask_get(pEvdev->vals, axis); valuator_mask_set(pEvdev->vals, axis, value); value -= oldValue; /* make value into a differential measurement */ diff --git a/src/evdev.c b/src/evdev.c index c689257..570dd06 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -123,7 +123,7 @@ static int EvdevOpenDevice(InputInfoPtr pInfo); static void EvdevCloseDevice(InputInfoPtr pInfo); static void EvdevInitAxesLabels(EvdevPtr pEvdev, int mode, int natoms, Atom *atoms); -static void EvdevInitOneAxisLabel(EvdevPtr pEvdev, int axis, +static void EvdevInitOneAxisLabel(EvdevPtr pEvdev, int mapped_axis, const char **labels, int label_idx, Atom *atoms); static void EvdevInitButtonLabels(EvdevPtr pEvdev, int natoms, Atom *atoms); static void EvdevInitProperty(DeviceIntPtr dev); @@ -545,7 +545,7 @@ EvdevProcessValuators(InputInfoPtr pInfo) for (i = 0; i < REL_CNT; i++) { - int map = pEvdev->axis_map[i]; + int map = pEvdev->rel_axis_map[i]; if (pEvdev->delta[i] && map != -1) valuator_mask_set(pEvdev->vals, map, pEvdev->delta[i]); } @@ -707,7 +707,9 @@ EvdevProcessRelativeMotionEvent(InputInfoPtr pInfo, struct input_event *ev) #endif default: /* Ignore EV_REL events if we never set up for them. */ - if (!(pEvdev->flags & EVDEV_RELATIVE_EVENTS)) + if (!(pEvdev->flags & EVDEV_RELATIVE_EVENTS) && + ev->code != REL_WHEEL && ev->code != REL_DIAL && + ev->code != REL_HWHEEL) return; /* Handle mouse wheel emulation */ @@ -716,7 +718,7 @@ EvdevProcessRelativeMotionEvent(InputInfoPtr pInfo, struct input_event *ev) pEvdev->rel_queued = 1; pEvdev->delta[ev->code] += value; - map = pEvdev->axis_map[ev->code]; + map = pEvdev->rel_axis_map[ev->code]; valuator_mask_set(pEvdev->vals, map, value); break; } @@ -805,7 +807,7 @@ EvdevProcessTouchEvent(InputInfoPtr pInfo, struct input_event *ev) } else pEvdev->slot_state = SLOTSTATE_CLOSE; } else { - map = pEvdev->axis_map[ev->code]; + map = pEvdev->abs_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, @@ -845,7 +847,7 @@ EvdevProcessAbsoluteMotionEvent(InputInfoPtr pInfo, struct input_event *ev) EvdevProcessTouchEvent(pInfo, ev); pEvdev->abs_queued = 1; } else if (!pEvdev->mt_mask) { - map = pEvdev->axis_map[ev->code]; + map = pEvdev->abs_axis_map[ev->code]; valuator_mask_set(pEvdev->vals, map, value); pEvdev->abs_queued = 1; } @@ -1233,7 +1235,7 @@ is_blacklisted_axis(int axis) static int -EvdevAddAbsValuatorClass(DeviceIntPtr device) +EvdevAddAbsValuatorClass(DeviceIntPtr device, int want_scroll_axes) { InputInfoPtr pInfo; EvdevPtr pEvdev; @@ -1242,6 +1244,7 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device) num_mt_axes_total = 0; /* total number of MT axes, including double-counted ones, excluding blacklisted */ Atom *atoms; + int mapping = 0; pInfo = device->public.devicePrivate; pEvdev = pInfo->private; @@ -1281,6 +1284,19 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device) } } #endif + +#ifdef HAVE_SMOOTH_SCROLLING + if (want_scroll_axes && EvdevBitIsSet(pEvdev->bitmask, EV_REL)) + { + if (EvdevBitIsSet(pEvdev->rel_bitmask, REL_WHEEL)) + num_axes++; + if (EvdevBitIsSet(pEvdev->rel_bitmask, REL_HWHEEL)) + num_axes++; + if (EvdevBitIsSet(pEvdev->rel_bitmask, REL_DIAL)) + num_axes++; + } +#endif + if (num_axes + num_mt_axes > MAX_VALUATORS) { xf86IDrvMsg(pInfo, X_WARNING, "found %d axes, limiting to %d.\n", num_axes, MAX_VALUATORS); num_axes = MAX_VALUATORS; @@ -1347,8 +1363,7 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device) #ifdef MULTITOUCH int j; #endif - int mapping; - pEvdev->axis_map[axis] = -1; + pEvdev->abs_axis_map[axis] = -1; if (!EvdevBitIsSet(pEvdev->abs_bitmask, axis) || is_blacklisted_axis(axis)) continue; @@ -1365,11 +1380,25 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device) mapping = mt_axis_mappings[j].mapping; } #endif - pEvdev->axis_map[axis] = mapping; + pEvdev->abs_axis_map[axis] = mapping; if (mapping == i) i++; } +#ifdef HAVE_SMOOTH_SCROLLING + if (want_scroll_axes) + { + mapping++; /* continue from abs axis mapping */ + + if (EvdevBitIsSet(pEvdev->rel_bitmask, REL_HWHEEL)) + pEvdev->rel_axis_map[REL_HWHEEL] = mapping++; + if (EvdevBitIsSet(pEvdev->rel_bitmask, REL_DIAL)) + pEvdev->rel_axis_map[REL_DIAL] = mapping++; + if (EvdevBitIsSet(pEvdev->rel_bitmask, REL_WHEEL)) + pEvdev->rel_axis_map[REL_WHEEL] = mapping++; + } +#endif + EvdevInitAxesLabels(pEvdev, Absolute, pEvdev->num_vals + num_mt_axes, atoms); if (!InitValuatorClassDeviceStruct(device, num_axes + num_mt_axes, atoms, @@ -1398,11 +1427,11 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device) for (i = 0; i < num_slots(pEvdev); i++) { for (axis = ABS_MT_TOUCH_MAJOR; axis < ABS_MAX; axis++) { - if (pEvdev->axis_map[axis] >= 0) { + if (pEvdev->abs_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); + pEvdev->abs_axis_map[axis], 0); } } } @@ -1410,7 +1439,7 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device) #endif for (axis = ABS_X; axis < ABS_MT_SLOT; axis++) { - int axnum = pEvdev->axis_map[axis]; + int axnum = pEvdev->abs_axis_map[axis]; int resolution = 0; if (axnum == -1) @@ -1432,7 +1461,7 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device) #ifdef MULTITOUCH for (axis = ABS_MT_TOUCH_MAJOR; axis <= ABS_MAX; axis++) { - int axnum = pEvdev->axis_map[axis]; + int axnum = pEvdev->abs_axis_map[axis]; int resolution = 0; int j; BOOL skip = FALSE; @@ -1464,6 +1493,51 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device) } #endif +#ifdef HAVE_SMOOTH_SCROLLING + if (want_scroll_axes) + { + int idx; + if (EvdevBitIsSet(pEvdev->rel_bitmask, REL_WHEEL)) + { + idx = REL_WHEEL; + xf86InitValuatorAxisStruct(device, + pEvdev->rel_axis_map[idx], + atoms[pEvdev->rel_axis_map[idx]], + NO_AXIS_LIMITS, NO_AXIS_LIMITS, + 0, 0, 0, Relative); + SetScrollValuator(device, pEvdev->rel_axis_map[idx], + SCROLL_TYPE_VERTICAL, -1.0, + SCROLL_FLAG_PREFERRED); + } + + if (EvdevBitIsSet(pEvdev->rel_bitmask, REL_HWHEEL)) + { + idx = REL_HWHEEL; + xf86InitValuatorAxisStruct(device, + pEvdev->rel_axis_map[idx], + atoms[pEvdev->rel_axis_map[idx]], + NO_AXIS_LIMITS, NO_AXIS_LIMITS, + 0, 0, 0, Relative); + SetScrollValuator(device, pEvdev->rel_axis_map[idx], + SCROLL_TYPE_HORIZONTAL, 1.0, + SCROLL_FLAG_NONE); + } + + if (EvdevBitIsSet(pEvdev->rel_bitmask, REL_DIAL)) + { + idx = REL_DIAL; + xf86InitValuatorAxisStruct(device, + pEvdev->rel_axis_map[idx], + atoms[pEvdev->rel_axis_map[idx]], + NO_AXIS_LIMITS, NO_AXIS_LIMITS, + 0, 0, 0, Relative); + SetScrollValuator(device, pEvdev->rel_axis_map[idx], + SCROLL_TYPE_HORIZONTAL, 1.0, + SCROLL_FLAG_NONE); + } + } +#endif + free(atoms); for (i = 0; i < ArrayLength(proximity_bits); i++) @@ -1562,7 +1636,7 @@ EvdevAddRelValuatorClass(DeviceIntPtr device) for (axis = REL_X; i < MAX_VALUATORS && axis <= REL_MAX; axis++) { - pEvdev->axis_map[axis] = -1; + pEvdev->rel_axis_map[axis] = -1; #ifndef HAVE_SMOOTH_SCROLLING /* We don't post wheel events, so ignore them here too */ if (axis == REL_WHEEL || axis == REL_HWHEEL || axis == REL_DIAL) @@ -1570,7 +1644,7 @@ EvdevAddRelValuatorClass(DeviceIntPtr device) #endif if (!EvdevBitIsSet(pEvdev->rel_bitmask, axis)) continue; - pEvdev->axis_map[axis] = i; + pEvdev->rel_axis_map[axis] = i; i++; } @@ -1590,7 +1664,7 @@ EvdevAddRelValuatorClass(DeviceIntPtr device) for (axis = REL_X; axis <= REL_MAX; axis++) { - int axnum = pEvdev->axis_map[axis]; + int axnum = pEvdev->rel_axis_map[axis]; if (axnum == -1) continue; @@ -1693,12 +1767,16 @@ static void EvdevInitAnyValuators(DeviceIntPtr device, EvdevPtr pEvdev) { InputInfoPtr pInfo = device->public.devicePrivate; + int rel_success = FALSE; if (pEvdev->flags & EVDEV_RELATIVE_EVENTS && EvdevAddRelValuatorClass(device) == Success) + { + rel_success = TRUE; xf86IDrvMsg(pInfo, X_INFO, "initialized for relative axes.\n"); + } if (pEvdev->flags & EVDEV_ABSOLUTE_EVENTS && - EvdevAddAbsValuatorClass(device) == Success) + EvdevAddAbsValuatorClass(device, !rel_success) == Success) xf86IDrvMsg(pInfo, X_INFO, "initialized for absolute axes.\n"); } @@ -1707,7 +1785,7 @@ EvdevInitAbsValuators(DeviceIntPtr device, EvdevPtr pEvdev) { InputInfoPtr pInfo = device->public.devicePrivate; - if (EvdevAddAbsValuatorClass(device) == Success) { + if (EvdevAddAbsValuatorClass(device, TRUE) == Success) { xf86IDrvMsg(pInfo, X_INFO,"initialized for absolute axes.\n"); } else { xf86IDrvMsg(pInfo, X_ERROR,"failed to initialize for absolute axes.\n"); @@ -1757,17 +1835,12 @@ EvdevInitTouchDevice(DeviceIntPtr device, EvdevPtr pEvdev) static int EvdevInit(DeviceIntPtr device) { - int i; InputInfoPtr pInfo; EvdevPtr pEvdev; pInfo = device->public.devicePrivate; pEvdev = pInfo->private; - /* clear all axis_map entries */ - for(i = 0; i < max(ABS_CNT,REL_CNT); i++) - pEvdev->axis_map[i]=-1; - if (pEvdev->flags & EVDEV_KEYBOARD_EVENTS) EvdevAddKeyClass(device); if (pEvdev->flags & EVDEV_BUTTON_EVENTS) @@ -2479,13 +2552,40 @@ EvdevUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags) xf86DeleteInput(pInfo, flags); } +static EvdevPtr +EvdevAlloc(void) +{ + int i; + EvdevPtr pEvdev = calloc(sizeof(EvdevRec), 1); + + if (!pEvdev) + return NULL; + /* + * We initialize pEvdev->in_proximity to 1 so that device that doesn't use + * proximity will still report events. + */ + pEvdev->in_proximity = 1; + pEvdev->use_proximity = 1; + +#ifdef MULTITOUCH + pEvdev->cur_slot = -1; +#endif + + for (i = 0; i < ArrayLength(pEvdev->rel_axis_map); i++) + pEvdev->rel_axis_map[i] = -1; + for (i = 0; i < ArrayLength(pEvdev->abs_axis_map); i++) + pEvdev->abs_axis_map[i] = -1; + + return pEvdev; +} + static int EvdevPreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags) { EvdevPtr pEvdev; int rc = BadAlloc; - if (!(pEvdev = calloc(sizeof(EvdevRec), 1))) + if (!(pEvdev = EvdevAlloc())) goto error; pInfo->private = pEvdev; @@ -2498,17 +2598,6 @@ EvdevPreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags) if (rc != Success) goto error; -#ifdef MULTITOUCH - pEvdev->cur_slot = -1; -#endif - - /* - * We initialize pEvdev->in_proximity to 1 so that device that doesn't use - * proximity will still report events. - */ - pEvdev->in_proximity = 1; - pEvdev->use_proximity = 1; - /* 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. */ @@ -2630,43 +2719,32 @@ EvdevUtilButtonEventToButtonNumber(EvdevPtr pEvdev, int code) } } -static void EvdevInitOneAxisLabel(EvdevPtr pEvdev, int axis, +static void EvdevInitOneAxisLabel(EvdevPtr pEvdev, int mapped_axis, const char **labels, int label_idx, Atom *atoms) { Atom atom; - if (pEvdev->axis_map[axis] == -1) + if (mapped_axis == -1) return; atom = XIGetKnownProperty(labels[label_idx]); if (!atom) /* Should not happen */ return; - atoms[pEvdev->axis_map[axis]] = atom; + atoms[mapped_axis] = atom; } static void EvdevInitAxesLabels(EvdevPtr pEvdev, int mode, int natoms, Atom *atoms) { int axis; - const char **labels; - int labels_len = 0; - - if (mode == Absolute) - { - labels = abs_labels; - labels_len = ArrayLength(abs_labels); - } else if (mode == Relative) - { - labels = rel_labels; - labels_len = ArrayLength(rel_labels); - } else - return; memset(atoms, 0, natoms * sizeof(Atom)); - /* Now fill the ones we know */ - for (axis = 0; axis < labels_len; axis++) - EvdevInitOneAxisLabel(pEvdev, axis, labels, axis, atoms); + for (axis = 0; axis < ArrayLength(rel_labels); axis++) + EvdevInitOneAxisLabel(pEvdev, pEvdev->rel_axis_map[axis], rel_labels, axis, atoms); + + for (axis = 0; axis < ArrayLength(abs_labels); axis++) + EvdevInitOneAxisLabel(pEvdev, pEvdev->abs_axis_map[axis], abs_labels, axis, atoms); } static void EvdevInitButtonLabels(EvdevPtr pEvdev, int natoms, Atom *atoms) diff --git a/src/evdev.h b/src/evdev.h index 51b7fa0..63c3bfa 100644 --- a/src/evdev.h +++ b/src/evdev.h @@ -158,7 +158,8 @@ typedef struct { 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 */ + int abs_axis_map[ABS_CNT]; /* Map evdev ABS_* to index */ + int rel_axis_map[REL_CNT]; /* Map evdev REL_* 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 */ |