| // Copyright (c) 2013 The Chromium OS Authors. All rights reserved. |
| // 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> |
| #include <string.h> |
| |
| #include <linux/input.h> |
| |
| #include "touch_noise_filter/touch_noise_filter.h" |
| |
| void TouchNoiseFilterLog(int verb, const char* format, ...) { |
| va_list args; |
| va_start(args, format); |
| vprintf(format, args); |
| va_end(args); |
| } |
| |
| __attribute__((noreturn)) // to appease g++ |
| void usage(const char* argv0) { |
| printf("Usage: %s logfile\n", argv0); |
| exit(1); |
| } |
| |
| #define PERROR_ASSERT(x, str) \ |
| do { \ |
| bool success = (x); \ |
| if (!success) { \ |
| perror(str); \ |
| exit(1); \ |
| } \ |
| } while (0); |
| |
| struct timeval TimevalFromDouble(double when) { |
| long int_part = static_cast<long>(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; |
| } |
| |
| void ParseLine(const char* line, void* x_filter) { |
| const char kPrefix[] = "E: "; |
| if (strncmp(line, kPrefix, strlen(kPrefix))) |
| return; // doesn't have prefix |
| |
| double when; |
| int type; |
| int code; |
| int value; |
| |
| PERROR_ASSERT( |
| sscanf(line, "E: %lf %x %x %d", &when, &type, &code, &value) == 4, |
| "sscanf"); |
| |
| struct input_event ev = { |
| TimevalFromDouble(when), |
| static_cast<__u16>(type), |
| static_cast<__u16>(code), |
| static_cast<__s32>(value) |
| }; |
| XFilterHandleInputEvent(x_filter, &ev); |
| if (type == 0 && code == 0 && value == 0) { |
| uint64_t canceled = 0; |
| XFilterGetCanceledTouches(x_filter, &canceled); |
| if (canceled) { |
| printf("CANCELED SLOTS: "); |
| for (size_t i = 0; i < 8 * sizeof(canceled); i++) { |
| if (!(canceled & (1ULL << i))) |
| continue; |
| printf("%zu ", i); |
| } |
| printf("\n"); |
| } |
| } |
| // 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) { |
| if (argc < 2) |
| usage(argv[0]); |
| const char* filename = argv[1]; |
| |
| void* x_filter = NewXFilter(); |
| |
| FILE* fp = fopen(filename, "r"); |
| PERROR_ASSERT(fp, "fopen"); |
| while (true) { |
| char buf[1024]; |
| char* result = fgets(buf, sizeof(buf), fp); |
| if (result == NULL) |
| break; |
| ParseLine(buf, x_filter); |
| } |
| fclose(fp); |
| |
| FreeXFilter(x_filter); |
| } |