diff options
author | Scott Brady <sbradymobile@gmail.com> | 2011-04-16 11:44:54 -0700 |
---|---|---|
committer | Steve Kondik <shade@chemlab.org> | 2011-04-30 00:52:42 -0400 |
commit | eaf9b10827c8f5a651b0fef230978ee1e22cc20a (patch) | |
tree | 50bf8d7dd5ecfeaf0b33c46a4cefb918634b7585 /libs | |
parent | 937a7ba32f2a5592ecd0c787edb671caa011d6b2 (diff) | |
download | frameworks_base-eaf9b10827c8f5a651b0fef230978ee1e22cc20a.zip frameworks_base-eaf9b10827c8f5a651b0fef230978ee1e22cc20a.tar.gz frameworks_base-eaf9b10827c8f5a651b0fef230978ee1e22cc20a.tar.bz2 |
Fixed up mouse pointer with auto bluetooth on and scroll Change-Id: I6850236a3058475694793e40717f69683c50edd7
Change-Id: I760e09e63c51278c96e2ae3b75b02d73da091eb5
Diffstat (limited to 'libs')
-rw-r--r-- | libs/ui/EventHub.cpp | 5 | ||||
-rw-r--r-- | libs/ui/InputDispatcher.cpp | 10 | ||||
-rw-r--r-- | libs/ui/InputReader.cpp | 322 |
3 files changed, 332 insertions, 5 deletions
diff --git a/libs/ui/EventHub.cpp b/libs/ui/EventHub.cpp index 41daa9c..5f920a7 100644 --- a/libs/ui/EventHub.cpp +++ b/libs/ui/EventHub.cpp @@ -719,7 +719,10 @@ int EventHub::openDevice(const char *deviceName) { LOGV("Getting relative controllers..."); if (ioctl(fd, EVIOCGBIT(EV_REL, sizeof(rel_bitmask)), rel_bitmask) >= 0) { if (test_bit(REL_X, rel_bitmask) && test_bit(REL_Y, rel_bitmask)) { - device->classes |= INPUT_DEVICE_CLASS_TRACKBALL; + if (test_bit(BTN_LEFT, key_bitmask) && test_bit(BTN_RIGHT, key_bitmask)) + device->classes |= INPUT_DEVICE_CLASS_MOUSE; + else + device->classes |= INPUT_DEVICE_CLASS_TRACKBALL; } } } diff --git a/libs/ui/InputDispatcher.cpp b/libs/ui/InputDispatcher.cpp index 117d705..3637ad3 100644 --- a/libs/ui/InputDispatcher.cpp +++ b/libs/ui/InputDispatcher.cpp @@ -733,17 +733,19 @@ bool InputDispatcher::dispatchMotionLocked( return true; } - bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER; + bool isTouchEvent = ! ((entry->source & AINPUT_SOURCE_TOUCHSCREEN) ^ AINPUT_SOURCE_TOUCHSCREEN); + bool isMouseEvent = ! ((entry->source & AINPUT_SOURCE_MOUSE) ^ AINPUT_SOURCE_MOUSE); + bool isDownEvent = (entry->action & AMOTION_EVENT_ACTION_MASK) == AMOTION_EVENT_ACTION_DOWN; // Identify targets. if (! mCurrentInputTargetsValid) { int32_t injectionResult; - if (isPointerEvent) { - // Pointer event. (eg. touchscreen) + if (isTouchEvent || (isMouseEvent && (isDownEvent || mTouchState.down))) { + // Touch-like event. (eg. touchscreen or mouse drag-n-drop ) injectionResult = findTouchedWindowTargetsLocked(currentTime, entry, nextWakeupTime); } else { - // Non touch event. (eg. trackball) + // Non touch event. (eg. trackball or mouse simple move) injectionResult = findFocusedWindowTargetsLocked(currentTime, entry, nextWakeupTime); } diff --git a/libs/ui/InputReader.cpp b/libs/ui/InputReader.cpp index 34e44e4..0729b68 100644 --- a/libs/ui/InputReader.cpp +++ b/libs/ui/InputReader.cpp @@ -347,6 +347,11 @@ InputDevice* InputReader::createDevice(int32_t deviceId, const String8& name, ui device->addMapper(new SingleTouchInputMapper(device, associatedDisplayId)); } + // Mouse-like devices. + if (classes & INPUT_DEVICE_CLASS_MOUSE) { + device->addMapper(new MouseInputMapper(device, associatedDisplayId)); + } + return device; } @@ -3177,6 +3182,323 @@ bool TouchInputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCode return true; } +// --- MouseInputMapper --- + +MouseInputMapper::MouseInputMapper(InputDevice* device, int32_t associatedDisplayId) : + InputMapper(device), mAssociatedDisplayId(associatedDisplayId) { + initializeLocked(); +} + +MouseInputMapper::~MouseInputMapper() { +} + +uint32_t MouseInputMapper::getSources() { + return AINPUT_SOURCE_MOUSE; +} + +void MouseInputMapper::populateDeviceInfo(InputDeviceInfo* info) { + InputMapper::populateDeviceInfo(info); +} + +void MouseInputMapper::dump(String8& dump) { + { // acquire lock + AutoMutex _l(mLock); + dump.append(INDENT2 "Mouse Input Mapper:\n"); + dump.appendFormat(INDENT3 "AssociatedDisplayId: %d\n", mAssociatedDisplayId); + dump.appendFormat(INDENT3 "Down: %s\n", toString(mLocked.down)); + dump.appendFormat(INDENT3 "DownTime: %lld\n", mLocked.downTime); + } // release lock +} + +void MouseInputMapper::initializeLocked() { + mAccumulator.clear(); + + mLocked.down = false; + mLocked.downTime = 0; + + int32_t screenWidth; + int32_t screenHeight; + if (mAssociatedDisplayId < 0 || ! getPolicy()->getDisplayInfo(mAssociatedDisplayId, &screenWidth, &screenHeight, NULL)) { + mAccumulator.absX = 0; + mAccumulator.absY = 0; + }else{ + mAccumulator.absX = screenWidth/2; + mAccumulator.absY = screenHeight/2; + } +} + +void MouseInputMapper::reset() { + for (;;) { + { // acquire lock + AutoMutex _l(mLock); + + if (! mLocked.down) { + initializeLocked(); + break; // done + } + } // release lock + + // Synthesize trackball button up event on reset. + nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC); + mAccumulator.fields = Accumulator::FIELD_BTN_MOUSE; + mAccumulator.btnMouse = false; + mAccumulator.btnScrollUp = false; + mAccumulator.btnScrollDown = false; + sync(when); + } + + InputMapper::reset(); +} + +void MouseInputMapper::process(const RawEvent* rawEvent) { + switch (rawEvent->type) { + case EV_KEY: + switch (rawEvent->scanCode) { + case BTN_MOUSE: + mAccumulator.fields |= Accumulator::FIELD_BTN_MOUSE; + mAccumulator.btnMouse = rawEvent->value != 0; + sync(rawEvent->when); + break; + case BTN_RIGHT: + // Back Button + mAccumulator.fields |= Accumulator::FIELD_BTN_RIGHT; + mAccumulator.btnRight = rawEvent->value != 0; + sync(rawEvent->when); + break; + case BTN_MIDDLE: + // Menu Button + mAccumulator.fields |= Accumulator::FIELD_BTN_MIDDLE; + mAccumulator.btnMiddle = rawEvent->value != 0; + sync(rawEvent->when); + break; + case BTN_SIDE: + // Home Button + mAccumulator.fields |= Accumulator::FIELD_BTN_SIDE; + mAccumulator.btnSide = rawEvent->value != 0; + sync(rawEvent->when); + break; + case BTN_EXTRA: + // Search Button + mAccumulator.fields |= Accumulator::FIELD_BTN_EXTRA; + mAccumulator.btnExtra = rawEvent->value != 0; + sync(rawEvent->when); + break; + case BTN_FORWARD: + // Search Button + mAccumulator.fields |= Accumulator::FIELD_BTN_FORWARD; + mAccumulator.btnForward = rawEvent->value != 0; + sync(rawEvent->when); + break; + case BTN_BACK: + // Home Button + mAccumulator.fields |= Accumulator::FIELD_BTN_BACK; + mAccumulator.btnBack = rawEvent->value != 0; + sync(rawEvent->when); + break; + } + break; + + case EV_REL: + switch (rawEvent->scanCode) { + case REL_X: + mAccumulator.fields |= Accumulator::FIELD_REL_X; + mAccumulator.relX = rawEvent->value; + break; + case REL_Y: + mAccumulator.fields |= Accumulator::FIELD_REL_Y; + mAccumulator.relY = rawEvent->value; + break; + case REL_WHEEL: + mAccumulator.fields |= Accumulator::FIELD_REL_WHEEL; + mAccumulator.btnScrollUp = rawEvent->value == 1; + mAccumulator.btnScrollDown = rawEvent->value == -1; + break; + } + break; + + case EV_SYN: + switch (rawEvent->scanCode) { + case SYN_REPORT: + sync(rawEvent->when); + break; + } + break; + } +} + +void MouseInputMapper::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); + + if (fields & Accumulator::FIELD_BTN_RIGHT) { + getDispatcher()->notifyKey(when, getDeviceId(), + AINPUT_SOURCE_DPAD, 0, mAccumulator.btnRight ? + AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP, + AKEY_EVENT_FLAG_FROM_SYSTEM, + 0x04 /*Keycode for back key*/, 0x18 /*Scancode*/, + mContext->getGlobalMetaState(), when); + } + + if (fields & Accumulator::FIELD_BTN_MIDDLE) { + getDispatcher()->notifyKey(when, getDeviceId(), + AINPUT_SOURCE_DPAD, 0, mAccumulator.btnMiddle ? + AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP, + AKEY_EVENT_FLAG_FROM_SYSTEM, + 0x52/*Keycode for menu key*/, 0x19 /*Scancode*/, + mContext->getGlobalMetaState(), when); + } + + if (fields & Accumulator::FIELD_BTN_SIDE) { + getDispatcher()->notifyKey(when, getDeviceId(), + AINPUT_SOURCE_DPAD, 0, mAccumulator.btnSide ? + AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP, + AKEY_EVENT_FLAG_FROM_SYSTEM, + 0x03 /*Keycode for home key*/, 0x20 /*Scancode*/, + mContext->getGlobalMetaState(), when); + } + + if (fields & Accumulator::FIELD_BTN_EXTRA) { + getDispatcher()->notifyKey(when, getDeviceId(), + AINPUT_SOURCE_DPAD, 0, mAccumulator.btnExtra ? + AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP, + AKEY_EVENT_FLAG_FROM_SYSTEM, + 0x54/*Keycode for search key*/, 0x21 /*Scancode*/, + mContext->getGlobalMetaState(), when); + } + + if (fields & Accumulator::FIELD_BTN_FORWARD) { + getDispatcher()->notifyKey(when, getDeviceId(), + AINPUT_SOURCE_DPAD, 0, mAccumulator.btnForward ? + AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP, + AKEY_EVENT_FLAG_FROM_SYSTEM, + 0x16 /*Keycode for right key*/, 0x22 /*Scancode*/, + mContext->getGlobalMetaState(), when); + } + + if (fields & Accumulator::FIELD_BTN_BACK) { + getDispatcher()->notifyKey(when, getDeviceId(), + AINPUT_SOURCE_DPAD, 0, mAccumulator.btnBack ? + AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP, + AKEY_EVENT_FLAG_FROM_SYSTEM, + 0x15/*Keycode for left key*/, 0x23 /*Scancode*/, + mContext->getGlobalMetaState(), when); + } + + bool downChanged = fields & Accumulator::FIELD_BTN_MOUSE; + if (downChanged) { + if (mAccumulator.btnMouse) { + mLocked.down = true; + mLocked.downTime = when; + } else { + mLocked.down = false; + } + motionEventAction = mLocked.down ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP; + } else { + motionEventAction = AMOTION_EVENT_ACTION_MOVE; + } + + bool scrollChanged = fields & Accumulator::FIELD_REL_WHEEL; + if (mAccumulator.btnScrollUp && scrollChanged) { + getDispatcher()->notifyKey(when, getDeviceId(), + AINPUT_SOURCE_DPAD, 0, AKEY_EVENT_ACTION_DOWN, + AKEY_EVENT_FLAG_FROM_SYSTEM, + 0x5c/*Keycode for page up key*/, 0x24 /*Scancode*/, + mContext->getGlobalMetaState(), when); + getDispatcher()->notifyKey(when + (10 * 1000000LL), getDeviceId(), + AINPUT_SOURCE_DPAD, 0, AKEY_EVENT_ACTION_UP, + AKEY_EVENT_FLAG_FROM_SYSTEM, + 0x5c/*Keycode for page up key*/, 0x24 /*Scancode*/, + mContext->getGlobalMetaState(), when + (10 * 1000000LL)); + } + else if (mAccumulator.btnScrollDown && scrollChanged) { + getDispatcher()->notifyKey(when, getDeviceId(), + AINPUT_SOURCE_DPAD, 0, AKEY_EVENT_ACTION_DOWN, + AKEY_EVENT_FLAG_FROM_SYSTEM, + 0x5d/*Keycode for page down key*/, 0x25 /*Scancode*/, + mContext->getGlobalMetaState(), when); + getDispatcher()->notifyKey(when + (10 * 1000000LL), getDeviceId(), + AINPUT_SOURCE_DPAD, 0, AKEY_EVENT_ACTION_UP, + AKEY_EVENT_FLAG_FROM_SYSTEM, + 0x5d/*Keycode for page down key*/, 0x25 /*Scancode*/, + mContext->getGlobalMetaState(), when + (10 * 1000000LL)); + } + + downTime = mLocked.downTime; + + float x = fields & Accumulator::FIELD_REL_X ? mAccumulator.relX : 0.0f; + float y = fields & Accumulator::FIELD_REL_Y ? mAccumulator.relY : 0.0f; + + int32_t screenWidth; + int32_t screenHeight; + int32_t orientation; + + mAccumulator.absX = (mAccumulator.absX + x) > screenWidth ? screenWidth -1 : ((mAccumulator.absX + x) < 0 ? 0 : mAccumulator.absX + x); + mAccumulator.absY = (mAccumulator.absY + y) > screenHeight ? screenHeight -1 : ((mAccumulator.absY + y) < 0 ? 0 : mAccumulator.absY + y); + pointerCoords.x = mAccumulator.absX; + pointerCoords.y = mAccumulator.absY; + pointerCoords.pressure = mLocked.down ? 1.0f : 0.0f; + pointerCoords.size = 0; + pointerCoords.touchMajor = 0; + pointerCoords.touchMinor = 0; + pointerCoords.toolMajor = 0; + pointerCoords.toolMinor = 0; + pointerCoords.orientation = 0; + + if (mAssociatedDisplayId < 0 || ! getPolicy()->getDisplayInfo(mAssociatedDisplayId, &screenWidth, &screenHeight, &orientation)) { + return; + } + + float temp; + switch (orientation) { + case InputReaderPolicyInterface::ROTATION_90: + temp = x; + x = y; + y = - temp; + temp = screenHeight; + screenHeight = screenWidth; + screenWidth = temp; + break; + + case InputReaderPolicyInterface::ROTATION_180: + x = - x; + y = - y; + break; + + case InputReaderPolicyInterface::ROTATION_270: + temp = x; + x = - y; + y = temp; + temp = screenHeight; + screenHeight = screenWidth; + screenWidth = temp; + break; + } + + } // release lock + + int32_t metaState = mContext->getGlobalMetaState(); + int32_t pointerId = 0; + getDispatcher()->notifyMotion(when, getDeviceId(), AINPUT_SOURCE_MOUSE, 0, + motionEventAction, 0, metaState, AMOTION_EVENT_EDGE_FLAG_NONE, + 1, &pointerId, &pointerCoords, 1, 1, downTime); + mAccumulator.clear(); +} + +int32_t MouseInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) { + if (scanCode >= BTN_MOUSE && scanCode < BTN_JOYSTICK) { + return getEventHub()->getScanCodeState(getDeviceId(), scanCode); + } else { + return AKEY_STATE_UNKNOWN; + } +} // --- SingleTouchInputMapper --- |