Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0dd7cb4b authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

Finish implementation of multiple pointer support for MotionEvent.

The major things going on here:

- The MotionEvent API is now extended to included "pointer ID" information, for
  applications to keep track of individual fingers as they move up and down.
  PointerLocation has been updated to take advantage of this.

- The input system now has logic to generate MotionEvents with the new ID
  information, synthesizing an identifier as new points are down and trying to
  keep pointer ids consistent across events by looking at the distance between
  the last and next set of pointers.

- We now support the new multitouch driver protocol, and will use that instead
  of the old one if it is available.  We do NOT use any finger id information
  coming from the driver, but always synthesize pointer ids in user space.
  (This is simply because we don't yet have a driver reporting this information
  from which to base an implementation on.)

- Increase maximum number of fingers to 10.  This code has only been used
  with a driver that reports up to 2, so no idea how more will actually work.

- Oh and the input system can now detect and report physical DPAD devices.
parent a2136d6b
Loading
Loading
Loading
Loading
+36 −10
Original line number Diff line number Diff line
@@ -145940,6 +145940,19 @@
 visibility="public"
>
</method>
<method name="findPointerIndex"
 return="int"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="pointerId" type="int">
</parameter>
</method>
<method name="getAction"
 return="int"
 abstract="false"
@@ -146031,7 +146044,7 @@
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="pointer" type="int">
<parameter name="pointerIndex" type="int">
</parameter>
<parameter name="pos" type="int">
</parameter>
@@ -146059,7 +146072,7 @@
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="pointer" type="int">
<parameter name="pointerIndex" type="int">
</parameter>
<parameter name="pos" type="int">
</parameter>
@@ -146087,7 +146100,7 @@
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="pointer" type="int">
<parameter name="pointerIndex" type="int">
</parameter>
<parameter name="pos" type="int">
</parameter>
@@ -146115,7 +146128,7 @@
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="pointer" type="int">
<parameter name="pointerIndex" type="int">
</parameter>
<parameter name="pos" type="int">
</parameter>
@@ -146153,6 +146166,19 @@
 visibility="public"
>
</method>
<method name="getPointerId"
 return="int"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="index" type="int">
</parameter>
</method>
<method name="getPressure"
 return="float"
 abstract="false"
@@ -146174,7 +146200,7 @@
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="pointer" type="int">
<parameter name="pointerIndex" type="int">
</parameter>
</method>
<method name="getRawX"
@@ -146220,7 +146246,7 @@
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="pointer" type="int">
<parameter name="pointerIndex" type="int">
</parameter>
</method>
<method name="getX"
@@ -146244,7 +146270,7 @@
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="pointer" type="int">
<parameter name="pointerIndex" type="int">
</parameter>
</method>
<method name="getXPrecision"
@@ -146279,7 +146305,7 @@
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="pointer" type="int">
<parameter name="pointerIndex" type="int">
</parameter>
</method>
<method name="getYPrecision"
@@ -146615,7 +146641,7 @@
 visibility="public"
>
</field>
<field name="ACTION_POINTER_MASK"
<field name="ACTION_POINTER_ID_MASK"
 type="int"
 transient="false"
 volatile="false"
@@ -146626,7 +146652,7 @@
 visibility="public"
>
</field>
<field name="ACTION_POINTER_SHIFT"
<field name="ACTION_POINTER_ID_SHIFT"
 type="int"
 transient="false"
 volatile="false"
+211 −156

File changed.

Preview size limit exceeded, changes collapsed.

+15 −0
Original line number Diff line number Diff line
@@ -13,6 +13,8 @@ public class RawInputEvent {
    public static final int CLASS_ALPHAKEY = 0x00000002;
    public static final int CLASS_TOUCHSCREEN = 0x00000004;
    public static final int CLASS_TRACKBALL = 0x00000008;
    public static final int CLASS_TOUCHSCREEN_MT = 0x00000010;
    public static final int CLASS_DPAD = 0x00000020;
    
    // More special classes for QueuedEvent below.
    public static final int CLASS_CONFIGURATION_CHANGED = 0x10000000;
@@ -158,8 +160,21 @@ public class RawInputEvent {
    public static final int ABS_TOOL_WIDTH = 0x1c;
    public static final int ABS_VOLUME = 0x20;
    public static final int ABS_MISC = 0x28;
    public static final int ABS_MT_TOUCH_MAJOR = 0x30;
    public static final int ABS_MT_TOUCH_MINOR = 0x31;
    public static final int ABS_MT_WIDTH_MAJOR = 0x32;
    public static final int ABS_MT_WIDTH_MINOR = 0x33;
    public static final int ABS_MT_ORIENTATION = 0x34;
    public static final int ABS_MT_POSITION_X = 0x35;
    public static final int ABS_MT_POSITION_Y = 0x36;
    public static final int ABS_MT_TOOL_TYPE = 0x37;
    public static final int ABS_MT_BLOB_ID = 0x38;
    public static final int ABS_MAX = 0x3f;

    public static final int SYN_REPORT = 0;
    public static final int SYN_CONFIG = 1;
    public static final int SYN_MT_REPORT = 2;
    
    public int deviceId;
    public int type;
    public int scancode;
+4 −1
Original line number Diff line number Diff line
@@ -55,7 +55,9 @@ public:
        CLASS_KEYBOARD      = 0x00000001,
        CLASS_ALPHAKEY      = 0x00000002,
        CLASS_TOUCHSCREEN   = 0x00000004,
        CLASS_TRACKBALL     = 0x00000008
        CLASS_TRACKBALL     = 0x00000008,
        CLASS_TOUCHSCREEN_MT= 0x00000010,
        CLASS_DPAD          = 0x00000020
    };
    uint32_t getDeviceClasses(int32_t deviceId) const;
    
@@ -122,6 +124,7 @@ private:
    };

    device_t* getDevice(int32_t deviceId) const;
    bool hasKeycode(device_t* device, int keycode) const;
    
    // Protect all internal state.
    mutable Mutex   mLock;
+71 −19
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
//#define LOG_NDEBUG 0

#include <ui/EventHub.h>
#include <ui/KeycodeLabels.h>
#include <hardware_legacy/power.h>

#include <cutils/properties.h>
@@ -58,6 +59,18 @@
#define SEQ_SHIFT 16
#define id_to_index(id)         ((id&ID_MASK)+1)

#ifndef ABS_MT_TOUCH_MAJOR
#define ABS_MT_TOUCH_MAJOR      0x30    /* Major axis of touching ellipse */
#endif

#ifndef ABS_MT_POSITION_X
#define ABS_MT_POSITION_X       0x35    /* Center X ellipse position */
#endif

#ifndef ABS_MT_POSITION_Y
#define ABS_MT_POSITION_Y       0x36    /* Center Y ellipse position */
#endif

namespace android {

static const char *WAKE_LOCK_ID = "KeyEvents";
@@ -590,6 +603,8 @@ int EventHub::open_device(const char *deviceName)
    mFDs[mFDCount].events = POLLIN;

    // figure out the kinds of events the device reports
    
    // See if this is a keyboard, and classify it.
    uint8_t key_bitmask[(KEY_MAX+1)/8];
    memset(key_bitmask, 0, sizeof(key_bitmask));
    LOGV("Getting keys...");
@@ -601,15 +616,11 @@ int EventHub::open_device(const char *deviceName)
        for (int i=0; i<((BTN_MISC+7)/8); i++) {
            if (key_bitmask[i] != 0) {
                device->classes |= CLASS_KEYBOARD;
                // 'Q' key support = cheap test of whether this is an alpha-capable kbd
                if (test_bit(KEY_Q, key_bitmask)) {
                    device->classes |= CLASS_ALPHAKEY;
                }
                break;
            }
        }
        if ((device->classes & CLASS_KEYBOARD) != 0) {
            device->keyBitmask = new uint8_t[(KEY_MAX+1)/8];
            device->keyBitmask = new uint8_t[sizeof(key_bitmask)];
            if (device->keyBitmask != NULL) {
                memcpy(device->keyBitmask, key_bitmask, sizeof(key_bitmask));
            } else {
@@ -619,6 +630,8 @@ int EventHub::open_device(const char *deviceName)
            }
        }
    }
    
    // See if this is a trackball.
    if (test_bit(BTN_MOUSE, key_bitmask)) {
        uint8_t rel_bitmask[(REL_MAX+1)/8];
        memset(rel_bitmask, 0, sizeof(rel_bitmask));
@@ -630,17 +643,23 @@ int EventHub::open_device(const char *deviceName)
            }
        }
    }
    if (test_bit(BTN_TOUCH, key_bitmask)) {
    
    uint8_t abs_bitmask[(ABS_MAX+1)/8];
    memset(abs_bitmask, 0, sizeof(abs_bitmask));
    LOGV("Getting absolute controllers...");
        if (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(abs_bitmask)), abs_bitmask) >= 0)
        {
            if (test_bit(ABS_X, abs_bitmask) && test_bit(ABS_Y, abs_bitmask)) {
    ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(abs_bitmask)), abs_bitmask);
    
    // Is this a new modern multi-touch driver?
    if (test_bit(ABS_MT_TOUCH_MAJOR, abs_bitmask)
            && test_bit(ABS_MT_POSITION_X, abs_bitmask)
            && test_bit(ABS_MT_POSITION_Y, abs_bitmask)) {
        device->classes |= CLASS_TOUCHSCREEN | CLASS_TOUCHSCREEN_MT;
        
    // Is this an old style single-touch driver?
    } else if (test_bit(BTN_TOUCH, key_bitmask)
            && test_bit(ABS_X, abs_bitmask) && test_bit(ABS_Y, abs_bitmask)) {
        device->classes |= CLASS_TOUCHSCREEN;
    }
        }
    }

#ifdef EV_SW
    // figure out the switches this device reports
@@ -658,9 +677,6 @@ int EventHub::open_device(const char *deviceName)
    }
#endif

    LOGI("New device: path=%s name=%s id=0x%x (of 0x%x) index=%d fd=%d classes=0x%x\n",
         deviceName, name, device->id, mNumDevicesById, mFDCount, fd, device->classes);

    if ((device->classes&CLASS_KEYBOARD) != 0) {
        char devname[101];
        char tmpfn[101];
@@ -707,10 +723,27 @@ int EventHub::open_device(const char *deviceName)
        sprintf(propName, "hw.keyboards.%u.devname", publicID);
        property_set(propName, devname);

        LOGI("New keyboard: publicID=%d device->id=%d devname='%s' propName='%s' keylayout='%s'\n",
        // 'Q' key support = cheap test of whether this is an alpha-capable kbd
        if (hasKeycode(device, kKeyCodeQ)) {
            device->classes |= CLASS_ALPHAKEY;
        }
        
        // See if this has a DPAD.
        if (hasKeycode(device, kKeyCodeDpadUp) &&
                hasKeycode(device, kKeyCodeDpadDown) &&
                hasKeycode(device, kKeyCodeDpadLeft) &&
                hasKeycode(device, kKeyCodeDpadRight) &&
                hasKeycode(device, kKeyCodeDpadCenter)) {
            device->classes |= CLASS_DPAD;
        }
        
        LOGI("New keyboard: publicID=%d device->id=0x%x devname='%s' propName='%s' keylayout='%s'\n",
                publicID, device->id, devname, propName, keylayoutFilename);
    }

    LOGI("New device: path=%s name=%s id=0x%x (of 0x%x) index=%d fd=%d classes=0x%x\n",
         deviceName, name, device->id, mNumDevicesById, mFDCount, fd, device->classes);
         
    LOGV("Adding device %s %p at %d, id = %d, classes = 0x%x\n",
         deviceName, device, mFDCount, devid, device->classes);

@@ -723,6 +756,25 @@ int EventHub::open_device(const char *deviceName)
    return 0;
}

bool EventHub::hasKeycode(device_t* device, int keycode) const
{
    if (device->keyBitmask == NULL || device->layoutMap == NULL) {
        return false;
    }
    
    Vector<int32_t> scanCodes;
    device->layoutMap->findScancodes(keycode, &scanCodes);
    const size_t N = scanCodes.size();
    for (size_t i=0; i<N && i<=KEY_MAX; i++) {
        int32_t sc = scanCodes.itemAt(i);
        if (sc >= 0 && sc <= KEY_MAX && test_bit(sc, device->keyBitmask)) {
            return true;
        }
    }
    
    return false;
}

int EventHub::close_device(const char *deviceName)
{
    AutoMutex _l(mLock);
Loading