#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <pthread.h>
#include <sys/select.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <linux/input.h>
#define DEV_ENENT "/dev/input/event2"
#define EVENT_STACK_SIZE 16
#define BUTTON_LONG_PRESS_TIME 1500 //ms
#define OUT_HANDLE_CODE 4
enum ButtonStatusCode {
BUTTON_LONG_PRESS,
BUTTON_SHORT_PRESS,
};
typedef void (*KeyCallBack)(int code, int value, int type);
struct input_event event_stack[EVENT_STACK_SIZE];
static pthread_t KeyThreadId;
void KeyHandle(int code, int value, KeyCallBack cb)
{
static struct timeval OldTimer;
struct timeval CurrentTimer;
static int OldCode = 0;
#if 0
printf("code: %d, value: %d\n", code, value);
if (code == OUT_HANDLE_CODE) {
printf("release code\n");
cb(code, value, BUTTON_SHORT_PRESS);
return;
}
#endif
if (code == OldCode) {
gettimeofday(&CurrentTimer, NULL);
long TmpCurTimer = CurrentTimer.tv_sec * 1000 + CurrentTimer.tv_usec/1000;
long TmpOldTimer = OldTimer.tv_sec * 1000 + OldTimer.tv_usec/1000;
if ((TmpCurTimer - TmpOldTimer) > BUTTON_LONG_PRESS_TIME) {
printf("long press\n");
cb(code, value, BUTTON_LONG_PRESS);
} else {
printf("short press\n");
cb(code, value, BUTTON_SHORT_PRESS);
switch(code)
{
case KEY_1://音量-
printf("--Volume down--\n");
break;
case KEY_2://音量+
printf("--Volume up--\n");
break;
case KEY_3://对话
printf("--Chat--\n");
break;
case KEY_4://下一曲
printf("--Netx music--\n");
break;
case KEY_5://上一曲
printf("--Pre music--\n");
break;
case KEY_6://播放
printf("--Play--\n");
break;
default:
printf("--Invalid key code--\n");
}
}
OldCode = 0;
} else {
OldCode = code;
gettimeofday(&OldTimer, NULL);
}
}
void *KeyStart(void *param)
{
if (param == NULL) {
printf("button callback is null\n");
pthread_exit(NULL);
}
KeyCallBack cb = (KeyCallBack)param;
int Fd = -1;
int Size = 0;
int i;
int retval;
fd_set rfds;
Fd = open(DEV_ENENT, O_RDONLY | O_NONBLOCK);
if(Fd < 0)
{
perror(DEV_ENENT);
goto fail;
}
while(1)
{
FD_ZERO(&rfds);
FD_SET(Fd, &rfds);
retval = select(Fd + 1, &rfds, NULL, NULL, NULL);
if (retval == -1)
{
perror("select()");
continue;
}
else if (retval)
printf("Data is available now.\n");
else
continue;
Size = read(Fd, event_stack, sizeof(event_stack));
if(Size >= 0)
{
for(i = 0; i < Size/sizeof(event_stack[0]); i++) {
//printf("type = %d code = %d value = %d\n", event_stack[i].type, event_stack[i].code, event_stack[i].value);
if (event_stack[i].type == 1) {
KeyHandle(event_stack[i].code, event_stack[i].value, cb);
}
}
}
else
{
perror(DEV_ENENT);
}
}
close(Fd);
fail:
pthread_exit(NULL);
}
int KeyInit(KeyCallBack cb)
{
int ret = pthread_create(&KeyThreadId, NULL, KeyStart, (void*)cb);
if(ret != 0)
{
printf("Create Key thread fail\n");
}
pthread_detach(KeyThreadId);
return 0;
}
void KeyUninit()
{
pthread_cancel(KeyThreadId);
pthread_join(KeyThreadId, NULL);
printf("Button thread uninit\n");
}
//------------------------> example <----------------------------
void tmp_key(int code, int value, int type)
{
printf("cb code: %d, value: %d, type: %d\n", code, value, type);
}
#if 1
//void KeyMain(void)
int main(void)
{
KeyInit(tmp_key);
sleep(10);
KeyUninit();
return 0;
}
#endif
//------------------------> example <----------------------------
参考: