diff -ruN tslib-1.0.orig/AUTHORS tslib-1.0/AUTHORS --- tslib-1.0.orig/AUTHORS 2006-08-24 16:02:55.000000000 -0500 +++ tslib-1.0/AUTHORS 2007-06-03 20:34:00.000000000 -0500 @@ -2,3 +2,4 @@ Russell King Douglas Lowder Chris Larson +Jay Kuri diff -ruN tslib-1.0.orig/autogen.sh tslib-1.0/autogen.sh --- tslib-1.0.orig/autogen.sh 2006-08-24 16:02:55.000000000 -0500 +++ tslib-1.0/autogen.sh 2007-05-06 20:19:42.000000000 -0500 @@ -1,8 +1,8 @@ #!/bin/sh # $Id: autogen.sh,v 1.3 2005/02/26 01:47:22 kergoth Exp $ -autoreconf -f -i -I `pwd`/m4 -exit $? +#autoreconf -f -i -I `pwd`/m4 +#exit $? echo -n "Libtoolize..." libtoolize --force --copy diff -ruN tslib-1.0.orig/configure.ac tslib-1.0/configure.ac --- tslib-1.0.orig/configure.ac 2006-08-24 16:02:55.000000000 -0500 +++ tslib-1.0/configure.ac 2007-06-03 17:26:07.000000000 -0500 @@ -163,6 +163,45 @@ AC_MSG_RESULT($input_module) AM_CONDITIONAL(ENABLE_INPUT_MODULE, test "$input_module" = "yes") +AC_MSG_CHECKING([whether idsv4 module is requested]) +AC_ARG_ENABLE(idsv4, + AS_HELP_STRING([--enable-idsv4], + [Enable building of idsv4(wacom) raw module (default=yes)]), + [idsv4_module=$enableval], + [idsv4_module=yes]) +AC_MSG_RESULT($idsv4_module) +AM_CONDITIONAL(ENABLE_IDSV4_MODULE, test "$idsv4_module" = "yes") + +AC_MSG_CHECKING([whether offset module is requested]) +AC_ARG_ENABLE(offset, + AS_HELP_STRING([--enable-offset], + [Enable building of offset module (default=yes)]), + [offset_module=$enableval], + [offset_module=yes]) +AC_MSG_RESULT($offset_module) +AM_CONDITIONAL(ENABLE_OFFSET_MODULE, test "$offset_module" = "yes") + +AC_MSG_CHECKING([whether taphold module is requested]) +AC_ARG_ENABLE(taphold, + AS_HELP_STRING([--enable-taphold], + [Enable building of taphold module (default=yes)]), + [taphold_module=$enableval], + [taphold_module=yes]) +AC_MSG_RESULT($taphold_module) +AM_CONDITIONAL(ENABLE_TAPHOLD_MODULE, test "$taphold_module" = "yes") + +AC_MSG_CHECKING([whether penclick module is requested]) +AC_ARG_ENABLE(penclick, + AS_HELP_STRING([--enable-penclick], + [Enable building of penclick module (default=yes)]), + [penclick_module=$enableval], + [penclick_module=yes]) +AC_MSG_RESULT($penclick_module) +AM_CONDITIONAL(ENABLE_PENCLICK_MODULE, test "$penclick_module" = "yes") + + + + AC_MSG_CHECKING([where to place modules]) AC_ARG_WITH(plugindir, AS_HELP_STRING([--with-plugindir=ARG], diff -ruN tslib-1.0.orig/etc/ts.conf tslib-1.0/etc/ts.conf --- tslib-1.0.orig/etc/ts.conf 2006-08-24 16:02:55.000000000 -0500 +++ tslib-1.0/etc/ts.conf 2007-06-03 20:29:04.000000000 -0500 @@ -19,6 +19,10 @@ # Uncomment if you're using an IBM Arctic II # module_raw arctic2 +module_raw idsv4 +module taphold +module penclick +module offset module pthres pmin=1 module variance delta=30 module dejitter delta=100 diff -ruN tslib-1.0.orig/plugins/click.c tslib-1.0/plugins/click.c --- tslib-1.0.orig/plugins/click.c 1969-12-31 18:00:00.000000000 -0600 +++ tslib-1.0/plugins/click.c 2007-05-06 20:38:27.000000000 -0500 @@ -0,0 +1,105 @@ +/** + * \file click.c + * \brief content lister - eReader key-click handling + * + * Generate key-clicks on request + */ + +/* contentLister - A GTK based content lister (read only) application on the eReader platform + * Copyright (C) 2006 iRex Technologies B.V. + */ + +//#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "click.h" +//#include "contentListerLog.h" +#define CL_ERRORPRINTF printf + + +// global data +static int g_click_size = 0; +static char* g_click_waveform = NULL; +static pthread_mutex_t g_click_mutex; + +// local functions +static void* click_thread(void* arg); + + +// initialise: read click waveform +// return 1 when ok, 0 when error +int click_init(void) +{ + int fd; + int err; + pthread_t click_tid; + int success = 0; + + // initialise mutex + err = pthread_mutex_init(&g_click_mutex, NULL); + if (err != 0) + { + CL_ERRORPRINTF("Mutex init error [%d]", err); + } + else + { + // read click waveform in memory + fd = open(FILENAME_PEN_CLICK, O_RDONLY); + if (fd <= 0) + { + err = errno; + CL_ERRORPRINTF("Open error [%d] file [%s]", err, FILENAME_PEN_CLICK); + } + else + { + g_click_size = lseek(fd, 0, SEEK_END); + g_click_waveform = malloc(g_click_size); + if (g_click_waveform) + { + ssize_t n; + lseek(fd, 0, SEEK_SET); + n = read(fd, g_click_waveform, g_click_size); + if (n != g_click_size) + { + err = errno; + CL_ERRORPRINTF("Read error [%d] file [%s]", err, FILENAME_PEN_CLICK); + free(g_click_waveform); + g_click_waveform = NULL; + } + } + } + } + + return success; +} + + +void click(void) +{ + int fd; + int err; + + // click once + if (g_click_waveform != NULL && g_click_size != 0) + { + fd = open(AUDIO_DEVICE, O_WRONLY); + if (fd <= 0) + { + err = errno; + CL_ERRORPRINTF("Open error [%d] device [%s]", err, AUDIO_DEVICE); + } + else + { + write(fd, g_click_waveform, g_click_size); + close(fd); + } + } +} + diff -ruN tslib-1.0.orig/plugins/click.h tslib-1.0/plugins/click.h --- tslib-1.0.orig/plugins/click.h 1969-12-31 18:00:00.000000000 -0600 +++ tslib-1.0/plugins/click.h 2007-05-06 20:38:27.000000000 -0500 @@ -0,0 +1,29 @@ +/** + * \file click.h + * \brief content lister - eReader key-click handling + * + * Generate keys-click on request + */ + +/* contentLister - A GTK based content lister (read only) application on the eReader platform + * Copyright (C) 2006 iRex Technologies B.V. + */ + + +#ifndef __CL_CLICK__H__ +#define __CL_CLICK__H__ + + +#define AUDIO_DEVICE "/dev/dsp" + +#define DATA_DIR "/usr/share/contentlister" +#define FILENAME_KEY_CLICK (DATA_DIR "/clicked_key.wav") +#define FILENAME_PEN_CLICK (DATA_DIR "/clicked_pen.wav") + +int click_init(void); + +void click(void); + + +#endif //__CL_CLICK__H__ + Binary files tslib-1.0.orig/plugins/.DS_Store and tslib-1.0/plugins/.DS_Store differ diff -ruN tslib-1.0.orig/plugins/idsv4-raw.c tslib-1.0/plugins/idsv4-raw.c --- tslib-1.0.orig/plugins/idsv4-raw.c 1969-12-31 18:00:00.000000000 -0600 +++ tslib-1.0/plugins/idsv4-raw.c 2007-06-17 12:53:16.000000000 -0500 @@ -0,0 +1,290 @@ +/* + * tslib/plugins/idsv4.c + * + * Copyright (C) 2007 Jason Kuri. + * + * This file is placed under the LGPL. Please see the file + * COPYING for more details. + * + * This raw input supports the wacom Tablet-PC serial interface. + * It was written to support the wacom digitizer pad for the + * iRex iLiad eBook reader. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "config.h" +#include "tslib-private.h" + +struct tslib_idsv4 { + struct tslib_module_info module; + int sane_fd; +}; + + +// This routine is a workaround. We'd like to do this in mod_init - but because +// tslib opens the fd after module initialization, we can't. So we set a flag +// to indicate it hasn't been called, and call it on the first read. +// The unfortunate side effect of this is that we can't indicate that the module +// did not load properly if there was a problem. So we just have to keep +// responding as 'failed' to the data requests. +static int setup_fd(int fd) +{ + + struct termios tios; + int bytes_read=0; + int bytes_needed=0; + int offset = 0; + int stored_offset = 0; + int tries = 0; + char s[12]; + char buffer[12]; + + #ifdef DEBUG + fprintf(stderr,"Initializing fd for idsv4\n"); + #endif + + // Let's lock the port - just so nobody messes up our tablet configuration + // while we are running + if (flock(fd, (LOCK_EX|LOCK_NB)) == -1) { + fprintf(stderr,"Unable to lock port: %s\n",strerror(errno)); + return -1; + } + + if (tcgetattr (fd, &tios)) + { + fprintf(stderr,"Failed to get port params: %s",strerror(errno)); + return -1; + } + + tios.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); + tios.c_oflag &= ~OPOST; + tios.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); + tios.c_cflag &= ~(CSIZE|PARENB); + tios.c_cflag |= CS8|CLOCAL; + tios.c_cflag &= ~(CSTOPB); /* 1 stop bit */ + tios.c_cflag &= ~(CSIZE); /* 8 data bits */ + tios.c_cflag |= CS8; + tios.c_cflag &= ~(PARENB); /* no parity */ + tios.c_iflag |= IXOFF; /* flow control XOff */ + tios.c_cc[VMIN] = 1; /* vmin value */ + tios.c_cc[VTIME] = 0; /* vtime value */ + + cfsetispeed(&tios, B19200); + cfsetospeed(&tios, B19200); + + if (tcsetattr (fd, TCSANOW, &tios)) + { + fprintf(stderr, "Failed to set port params: %s", strerror(errno)); + return -1; + } + + // Tell the wacom to stop sampling + write(fd, "0", 1); + + // sleep for 200ms for wacom to relax. + usleep(200000); + + // query the tablet. It seems to want to tell us it's capabilities. + // if we don't ask it it tells us in the first packet - which is no good, + // and confuses everything... so we ask it. + write(fd, "*", 1); + + // give it a moment to respond + usleep(200000); + + + memset(s, 0, 11); + bytes_needed=11; + + while(bytes_needed > 0) { + offset = 0; + bytes_read = read(fd, buffer, bytes_needed); + if (bytes_read <= 0) { +#ifdef DEBUG + if (bytes_read == -1) { + fprintf(stderr, "Failed tablet read during init: %s\n", strerror(errno)); + } +#endif + // if we get no data, or an error, we sleep for a bit and try again. + if (tries>3) { + fprintf(stderr, "Failing init after 3 tries\n"); + return -1; + } else { + usleep(200000); + tries++; + } + //return 0; + } else { + if (stored_offset == 0) { + while ( offset < bytes_read) { + if (!((buffer[offset] & 0xc0) && (buffer[offset] & 0x80))) { + offset++; + } else { + memcpy(s, buffer+offset, bytes_read-offset); + stored_offset = bytes_read-offset; + bytes_needed -= stored_offset; + offset = bytes_read; + } + } + } else { + memcpy(s+stored_offset, buffer, bytes_read); + stored_offset += bytes_read; + bytes_needed -= bytes_read; + } + } + } + #ifdef DEBUG + fprintf(stderr, "Wacom Version: %d\n", ( s[10] | (s[9] << 7) )); + fprintf(stderr, "Tablet max dimensions: %dx%d\n", ( (s[1] << 9) | (s[2] << 2) | ((s[6] & 0x60) >> 5) ), + ( (s[3] << 9) | (s[4] << 2 ) | ((s[6] & 0x18) >> 3) )); + #endif + + // enable sampling. + write(fd, "1", 1); + + + return(1); +} + +/* this needs to be it's own routine because the wacom doesn't always give us the right + number of bytes on the first read, so we need to do some funkyness to get it right */ + +static int idsv4_read_and_decode_packet(int fd, struct ts_sample *samp) { + unsigned char event_buffer[9]; + unsigned char s[9]; + int stored_offset = 0; + int offset = 0; + int bytes_needed = 9; + int bytes_read = 0; + unsigned int buttons = 0; + + memset(s, 0, 9); + + while(bytes_needed > 0) { + offset = 0; + bytes_read = read(fd, event_buffer, bytes_needed); + if (bytes_read <= 0) { +#ifdef DEBUG + if (bytes_read == -1) { + fprintf(stderr, "tablet read error: %s\n", strerror(errno)); + } +#endif + return 0; + } else { + if (stored_offset == 0) { + while ( offset < bytes_read) { + /* 0x20 - docs say yes. Tablet says no. 0xc0 is the only one that works. + * if (!((event_buffer[offset] & 0x20) && (event_buffer[offset] & 0x80))) { + */ + if (!((event_buffer[offset] & 0xc0) && (event_buffer[offset] & 0x80))) { + offset++; + } else { + memcpy(s, event_buffer+offset, bytes_read-offset); + stored_offset = bytes_read-offset; + bytes_needed -= stored_offset; + offset = bytes_read; + } + } + } else { + memcpy(s+stored_offset, event_buffer, bytes_read); + stored_offset += bytes_read; + bytes_needed -= bytes_read; + } + } + } + + int prox = (s[0] & 0x20); + +// fprintf(stderr, "Proximity: %d", (s[0] & 0x20)); +// fprintf(stderr, "xtilt: %d\n", (s[7] & 0x3F)); +// fprintf(stderr, "ytilt: %d\n", (s[8] & 0x3F)); + samp->y = (s[1]<<9) | (s[2]<<2) | ((s[6]>>5)&0x03); + samp->x = (s[3]<<9) | (s[4]<<2) | ((s[6]>>3)&0x03); + samp->pressure = ((s[6]&0x07)<<7) | s[5]; + gettimeofday(&samp->tv,NULL); + buttons = s[0] & 0x07; + + // buttons & 0x04 = eraser, buttons & 0x02 = button + samp->flags = (buttons>>2) & TSFLAG_ERASER | buttons & TSFLAG_BUTTON1; + #ifdef DEBUG + fprintf(stderr, "%dx%d flag: %d\tcontact: %d\teraser: %d\tbutton: %d\n", samp->x, samp->y, samp->flags, buttons & 0x01, buttons & 0x04, buttons & 0x02); + #endif + return 1; +} + +static int idsv4_read(struct tslib_module_info *inf, struct ts_sample *samp, int nr) +{ + struct tslib_idsv4 *i = (struct tslib_idsv4 *)inf; + struct tsdev *dev = i->module.dev; + int total; + + + // if we got an error back from initializing the tablet we fail on the read + // Sorry, but what else can we do? + if (i->sane_fd == -1) { + fprintf(stderr, "fd is not sane. I'm freaking out!!\n"); + return 0; + } + + total = 0; + + while(total < nr) { + if (idsv4_read_and_decode_packet(dev->fd, samp) == 1) { + samp++; + total++; + } else { + total = 0; + break; + } + } + #ifdef DEBUG + fprintf(stderr, "returning %d samples\n", total); + #endif + return total; +} + +static int ts_idsv4_fini(struct tslib_module_info *inf) +{ + struct tslib_idsv4 *i = (struct tslib_idsv4 *)inf; + + flock(i->module.dev->fd, LOCK_UN); + free(inf); + return 0; +} + +static const struct tslib_ops idsv4_ops = +{ + .read = idsv4_read, + .fini = ts_idsv4_fini, + +}; + +TSAPI struct tslib_module_info *mod_init(struct tsdev *dev, const char *params) +{ + struct tslib_idsv4 *i; + + i = malloc(sizeof(struct tslib_idsv4)); + if (i == NULL) + return NULL; + + i->module.ops = &idsv4_ops; + i->sane_fd = 0; + + + #ifdef DEBUG + fprintf(stderr, "Initializing IDSV4 module\n"); + #endif + + i->sane_fd = setup_fd(dev->fd); + + return &(i->module); +} diff -ruN tslib-1.0.orig/plugins/Makefile.am tslib-1.0/plugins/Makefile.am --- tslib-1.0.orig/plugins/Makefile.am 2006-08-24 16:02:54.000000000 -0500 +++ tslib-1.0/plugins/Makefile.am 2007-06-03 17:49:59.000000000 -0500 @@ -85,6 +85,30 @@ INPUT_MODULE = endif +if ENABLE_IDSV4_MODULE +IDSV4_MODULE = idsv4.la +else +IDSV4_MODULE = +endif + +if ENABLE_OFFSET_MODULE +OFFSET_MODULE = offset.la +else +OFFSET_MODULE = +endif + +if ENABLE_PENCLICK_MODULE +PENCLICK_MODULE = penclick.la +else +PENCLICK_MODULE = +endif + +if ENABLE_TAPHOLD_MODULE +TAPHOLD_MODULE = taphold.la +else +TAPHOLD_MODULE = +endif + if ENABLE_H2200_LINEAR_MODULE H2200_LINEAR_MODULE = linear_h2200.la else @@ -103,7 +127,11 @@ $(MK712_MODULE) \ $(ARCTIC2_MODULE) \ $(H2200_LINEAR_MODULE) \ - $(INPUT_MODULE) + $(INPUT_MODULE) \ + $(OFFSET_MODULE) \ + $(PENCLICK_MODULE) \ + $(TAPHOLD_MODULE) \ + $(IDSV4_MODULE) variance_la_SOURCES = variance.c variance_la_LDFLAGS = -module $(LTVSN) @@ -114,6 +142,12 @@ linear_la_SOURCES = linear.c linear_la_LDFLAGS = -module $(LTVSN) +offset_la_SOURCES = offset.c +offset_la_LDFLAGS = -module $(LTVSN) + +taphold_la_SOURCES = taphold.c +taphold_la_LDFLAGS = -module $(LTVSN) + pthres_la_SOURCES = pthres.c pthres_la_LDFLAGS = -module $(LTVSN) @@ -141,3 +175,9 @@ linear_h2200_la_SOURCES = linear-h2200.c linear_h2200_la_LDFLAGS = -module $(LTVSN) + +idsv4_la_SOURCES = idsv4-raw.c +idsv4_la_LDFLAGS = -module $(LTVSN) + +penclick_la_SOURCES = penclick.c click.c +penclick_la_LDFLAGS = -module $(LTVSN) diff -ruN tslib-1.0.orig/plugins/offset.c tslib-1.0/plugins/offset.c --- tslib-1.0.orig/plugins/offset.c 1969-12-31 18:00:00.000000000 -0600 +++ tslib-1.0/plugins/offset.c 2007-05-18 00:41:57.000000000 -0500 @@ -0,0 +1,182 @@ +/* + * tslib/plugins/offset.c + * + * Copyright (C) 2007 Jason Kuri + * + * This file is placed under the LGPL. Please see the file + * COPYING for more details. + * + * offset touchscreen values - in order to adjust for pen angle + * on the fly. Reads default from offset file, can be updated by + * writing x and y offset values to a pipe - by default /var/tmp/offsetpipe + * the format for the file and for what is written to the pipe is the same. + * It should be a single string terminated by a null or newline with + * x offset first, followed by y offset. Negative offsets are allowed. + * This example would create a +10 x offset and a -20 y offset (exclude quotes): + * "10 -20\n" + */ +#include +#include +#include +#include +#include +#include +#include + + +#include + +#include "tslib.h" +#include "tslib-filter.h" + +struct tslib_offset { + struct tslib_module_info module; + int x_offset; + int y_offset; + int fifo_fd; + int sample_count; +}; + + + +static int offset_fini(struct tslib_module_info *info) +{ + struct tslib_offset *off = (struct tslib_offset *)info; + + close(off->fifo_fd); + free(info); + return 0; +} + + + +void parse_offset(struct tslib_offset *off, char *offsetinfo, int len) { + + char buffer[512]; + int o[2]; + int pos = 0; + int index = 0; + char *valueptr; + + if (len >= 512) { + len = 511; + } + strncpy(buffer, offsetinfo, len); + valueptr = buffer; + while(pos <= len && index < 2 && buffer[pos] != 0) { + if (buffer[pos] == ' ' || buffer[pos] == '\n' || pos == len) { + buffer[pos] = '\0'; + o[index] = atoi(valueptr); + index++; + valueptr = buffer + pos + 1; + } + pos++; + } + if (index == 2) { + off->x_offset = o[0]; + off->y_offset = o[1]; + #ifdef DEBUG + fprintf(stderr,"offset changed: x: %d y: %d\n", off->x_offset, off->y_offset); + #endif /*DEBUG*/ + } +} + +static int +offset_read(struct tslib_module_info *info, struct ts_sample *samp, int nr) +{ + struct tslib_offset *off = (struct tslib_offset *)info; + struct ts_sample cur; + int ret; + int bytes_read; + int count; + int xtemp,ytemp; + char buffer[512]; + + //fprintf(stderr, "Reading %d samples\n", nr); + if (off->sample_count > 50) { + off->sample_count = 0; + // check the fifo. it's in nonblocking - so we can read as much as we want + // it will just give back what it had in the buffer + bytes_read = read(off->fifo_fd, buffer, 512); + if (bytes_read > 0) { + parse_offset(off, buffer, bytes_read); + } + } + //fprintf(stderr, "past fifo check\n"); + + ret = info->next->ops->read(info->next, samp, nr); + if (ret >= 0) { + int nr; + + for (nr = 0; nr < ret; nr++, samp++) { + samp->x += off->x_offset; + samp->y += off->y_offset; + #ifdef DEBUG + fprintf(stderr, "------> adjusted: %d\t%d\n", samp->x, samp->y); + #endif + off->sample_count++; + } + } + + return ret; +} + +static const struct tslib_ops offset_ops = +{ + .read = offset_read, + .fini = offset_fini, +}; + +#define NR_VARS (sizeof(offset_vars) / sizeof(offset_vars[0])) + +TSAPI struct tslib_module_info *mod_init(struct tsdev *dev, const char *params) +{ + + struct tslib_offset *off; + + struct stat sbuf; + int offset_fd; + char offsetbuf[200]; + int bytes,ret; + char *offsetfile=NULL; + char *defaultoffsetfile = "/etc/pointeroffset"; + + char *fifofile=NULL; + char *defaultfifofile = "/var/tmp/offsetpipe"; + + + off = malloc(sizeof(struct tslib_offset)); + if (off == NULL) { + return NULL; + } + + off->module.ops = &offset_ops; + off->x_offset = 0; + off->y_offset = 0; + + off->fifo_fd = 0; + off->sample_count = 0; + + /* + * Check calibration file + */ + //fprintf(stderr, "Loading offsetfile\n"); + + if( (offsetfile = getenv("TSLIB_OFFSETFILE")) == NULL) offsetfile = defaultoffsetfile; + if(stat(offsetfile,&sbuf)==0) { + offset_fd = open(offsetfile,O_RDONLY); + bytes = read(offset_fd,offsetbuf,sbuf.st_size); + //fprintf(stderr, "Loaded %d bytes from offsetfile\n", bytes); + parse_offset(off, offsetbuf, bytes); + close(offset_fd); + } + + if( (fifofile = getenv("TSLIB_OFFSETFIFO")) == NULL) fifofile = defaultfifofile; + //fprintf(stderr, "making fifo file\n"); + ret = mknod(fifofile, S_IFIFO | 0660, 0); + if (ret == 0 || (ret == -1 && errno == EEXIST)) { + off->fifo_fd = open(fifofile, O_RDONLY|O_NONBLOCK|O_NDELAY); + } + + return &off->module; +} diff -ruN tslib-1.0.orig/plugins/penclick.c tslib-1.0/plugins/penclick.c --- tslib-1.0.orig/plugins/penclick.c 1969-12-31 18:00:00.000000000 -0600 +++ tslib-1.0/plugins/penclick.c 2007-05-17 19:59:36.000000000 -0500 @@ -0,0 +1,88 @@ +#include +#include +#include +#include +#include +#include + +#include "config.h" +#include "tslib-private.h" +#include "click.h" + +struct tslib_penclick { + struct tslib_module_info module; + int pendown; +}; + + + +static int penclick_read(struct tslib_module_info *info, struct ts_sample *samp, int nr) +{ + + int ret; + + + struct tslib_penclick *cur = (struct tslib_penclick *)info; + + ret = info->next->ops->read(info->next, samp, nr); + if (ret >= 0) { + int nr; + + for (nr =0; nr < ret; nr++, samp++) { + + if (samp->pressure > 0){ // pendown + if (cur->pendown==0){ + #ifdef DEBUG + fprintf(stderr,"********click********\n"); + #endif + cur->pendown = 1; + click(); + } + } + else { //penup + if (cur->pendown==1){ + #ifdef DEBUG + fprintf(stderr,"*********penup*********\n"); + #endif + cur->pendown=0; + } + } + + #ifdef DEBUG + fprintf(stderr, "------> out: %d\t%d\t%d\t%i\n", samp->x, samp->y,samp->pressure,cur->pendown); + #endif + + } //ret>=0 + } + + return ret; +} + +static int ts_penclick_fini(struct tslib_module_info *inf) +{ + free(inf); + return 0; +} + +static const struct tslib_ops penclick_ops = +{ + .read = penclick_read, + .fini = ts_penclick_fini, + +}; + +TSAPI struct tslib_module_info *mod_init(struct tsdev *dev, const char *params) +{ + struct tslib_penclick *i; + + i = malloc(sizeof(struct tslib_penclick)); + if (i == NULL) + return NULL; + + i->module.ops = &penclick_ops; + i->pendown = 0; + + click_init(); + + return &(i->module); +} \ No newline at end of file diff -ruN tslib-1.0.orig/plugins/pthres.c tslib-1.0/plugins/pthres.c --- tslib-1.0.orig/plugins/pthres.c 2006-08-24 16:02:54.000000000 -0500 +++ tslib-1.0/plugins/pthres.c 2007-06-03 20:18:59.000000000 -0500 @@ -43,39 +43,43 @@ struct ts_sample *s; for (s = samp, i = 0; i < ret; i++, s++) { - if (s->pressure < p->pmin) { - if (press != 0) { - /* release */ - press = 0; - s->pressure = 0; - s->x = xsave; - s->y = ysave; - } else { - /* release with no press, outside bounds, dropping */ - int left = ret - nr - 1; - if (left > 0) { - memmove(s, s + 1, left * sizeof(struct ts_sample)); - s--; - continue; - } - break; - } - } else { - if (s->pressure > p->pmax) { - /* pressure outside bounds, dropping */ - int left = ret - nr - 1; - if (left > 0) { - memmove(s, s + 1, left * sizeof(struct ts_sample)); - s--; - continue; - } - break; - } - /* press */ - press = 1; - xsave = s->x; - ysave = s->y; - } + // We pass through any events where there are buttons pressed + // regardless of pressure. + if ((s->flags & TSFLAG_ANYBUTTON) == 0) { + if (s->pressure < p->pmin) { + if (press != 0) { + /* release */ + press = 0; + s->pressure = 0; + //s->x = xsave; + //s->y = ysave; + } else { + /* release with no press, outside bounds, dropping */ + int left = ret - nr - 1; + if (left > 0) { + memmove(s, s + 1, left * sizeof(struct ts_sample)); + s--; + continue; + } + break; + } + } else { + if (s->pressure > p->pmax) { + /* pressure outside bounds, dropping */ + int left = ret - nr - 1; + if (left > 0) { + memmove(s, s + 1, left * sizeof(struct ts_sample)); + s--; + continue; + } + break; + } + /* press */ + press = 1; + xsave = s->x; + ysave = s->y; + } + } nr++; } return nr; diff -ruN tslib-1.0.orig/plugins/taphold.c tslib-1.0/plugins/taphold.c --- tslib-1.0.orig/plugins/taphold.c 1969-12-31 18:00:00.000000000 -0600 +++ tslib-1.0/plugins/taphold.c 2007-06-03 20:28:50.000000000 -0500 @@ -0,0 +1,240 @@ +/* + * tslib/plugins/taphold.c + * + * Copyright (C) 2007 Jason Kuri + * + * This file is placed under the LGPL. Please see the file + * COPYING for more details. + * + * allow a tap-hold to trigger as a second button + * Tap + hold for 'delay' milliseconds and your pen-down will + * translate into a button press on the button specified by 'button' + * (1 by default) Note that until the pen is released, all + * samples will be converted from pressure to 'button' - so, + * essentially you can draw with button1. + * + * note that this eats the stylus pressure events immediately after the + * tip-down until it determines that it is not a hold. The events that + * tell it this are either a) pen is lifted, or b) the pen is moved + * beyond the 'variation' limit. + * + * This should be the first plugin after the raw input. + * + * If you set this somewhere else, you results may be unusual... and + * note especially that the scale of the variation is VERY different + * dependingon whether the taphold plugin is placed before or + * after the 'linear' (aka calibration) plugin. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "tslib.h" +#include "tslib-filter.h" + +struct tslib_taphold { + struct tslib_module_info module; + // which button to put down + char holdbutton; + // tap-hold delay in ms. + int delay; + // how far do we allow before we break the tap-hold + char variation; + + // current status + // holding = 0 - not a hold. + // holding = 1 - pen is moving but is not a hold. + // holding = 2 - pen just went down, tap is not yet a hold + // holding = 3 - is a hold. + char holding; + + // last pressure status + char startpressure; + int startx; + int starty; + struct timeval tapstart; + +}; + +static int +taphold_read(struct tslib_module_info *info, struct ts_sample *samp, int nr) +{ + struct tslib_taphold *th = (struct tslib_taphold *)info; + int ret; + + ret = info->next->ops->read(info->next, samp, nr); + if (ret >= 0) { + int nr = 0, i; + struct ts_sample *s; + int eatevent; + + for (s = samp, i = 0; i < ret; i++, s++) { + eatevent = 0; + if (s->pressure == 0) { + // pressure has gone to 0. in all cases we reset our data. + // If we were waiting for a hold, trigger the + // original event. + if (th->holding == 2) { + s->x = th->startx; + s->y = th->starty; + s->pressure = th->startpressure; + } + th->holding = 0; + th->startx = -1; + th->starty = -1; + th->startpressure = 0; + } else { + // pen is down.... let's see what's happenning + if (th->holding == 0) { + // pen just went down - lets mark it as a potential taphold and eat the event. + th->holding = 2; + th->startx = s->x; + th->starty = s->y; + th->startpressure = s->pressure; + th->tapstart.tv_sec = s->tv.tv_sec; + th->tapstart.tv_usec = s->tv.tv_usec; + eatevent = 1; + } else if (th->holding == 2) { + // waiting for taphold - let see if we moved too far + if ((s->x - th->startx) > th->variation || + (th->startx - s->x) > th->variation || + (s->y - th->starty) > th->variation || + (th->starty - s->y) > th->variation) { + + // this means that we've moved too far so we need to clear + // out our settings and ignore future movements until the pen goes up and down again + th->holding = 1; + } else { + // we are still in the tap-hold delay... + long timediff = ((s->tv.tv_sec - th->tapstart.tv_sec) * 1000) + + ((s->tv.tv_usec - th->tapstart.tv_usec) / 1000); + if (timediff > th->delay) { + // we have a valid tap-hold - let's mark as such. + th->holding = 3; + } else { + eatevent = 1; + } + } + } + if (th->holding == 3 ) { + //fprintf(stderr, "Converting to a button press: %d\n", th->holdbutton); + s->pressure = 0; + s->flags |= th->holdbutton; + } + } + if (eatevent == 1) { + //fprintf(stderr, "eating event\n"); + int left = ret - nr - 1; + if (left > 0) { + memmove(s, s + 1, left * sizeof(struct ts_sample)); + s--; + continue; + } + } else { + nr++; + } + } + //fprintf(stderr, "returning %d\n", nr); + return nr; + } + return ret; +} + +static int taphold_fini(struct tslib_module_info *info) +{ + free(info); + return 0; +} + +static const struct tslib_ops taphold_ops = +{ + .read = taphold_read, + .fini = taphold_fini, +}; + +static int taphold_args(struct tslib_module_info *inf, char *str, void *data) +{ + struct tslib_taphold *th = (struct tslib_taphold *)inf; + unsigned long v; + int err = errno; + + v = strtoul(str, NULL, 0); + + if (v == ULONG_MAX && errno == ERANGE) + return -1; + + errno = err; + switch ((int)data) { + case 0: + th->delay = v; + break; + + case 1: + th->variation = v; + break; + + case 2: + if (v == 1) { + th->holdbutton = TSFLAG_BUTTON1; + } else if (v == 2) { + th->holdbutton = TSFLAG_BUTTON2; + } else if (v == 3) { + th->holdbutton = TSFLAG_BUTTON3; + } else if (v == 4) { + th->holdbutton = TSFLAG_BUTTON4; + } + break; + + default: + return -1; + } + return 0; +} + + +static const struct tslib_vars taphold_vars[] = +{ + { "delay", (void *)0, taphold_args }, + { "variation", (void *)1, taphold_args }, + { "button", (void *)2, taphold_args } +}; + +#define NR_VARS (sizeof(taphold_vars) / sizeof(taphold_vars[0])) + +TSAPI struct tslib_module_info *mod_init(struct tsdev *dev, const char *params) +{ + + struct tslib_taphold *th; + + th = malloc(sizeof(struct tslib_taphold)); + if (th == NULL) + return NULL; + + th->module.ops = &taphold_ops; + + + th->holdbutton = TSFLAG_BUTTON1; + th->delay = 500; + th->variation = 30; + th->holding=0; + th->startx = -1; + th->starty = -1; + th->startpressure = 0; + th->tapstart.tv_usec = 0; + th->tapstart.tv_sec = 0; + + /* + * Parse the parameters. + */ + if (tslib_parse_vars(&th->module, taphold_vars, NR_VARS, params)) { + free(th); + return NULL; + } + + return &th->module; +} diff -ruN tslib-1.0.orig/src/tslib.h tslib-1.0/src/tslib.h --- tslib-1.0.orig/src/tslib.h 2006-08-24 16:02:55.000000000 -0500 +++ tslib-1.0/src/tslib.h 2007-06-02 20:07:08.000000000 -0500 @@ -38,15 +38,46 @@ #define TSAPI TSIMPORT #endif // TSLIB_INTERNAL +#define TSFLAG_ERASER 0x01 +#define TSFLAG_BUTTON1 0x02 +#define TSFLAG_BUTTON2 0x04 +#define TSFLAG_BUTTON3 0x08 +#define TSFLAG_BUTTON4 0x10 +#define TSFLAG_ANYBUTTON 0x1E + struct tsdev; +/* Flags addition to ts_sample - by Jay Kuri + + flags is a new addition - allows a bit more information to be passed up. + all code should be able to cope with a completely empty flags var + so be aware of this as you add to it - many applications will never even + look at flags - so the default state should be flags == 0x0; + + current assignments: + + flags & 0x1F = buttons. We provide room for 4 buttons. + Note that you have to look at both pressure and buttons to determine if + there is actually a stylus press going on. (Unless you don't care which + end of the stylus is in use - in which case, pressure is enough) + Pressure without any flags set = stylus tip + + flags & 0x01 = stylus eraser + flags & 0x02 = button 1 + flags & 0x04 = button 2 + flags & 0x08 = button 3 + flags & 0x10 = button 4 +*/ struct ts_sample { int x; int y; unsigned int pressure; struct timeval tv; + unsigned long flags; }; + + /* * Close the touchscreen device, free all resources. */ diff -ruN tslib-1.0.orig/src/ts_open.c tslib-1.0/src/ts_open.c --- tslib-1.0.orig/src/ts_open.c 2006-08-24 16:02:55.000000000 -0500 +++ tslib-1.0/src/ts_open.c 2007-05-16 11:07:36.000000000 -0500 @@ -29,7 +29,11 @@ struct tsdev *ts_open(const char *name, int nonblock) { struct tsdev *ts; - int flags = O_RDONLY; + + // This used to be O_READONLY but this means we can't initialize our tablet + // so we had to change it to O_RDWR. It'd be nice if the open could be + // controlled somehow by the module that needed the device. :-( + int flags = O_RDWR; if (nonblock) flags |= O_NONBLOCK; diff -ruN tslib-1.0.orig/tests/ts_calibrate.c tslib-1.0/tests/ts_calibrate.c --- tslib-1.0.orig/tests/ts_calibrate.c 2006-08-24 16:02:55.000000000 -0500 +++ tslib-1.0/tests/ts_calibrate.c 2007-05-09 23:40:59.000000000 -0500 @@ -135,7 +135,7 @@ int index, int x, int y, char *name) { static int last_x = -1, last_y; - +/* if (last_x != -1) { #define NR_STEPS 10 int dx = ((x - last_x) << 16) / NR_STEPS; @@ -151,8 +151,9 @@ last_y += dy; } } - +*/ put_cross(x, y, 2 | XORMODE); + system("/usr/bin/displayMgrClient"); getxy (ts, &cal->x [index], &cal->y [index]); put_cross(x, y, 2 | XORMODE); @@ -203,12 +204,15 @@ for (i = 0; i < NR_COLORS; i++) setcolor (i, palette [i]); + fillrect(0,0,xres,yres, 2); + put_string_center (xres / 2, yres / 4, "TSLIB calibration utility", 1); put_string_center (xres / 2, yres / 4 + 20, "Touch crosshair to calibrate", 2); printf("xres = %d, yres = %d\n", xres, yres); + system("/usr/bin/displayMgrClient"); // Read a touchscreen event to clear the buffer //getxy(ts, 0, 0); diff -ruN tslib-1.0.orig/tests/ts_print.c tslib-1.0/tests/ts_print.c --- tslib-1.0.orig/tests/ts_print.c 2006-08-24 16:02:55.000000000 -0500 +++ tslib-1.0/tests/ts_print.c 2007-06-03 20:25:55.000000000 -0500 @@ -59,7 +59,7 @@ if (ret != 1) continue; - printf("%ld.%06ld: %6d %6d %6d\n", samp.tv.tv_sec, samp.tv.tv_usec, samp.x, samp.y, samp.pressure); + printf("%ld.%06ld: %6d %6d %6d %6d\n", samp.tv.tv_sec, samp.tv.tv_usec, samp.x, samp.y, samp.pressure, samp.flags); } } diff -ruN tslib-1.0.orig/tests/ts_print_raw.c tslib-1.0/tests/ts_print_raw.c --- tslib-1.0.orig/tests/ts_print_raw.c 2006-08-24 16:02:55.000000000 -0500 +++ tslib-1.0/tests/ts_print_raw.c 2007-06-03 20:25:47.000000000 -0500 @@ -59,7 +59,7 @@ if (ret != 1) continue; - printf("%ld.%06ld: %6d %6d %6d\n", samp.tv.tv_sec, samp.tv.tv_usec, samp.x, samp.y, samp.pressure); + printf("%ld.%06ld: %6d %6d %6d %6d\n", samp.tv.tv_sec, samp.tv.tv_usec, samp.x, samp.y, samp.pressure, samp.flags); } } diff -ruN tslib-1.0.orig/tslib-0.0.pc tslib-1.0/tslib-0.0.pc --- tslib-1.0.orig/tslib-0.0.pc 1969-12-31 18:00:00.000000000 -0600 +++ tslib-1.0/tslib-0.0.pc 2007-06-10 13:48:18.000000000 -0500 @@ -0,0 +1,10 @@ +prefix=/usr +exec_prefix=${prefix} +libdir=${exec_prefix}/lib +includedir=${prefix}/include + +Name: tslib +Description: Touchscreen Access Library +Version: 0.0.2 +Libs: -L${libdir} -lts +Cflags: -I${includedir}