281 lines
12 KiB
C++
281 lines
12 KiB
C++
/*
|
|
* Copyright (C) 2019 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include "../Macros.h"
|
|
|
|
#include "KeyMouseInputMapper.h"
|
|
#include "TouchCursorInputMapperCommon.h"
|
|
#include <cutils/properties.h>
|
|
|
|
namespace android {
|
|
|
|
// --- Static Definitions ---
|
|
|
|
KeyMouseInputMapper::KeyMouseInputMapper(InputDeviceContext& deviceContext) : InputMapper(deviceContext) {
|
|
}
|
|
|
|
KeyMouseInputMapper::~KeyMouseInputMapper() {
|
|
}
|
|
|
|
uint32_t KeyMouseInputMapper::getSources() const{
|
|
return AINPUT_SOURCE_MOUSE;
|
|
}
|
|
|
|
void KeyMouseInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
|
|
InputMapper::populateDeviceInfo(info);
|
|
}
|
|
|
|
void KeyMouseInputMapper::dump(std::string& dump) {
|
|
|
|
}
|
|
|
|
void KeyMouseInputMapper::configure(nsecs_t when,
|
|
const InputReaderConfiguration* config, uint32_t changes) {
|
|
|
|
InputMapper::configure(when, config, changes);
|
|
mSource=AINPUT_SOURCE_MOUSE;
|
|
mXPrecision = 1.0f;
|
|
mYPrecision = 1.0f;
|
|
mPointerController = getContext()->getPointerController(getDeviceId());
|
|
mOrientation = DISPLAY_ORIENTATION_0;
|
|
mDisplayWidth = 0;
|
|
mDisplayHeight = 0;
|
|
if (false) {
|
|
// When per-window input rotation is enabled, InputReader works in the un-rotated
|
|
// coordinate space, so we don't need to do anything if the device is already
|
|
// orientation-aware. If the device is not orientation-aware, then we need to apply the
|
|
// inverse rotation of the display so that when the display rotation is applied later
|
|
// as a part of the per-window transform, we get the expected screen coordinates.
|
|
if (false) {
|
|
std::optional<DisplayViewport> internalViewport =
|
|
config->getDisplayViewportByType(ViewportType::INTERNAL);
|
|
if (internalViewport) {
|
|
mOrientation = getInverseRotation(internalViewport->orientation);
|
|
mDisplayWidth = internalViewport->deviceWidth;
|
|
mDisplayHeight = internalViewport->deviceHeight;
|
|
}
|
|
}
|
|
} else {
|
|
if (false) {
|
|
std::optional<DisplayViewport> internalViewport =
|
|
config->getDisplayViewportByType(ViewportType::INTERNAL);
|
|
if (internalViewport) {
|
|
mOrientation = internalViewport->orientation;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void KeyMouseInputMapper::reset(nsecs_t when) {
|
|
mButtonState = 0;
|
|
mDownTime = 0;
|
|
mCursorButtonAccumulator.reset(getDeviceContext());
|
|
|
|
InputMapper::reset(when);
|
|
}
|
|
|
|
void KeyMouseInputMapper::process(const RawEvent* rawEvent) {
|
|
|
|
mCursorButtonAccumulator.process(rawEvent);
|
|
|
|
int mID;
|
|
char mgetDeviceID[PROPERTY_VALUE_MAX] = "";
|
|
property_get("sys.ID.mID", mgetDeviceID,0);
|
|
mID=atoi(mgetDeviceID);
|
|
if (rawEvent->type == EV_KEY && ((rawEvent->code== 28)||(rawEvent->code== 232))) {
|
|
mdeltax = 0;
|
|
mdeltay = 0;
|
|
sync(rawEvent->when, rawEvent->readTime);
|
|
}
|
|
}
|
|
|
|
void KeyMouseInputMapper::sync(nsecs_t when, nsecs_t readTime) {
|
|
int32_t lastButtonState = mButtonState;
|
|
int32_t currentButtonState = mCursorButtonAccumulator.getButtonState();
|
|
mButtonState = currentButtonState;
|
|
char mKeyLock[PROPERTY_VALUE_MAX] = "";
|
|
memset(mKeyLock,0,5);
|
|
property_get("sys.KeyMouse.mKeyMouseState", mKeyLock, "off");
|
|
|
|
bool wasDown = isPointerDown(lastButtonState);
|
|
bool down = isPointerDown(currentButtonState);
|
|
bool downChanged;
|
|
if (!wasDown && down) {
|
|
mDownTime = when;
|
|
downChanged = true;
|
|
} else if (wasDown && !down) {
|
|
downChanged = true;
|
|
} else {
|
|
downChanged = false;
|
|
}
|
|
nsecs_t downTime = mDownTime;
|
|
if(strcmp(mKeyLock, "off") == 0) {
|
|
return;
|
|
}
|
|
bool buttonsChanged = currentButtonState != lastButtonState;
|
|
int32_t buttonsPressed = currentButtonState & ~lastButtonState;
|
|
int32_t buttonsReleased = lastButtonState & ~currentButtonState;
|
|
|
|
float deltaX = mdeltax;
|
|
float deltaY = mdeltay;
|
|
|
|
// Rotate delta according to orientation if needed.
|
|
if (false) {
|
|
rotateDelta(DISPLAY_ORIENTATION_0, &deltaX, &deltaY);
|
|
}
|
|
|
|
// Move the pointer.
|
|
PointerProperties pointerProperties;
|
|
pointerProperties.clear();
|
|
pointerProperties.id = 0;
|
|
pointerProperties.toolType = AMOTION_EVENT_TOOL_TYPE_MOUSE;
|
|
|
|
PointerCoords pointerCoords;
|
|
pointerCoords.clear();
|
|
|
|
//paint the pointer of mouse here
|
|
uint32_t policyFlags = 0;
|
|
policyFlags |= POLICY_FLAG_WAKE;
|
|
|
|
int32_t displayId = ADISPLAY_ID_DEFAULT;
|
|
float xCursorPosition = AMOTION_EVENT_INVALID_CURSOR_POSITION;
|
|
float yCursorPosition = AMOTION_EVENT_INVALID_CURSOR_POSITION;
|
|
|
|
if (mPointerController != NULL) {
|
|
mPointerController->setPresentation(PointerControllerInterface::Presentation::POINTER);
|
|
mPointerController->move(deltaX,deltaY);
|
|
mPointerController->unfade(PointerControllerInterface::Transition::IMMEDIATE);
|
|
|
|
mPointerController->getPosition(&xCursorPosition, &yCursorPosition);
|
|
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, xCursorPosition);
|
|
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, yCursorPosition);
|
|
displayId = mPointerController->getDisplayId();//ADISPLAY_ID_DEFAULT;
|
|
}
|
|
// Moving an external trackball or mouse should wake the device.
|
|
// We don't do this for internal cursor devices to prevent them from waking up
|
|
// the device in your pocket.
|
|
// TODO: Use the input device configuration to control this behavior more finely.
|
|
|
|
// Synthesize key down from buttons if needed.
|
|
synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_DOWN, when, readTime, getDeviceId(),
|
|
mSource, displayId, policyFlags, lastButtonState, currentButtonState);
|
|
|
|
// Send motion event.
|
|
if (downChanged || buttonsChanged) {
|
|
int32_t metaState = getContext()->getGlobalMetaState();
|
|
int32_t buttonState = lastButtonState;
|
|
int32_t motionEventAction;
|
|
if (downChanged) {
|
|
motionEventAction = down ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
|
|
} else if (down || (mSource != AINPUT_SOURCE_MOUSE)) {
|
|
motionEventAction = AMOTION_EVENT_ACTION_MOVE;
|
|
} else {
|
|
motionEventAction = AMOTION_EVENT_ACTION_HOVER_MOVE;
|
|
}
|
|
if (buttonsReleased) {
|
|
BitSet32 released(buttonsReleased);
|
|
while (!released.isEmpty()) {
|
|
int32_t actionButton = BitSet32::valueForBit(released.clearFirstMarkedBit());
|
|
buttonState &= ~actionButton;
|
|
NotifyMotionArgs releaseArgs(getContext()->getNextId(), when, readTime,
|
|
getDeviceId(), mSource, displayId, policyFlags,
|
|
AMOTION_EVENT_ACTION_BUTTON_RELEASE, actionButton, 0,
|
|
metaState, buttonState, MotionClassification::NONE,
|
|
AMOTION_EVENT_EDGE_FLAG_NONE, 1, &pointerProperties,
|
|
&pointerCoords, mXPrecision, mYPrecision,
|
|
xCursorPosition, yCursorPosition, downTime,
|
|
/* videoFrames */ {});
|
|
getListener().notifyMotion(&releaseArgs);
|
|
}
|
|
}
|
|
|
|
NotifyMotionArgs args(getContext()->getNextId(), when, readTime, getDeviceId(), mSource,
|
|
displayId, policyFlags, motionEventAction, 0, 0, metaState,
|
|
currentButtonState, MotionClassification::NONE,
|
|
AMOTION_EVENT_EDGE_FLAG_NONE, 1, &pointerProperties, &pointerCoords,
|
|
mXPrecision, mYPrecision, xCursorPosition, yCursorPosition, downTime,
|
|
/* videoFrames */ {});
|
|
getListener().notifyMotion(&args);
|
|
|
|
if (buttonsPressed) {
|
|
BitSet32 pressed(buttonsPressed);
|
|
while (!pressed.isEmpty()) {
|
|
int32_t actionButton = BitSet32::valueForBit(pressed.clearFirstMarkedBit());
|
|
buttonState |= actionButton;
|
|
NotifyMotionArgs pressArgs(getContext()->getNextId(), when, readTime, getDeviceId(),
|
|
mSource, displayId, policyFlags,
|
|
AMOTION_EVENT_ACTION_BUTTON_PRESS, actionButton, 0,
|
|
metaState, buttonState, MotionClassification::NONE,
|
|
AMOTION_EVENT_EDGE_FLAG_NONE, 1, &pointerProperties,
|
|
&pointerCoords, mXPrecision, mYPrecision,
|
|
xCursorPosition, yCursorPosition, downTime,
|
|
/* videoFrames */ {});
|
|
getListener().notifyMotion(&pressArgs);
|
|
}
|
|
}
|
|
|
|
ALOG_ASSERT(buttonState == currentButtonState);
|
|
|
|
// Send hover move after UP to tell the application that the mouse is hovering now.
|
|
if (motionEventAction == AMOTION_EVENT_ACTION_UP
|
|
&& (mSource == AINPUT_SOURCE_MOUSE)) {
|
|
if (buttonsChanged) {
|
|
mPointerController->setPresentation(
|
|
PointerControllerInterface::Presentation::POINTER);
|
|
|
|
if (buttonsChanged) {
|
|
mPointerController->setButtonState(currentButtonState);
|
|
}
|
|
|
|
mPointerController->unfade(PointerControllerInterface::Transition::IMMEDIATE);
|
|
}
|
|
|
|
if (false) {
|
|
// Rotate the cursor position that is in PointerController's rotated coordinate
|
|
// space to InputReader's un-rotated coordinate space.
|
|
//rotatePoint(mOrientation, xCursorPosition /*byRef*/, yCursorPosition /*byRef*/,
|
|
// mDisplayWidth, mDisplayHeight);
|
|
}
|
|
NotifyMotionArgs hoverArgs(getContext()->getNextId(), when, readTime, getDeviceId(),
|
|
mSource, displayId, policyFlags,
|
|
AMOTION_EVENT_ACTION_HOVER_MOVE, 0, 0, metaState,
|
|
currentButtonState, MotionClassification::NONE,
|
|
AMOTION_EVENT_EDGE_FLAG_NONE, 1, &pointerProperties,
|
|
&pointerCoords, mXPrecision, mYPrecision, xCursorPosition,
|
|
yCursorPosition, downTime, /* videoFrames */ {});
|
|
getListener().notifyMotion(&hoverArgs);
|
|
}
|
|
|
|
}
|
|
// Synthesize key up from buttons if needed.
|
|
synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_UP, when, readTime, getDeviceId(), mSource,
|
|
displayId, policyFlags, lastButtonState, currentButtonState);
|
|
}
|
|
|
|
int32_t KeyMouseInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
|
|
if (scanCode >= BTN_MOUSE && scanCode < BTN_JOYSTICK) {
|
|
return getDeviceContext().getScanCodeState(scanCode);
|
|
} else {
|
|
return AKEY_STATE_UNKNOWN;
|
|
}
|
|
}
|
|
|
|
void KeyMouseInputMapper::fadePointer() {
|
|
|
|
}
|
|
|
|
} // namespace android
|