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