以前做过将红外触摸框的触摸事件进行简单的输入子系统获取,使用的是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
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\n"); 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\n"); 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\n", name); 122 //printf("name: %s\n", 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\n",event.getX());
printf("Y = %d\n",event.getY());
}
return 0;
}
时间: 2024-12-07 16:16:13