最近這一週都在處理有關 Linux input 問題,詳細就不說了,主要這次對 /dev/input/eventX 做了稍微詳細的測試一下.
有關取 key 的方式就是open & read ,這也是一般方式,問題是open 兩次得到兩個handle id 分別對這兩個去讀取會得到啥呢?一個按鍵的值會給哪一個呢? 結果是兩者都會收到 , 並且先 open 先收到 , 這樣說可能不是很清楚 , 舉個例子說明吧.
先利用 open 開啟 input device , 並且不要關閉(close) ,然後輸入 A,B,C,D & E , 接著再open input device 一次 , 然後 輸入 F,G,H,U,J & K , 接著讀取兩個 handle file ID . 第一個 open 的會讀取到 A,B,C,D,E,F,G,H,I,J & K , 第二次 open 的會讀取到 F,G,H,I,J & K . 這樣應該了解我說的先 open 先讀到的意思了吧 ! 想一想, 這樣的邏輯也對 , open 一次就是新的一個 file , 之前已經過去的 key ( open 之前) 當然收不到 .
問題又來了 , 這樣會導致兩個 task 都收到 key , 這樣的情況下 , 我能只限定某個 task 收到 , 另外一個不要收到嗎 ?? 這就是今天的主題了.
可以利用今天說的主題 EVIOCGRAB ioctl command 來進行這樣的控制 , 對於想要 "獨佔" 的 device file 下 EVIOCGRAB command , 就可以確保只有它收到 , 其它有 open 的 device 不會收到. 如果兩者都下 EVIOCGRAB command , 就看誰先了, 先的就 "獨占" .
下面就是我測試的 sample code (部份), 會發現只有第二次 open 的會讀到輸入值.
devfd_1 = open(key_dev, O_RDONLY | O_NONBLOCK);
devfd = open(key_dev, O_RDONLY | O_NONBLOCK);
ioctl(devfd, EVIOCGRAB,1);
ioctl(devfd_1, EVIOCGRAB,1);
ioctl(devfd_1, EVIOCGRAB,1);
for ( i = 0 ; i < 20 ; i ++ )
{
readlen = read(devfd,&inputdata,sizeof(struct input_event));
if ( readlen == sizeof(struct input_event) && (inputdata.type == EV_KEY) )
{
printf("Keypad code:%d",inputdata.code);
{
readlen = read(devfd,&inputdata,sizeof(struct input_event));
if ( readlen == sizeof(struct input_event) && (inputdata.type == EV_KEY) )
{
printf("Keypad code:%d",inputdata.code);
if (inputdata.value == 1)
printf(" Down!\n");
else if (inputdata.value == 0)
printf(" Up!\n");
else if (inputdata.value == 2 )
printf(" PRESSED !\n");
}
readlen = read(devfd_1,&inputdata,sizeof(struct input_event));
if ( readlen == sizeof(struct input_event) && (inputdata.type == EV_KEY) )
{
printf("2 Keypad code:%d",inputdata.code);
if (inputdata.value == 1)
printf(" Down!\n");
else if (inputdata.value == 0)
printf(" Up!\n");
else if (inputdata.value == 2 )
printf(" PRESSED !\n");
}
}
close(devfd);
close(devfd_1);