8d769cc9 |
1 | #include <errno.h> |
2 | #include <unistd.h> |
3 | #include <termios.h> |
4 | #include <stdio.h> |
5 | #include <stdlib.h> |
6 | #include <string.h> |
7 | #include <fcntl.h> |
8 | |
8d769cc9 |
9 | int main(int argc, char *argv[]) |
8d769cc9 |
10 | { |
11 | int query = 0; |
12 | int fd; |
13 | int openned = 0; |
b2ffb9b7 |
14 | int i; |
8d769cc9 |
15 | |
8d769cc9 |
16 | for (;;) { |
b2ffb9b7 |
17 | i = getopt(argc, argv, "q"); |
8d769cc9 |
18 | if (i < 0) |
19 | break; |
20 | switch (i) { |
21 | case 'q': |
22 | query = 1; |
23 | break; |
24 | default: |
b2ffb9b7 |
25 | fprintf(stderr, "usage: xtitle [-q] [STRING]\n"); |
8d769cc9 |
26 | return (1); |
27 | } |
28 | } |
29 | |
8d769cc9 |
30 | if (!query && optind == argc) { |
8d769cc9 |
31 | fprintf(stderr, "xtitle: no string to set\n"); |
32 | return (1); |
33 | } |
34 | |
35 | { |
36 | char *t = getenv("TERM"); |
37 | if (!t || strncmp(t, "xterm", 5)) |
38 | return (0); |
39 | } |
40 | |
41 | if (isatty(0)) |
42 | fd = 0; |
43 | else { |
44 | fd = open("/dev/tty", O_RDWR); |
45 | if (fd < 0) { |
46 | fprintf(stderr, "xtitle: couldn't open terminal: %s", strerror(errno)); |
47 | return (1); |
48 | } |
49 | openned = 1; |
50 | } |
51 | |
52 | if (!query) { |
8d769cc9 |
53 | char sp = ' '; |
54 | write(fd, "\33]0;", 4); |
55 | for (i = optind; i < argc; i++) { |
56 | write(fd, argv[i], strlen(argv[i])); |
57 | if (i < argc - 1) |
58 | write(fd, &sp, 1); |
59 | } |
60 | write(fd, "\7", 2); |
8d769cc9 |
61 | } else { |
62 | struct termios o, n; |
63 | char hack; |
64 | int state = 0; |
65 | |
66 | tcgetattr(fd, &o); |
67 | n = o; |
68 | n.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP |
69 | |INLCR|IGNCR|ICRNL|IXON); |
70 | n.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); |
71 | n.c_cflag &= ~(CSIZE|PARENB); |
72 | n.c_cflag |= CS8; |
73 | tcsetattr(fd, TCSAFLUSH, &n); |
74 | write(fd, "\33[21t", 5); |
75 | |
76 | while (state != -1) { |
77 | if (read(fd, &hack, 1) < 1) |
78 | break; |
79 | switch (state) { |
80 | case 0: |
81 | if (hack == '\33') state = 1; |
82 | break; |
83 | case 1: |
84 | if (hack == ']') state = 2; else state = 0; |
85 | break; |
86 | case 2: |
87 | if (hack == 'l') state = 3; else state = 0; |
88 | break; |
89 | case 3: |
90 | if (hack == '\33') state = 4; else putchar(hack); |
91 | break; |
92 | case 4: |
93 | if (hack == '\\') { state = -1; putchar('\n'); } |
94 | else { putchar('\33'); putchar(hack); state = 3; } |
95 | break; |
96 | } |
97 | } |
98 | |
99 | tcsetattr(fd, TCSAFLUSH, &o); |
100 | } |
101 | |
102 | if (openned) |
103 | close(fd); |
104 | |
105 | return (0); |
106 | } |