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