Android应用程序键盘(Keyboard)消息处理机制分析(7)
16lz
2021-01-26
函数首先根据文件名来打开这个设备文件:
- fd=open(deviceName,O_RDWR);
系统中所有输入设备文件信息都保存在成员变量mDevicesById中,因此,先在mDevicesById找到一个空位置来保存当前打开的设备文件信息:
- mDevicesById[devid].seq=(mDevicesById[devid].seq+(1<<SEQ_SHIFT))&SEQ_MASK;
- if(mDevicesById[devid].seq==0){
- mDevicesById[devid].seq=1<<SEQ_SHIFT;
- }
找到了空闲位置后,就为这个输入设备文件创建相应的device_t信息:
- 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("outofmemory");
- return-1;
- }
- mFDs=new_mFDs;
- mDevices=new_devices;
- ......
- device_t*device=newdevice_t(devid|mDevicesById[devid].seq,deviceName,name);
- if(device==NULL){
- LOGE("outofmemory");
- return-1;
- }
- device->fd=fd;
同时,这个设备文件还会保存在数组mFDs中:
- mFDs[mFDCount].fd=fd;
- mFDs[mFDCount].events=POLLIN;
- mFDs[mFDCount].revents=0;
接下来查看这个设备是不是键盘:
- //Figureoutthekindsofeventsthedevicereports.
- uint8_tkey_bitmask[sizeof_bit_array(KEY_MAX+1)];
- memset(key_bitmask,0,sizeof(key_bitmask));
- LOGV("Gettingkeys...");
- if(ioctl(fd,EVIOCGBIT(EV_KEY,sizeof(key_bitmask)),key_bitmask)>=0){
- //Seeifthisisakeyboard.Ignoreeverythinginthebuttonrangeexceptfor
- //gamepadswhicharealsoconsideredkeyboards.
- 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=newuint8_t[sizeof(key_bitmask)];
- if(device->keyBitmask!=NULL){
- memcpy(device->keyBitmask,key_bitmask,sizeof(key_bitmask));
- }else{
- deletedevice;
- LOGE("outofmemoryallocatingkeybitmask");
- return-1;
- }
- }
- }
如果是的话,还要继续进一步初始化前面为这个设备文件所创建的device_t结构体,主要就是把结构体device的classes成员变量的INPUT_DEVICE_CLASS_KEYBOARD位置为1了,以表明这是一个键盘。
如果是键盘设备,初始化工作还未完成,还要继续设置键盘的布局等信息:
- if((device->classes&INPUT_DEVICE_CLASS_KEYBOARD)!=0){
- chartmpfn[sizeof(name)];
- charkeylayoutFilename[300];
- //amoredescriptivename
- device->name=name;
- //replaceallthespaceswithunderscores
- strcpy(tmpfn,name);
- for(char*p=strchr(tmpfn,'');p&&*p;p=strchr(tmpfn,''))
- *p='_';
- //findthe.klfileweneedforthisdevice
- constchar*root=getenv("ANDROID_ROOT");
- snprintf(keylayoutFilename,sizeof(keylayoutFilename),
- "%s/usr/keylayout/%s.kl",root,tmpfn);
- booldefaultKeymap=false;
- if(access(keylayoutFilename,R_OK)){
- snprintf(keylayoutFilename,sizeof(keylayoutFilename),
- "%s/usr/keylayout/%s",root,"qwerty.kl");
- defaultKeymap=true;
- }
- status_tstatus=device->layoutMap->load(keylayoutFilename);
- if(status){
- LOGE("Error%dloadingkeylayout.",status);
- }
- //telltheworldaboutthedevname(thedescriptivename)
- if(!mHaveFirstKeyboard&&!defaultKeymap&&strstr(name,"-keypad")){
- //thebuilt-inkeyboardhasawell-knowndeviceIDof0,
- //thisdevicebetternotgoaway.
- mHaveFirstKeyboard=true;
- mFirstKeyboardId=device->id;
- property_set("hw.keyboards.0.devname",name);
- }else{
- //ensuremFirstKeyboardIdissetto-something-.
- if(mFirstKeyboardId==0){
- mFirstKeyboardId=device->id;
- }
- }
- charpropName[100];
- sprintf(propName,"hw.keyboards.%u.devname",device->id);
- property_set(propName,name);
- //'Q'keysupport=cheaptestofwhetherthisisanalpha-capablekbd
- if(hasKeycodeLocked(device,AKEYCODE_Q)){
- device->classes|=INPUT_DEVICE_CLASS_ALPHAKEY;
- }
- //SeeifthisdevicehasaDPAD.
- 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;
- }
- //Seeifthisdevicehasagamepad.
- for(size_ti=0;i<sizeof(GAMEPAD_KEYCODES)/sizeof(GAMEPAD_KEYCODES[0]);i++){
- if(hasKeycodeLocked(device,GAMEPAD_KEYCODES[i])){
- device->classes|=INPUT_DEVICE_CLASS_GAMEPAD;
- break;
- }
- }
- LOGI("Newkeyboard:device->id=0x%xdevname='%s'propName='%s'keylayout='%s'\n",
- device->id,name,propName,keylayoutFilename);
- }
到这里,系统中的输入设备文件就打开了。
更多相关文章
- Android(安卓)Studio基础:USB联调App
- 电脑导出文件到手机 adb push
- Android(安卓)NDK r5 windows系统上安装与使用
- Doze和App Standby的优化(API23)
- cocos2dx3.0打包注意事项
- Android(安卓)反编译:加固前后对比
- FileProvider的使用
- Android(安卓)多语言开发
- android 上传文件到 spring 搭建的后台