原文地址:http://blog.csdn.net/skdev/archive/2010/03/08/5357358.aspx
文件: frameworks/base/libs/ui/EventHub.cpp
// 输入事件有:键盘、轨迹球、单点触摸、多点触摸 int EventHub::open_device(const char *deviceName) { ... uint8_t key_bitmask[(KEY_MAX+1)/8]; memset(key_bitmask, 0, sizeof(key_bitmask)); LOGV("Getting keys..."); if (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(key_bitmask)), key_bitmask) >= 0) { //LOGI("MAP/n"); //for (int i=0; i<((KEY_MAX+1)/8); i++) { // LOGI("%d: 0x%02x/n", i, key_bitmask[i]); //} for (int i=0; i<((BTN_MISC+7)/8); i++) { if (key_bitmask[i] != 0) { device->classes |= CLASS_KEYBOARD; break; } } // 是否为键盘 if ((device->classes & CLASS_KEYBOARD) != 0) { device->keyBitmask = new uint8_t[sizeof(key_bitmask)]; if (device->keyBitmask != NULL) { memcpy(device->keyBitmask, key_bitmask, sizeof(key_bitmask)); } else { delete device; LOGE("out of memory allocating key bitmask"); return -1; } } } // 是否为轨迹球 // 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)); LOGV("Getting relative controllers..."); 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; } } } uint8_t abs_bitmask[(ABS_MAX+1)/8]; memset(abs_bitmask, 0, sizeof(abs_bitmask)); LOGV("Getting absolute controllers..."); 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; } ... }
文件: frameworks/base/services/java/com/android/server/KeyInputQueue.java
Thread mThread = new Thread("InputDeviceReader") { public void run() { if (DEBUG) Log.v(TAG, "InputDeviceReader.run()"); android.os.Process.setThreadPriority( android.os.Process.THREAD_PRIORITY_URGENT_DISPLAY); // 定义事件变量 RawInputEvent ev = new RawInputEvent(); while (true) { try { ... // block, doesn't release the monitor // 调用readEvent,将输入事件读取到ev类,即RawInputEvent的变量里,readEvent对应jni的android_server_KeyInputQueue_readEvent readEvent(ev); ...
// 多点触摸和单点触摸的处理:保存多点或单点触摸的数据。 // 从多点触摸协议中获取位置事件 else if (ev.type == RawInputEvent.EV_ABS && (classes&RawInputEvent.CLASS_TOUCHSCREEN_MT) != 0) { if (ev.scancode == RawInputEvent.ABS_MT_TOUCH_MAJOR) { di.mAbs.changed = true; di.mAbs.mNextData[di.mAbs.mAddingPointerOffset + MotionEvent.SAMPLE_PRESSURE] = ev.value; } else if (ev.scancode == RawInputEvent.ABS_MT_POSITION_X) { di.mAbs.changed = true; di.mAbs.mNextData[di.mAbs.mAddingPointerOffset + MotionEvent.SAMPLE_X] = ev.value; if (DEBUG_POINTERS) Log.v(TAG, "MT @" + di.mAbs.mAddingPointerOffset + " X:" + ev.value); } else if (ev.scancode == RawInputEvent.ABS_MT_POSITION_Y) { di.mAbs.changed = true; di.mAbs.mNextData[di.mAbs.mAddingPointerOffset + MotionEvent.SAMPLE_Y] = ev.value; if (DEBUG_POINTERS) Log.v(TAG, "MT @" + di.mAbs.mAddingPointerOffset + " Y:" + ev.value); } else if (ev.scancode == RawInputEvent.ABS_MT_WIDTH_MAJOR) { di.mAbs.changed = true; di.mAbs.mNextData[di.mAbs.mAddingPointerOffset + MotionEvent.SAMPLE_SIZE] = ev.value; } // 处理单点触摸位置事件 // Process position events from single touch protocol. } else if (ev.type == RawInputEvent.EV_ABS && (classes&RawInputEvent.CLASS_TOUCHSCREEN) != 0) { if (ev.scancode == RawInputEvent.ABS_X) { di.mAbs.changed = true; di.curTouchVals[MotionEvent.SAMPLE_X] = ev.value; } else if (ev.scancode == RawInputEvent.ABS_Y) { di.mAbs.changed = true; di.curTouchVals[MotionEvent.SAMPLE_Y] = ev.value; } else if (ev.scancode == RawInputEvent.ABS_PRESSURE) { di.mAbs.changed = true; di.curTouchVals[MotionEvent.SAMPLE_PRESSURE] = ev.value; di.curTouchVals[MotionEvent.NUM_SAMPLE_DATA + MotionEvent.SAMPLE_PRESSURE] = ev.value; } else if (ev.scancode == RawInputEvent.ABS_TOOL_WIDTH) { di.mAbs.changed = true; di.curTouchVals[MotionEvent.SAMPLE_SIZE] = ev.value; di.curTouchVals[MotionEvent.NUM_SAMPLE_DATA + MotionEvent.SAMPLE_SIZE] = ev.value; } }
if (doMotion) { // XXX Need to be able to generate // multiple events here, for example // if two fingers change up/down state // at the same time. do { // 获取转换后触摸点数据并加入到输入事件队列。 me = ms.generateAbsMotion(di, curTime, curTimeNano, mDisplay, mOrientation, mGlobalMetaState); if (DEBUG_POINTERS) Log.v(TAG, "Absolute: x=" + di.mAbs.mNextData[MotionEvent.SAMPLE_X] + " y=" + di.mAbs.mNextData[MotionEvent.SAMPLE_Y] + " ev=" + me); if (me != null) { if (WindowManagerPolicy.WATCH_POINTER) { Log.i(TAG, "Enqueueing: " + me); } addLocked(di, curTimeNano, ev.flags, RawInputEvent.CLASS_TOUCHSCREEN, me); } } while (ms.hasMore()); }
// 文件:frameworks/base/services/java/com/android/server/KeyInputQueue.java readEvent(ev); di.curTouchVals[MotionEvent.SAMPLE_X] = ev.value; // 文件:frameworks/base/services/jni/com_android_server_KeyInputQueue.cpp { "readEvent", "(Landroid/view/RawInputEvent;)Z", (void*) android_server_KeyInputQueue_readEvent }, .. static jboolean android_server_KeyInputQueue_readEvent(JNIEnv* env, jobject clazz, jobject event) { ... bool res = hub->getEvent(&deviceId, &type, &scancode, &keycode, &flags, &value, &when); ... } // 文件:frameworks/base/libs/ui/EventHub.cpp bool EventHub::getEvent(int32_t* outDeviceId, int32_t* outType, int32_t* outScancode, int32_t* outKeycode, uint32_t *outFlags, int32_t* outValue, nsecs_t* outWhen) { ... res = read(mFDs[i].fd, &iev, sizeof(iev)); ... *outValue = iev.value; .. }