diff options
Diffstat (limited to 'services/java/com/android/server/InputDevice.java')
-rw-r--r-- | services/java/com/android/server/InputDevice.java | 210 |
1 files changed, 210 insertions, 0 deletions
diff --git a/services/java/com/android/server/InputDevice.java b/services/java/com/android/server/InputDevice.java new file mode 100644 index 000000000000..70bf38e03e42 --- /dev/null +++ b/services/java/com/android/server/InputDevice.java @@ -0,0 +1,210 @@ +/* + * Copyright (C) 2007 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. + */ + +package com.android.server; + +import android.util.Log; +import android.view.Display; +import android.view.MotionEvent; +import android.view.Surface; +import android.view.WindowManagerPolicy; + +public class InputDevice { + /** Amount that trackball needs to move in order to generate a key event. */ + static final int TRACKBALL_MOVEMENT_THRESHOLD = 6; + + final int id; + final int classes; + final String name; + final AbsoluteInfo absX; + final AbsoluteInfo absY; + final AbsoluteInfo absPressure; + final AbsoluteInfo absSize; + + long mDownTime = 0; + int mMetaKeysState = 0; + + final MotionState mAbs = new MotionState(0, 0); + final MotionState mRel = new MotionState(TRACKBALL_MOVEMENT_THRESHOLD, + TRACKBALL_MOVEMENT_THRESHOLD); + + static class MotionState { + int xPrecision; + int yPrecision; + float xMoveScale; + float yMoveScale; + MotionEvent currentMove = null; + boolean changed = false; + boolean down = false; + boolean lastDown = false; + long downTime = 0; + int x = 0; + int y = 0; + int pressure = 1; + int size = 0; + + MotionState(int mx, int my) { + xPrecision = mx; + yPrecision = my; + xMoveScale = mx != 0 ? (1.0f/mx) : 1.0f; + yMoveScale = my != 0 ? (1.0f/my) : 1.0f; + } + + MotionEvent generateMotion(InputDevice device, long curTime, + boolean isAbs, Display display, int orientation, + int metaState) { + if (!changed) { + return null; + } + + float scaledX = x; + float scaledY = y; + float temp; + float scaledPressure = 1.0f; + float scaledSize = 0; + if (isAbs) { + int w = display.getWidth()-1; + int h = display.getHeight()-1; + if (orientation == Surface.ROTATION_90 + || orientation == Surface.ROTATION_270) { + int tmp = w; + w = h; + h = tmp; + } + if (device.absX != null) { + scaledX = ((scaledX-device.absX.minValue) + / device.absX.range) * w; + } + if (device.absY != null) { + scaledY = ((scaledY-device.absY.minValue) + / device.absY.range) * h; + } + if (device.absPressure != null) { + scaledPressure = + ((pressure-device.absPressure.minValue) + / (float)device.absPressure.range); + } + if (device.absSize != null) { + scaledSize = + ((size-device.absSize.minValue) + / (float)device.absSize.range); + } + switch (orientation) { + case Surface.ROTATION_90: + temp = scaledX; + scaledX = scaledY; + scaledY = w-temp; + break; + case Surface.ROTATION_180: + scaledX = w-scaledX; + scaledY = h-scaledY; + break; + case Surface.ROTATION_270: + temp = scaledX; + scaledX = h-scaledY; + scaledY = temp; + break; + } + } else { + scaledX *= xMoveScale; + scaledY *= yMoveScale; + switch (orientation) { + case Surface.ROTATION_90: + temp = scaledX; + scaledX = scaledY; + scaledY = -temp; + break; + case Surface.ROTATION_180: + scaledX = -scaledX; + scaledY = -scaledY; + break; + case Surface.ROTATION_270: + temp = scaledX; + scaledX = -scaledY; + scaledY = temp; + break; + } + } + + int edgeFlags = 0; + if (scaledX == 0) { + edgeFlags += MotionEvent.EDGE_LEFT; + } else if (scaledX == display.getWidth() - 1.0f) { + edgeFlags += MotionEvent.EDGE_RIGHT; + } + + if (scaledY == 0) { + edgeFlags += MotionEvent.EDGE_TOP; + } else if (scaledY == display.getHeight() - 1.0f) { + edgeFlags += MotionEvent.EDGE_BOTTOM; + } + + changed = false; + if (down != lastDown) { + int action; + lastDown = down; + if (down) { + action = MotionEvent.ACTION_DOWN; + downTime = curTime; + } else { + action = MotionEvent.ACTION_UP; + } + currentMove = null; + if (!isAbs) { + x = y = 0; + } + return MotionEvent.obtain(downTime, curTime, action, + scaledX, scaledY, scaledPressure, scaledSize, metaState, + xPrecision, yPrecision, device.id, edgeFlags); + } else { + if (currentMove != null) { + currentMove.addBatch(curTime, scaledX, scaledY, + scaledPressure, scaledSize, metaState); + if (WindowManagerPolicy.WATCH_POINTER) { + Log.i("KeyInputQueue", "Updating: " + currentMove); + } + return null; + } + MotionEvent me = MotionEvent.obtain(downTime, curTime, + MotionEvent.ACTION_MOVE, scaledX, scaledY, + scaledPressure, scaledSize, metaState, + xPrecision, yPrecision, device.id, edgeFlags); + currentMove = me; + return me; + } + } + } + + static class AbsoluteInfo { + int minValue; + int maxValue; + int range; + int flat; + int fuzz; + }; + + InputDevice(int _id, int _classes, String _name, + AbsoluteInfo _absX, AbsoluteInfo _absY, + AbsoluteInfo _absPressure, AbsoluteInfo _absSize) { + id = _id; + classes = _classes; + name = _name; + absX = _absX; + absY = _absY; + absPressure = _absPressure; + absSize = _absSize; + } +}; |