⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xf86onetouch.c

📁 基于linux的串口声波屏驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright 2000-2003 by Alessandro Rubini <rubini@linux.it> *      somehow based on xf86Summa.c: * Copyright 1996 by Steven Lang <tiger@tyger.org> * * This work is sponsored by Automata S.p.A, Cannon group. * It is also based on previous work of mine sponsored by Gunze-USA. * * 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 not be used in advertising * or publicity pertaining to distribution of the software without specific, * written prior permission.  The authors make no representations about the * suitability of this software for any purpose.  It is provided "as is" * without express or implied warranty. * * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL STEVEN LANG 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 ACTIONS, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. *//* $XFree86: <I think this string is added by official archiving> */static const char identification[] = "$Identification: What? $";#include <xf86Version.h>#if XF86_VERSION_MAJOR > 3#define XFREE86_V4#else#error "Versions of X less than 4 are not supported by this module"#endif#include <fcntl.h>#ifndef XFree86LOADER#include <unistd.h>#include <errno.h>#endif#include <misc.h>#include <xf86.h>#define NEED_XF86_TYPES#if !defined(DGUX)#include <xf86_ansic.h>#include <xisb.h>#endif#include <xf86_OSproc.h>#include <xf86Xinput.h>#include <exevents.h>		/* Needed for InitValuator/Proximity stuff */#include <keysym.h>#include <mipointer.h>#ifdef XFree86LOADER#include <xf86Module.h>#endif#include "calib-math.h"#undef memset#define memset xf86memset#undef sleep#define sleep(t) xf86WaitForInput(-1, 1000 * (t))#define wait_for_fd(fd) xf86WaitForInput((fd), 1000)#define tcflush(fd, n) xf86FlushInput((fd))#undef read#define read(a,b,c) xf86ReadSerial((a),(b),(c))#undef write#define write(a,b,c) xf86WriteSerial((a),(char*)(b),(c))#undef close#define close(a) xf86CloseSerial((a))#define XCONFIG_PROBED "(==)"#define XCONFIG_GIVEN "(**)"#define xf86Verbose 1#undef PRIVATE#define PRIVATE(x) XI_PRIVATE(x)/*  * Be sure to set vmin appropriately for your device's protocol. You want to * read a full packet before returning */static const char *default_options[] ={	"BaudRate", "9600",	"StopBits", "1",	"DataBits", "8",	"Parity", "None",	"Vmin", "1",	"Vtime", "10",	"FlowControl", "None",	NULL};static InputDriverPtr gnzDrv;#if defined(__QNX__) || defined(__QNXNTO__)#define POSIX_TTY#endif#include "onetouch.h" /* Definitions for the led meanings *//*** Debugging macros*/#ifdef DBG#undef DBG#endif#ifdef DEBUG#undef DEBUG#endifstatic int      debug_level = 0;#define DEBUG	1#if DEBUG#define 	DBG(lvl, f) 	{if ((lvl) <= debug_level) f;}#else#define 	DBG(lvl, f)#endif/*** Device records*/#define ONETOUCH_MAXPHYSCOORD 1023#define ONETOUCH_MAXCOORD     (64*1024-1) /* oversampled, synthetic value */#define FLAG_PRE_TAPPING	1 /* this is motion, despite being pen-down */#define FLAG_WAS_UP		2 /* last event was a pen-up event */#define ONETOUCH_DEFAULT_TAPPING_DELAY 0 /* off */#define ONETOUCH_DEFAULT_JITTER_DELAY 50 /* milli Seconds *//* * Prototype for a callback to handle delayed release event. * This is handy for integrating out the on/off jitter that * the Onetouch device tends to produce during a user drag (Chris Howe) */static CARD32 touchButtonTimer(OsTimerPtr timer, CARD32 now, pointer arg); typedef struct {    char	*onetDevice;	/* device file name */    int		flags;		/* various flags */    int		onetBaud;	/* 9600 or 19200 */    int		onetDlen;	/* data length (3 or 11) */    int		onetAvgX;	/* previous X position */    int		onetAvgY;	/* previous Y position */    int		onetSmooth;	/* how smooth the motion is */    int		onetPrevButton;	/* previous button state */    int		onetBytes;	/* number of bytes read */    int         onetButton;     /* 0 (default), 1, 2, -1, -2 for "once" */    unsigned char onetData[16];	/* data read on the device */    double      onetCalib[6];    /* Calibration parameters */    char	*onetConfig;     /* filename for configuration */    int         onetJitterDelay;  /* time to delay before issuing a buttonup */    int         onetTappingDelay;  /* longer hops are not considered ticks */    long        onetUpSec;         /* when did pen-up happen */    long        onetUpUsec;        /* when did pen-up happen */    LedCtrl    *onetLeds;    OsTimerPtr  timer;} OnetouchDeviceRec, *OnetouchDevicePtr;#define ONETOUCH_SERIAL_DLEN 11#define ONETOUCH_PS2_DLEN     3/*** Configuration data*/#define ONETOUCH_SECTION_NAME    "Onetouch"#define ONETOUCH_DEFAULT_CFGFILE "/etc/onetouch.calib"/*** Contants and macro*/#define BUFFER_SIZE	120	  /* size of reception buffer */#define XI_NAME 	"ONETOUCH" /* X device name for the touch screen */#define MSGID           "xf86Onetouch: "#define SYSCALL(call) while(((call) == -1) && (errno == EINTR))/*** xf86OnetouchConvert** Convert valuators to X and Y. Since calibration data has already been used,** this only requires downscaling to screen size*/static Boolxf86OnetouchConvert(LocalDevicePtr	local,	       int		first,	       int		num,	       int		v0,	       int		v1,	       int		v2,	       int		v3,	       int		v4,	       int		v5,	       int*		x,	       int*		y){    if (first != 0 || num == 1)      return FALSE;    *x = v0 * screenInfo.screens[0]->width  / (ONETOUCH_MAXCOORD);    *y = v1 * screenInfo.screens[0]->height / (ONETOUCH_MAXCOORD);    if (*x < 0)	*x = 0;    if (*y < 0)	*y = 0;    if (*x > screenInfo.screens[0]->width-1)	*x = screenInfo.screens[0]->width-1;    if (*y > screenInfo.screens[0]->height-1)	*y = screenInfo.screens[0]->height-1;    DBG(6, ErrorF("Adjusted coords x=%d y=%d\n", *x, *y));    return TRUE;}/*** xf86OnetouchReadInput** Reads from the touch screen, uses calibration data** and posts any new events to the server.*/static voidxf86OnetouchReadInput(LocalDevicePtr local){    OnetouchDevicePtr	priv = (OnetouchDevicePtr) local->private;    unsigned char *	pkt = priv->onetData;    int			len, loop;    int			x, y, button;    double *		calib = priv->onetCalib;    DeviceIntPtr	device;    unsigned char	buffer[BUFFER_SIZE];    static 		int oldbytes; /* bytes left over on the buffer */    static		unsigned char up_packet[] = "\xff\xfe\xfe";    #define		up_size 3    long                sec, usec;      DBG(7, ErrorF("xf86OnetouchReadInput BEGIN device=%s fd=%d (bytes %i)\n",       priv->onetDevice, local->fd, priv->onetBytes));    oldbytes = priv->onetBytes;    priv->onetBytes = 0;    memcpy(buffer, pkt, oldbytes);    SYSCALL(len = read(local->fd, buffer+oldbytes, sizeof(buffer)-oldbytes));    if (len <= 0) {	Error("error reading Onetouch touch screen device");	return;    }    len += oldbytes;    /*     * Serial protocol:     *    0xff, <lowx>, <highx>, <lowy>, <highy>  (5b)     *    0xff, 0xfe, 0xfe (3b) == release     */    for (loop = 0; loop < len; ) {	/* resync, in case we lost something */	if (buffer[loop] != 0xff) {	    loop++;	    if (loop == len) {		oldbytes = 0;		return;	    }	}	/* check if not enough data for a packet */	if ( len-loop < 3	     || (strncmp(buffer+loop, up_packet, up_size) && len-loop < 5)) {	    DBG(6, ErrorF("short (%i) %02x %02x %02x\n", len-loop,			  buffer[loop], buffer[loop+1],buffer[loop+2]));	    if (loop)		memcpy(priv->onetData, buffer+loop, len-loop);	    priv->onetBytes = len-loop;	    return;	}	/* handle the 3-byte packet */	if (len-loop >= 3 && !strncmp(buffer+loop, up_packet, up_size)) {	    /* If there is further data, ignore this up event */	    if (len-loop > 4 && buffer[loop+3] == 0xff) {		loop += 3;		continue;	    }	    /*	     * The user has let go of the touchpad, but we dont know 	     * if this is a bounce or a real button up event. Set up	     * a timer to fire off the button up event unless something	     * else happens (Chris Howe)	     */	    xf86getsecs(&priv->onetUpSec, &priv->onetUpUsec); /* tap info */	    if (priv->onetJitterDelay) {		priv->timer = TimerSet( priv->timer, 0,					priv->onetJitterDelay  /* delay */,					touchButtonTimer, local);	    }	    loop += 3;	    continue;	}	/*	 * everything from here onwards is about the 5-byte packet	 */	x = buffer[loop+1] + (buffer[loop+2]<<8);	y = buffer[loop+3] + (buffer[loop+4]<<8);	/* calibration leads to values that span 16 bits like before */	x = (int)(calib[0]*(double)x + calib[1]*(double)y + calib[2]);	y = (int)(calib[3]*(double)x + calib[4]*(double)y + calib[5]);	button = 1;	/* smooth it down, unless first touch */	if (!(priv->flags & FLAG_WAS_UP)) {	    x = (priv->onetAvgX * priv->onetSmooth + x)/(priv->onetSmooth+1);	    y = (priv->onetAvgY * priv->onetSmooth + y)/(priv->onetSmooth+1);	}	/* FIXME: this isn't coordinated with debouncing */	if (!button) priv->flags |= FLAG_WAS_UP;	else priv->flags &= ~FLAG_WAS_UP;	DBG(6, ErrorF("Cooked: %5i, %5i (%i)\n", x, y, !!button));		/* Now send events */	device = local->dev;	if ( (priv->onetAvgX != x) || (priv->onetAvgY != y) ) {	    xf86PostMotionEvent(device, 1 /* absolute */, 0, 2, x, y);	}	/*	 * If we were in an up state and now we are in a down state	 * consider sending a button down event.	 */	if (!priv->onetPrevButton) {	    if( priv->timer ) {		/*		 * Uh-oh. We have detected a bounce. Cancel the timer		 * and do not send a button event.		 */		TimerFree( priv->timer );		priv->timer = NULL;	    } else {		int deltams = 0;		/* No timer: real touchdown. Is this pre-tap? */		xf86getsecs(&sec, &usec);		deltams = (sec - priv->onetUpSec) * 1000		    + (usec - priv->onetUpUsec) / 1000;		if (!priv->onetTappingDelay 		    || (deltams < priv->onetTappingDelay)) {		    int b = priv->onetButton;		    if (b < 0) b = -b;		    xf86PostButtonEvent(device, 1 /* absolute */, 					b+1 /* button, 0 is b1 etc */,					1 /* isdown */, 0, 2, x, y);		    DBG(1, ErrorF("Post button %i\n", b+1));		} else {		    priv->flags |= FLAG_PRE_TAPPING;		    DBG(1, ErrorF("Pre-tapping\n"));		}	    }	}	/* remember data */	priv->onetPrevButton = button;	priv->onetAvgX = x;	priv->onetAvgY = y;	loop += 5;    }    priv->onetBytes = len - loop;    memcpy(priv->onetData, buffer+loop, len-loop);    return;}/* send a button event after a delay */static CARD32touchButtonTimer(OsTimerPtr timer, CARD32 now, pointer arg){    LocalDevicePtr local = (LocalDevicePtr) arg;    OnetouchDevicePtr priv = (OnetouchDevicePtr)(local->private);    int sigstate;    int b = priv->onetButton;    if (b < 0) b = -b;    sigstate = xf86BlockSIGIO();    xf86PostButtonEvent(local->dev, 1 /* absolute */, b+1 /* button */,		      0 /* isdown */, 0, 2, 		      priv->onetAvgX, priv->onetAvgY);    xf86UnblockSIGIO(sigstate);    if (priv->onetButton < 0) { /* "once" done, reset it */	priv->onetLeds->led_values = 0;	priv->onetButton = 0;    }    priv->onetPrevButton = 0;    priv->flags &= ~FLAG_PRE_TAPPING;    DBG(1, ErrorF("Post delayed button-up %i\n", b+1));    priv->timer = NULL;    return(0);}/*** xf86OnetouchControlProc** This is called for each device control that is defined at init time.** It currently isn't use, but I plan to make tapping, smoothness and** on/off available as integer device controls.*/static voidxf86OnetouchControlProc(DeviceIntPtr	device, PtrCtrl *ctrl){    DBG(2, ErrorF("xf86OnetouchControlProc\n"));}/* Read the configuration file or revert to default (identity) cfg */static int xf86OnetouchReadCalib(OnetouchDevicePtr priv, int activate){    int i, err = 1;    static int numbers[10];    FILE *f;    double precision; /* unused by now */    f = fopen(priv->onetConfig, "r");    if (f) {	char s[80];	fgets(s, 80, f); /* discard the comment */	for (i=0; i<10; i++)	    err = fscanf(f, "%i", numbers+i);	err = (err == 1) ? 0 : 1; /* 1 means ok, 0 or -1 means error */	fclose(f);	}    if (err)	ErrorF(MSGID "Calibration data absent or invalid, using defaults\n");    if (!err) {	/* ok, we now have the 10 raw values, convert them */	err = official_5p_calibration( 1<<16, 1<<16, /* 64k range */				      numbers, priv->onetCalib, &precision);    }    if (err || !activate) {	/* LED_UNCALIBRATE passes through here, to avoid duplication */	memset(priv->onetCalib, 0, 6 * sizeof(double));	priv->onetCalib[0] = 1.0; /* X = 1*x + 0*y + 0 */	priv->onetCalib[4] = 1.0; /* Y = 0*x + 1*y + 0 */	return 0;    }    ErrorF(MSGID "Calibration data valid\n");    ErrorF(MSGID "Calibration: X = %f x + %f y + %f\n",	   priv->onetCalib[0], priv->onetCalib[1], priv->onetCalib[2]);    ErrorF(MSGID "Calibration: Y = %f x + %f y + %f\n",	   priv->onetCalib[3], priv->onetCalib[4], priv->onetCalib[5]);    return 0;}/* * This feedback function is used to get commands from a client application */static void xf86OnetouchLeds(DeviceIntPtr dev, LedCtrl *ctrl){    LocalDevicePtr	local = (LocalDevicePtr)dev->public.devicePrivate;    OnetouchDevicePtr	priv = (OnetouchDevicePtr)local->private;    int cmd;    if (!priv->onetLeds) {	/* fist time */	priv->onetLeds = ctrl;	ctrl->led_mask = ~0;    }    DBG(9, ErrorF(MSGID "ledfeedback  %x %x\n",		  ctrl->led_values, ctrl->led_mask));    cmd = ctrl->led_values & ctrl->led_mask;    if (cmd & OTLED_UNCALIBRATE) {	/* remove calibration, used before making a new calibration */	xf86OnetouchReadCalib(priv, 0);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -