summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
authorScott Brady <sbradymobile@gmail.com>2011-04-16 11:44:54 -0700
committerSteve Kondik <shade@chemlab.org>2011-04-30 00:52:42 -0400
commiteaf9b10827c8f5a651b0fef230978ee1e22cc20a (patch)
tree50bf8d7dd5ecfeaf0b33c46a4cefb918634b7585 /libs
parent937a7ba32f2a5592ecd0c787edb671caa011d6b2 (diff)
downloadframeworks_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.cpp5
-rw-r--r--libs/ui/InputDispatcher.cpp10
-rw-r--r--libs/ui/InputReader.cpp322
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 ---