前提条件:按键事件与触摸事件为同一个事件
问题现象:按虚拟按键后再按触摸屏幕范围,位置报错
源码分析
源码修改:
static int ts_input_read(struct tslib_module_info *inf,
struct ts_sample *samp, int nr)
{
struct tslib_input *i = (struct tslib_input *)inf;
struct tsdev *ts = inf->dev;
struct input_event ev;
int ret = nr;
int total = 0;
int pen_up = 0;
if (ts->fd != i->last_fd)
i->last_fd = check_fd(i);
if (i->last_fd == -1)
return -ENODEV;
if (i->no_pressure)
set_pressure(i);
if (i->using_syn) {
while (total < nr) {
ret = read(ts->fd, &ev, sizeof(struct input_event));
if (ret < (int)sizeof(struct input_event)) {
total = -1;
break;
}
switch (ev.type) {
case EV_KEY:
switch (ev.code) {
case BTN_TOUCH:
case BTN_LEFT:
pen_up = 1; // lyp改
// if (ev.value == 0)
// pen_up = 1;
break;
}
break;
case EV_SYN:
if (ev.code == SYN_REPORT) {
/* Fill out a new complete event */
if (pen_up) {
samp->x = 0;
samp->y = 0;
samp->pressure = 0;
pen_up = 0;
} else {
samp->x = i->current_x;
samp->y = i->current_y;
samp->pressure = i->current_p;
}
samp->tv = ev.time;
#ifdef DEBUG
fprintf(stderr,
"RAW---------------------> %d %d %d %ld.%ld\n",
samp->x, samp->y, samp->pressure,
(long)samp->tv.tv_sec,
(long)samp->tv.tv_usec);
#endif /* DEBUG */
samp++;
total++;
} else if (ev.code == SYN_MT_REPORT) {
if (!i->type_a)
break;
if (i->type_a == 1) { /* no data: pen-up */
pen_up = 1;
} else {
i->type_a = 1;
}
#ifdef DEBUG
} else if (ev.code == SYN_DROPPED) {
fprintf(stderr,
"INPUT-RAW: SYN_DROPPED\n");
#endif
}
break;
case EV_ABS:
if (i->special_device == EGALAX_VERSION_210) {
switch (ev.code) {
case ABS_X:
i->current_x = ev.value;
break;
case ABS_Y:
i->current_y = ev.value;
break;
case ABS_PRESSURE:
i->current_p = ev.value;
break;
case ABS_MT_DISTANCE:
if (ev.value > 0)
i->current_p = 0;
else
i->current_p = 255;
break;
}
} else {
switch (ev.code) {
case ABS_X:
i->current_x = ev.value;
break;
case ABS_Y:
i->current_y = ev.value;
break;
case ABS_MT_POSITION_X:
i->current_x = ev.value;
i->type_a++;
break;
case ABS_MT_POSITION_Y:
i->current_y = ev.value;
i->type_a++;
break;
case ABS_PRESSURE:
i->current_p = ev.value;
break;
case ABS_MT_PRESSURE:
i->current_p = ev.value;
break;
case ABS_MT_TOUCH_MAJOR:
if (ev.value == 0)
i->current_p = 0;
break;
case ABS_MT_TRACKING_ID:
if (ev.value == -1)
i->current_p = 0;
break;
}
}
break;
}
}
ret = total;
} else {
unsigned char *p = (unsigned char *) &ev;
int len = sizeof(struct input_event);
while (total < nr) {
ret = read(ts->fd, p, len);
if (ret == -1) {
if (errno == EINTR)
continue;
break;
}
if (ret < (int)sizeof(struct input_event)) {
/* short read
* restart read to get the rest of the event
*/
p += ret;
len -= ret;
continue;
}
/* successful read of a whole event */
if (ev.type == EV_ABS) {
switch (ev.code) {
case ABS_X:
if (ev.value != 0) {
samp->x = i->current_x = ev.value;
samp->y = i->current_y;
samp->pressure = i->current_p;
} else {
fprintf(stderr,
"tslib: dropped x = 0\n");
continue;
}
break;
case ABS_Y:
if (ev.value != 0) {
samp->x = i->current_x;
samp->y = i->current_y = ev.value;
samp->pressure = i->current_p;
} else {
fprintf(stderr,
"tslib: dropped y = 0\n");
continue;
}
break;
case ABS_PRESSURE:
samp->x = i->current_x;
samp->y = i->current_y;
samp->pressure = i->current_p = ev.value;
break;
}
samp->tv = ev.time;
#ifdef DEBUG
fprintf(stderr,
"RAW---------------------------> %d %d %d\n",
samp->x, samp->y, samp->pressure);
#endif /* DEBUG */
samp++;
total++;
} else if (ev.type == EV_KEY) {
switch (ev.code) {
case BTN_TOUCH:
case BTN_LEFT:
if (ev.value == 0) {
/* pen up */
samp->x = 0;
samp->y = 0;
samp->pressure = 0;
samp->tv = ev.time;
samp++;
total++;
}
break;
}
} else {
fprintf(stderr,
"tslib: Unknown event type %d\n",
ev.type);
}
p = (unsigned char *) &ev;
}
fprintf(stdout,
"tslib: event type %d\n",
ev.type);
ret = total;
}
return ret;
}