20090826 Android上使用觸控面板(TouchScreen)模擬KeyEvent (二)
所以我們的Native Code就是從/dev/input裡面讀資料了,這是有標準寫法的,可以去搜尋evtest,這也是一個好物~Driver回報的時候,最後會使用SYNC Flag,而User Level程式在讀的時候也是這樣子,當Android層的Service呼叫c的ReadPointer時,c會進入一個無窮迴圈直到他讀到sync,如果沒資料就會被block住(Good,不佔用cpu),如果讀到Sync之後,Service就再透過jni去讀取c剛剛從driver讀到的x,y,touch。原理就是這麼簡單,下面是Code,MT的部份是為了支援Linux 2.6.30之後的Multitouch功能,目前用不到。
1: #include "ITRI_MTube_EventReader.h"
2: #define SYN_MT_REPORT 2
3:
4: #define ABS_MT_TOUCH_MAJOR 0x30 /* Major axis of touching ellipse */
5: #define ABS_MT_TOUCH_MINOR 0x31 /* Minor axis (omit if circular) */
6: #define ABS_MT_WIDTH_MAJOR 0x32 /* Major axis of approaching ellipse */
7: #define ABS_MT_WIDTH_MINOR 0x33 /* Minor axis (omit if circular) */
8: #define ABS_MT_ORIENTATION 0x34 /* Ellipse orientation */
9: #define ABS_MT_POSITION_X 0x35 /* Center X ellipse position */
10: #define ABS_MT_POSITION_Y 0x36 /* Center Y ellipse position */
11: #define ABS_MT_TOOL_TYPE 0x37 /* Type of touching device */
12: #define ABS_MT_BLOB_ID 0x38 /* Group a set of packets as a blob */
13: #define ABS_MT_TRACKING_ID 0x39 /* Unique ID of initiated contact */
14:
15:
16: #include <fcntl.h>
17: #include <linux/input.h>
18: #include <errno.h>
19: #include <math.h>
20:
21: static jint Id;
22: static jint X;
23: static jint Y;
24: static jint Touch;
25:
26:
27: JNIEXPORT jlong JNICALL Java_ITRI_MTube_EventReader_Add(JNIEnv *env, jclass c, jlong a, jlong b)
28: {
29: return a + b;
30: }
31:
32: JNIEXPORT jint JNICALL Java_ITRI_MTube_EventReader_ReadPointerTouch(JNIEnv *env, jclass c)
33: {
34: return Touch;
35: }
36:
37: JNIEXPORT jint JNICALL Java_ITRI_MTube_EventReader_ReadPointerX(JNIEnv *env, jclass c)
38: {
39: return X;
40: }
41:
42: JNIEXPORT jint JNICALL Java_ITRI_MTube_EventReader_ReadPointerY(JNIEnv *env, jclass c)
43: {
44: return Y;
45: }
46:
47: JNIEXPORT jint JNICALL Java_ITRI_MTube_EventReader_ReadPointer(JNIEnv *env, jclass c, jstring TSFD)
48: {
49:
50:
51: int fd, rd, i, j, k;
52: struct input_event ev[64];
53: int version;
54: unsigned short id[4];
55: char name[256] = "Unknown";
56: int abs[5];
57:
58: const jbyte *FD;
59: FD = (*env)->GetStringUTFChars(env, TSFD, NULL);
60: if (FD == NULL) {
61: return NULL; /* OutOfMemoryError already thrown */
62: }
63:
64: if ((fd = open(FD, O_RDWR)) < 0) {
65: (*env)->ReleaseStringUTFChars(env, TSFD, FD);
66: return -1;
67: }
68:
69: (*env)->ReleaseStringUTFChars(env, TSFD, FD);
70:
71:
72: ioctl(fd, EVIOCGNAME(sizeof(name)), name);
73: //printf("Input device name: \"%s\"\n", name);
74:
75: while(1)
76: {
77: //printf("Reading input from device ... (interrupt to exit)\n");
78: rd = read(fd, ev, sizeof(struct input_event) * 64);
79: if (rd < (int) sizeof(struct input_event)) {
80: perror("\nReadBlockEvent: error reading event");
81: return -2;
82: }
83: for (i = 0; i < rd / sizeof(struct input_event); i++)
84: {
85: if (ev[i].type == EV_SYN)
86: {
87: //We don't have multitouch device now.
88: if (SYN_MT_REPORT==ev[i].code)
89: { // MT_Sync : Multitouch event end
90: //sendpoint(&tmpP, &contactsNum);
91:
92: }
93: else if (SYN_REPORT==ev[i].code)
94: {
95: //printf("Read X:%d, Y:%d\n, Btn_Touch:%d",tmpP.x,tmpP.y,tmpP.btn_touch);
96: //Read a event
97: return 1;
98: }
99: }
100: else if (ev[i].type == EV_MSC && (ev[i].code == MSC_RAW || ev[i].code == MSC_SCAN))
101: { }
102: else
103: {
104: if (ev[i].code==ABS_MT_TRACKING_ID)
105: {
106: Id = ev[i].value;
107: }
108: else if (ev[i].code == ABS_MT_POSITION_X || ev[i].code == ABS_X)
109: X = ev[i].value;
110: else if (ev[i].code == ABS_MT_POSITION_Y || ev[i].code == ABS_Y)
111: Y = ev[i].value;
112: else if (ev[i].code ==BTN_TOUCH)
113: Touch = ev[i].value;
114: }
115: }
116: }
117:
118: return 0;
119: }
留言