Skip to content

Commit 74e50e7

Browse files
committed
tslib.c: add support for devices with ABS_X only
I.e.: full single touch device support
1 parent fd8c10e commit 74e50e7

File tree

1 file changed

+97
-36
lines changed

1 file changed

+97
-36
lines changed

src/tslib.c

Lines changed: 97 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747

4848
#include <sys/time.h>
4949
#include <time.h>
50+
#include <stdint.h>
5051

5152
#if defined (__FreeBSD__)
5253
#include <dev/evdev/input.h>
@@ -77,6 +78,8 @@ struct ts_priv {
7778
int width;
7879
struct ts_sample last;
7980
ValuatorMask *valuators;
81+
int8_t abs_x_only;
82+
8083
#ifdef TSLIB_VERSION_MT
8184
struct ts_sample_mt **samp_mt;
8285
struct ts_sample_mt *last_mt;
@@ -248,29 +251,43 @@ static int xf86TslibControlProc(DeviceIntPtr device, int what)
248251

249252
axiswidth = priv->width;
250253
axisheight = priv->height;
251-
252-
/* TODO
253-
one unified touch init that both read function can work with.
254-
at first ABS_MT_POS X/Y only!
255-
later ABS_X handling like evdev does
256-
*/
257-
InitValuatorAxisStruct(device, 0,
258-
XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_POSITION_X),
259-
0, /* min val */
260-
axiswidth - 1, /* max val */
261-
axiswidth, /* resolution */
262-
0, /* min_res */
263-
axiswidth, /* max_res */
264-
Absolute);
265-
266-
InitValuatorAxisStruct(device, 1,
267-
XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_POSITION_Y),
268-
0, /* min val */
269-
axisheight - 1, /* max val */
270-
axisheight, /* resolution */
271-
0, /* min_res */
272-
axisheight, /* max_res */
273-
Absolute);
254+
if (priv->abs_x_only) {
255+
InitValuatorAxisStruct(device, 0,
256+
XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X),
257+
0, /* min val */
258+
axiswidth - 1, /* max val */
259+
axiswidth, /* resolution */
260+
0, /* min_res */
261+
axiswidth, /* max_res */
262+
Absolute);
263+
264+
InitValuatorAxisStruct(device, 1,
265+
XIGetKnownProperty(AXIS_LABEL_PROP_ABS_Y),
266+
0, /* min val */
267+
axisheight - 1, /* max val */
268+
axisheight, /* resolution */
269+
0, /* min_res */
270+
axisheight, /* max_res */
271+
Absolute);
272+
} else {
273+
InitValuatorAxisStruct(device, 0,
274+
XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_POSITION_X),
275+
0, /* min val */
276+
axiswidth - 1, /* max val */
277+
axiswidth, /* resolution */
278+
0, /* min_res */
279+
axiswidth, /* max_res */
280+
Absolute);
281+
282+
InitValuatorAxisStruct(device, 1,
283+
XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_POSITION_Y),
284+
0, /* min val */
285+
axisheight - 1, /* max val */
286+
axisheight, /* resolution */
287+
0, /* min_res */
288+
axisheight, /* max_res */
289+
Absolute);
290+
}
274291

275292
if (InitTouchClassDeviceStruct(device,
276293
TOUCH_MAX_SLOTS,
@@ -328,16 +345,29 @@ xf86TslibUninit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
328345
xf86DeleteInput(pInfo, 0);
329346
}
330347

348+
#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
349+
#define BIT(nr) (1UL << (nr))
350+
#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
351+
#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
352+
#define BITS_PER_BYTE 8
353+
#define BITS_PER_LONG (sizeof(long) * BITS_PER_BYTE)
354+
#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
355+
356+
#ifndef ABS_CNT /* < 2.6.24 kernel headers */
357+
# define ABS_CNT (ABS_MAX+1)
358+
#endif
359+
331360
static int xf86TslibInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
332361
{
333362
struct ts_priv *priv;
334363
char *s;
335364
int i;
336-
struct input_absinfo abs_mt_x;
337-
struct input_absinfo abs_mt_y;
365+
struct input_absinfo abs_x;
366+
struct input_absinfo abs_y;
338367
#ifdef TSLIB_VERSION_MT
339368
struct ts_lib_version_data *ver = ts_libversion();
340369
#endif
370+
long absbit[BITS_TO_LONGS(ABS_CNT)];
341371

342372
priv = calloc(1, sizeof (struct ts_priv));
343373
if (!priv)
@@ -381,17 +411,6 @@ static int xf86TslibInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
381411

382412
pInfo->fd = ts_fd(priv->ts);
383413

384-
if (ioctl(pInfo->fd, EVIOCGABS(ABS_MT_POSITION_X), &abs_mt_x) < 0) {
385-
xf86IDrvMsg(pInfo, X_ERROR, "ioctl EVIOGABS failed");
386-
return BadValue;
387-
}
388-
if (ioctl(pInfo->fd, EVIOCGABS(ABS_MT_POSITION_Y), &abs_mt_y) < 0) {
389-
xf86IDrvMsg(pInfo, X_ERROR, "ioctl EVIOGABS failed");
390-
return BadValue;
391-
}
392-
priv->width = abs_mt_x.maximum;
393-
priv->height = abs_mt_y.maximum;
394-
395414
/* process generic options */
396415
xf86CollectInputOptions(pInfo, NULL);
397416
xf86ProcessCommonOptions(pInfo, pInfo->options);
@@ -417,6 +436,48 @@ static int xf86TslibInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
417436

418437
#endif /* TSLIB_VERSION_MT */
419438

439+
if (ioctl(pInfo->fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit) < 0) {
440+
xf86IDrvMsg(pInfo, X_ERROR, "ioctl EVIOCGBIT failed");
441+
return BadValue;
442+
}
443+
444+
if (!(absbit[BIT_WORD(ABS_MT_POSITION_X)] & BIT_MASK(ABS_MT_POSITION_X)) ||
445+
!(absbit[BIT_WORD(ABS_MT_POSITION_Y)] & BIT_MASK(ABS_MT_POSITION_Y))) {
446+
if (!(absbit[BIT_WORD(ABS_X)] & BIT_MASK(ABS_X)) ||
447+
!(absbit[BIT_WORD(ABS_Y)] & BIT_MASK(ABS_Y))) {
448+
xf86IDrvMsg(pInfo, X_ERROR, "no touchscreen device");
449+
return BadValue;
450+
} else {
451+
priv->abs_x_only = 1;
452+
}
453+
} else {
454+
priv->abs_x_only = 0;
455+
}
456+
457+
if (priv->abs_x_only) {
458+
if (ioctl(pInfo->fd, EVIOCGABS(ABS_X), &abs_x) < 0) {
459+
xf86IDrvMsg(pInfo, X_ERROR, "ioctl EVIOGABS failed");
460+
return BadValue;
461+
}
462+
if (ioctl(pInfo->fd, EVIOCGABS(ABS_Y), &abs_y) < 0) {
463+
xf86IDrvMsg(pInfo, X_ERROR, "ioctl EVIOGABS failed");
464+
return BadValue;
465+
}
466+
priv->width = abs_x.maximum;
467+
priv->height = abs_y.maximum;
468+
} else {
469+
if (ioctl(pInfo->fd, EVIOCGABS(ABS_MT_POSITION_X), &abs_x) < 0) {
470+
xf86IDrvMsg(pInfo, X_ERROR, "ioctl EVIOGABS failed");
471+
return BadValue;
472+
}
473+
if (ioctl(pInfo->fd, EVIOCGABS(ABS_MT_POSITION_Y), &abs_y) < 0) {
474+
xf86IDrvMsg(pInfo, X_ERROR, "ioctl EVIOGABS failed");
475+
return BadValue;
476+
}
477+
priv->width = abs_x.maximum;
478+
priv->height = abs_y.maximum;
479+
}
480+
420481
/* Return the configured device */
421482
return Success;
422483
}

0 commit comments

Comments
 (0)