|
|
7e0df9 |
|
|
|
7e0df9 |
#include "touch.h"
|
|
|
7e0df9 |
|
|
|
7e0df9 |
|
|
|
7e0df9 |
#ifndef DIRECT_TOUCH
|
|
|
7e0df9 |
|
|
|
7e0df9 |
|
|
|
7e0df9 |
int touchInit(Touch *touch, App *app, const char *dev) { return 0; }
|
|
|
7e0df9 |
void touchDeinit(Touch *touch) { }
|
|
|
7e0df9 |
int touchGet(Touch *touch, int *x, int *y, int *p) { return 0; }
|
|
|
7e0df9 |
|
|
|
7e0df9 |
|
|
|
7e0df9 |
#else // DIRECT_TOUCH
|
|
|
7e0df9 |
|
|
|
7e0df9 |
|
|
|
7e0df9 |
#include <math.h></math.h>
|
|
|
7e0df9 |
#include <mtdev.h></mtdev.h>
|
|
|
7e0df9 |
#include <stdio.h></stdio.h>
|
|
|
7e0df9 |
#include <unistd.h></unistd.h>
|
|
|
7e0df9 |
#include <fcntl.h></fcntl.h>
|
|
|
7e0df9 |
|
|
|
7e0df9 |
|
|
|
7e0df9 |
|
|
|
7e0df9 |
static int touch_field_codes[TOUCH_FIELDS] =
|
|
|
7e0df9 |
{ ABS_MT_POSITION_X, ABS_MT_POSITION_Y, ABS_MT_PRESSURE };
|
|
|
7e0df9 |
|
|
|
7e0df9 |
|
|
|
7e0df9 |
int touchInit(Touch *touch, App *app, const char *dev) {
|
|
|
7e0df9 |
if (!app || !dev) return 0;
|
|
|
7e0df9 |
LOGDBG("touch: init");
|
|
|
7e0df9 |
|
|
|
7e0df9 |
touch->fd = open(dev, O_RDONLY | O_NONBLOCK);
|
|
|
7e0df9 |
if (touch->fd < 0)
|
|
|
7e0df9 |
return LOGERR("touch: init: cannot open file: %s", dev);
|
|
|
7e0df9 |
|
|
|
7e0df9 |
int ret = mtdev_open(&touch->dev, touch->fd);
|
|
|
7e0df9 |
if (ret) {
|
|
|
7e0df9 |
close(touch->fd);
|
|
|
7e0df9 |
touch->fd = 0;
|
|
|
7e0df9 |
return LOGERR("touch: init: cannot open device: %s", dev);
|
|
|
7e0df9 |
}
|
|
|
7e0df9 |
|
|
|
7e0df9 |
for(int i = 0; i < TOUCH_FIELDS; ++i) {
|
|
|
7e0df9 |
int *f = touch->fields[i];
|
|
|
7e0df9 |
f[0] = mtdev_get_abs_minimum(&touch->dev, touch_field_codes[i]);
|
|
|
7e0df9 |
f[1] = mtdev_get_abs_maximum(&touch->dev, touch_field_codes[i]);
|
|
|
7e0df9 |
if (f[0] >= f[1]) {
|
|
|
7e0df9 |
mtdev_close(&touch->dev);
|
|
|
7e0df9 |
close(touch->fd);
|
|
|
7e0df9 |
return LOGERR("touch: init: cannot get field bounds for device: %s (field %d:%d)", dev, i, touch_field_codes[i]);
|
|
|
7e0df9 |
}
|
|
|
7e0df9 |
f[2] = 0;
|
|
|
7e0df9 |
if (f[2] > f[1]) f[2] = f[1];
|
|
|
7e0df9 |
if (f[2] < f[0]) f[2] = f[0];
|
|
|
7e0df9 |
}
|
|
|
7e0df9 |
|
|
|
8603b4 |
touch->app = app;
|
|
|
8603b4 |
touch->slot = 0;
|
|
|
8603b4 |
touch->id = -1;
|
|
|
8603b4 |
touch->pressed = 0;
|
|
|
7e0df9 |
return 1;
|
|
|
7e0df9 |
}
|
|
|
7e0df9 |
|
|
|
7e0df9 |
|
|
|
7e0df9 |
void touchDeinit(Touch *touch) {
|
|
|
7e0df9 |
if (touch->app) {
|
|
|
7e0df9 |
mtdev_close(&touch->dev);
|
|
|
7e0df9 |
close(touch->fd);
|
|
|
7e0df9 |
}
|
|
|
7e0df9 |
touch->app = NULL;
|
|
|
7e0df9 |
}
|
|
|
7e0df9 |
|
|
|
7e0df9 |
|
|
|
7e0df9 |
int touchGet(Touch *touch, int *x, int *y, int *p) {
|
|
|
7e0df9 |
if (!touch->app) return 0;
|
|
|
7e0df9 |
|
|
|
7e0df9 |
struct input_event ev;
|
|
|
7e0df9 |
while(mtdev_get(&touch->dev, touch->fd, &ev, 1) > 0) {
|
|
|
7e0df9 |
if (ev.type == EV_SYN) {
|
|
|
7e0df9 |
// return event
|
|
|
7e0df9 |
double f[TOUCH_FIELDS];
|
|
|
7e0df9 |
for(int i = 0; i < TOUCH_FIELDS; ++i) {
|
|
|
7e0df9 |
int *tf = touch->fields[i];
|
|
|
7e0df9 |
f[i] = (tf[2] - tf[0])/(double)(tf[1] - tf[0]);
|
|
|
7e0df9 |
}
|
|
|
7e0df9 |
double fx = f[0], fy = f[1], fp = f[2];
|
|
|
7e0df9 |
|
|
|
7e0df9 |
App *app = touch->app;
|
|
|
7e0df9 |
if (app->sr & RR_Rotate_90)
|
|
|
7e0df9 |
{ double v = fx; fx = fy; fy = 1-v; }
|
|
|
7e0df9 |
if (app->sr & RR_Rotate_180)
|
|
|
7e0df9 |
{ fx = 1-fx; fy = 1-fy; }
|
|
|
7e0df9 |
if (app->sr & RR_Rotate_270)
|
|
|
7e0df9 |
{ double v = fx; fx = 1-fy; fy = v; }
|
|
|
7e0df9 |
if (app->sr & RR_Reflect_X)
|
|
|
7e0df9 |
fx = 1-fx;
|
|
|
7e0df9 |
if (app->sr & RR_Reflect_Y)
|
|
|
7e0df9 |
fy = 1-fy;
|
|
|
7e0df9 |
|
|
|
7e0df9 |
*x = (int)round(fx*app->sw - app->x);
|
|
|
7e0df9 |
*y = (int)round(fy*app->sh - app->y);
|
|
|
7e0df9 |
*p = touch->id >= 0 && fp > (touch->pressed ? TOUCH_THRESHOLD0 : TOUCH_THRESHOLD1);
|
|
|
7e0df9 |
touch->pressed = *p;
|
|
|
7e0df9 |
return 1;
|
|
|
7e0df9 |
}
|
|
|
7e0df9 |
|
|
|
7e0df9 |
if (ev.type != EV_ABS)
|
|
|
7e0df9 |
continue; // ignore non ABS events
|
|
|
7e0df9 |
|
|
|
7e0df9 |
if (ev.code == ABS_MT_SLOT)
|
|
|
7e0df9 |
{ touch->slot = ev.value; continue; } // switch slot
|
|
|
7e0df9 |
if (touch->slot != 0)
|
|
|
7e0df9 |
continue; // handle only first slot
|
|
|
7e0df9 |
|
|
|
7e0df9 |
if (ev.code == ABS_MT_TRACKING_ID)
|
|
|
7e0df9 |
{ touch->id = ev.value; continue; } // set track id
|
|
|
7e0df9 |
|
|
|
7e0df9 |
for(int i = 0; i < TOUCH_FIELDS; ++i)
|
|
|
7e0df9 |
if (ev.code == touch_field_codes[i])
|
|
|
7e0df9 |
touch->fields[i][2] = ev.value;
|
|
|
7e0df9 |
}
|
|
|
7e0df9 |
|
|
|
7e0df9 |
return 0;
|
|
|
7e0df9 |
}
|
|
|
7e0df9 |
|
|
|
7e0df9 |
|
|
|
7e0df9 |
#endif // DIRECT_TOUCH
|