2 * (C) GraÅžvydas "notaz" Ignotas, 2011
4 * This work is licensed under the terms of any of these licenses
6 * - GNU GPL, version 2 or later.
7 * - GNU LGPL, version 2.1 or later.
8 * See the COPYING file in the top-level directory.
15 #include "plugin_lib.h"
16 #include "pl_gun_ts.h"
18 #include "../plugins/dfinput/externals.h"
20 static int gun_x, gun_y, gun_in;
21 static int ts_multiplier_x, ts_multiplier_y, ts_offs_x, ts_offs_y;
22 static int (*pts_read)(struct tsdev *dev, struct ts_sample *sample, int nr);
23 static int (*pts_fd)(struct tsdev *dev);
25 #define limit(v, min, max) \
26 if (v < min) v = min; \
27 else if (v > max) v = max
29 int pl_gun_ts_update_raw(struct tsdev *ts, int *x, int *y, int *p)
31 struct ts_sample sample;
32 int sx = 0, sy = 0, sp = 0, updated = 0;
35 while (pts_read(ts, &sample, 1) > 0) {
43 gun_x = (sx - ts_offs_x) * ts_multiplier_x >> 10;
44 gun_y = (sy - ts_offs_y) * ts_multiplier_y >> 10;
45 limit(gun_x, 0, 1023);
46 limit(gun_y, 0, 1023);
47 if (sp && !(g_opts & OPT_TSGUN_NOTRIGGER))
48 gun_in |= GUNIN_TRIGGER;
50 gun_in &= ~GUNIN_TRIGGER;
64 /* returns x, y in range 0..1023 (normalized to visible layer) */
65 void pl_gun_ts_update(struct tsdev *ts, int *x, int *y, int *in)
67 pl_gun_ts_update_raw(ts, NULL, NULL, NULL);
71 *in = gun_in | in_state_gun;
74 void pl_set_gun_rect(int x, int y, int w, int h)
78 ts_multiplier_x = (1<<20) / w;
79 ts_multiplier_y = (1<<20) / h;
82 int pl_gun_ts_get_fd(struct tsdev *ts)
84 if (ts != NULL && pts_fd != NULL)
90 struct tsdev *pl_gun_ts_init(void)
92 struct tsdev *(*pts_open)(const char *dev_name, int nonblock) = NULL;
93 int (*pts_config)(struct tsdev *) = NULL;
94 int (*pts_close)(struct tsdev *) = NULL;
95 const char *tsdevname;
99 tsdevname = getenv("TSLIB_TSDEVICE");
100 if (tsdevname == NULL)
101 tsdevname = "/dev/input/touchscreen0";
103 // avoid hard dep on tslib
104 ltsh = dlopen("/usr/lib/libts-1.0.so.0", RTLD_NOW|RTLD_GLOBAL);
106 ltsh = dlopen("/usr/lib/libts-0.0.so.0", RTLD_NOW|RTLD_GLOBAL);
108 ltsh = dlopen("/lib/libts-0.0.so.0", RTLD_NOW|RTLD_GLOBAL);
110 fprintf(stderr, "%s\n", dlerror());
114 pts_open = dlsym(ltsh, "ts_open");
115 pts_config = dlsym(ltsh, "ts_config");
116 pts_read = dlsym(ltsh, "ts_read");
117 pts_fd = dlsym(ltsh, "ts_fd");
118 pts_close = dlsym(ltsh, "ts_close");
119 if (pts_open == NULL || pts_config == NULL || pts_read == NULL
120 || pts_fd == NULL || pts_close == NULL) {
121 fprintf(stderr, "%s\n", dlerror());
125 ts = pts_open(tsdevname, 1);
128 if (pts_config(ts) != 0)
131 // FIXME: we should be able to get this somewhere
132 // the problem is this doesn't always match resolution due to different display modes
133 #ifdef __ARM_ARCH_7A__
134 pl_set_gun_rect(0, 0, 800, 480);
136 pl_set_gun_rect(0, 0, 320, 240);
147 fprintf(stderr, "Could not open touchscreen\n");