input_manager.h
#ifndef _INPUT_MANAGER_H #define _INPUT_MANAGER_H #include <sys/time.h> #define INPUT_TYPE_STDIN 0 #define INPUT_TYPE_TOUCHSCREEN 1 #define INPUT_VALUE_UP 0 #define INPUT_VALUE_DOWN 1 #define INPUT_VALUE_EXIT 2 #define INPUT_VALUE_UNKNOWN -1 typedef struct InputEvent { struct timeval tTime; int iType; /* stdin, touchsceen */ int iVal; /* */ }T_InputEvent, *PT_InputEvent; typedef struct InputOpr { char *name; int (*DeviceInit)(void); int (*DeviceExit)(void); int (*GetInputEvent)(PT_InputEvent ptInputEvent); struct InputOpr *ptNext; }T_InputOpr, *PT_InputOpr; int InputInit(void); int RegisterInputOpr(PT_InputOpr ptInputOpr); void ShowInputOpr(void); int AllInputDevicesInit(void); int GetInputEvent(PT_InputEvent ptInputEvent); #endif /* _INPUT_MANAGER_H */
input_manager.c
#include <config.h> #include <input_manager.h> #include <stdlib.h> #include <tslib.h> /* 参考tslib里的ts_print.c */ static struct tsdev *g_tTSDev; static int giXres; static int giYres; /* 注意: 由于要用到LCD的分辨率, 此函数要在SelectAndInitDisplay之后调用 */ static int TouchScreenDevInit(void) { char *pcTSName = NULL; if ((pcTSName = getenv("TSLIB_TSDEVICE")) != NULL ) { g_tTSDev = ts_open(pcTSName, 1); } else { g_tTSDev = ts_open("/dev/event0", 1); } if (!g_tTSDev) { DBG_PRINTF("ts_open error!\n"); return -1; } if (ts_config(g_tTSDev)) { DBG_PRINTF("ts_config error!\n"); return -1; } if (GetDispResolution(&giXres, &giYres)) { return -1; } return 0; } static int TouchScreenDevExit(void) { return 0; } static int isOutOf500ms(struct timeval *ptPreTime, struct timeval *ptNowTime) { int iPreMs; int iNowMs; iPreMs = ptPreTime->tv_sec * 1000 + ptPreTime->tv_usec / 1000; iNowMs = ptNowTime->tv_sec * 1000 + ptNowTime->tv_usec / 1000; return (iNowMs > iPreMs + 500); } static int TouchScreenGetInputEvent(PT_InputEvent ptInputEvent) { struct ts_sample tSamp; int iRet; static struct timeval tPreTime; iRet = ts_read(g_tTSDev, &tSamp, 1); if (iRet < 0) { return -1; } /* 处理数据 */ if (isOutOf500ms(&tPreTime, &tSamp.tv)) { /* 如果此次触摸事件发生的时间, 距上次事件超过了500ms */ tPreTime = tSamp.tv; ptInputEvent->tTime = tSamp.tv; ptInputEvent->iType = INPUT_TYPE_TOUCHSCREEN; if (tSamp.y < giYres/3) { ptInputEvent->iVal = INPUT_VALUE_UP; } else if (tSamp.y > 2*giYres/3) { ptInputEvent->iVal = INPUT_VALUE_DOWN; } else { ptInputEvent->iVal = INPUT_VALUE_UNKNOWN; } return 0; } else { return -1; } return 0; } static T_InputOpr g_tTouchScreenOpr = { .name = "touchscreen", .DeviceInit = TouchScreenDevInit, .DeviceExit = TouchScreenDevExit, .GetInputEvent = TouchScreenGetInputEvent, }; int TouchScreenInit(void) { return RegisterInputOpr(&g_tTouchScreenOpr); }
stdin.c
#include <input_manager.h> #include <termios.h> #include <unistd.h> #include <stdio.h> static int StdinDevInit(void) { struct termios tTTYState; //get the terminal state tcgetattr(STDIN_FILENO, &tTTYState); //turn off canonical mode tTTYState.c_lflag &= ~ICANON; //minimum of number input read. tTTYState.c_cc[VMIN] = 1; /* 有一个数据时就立刻返回 */ //set the terminal attributes. tcsetattr(STDIN_FILENO, TCSANOW, &tTTYState); return 0; } static int StdinDevExit(void) { struct termios tTTYState; //get the terminal state tcgetattr(STDIN_FILENO, &tTTYState); //turn on canonical mode tTTYState.c_lflag |= ICANON; //set the terminal attributes. tcsetattr(STDIN_FILENO, TCSANOW, &tTTYState); return 0; } static int StdinGetInputEvent(PT_InputEvent ptInputEvent) { /* 如果有数据就读取、处理、返回 * 如果没有数据, 立刻返回, 不等待 */ /* select, poll 可以参数 UNIX环境高级编程 */ struct timeval tTV; fd_set tFDs; char c; tTV.tv_sec = 0; tTV.tv_usec = 0; FD_ZERO(&tFDs); FD_SET(STDIN_FILENO, &tFDs); //STDIN_FILENO is 0 select(STDIN_FILENO+1, &tFDs, NULL, NULL, &tTV); if (FD_ISSET(STDIN_FILENO, &tFDs)) { /* 处理数据 */ ptInputEvent->iType = INPUT_TYPE_STDIN; gettimeofday(&ptInputEvent->tTime, NULL); c = fgetc(stdin); if (c == 'u') { ptInputEvent->iVal = INPUT_VALUE_UP; } else if (c == 'n') { ptInputEvent->iVal = INPUT_VALUE_DOWN; } else if (c == 'q') { ptInputEvent->iVal = INPUT_VALUE_EXIT; } else { ptInputEvent->iVal = INPUT_VALUE_UNKNOWN; } return 0; } else { return -1; } } static T_InputOpr g_tStdinOpr = { .name = "stdin", .DeviceInit = StdinDevInit, .DeviceExit = StdinDevExit, .GetInputEvent = StdinGetInputEvent, }; int StdinInit(void) { return RegisterInputOpr(&g_tStdinOpr); }
touchscreen.c
#include <config.h> #include <input_manager.h> #include <stdlib.h> #include <tslib.h> /* 参考tslib里的ts_print.c */ static struct tsdev *g_tTSDev; static int giXres; static int giYres; /* 注意: 由于要用到LCD的分辨率, 此函数要在SelectAndInitDisplay之后调用 */ static int TouchScreenDevInit(void) { char *pcTSName = NULL; if ((pcTSName = getenv("TSLIB_TSDEVICE")) != NULL ) { g_tTSDev = ts_open(pcTSName, 1); } else { g_tTSDev = ts_open("/dev/event0", 1); } if (!g_tTSDev) { DBG_PRINTF("ts_open error!\n"); return -1; } if (ts_config(g_tTSDev)) { DBG_PRINTF("ts_config error!\n"); return -1; } if (GetDispResolution(&giXres, &giYres)) { return -1; } return 0; } static int TouchScreenDevExit(void) { return 0; } static int isOutOf500ms(struct timeval *ptPreTime, struct timeval *ptNowTime) { int iPreMs; int iNowMs; iPreMs = ptPreTime->tv_sec * 1000 + ptPreTime->tv_usec / 1000; iNowMs = ptNowTime->tv_sec * 1000 + ptNowTime->tv_usec / 1000; return (iNowMs > iPreMs + 500); } static int TouchScreenGetInputEvent(PT_InputEvent ptInputEvent) { struct ts_sample tSamp; int iRet; static struct timeval tPreTime; iRet = ts_read(g_tTSDev, &tSamp, 1); if (iRet < 0) { return -1; } /* 处理数据 */ if (isOutOf500ms(&tPreTime, &tSamp.tv)) { /* 如果此次触摸事件发生的时间, 距上次事件超过了500ms */ tPreTime = tSamp.tv; ptInputEvent->tTime = tSamp.tv; ptInputEvent->iType = INPUT_TYPE_TOUCHSCREEN; if (tSamp.y < giYres/3) { ptInputEvent->iVal = INPUT_VALUE_UP; } else if (tSamp.y > 2*giYres/3) { ptInputEvent->iVal = INPUT_VALUE_DOWN; } else { ptInputEvent->iVal = INPUT_VALUE_UNKNOWN; } return 0; } else { return -1; } return 0; } static T_InputOpr g_tTouchScreenOpr = { .name = "touchscreen", .DeviceInit = TouchScreenDevInit, .DeviceExit = TouchScreenDevExit, .GetInputEvent = TouchScreenGetInputEvent, }; int TouchScreenInit(void) { return RegisterInputOpr(&g_tTouchScreenOpr); }
5.1 使用轮询方法 // CPU占用率高
实验方法:
a. insmod s3c_ts.ko
确定是哪个设备节点对应触摸屏
b.
export TSLIB_TSDEVICE=/dev/event0
export TSLIB_CALIBFILE=/etc/pointercal
export TSLIB_CONFFILE=/etc/ts.conf
export TSLIB_PLUGINDIR=/lib/ts
export TSLIB_CONSOLEDEVICE=none
export TSLIB_FBDEVICE=/dev/fb0
c. 较准
ts_calibrate
d. telnetd -l /bin/sh //启动telnet服务,为了登录进去观察CPU占用率
e. ./show_file -s 24 -d fb -f ./MSYH.TTF ./utf8_novel.txt
f. telnet上开发板执行top命令观察