dd56fb17b5
in various configurations.
198 lines
5.4 KiB
C
198 lines
5.4 KiB
C
/*
|
|
* TSLIB based touchscreen driver for KDrive
|
|
* Porting to new input API and event queueing by Daniel Stone.
|
|
* Derived from ts.c by Keith Packard
|
|
* Derived from ps2.c by Jim Gettys
|
|
*
|
|
* Copyright © 1999 Keith Packard
|
|
* Copyright © 2000 Compaq Computer Corporation
|
|
* Copyright © 2002 MontaVista Software Inc.
|
|
* Copyright © 2005 OpenedHand Ltd.
|
|
* Copyright © 2006 Nokia Corporation
|
|
*
|
|
* Permission to use, copy, modify, distribute, and sell this software and its
|
|
* documentation for any purpose is hereby granted without fee, provided that
|
|
* the above copyright notice appear in all copies and that both that
|
|
* copyright notice and this permission notice appear in supporting
|
|
* documentation, and that the name of the authors and/or copyright holders
|
|
* not be used in advertising or publicity pertaining to distribution of the
|
|
* software without specific, written prior permission. The authors and/or
|
|
* copyright holders make no representations about the suitability of this
|
|
* software for any purpose. It is provided "as is" without express or
|
|
* implied warranty.
|
|
*
|
|
* THE AUTHORS AND/OR COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD
|
|
* TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
* AND FITNESS, IN NO EVENT SHALL THE AUTHORS AND/OR COPYRIGHT HOLDERS BE
|
|
* LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
*/
|
|
|
|
|
|
#ifdef HAVE_KDRIVE_CONFIG_H
|
|
#include <kdrive-config.h>
|
|
#endif
|
|
|
|
#include <X11/X.h>
|
|
#include <X11/Xproto.h>
|
|
#include <X11/Xpoll.h>
|
|
#include "inputstr.h"
|
|
#include "scrnintstr.h"
|
|
#include "kdrive.h"
|
|
#include <sys/ioctl.h>
|
|
#include <tslib.h>
|
|
#include <dirent.h>
|
|
#include <linux/input.h>
|
|
|
|
struct TslibPrivate {
|
|
int fd;
|
|
int lastx, lasty;
|
|
struct tsdev *tsDev;
|
|
void (*raw_event_hook)(int x, int y, int pressure, void *closure);
|
|
void *raw_event_closure;
|
|
int phys_screen;
|
|
};
|
|
|
|
|
|
static void
|
|
TsRead (int fd, void *closure)
|
|
{
|
|
KdPointerInfo *pi = closure;
|
|
struct TslibPrivate *private = pi->driverPrivate;
|
|
struct ts_sample event;
|
|
long x = 0, y = 0;
|
|
unsigned long flags;
|
|
|
|
if (private->raw_event_hook) {
|
|
while (ts_read_raw(private->tsDev, &event, 1) == 1)
|
|
private->raw_event_hook (event.x, event.y, event.pressure,
|
|
private->raw_event_closure);
|
|
return;
|
|
}
|
|
|
|
while (ts_read(private->tsDev, &event, 1) == 1) {
|
|
if (event.pressure) {
|
|
flags = KD_BUTTON_1;
|
|
|
|
/*
|
|
* Here we test for the touch screen driver actually being on the
|
|
* touch screen, if it is we send absolute coordinates. If not,
|
|
* then we send delta's so that we can track the entire vga screen.
|
|
*/
|
|
if (KdCurScreen == private->phys_screen) {
|
|
x = event.x;
|
|
y = event.y;
|
|
} else {
|
|
flags |= KD_MOUSE_DELTA;
|
|
if ((private->lastx == 0) || (private->lasty == 0)) {
|
|
x = event.x;
|
|
y = event.y;
|
|
} else {
|
|
x = event.x - private->lastx;
|
|
y = event.y - private->lasty;
|
|
}
|
|
}
|
|
private->lastx = event.x;
|
|
private->lasty = event.y;
|
|
} else {
|
|
flags = 0;
|
|
x = private->lastx;
|
|
y = private->lasty;
|
|
}
|
|
|
|
KdEnqueuePointerEvent (pi, flags, x, y, event.pressure);
|
|
}
|
|
}
|
|
|
|
static Status
|
|
TslibEnable (KdPointerInfo *pi)
|
|
{
|
|
struct TslibPrivate *private = pi->driverPrivate;
|
|
|
|
private->raw_event_hook = NULL;
|
|
private->raw_event_closure = NULL;
|
|
if (!pi->path) {
|
|
pi->path = strdup("/dev/input/touchscreen0");
|
|
ErrorF("[tslib/TslibEnable] no device path given, trying %s\n", pi->path);
|
|
}
|
|
|
|
private->tsDev = ts_open(pi->path, 0);
|
|
if (!private->tsDev) {
|
|
ErrorF("[tslib/TslibEnable] failed to open %s\n", pi->path);
|
|
return BadAlloc;
|
|
}
|
|
|
|
if (ts_config(private->tsDev)) {
|
|
ErrorF("[tslib/TslibEnable] failed to load configuration\n");
|
|
ts_close(private->tsDev);
|
|
private->tsDev = NULL;
|
|
return BadValue;
|
|
}
|
|
|
|
private->fd = ts_fd(private->tsDev);
|
|
|
|
KdRegisterFd(private->fd, TsRead, pi);
|
|
|
|
return Success;
|
|
}
|
|
|
|
|
|
static void
|
|
TslibDisable (KdPointerInfo *pi)
|
|
{
|
|
struct TslibPrivate *private = pi->driverPrivate;
|
|
|
|
if (private->fd)
|
|
KdUnregisterFd(pi, private->fd, TRUE);
|
|
|
|
if (private->tsDev)
|
|
ts_close(private->tsDev);
|
|
|
|
private->fd = 0;
|
|
private->tsDev = NULL;
|
|
}
|
|
|
|
|
|
static Status
|
|
TslibInit (KdPointerInfo *pi)
|
|
{
|
|
struct TslibPrivate *private = NULL;
|
|
|
|
if (!pi || !pi->dixdev)
|
|
return !Success;
|
|
|
|
pi->driverPrivate = (struct TslibPrivate *)
|
|
calloc(sizeof(struct TslibPrivate), 1);
|
|
if (!pi->driverPrivate)
|
|
return !Success;
|
|
|
|
private = pi->driverPrivate;
|
|
/* hacktastic */
|
|
private->phys_screen = 0;
|
|
pi->nAxes = 3;
|
|
pi->name = strdup("Touchscreen");
|
|
pi->inputClass = KD_TOUCHSCREEN;
|
|
|
|
return Success;
|
|
}
|
|
|
|
|
|
static void
|
|
TslibFini (KdPointerInfo *pi)
|
|
{
|
|
free(pi->driverPrivate);
|
|
pi->driverPrivate = NULL;
|
|
}
|
|
|
|
|
|
KdPointerDriver TsDriver = {
|
|
"tslib",
|
|
TslibInit,
|
|
TslibEnable,
|
|
TslibDisable,
|
|
TslibFini,
|
|
NULL,
|
|
};
|