自定义触摸事件封装

  版权声明:本文为博主原创文章,未经博主允许不得转载。 http://www.cnblogs.com/winfu

  以前做过将红外触摸框的触摸事件进行简单的输入子系统获取,使用的是C语言,这次特地将以前的C封装为C++类,这样使用起来相对方便。该触摸事件采用了andrdoid操作事件的思想,采用多线程一个负责读取事件,一个负责分发事件,在类中采用了线程,使用的是linux的pthread_create函数,在类中线程函数我采用的是友元函数的方式。

  inputEvent.h 代码如下:

 1 #ifndef INPUTEVENT_H
 2 #define INPUTEVENT_H
 3 
 4 #include "gui.h"
 5 #include <linux/input.h>
 6 #include <stdio.h>
 7 #include <pthread.h>
 8 #include <stdlib.h>
 9 #include <sys/types.h>
10 #include <string.h>
11 #include <sys/stat.h>
12 #include <fcntl.h>
13 #include <linux/fb.h>
14 #include <sys/ioctl.h>
15 
16 using namespace android; 
17 
18 class InputEvent 
19 {
20 public:
21     InputEvent(void);
22     
23     int xScaleyScale(void); //显示屏幕和触摸屏幕比列关系
24 
25     int getTouchEventNum() ; // 触摸框事件数列
26 
27     friend void* readInput(void *data); //读取事件线程
28     
29     friend void* dispatchInput(void *data); //分发事件线程
30         
31     float getX(void); //获取x坐标
32     
33     float getY(void); //获取y坐标
34     
35     float getW(void); //获取触摸宽度
36     
37     float getH(void); //获取触摸高度
38     
39     int getDown(void); //按下
40     
41     int getUp(void); //抬起
42     
43 private:
44     //LCD和触摸框转换比例
45     float xScale;
46     float yScale;
47     
48     int fd ; // dev的文件描述符
49     int fds[2];  //管道
50     
51     float x; //x坐标
52     float y; //y坐标
53     int pressure; //按下
54     float touchMajor; //宽触摸
55     float touchMinor; //高触摸
56     int down,up; // 按下,抬起
57 };
58 #endi

gui.h头文件:

 1 #ifndef GUI_H
 2 #define GUI_H
 3 
 4 #include <cutils/memory.h>    
 5 #include <unistd.h>  
 6 #include <utils/Log.h>  
 7 #include <binder/IPCThreadState.h>  
 8 #include <binder/ProcessState.h>  
 9 #include <binder/IServiceManager.h>  
10 #include <gui/SurfaceComposerClient.h>  
11 #include <gui/ISurfaceComposer.h>  
12 #include <ui/DisplayInfo.h>  
13 #include <ui/Rect.h>  
14 #include <ui/Region.h>  
15 #include <android/native_window.h>  
16 #include <SkGraphics.h>  
17 #include <SkBitmap.h>  
18 #include <SkCanvas.h>  
19 #include <SkDevice.h>  
20 #include <SkStream.h>  
21 #include <SkImageDecoder.h>   
22 #include <hardware/hwcomposer_defs.h>  
23 #include <errno.h>
24 #include <sys/mman.h>
25 #include <binder/IMemory.h>
26 #include <SkImageEncoder.h>
27 #include <SkData.h>
28 
29 #endif
View Code

inputEvent.cpp

  1 #include "inputEvent.h"
  2 
  3 void* readInput(void *data)  //读取事件线程
  4 {
  5     InputEvent *ev = (InputEvent*)data;
  6     struct input_event inputEvent;
  7     while(1)
  8     {
  9         read(ev->fd, &inputEvent, sizeof(struct input_event));
 10         // 向管道中写数据
 11         write(ev->fds[1], &inputEvent, sizeof(struct input_event));
 12     }
 13     return NULL;
 14 }
 15 void* dispatchInput(void *data)  //分发事件线程
 16 {
 17     InputEvent *ev = (InputEvent*)data;
 18     struct input_event inputEvent;
 19     while(1)
 20     {
 21         //从管道中读取数据
 22         read(ev->fds[0], &inputEvent, sizeof(struct input_event));
 23         
 24         if(inputEvent.type == EV_ABS && inputEvent.code == ABS_X ){
 25             float fv = inputEvent.value * 1.0;
 26             ev->x = fv * ev->xScale;
 27             continue;
 28         }
 29         if(inputEvent.type == EV_ABS && inputEvent.code == ABS_Y ){
 30              float fv = inputEvent.value * 1.0;
 31              ev->y = fv * ev->yScale;
 32              continue;
 33         }
 34         if(inputEvent.type == EV_KEY && inputEvent.code == BTN_TOUCH ){
 35             ev->pressure = inputEvent.value;
 36             if(1 == ev->pressure )
 37             {
 38                 ev->down = 1;
 39                 ev->up = 0;
 40             }
 41             else if(0 == ev->pressure)
 42             {
 43                 ev->up  = 1;
 44                 ev->down = 0;
 45             }
 46             continue;
 47         }
 48         //增加flag的判断作用是touchMajor和toushMinor事件在pressure事件之前的比较准确
 49         if(inputEvent.type == EV_ABS && inputEvent.code == ABS_MT_TOUCH_MAJOR ){
 50              float fv = inputEvent.value * 1.0;
 51              ev->touchMajor = fv * 10; //10  = 0x4000 / 1920
 52              continue;
 53         }
 54         
 55         if(inputEvent.type == EV_ABS && inputEvent.code == ABS_MT_TOUCH_MINOR ){
 56             float fv = inputEvent.value * 1.0;
 57             ev->touchMinor = fv * 18;  //18  15 = 0x4000 / 1080;
 58             continue;
 59         }
 60     }
 61     return NULL;
 62 }
 63 
 64 InputEvent::InputEvent(void) 
 65 {
 66     int num = getTouchEventNum();
 67     if( num == -1)
 68     {
 69         printf("No Touch Event
");
 70         return ;
 71     }
 72     char name[64];
 73     sprintf(name, "/dev/input/event%d", num);
 74     fd = open(name, O_RDWR);
 75     if(fd < 0)
 76     {
 77         printf("Open dev Error");
 78         return ;
 79     }
 80     
 81     xScaleyScale();//初始化xy坐标的比例关系
 82     
 83     //创建无名管道
 84     if(-1 == pipe(fds))
 85     {
 86         printf("pipe
");
 87         exit(-1);
 88     }
 89     pthread_t readId, disPatchId; 
 90     pthread_create(&readId, NULL, readInput, (void*)this);
 91     pthread_create(&disPatchId, NULL, dispatchInput, (void*)this);
 92     return ;
 93 }
 94 int InputEvent::xScaleyScale(void)  //显示屏幕和触摸屏幕比列关系
 95 {
 96     sp<SurfaceComposerClient> surfaceComposerClient = new SurfaceComposerClient();  //创建SurfaceFlinger的本地代理
 97     DisplayInfo displayInfo;  
 98     //获取屏幕的宽高等信息
 99     surfaceComposerClient->getDisplayInfo(surfaceComposerClient->getBuiltInDisplay(HWC_DISPLAY_PRIMARY), &displayInfo); 
100     xScale = displayInfo.w / 32768.0;
101     yScale = displayInfo.h / 32768.0;
102     return 0;
103 }
104 int InputEvent::getTouchEventNum()   // 触摸框事件数列
105 {
106     char  name[64];       /* RATS: Use ok, but could be better */  
107     char  buf[256] = { 0, };  /* RATS: Use ok */  
108     int   fd = 0;   
109     int   i;    
110     for (i = 0; i < 32; i++) 
111     {  
112         sprintf(name, "/dev/input/event%d", i);  
113         if ((fd = open(name, O_RDONLY, 0)) >= 0) 
114         {  
115             ioctl(fd, EVIOCGNAME(sizeof(buf)), buf);   
116             if(strstr(buf, "MTOUC Touch"))
117             {
118                 close(fd);
119                 return i;
120             }
121             //printf("%s
", name);  
122             //printf("name: %s
", buf);           
123             close(fd);  
124         }
125     }
126     return -1;
127 }
128 
129 float InputEvent::getX(void)  //获取x坐标
130 {
131     return this->x;
132 }
133 float InputEvent::getY(void)  //获取y坐标
134 {
135     return this->y;
136 }
137 float InputEvent::getW(void)  //获取触摸宽度
138 {
139     return this->touchMajor;
140 }
141 float InputEvent::getH(void)  //获取触摸高度
142 {
143     return this->touchMinor;
144 }
145 int InputEvent::getDown(void)  //按下
146 {
147     return this->down;
148 }
149 int InputEvent::getUp(void)  //抬起
150 {
151     return this->up;
152 }

其中gui.h是一些android显示图像的头文件。

测试代码简单:

int main (int argc, char** argv)  

  InputEvent event;

  while(1){

    printf("X = %d ",event.getX());

    printf("Y = %d ",event.getY());

  }

  return 0;  

}

原文地址:https://www.cnblogs.com/winfu/p/5750414.html