Android应用程序键盘(Keyboard)消息处理机制分析(6)
2011-10-24 00:59
399 查看
Step 21. EventHub.openDevice
这个函数定义在frameworks/base/libs/ui/EventHub.cpp文件中:
这个函数定义在frameworks/base/libs/ui/EventHub.cpp文件中:
int EventHub::openDevice(const char *deviceName) { int version; int fd; struct pollfd *new_mFDs; device_t **new_devices; char **new_device_names; char name[80]; char location[80]; char idstr[80]; struct input_id id; LOGV("Opening device: %s", deviceName); AutoMutex _l(mLock); fd = open(deviceName, O_RDWR); if(fd < 0) { LOGE("could not open %s, %s\n", deviceName, strerror(errno)); return -1; } ...... int devid = 0; while (devid < mNumDevicesById) { if (mDevicesById[devid].device == NULL) { break; } devid++; } ...... mDevicesById[devid].seq = (mDevicesById[devid].seq+(1<<SEQ_SHIFT))&SEQ_MASK; if (mDevicesById[devid].seq == 0) { mDevicesById[devid].seq = 1<<SEQ_SHIFT; } new_mFDs = (pollfd*)realloc(mFDs, sizeof(mFDs[0]) * (mFDCount + 1)); new_devices = (device_t**)realloc(mDevices, sizeof(mDevices[0]) * (mFDCount + 1)); if (new_mFDs == NULL || new_devices == NULL) { LOGE("out of memory"); return -1; } mFDs = new_mFDs; mDevices = new_devices; ...... device_t* device = new device_t(devid|mDevicesById[devid].seq, deviceName, name); if (device == NULL) { LOGE("out of memory"); return -1; } device->fd = fd; mFDs[mFDCount].fd = fd; mFDs[mFDCount].events = POLLIN; mFDs[mFDCount].revents = 0; // Figure out the kinds of events the device reports. uint8_t key_bitmask[sizeof_bit_array(KEY_MAX + 1)]; memset(key_bitmask, 0, sizeof(key_bitmask)); LOGV("Getting keys..."); if (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(key_bitmask)), key_bitmask) >= 0) { // See if this is a keyboard. Ignore everything in the button range except for // gamepads which are also considered keyboards. if (containsNonZeroByte(key_bitmask, 0, sizeof_bit_array(BTN_MISC)) || containsNonZeroByte(key_bitmask, sizeof_bit_array(BTN_GAMEPAD), sizeof_bit_array(BTN_DIGI)) || containsNonZeroByte(key_bitmask, sizeof_bit_array(KEY_OK), sizeof_bit_array(KEY_MAX + 1))) { device->classes |= INPUT_DEVICE_CLASS_KEYBOARD; 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; } } } ...... if ((device->classes & INPUT_DEVICE_CLASS_KEYBOARD) != 0) { char tmpfn[sizeof(name)]; char keylayoutFilename[300]; // a more descriptive name device->name = name; // replace all the spaces with underscores strcpy(tmpfn, name); for (char *p = strchr(tmpfn, ' '); p && *p; p = strchr(tmpfn, ' ')) *p = '_'; // find the .kl file we need for this device const char* root = getenv("ANDROID_ROOT"); snprintf(keylayoutFilename, sizeof(keylayoutFilename), "%s/usr/keylayout/%s.kl", root, tmpfn); bool defaultKeymap = false; if (access(keylayoutFilename, R_OK)) { snprintf(keylayoutFilename, sizeof(keylayoutFilename), "%s/usr/keylayout/%s", root, "qwerty.kl"); defaultKeymap = true; } status_t status = device->layoutMap->load(keylayoutFilename); if (status) { LOGE("Error %d loading key layout.", status); } // tell the world about the devname (the descriptive name) if (!mHaveFirstKeyboard && !defaultKeymap && strstr(name, "-keypad")) { // the built-in keyboard has a well-known device ID of 0, // this device better not go away. mHaveFirstKeyboard = true; mFirstKeyboardId = device->id; property_set("hw.keyboards.0.devname", name); } else { // ensure mFirstKeyboardId is set to -something-. if (mFirstKeyboardId == 0) { mFirstKeyboardId = device->id; } } char propName[100]; sprintf(propName, "hw.keyboards.%u.devname", device->id); property_set(propName, name); // 'Q' key support = cheap test of whether this is an alpha-capable kbd if (hasKeycodeLocked(device, AKEYCODE_Q)) { device->classes |= INPUT_DEVICE_CLASS_ALPHAKEY; } // See if this device has a DPAD. if (hasKeycodeLocked(device, AKEYCODE_DPAD_UP) && hasKeycodeLocked(device, AKEYCODE_DPAD_DOWN) && hasKeycodeLocked(device, AKEYCODE_DPAD_LEFT) && hasKeycodeLocked(device, AKEYCODE_DPAD_RIGHT) && hasKeycodeLocked(device, AKEYCODE_DPAD_CENTER)) { device->classes |= INPUT_DEVICE_CLASS_DPAD; } // See if this device has a gamepad. for (size_t i = 0; i < sizeof(GAMEPAD_KEYCODES)/sizeof(GAMEPAD_KEYCODES[0]); i++) { if (hasKeycodeLocked(device, GAMEPAD_KEYCODES[i])) { device->classes |= INPUT_DEVICE_CLASS_GAMEPAD; break; } } LOGI("New keyboard: device->id=0x%x devname='%s' propName='%s' keylayout='%s'\n", device->id, name, propName, keylayoutFilename); } ...... mDevicesById[devid].device = device; device->next = mOpeningDevices; mOpeningDevices = device; mDevices[mFDCount] = device; mFDCount++; return 0; }
相关文章推荐
- Android应用程序键盘(Keyboard)消息处理机制分析(9)
- Android应用程序键盘(Keyboard)消息处理机制分析
- Android应用程序键盘(Keyboard)消息处理机制分析
- Android应用程序键盘(Keyboard)消息处理机制分析(11)
- Android应用程序键盘(Keyboard)消息处理机制分析(27)
- Android应用程序键盘(Keyboard)消息处理机制分析(二)
- Android应用程序键盘(Keyboard)消息处理机制分析
- Android应用程序键盘(Keyboard)消息处理机制分析
- Android应用程序键盘(Keyboard)消息处理机制分析(12)
- Android应用程序键盘(Keyboard)消息处理机制分析(28)
- Android应用程序键盘(Keyboard)消息处理机制分析
- Android应用程序键盘(Keyboard)消息处理机制分析(13)
- Android应用程序键盘(Keyboard)消息处理机制分析
- Android应用程序键盘(Keyboard)消息处理机制分析(14)
- Android应用程序键盘(Keyboard)消息处理机制分析(四)
- Android应用程序键盘(Keyboard)消息处理机制分析(15)
- Android应用程序键盘(Keyboard)消息处理机制分析
- Android应用程序键盘(Keyboard)消息处理机制分析(16)
- Android应用程序键盘(Keyboard)消息处理机制分析
- Android应用程序键盘(Keyboard)消息处理机制分析(1)