README: mention SDL2 backend
[rofl0r-concol.git] / color_reader.c
blobaa78e1aef79a54a57b8d1c2cb2aecc8475bd605b
1 #include <unistd.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <ctype.h>
5 #include <fcntl.h>
6 #include <termios.h>
7 #include <string.h>
8 #include <sys/select.h>
9 #include "rgb.h"
10 #include "color_reader.h"
12 #ifndef XCASE
13 #define XCASE 0
14 #endif
16 static int byte_from_hex(const char* s, unsigned char* out) {
17 static const char hex[] = "0123456789abcdef";
18 char* h1 = strchr(hex, s[0]);
19 char* h2 = strchr(hex, s[1]);
20 if(!h1 || !h2) return 1;
21 *out = ((h1 - hex) << 4) | (h2 - hex);
22 return 0;
25 int color_reader_init(struct color_reader *cr) {
26 if(-1==(cr->fd = open("/dev/tty", O_RDWR|O_CLOEXEC))) return 1;
27 if(-1==tcgetattr(cr->fd, &cr->t)) goto err;
28 struct termios new = cr->t;
29 new.c_iflag = 0;
30 new.c_oflag &= ~OPOST;
31 new.c_lflag &= ~(ISIG | ICANON | ECHO | XCASE);
32 new.c_cc[VMIN] = 0;
33 new.c_cc[VTIME] = 0;
34 if(-1==tcsetattr(cr->fd, TCSAFLUSH, &new)) goto err;
35 tcdrain(cr->fd);
36 return 0;
37 err:
38 close(cr->fd);
39 return 1;
42 int color_reader_get_color(struct color_reader *cr, int colnr, rgb_t*out) {
43 char buf[128], *p;
44 unsigned l;
45 fd_set reed;
47 dprintf(cr->fd, "\x1b]4;%d;?\x1b\x5c", colnr);
48 FD_ZERO(&reed);
49 FD_SET(cr->fd, &reed);
50 while(select(cr->fd+1, &reed, 0, 0, 0)<=0);
51 for(l=0,p=buf;l<sizeof(buf);l++,p++) {
52 ssize_t rd;
53 if(1==(rd=read(cr->fd, p, 1))) continue;
54 if(rd < 0) return 2;
56 if(l<23) return 3;
57 *p = 0, p = buf;
58 if(memcmp(p,"\x1b]4;",4)) return 4;
59 p+=4;l-=4;
60 while(l>4 && memcmp(p,"rgb:",4)) p++,l--;
61 p+=4;l-=4;
62 if(l<14) return 5;
63 if(byte_from_hex(p, &out->r)) return 6;
64 p+=5;
65 if(byte_from_hex(p, &out->g)) return 7;
66 p+=5;
67 if(byte_from_hex(p, &out->b)) return 8;
68 return 0;
70 int color_reader_close(struct color_reader *cr) {
71 int err = 0;
72 if(tcsetattr(cr->fd, TCSAFLUSH, &cr->t)==-1) err=1;
73 close(cr->fd);
74 return err;