Linux应用程序-按键响应

Linux应用程序-按键响应

Linux中的按键检测通过循环读取设备文件/dev/input/eventx设备文件获取按键事件,一般由主线程循环获取按键事件,然后通过消息队列通知其他子线程,从而做出响应。

Linux内核中,按键事件用input_event结构体描述,该结构体在头文件中定义,同时该文件还定义了有关按键事件的API函数接口、标准按键编码等。

input_event结构体定义如下:

struct input_event {  
    struct timeval time;  
    __u16 type;  
    __u16 code;  
    __s32 value;  
};

还定义了常用标准按键编码:

#define KEY_RESERVED        0  
#define KEY_ESC         1  
#define KEY_1           2  
#define KEY_2           3  
#define KEY_3           4  
#define KEY_4           5  
#define KEY_5           6  
#define KEY_6           7

在用户态,我们只需要循环读取设备文件/dev/input/eventx,就可以得到相应的键盘事件,代码如下:

#include <linux/input.h>  
#include <fcntl.h>  
#include <stdio.h>  
#include <stdint.h>  

#define  KEY_EVENT_DEV1_NAME    "/dev/input/event1"  

int sysKeyScan(void)  
{  
    int l_ret = -1;  
    int i = 0;  

    int key_fd  = 0;  
    struct input_event key_event  = {0};  

    key_fd = open(KEY_EVENT_DEV1_NAME, O_RDONLY);  
    if(key_fd <= 0)  
    {  
        printf("---open /dev/input/event1 device error!---\n");  
        return l_ret;  
    }  

    while(1)  
    {  
        l_ret = lseek(key_fd, 0, SEEK_SET);  
        l_ret = read(key_fd, &key_event, sizeof(key_event));  

        if(l_ret)  
        {  
            if(key_event.type == EV_KEY  
                && (key_event.value == 0 || key_event.value == 1))  
            {  
                printf("key %d %s\n", key_event.code, (key_event.value) ? "pressed" : "released");  

                if(key_event.code == KEY_ESC)  
                {  
                    break;  
                }  

            }  
        }  

    }  

    close(key_fd);  

    return l_ret;  

}  

int main(int arg, char *arc[])  
{  
    printf("---This is a key event test!---\n");  

    sysKeyScan();  

    return 0;  
}

有时候,我们的的Linux内核也可以把不同的按键封装到不同的event中,例如数字键键盘事件通过event1通知用户态,而功能键通过event0通知用户态。此时我们可以使用poll函数来同时监测多个等待事件,若事件未发生,进程睡眠,放弃CPU控制权,直到有键盘事件发生,poll将唤醒睡眠的进程,并执行相应的操作。代码如下:

#include <linux/input.h>  
#include <fcntl.h>  
#include <poll.h>  
#include <stdio.h>  
#include <stdint.h>  

#define  KEY_EVENT_DEV0_NAME    "/dev/input/event0"  
#define  KEY_EVENT_DEV1_NAME    "/dev/input/event1"  

int sysKeyScan(void)  
{  
    int l_ret = -1;  
    int i = 0;  

    int key_fd[2]  = {0};  
    struct pollfd key_fds[2] = {0};  
    struct input_event key_event  = {0};  

    key_fd[0] = open(KEY_EVENT_DEV0_NAME, O_RDONLY);  
    if(key_fd[0] <= 0)  
    {  
        printf("---open /dev/input/event0 device error!---\n");  
        return l_ret;  
    }  

    key_fd[1] = open(KEY_EVENT_DEV1_NAME, O_RDONLY);  
    if(key_fd[1] <= 0)  
    {  
        printf("---open /dev/input/event1 device error!---\n");  
        return l_ret;  
    }  

    for(i = 0; i < 2; i++)  
    {  
        key_fds[i].fd = key_fd[i];  
        key_fds[i].events = POLLIN;  
    }  

    while(1)  
    {  
        l_ret = poll(key_fds, 2, -1);  

        for(i = 0; i < 2; i++)  
        {  
            l_ret = lseek(key_fd[i], 0, SEEK_SET);  
            l_ret = read(key_fd[i], &key_event, sizeof(key_event));  

            if(l_ret)  
            {  
                if(key_event.type == EV_KEY  
                    && (key_event.value == 0 || key_event.value == 1))  
                {  

                    printf("key value(%d) %s", key_event.code, key_event.value ? "press" : "release");  

                }  
            }  
        }  
    }  

    close(key_fd[0]);  
    close(key_fd[1]);  

    return l_ret;  

}  

int main(int argc, char *argv[])  
{  
    printf("---This is a key event test!---\n");  

    sysKeyScan();  

    return 0;  
}
博客
32132
07-14 364
07-12 297
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值