Hi,
here are 3 patches that enable hardware keyboard of FR in userspace.
After applying, long presses will generate different keycodes then
short pressed (this probably the same principle as the kernel patch
for MENU key).

The first patch simply adds timeout parameter to readEvent function.
I think we should push this patch to google for review and inclusion
because it's pretty simple and opens up possibilities for devices
with limited number of hardware keys.

The second patch generates alternative keycodes if timeout is not
hit.

The third patch simply remaps AUX from BACK key to MENU key so that
we can bring up list of running applications on long AUX press.

Please give me know if it works for you

Thanks

Radek
diff --git a/core/jni/server/com_android_server_KeyInputQueue.cpp b/core/jni/server/com_android_server_KeyInputQueue.cpp
index 4e9ffb1..8963b10 100644
--- a/core/jni/server/com_android_server_KeyInputQueue.cpp
+++ b/core/jni/server/com_android_server_KeyInputQueue.cpp
@@ -53,7 +53,7 @@ static sp<EventHub> gHub;
 
 static jboolean
 android_server_KeyInputQueue_readEvent(JNIEnv* env, jobject clazz,
-                                          jobject event)
+                                          jobject event, jint timeout)
 {
     gLock.lock();
     sp<EventHub> hub = gHub;
@@ -69,7 +69,7 @@ android_server_KeyInputQueue_readEvent(JNIEnv* env, jobject clazz,
     uint32_t flags;
     int32_t value;
     nsecs_t when;
-    bool res = hub->getEvent(&deviceId, &type, &scancode, &keycode,
+    bool res = hub->getEvent(timeout, &deviceId, &type, &scancode, &keycode,
             &flags, &value, &when);
 
     env->SetIntField(event, gInputOffsets.mDeviceId, (jint)deviceId);
@@ -213,7 +213,7 @@ android_server_KeyInputQueue_getKeycodeStateDevice(JNIEnv* env, jobject clazz,
  */
 static JNINativeMethod gInputMethods[] = {
     /* name, signature, funcPtr */
-    { "readEvent",       "(Landroid/view/RawInputEvent;)Z",
+    { "readEvent",       "(Landroid/view/RawInputEvent;I)Z",
             (void*) android_server_KeyInputQueue_readEvent },
     { "getDeviceClasses", "(I)I",
         (void*) android_server_KeyInputQueue_getDeviceClasses },
diff --git a/include/ui/EventHub.h b/include/ui/EventHub.h
index 16baa65..6fb4a94 100644
--- a/include/ui/EventHub.h
+++ b/include/ui/EventHub.h
@@ -76,9 +76,9 @@ public:
         DEVICE_REMOVED = 0x20000000
     };
     
-    virtual bool getEvent(int32_t* outDeviceId, int32_t* outType,
-            int32_t* outScancode, int32_t* outKeycode, uint32_t *outFlags,
-            int32_t* outValue, nsecs_t* outWhen);
+    virtual bool getEvent(int32_t timeout, int32_t* outDeviceId,
+            int32_t* outType, int32_t* outScancode, int32_t* outKeycode,
+            uint32_t *outFlags, int32_t* outValue, nsecs_t* outWhen);
     
 protected:
     virtual ~EventHub();
diff --git a/libs/ui/EventHub.cpp b/libs/ui/EventHub.cpp
index c35014d..cbb9685 100644
--- a/libs/ui/EventHub.cpp
+++ b/libs/ui/EventHub.cpp
@@ -250,9 +250,9 @@ EventHub::device_t* EventHub::getDevice(int32_t deviceId) const
     return NULL;
 }
 
-bool EventHub::getEvent(int32_t* outDeviceId, int32_t* outType,
-        int32_t* outScancode, int32_t* outKeycode, uint32_t *outFlags,
-        int32_t* outValue, nsecs_t* outWhen)
+bool EventHub::getEvent(int32_t timeout, int32_t* outDeviceId,
+        int32_t* outType, int32_t* outScancode, int32_t* outKeycode,
+        uint32_t *outFlags, int32_t* outValue, nsecs_t* outWhen)
 {
     *outDeviceId = 0;
     *outType = 0;
@@ -302,12 +302,14 @@ bool EventHub::getEvent(int32_t* outDeviceId, int32_t* outType,
 
         release_wake_lock(WAKE_LOCK_ID);
 
-        pollres = poll(mFDs, mFDCount, -1);
+        pollres = poll(mFDs, mFDCount, timeout);
 
         acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
 
         if (pollres <= 0) {
-            if (errno != EINTR) {
+            if (pollres == 0) {
+                return false;
+            } else if (errno != EINTR) {
                 LOGW("select failed (errno=%d)\n", errno);
                 usleep(100000);
             }
diff --git a/services/java/com/android/server/KeyInputQueue.java b/services/java/com/android/server/KeyInputQueue.java
index c67754b..81fa850 100644
--- a/services/java/com/android/server/KeyInputQueue.java
+++ b/services/java/com/android/server/KeyInputQueue.java
@@ -184,7 +184,7 @@ public abstract class KeyInputQueue {
                     InputDevice di;
 
                     // block, doesn't release the monitor
-                    readEvent(ev);
+                    readEvent(ev, -1);
 
                     boolean send = false;
                     boolean configChanged = false;
@@ -616,5 +616,5 @@ public abstract class KeyInputQueue {
         Log.i(TAG, "  " + name + ": unknown values");
         return null;
     }
-    private static native boolean readEvent(RawInputEvent outEvent);
+    private static native boolean readEvent(RawInputEvent outEvent, int timeout);
 }
diff --git a/services/java/com/android/server/KeyInputQueue.java b/services/java/com/android/server/KeyInputQueue.java
index 81fa850..71d66ae 100644
--- a/services/java/com/android/server/KeyInputQueue.java
+++ b/services/java/com/android/server/KeyInputQueue.java
@@ -173,18 +173,65 @@ public abstract class KeyInputQueue {
                 flags);
     }
     
+    private static void substKeys(RawInputEvent ev, RawInputEvent ev2) {
+        if(ev.keycode == KeyEvent.KEYCODE_ENDCALL) {
+            ev.keycode = ev2.keycode = KeyEvent.KEYCODE_MENU;
+        } else if(ev.keycode == KeyEvent.KEYCODE_HOME) {
+            ev.keycode = ev2.keycode = KeyEvent.KEYCODE_BACK;
+        }
+    }
+
     Thread mThread = new Thread("InputDeviceReader") {
         public void run() {
             android.os.Process.setThreadPriority(
                     android.os.Process.THREAD_PRIORITY_URGENT_DISPLAY);
             
             try {
-                RawInputEvent ev = new RawInputEvent();
+                RawInputEvent evDown = new RawInputEvent();
+                RawInputEvent evUp = new RawInputEvent();
+                RawInputEvent ev = evDown;
+                long downTime = 0;
+                int state = 0;
                 while (true) {
                     InputDevice di;
 
-                    // block, doesn't release the monitor
-                    readEvent(ev, -1);
+                    if(state == 0) {
+                        // block, doesn't release the monitor
+                        readEvent(ev, -1);
+                        if(ev.type == RawInputEvent.EV_KEY &&
+                                ev.value != 0 &&
+                                (ev.keycode == KeyEvent.KEYCODE_ENDCALL ||
+                                ev.keycode == KeyEvent.KEYCODE_HOME)) {
+                            ev = evUp;    // start to listen for up
+                            downTime = SystemClock.uptimeMillis();
+                            state = 1;
+                            continue;
+                        }
+                    }
+                    else if(state == 1) {
+                        int timeout = (int)(downTime + 1000 - SystemClock.uptimeMillis());
+                        if(timeout > 0) {
+                            // block, doesn't release the monitor
+                            readEvent(ev, timeout);
+                            if(ev.type == RawInputEvent.EV_KEY &&
+                                    ev.value == 0 &&
+                                    evUp.keycode == evDown.keycode) {
+                                substKeys(evDown, evUp);
+                                ev = evDown;
+                                state = 2;
+                            }
+                        } else {
+                            ev = evDown;    // substitution timed out, send original event
+                            state = 0;
+                        }
+                    } else if(state == 2) {
+                        ev = evUp;
+                        state = 3;
+                    } else if(state == 3) {
+                        ev = evDown;
+                        state = 0;
+                        continue;
+                    }
 
                     boolean send = false;
                     boolean configChanged = false;
diff --git a/Neo1973_Buttons.kl b/Neo1973_Buttons.kl
index 8db354e..7920d11 100644
--- a/Neo1973_Buttons.kl
+++ b/Neo1973_Buttons.kl
@@ -1,4 +1,4 @@
-key 169   BACK              WAKE_DROPPED
+key 169   HOME              WAKE_DROPPED
 
 key 2     1
 key 3     2

<<inline: keys.png>>

_______________________________________________
android-freerunner mailing list
[email protected]
http://android.koolu.org/listinfo.cgi/android-freerunner-koolu.org

Reply via email to