📄 touch.c
字号:
/*************************************************** Copyright(C), 2009 , JUST File name: touch.h Author: 郑慎 Version: 0.1 Date: 09/03/29 Description: 实现触摸屏的打开和取点等功能 History: 09/03/29 V0.1***************************************************/#include <stdio.h>#include <stdlib.h>#include <linux/fb.h>#include <asm/fcntl.h>#include <linux/input.h>#include <asm/mman.h>#include "touch.h"#define MAX_DRAG_X 80//区别划动的x方向最大值#define MAX_DRAG_Y 80//区别划动的y方向最大值/*双击间隔时间0.5s*/ #define WAIT_TIME_NSEC 500000 int touchscreen_fd = 0; /* touch screen device handle */ /*时间的拷贝*/void copy_time(struct timeval *t1,struct timeval *t2){ t1->tv_sec=t2->tv_sec; t1->tv_usec=t2->tv_usec;} /*点的拷贝*/void copy_point(POINT *p1,POINT *p2){ p1->x=p2->x; p1->y=p2->y;}// Retrieve an average data from touch screen input deviceint cal_data_avg(int ts_handler, ts_event_t * ts_avg, unsigned short max_num){ ts_event_t *tmpDataArr; //ts_event_t tmpData; unsigned short bp, i ; unsigned short count; long tempX, tempY; int ret,tFlg=0,timeFlg=1; static int pressureFlg=1; static int curr_x = 0, curr_y = 0, curr_p = 0; struct input_event ev; //Allocate a buffer for input data tmpDataArr = (ts_event_t *)malloc(max_num * sizeof(ts_event_t)); if (tmpDataArr == NULL) { printf("Error: malloc failed.\n"); return -1; } //printf("malloc ok.\n"); for (i = 0; i < max_num; i++) { tmpDataArr[i].x = 0; tmpDataArr[i].y = 0; tmpDataArr[i].pressure = 0; tmpDataArr[i].time.tv_sec=0; tmpDataArr[i].time.tv_usec=0; } // Read a set of data into buffer count = 0; do { bp = 0; while (1) { memset(&tmpDataArr[bp], 0, sizeof(ts_event_t)); ret = read(ts_handler, &ev, sizeof(struct input_event)); if (ret < sizeof(struct input_event)) { //printf("ret<size!!!\n"); break; } //printf("ev.time.tv_sec=%d,",ev.time.tv_sec); //printf("ev.time.tv_usec=%d,",ev.time.tv_usec); //printf("ev.type=0x%x,",ev.type); //printf("ev.code=0x%x,",ev.code); //printf("ev.value=%d!\n",ev.value); if(timeFlg) { ts_avg->time.tv_sec=ev.time.tv_sec; ts_avg->time.tv_usec=ev.time.tv_usec; timeFlg=0; } if (ev.type == EV_ABS) switch (ev.code) { case ABS_X: curr_x = ev.value; break; case ABS_Y: curr_y = ev.value; break; case ABS_PRESSURE: curr_p = ev.value; break; } /* We consider having a complete ts event */ tmpDataArr[bp].x = curr_x; tmpDataArr[bp].y = curr_y; tmpDataArr[bp].pressure = curr_p; if(curr_p!=0) tFlg=1;//第一次中未满max_num时 //printf("tmpDataArr[%d].x=%d,",bp,curr_x); //printf("tmpDataArr[%d].y=%d,",bp,curr_y); //printf("tmpDataArr[%d].pressure=%d\n",bp,curr_p); //printf("pressureFlg=%d\n",pressureFlg); if (bp < max_num) { if((curr_x!=0&&curr_y!=0&&curr_p==0)&&(pressureFlg!=1||tFlg)) { //printf("pressureFlg=%d!!!!\n",pressureFlg); //bp++; break; } else bp++; } else { //printf("break>max_num!!!\n"); break; } } count = bp; //printf("count=%d!!!!\n",count); }while (0); if(curr_x!=0&&curr_y!=0&&curr_p==0) pressureFlg=0; tempX = tempY = 0; for (bp=0; bp < count; bp++) { tempX += tmpDataArr[bp].x; if(bp!=0) { tempY += tmpDataArr[bp].y; } //if(pressureFlg!=0&&tmpDataArr[bp].x==0) // pressureFlg=1; } // Calculate an average value if(count!=0) { ts_avg->x = tempX / count; if(count>1) ts_avg->y = tempY / (count-1.0); else ts_avg->y = curr_y; } else { ts_avg->x = curr_x; ts_avg->y = curr_y; } switch(pressureFlg) { case 0: ts_avg->pressure = 0; pressureFlg=1; break; case 1: ts_avg->pressure = 1; pressureFlg=2; break; case 2: ts_avg->pressure = 2; break; } // Release free(tmpDataArr);}/*根据两个点的位置分析操作类型*/int analize_type(POINT *p1,POINT *p2){ if(p1->y-p2->y>MAX_DRAG_Y) return DOWN; if(p1->y-p2->y<-MAX_DRAG_Y) return UP; if(p1->x-p2->x>MAX_DRAG_X) return LEFT; if(p1->x-p2->x<-MAX_DRAG_X) return RIGHT; return STAY;}/*测试两次单点间隔是否在双点时间内,是返回1,否则返回0*/int IsSmallTime(struct timeval *t1,struct timeval *t2){ if(t2->tv_sec-t1->tv_sec>=2) return 0; if(t2->tv_sec-t1->tv_sec==1) { if(1000000+t2->tv_usec-t1->tv_usec>WAIT_TIME_NSEC) return 0; return 1; } if(t2->tv_usec-t1->tv_usec>WAIT_TIME_NSEC) return 0; return 1;}int ts_operation(TS_OP *ret,int support_dc){ ts_event_t ts_CalPoint;/* touch screen calibration pBuffer */ char * tsconf_name; unsigned short x_max, y_max; unsigned short i; FILE * fp; static int firstFlg=1;//一次双点后或第一次点击 static POINT newp1,newp2,oldp1,oldp2; static struct timeval newt1,newt2,oldt1,oldt2; i = 0; //初始化开启触摸屏 touchscreen_fd = open(TOUCHSCREEN_DEV, O_RDONLY); if (touchscreen_fd < 0) { fprintf (stderr, "Cannot open touch screen device [%s].\n", TOUCHSCREEN_DEV); return -1; } else { fprintf (stderr, "the touch screen device [%s]is opened.\n", TOUCHSCREEN_DEV); fprintf (stderr, "please touch the screen to test the driver is working \n"); } //读点直至抬起 i=0; while(1) { printf("begin cal!\n"); cal_data_avg(touchscreen_fd, &ts_CalPoint, 6); if(ts_CalPoint.pressure==1) { newp1.x=ts_CalPoint.x; newp1.y=ts_CalPoint.y; newt1.tv_sec=ts_CalPoint.time.tv_sec; newt1.tv_usec=ts_CalPoint.time.tv_usec; } else if(ts_CalPoint.pressure==0) { if(i==0) { newp1.x=ts_CalPoint.x; newp1.y=ts_CalPoint.y; newp2.x=ts_CalPoint.x; newp2.y=ts_CalPoint.y; newt1.tv_sec=ts_CalPoint.time.tv_sec; newt1.tv_usec=ts_CalPoint.time.tv_usec; newt2.tv_sec=ts_CalPoint.time.tv_sec; newt2.tv_usec=ts_CalPoint.time.tv_usec; break; } else { newp2.x=ts_CalPoint.x; newp2.y=ts_CalPoint.y; newt2.tv_sec=ts_CalPoint.time.tv_sec; newt2.tv_usec=ts_CalPoint.time.tv_usec; break; } } i++; } //产生操作类型 copy_time(&ret->time,&newt1); copy_point(&ret->pos_start,&newp1); copy_point(&ret->pos_end,&newp2); ret->type=TS_RESERVE; if(support_dc) {/*有双击功能*/ printf("newt1.tv_sec=%d,tv_usec=%d\n",newt1.tv_sec,newt1.tv_usec); printf("oldt2.tv_sec=%d,tv_usec=%d\n",oldt2.tv_sec,oldt2.tv_usec); if(firstFlg||!IsSmallTime(&oldt2,&newt1)) { switch(analize_type(&newp1,&newp2)) { case UP: ret->type=TS_UP; break; case DOWN: ret->type=TS_DOWN; break; case LEFT: ret->type=TS_LEFT; break; case RIGHT: ret->type=TS_RIGHT; break; case STAY: ret->type=TS_CLICK; break; } copy_time(&oldt1,&newt1); copy_time(&oldt2,&newt2); firstFlg=0; } else { ret->type=TS_DCLICK; firstFlg=1; } } else {/*无双击功能*/ switch(analize_type(&newp1,&newp2)) { case UP: ret->type=TS_UP; break; case DOWN: ret->type=TS_DOWN; break; case LEFT: ret->type=TS_LEFT; break; case RIGHT: ret->type=TS_RIGHT; break; case STAY: ret->type=TS_CLICK; break; } firstFlg=1; } //关闭触摸屏 close(touchscreen_fd); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -