Author: Jaret Cantu <jaret.cantu@timesys.com>
Date:   Fri Sep 25 03:44:00 EST 2020 

    Fix multitouch support

    Currently, devices which report multitouch support but not regular
    absolute coordinate support will fail. Check for MT support
    specifically.

    Also, devices are required to have some sort of down event if they
    do not provide pressure. Multitouch devices typically use an empty
    set of SYN events to mark the stop of a tracked touch, so overload
    the using_syn data member for this purpose.

diff -Naur tslib-1.22.orig/plugins/input-raw.c tslib-1.22/plugins/input-raw.c
--- tslib-1.22.orig/plugins/input-raw.c	2020-03-12 14:41:13.000000000 +0530
+++ tslib-1.22/plugins/input-raw.c	2020-09-23 12:39:09.490319057 +0530
@@ -111,6 +111,10 @@
 
 #define NUM_EVENTS_READ 1 /* internal. independent from the user call */
 
+#define USE_EV_SYN		1
+#define USE_SYN_FOR_UP		2
+#define SYN_TOUCH_DATA		4
+
 struct tslib_input {
 	struct tslib_module_info module;
 
@@ -245,8 +249,10 @@
 	}
 
 	if ((ioctl(ts->fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit)) < 0 ||
-	    !(absbit[BIT_WORD(ABS_X)] & BIT_MASK(ABS_X)) ||
-	    !(absbit[BIT_WORD(ABS_Y)] & BIT_MASK(ABS_Y))) {
+		!((absbit[BIT_WORD(ABS_X)] & BIT_MASK(ABS_X)) ||
+		  (absbit[BIT_WORD(ABS_MT_POSITION_X)] & BIT_MASK(ABS_MT_POSITION_X))) ||
+		!((absbit[BIT_WORD(ABS_Y)] & BIT_MASK(ABS_Y)) ||
+		  (absbit[BIT_WORD(ABS_MT_POSITION_Y)] & BIT_MASK(ABS_MT_POSITION_Y)))) {
 		if (!(absbit[BIT_WORD(ABS_MT_POSITION_X)] & BIT_MASK(ABS_MT_POSITION_X)) ||
 		    !(absbit[BIT_WORD(ABS_MT_POSITION_Y)] & BIT_MASK(ABS_MT_POSITION_Y))) {
 			fprintf(stderr,
@@ -255,6 +261,9 @@
 		}
 	}
 
+	if (evbit[BIT_WORD(EV_SYN)] & BIT_MASK(EV_SYN))
+		i->using_syn = USE_EV_SYN;
+
 	/* Remember whether we have a multitouch device. We need to know for ABS_X,
 	 * ABS_Y and ABS_PRESSURE data.
 	 */
@@ -274,14 +283,14 @@
 		 */
 		if (!(keybit[BIT_WORD(BTN_TOUCH)] & BIT_MASK(BTN_TOUCH) ||
 		      keybit[BIT_WORD(BTN_LEFT)] & BIT_MASK(BTN_LEFT)) && !i->mt) {
-			fprintf(stderr,
-				"tslib: Selected device is not a touchscreen (missing BTN_TOUCH or BTN_LEFT)\n");
-			return -1;
+			if (!i->using_syn) {
+				fprintf(stderr, "tslib: Selected device is not a touchscreen (must support BTN_TOUCH or BTN_LEFT events)\n");
+				return -1;
+			}
+			i->using_syn = USE_SYN_FOR_UP;
 		}
 	}
 
-	if (evbit[BIT_WORD(EV_SYN)] & BIT_MASK(EV_SYN))
-		i->using_syn = 1;
 
 	/* read device info and set special device nr */
 	get_special_device(i);
@@ -379,7 +388,8 @@
 			case EV_SYN:
 				if (ev.code == SYN_REPORT) {
 					/* Fill out a new complete event */
-					if (pen_up) {
+					if (pen_up ||
+					    (i->using_syn & (USE_SYN_FOR_UP | SYN_TOUCH_DATA)) == USE_SYN_FOR_UP) { /* spoof up event on sync without data */
 						samp->x = 0;
 						samp->y = 0;
 						samp->pressure = 0;
@@ -388,6 +398,7 @@
 						samp->x = i->current_x;
 						samp->y = i->current_y;
 						samp->pressure = i->current_p;
+					i->using_syn &= ~SYN_TOUCH_DATA;	
 					}
 					samp->tv.tv_sec = ev.input_event_sec;
 					samp->tv.tv_usec = ev.input_event_usec;
@@ -439,21 +450,23 @@
 				} else {
 					switch (ev.code) {
 					case ABS_X:
-						i->current_x = ev.value;
-						break;
-					case ABS_Y:
-						i->current_y = ev.value;
-						break;
 					case ABS_MT_POSITION_X:
 						i->current_x = ev.value;
+					        if (i->using_syn & USE_SYN_FOR_UP)
+						        i->using_syn|= SYN_TOUCH_DATA;
 						i->type_a++;
 						break;
+      				        case ABS_Y:
 					case ABS_MT_POSITION_Y:
 						i->current_y = ev.value;
+					        if (i->using_syn & USE_SYN_FOR_UP)
+ 						        i->using_syn|= SYN_TOUCH_DATA;
 						i->type_a++;
 						break;
 					case ABS_PRESSURE:
 						i->current_p = ev.value;
+					if (i->using_syn & USE_SYN_FOR_UP)
+						i->using_syn|= SYN_TOUCH_DATA;
 						break;
 					case ABS_MT_PRESSURE:
 						i->current_p = ev.value;
