https://sourceforge.net/p/vilivs5/framework_base/ci/41d38532eb9cc8a3bf6742abb344d86cd40639f1/
This is a rework of mouse cursor for eclair that merges all patches
into one. Also incorporates the button features from 0xdroid:
Menu: Middle button
Back: Right button
I think it's more convenient.
--- a/core/java/android/view/RawInputEvent.java
+++ b/core/java/android/view/RawInputEvent.java
@@ -15,6 +15,7 @@
public static final int CLASS_TRACKBALL = 0x00000008;
public static final int CLASS_TOUCHSCREEN_MT = 0x00000010;
public static final int CLASS_DPAD = 0x00000020;
+ public static final int CLASS_MOUSE= 0x00000040;
// More special classes for QueuedEvent below.
public static final int CLASS_CONFIGURATION_CHANGED = 0x10000000;
--- a/include/ui/EventHub.h
+++ b/include/ui/EventHub.h
@@ -57,7 +57,8 @@
CLASS_TOUCHSCREEN = 0x00000004,
CLASS_TRACKBALL = 0x00000008,
CLASS_TOUCHSCREEN_MT= 0x00000010,
- CLASS_DPAD = 0x00000020
+ CLASS_DPAD = 0x00000020,
+ CLASS_MOUSE = 0x00000040
};
uint32_t getDeviceClasses(int32_t deviceId) const;
--- a/libs/ui/EventHub.cpp
+++ b/libs/ui/EventHub.cpp
@@ -652,7 +652,10 @@
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 |= CLASS_TRACKBALL;
+ if (test_bit(BTN_LEFT, key_bitmask) && test_bit(BTN_RIGHT, key_bitmask))
+ device->classes |= CLASS_MOUSE;
+ else
+ device->classes |= CLASS_TRACKBALL;
}
}
}
--- a/services/java/com/android/server/InputDevice.java
+++ b/services/java/com/android/server/InputDevice.java
@@ -24,10 +24,13 @@
import java.io.FileInputStream;
import java.util.StringTokenizer;
+import android.view.RawInputEvent;
public class InputDevice {
static final boolean DEBUG_POINTERS = false;
static final boolean DEBUG_HACKS = false;
+ static final boolean DEBUG_MOUSE = false;
+ static final String TAG = "InputDevice";
/** Amount that trackball needs to move in order to generate a key event. */
static final int TRACKBALL_MOVEMENT_THRESHOLD = 6;
@@ -524,13 +527,13 @@
MotionEvent generateAbsMotion(InputDevice device, long curTime,
long curTimeNano, Display display, int orientation,
int metaState) {
-
+ boolean isMouse = (device.classes & RawInputEvent.CLASS_MOUSE) != 0;
if (mSkipLastPointers) {
mSkipLastPointers = false;
mLastNumPointers = 0;
}
- if (mNextNumPointers <= 0 && mLastNumPointers <= 0) {
+ if (!isMouse && (mNextNumPointers <= 0 && mLastNumPointers <= 0)) {
return null;
}
@@ -541,24 +544,28 @@
+ " exceeded maximum of " + MAX_POINTERS);
mNextNumPointers = MAX_POINTERS;
}
-
- int upOrDownPointer = updatePointerIdentifiers();
+
+ /*
+ * This is not used for mouse
+ */
+ int upOrDownPointer = isMouse ? 0 : updatePointerIdentifiers();
final float[] reportData = mReportData;
final int[] rawData;
- if (KeyInputQueue.BAD_TOUCH_HACK) {
+ if (!isMouse && KeyInputQueue.BAD_TOUCH_HACK) {
rawData = generateAveragedData(upOrDownPointer, lastNumPointers,
nextNumPointers);
} else {
- rawData = mLastData;
- }
-
- final int numPointers = mLastNumPointers;
-
- if (DEBUG_POINTERS) Log.v("InputDevice", "Processing "
+ rawData = isMouse ? mNextData : mLastData;
+ }
+
+ final int numPointers = isMouse ? 1 : mLastNumPointers;
+
+ if (DEBUG_POINTERS || DEBUG_MOUSE)
+ Log.v("InputDevice", "Processing "
+ numPointers + " pointers (going from " + lastNumPointers
- + " to " + nextNumPointers + ")");
-
+ + " to " + nextNumPointers + ")" + " touch hack "
+ + KeyInputQueue.BAD_TOUCH_HACK);
for (int i=0; i<numPointers; i++) {
final int pos = i * MotionEvent.NUM_SAMPLE_DATA;
reportData[pos + MotionEvent.SAMPLE_X] = rawData[pos + MotionEvent.SAMPLE_X];
@@ -566,29 +573,48 @@
reportData[pos + MotionEvent.SAMPLE_PRESSURE] = rawData[pos + MotionEvent.SAMPLE_PRESSURE];
reportData[pos + MotionEvent.SAMPLE_SIZE] = rawData[pos + MotionEvent.SAMPLE_SIZE];
}
-
+
int action;
int edgeFlags = 0;
- if (nextNumPointers != lastNumPointers) {
- if (nextNumPointers > lastNumPointers) {
- if (lastNumPointers == 0) {
+ if (!isMouse) {
+ if (nextNumPointers != lastNumPointers) {
+ if (nextNumPointers > lastNumPointers) {
+ if (lastNumPointers == 0) {
+ action = MotionEvent.ACTION_DOWN;
+ mDownTime = curTime;
+ } else {
+ action = MotionEvent.ACTION_POINTER_DOWN
+ | (upOrDownPointer << MotionEvent.ACTION_POINTER_ID_SHIFT);
+ }
+ } else {
+ if (numPointers == 1) {
+ action = MotionEvent.ACTION_UP;
+ } else {
+ action = MotionEvent.ACTION_POINTER_UP
+ | (upOrDownPointer << MotionEvent.ACTION_POINTER_ID_SHIFT);
+ }
+ }
+ currentMove = null;
+ } else {
+ action = MotionEvent.ACTION_MOVE;
+ }
+ } else {
+ if (mNextNumPointers != mLastNumPointers) {
+ if (mNextNumPointers == 1) {
action = MotionEvent.ACTION_DOWN;
mDownTime = curTime;
- } else {
- action = MotionEvent.ACTION_POINTER_DOWN
- | (upOrDownPointer << MotionEvent.ACTION_POINTER_ID_SHIFT);
- }
- } else {
- if (numPointers == 1) {
+ } else if (mNextNumPointers == 2) {
action = MotionEvent.ACTION_UP;
} else {
- action = MotionEvent.ACTION_POINTER_UP
- | (upOrDownPointer << MotionEvent.ACTION_POINTER_ID_SHIFT);
- }
- }
- currentMove = null;
- } else {
- action = MotionEvent.ACTION_MOVE;
+ action = MotionEvent.ACTION_MOVE;
+ }
+ mLastNumPointers = mNextNumPointers;
+ currentMove = null;
+ } else {
+ action = MotionEvent.ACTION_MOVE;
+ }
+ if (DEBUG_MOUSE)
+ Log.i(TAG, "mouse action " + action);
}
final int dispW = display.getWidth()-1;
@@ -670,7 +696,7 @@
}
if (currentMove != null) {
- if (false) Log.i("InputDevice", "Adding batch x="
+ if (DEBUG_MOUSE) Log.i("InputDevice", "Adding batch x="
+ reportData[MotionEvent.SAMPLE_X]
+ " y=" + reportData[MotionEvent.SAMPLE_Y]
+ " to " + currentMove);
@@ -688,7 +714,7 @@
currentMove = me;
}
- if (nextNumPointers < lastNumPointers) {
+ if ((!isMouse) && (nextNumPointers < lastNumPointers)) {
removeOldPointer(upOrDownPointer);
}
--- a/services/java/com/android/server/KeyInputQueue.java
+++ b/services/java/com/android/server/KeyInputQueue.java
@@ -47,10 +47,13 @@
public abstract class KeyInputQueue {
static final String TAG = "KeyInputQueue";
+ static final int UPKEY_KEYWORD = 19;
+ static final int DOWNKEY_KEYWORD = 20;
static final boolean DEBUG = false;
static final boolean DEBUG_VIRTUAL_KEYS = false;
static final boolean DEBUG_POINTERS = false;
+ static final boolean DEBUG_MOUSE = false;
/**
* Turn on some hacks we have to improve the touch interaction with a
@@ -76,6 +79,8 @@
Display mDisplay = null;
int mDisplayWidth;
int mDisplayHeight;
+ int mCx;
+ int mCy;
int mOrientation = Surface.ROTATION_0;
int[] mKeyRotationMap = null;
@@ -311,6 +316,8 @@
// buttons based on that display.
mDisplayWidth = display.getWidth();
mDisplayHeight = display.getHeight();
+ mCx = mDisplayWidth / 2;
+ mCy = mDisplayHeight / 2;
}
public void getInputConfiguration(Configuration config) {
@@ -629,11 +636,35 @@
di.mAbs.mDown[0] = ev.value != 0;
// Trackball (mouse) protocol: press down or up.
- } else if (ev.scancode == RawInputEvent.BTN_MOUSE &&
- (classes&RawInputEvent.CLASS_TRACKBALL) != 0) {
- di.mRel.changed = true;
- di.mRel.mNextNumPointers = ev.value != 0 ? 1 : 0;
- send = true;
+ } else if (ev.scancode == RawInputEvent.BTN_MOUSE) {
+ if ((classes&RawInputEvent.CLASS_TRACKBALL) != 0) {
+ di.mRel.changed = true;
+ di.mRel.mNextNumPointers = ev.value != 0 ? 1 : 0;
+ send = true;
+ } else if ((classes&RawInputEvent.CLASS_MOUSE) != 0) {
+ if (DEBUG_MOUSE)
+ Log.i(TAG, "Mouse key event found, down:"
+ + ev.value + " was :" +
+ di.mAbs.mDown[0] + " Send " + send);
+ di.mAbs.changed = true;
+ di.mAbs.mNextNumPointers = (ev.value != 0) ? 1 : 2;
+ send = true;
+ }
+ } else if ((ev.scancode == RawInputEvent.BTN_RIGHT ||
+ ev.scancode == RawInputEvent.BTN_MIDDLE) &&
+ (classes&RawInputEvent.CLASS_MOUSE) != 0) {
+ boolean down = (ev.value != 0);
+ if (down)
+ di.mKeyDownTime = curTime;
+
+ addLocked(di, curTime, ev.flags,
+ RawInputEvent.CLASS_KEYBOARD,
+ newKeyEvent(di, di.mKeyDownTime, curTime, down,
+ (ev.scancode == RawInputEvent.BTN_RIGHT)
+ ? KeyEvent.KEYCODE_BACK : KeyEvent.KEYCODE_MENU,
+ 0, scancode,
+ ((ev.flags & WindowManagerPolicy.FLAG_WOKE_HERE) != 0)
+ ? KeyEvent.FLAG_WOKE_HERE : 0));
}
// Process position events from multitouch protocol.
@@ -687,15 +718,59 @@
}
// Process movement events from trackball (mouse) protocol.
- } else if (ev.type == RawInputEvent.EV_REL &&
- (classes&RawInputEvent.CLASS_TRACKBALL) != 0) {
- // Add this relative movement into our totals.
- if (ev.scancode == RawInputEvent.REL_X) {
- di.mRel.changed = true;
- di.mRel.mNextData[MotionEvent.SAMPLE_X] += ev.value;
- } else if (ev.scancode == RawInputEvent.REL_Y) {
- di.mRel.changed = true;
- di.mRel.mNextData[MotionEvent.SAMPLE_Y] += ev.value;
+ } else if (ev.type == RawInputEvent.EV_REL) {
+ if (DEBUG_MOUSE)
+ Log.i(TAG, "rel event found, class :" + classes + " mouse value: " + RawInputEvent.CLASS_MOUSE);
+ if ((classes&RawInputEvent.CLASS_TRACKBALL) != 0) {
+ // Add this relative movement into our totals.
+ if (ev.scancode == RawInputEvent.REL_X) {
+ di.mRel.changed = true;
+ di.mRel.mNextData[MotionEvent.SAMPLE_X] += ev.value;
+ } else if (ev.scancode == RawInputEvent.REL_Y) {
+ di.mRel.changed = true;
+ di.mRel.mNextData[MotionEvent.SAMPLE_Y] += ev.value;
+ }
+ } else if ((classes&RawInputEvent.CLASS_MOUSE) != 0) {
+ if (ev.scancode == RawInputEvent.REL_X) {
+ di.mAbs.changed = true;
+ mCx += (int)ev.value;
+ mCx = ((mCx < 0) ? 0 : (mCx >= mDisplayWidth ? mDisplayWidth - 1 : mCx));
+ di.mAbs.mNextData[MotionEvent.SAMPLE_X] = mCx;
+ } else if (ev.scancode == RawInputEvent.REL_Y) {
+ di.mAbs.changed = true;
+ mCy += (int)ev.value;
+ mCy = ((mCy < 0) ? 0 : (mCy >= mDisplayHeight ? mDisplayHeight - 1 : mCy));
+ di.mAbs.mNextData[MotionEvent.SAMPLE_Y] = mCy;
+ } else if (ev.scancode == RawInputEvent.REL_WHEEL &&
+ (classes&RawInputEvent.CLASS_MOUSE) != 0) {
+ boolean down;
+ int keycode;
+ if (ev.value != 0) {
+ down = true;
+ di.mKeyDownTime = curTime;
+ } else {
+ down = false;
+ }
+ if (ev.value < 0){
+ keycode = rotateKeyCodeLocked(DOWNKEY_KEYWORD);
+ } else if(ev.value > 0){
+ keycode = rotateKeyCodeLocked(UPKEY_KEYWORD);
+ } else {
+ keycode = rotateKeyCodeLocked(ev.keycode);
+ }
+ addLocked(di, curTime, ev.flags,
+ RawInputEvent.CLASS_KEYBOARD,
+ newKeyEvent(di, di.mKeyDownTime, curTime, down,
+ keycode, 0, scancode,
+ ((ev.flags & WindowManagerPolicy.FLAG_WOKE_HERE) != 0)
+ ? KeyEvent.FLAG_WOKE_HERE : 0));
+ addLocked(di, curTime, ev.flags,
+ RawInputEvent.CLASS_KEYBOARD,
+ newKeyEvent(di, di.mKeyDownTime, curTime, !down,
+ keycode, 0, scancode,
+ ((ev.flags & WindowManagerPolicy.FLAG_WOKE_HERE) != 0)
+ ? KeyEvent.FLAG_WOKE_HERE : 0));
+ }
}
}
@@ -778,7 +853,8 @@
me = ms.generateAbsMotion(di, curTime,
curTimeNano, mDisplay,
mOrientation, mGlobalMetaState);
- if (DEBUG_POINTERS) Log.v(TAG, "Absolute: x="
+ if (DEBUG_POINTERS || DEBUG_MOUSE)
+ Log.v(TAG, "Absolute: x="
+ di.mAbs.mNextData[MotionEvent.SAMPLE_X]
+ " y="
+ di.mAbs.mNextData[MotionEvent.SAMPLE_Y]
@@ -787,8 +863,15 @@
if (WindowManagerPolicy.WATCH_POINTER) {
Log.i(TAG, "Enqueueing: " + me);
}
- addLocked(di, curTimeNano, ev.flags,
- RawInputEvent.CLASS_TOUCHSCREEN, me);
+ if ((classes & RawInputEvent.CLASS_TOUCHSCREEN) != 0) {
+ addLocked(di, curTime, ev.flags,
+ RawInputEvent.CLASS_TOUCHSCREEN, me);
+ } else if ((classes & RawInputEvent.CLASS_MOUSE) != 0) {
+ addLocked(di, curTime, ev.flags,
+ RawInputEvent.CLASS_MOUSE, me);
+ } else {
+ Log.w(TAG, "Unknown classes? " + classes);
+ }
}
} while (ms.hasMore());
} else {
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -58,6 +58,7 @@
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
import android.graphics.Matrix;
+import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.Region;
@@ -126,6 +127,9 @@
import java.util.Iterator;
import java.util.List;
+import android.graphics.Canvas;
+import android.graphics.Path;
+
/** {@hide} */
public class WindowManagerService extends IWindowManager.Stub
implements Watchdog.Monitor, KeyInputQueue.HapticFeedbackCallback {
@@ -357,6 +361,13 @@
private DimAnimator mDimAnimator = null;
Surface mBlurSurface;
boolean mBlurShown;
+
+ Surface mMouseSurface;
+ int mShowMouse = 0;
+ int mMlx;
+ int mMly;
+ int mMlw;
+ int mMlh;
int mTransactionSequence = 0;
@@ -5112,7 +5123,7 @@
// dispatch the event.
try {
if (DEBUG_INPUT || DEBUG_FOCUS || WindowManagerPolicy.WATCH_POINTER) {
- Log.v(TAG, "Delivering pointer " + qev + " to " + target);
+ Log.v(TAG, "Delivering pointer " + qev + " Ev " + ev + " to " + target);
}
if (MEASURE_LATENCY) {
@@ -6021,7 +6032,7 @@
if (qev != null) {
res = (MotionEvent)qev.event;
if (DEBUG_INPUT) Log.v(TAG,
- "Returning pending motion: " + res);
+ "Returning pending motion: " + res + "q: " + qev);
mQueue.recycleEvent(qev);
if (win != null && returnWhat == RETURN_PENDING_POINTER) {
res.offsetLocation(-win.mFrame.left, -win.mFrame.top);
@@ -6254,7 +6265,8 @@
if (screenIsOff) {
if (!mPolicy.isWakeRelMovementTq(event.deviceId,
device.classes, event)) {
- //Log.i(TAG, "dropping because screenIsOff and !isWakeKey");
+ if (DEBUG_INPUT)
+ Log.i(TAG, "dropping because screenIsOff and !isWakeKey");
return false;
}
event.flags |= WindowManagerPolicy.FLAG_WOKE_HERE;
@@ -6400,7 +6412,8 @@
if (ev.classType == RawInputEvent.CLASS_TOUCHSCREEN) {
eventType = eventType((MotionEvent)ev.event);
} else if (ev.classType == RawInputEvent.CLASS_KEYBOARD ||
- ev.classType == RawInputEvent.CLASS_TRACKBALL) {
+ ev.classType == RawInputEvent.CLASS_TRACKBALL ||
+ ev.classType == RawInputEvent.CLASS_MOUSE) {
eventType = LocalPowerManager.BUTTON_EVENT;
} else {
eventType = LocalPowerManager.OTHER_EVENT;
@@ -6459,6 +6472,38 @@
break;
case RawInputEvent.CLASS_TOUCHSCREEN:
//Log.i(TAG, "Read next event " + ev);
+ dispatchPointer(ev, (MotionEvent)ev.event, 0, 0);
+ break;
+ case RawInputEvent.CLASS_MOUSE:
+ MotionEvent mmev = (MotionEvent)ev.event;
+ int mcx = (int)mmev.getX();
+ int mcy = (int)mmev.getY();
+
+ if (mMouseSurface != null && (mMlx != mcx || mMly != mcy)) {
+ Surface.openTransaction();
+ if (DEBUG_INPUT)
+ Log.i(TAG, "Open transaction for the mouse surface");
+ WindowState top =
+ (WindowState)mWindows.get(mWindows.size() - 1);
+ try {
+ if (DEBUG_INPUT)
+ Log.i(TAG, "Move surf, x: " +
+ Integer.toString(mcx) + " y:"
+ + Integer.toString(mcy));
+
+ mMouseSurface.setPosition(mcx, mcy);
+ mMouseSurface.setLayer(top.mAnimLayer + 1);
+ if (mShowMouse != 1) {
+ mMouseSurface.show();
+ mShowMouse = 1;
+ }
+ mMlx = mcx;
+ mMly = mcy;
+ } catch ( RuntimeException e) {
+ Log.e(TAG, "Failure showing mouse surface",e);
+ }
+ Surface.closeTransaction();
+ }
dispatchPointer(ev, (MotionEvent)ev.event, 0, 0);
break;
case RawInputEvent.CLASS_TRACKBALL:
@@ -9375,6 +9420,61 @@
if (mFxSession == null) {
mFxSession = new SurfaceSession();
+ }
+
+ if (mMouseSurface == null) {
+ int mMx, mMy, mMw, mMh;
+ Canvas mCanvas;
+ Path mPath = new Path();
+
+ if (DEBUG_INPUT)
+ Log.i(TAG, "Create Mouse Surface");
+
+ mMw = 12;
+ mMh = 20;
+ mMx = (mDisplay.getWidth() - mMw) / 2;
+ mMy = (mDisplay.getHeight() - mMh) / 2;
+
+ try {
+
+ /*
+ *First Mouse event, create Surface
+ */
+
+ mMouseSurface =
+ new Surface(mFxSession,
+ 0, -1, mMw, mMh,
+ PixelFormat.TRANSPARENT,
+ Surface.FX_SURFACE_NORMAL);
+ mCanvas = mMouseSurface.lockCanvas(null);
+ Paint tPaint = new Paint();
+ tPaint.setStyle(Paint.Style.STROKE);
+ tPaint.setStrokeWidth(2);
+ tPaint.setColor(0xffffffff);
+ mPath.moveTo(0.0f, 0.0f);
+ mPath.lineTo(12.0f, 12.0f);
+ mPath.lineTo(7.0f, 12.0f);
+ mPath.lineTo(11.0f, 20.0f);
+ mPath.lineTo(8.0f, 21.0f);
+ mPath.lineTo(4.0f, 13.0f);
+ mPath.lineTo(0.0f, 17.0f);
+ mPath.close();
+ mCanvas.clipPath(mPath);
+ mCanvas.drawColor(0xff000000);
+ mCanvas.drawPath(mPath, tPaint);
+
+ mMouseSurface.unlockCanvasAndPost(mCanvas);
+ mMouseSurface.openTransaction();
+ mMouseSurface.setSize(mMw, mMh);
+ mMouseSurface.closeTransaction();
+
+ } catch (Exception e) {
+ Log.e(TAG, "Exception creating mouse surface",e);
+ }
+ mMlx = mMx;
+ mMly = mMy;
+ mMlw = mMw;
+ mMlh = mMh;
}
if (SHOW_TRANSACTIONS) Log.i(TAG, ">>> OPEN TRANSACTION");