add software "mouse cursor" in Android-x86


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.

Chih-Wei HuangChih-Wei Huang2010-02-25


changed core/java/android/view/RawInputEvent.java
changed include/ui/EventHub.h
changed libs/ui/EventHub.cpp
changed services/java/com/android/server/InputDevice.java
changed services/java/com/android/server/KeyInputQueue.java
changed services/java/com/android/server/WindowManagerService.java
--- 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");



原文地址:https://www.cnblogs.com/ztguang/p/12644902.html