1 --- tslib/plugins/linear.c~multievent
2 +++ tslib/plugins/linear.c
4 linear_read(struct tslib_module_info *info, struct ts_sample *samp, int nr)
6 struct tslib_linear *lin = (struct tslib_linear *)info;
11 ret = info->next->ops->read(info->next, samp, nr);
15 - for (nr = 0; nr < ret; nr++, samp++) {
16 + for (i = 0; i < ret; i++, samp++) {
18 fprintf(stderr,"BEFORE CALIB--------------------> %d %d %d\n",samp->x, samp->y, samp->pressure);
28 --- tslib/plugins/dejitter.c~multievent
29 +++ tslib/plugins/dejitter.c
32 struct tslib_threshold {
33 struct tslib_module_info module;
39 static int threshold_read(struct tslib_module_info *info, struct ts_sample *samp, int nr)
41 struct tslib_threshold *thr = (struct tslib_threshold *)info;
42 - struct ts_sample *s;
44 + struct ts_sample *src = samp, *dest = samp;
47 ret = info->next->ops->read(info->next, samp, nr);
51 - for (s = samp; s < samp + ret; s++) {
52 + for (i = 0; i < ret; i++, samp++) {
55 - fprintf(stderr,"BEFORE DEJITTER---------------> %d %d %d\n",s->x,s->y,s->pressure);
56 + fprintf(stderr,"BEFORE DEJITTER---------------> %d %d %d\n", samp->x, samp->y, samp->pressure);
58 - thr->down = (s->pressure >= thr->pthreshold);
60 - dr2 = (thr->x - s->x)*(thr->x - s->x)
61 - + (thr->y - s->y)*(thr->y - s->y);
62 - if(dr2 < thr->delta2) {
70 + dr2 = (thr->x - samp->x)*(thr->x - samp->x)
71 + + (thr->y - samp->y)*(thr->y - samp->y);
72 + if(dr2 < thr->delta2) {
96 - thr->pthreshold = v;
104 { "xdelta", (void *)1, threshold_limit },
105 { "ydelta", (void *)2, threshold_limit },
106 - { "pthreshold", (void *)3, threshold_limit }
109 //#define NR_VARS (sizeof(threshold_vars) / sizeof(threshold_vars[0]))
114 - thr->pthreshold = 100;
116 if (tslib_parse_vars(&thr->module, threshold_vars, NR_VARS, params)) {
118 --- tslib/plugins/variance.c~multievent
119 +++ tslib/plugins/variance.c
121 * $Id: variance.c,v 1.3 2002/11/08 23:28:55 dlowder Exp $
123 * Variance filter for touchscreen values
125 + * Policy question (applies to all tslib modules that consume events):
126 + * 1) User requests a read of 5 events using nr.
127 + * 2) Lower layers return us 4 events.
128 + * 3) Perform variance calculation, we now only have _1_ event.
129 + * 4) Do we, a) duplicate this data across the user requested 4 events,
130 + * b) push up the single event
131 + * c) loop on the read from the lower layers to obtain
132 + * the user's requested number of events, unless we hit
144 #include "tslib-filter.h"
149 struct tslib_variance {
150 struct tslib_module_info module;
152 - unsigned int pthreshold;
155 + unsigned int pthreshold;
156 struct ts_sample last[NR_LAST];
160 * least variance, and average them.
163 -variance_calculate(struct tslib_variance *var, struct ts_sample *samp,
164 - struct ts_sample *s)
165 +variance_calculate(struct tslib_variance *var, struct ts_sample *dest, struct ts_sample *src)
168 int diff_x, min_x, i_x, j_x;
169 @@ -100,11 +110,11 @@
173 - samp->x = (var->last[i_x].x + var->last[j_x].x) / 2;
174 - samp->y = (var->last[i_y].y + var->last[j_y].y) / 2;
175 - samp->pressure = (var->last[i_p].pressure + var->last[j_p].pressure) / 2;
176 - samp->tv.tv_sec = s->tv.tv_sec;
177 - samp->tv.tv_usec = s->tv.tv_usec;
178 + dest->x = (var->last[i_x].x + var->last[j_x].x) / 2;
179 + dest->y = (var->last[i_y].y + var->last[j_y].y) / 2;
180 + dest->pressure = (var->last[i_p].pressure + var->last[j_p].pressure) / 2;
181 + dest->tv.tv_sec = src->tv.tv_sec;
182 + dest->tv.tv_usec = src->tv.tv_usec;
186 @@ -112,55 +122,57 @@
187 static int variance_read(struct tslib_module_info *info, struct ts_sample *samp, int nr)
189 struct tslib_variance *var = (struct tslib_variance *)info;
190 - struct ts_sample *s;
193 - ret = info->next->ops->read(info->next, samp, nr);
197 - for (s = samp; s < samp + ret; s++) {
198 - if (s->pressure < var->pthreshold) {
200 - * Pen was released. Reset our state and
201 - * pass up the release information.
205 - samp[nr].pressure = s->pressure;
206 - samp[nr].tv.tv_sec = s->tv.tv_sec;
207 - samp[nr].tv.tv_usec = s->tv.tv_usec;
213 - } else if (var->nr == -1) {
215 - * Pen was pressed. Inform upper layers
222 - if (var->nr >= 0) {
223 - var->last[var->nr].x = s->x;
224 - var->last[var->nr].y = s->y;
225 - var->last[var->nr].pressure = s->pressure;
229 + struct ts_sample *src = samp, *dest = samp;
232 - if (var->nr == NR_LAST) {
233 - if (variance_calculate(var, samp + nr, s))
239 + * Loop on read, collecting events until we hit nr, unless
240 + * we hit a pen up or encounter a failure.
242 + while ((i < nr) && (ret != -1)) {
243 + ret = info->next->ops->read(info->next, dest + i, nr - i);
245 + for (src = dest + i; src < dest + ret; src++) {
246 + if (src->pressure < var->pthreshold) {
247 + /* pen released, reset var->nr,
248 + * do a calc based on what we have so
249 + * far, and let this event flow up */
250 + if (variance_calculate(var, dest + i, src))
253 + ret = -1; /* break outer loop, push up event */
255 + } else if (var->nr == NR_INIT) {
257 + * First pen down event. Inform upper layers
258 + * immediately for responsiveness.
262 + ret = -1; /* break outer loop */
266 + if (var->nr >= 0) {
267 + var->last[var->nr].x = src->x;
268 + var->last[var->nr].y = src->y;
269 + var->last[var->nr].pressure = src->pressure;
274 + if (var->nr == NR_LAST) {
275 + if (variance_calculate(var, dest + i, src))
284 + /* if we've collected at least one event, send it up */
285 + if (i != 0) ret = i;
294 - var->pthreshold = v;
302 { "xlimit", (void *)1, variance_limit },
303 { "ylimit", (void *)2, variance_limit },
304 - { "pthreshold", (void *)3, variance_limit }
307 #define NR_VARS (sizeof(variance_vars) / sizeof(variance_vars[0]))
309 struct tslib_module_info *mod_init(struct tsdev *dev, const char *params)
311 struct tslib_variance *var;
314 var = malloc(sizeof(struct tslib_variance));
316 @@ -225,10 +233,15 @@
318 var->module.ops = &variance_ops;
324 var->pthreshold = 100;
325 + pthresvar = getenv("TSLIB_PTHRES");
326 + if (pthresvar != NULL) {
327 + int p = strtol(pthresvar, (char **)NULL, 10);
328 + if (p != -1) var->pthreshold = p;
331 if (tslib_parse_vars(&var->module, variance_vars, NR_VARS, params)) {
333 --- tslib/README~multievent
336 usages. They are by no means exhaustive, nor probably even good examples.
337 They are basically the programs I used to test this library.
339 +Module Creation Notes
340 +=====================
342 +For those creating tslib modules, it is important to note a couple things with
343 +regard to handling of the ability for a user to request more than one ts event
344 +at a time. The first thing to note is that the lower layers may send up less
345 +events than the user requested, but only if that was a result of a pen release.
346 +Next, your module should send up just as many events as the user requested in
347 +nr. If your module is one that consumes events, such as variance, then you
348 +loop on the read from the lower layers, and only send the events up when
349 +1) you have the number of events requested by the user, or 2) one of the events
350 +from the lower layers was a pen release.
355 --- tslib/src/ts_read_raw.c~multievent
356 +++ tslib/src/ts_read_raw.c
359 * Read raw pressure, x, y, and timestamp from a touchscreen device.
370 #include <sys/time.h>
371 #include <sys/types.h>
373 -#ifdef USE_INPUT_API
374 -#include <linux/input.h>
376 -struct ts_event { /* Used in UCB1x00 style touchscreens (the default) */
377 - unsigned short pressure;
380 - unsigned short pad;
381 - struct timeval stamp;
383 -struct h3600_ts_event { /* Used in the Compaq IPAQ */
384 - unsigned short pressure;
387 - unsigned short pad;
389 -struct mk712_ts_event { /* Used in the Hitachi Webpad */
390 - unsigned int header;
393 - unsigned int reserved;
395 -struct arctic2_ts_event { /* Used in the IBM Arctic II */
396 - signed short pressure;
402 -struct collie_ts_event { /* Used in the Sharp Zaurus SL-5000d and SL-5500 */
406 - long long millisecs;
408 -struct corgi_ts_event { /* Used in the Sharp Zaurus SL-C700 */
414 -#endif /* USE_INPUT_API */
416 #include "tslib-private.h"
418 -int ts_read_raw(struct tsdev *ts, struct ts_sample *samp, int nr)
421 +#include <linux/input.h>
423 +static inline int get_input_event(struct tsdev *ts, struct ts_sample *samp) {
424 struct input_event ev;
426 - struct ts_event *evt;
427 - struct h3600_ts_event *hevt;
428 - struct mk712_ts_event *mevt;
429 - struct arctic2_ts_event *aevt;
430 - struct collie_ts_event *collie_evt;
431 - struct corgi_ts_event *corgi_evt;
432 -#endif /* USE_INPUT_API */
435 + struct timeval tv = {0, 0};
439 - char *tseventtype=NULL;
440 - char *defaulttseventtype="UCB1x00";
442 + static int curr_x = 0, curr_y = 0;
443 + int curr_p = 0, next_x = 0, next_y = 0;
445 -#ifdef USE_INPUT_API
446 - /* warning: maybe those static vars should be part of the tsdev struct? */
447 - static int curr_x = 0, curr_y = 0, curr_p = 0;
448 - static int got_curr_x = 0, got_curr_y = 0;
449 - int got_curr_p = 0;
450 - int next_x, next_y;
451 + /* state variables */
452 + int got_curr_x = 0, got_curr_y = 0, got_curr_p = 0;
453 int got_next_x = 0, got_next_y = 0;
456 - while (total < nr) {
458 ret = read(ts->fd, &ev, sizeof(struct input_event));
459 if (ret < sizeof(struct input_event)) break;
461 @@ -146,177 +94,231 @@
465 - if ( (!got_curr_x || !got_curr_y) && !got_curr_p &&
466 - !got_next_x && !got_next_y ) {
468 - * The current event is not complete yet.
469 - * Give the kernel a chance to feed us more.
471 - struct timeval tv = {0, 0};
474 - FD_SET(ts->fd, &fdset);
475 - ret = select(ts->fd+1, &fdset, NULL, NULL, &tv);
476 - if (ret == 1) continue;
477 - if (ret == -1) break;
478 + if (got_curr_x && got_curr_y && got_curr_p) {
479 + /* we have a complete event */
482 + samp->pressure = curr_p;
483 + ret = 0; /* indicate success */
484 + if (got_next_x) curr_x = next_x;
485 + if (got_next_y) curr_y = next_y;
489 - /* We consider having a complete ts event */
492 - samp->pressure = curr_p;
494 - fprintf(stderr,"RAW---------------------------> %d %d %d\n",samp->x,samp->y,samp->pressure);
499 - /* get ready for next event */
500 - if (got_next_x) curr_x = next_x; else got_curr_x = 0;
501 - if (got_next_y) curr_y = next_y; else got_curr_y = 0;
502 - got_next_x = got_next_y = got_tstamp = 0;
504 + * The current event is not complete yet.
505 + * Give the kernel a chance to feed us more.
508 + FD_SET(ts->fd, &fdset);
509 + ret = select(ts->fd+1, &fdset, NULL, NULL, &tv);
510 + if (ret == 1) continue;
511 + if (ret == -1) break;
515 - if (total) ret = total;
516 +// fprintf(stdout, "%s: returning %d\n", __FUNCTION__, ret);
517 + if (ret != 0) ret = -1;
523 +struct ucb1x00_ts_event { /* Used in UCB1x00 style touchscreens (the default) */
524 + unsigned short pressure;
527 + unsigned short pad;
528 + struct timeval stamp;
530 +struct h3600_ts_event { /* Used in the Compaq IPAQ */
531 + unsigned short pressure;
534 + unsigned short pad;
536 +struct mk712_ts_event { /* Used in the Hitachi Webpad */
537 + unsigned int header;
540 + unsigned int reserved;
542 +struct arctic2_ts_event { /* Used in the IBM Arctic II */
543 + signed short pressure;
549 +struct collie_ts_event { /* Used in the Sharp Zaurus SL-5000d and SL-5500 */
553 + long long millisecs;
555 +struct corgi_ts_event { /* Used in the Sharp Zaurus SL-C700 */
562 +static inline int get_ucb1x00_event(struct tsdev *ts, struct ts_sample *samp) {
563 + struct ucb1x00_ts_event evt;
564 + int ret = read(ts->fd, &evt, sizeof(struct ucb1x00_ts_event));
568 + samp->pressure = evt.pressure;
569 + samp->tv.tv_usec = evt.stamp.tv_usec;
570 + samp->tv.tv_sec = evt.stamp.tv_sec;
571 + ret = 0; /* success */
576 +static inline int get_h3600_event(struct tsdev *ts, struct ts_sample *samp) {
577 + struct h3600_ts_event evt;
578 + int ret = read(ts->fd, &evt, sizeof(struct h3600_ts_event));
582 + samp->pressure = evt.pressure;
583 + gettimeofday(&samp->tv, NULL);
584 + ret = 0; /* success */
589 +static inline int get_mk712_event(struct tsdev *ts, struct ts_sample *samp) {
590 + struct mk712_ts_event evt;
591 + int ret = read(ts->fd, &evt, sizeof(struct mk712_ts_event));
593 + samp->x = (short)evt.x;
594 + samp->y = (short)evt.y;
599 + gettimeofday(&samp->tv, NULL);
600 + ret = 0; /* success */
605 +static inline int get_arctic2_event(struct tsdev *ts, struct ts_sample *samp) {
606 + struct arctic2_ts_event evt;
607 + int ret = read(ts->fd, &evt, sizeof(struct arctic2_ts_event));
609 + samp->x = (short)evt.x;
610 + samp->y = (short)evt.y;
611 + samp->pressure = evt.pressure;
612 + gettimeofday(&samp->tv, NULL);
613 + ret = 0; /* success */
618 +static inline int get_collie_event(struct tsdev *ts, struct ts_sample *samp) {
619 + struct collie_ts_event evt;
620 + int ret = read(ts->fd, &evt, sizeof(struct collie_ts_event));
624 + samp->pressure = evt.pressure;
625 + samp->tv.tv_usec = evt.millisecs % 1000;
626 + samp->tv.tv_sec = evt.millisecs / 1000;
627 + ret = 0; /* success */
632 +static inline int get_corgi_event(struct tsdev *ts, struct ts_sample *samp) {
633 + struct corgi_ts_event evt;
634 + int ret = read(ts->fd, &evt, sizeof(struct corgi_ts_event));
638 + samp->pressure = evt.pressure;
639 + samp->tv.tv_usec = evt.millisecs % 1000;
640 + samp->tv.tv_sec = evt.millisecs / 1000;
641 + ret = 0; /* success */
648 +int ts_read_raw(struct tsdev *ts, struct ts_sample *samp, int nr)
653 + static short x_save = 0, y_save = 0;
654 + static int pthres = -1;
656 +#ifndef USE_INPUT_API
657 + char *tseventtype=NULL;
658 + char *defaulttseventtype="UCB1x00";
659 tseventtype = getenv("TSLIB_TSEVENTTYPE");
660 if(tseventtype==NULL) tseventtype=defaulttseventtype;
663 - if( strcmp(tseventtype,"H3600") == 0) { /* iPAQ style h3600 touchscreen events */
664 - hevt = alloca(sizeof(*hevt) * nr);
665 - ret = read(ts->fd, hevt, sizeof(*hevt) * nr);
667 - int nr = ret / sizeof(*hevt);
668 - while(ret >= sizeof(*hevt)) {
671 - samp->pressure = hevt->pressure;
673 - fprintf(stderr,"RAW---------------------------> %d %d %d\n",samp->x,samp->y,samp->pressure);
675 - gettimeofday(&samp->tv,NULL);
678 - ret -= sizeof(*hevt);
683 - } else if( strcmp(tseventtype,"MK712") == 0) { /* Hitachi Webpad events */
684 - mevt = alloca(sizeof(*mevt) * nr);
685 - ret = read(ts->fd, mevt, sizeof(*mevt) * nr);
687 - int nr = ret / sizeof(*mevt);
688 - while(ret >= sizeof(*mevt)) {
689 - samp->x = (short)mevt->x;
690 - samp->y = (short)mevt->y;
691 - if(mevt->header==0)
696 - fprintf(stderr,"RAW---------------------------> %d %d %d\n",samp->x,samp->y,samp->pressure);
698 - gettimeofday(&samp->tv,NULL);
701 - ret -= sizeof(*mevt);
707 - } else if( strcmp(tseventtype,"ARCTIC2") == 0) { /* IBM Arctic II events */
708 - aevt = alloca(sizeof(*aevt) * nr);
709 - ret = read(ts->fd, aevt, sizeof(*aevt) * nr);
711 - int nr = ret / sizeof(*aevt);
712 - while(ret >= sizeof(*aevt)) {
713 - samp->x = (short)aevt->x;
714 - samp->y = (short)aevt->y;
715 - samp->pressure = aevt->pressure;
717 - fprintf(stderr,"RAW---------------------------> %d %d %d\n",samp->x,samp->y,samp->pressure);
719 - gettimeofday(&samp->tv,NULL);
722 - ret -= sizeof(*aevt);
724 + while ((total < nr) && pen_down) {
725 +// fprintf(stdout, "total: %d, nr: %d\n", total, nr);
726 +#ifdef USE_INPUT_API
727 + ret = get_input_event(ts, samp);
729 + if (strcmp(tseventtype, "H3600") == 0) {
730 + /* iPAQ style h3600 touchscreen events */
731 + ret = get_h3600_event(ts, samp);
732 + } else if (strcmp(tseventtype, "MK712") == 0) {
733 + /* Hitachi Webpad events */
734 + ret = get_mk712_event(ts, samp);
735 + } else if (strcmp(tseventtype, "ARCTIC2") == 0) {
736 + /* IBM Arctic II events */
737 + ret = get_arctic2_event(ts, samp);
738 + } else if (strcmp(tseventtype, "COLLIE") == 0) {
739 + /* Sharp Zaurus SL-5000d/5500 events */
740 + ret = get_collie_event(ts, samp);
741 + } else if (strcmp(tseventtype,"CORGI") == 0) {
742 + /* Sharp Zaurus SL-C700 events */
743 + ret = get_corgi_event(ts, samp);
746 + /* Use normal UCB1x00 type events */
747 + ret = get_ucb1x00_event(ts, samp);
750 + if (ret != 0) break;
752 - } else if( strcmp(tseventtype,"COLLIE") == 0) { /* Sharp Zaurus SL-5000d/5500 events */
753 - collie_evt = alloca(sizeof(*collie_evt) * nr);
754 - ret = read(ts->fd, collie_evt, sizeof(*collie_evt) * nr);
756 - int nr = ret / sizeof(*collie_evt);
757 - while(ret >= sizeof(*collie_evt)) {
758 - samp->x = collie_evt->x;
759 - samp->y = collie_evt->y;
760 - samp->pressure = collie_evt->pressure;
762 - fprintf(stderr,"RAW---------------------------> %d %d %d\n",samp->x,samp->y,samp->pressure);
764 - samp->tv.tv_usec = collie_evt->millisecs % 1000;
765 - samp->tv.tv_sec = collie_evt->millisecs / 1000;
768 - ret -= sizeof(*collie_evt);
769 + if (pthres == -1) {
770 + char *pthresvar = getenv("TSLIB_PTHRES");
772 + if (pthresvar != NULL) {
773 + int p = strtol(pthresvar, (char **)NULL, 10);
774 + if (p != -1) pthres = p;
780 - } else if( strcmp(tseventtype,"CORGI") == 0) { /* Sharp Zaurus SL-C700 events */
781 - corgi_evt = alloca(sizeof(*corgi_evt) * nr);
782 - ret = read(ts->fd, corgi_evt, sizeof(*corgi_evt) * nr);
784 - int nr = ret / sizeof(*corgi_evt);
785 - while(ret >= sizeof(*corgi_evt)) {
786 - samp->x = corgi_evt->x;
787 - samp->y = corgi_evt->y;
788 - samp->pressure = corgi_evt->pressure;
790 - fprintf(stderr,"RAW---------------------------> %d %d %d\n",samp->x,samp->y,samp->pressure);
792 - samp->tv.tv_usec = corgi_evt->millisecs % 1000;
793 - samp->tv.tv_sec = corgi_evt->millisecs / 1000;
796 - ret -= sizeof(*corgi_evt);
798 + if (samp->pressure < pthres) {
799 + /* pen released, send events up */
801 + /* set x and y to previous values */
811 - } else { /* Use normal UCB1x00 type events */
812 - evt = alloca(sizeof(*evt) * nr);
813 - ret = read(ts->fd, evt, sizeof(*evt) * nr);
815 - int nr = ret / sizeof(*evt);
816 - while(ret >= sizeof(*evt)) {
819 - samp->pressure = evt->pressure;
821 - fprintf(stderr,"RAW---------------------------> %d %d %d\n",samp->x,samp->y,samp->pressure);
822 + fprintf(stderr,"RAW---------------------------> %d %d %d\n",samp->x, samp->y, samp->pressure);
824 - samp->tv.tv_usec = evt->stamp.tv_usec;
825 - samp->tv.tv_sec = evt->stamp.tv_sec;
828 - ret -= sizeof(*evt);
837 -#endif /* USE_INPUT_API */
839 + if (ret != 0) ret = -1;
840 + if (total) ret = total;