1706f2543Smrg/*
2706f2543Smrg * TSLIB based touchscreen driver for KDrive
3706f2543Smrg * Porting to new input API and event queueing by Daniel Stone.
4706f2543Smrg * Derived from ts.c by Keith Packard
5706f2543Smrg * Derived from ps2.c by Jim Gettys
6706f2543Smrg *
7706f2543Smrg * Copyright � 1999 Keith Packard
8706f2543Smrg * Copyright � 2000 Compaq Computer Corporation
9706f2543Smrg * Copyright � 2002 MontaVista Software Inc.
10706f2543Smrg * Copyright � 2005 OpenedHand Ltd.
11706f2543Smrg * Copyright � 2006 Nokia Corporation
12706f2543Smrg *
13706f2543Smrg * Permission to use, copy, modify, distribute, and sell this software and its
14706f2543Smrg * documentation for any purpose is hereby granted without fee, provided that
15706f2543Smrg * the above copyright notice appear in all copies and that both that
16706f2543Smrg * copyright notice and this permission notice appear in supporting
17706f2543Smrg * documentation, and that the name of the authors and/or copyright holders
18706f2543Smrg * not be used in advertising or publicity pertaining to distribution of the
19706f2543Smrg * software without specific, written prior permission.  The authors and/or
20706f2543Smrg * copyright holders make no representations about the suitability of this
21706f2543Smrg * software for any purpose.  It is provided "as is" without express or
22706f2543Smrg * implied warranty.
23706f2543Smrg *
24706f2543Smrg * THE AUTHORS AND/OR COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD
25706f2543Smrg * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
26706f2543Smrg * AND FITNESS, IN NO EVENT SHALL THE AUTHORS AND/OR COPYRIGHT HOLDERS BE
27706f2543Smrg * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
28706f2543Smrg * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
29706f2543Smrg * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
30706f2543Smrg * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
31706f2543Smrg */
32706f2543Smrg
33706f2543Smrg
34706f2543Smrg#ifdef HAVE_KDRIVE_CONFIG_H
35706f2543Smrg#include <kdrive-config.h>
36706f2543Smrg#endif
37706f2543Smrg
38706f2543Smrg#include <X11/X.h>
39706f2543Smrg#include <X11/Xproto.h>
40706f2543Smrg#include <X11/Xpoll.h>
41706f2543Smrg#include "inputstr.h"
42706f2543Smrg#include "scrnintstr.h"
43706f2543Smrg#include "kdrive.h"
44706f2543Smrg#include <sys/ioctl.h>
45706f2543Smrg#include <tslib.h>
46706f2543Smrg#include <dirent.h>
47706f2543Smrg#include <linux/input.h>
48706f2543Smrg
49706f2543Smrgstruct TslibPrivate {
50706f2543Smrg    int fd;
51706f2543Smrg    int lastx, lasty;
52706f2543Smrg    struct tsdev *tsDev;
53706f2543Smrg    void (*raw_event_hook)(int x, int y, int pressure, void *closure);
54706f2543Smrg    void *raw_event_closure;
55706f2543Smrg    int phys_screen;
56706f2543Smrg};
57706f2543Smrg
58706f2543Smrg
59706f2543Smrgstatic void
60706f2543SmrgTsRead (int fd, void *closure)
61706f2543Smrg{
62706f2543Smrg    KdPointerInfo       *pi = closure;
63706f2543Smrg    struct TslibPrivate *private = pi->driverPrivate;
64706f2543Smrg    struct ts_sample    event;
65706f2543Smrg    long                x = 0, y = 0;
66706f2543Smrg    unsigned long       flags;
67706f2543Smrg
68706f2543Smrg    if (private->raw_event_hook) {
69706f2543Smrg        while (ts_read_raw(private->tsDev, &event, 1) == 1)
70706f2543Smrg            private->raw_event_hook (event.x, event.y, event.pressure,
71706f2543Smrg                                     private->raw_event_closure);
72706f2543Smrg        return;
73706f2543Smrg    }
74706f2543Smrg
75706f2543Smrg    while (ts_read(private->tsDev, &event, 1) == 1) {
76706f2543Smrg        if (event.pressure) {
77706f2543Smrg            flags = KD_BUTTON_1;
78706f2543Smrg
79706f2543Smrg            /*
80706f2543Smrg             * Here we test for the touch screen driver actually being on the
81706f2543Smrg             * touch screen, if it is we send absolute coordinates. If not,
82706f2543Smrg             * then we send delta's so that we can track the entire vga screen.
83706f2543Smrg             */
84706f2543Smrg            if (KdCurScreen == private->phys_screen) {
85706f2543Smrg                x = event.x;
86706f2543Smrg                y = event.y;
87706f2543Smrg            } else {
88706f2543Smrg                flags |= KD_MOUSE_DELTA;
89706f2543Smrg                if ((private->lastx == 0) || (private->lasty == 0)) {
90706f2543Smrg                    x = event.x;
91706f2543Smrg                    y = event.y;
92706f2543Smrg                } else {
93706f2543Smrg                    x = event.x - private->lastx;
94706f2543Smrg                    y = event.y - private->lasty;
95706f2543Smrg	    	}
96706f2543Smrg            }
97706f2543Smrg            private->lastx = event.x;
98706f2543Smrg            private->lasty = event.y;
99706f2543Smrg        } else {
100706f2543Smrg            flags = 0;
101706f2543Smrg            x = private->lastx;
102706f2543Smrg            y = private->lasty;
103706f2543Smrg        }
104706f2543Smrg
105706f2543Smrg        KdEnqueuePointerEvent (pi, flags, x, y, event.pressure);
106706f2543Smrg    }
107706f2543Smrg}
108706f2543Smrg
109706f2543Smrgstatic Status
110706f2543SmrgTslibEnable (KdPointerInfo *pi)
111706f2543Smrg{
112706f2543Smrg    struct TslibPrivate *private = pi->driverPrivate;
113706f2543Smrg
114706f2543Smrg    private->raw_event_hook = NULL;
115706f2543Smrg    private->raw_event_closure = NULL;
116706f2543Smrg    if (!pi->path) {
117706f2543Smrg        pi->path = strdup("/dev/input/touchscreen0");
118706f2543Smrg        ErrorF("[tslib/TslibEnable] no device path given, trying %s\n", pi->path);
119706f2543Smrg    }
120706f2543Smrg
121706f2543Smrg    private->tsDev = ts_open(pi->path, 0);
122706f2543Smrg    if (!private->tsDev) {
123706f2543Smrg        ErrorF("[tslib/TslibEnable] failed to open %s\n", pi->path);
124706f2543Smrg        return BadAlloc;
125706f2543Smrg    }
126706f2543Smrg
127706f2543Smrg    if (ts_config(private->tsDev)) {
128706f2543Smrg        ErrorF("[tslib/TslibEnable] failed to load configuration\n");
129706f2543Smrg        ts_close(private->tsDev);
130706f2543Smrg        private->tsDev = NULL;
131706f2543Smrg        return BadValue;
132706f2543Smrg    }
133706f2543Smrg
134706f2543Smrg    private->fd = ts_fd(private->tsDev);
135706f2543Smrg
136706f2543Smrg    KdRegisterFd(private->fd, TsRead, pi);
137706f2543Smrg
138706f2543Smrg    return Success;
139706f2543Smrg}
140706f2543Smrg
141706f2543Smrg
142706f2543Smrgstatic void
143706f2543SmrgTslibDisable (KdPointerInfo *pi)
144706f2543Smrg{
145706f2543Smrg    struct TslibPrivate *private = pi->driverPrivate;
146706f2543Smrg
147706f2543Smrg    if (private->fd)
148706f2543Smrg        KdUnregisterFd(pi, private->fd, TRUE);
149706f2543Smrg
150706f2543Smrg    if (private->tsDev)
151706f2543Smrg        ts_close(private->tsDev);
152706f2543Smrg
153706f2543Smrg    private->fd = 0;
154706f2543Smrg    private->tsDev = NULL;
155706f2543Smrg}
156706f2543Smrg
157706f2543Smrg
158706f2543Smrgstatic Status
159706f2543SmrgTslibInit (KdPointerInfo *pi)
160706f2543Smrg{
161706f2543Smrg    struct TslibPrivate *private = NULL;
162706f2543Smrg
163706f2543Smrg    if (!pi || !pi->dixdev)
164706f2543Smrg        return !Success;
165706f2543Smrg
166706f2543Smrg    pi->driverPrivate = (struct TslibPrivate *)
167706f2543Smrg                        calloc(sizeof(struct TslibPrivate), 1);
168706f2543Smrg    if (!pi->driverPrivate)
169706f2543Smrg        return !Success;
170706f2543Smrg
171706f2543Smrg    private = pi->driverPrivate;
172706f2543Smrg    /* hacktastic */
173706f2543Smrg    private->phys_screen = 0;
174706f2543Smrg    pi->nAxes = 3;
175706f2543Smrg    pi->name = strdup("Touchscreen");
176706f2543Smrg    pi->inputClass = KD_TOUCHSCREEN;
177706f2543Smrg
178706f2543Smrg    return Success;
179706f2543Smrg}
180706f2543Smrg
181706f2543Smrg
182706f2543Smrgstatic void
183706f2543SmrgTslibFini (KdPointerInfo *pi)
184706f2543Smrg{
185706f2543Smrg    free(pi->driverPrivate);
186706f2543Smrg    pi->driverPrivate = NULL;
187706f2543Smrg}
188706f2543Smrg
189706f2543Smrg
190706f2543SmrgKdPointerDriver TsDriver = {
191706f2543Smrg    "tslib",
192706f2543Smrg    TslibInit,
193706f2543Smrg    TslibEnable,
194706f2543Smrg    TslibDisable,
195706f2543Smrg    TslibFini,
196706f2543Smrg    NULL,
197706f2543Smrg};
198