summaryrefslogtreecommitdiff
path: root/sleep_good.c
blob: 638235214cc9c6caa8464308e3e21b7ec638f223 (plain)
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
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <termios.h>
#include <string.h>
#include <poll.h>

int parse(char *s) {
	int cur=0,tot=0;
	int pos; char c;
	for (pos=0; c=s[pos],c!=0; pos++) {
		if ('0'<=c && c<='9') {
			cur*=10;
			cur+=c-'0';
		} else {
			switch(c) {
			case 'h': cur *= 60;
			case 'm': cur *= 60;
			case 's': break;
			default: return -1;
			}
			tot+=cur; cur=0;
		}
	}
	return tot+cur;
}

void disp(int secs) {
	int rem;
	int h = secs/3600; rem= secs%3600;
	int m = rem/60;    int s = rem%60; 
	if (h>0) printf("%02dh",h);
	if (h>0||m>0) printf("%02dm",m);
	printf("%02ds",s);
	fflush(stdout);
}

int main(int argc, char **argv) {
	if (argc != 2) {
		fprintf(stderr, "usage: %s TIMESPEC\n", argv[0]);
		exit(1);
	}

	int secs = parse(argv[1]);
	if (secs==0) return 0;
	if (secs<0) {
		fprintf(stderr, "%s: invalid timespec %s\n", argv[0], argv[1]);
		exit(1);
	}

	struct termios orig_term, new_term;
	tcgetattr(0, &orig_term);
	memcpy(&new_term, &orig_term, sizeof(struct termios));
	cfmakeraw(&new_term);
	tcsetattr(0, TCSADRAIN, &new_term);

	int paused = 0;
	struct pollfd pf = {
		.fd = 0,
		.events = POLLIN,
	};
	while (secs>0) {
		if (paused) printf("[paused] ");
		disp(secs);
		int rc = poll(&pf, 1, paused ? -1 : 1000);
		if (rc == 0 && !paused) secs--;

		printf("\033[2K\033[G");
		if (pf.revents & POLLIN) {
			char c;
			read(0,&c,1);
			switch(c){
			case 'q':
			case 3: // ctrl-C
				goto end;
			case '+':
				secs+=10;
				break;
			case '=':
				secs++;
				break;
			case '_':
				secs -= 10;
				if (secs <= 0) secs=10;
				break;
			case '-':
				secs--;
				if (secs <= 0) secs=1;
				break;
			case ' ':
				paused = !paused;
				break;
			}
		}
	}
end:
	tcsetattr(0, TCSADRAIN, &orig_term);
	return 0;
}