1/* 2 * TSLIB based touchscreen driver for KDrive 3 * Porting to new input API and event queueing by Daniel Stone. 4 * Derived from ts.c by Keith Packard 5 * Derived from ps2.c by Jim Gettys 6 * 7 * Copyright � 1999 Keith Packard 8 * Copyright � 2000 Compaq Computer Corporation 9 * Copyright � 2002 MontaVista Software Inc. 10 * Copyright � 2005 OpenedHand Ltd. 11 * Copyright � 2006 Nokia Corporation 12 * 13 * Permission to use, copy, modify, distribute, and sell this software and its 14 * documentation for any purpose is hereby granted without fee, provided that 15 * the above copyright notice appear in all copies and that both that 16 * copyright notice and this permission notice appear in supporting 17 * documentation, and that the name of the authors and/or copyright holders 18 * not be used in advertising or publicity pertaining to distribution of the 19 * software without specific, written prior permission. The authors and/or 20 * copyright holders make no representations about the suitability of this 21 * software for any purpose. It is provided "as is" without express or 22 * implied warranty. 23 * 24 * THE AUTHORS AND/OR COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD 25 * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 26 * AND FITNESS, IN NO EVENT SHALL THE AUTHORS AND/OR COPYRIGHT HOLDERS BE 27 * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 28 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 29 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 30 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 31 */ 32 33 34#ifdef HAVE_KDRIVE_CONFIG_H 35#include <kdrive-config.h> 36#endif 37 38#include <X11/X.h> 39#include <X11/Xproto.h> 40#include <X11/Xpoll.h> 41#include "inputstr.h" 42#include "scrnintstr.h" 43#include "kdrive.h" 44#include <sys/ioctl.h> 45#include <tslib.h> 46#include <dirent.h> 47#include <linux/input.h> 48 49struct TslibPrivate { 50 int fd; 51 int lastx, lasty; 52 struct tsdev *tsDev; 53 void (*raw_event_hook)(int x, int y, int pressure, void *closure); 54 void *raw_event_closure; 55 int phys_screen; 56}; 57 58 59static void 60TsRead (int fd, void *closure) 61{ 62 KdPointerInfo *pi = closure; 63 struct TslibPrivate *private = pi->driverPrivate; 64 struct ts_sample event; 65 long x = 0, y = 0; 66 unsigned long flags; 67 68 if (private->raw_event_hook) { 69 while (ts_read_raw(private->tsDev, &event, 1) == 1) 70 private->raw_event_hook (event.x, event.y, event.pressure, 71 private->raw_event_closure); 72 return; 73 } 74 75 while (ts_read(private->tsDev, &event, 1) == 1) { 76 if (event.pressure) { 77 flags = KD_BUTTON_1; 78 79 /* 80 * Here we test for the touch screen driver actually being on the 81 * touch screen, if it is we send absolute coordinates. If not, 82 * then we send delta's so that we can track the entire vga screen. 83 */ 84 if (KdCurScreen == private->phys_screen) { 85 x = event.x; 86 y = event.y; 87 } else { 88 flags |= KD_MOUSE_DELTA; 89 if ((private->lastx == 0) || (private->lasty == 0)) { 90 x = event.x; 91 y = event.y; 92 } else { 93 x = event.x - private->lastx; 94 y = event.y - private->lasty; 95 } 96 } 97 private->lastx = event.x; 98 private->lasty = event.y; 99 } else { 100 flags = 0; 101 x = private->lastx; 102 y = private->lasty; 103 } 104 105 KdEnqueuePointerEvent (pi, flags, x, y, event.pressure); 106 } 107} 108 109static Status 110TslibEnable (KdPointerInfo *pi) 111{ 112 struct TslibPrivate *private = pi->driverPrivate; 113 114 private->raw_event_hook = NULL; 115 private->raw_event_closure = NULL; 116 if (!pi->path) { 117 pi->path = strdup("/dev/input/touchscreen0"); 118 ErrorF("[tslib/TslibEnable] no device path given, trying %s\n", pi->path); 119 } 120 121 private->tsDev = ts_open(pi->path, 0); 122 if (!private->tsDev) { 123 ErrorF("[tslib/TslibEnable] failed to open %s\n", pi->path); 124 return BadAlloc; 125 } 126 127 if (ts_config(private->tsDev)) { 128 ErrorF("[tslib/TslibEnable] failed to load configuration\n"); 129 ts_close(private->tsDev); 130 private->tsDev = NULL; 131 return BadValue; 132 } 133 134 private->fd = ts_fd(private->tsDev); 135 136 KdRegisterFd(private->fd, TsRead, pi); 137 138 return Success; 139} 140 141 142static void 143TslibDisable (KdPointerInfo *pi) 144{ 145 struct TslibPrivate *private = pi->driverPrivate; 146 147 if (private->fd) 148 KdUnregisterFd(pi, private->fd, TRUE); 149 150 if (private->tsDev) 151 ts_close(private->tsDev); 152 153 private->fd = 0; 154 private->tsDev = NULL; 155} 156 157 158static Status 159TslibInit (KdPointerInfo *pi) 160{ 161 struct TslibPrivate *private = NULL; 162 163 if (!pi || !pi->dixdev) 164 return !Success; 165 166 pi->driverPrivate = (struct TslibPrivate *) 167 calloc(sizeof(struct TslibPrivate), 1); 168 if (!pi->driverPrivate) 169 return !Success; 170 171 private = pi->driverPrivate; 172 /* hacktastic */ 173 private->phys_screen = 0; 174 pi->nAxes = 3; 175 pi->name = strdup("Touchscreen"); 176 pi->inputClass = KD_TOUCHSCREEN; 177 178 return Success; 179} 180 181 182static void 183TslibFini (KdPointerInfo *pi) 184{ 185 free(pi->driverPrivate); 186 pi->driverPrivate = NULL; 187} 188 189 190KdPointerDriver TsDriver = { 191 "tslib", 192 TslibInit, 193 TslibEnable, 194 TslibDisable, 195 TslibFini, 196 NULL, 197}; 198