aboutsummaryrefslogtreecommitdiffstats
path: root/main.c
blob: 6ac36b829ab4ffcb63646bea6945b88155d71258 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/input.h>
#include <termios.h>
#include <errno.h>
#include <stdbool.h>
#include <sys/time.h>
#include <time.h>
#include <string.h>

#include "config.h"
#include "keys.h"
#include "utils.h"

static int repeat_counters[256] = { 1 };
static int line_lock = -1;

enum KEY_STATUS { KEY_RELEASE = 0, KEY_PRESS = 1, KEY_REPEAT = 2 };

void usage()
{
	printf("Usage: %s <EVENT_FILE_PATH>.\n", PROGRAM_NAME);
}

void version()
{
	printf("%s (v%s)\n", PROGRAM_FULL_NAME, PROGRAM_VERSION);
	printf("%s\n", PROGRAM_AUTHORS);
}

void print_pure(struct input_event *ie)
{
	if (repeat_counters[ie->code] != 1) {
		printf("%-15s x%-13d\r", key_names[ie->code],
		       repeat_counters[ie->code]);
	} else {
		printf("%s", key_names[ie->code]);
	}

	fflush(stdout);
}

void print_with_time(struct input_event *ie)
{
	struct tm *tm_info;
	char time_buf[64];
	time_t sec = (time_t)ie->input_event_sec;
	tm_info = localtime(&sec);
	strftime(time_buf, sizeof(time_buf), "%F %T", tm_info);

	if (repeat_counters[ie->code] != 1) {
		printf("%s.%06ld: %s x%d\n", time_buf, (long)ie->time.tv_usec,
		       key_names[ie->code], repeat_counters[ie->code]);
	} else {
		printf("%s.%06ld: %s\n", time_buf, (long)ie->time.tv_usec,
		       key_names[ie->code]);
	}

	return;
}

int main(int argc, char **argv)
{
	if (argv[1] != NULL &&
	    (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-h") == 0)) {
		usage();
		return -1;
	} else if (argv[1] != NULL && (strcmp(argv[1], "--version") == 0 ||
				       strcmp(argv[1], "-v")) == 0) {
		version();
		return -1;
	}

	setvbuf(stdout, NULL, _IONBF, 0);
	disable_term_echo();

	struct config *cfg = config_init();
	if (!cfg) {
		return -1;
	}

	printf("Device: %s\n", cfg->device);

	struct input_event ie;
	int fd = open(cfg->device, O_RDONLY);

	if (fd == -1 && errno == EACCES) {
		printf("Permission denied: please run %s with sudo.\n",
		       PROGRAM_NAME);
		return -1;
	}

	if (fd == -1 && errno == ENOENT) {
		printf("Invalid device, please check your config file.\n");
		return -1;
	}

	init_key_names();

	void (*fp)(struct input_event * ie) =
		(cfg->time == true) ? print_with_time : print_pure;

	while (1) {
		read(fd, &ie, sizeof(ie));
		if (ie.type == EV_KEY) {
			if (ie.value == KEY_PRESS) {
				if (line_lock != -1 && !cfg->time)
					printf("\n");
				repeat_counters[ie.code] = 1;
				line_lock = ie.code;
				fp(&ie);
			}

			if (ie.value == KEY_REPEAT) {
				if (cfg->time) {
					if (cfg->time)
						printf("\r\033[K");
				}
				line_lock = ie.code;
				repeat_counters[ie.code]++;
				fp(&ie);
			}
		}
	}

	enable_term_echo();
	return 0;
}