#include <errno.h>
#include <linux/input.h>
#include <SDL/SDL.h>
+#if SDL_INPUT_TSLIB
+#include <tslib.h>
+#endif
#include "omapsdl.h"
+/* XXX: these should go to private data */
static int osdl_evdev_devs[32];
static int osdl_evdev_dev_count;
+static int osdl_tslib_fd;
+static struct tsdev *osdl_tslib_dev;
static short osdl_evdev_map[KEY_CNT] = {
[KEY_0] = SDLK_0,
void omapsdl_input_init(void)
{
long keybits[KEY_CNT / sizeof(long) / 8];
+ ino_t touchscreen_ino = (ino_t)-1;
+ struct stat stat_buf;
int i;
- // the kernel might support and return less keys then we know about,
- // so make sure the buffer is clear.
+#if SDL_INPUT_TSLIB
+ /* start with touchscreen so that we can skip it later */
+ osdl_tslib_dev = ts_open(SDL_getenv("TSLIB_TSDEVICE"), 1);
+ if (ts_config(osdl_tslib_dev) < 0) {
+ ts_close(osdl_tslib_dev);
+ osdl_tslib_dev = NULL;
+ }
+ if (osdl_tslib_dev != NULL) {
+ osdl_tslib_fd = ts_fd(osdl_tslib_dev);
+ osdl_evdev_devs[osdl_evdev_dev_count++] = osdl_tslib_fd;
+ if (fstat(osdl_tslib_fd, &stat_buf) == -1)
+ err_perror("fstat ts");
+ else
+ touchscreen_ino = stat_buf.st_ino;
+ log("opened tslib touchscreen");
+ }
+#endif
+
+ /* the kernel might support and return less keys then we know about,
+ * so make sure the buffer is clear. */
memset(keybits, 0, sizeof(keybits));
for (i = 0;; i++)
break;
}
+ /* touchscreen check */
+ if (touchscreen_ino != (dev_t)-1) {
+ if (fstat(fd, &stat_buf) == -1)
+ err_perror("fstat");
+ else if (touchscreen_ino == stat_buf.st_ino) {
+ log("skip %s as ts", name);
+ goto skip;
+ }
+ }
+
/* check supported events */
ret = ioctl(fd, EVIOCGBIT(0, sizeof(support)), &support);
if (ret == -1) {
- printf("in_evdev: ioctl failed on %s\n", name);
+ err_perror("in_evdev: ioctl failed on %s", name);
goto skip;
}
ret = ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybits)), keybits);
if (ret == -1) {
- printf("in_evdev: ioctl failed on %s\n", name);
+ err_perror("in_evdev: ioctl failed on %s", name);
goto skip;
}
osdl_evdev_devs[osdl_evdev_dev_count++] = fd;
ioctl(fd, EVIOCGNAME(sizeof(name)), name);
- printf("in_evdev: found \"%s\" with %d events (type %08x)\n",
+ log("in_evdev: found \"%s\" with %d events (type %08x)",
name, count, support);
continue;
close(fd);
}
- printf("found %d evdev devices.\n", osdl_evdev_dev_count);
+ log("found %d evdev device(s).", osdl_evdev_dev_count);
+}
+
+void omapsdl_input_finish(void)
+{
+ int i;
+
+#if SDL_INPUT_TSLIB
+ if (osdl_tslib_dev != NULL)
+ ts_close(osdl_tslib_dev);
+#endif
+ osdl_tslib_dev = NULL;
+
+ for (i = 0; i < osdl_evdev_dev_count; i++) {
+ if (osdl_evdev_devs[i] != osdl_tslib_fd)
+ close(osdl_evdev_devs[i]);
+ }
+ osdl_evdev_dev_count = 0;
+ osdl_tslib_fd = 0;
}
int omapsdl_input_get_events(int timeout_ms,
- int (*cb)(void *cb_arg, int sdl_kc, int is_pressed), void *cb_arg)
+ int (*key_cb)(void *cb_arg, int sdl_kc, int is_pressed),
+ int (*ts_cb)(void *cb_arg, int x, int y, unsigned int pressure),
+ void *cb_arg)
{
struct timeval tv, *timeout = NULL;
struct input_event ev;
ret = select(fdmax + 1, &fdset, NULL, NULL, timeout);
if (ret == -1)
{
- perror("in_evdev: select failed");
+ err_perror("in_evdev: select failed");
return -1;
}
else if (ret == 0)
continue;
fd = osdl_evdev_devs[i];
+#if SDL_INPUT_TSLIB
+ if (fd == osdl_tslib_fd && ts_cb != NULL) {
+ while (1) {
+ struct ts_sample tss;
+ ret = ts_read(osdl_tslib_dev, &tss, 1);
+ if (ret <= 0)
+ break;
+ ret = ts_cb(cb_arg, tss.x, tss.y, tss.pressure);
+ if (ret != 0)
+ return ret;
+ }
+ continue;
+ }
+ /* else read below will consume the event, even if it's from ts */
+#endif
+
while (1) {
ret = read(fd, &ev, sizeof(ev));
if (ret < (int)sizeof(ev)) {
if (errno != EAGAIN) {
- perror("in_evdev: read failed");
+ err_perror("in_evdev: read failed");
return -1;
}
break;
sdl_kc = osdl_evdev_map[ev.code];
if (sdl_kc == 0)
continue; /* not mapped */
- ret = cb(cb_arg, sdl_kc, ev.value);
+ ret = key_cb(cb_arg, sdl_kc, ev.value);
if (ret != 0)
return ret;
}
struct key_event ev;
int ret;
- ret = omapsdl_input_get_events(timeout, do_key_cb, &ev);
+ ret = omapsdl_input_get_events(timeout, do_key_cb, NULL, &ev);
if (ret < 0)
return 0;