触摸屏输入
- tslib库
```cdefine INPUT_TYPE_STDIN 0define INPUT_TYPE_TOUCHSCREEN 1define INPUT_VALUE_UP 0 //上翻define INPUT_VALUE_DOWN 1 //下翻define INPUT_VALUE_EXIT 2 //退出define INPUT_VALUE_UNKNOW 3 //未知/ 抽象出输入事件 / typedef strut InputEvent{ struct timeval tTime; / 时间 / int iType; / 输入事件类别, stdin/ts… / int iVal; / 输入的值,0/1/2 / }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;
- 时间:
- 
- input_manager中需要实现几个函数:
- 提供给下层程序注册的函数InputOprRegister()
- 统一的初始化函数InputOprInit()
- 提供查询有哪些输入ShowInputOpr()
<a name="6F0ql"></a>
# 轮询方式
- stdin.c
```c
#include <input_manager.h>
/* 声明输入操作对象中要实现的几个函数 */
static int StdinDevInit(void);
static int StdinDevExit(void);
static int StdinGetInputEvent(PT_InputEvent ptInputEvent);
/* 定义输入操作对象 */
static T_InputOpr g_tStdinOpr = {
.name = "stdin",
.DeviceInit = StdinDevInit,
.DeviceExit = StdinDevExit,
.GetInputEvent = StdinGetInputEvent,
}
/* 实现输入操作对象中要实现的几个函数 */
//放在后面
/* 注册结构体(向上层input_manager提供的函数) */
int StdinInit(void)
{
return RegisterInputOpr(&g_tStdinOpr);
}
- scanf函数无法立刻返回,它会休眠直到有数据输入并回车
- 在stdin上以非阻塞的方式获得输入(stdin nonblock) - #include <termios.h>
- #include <unistd.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;
- }
 
- StdinGeytInputEvent() - 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->iTime, 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_UNKNOW;
- }
- }else
- {
- return -1;
- }
- return 0;
- }
 
- select函数和poll函数是一样的 
- touchscreen.c ```c - include- / 参考tslib里的ts_print.c, 里面实现打印触摸屏转换成LCD坐标的数据 / 
static struct tsdev g_tTSDev; / 定义输入操作对象 / static T_InputOpr g_tTouchScreenOpr = { .name = “touchscreen”, .DeviceInit = TouchScreenDevInit, .DeviceExit = TouchScreenDevExit, .GetInputEvent = TouchScreenGetInputEvent, }; / 提供注册结构体函数供上层input_manager使用 / int TouchScreenInit(void) { return RegisterInputOpr(&g_tTouchScreenOpr); }
- 对触摸屏的使用,需要参考tslib
```c
static int g_iXres,g_iYres;
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); /* 默认打开event0 */
}
if(!g_tTSDev)
{
DBG_PRINT("ts_open error\n");
return -1;
}
/* 配置 */
if( ts_config(g_tTSDev) )
{
DBG_PRINT("ts_config error\n");
return -1;
}
/* 获取X/Y分辨率 */
if ( GetDispResolution(&g_iXres, &g_iYres) )
{
return -1;
}
return 0;
}
int TouchScreenDevExit(void)
{
return 0;
}
- TouchScreenGetInputEvent() ```c 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){ - DBG_PRINT("ts_read error");
- return -1;
 - } / 处理数据 / if( isOutOf500ms(&tPreTime, &tSamp.tv) ) { - /* 如果此次触摸事件发生的时间距上次事件发生事件超过500ms,才认为是一次输入 */
- tPreTime = tSamp.tv;
- ptInputEvent->iType = tSamp.tv;
- ptInputEvent->iType = INPUT_TYPE_TOUCHSCREEN;
- if(tSamp.y < g_iYres/3)
- {
- ptInputEvent->iVal = INPUT_VALUE_UP;
- }else if(tSamp.y > g_iYres/3 * 2)
- {
- ptInputEvent->iVal = INPUT_VALUE_DOWN;
- }else
- {
- ptInputEvent->iVal = INPUT_VALUE_UNKNOW;
- }
 - }else { - return -1;
 - } - return 0; } 
/ 判断和上一次事件的事件是否超过了500ms / static int isOutOf500ms(struct timeval ptPreTime, struct timeval ptNowTime) { int iPreMs, iNowMs; iPreMs = ptPreTime->tv_sec 1000 + ptPreTime->tv_usec / 1000; iNowMs = ptNowTime->tv_sec 1000 + ptNowTime->tv_usec / 1000;
return (iNowMs > iPreMs + 500);
} ```
- 触摸屏点一下会得到多个数据 
- 启动开发板后安装各种触摸屏驱动程序等等 
- 搭建运行环境:2.6.22.6内核看第2期视频触摸屏章节,3.4.2内核看第2期视频毕业班里的相关章节 
- 轮询方式, CPU占用率很高 
- 要用标准输入,必须要让程序位于前台 
- telnetd 
 
 
 
                         
                                

