diff options
Diffstat (limited to 'libs/ui')
-rw-r--r-- | libs/ui/EventHub.cpp | 156 | ||||
-rw-r--r-- | libs/ui/InputDispatcher.cpp | 32 | ||||
-rw-r--r-- | libs/ui/InputReader.cpp | 160 |
3 files changed, 200 insertions, 148 deletions
diff --git a/libs/ui/EventHub.cpp b/libs/ui/EventHub.cpp index b1284fe..a3c34d0 100644 --- a/libs/ui/EventHub.cpp +++ b/libs/ui/EventHub.cpp @@ -99,6 +99,7 @@ EventHub::EventHub(void) , mDevicesById(0), mNumDevicesById(0) , mOpeningDevices(0), mClosingDevices(0) , mDevices(0), mFDs(0), mFDCount(0), mOpened(false) + , mInputBufferIndex(0), mInputBufferCount(0), mInputDeviceIndex(0) { acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID); #ifdef EV_SW @@ -341,13 +342,6 @@ bool EventHub::getEvent(RawEvent* outEvent) outEvent->value = 0; outEvent->when = 0; - status_t err; - - int i; - int res; - int pollres; - struct input_event iev; - // Note that we only allow one caller to getEvent(), so don't need // to do locking here... only when adding/removing devices. @@ -356,9 +350,8 @@ bool EventHub::getEvent(RawEvent* outEvent) mOpened = true; } - while(1) { - - // First, report any devices that had last been added/removed. + for (;;) { + // Report any devices that had last been added/removed. if (mClosingDevices != NULL) { device_t* device = mClosingDevices; LOGV("Reporting device closed: id=0x%x, name=%s\n", @@ -388,77 +381,96 @@ bool EventHub::getEvent(RawEvent* outEvent) return true; } - release_wake_lock(WAKE_LOCK_ID); - - pollres = poll(mFDs, mFDCount, -1); + // Grab the next input event. + for (;;) { + // Consume buffered input events, if any. + if (mInputBufferIndex < mInputBufferCount) { + const struct input_event& iev = mInputBufferData[mInputBufferIndex++]; + const device_t* device = mDevices[mInputDeviceIndex]; + + LOGV("%s got: t0=%d, t1=%d, type=%d, code=%d, v=%d", device->path.string(), + (int) iev.time.tv_sec, (int) iev.time.tv_usec, iev.type, iev.code, iev.value); + if (device->id == mFirstKeyboardId) { + outEvent->deviceId = 0; + } else { + outEvent->deviceId = device->id; + } + outEvent->type = iev.type; + outEvent->scanCode = iev.code; + if (iev.type == EV_KEY) { + status_t err = device->layoutMap->map(iev.code, + & outEvent->keyCode, & outEvent->flags); + LOGV("iev.code=%d keyCode=%d flags=0x%08x err=%d\n", + iev.code, outEvent->keyCode, outEvent->flags, err); + if (err != 0) { + outEvent->keyCode = AKEYCODE_UNKNOWN; + outEvent->flags = 0; + } + } else { + outEvent->keyCode = iev.code; + } + outEvent->value = iev.value; - acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID); + // Use an event timestamp in the same timebase as + // java.lang.System.nanoTime() and android.os.SystemClock.uptimeMillis() + // as expected by the rest of the system. + outEvent->when = systemTime(SYSTEM_TIME_MONOTONIC); + return true; + } - if (pollres <= 0) { - if (errno != EINTR) { - LOGW("select failed (errno=%d)\n", errno); - usleep(100000); + // Finish reading all events from devices identified in previous poll(). + // This code assumes that mInputDeviceIndex is initially 0 and that the + // revents member of pollfd is initialized to 0 when the device is first added. + // Since mFDs[0] is used for inotify, we process regular events starting at index 1. + mInputDeviceIndex += 1; + if (mInputDeviceIndex >= mFDCount) { + mInputDeviceIndex = 0; + break; } - continue; - } - //printf("poll %d, returned %d\n", mFDCount, pollres); - - // mFDs[0] is used for inotify, so process regular events starting at mFDs[1] - for(i = 1; i < mFDCount; i++) { - if(mFDs[i].revents) { - LOGV("revents for %d = 0x%08x", i, mFDs[i].revents); - if(mFDs[i].revents & POLLIN) { - res = read(mFDs[i].fd, &iev, sizeof(iev)); - if (res == sizeof(iev)) { - device_t* device = mDevices[i]; - LOGV("%s got: t0=%d, t1=%d, type=%d, code=%d, v=%d", - device->path.string(), - (int) iev.time.tv_sec, (int) iev.time.tv_usec, - iev.type, iev.code, iev.value); - if (device->id == mFirstKeyboardId) { - outEvent->deviceId = 0; - } else { - outEvent->deviceId = device->id; - } - outEvent->type = iev.type; - outEvent->scanCode = iev.code; - if (iev.type == EV_KEY) { - err = device->layoutMap->map(iev.code, - & outEvent->keyCode, & outEvent->flags); - LOGV("iev.code=%d keyCode=%d flags=0x%08x err=%d\n", - iev.code, outEvent->keyCode, outEvent->flags, err); - if (err != 0) { - outEvent->keyCode = AKEYCODE_UNKNOWN; - outEvent->flags = 0; - } - } else { - outEvent->keyCode = iev.code; - } - outEvent->value = iev.value; - - // Use an event timestamp in the same timebase as - // java.lang.System.nanoTime() and android.os.SystemClock.uptimeMillis() - // as expected by the rest of the system. - outEvent->when = systemTime(SYSTEM_TIME_MONOTONIC); - return true; - } else { - if (res<0) { - LOGW("could not get event (errno=%d)", errno); - } else { - LOGE("could not get event (wrong size: %d)", res); - } - continue; + const struct pollfd &pfd = mFDs[mInputDeviceIndex]; + if (pfd.revents & POLLIN) { + int32_t readSize = read(pfd.fd, mInputBufferData, + sizeof(struct input_event) * INPUT_BUFFER_SIZE); + if (readSize < 0) { + if (errno != EAGAIN && errno != EINTR) { + LOGW("could not get event (errno=%d)", errno); } + } else if ((readSize % sizeof(struct input_event)) != 0) { + LOGE("could not get event (wrong size: %d)", readSize); + } else { + mInputBufferCount = readSize / sizeof(struct input_event); + mInputBufferIndex = 0; } } } - + // read_notify() will modify mFDs and mFDCount, so this must be done after // processing all other events. if(mFDs[0].revents & POLLIN) { read_notify(mFDs[0].fd); } + + // Poll for events. Mind the wake lock dance! + // We hold a wake lock at all times except during poll(). This works due to some + // subtle choreography. When a device driver has pending (unread) events, it acquires + // a kernel wake lock. However, once the last pending event has been read, the device + // driver will release the kernel wake lock. To prevent the system from going to sleep + // when this happens, the EventHub holds onto its own user wake lock while the client + // is processing events. Thus the system can only sleep if there are no events + // pending or currently being processed. + release_wake_lock(WAKE_LOCK_ID); + + int pollResult = poll(mFDs, mFDCount, -1); + + acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID); + + if (pollResult <= 0) { + if (errno != EINTR) { + LOGW("select failed (errno=%d)\n", errno); + usleep(100000); + } + } } } @@ -476,6 +488,7 @@ bool EventHub::openPlatformInput(void) mFDs = (pollfd *)calloc(1, sizeof(mFDs[0])); mDevices = (device_t **)calloc(1, sizeof(mDevices[0])); mFDs[0].events = POLLIN; + mFDs[0].revents = 0; mDevices[0] = NULL; #ifdef HAVE_INOTIFY mFDs[0].fd = inotify_init(); @@ -582,6 +595,12 @@ int EventHub::open_device(const char *deviceName) idstr[0] = '\0'; } + if (fcntl(fd, F_SETFL, O_NONBLOCK)) { + LOGE("Error %d making device file descriptor non-blocking.", errno); + close(fd); + return -1; + } + int devid = 0; while (devid < mNumDevicesById) { if (mDevicesById[devid].device == NULL) { @@ -639,6 +658,7 @@ int EventHub::open_device(const char *deviceName) device->fd = fd; mFDs[mFDCount].fd = fd; mFDs[mFDCount].events = POLLIN; + mFDs[mFDCount].revents = 0; // Figure out the kinds of events the device reports. diff --git a/libs/ui/InputDispatcher.cpp b/libs/ui/InputDispatcher.cpp index b53f140..13030b5 100644 --- a/libs/ui/InputDispatcher.cpp +++ b/libs/ui/InputDispatcher.cpp @@ -433,8 +433,7 @@ void InputDispatcher::dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTi for (size_t i = 0; i < mCurrentInputTargets.size(); i++) { const InputTarget& inputTarget = mCurrentInputTargets.itemAt(i); - ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey( - inputTarget.inputChannel->getReceivePipeFd()); + ssize_t connectionIndex = getConnectionIndex(inputTarget.inputChannel); if (connectionIndex >= 0) { sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex); prepareDispatchCycleLocked(currentTime, connection, eventEntry, & inputTarget, @@ -1367,12 +1366,10 @@ status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChan LOGD("channel '%s' ~ registerInputChannel", inputChannel->getName().string()); #endif - int receiveFd; { // acquire lock AutoMutex _l(mLock); - receiveFd = inputChannel->getReceivePipeFd(); - if (mConnectionsByReceiveFd.indexOfKey(receiveFd) >= 0) { + if (getConnectionIndex(inputChannel) >= 0) { LOGW("Attempted to register already registered input channel '%s'", inputChannel->getName().string()); return BAD_VALUE; @@ -1386,12 +1383,13 @@ status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChan return status; } + int32_t receiveFd = inputChannel->getReceivePipeFd(); mConnectionsByReceiveFd.add(receiveFd, connection); + mPollLoop->setCallback(receiveFd, POLLIN, handleReceiveCallback, this); + runCommandsLockedInterruptible(); } // release lock - - mPollLoop->setCallback(receiveFd, POLLIN, handleReceiveCallback, this); return OK; } @@ -1400,12 +1398,10 @@ status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputCh LOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().string()); #endif - int32_t receiveFd; { // acquire lock AutoMutex _l(mLock); - receiveFd = inputChannel->getReceivePipeFd(); - ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(receiveFd); + ssize_t connectionIndex = getConnectionIndex(inputChannel); if (connectionIndex < 0) { LOGW("Attempted to unregister already unregistered input channel '%s'", inputChannel->getName().string()); @@ -1417,20 +1413,32 @@ status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputCh connection->status = Connection::STATUS_ZOMBIE; + mPollLoop->removeCallback(inputChannel->getReceivePipeFd()); + nsecs_t currentTime = now(); abortDispatchCycleLocked(currentTime, connection, true /*broken*/); runCommandsLockedInterruptible(); } // release lock - mPollLoop->removeCallback(receiveFd); - // Wake the poll loop because removing the connection may have changed the current // synchronization state. mPollLoop->wake(); return OK; } +ssize_t InputDispatcher::getConnectionIndex(const sp<InputChannel>& inputChannel) { + ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(inputChannel->getReceivePipeFd()); + if (connectionIndex >= 0) { + sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex); + if (connection->inputChannel.get() == inputChannel.get()) { + return connectionIndex; + } + } + + return -1; +} + void InputDispatcher::activateConnectionLocked(Connection* connection) { for (size_t i = 0; i < mActiveConnections.size(); i++) { if (mActiveConnections.itemAt(i) == connection) { diff --git a/libs/ui/InputReader.cpp b/libs/ui/InputReader.cpp index 5f5a4ac..6f042ec 100644 --- a/libs/ui/InputReader.cpp +++ b/libs/ui/InputReader.cpp @@ -945,7 +945,6 @@ void TrackballInputMapper::reset() { mAccumulator.fields = Accumulator::FIELD_BTN_MOUSE; mAccumulator.btnMouse = false; sync(when); - mAccumulator.clear(); } InputMapper::reset(); @@ -958,9 +957,9 @@ void TrackballInputMapper::process(const RawEvent* rawEvent) { case BTN_MOUSE: mAccumulator.fields |= Accumulator::FIELD_BTN_MOUSE; mAccumulator.btnMouse = rawEvent->value != 0; - + // Sync now since BTN_MOUSE is not necessarily followed by SYN_REPORT and + // we need to ensure that we report the up/down promptly. sync(rawEvent->when); - mAccumulator.clear(); break; } break; @@ -981,10 +980,7 @@ void TrackballInputMapper::process(const RawEvent* rawEvent) { case EV_SYN: switch (rawEvent->scanCode) { case SYN_REPORT: - if (mAccumulator.isDirty()) { - sync(rawEvent->when); - mAccumulator.clear(); - } + sync(rawEvent->when); break; } break; @@ -992,13 +988,17 @@ void TrackballInputMapper::process(const RawEvent* rawEvent) { } void TrackballInputMapper::sync(nsecs_t when) { + uint32_t fields = mAccumulator.fields; + if (fields == 0) { + return; // no new state changes, so nothing to do + } + int motionEventAction; PointerCoords pointerCoords; nsecs_t downTime; { // acquire lock AutoMutex _l(mLock); - uint32_t fields = mAccumulator.fields; bool downChanged = fields & Accumulator::FIELD_BTN_MOUSE; if (downChanged) { @@ -1061,6 +1061,8 @@ void TrackballInputMapper::sync(nsecs_t when) { } // release lock applyPolicyAndDispatch(when, motionEventAction, & pointerCoords, downTime); + + mAccumulator.clear(); } void TrackballInputMapper::applyPolicyAndDispatch(nsecs_t when, int32_t motionEventAction, @@ -2380,8 +2382,8 @@ void SingleTouchInputMapper::initialize() { mDown = false; mX = 0; mY = 0; - mPressure = 0; - mSize = 0; + mPressure = 1; // default to 1 for devices that don't report pressure + mSize = 0; // default to 0 for devices that don't report size } void SingleTouchInputMapper::reset() { @@ -2397,9 +2399,9 @@ void SingleTouchInputMapper::process(const RawEvent* rawEvent) { case BTN_TOUCH: mAccumulator.fields |= Accumulator::FIELD_BTN_TOUCH; mAccumulator.btnTouch = rawEvent->value != 0; - - sync(rawEvent->when); - mAccumulator.clear(); + // Don't sync immediately. Wait until the next SYN_REPORT since we might + // not have received valid position information yet. This logic assumes that + // BTN_TOUCH is always followed by SYN_REPORT as part of a complete packet. break; } break; @@ -2428,10 +2430,7 @@ void SingleTouchInputMapper::process(const RawEvent* rawEvent) { case EV_SYN: switch (rawEvent->scanCode) { case SYN_REPORT: - if (mAccumulator.isDirty()) { - sync(rawEvent->when); - mAccumulator.clear(); - } + sync(rawEvent->when); break; } break; @@ -2439,9 +2438,10 @@ void SingleTouchInputMapper::process(const RawEvent* rawEvent) { } void SingleTouchInputMapper::sync(nsecs_t when) { - /* Update device state */ - uint32_t fields = mAccumulator.fields; + if (fields == 0) { + return; // no new state changes, so nothing to do + } if (fields & Accumulator::FIELD_BTN_TOUCH) { mDown = mAccumulator.btnTouch; @@ -2472,8 +2472,8 @@ void SingleTouchInputMapper::sync(nsecs_t when) { mCurrentTouch.pointers[0].y = mY; mCurrentTouch.pointers[0].pressure = mPressure; mCurrentTouch.pointers[0].size = mSize; - mCurrentTouch.pointers[0].touchMajor = mPressure; - mCurrentTouch.pointers[0].touchMinor = mPressure; + mCurrentTouch.pointers[0].touchMajor = mSize; + mCurrentTouch.pointers[0].touchMinor = mSize; mCurrentTouch.pointers[0].toolMajor = mSize; mCurrentTouch.pointers[0].toolMinor = mSize; mCurrentTouch.pointers[0].orientation = 0; @@ -2482,6 +2482,8 @@ void SingleTouchInputMapper::sync(nsecs_t when) { } syncTouch(when, true); + + mAccumulator.clear(); } void SingleTouchInputMapper::configureAxes() { @@ -2494,8 +2496,8 @@ void SingleTouchInputMapper::configureAxes() { getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_PRESSURE, & mAxes.pressure); getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_TOOL_WIDTH, & mAxes.size); - mAxes.touchMajor = mAxes.pressure; - mAxes.touchMinor = mAxes.pressure; + mAxes.touchMajor = mAxes.size; + mAxes.touchMinor = mAxes.size; mAxes.toolMajor = mAxes.size; mAxes.toolMinor = mAxes.size; } @@ -2585,10 +2587,7 @@ void MultiTouchInputMapper::process(const RawEvent* rawEvent) { } case SYN_REPORT: - if (mAccumulator.isDirty()) { - sync(rawEvent->when); - mAccumulator.clear(); - } + sync(rawEvent->when); break; } break; @@ -2598,11 +2597,7 @@ void MultiTouchInputMapper::process(const RawEvent* rawEvent) { void MultiTouchInputMapper::sync(nsecs_t when) { static const uint32_t REQUIRED_FIELDS = Accumulator::FIELD_ABS_MT_POSITION_X - | Accumulator::FIELD_ABS_MT_POSITION_Y - | Accumulator::FIELD_ABS_MT_TOUCH_MAJOR - | Accumulator::FIELD_ABS_MT_WIDTH_MAJOR; - - /* Update device state */ + | Accumulator::FIELD_ABS_MT_POSITION_Y; uint32_t inCount = mAccumulator.pointerCount; uint32_t outCount = 0; @@ -2611,53 +2606,76 @@ void MultiTouchInputMapper::sync(nsecs_t when) { mCurrentTouch.clear(); for (uint32_t inIndex = 0; inIndex < inCount; inIndex++) { - uint32_t fields = mAccumulator.pointers[inIndex].fields; + const Accumulator::Pointer& inPointer = mAccumulator.pointers[inIndex]; + uint32_t fields = inPointer.fields; if ((fields & REQUIRED_FIELDS) != REQUIRED_FIELDS) { -#if DEBUG_POINTERS - LOGD("Pointers: Missing required multitouch pointer fields: index=%d, fields=%d", - inIndex, fields); + // Some drivers send empty MT sync packets without X / Y to indicate a pointer up. + // Drop this finger. continue; -#endif } - if (mAccumulator.pointers[inIndex].absMTTouchMajor <= 0) { - // Pointer is not down. Drop it. - continue; + PointerData& outPointer = mCurrentTouch.pointers[outCount]; + outPointer.x = inPointer.absMTPositionX; + outPointer.y = inPointer.absMTPositionY; + + if (fields & Accumulator::FIELD_ABS_MT_TOUCH_MAJOR) { + int32_t value = inPointer.absMTTouchMajor; + if (value <= 0) { + // Some devices send sync packets with X / Y but with a 0 touch major to indicate + // a pointer up. Drop this finger. + continue; + } + outPointer.touchMajor = inPointer.absMTTouchMajor; + } else { + outPointer.touchMajor = 0; } - mCurrentTouch.pointers[outCount].x = mAccumulator.pointers[inIndex].absMTPositionX; - mCurrentTouch.pointers[outCount].y = mAccumulator.pointers[inIndex].absMTPositionY; + if (fields & Accumulator::FIELD_ABS_MT_TOUCH_MINOR) { + outPointer.touchMinor = inPointer.absMTTouchMinor; + } else { + outPointer.touchMinor = outPointer.touchMajor; + } + + if (fields & Accumulator::FIELD_ABS_MT_WIDTH_MAJOR) { + outPointer.toolMajor = inPointer.absMTWidthMajor; + } else { + outPointer.toolMajor = outPointer.touchMajor; + } - mCurrentTouch.pointers[outCount].touchMajor = - mAccumulator.pointers[inIndex].absMTTouchMajor; - mCurrentTouch.pointers[outCount].touchMinor = - (fields & Accumulator::FIELD_ABS_MT_TOUCH_MINOR) != 0 - ? mAccumulator.pointers[inIndex].absMTTouchMinor - : mAccumulator.pointers[inIndex].absMTTouchMajor; + if (fields & Accumulator::FIELD_ABS_MT_WIDTH_MINOR) { + outPointer.toolMinor = inPointer.absMTWidthMinor; + } else { + outPointer.toolMinor = outPointer.toolMajor; + } - mCurrentTouch.pointers[outCount].toolMajor = - mAccumulator.pointers[inIndex].absMTWidthMajor; - mCurrentTouch.pointers[outCount].toolMinor = - (fields & Accumulator::FIELD_ABS_MT_WIDTH_MINOR) != 0 - ? mAccumulator.pointers[inIndex].absMTWidthMinor - : mAccumulator.pointers[inIndex].absMTWidthMajor; + if (fields & Accumulator::FIELD_ABS_MT_ORIENTATION) { + outPointer.orientation = inPointer.absMTOrientation; + } else { + outPointer.orientation = 0; + } - mCurrentTouch.pointers[outCount].orientation = - (fields & Accumulator::FIELD_ABS_MT_ORIENTATION) != 0 - ? mAccumulator.pointers[inIndex].absMTOrientation : 0; + if (fields & Accumulator::FIELD_ABS_MT_PRESSURE) { + outPointer.pressure = inPointer.absMTPressure; + } else { + // Derive an approximation of pressure. + // FIXME Traditionally we have just passed a normalized value based on + // ABS_MT_TOUCH_MAJOR as an estimate of pressure but the result is not + // very meaningful, particularly on large displays. We should probably let + // pressure = touch_major / tool_major but it is unclear whether that will + // break applications. + outPointer.pressure = outPointer.touchMajor; + } - // Derive an approximation of pressure and size. - // FIXME assignment of pressure may be incorrect, probably better to let - // pressure = touch / width. Later on we pass width to MotionEvent as a size, which - // isn't quite right either. Should be using touch for that. - mCurrentTouch.pointers[outCount].pressure = mAccumulator.pointers[inIndex].absMTTouchMajor; - mCurrentTouch.pointers[outCount].size = mAccumulator.pointers[inIndex].absMTWidthMajor; + // Size is an alias for a normalized tool width. + // FIXME Normalized tool width doesn't actually make much sense since it literally + // means the approaching contact major axis is divided by its full range as + // reported by the driver. On a large display this could produce very small values. + outPointer.size = outPointer.toolMajor; if (havePointerIds) { - if (fields & Accumulator:: - FIELD_ABS_MT_TRACKING_ID) { - uint32_t id = uint32_t(mAccumulator.pointers[inIndex].absMTTrackingId); + if (fields & Accumulator::FIELD_ABS_MT_TRACKING_ID) { + uint32_t id = uint32_t(inPointer.absMTTrackingId); if (id > MAX_POINTER_ID) { #if DEBUG_POINTERS @@ -2668,7 +2686,7 @@ void MultiTouchInputMapper::sync(nsecs_t when) { havePointerIds = false; } else { - mCurrentTouch.pointers[outCount].id = id; + outPointer.id = id; mCurrentTouch.idToIndex[id] = outCount; mCurrentTouch.idBits.markBit(id); } @@ -2683,6 +2701,8 @@ void MultiTouchInputMapper::sync(nsecs_t when) { mCurrentTouch.pointerCount = outCount; syncTouch(when, havePointerIds); + + mAccumulator.clear(); } void MultiTouchInputMapper::configureAxes() { @@ -2697,6 +2717,7 @@ void MultiTouchInputMapper::configureAxes() { getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_WIDTH_MAJOR, & mAxes.toolMajor); getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_WIDTH_MINOR, & mAxes.toolMinor); getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_ORIENTATION, & mAxes.orientation); + getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_PRESSURE, & mAxes.pressure); if (! mAxes.touchMinor.valid) { mAxes.touchMinor = mAxes.touchMajor; @@ -2706,7 +2727,10 @@ void MultiTouchInputMapper::configureAxes() { mAxes.toolMinor = mAxes.toolMajor; } - mAxes.pressure = mAxes.touchMajor; + if (! mAxes.pressure.valid) { + mAxes.pressure = mAxes.touchMajor; + } + mAxes.size = mAxes.toolMajor; } |