lessen indent, use spaces
[evhz] / evhz.c
1 /* Copyright (C) 2016 Ian Kelling */
2
3 /* Licensed under the Apache License, Version 2.0 (the "License"); */
4 /* you may not use this file except in compliance with the License. */
5 /* You may obtain a copy of the License at */
6
7 /* http://www.apache.org/licenses/LICENSE-2.0 */
8
9 /* Unless required by applicable law or agreed to in writing, software */
10 /* distributed under the License is distributed on an "AS IS" BASIS, */
11 /* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
12 /* See the License for the specific language governing permissions and */
13 /* limitations under the License. */
14 #include <string.h>
15 #include <stdio.h>
16 #include <linux/input.h>
17 #include <fcntl.h>
18 #include <signal.h>
19 #include <getopt.h>
20 #include <unistd.h>
21
22 #define EVENTS 50
23 #define HZ_LIST 64
24
25 typedef struct event_s {
26 int fd;
27 int hz[HZ_LIST];
28 int count;
29 int avghz;
30 double prvtime;
31 char name[128];
32 } event_t;
33
34 int quit = 0;
35
36 void sigint() {
37 quit = 1;
38 }
39
40 int main(int argc, char *argv[]) {
41 int optch;
42 int i;
43 event_t events[EVENTS];
44 int verbose = 1;
45
46 while((optch = getopt(argc, argv, "hn")) != -1) {
47 switch(optch) {
48 case('h'):
49 printf("Usage: %s [-n|-h]\n", argv[0]);
50 printf("-n nonverbose\n");
51 printf("-h help\n");
52 return 0;
53 break;
54 case('n'):
55 verbose = 0;
56 break;
57 }
58 }
59
60 if(geteuid() != 0) {
61 printf("%s must be used as superuser\n", argv[0]);
62 return 1;
63 }
64
65 signal(SIGINT, sigint);
66
67 printf("Press CTRL-C to exit.\n\n");
68
69 memset(events, 0, sizeof(events));
70
71 // List input devices
72 for(i = 0; i < EVENTS; i++) {
73 char device[19];
74
75 sprintf(device, "/dev/input/event%i", i);
76 events[i].fd = open(device, O_RDONLY);
77
78 if(events[i].fd != -1) {
79 ioctl(events[i].fd, EVIOCGNAME(sizeof(events[i].name)), events[i].name);
80 if(verbose) printf("event%i: %s\n", i, events[i].name);
81 }
82 }
83
84 while(!quit) {
85 fd_set set;
86
87 FD_ZERO(&set);
88
89 for(i = 0; i < EVENTS; i++) {
90 if(events[i].fd != -1) {
91 FD_SET(events[i].fd, &set);
92 }
93 }
94
95 if(select(FD_SETSIZE, &set, NULL, NULL, NULL) > 0) {
96 int bytes;
97 struct input_event event;
98
99 for(i = 0; i < EVENTS; i++) {
100 if(events[i].fd == -1 || !FD_ISSET(events[i].fd, &set)) {
101 continue;
102 }
103
104 bytes = read(events[i].fd, &event, sizeof(event));
105
106 if(bytes != sizeof(event)) {
107 continue;
108 }
109
110 if(event.type == EV_REL || event.type == EV_ABS) {
111 double time;
112 int hz;
113
114 time = event.time.tv_sec * 1000 + event.time.tv_usec / 1000;
115 hz = 1000 / (time - events[i].prvtime);
116
117 if(hz > 0) {
118 int j;
119
120 events[i].count++;
121 events[i].hz[events[i].count & (HZ_LIST - 1)] = hz;
122
123 events[i].avghz = 0;
124
125 for(j = 0; j < HZ_LIST; j++) {
126 events[i].avghz += events[i].hz[j];
127 }
128
129 events[i].avghz /= (events[i].count > HZ_LIST) ? HZ_LIST : events[i].count;
130
131 if(verbose) printf("%s: Latest % 5iHz, Average % 5iHz\n", events[i].name, hz, events[i].avghz);
132 }
133
134 events[i].prvtime = time;
135 }
136 }
137 }
138 }
139
140 for(i = 0; i < EVENTS; i++) {
141 if(events[i].fd != -1) {
142 if (events[i].avghz != 0) {
143 printf("\nAverage for %s: % 5iHz\n", events[i].name, events[i].avghz);
144 }
145 close(events[i].fd);
146 }
147 }
148
149 return 0;
150 }