198 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			198 lines
		
	
	
		
			5.5 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 = 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 = "/dev/input/touchscreen0";
 | 
						|
        ErrorF("[tslib/TslibEnable] no device path given, trying %s\n", pi->path);
 | 
						|
    }
 | 
						|
    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,
 | 
						|
};
 |