194 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			194 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
 | |
| 
 | |
| #define NEED_EVENTS
 | |
| #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 = x;
 | |
|             private->lasty = 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;
 | |
|     private->tsDev = ts_open(pi->path, 0);
 | |
|     private->fd = ts_fd(private->tsDev);
 | |
|     if (!private->tsDev || ts_config(private->tsDev) || private->fd < 0) {
 | |
|         ErrorF("[tslib/TslibEnable] failed to open %s\n", pi->path);
 | |
|         if (private->fd >= 0)
 | |
|             close(private->fd);
 | |
|         return BadAlloc;
 | |
|     }
 | |
| 
 | |
|     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)
 | |
| {
 | |
|     int		        fd = 0, i = 0;
 | |
|     DIR                 *inputdir = NULL;
 | |
|     struct dirent       *inputent = NULL;
 | |
|     struct tsdev        *tsDev = NULL;
 | |
|     struct TslibPrivate *private = NULL;
 | |
| 
 | |
|     if (!pi || !pi->dixdev)
 | |
|         return !Success;
 | |
|     
 | |
|     pi->driverPrivate = (struct TslibPrivate *)
 | |
|                         xcalloc(sizeof(struct TslibPrivate), 1);
 | |
|     if (!pi->driverPrivate)
 | |
|         return !Success;
 | |
| 
 | |
|     private = pi->driverPrivate;
 | |
|     /* hacktastic */
 | |
|     private->phys_screen = 0;
 | |
|     pi->nAxes = 3;
 | |
|     pi->name = KdSaveString("Touchscreen");
 | |
|     pi->inputClass = KD_TOUCHSCREEN;
 | |
| 
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| 
 | |
| static void
 | |
| TslibFini (KdPointerInfo *pi)
 | |
| {
 | |
|     if (pi->driverPrivate) {
 | |
|         xfree(pi->driverPrivate);
 | |
|         pi->driverPrivate = NULL;
 | |
|     }
 | |
| }
 | |
| 
 | |
| 
 | |
| KdPointerDriver TsDriver = {
 | |
|     "tslib",
 | |
|     TslibInit,
 | |
|     TslibEnable,
 | |
|     TslibDisable,
 | |
|     TslibFini,
 | |
|     NULL,
 | |
| };
 |