Working locally and in X! A bit chatty at the moment

Change-Id: Ica9e11419243d8b46ea150f3a6153f73cdf7a4e3
Reviewed-on: https://gerrit.chromium.org/gerrit/42739
Reviewed-by: Andrew de los Reyes <adlr@chromium.org>
Tested-by: Andrew de los Reyes <adlr@chromium.org>
diff --git a/Makefile b/Makefile
index ad7b65a..8e981eb 100644
--- a/Makefile
+++ b/Makefile
@@ -52,7 +52,7 @@
 all: $(SONAME) $(EXE)
 
 $(SONAME): $(OBJECTS)
-	$(CXX) -shared -o $@ $(SO_OBJECTS) -Wl,-h$(SONAME:$(OBJDIR)/%=%) \
+	$(CXX) -shared -o $@ $(OBJECTS) -Wl,-h$(SONAME:$(OBJDIR)/%=%) \
 		$(LINK_FLAGS)
 
 $(EXE): $(OBJECTS) $(MAINOBJ)
diff --git a/input_event_filter.cc b/input_event_filter.cc
index ce5ec52..0fd152c 100644
--- a/input_event_filter.cc
+++ b/input_event_filter.cc
@@ -4,12 +4,16 @@
 
 #include "touch_noise_filter/input_event_filter.h"
 
+#include <linux/input.h>
+#include <stdio.h>
+
 #include <base/basictypes.h>
 
 namespace touch_noise_filter {
 
 InputEventFilter::InputEventFilter(NoiseFilter* next)
-    : current_frame_(0), next_(next), current_slot_(0) {
+    : current_frame_(0), current_touching_(0), prev_touching_(0),
+      next_(next), current_slot_(0) {
   for (size_t i = 0; i < arraysize(frames_); i++) {
     for (size_t j = 0; j < arraysize(frames_[i].fingers_); j++) {
       frames_[i].fingers_[j].slot_ = j;
@@ -17,6 +21,80 @@
   }
 }
 
+namespace {
+#define SETSTR(type_num, code_num) \
+  do { \
+    if ((ev)->type == type_num) { \
+      type_str = #type_num; \
+      if ((ev)->code == code_num) { \
+        code_str = #code_num; \
+      } \
+    } \
+  } while (0)
+
+double TimevalToDouble(const struct timeval& tv) {
+  // printf("%ld usec\n", tv.tv_usec);
+  return static_cast<double>(tv.tv_sec) + static_cast<double>(tv.tv_usec) /
+    1000000.0;
+}
+
+void LogInputEvent(const struct input_event* ev) {
+  const char* type_str = "(unknown)";
+  const char* code_str = "(unknown)";
+
+  SETSTR(EV_KEY, BTN_TOUCH);
+
+  SETSTR(EV_ABS, ABS_X);
+  SETSTR(EV_ABS, ABS_Y);
+  SETSTR(EV_ABS, ABS_Z);
+  SETSTR(EV_ABS, ABS_RX);
+  SETSTR(EV_ABS, ABS_RY);
+  SETSTR(EV_ABS, ABS_RZ);
+  SETSTR(EV_ABS, ABS_THROTTLE);
+  SETSTR(EV_ABS, ABS_RUDDER);
+  SETSTR(EV_ABS, ABS_WHEEL);
+  SETSTR(EV_ABS, ABS_GAS);
+  SETSTR(EV_ABS, ABS_BRAKE);
+  SETSTR(EV_ABS, ABS_HAT0X);
+  SETSTR(EV_ABS, ABS_HAT0Y);
+  SETSTR(EV_ABS, ABS_HAT1X);
+  SETSTR(EV_ABS, ABS_HAT1Y);
+  SETSTR(EV_ABS, ABS_HAT2X);
+  SETSTR(EV_ABS, ABS_HAT2Y);
+  SETSTR(EV_ABS, ABS_HAT3X);
+  SETSTR(EV_ABS, ABS_HAT3Y);
+  SETSTR(EV_ABS, ABS_PRESSURE);
+  SETSTR(EV_ABS, ABS_DISTANCE);
+  SETSTR(EV_ABS, ABS_TILT_X);
+  SETSTR(EV_ABS, ABS_TILT_Y);
+  SETSTR(EV_ABS, ABS_TOOL_WIDTH);
+
+  SETSTR(EV_ABS, ABS_MT_SLOT);
+  SETSTR(EV_ABS, ABS_MT_TOUCH_MAJOR);
+  SETSTR(EV_ABS, ABS_MT_TOUCH_MINOR);
+  SETSTR(EV_ABS, ABS_MT_WIDTH_MAJOR);
+  SETSTR(EV_ABS, ABS_MT_WIDTH_MINOR);
+  SETSTR(EV_ABS, ABS_MT_ORIENTATION);
+  SETSTR(EV_ABS, ABS_MT_POSITION_X);
+  SETSTR(EV_ABS, ABS_MT_POSITION_Y);
+  SETSTR(EV_ABS, ABS_MT_TOOL_TYPE);
+  SETSTR(EV_ABS, ABS_MT_BLOB_ID);
+  SETSTR(EV_ABS, ABS_MT_TRACKING_ID);
+  SETSTR(EV_ABS, ABS_MT_PRESSURE);
+  SETSTR(EV_ABS, ABS_MT_DISTANCE);
+
+  if (ev->type == 0 && ev->code == 0) {
+    TouchNoiseFilterLog("INPUT: %f ---------- SYN_REPORT ----------\n",
+           TimevalToDouble(ev->time));
+  } else {
+    TouchNoiseFilterLog("INPUT: %f %s %s %d\n",
+           TimevalToDouble(ev->time), type_str, code_str, ev->value);
+  }
+}
+
+#undef SETSTR
+}  // namespace {}
+
 void InputEventFilter::HandleInputEvent(const struct input_event* ev) {
   static const __u16 kMinKey = ABS_MT_TOUCH_MAJOR;
   
@@ -42,6 +120,12 @@
         case ABS_MT_SLOT:
           current_slot_ = ev->value;
           break;
+        case ABS_MT_TRACKING_ID:
+          if (ev->value >= 0)
+            current_touching_ |= (1ULL << current_slot_);
+          else
+            current_touching_ &= ~(1ULL << current_slot_);
+          // fallthrough
         default:
           if (ev->code < kMinKey ||
               ev->code >= kMinKey + arraysize(member_map) ||
@@ -49,6 +133,7 @@
             break;
           CurrentFrame()->fingers_[
               current_slot_].*member_map[ev->code - kMinKey] = ev->value;
+          
           break;
       }
       break;
@@ -56,22 +141,28 @@
     case EV_SYN: {
       for (size_t i = 0; i < arraysize(frames_[0].fingers_); i++) {
         Finger* cur_finger = &CurrentFrame()->fingers_[i];
-        Finger* prev_finger = &PrevFrame()->fingers_[i];
         // New fingers should have their cancelled_ bit cleared
-        if (cur_finger->tracking_id_ > -1 && prev_finger->tracking_id_ == -1)
+        if ((current_touching_ & (1ULL << i)) &&
+            !(prev_touching_ & (1ULL << i)))
           cur_finger->cancelled_ = false;
+        cur_finger->timestamp_ = TimevalToDouble(ev->time);
         next_->FilterFinger(cur_finger);
       }
-      current_frame_ ^= 1;
+      prev_touching_ = current_touching_;
       break;
     }
   }
 }
 
 void InputEventFilter::GetCancelledTouches(uint64_t* slots_mask) {
-  for (size_t i = 0; i < arraysize(frames_[0].fingers_); i++)
-    if (PrevFrame()->fingers_[i].cancelled_)
+  for (size_t i = 0; i < arraysize(frames_[0].fingers_); i++) {
+    if (CurrentFrame()->fingers_[i].cancelled_) {
       (*slots_mask) |= 1 << i;
+      // If the finger was released, we can lose the cancel bit
+      if (!(prev_touching_ & (1ULL << i)))
+        CurrentFrame()->fingers_[i].cancelled_ = 0;
+    }
+  }
 }
 
 }  // namespace touch_noise_filter
diff --git a/input_event_filter.h b/input_event_filter.h
index 6f6e320..71d42c4 100644
--- a/input_event_filter.h
+++ b/input_event_filter.h
@@ -37,9 +37,13 @@
   Frame* CurrentFrame() { return &frames_[current_frame_]; }
   Frame* PrevFrame() { return &frames_[current_frame_ ^ 1]; }
 
-  Frame frames_[2];
+  Frame frames_[1];
   size_t current_frame_;
-  
+
+  // bitmasks of which slots have touches
+  uint64_t current_touching_;
+  uint64_t prev_touching_;  
+
   scoped_ptr<NoiseFilter> next_;
   size_t current_slot_;
 };
diff --git a/main.cc b/main.cc
index ecb3d1c..cd29244 100644
--- a/main.cc
+++ b/main.cc
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <math.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -35,8 +36,8 @@
 
 struct timeval TimevalFromDouble(double when) {
   long int_part = static_cast<long>(when);
-  long micro_part = static_cast<long>(1000000.0 *
-                                      static_cast<double>(int_part) - when);
+  long micro_part = static_cast<long>(static_cast<double>(1000000.0) *
+                                      fmod(when, 1.0) + 0.5);
   struct timeval tv = { int_part, micro_part };
   return tv;
 }
@@ -68,14 +69,16 @@
     if (cancelled) {
       printf("CANCELLED SLOTS: ");
       for (size_t i = 0; i < 8 * sizeof(cancelled); i++) {
-        if (!(cancelled & (1 << i)))
+        if (!(cancelled & (1ULL << i)))
           continue;
         printf("%zu ", i);
       }
       printf("\n");
     }
   }
-  printf("GOT LINE: %f %x %x %d\n", when, type, code, value);
+  // printf("GOT LINE: %f (%ld . %ld)%x %x %d\n", when * 10000,
+  //        ev.time.tv_sec, ev.time.tv_usec,
+  //        type, code, value);
 }
 
 int main(int argc, char** argv) {
diff --git a/single_frame_tap_filter.cc b/single_frame_tap_filter.cc
index e1a8586..e0a9840 100644
--- a/single_frame_tap_filter.cc
+++ b/single_frame_tap_filter.cc
@@ -7,25 +7,34 @@
 #include <base/basictypes.h>
 
 #include <cstddef>
+#include <cstdio>
 
 namespace touch_noise_filter {
 
 namespace {
-double kMaxTapDuration = 0.015;
+double kMaxTapDuration = 0.1;
 }  // namespace {}
 
 void SingleFrameTapFilter::FilterFinger(Finger* finger) {
   Finger* prev_finger = &prev_fingers_[finger->slot_];
+  Log("got finger at %f in slot %d", finger->timestamp_,
+    finger->slot_);
 
   bool arrived = prev_finger->tracking_id_ == -1 && finger->tracking_id_ > 0;
   bool departing = prev_finger->tracking_id_ >= 0 && finger->tracking_id_ == -1;
-  if (prev_arrived_ && departing &&
-      (prev_finger->timestamp_ - finger->timestamp_ < kMaxTapDuration))
+  if ((prev_arrived_ & (1ULL << finger->slot_)) && departing &&
+      (finger->timestamp_ - prev_finger->timestamp_ < kMaxTapDuration)) {
     finger->cancelled_ = true;
+    TouchNoiseFilterLog("CANCEL AT %f, %d\n",
+                        finger->timestamp_, finger->slot_);
+  }
   
   // Store previous info
   *prev_finger = *finger;
-  prev_arrived_ = arrived;
+  if (arrived)
+    prev_arrived_ |= 1ULL << finger->slot_;
+  else
+    prev_arrived_ &= ~(1ULL << finger->slot_);
 }
 
 }  // namespace touch_noise_filter
diff --git a/touch_noise_filter.cc b/touch_noise_filter.cc
index aa78ce8..00556d9 100644
--- a/touch_noise_filter.cc
+++ b/touch_noise_filter.cc
@@ -19,10 +19,13 @@
 extern "C" {
 
 void* NewXFilter() {
+  Log("In NewXFilter");
   NoiseFilter* filters[] = {
     new SingleFrameTapFilter
   };
-  return new InputEventFilter(new MuxFilter(filters, arraysize(filters)));
+  void* ret = new InputEventFilter(new MuxFilter(filters, arraysize(filters)));
+  Log("Exiting NewXFilter");
+  return ret;
 }
 
 void FreeXFilter(void* x_filter) {