Commit | Line | Data |
---|---|---|
ca67e7b4 C |
1 | /* |
2 | * $Source: /u1/X/xterm/RCS/resize.c,v $ | |
3 | * $Header: resize.c,v 10.101 86/12/02 10:35:30 swick Exp $ | |
4 | */ | |
5 | ||
6 | #ifndef lint | |
7 | static char *rcsid_resize_c = "$Header: resize.c,v 10.101 86/12/02 10:35:30 swick Exp $"; | |
8 | #endif lint | |
9 | ||
10 | #include <X/mit-copyright.h> | |
11 | ||
12 | /* Copyright Massachusetts Institute of Technology 1984 */ | |
13 | ||
14 | /* resize.c */ | |
15 | ||
16 | #include <stdio.h> | |
17 | #include <sgtty.h> | |
18 | #include <strings.h> | |
19 | #include <ctype.h> | |
20 | #include <sys/ioctl.h> | |
21 | #include <signal.h> | |
22 | #include <sys/time.h> | |
23 | ||
24 | #ifndef lint | |
25 | static char sccs_id[] = "@(#)resize.c\tX10/6.6B\t12/26/86"; | |
26 | #endif | |
27 | ||
28 | #define EMULATIONS 2 | |
29 | #define SUN 1 | |
30 | #define TIMEOUT 10 | |
31 | #define VT100 0 | |
32 | ||
33 | char *emuname[EMULATIONS] = { | |
34 | "VT100", | |
35 | "Sun", | |
36 | }; | |
37 | char *myname; | |
38 | int stdsh; | |
39 | char *getsize[EMULATIONS] = { | |
40 | "\0337\033[r\033[999;999H\033[6n", | |
41 | "\033[18t", | |
42 | }; | |
43 | #ifndef sun | |
44 | #ifdef TIOCSWINSZ | |
45 | char *getwsize[EMULATIONS] = { | |
46 | 0, | |
47 | "\033[14t", | |
48 | }; | |
49 | #endif TIOCSWINSZ | |
50 | #endif sun | |
51 | char *restore[EMULATIONS] = { | |
52 | "\0338", | |
53 | 0, | |
54 | }; | |
55 | char *setname = ""; | |
56 | char *setsize[EMULATIONS] = { | |
57 | 0, | |
58 | "\033[8;%s;%st", | |
59 | }; | |
60 | struct sgttyb sgorig; | |
61 | char *size[EMULATIONS] = { | |
62 | "\033[%d;%dR", | |
63 | "\033[8;%d;%dt", | |
64 | }; | |
65 | char sunname[] = "sunsize"; | |
66 | int tty; | |
67 | FILE *ttyfp; | |
68 | #ifndef sun | |
69 | #ifdef TIOCSWINSZ | |
70 | char *wsize[EMULATIONS] = { | |
71 | 0, | |
72 | "\033[4;%hd;%hdt", | |
73 | }; | |
74 | #endif TIOCSWINSZ | |
75 | #endif sun | |
76 | ||
77 | char *strindex (), *index (), *rindex(); | |
78 | ||
79 | main (argc, argv) | |
80 | char **argv; | |
81 | /* | |
82 | resets termcap string to reflect current screen size | |
83 | */ | |
84 | { | |
85 | register char *ptr, *env; | |
86 | register int emu = VT100; | |
87 | int rows, cols; | |
88 | struct sgttyb sg; | |
89 | char termcap [1024]; | |
90 | char newtc [1024]; | |
91 | char buf[BUFSIZ]; | |
92 | #ifdef sun | |
93 | #ifdef TIOCSSIZE | |
94 | struct ttysize ts; | |
95 | #endif TIOCSSIZE | |
96 | #else sun | |
97 | #ifdef TIOCSWINSZ | |
98 | struct winsize ws; | |
99 | #endif TIOCSWINSZ | |
100 | #endif sun | |
101 | char *getenv(); | |
102 | int onintr(); | |
103 | ||
104 | if(ptr = rindex(myname = argv[0], '/')) | |
105 | myname = ptr + 1; | |
106 | if(strcmp(myname, sunname) == 0) | |
107 | emu = SUN; | |
108 | for(argv++, argc-- ; argc > 0 && **argv == '-' ; argv++, argc--) { | |
109 | switch((*argv)[1]) { | |
110 | case 's': /* Sun emulation */ | |
111 | if(emu == SUN) | |
112 | Usage(); /* Never returns */ | |
113 | emu = SUN; | |
114 | break; | |
115 | case 'u': /* Bourne (Unix) shell */ | |
116 | stdsh++; | |
117 | break; | |
118 | default: | |
119 | Usage(); /* Never returns */ | |
120 | } | |
121 | } | |
122 | if(argc == 2) { | |
123 | if(!setsize[emu]) { | |
124 | fprintf(stderr, | |
125 | "%s: Can't set window size under %s emulation\n", | |
126 | myname, emuname[emu]); | |
127 | exit(1); | |
128 | } | |
129 | if(!checkdigits(argv[0]) || !checkdigits(argv[1])) | |
130 | Usage(); /* Never returns */ | |
131 | } else if(argc != 0) | |
132 | Usage(); /* Never returns */ | |
133 | if((ttyfp = fopen("/dev/tty", "r+")) == NULL) { | |
134 | fprintf(stderr, "%s: Can't open /dev/tty\n", myname); | |
135 | exit(1); | |
136 | } | |
137 | tty = fileno(ttyfp); | |
138 | if((env = getenv("TERMCAP")) && *env) | |
139 | strcpy(termcap, env); | |
140 | else { | |
141 | if(!(env = getenv("TERM")) || !*env) { | |
142 | env = "xterm"; | |
143 | if(stdsh) | |
144 | setname = "TERM=xterm;\n"; | |
145 | else setname = "setenv TERM xterm;\n"; | |
146 | } | |
147 | if(tgetent (termcap, env) <= 0) { | |
148 | fprintf(stderr, "%s: Can't get entry \"%s\"\n", | |
149 | myname, env); | |
150 | exit(1); | |
151 | } | |
152 | } | |
153 | ||
154 | ioctl (tty, TIOCGETP, &sgorig); | |
155 | sg = sgorig; | |
156 | sg.sg_flags |= RAW; | |
157 | sg.sg_flags &= ~ECHO; | |
158 | signal(SIGINT, onintr); | |
159 | signal(SIGQUIT, onintr); | |
160 | signal(SIGTERM, onintr); | |
161 | ioctl (tty, TIOCSETP, &sg); | |
162 | ||
163 | if (argc == 2) { | |
164 | sprintf (buf, setsize[emu], argv[0], argv[1]); | |
165 | write(tty, buf, strlen(buf)); | |
166 | } | |
167 | write(tty, getsize[emu], strlen(getsize[emu])); | |
168 | readstring(ttyfp, buf, size[emu]); | |
169 | if(sscanf (buf, size[emu], &rows, &cols) != 2) { | |
170 | fprintf(stderr, "%s: Can't get rows and columns\r\n", myname); | |
171 | onintr(); | |
172 | } | |
173 | if(restore[emu]) | |
174 | write(tty, restore[emu], strlen(restore[emu])); | |
175 | #ifdef sun | |
176 | #ifdef TIOCGSIZE | |
177 | /* finally, set the tty's window size */ | |
178 | if (ioctl (tty, TIOCGSIZE, &ts) != -1) { | |
179 | ts.ts_lines = rows; | |
180 | ts.ts_cols = cols; | |
181 | ioctl (tty, TIOCSSIZE, &ts); | |
182 | } | |
183 | #endif TIOCGSIZE | |
184 | #else sun | |
185 | #ifdef TIOCGWINSZ | |
186 | /* finally, set the tty's window size */ | |
187 | if(getwsize[emu]) { | |
188 | /* get the window size in pixels */ | |
189 | write (tty, getwsize[emu], strlen (getwsize[emu])); | |
190 | readstring(ttyfp, buf, wsize[emu]); | |
191 | if(sscanf (buf, wsize[emu], &ws.ws_xpixel, &ws.ws_ypixel) != 2) { | |
192 | fprintf(stderr, "%s: Can't get window size\r\n", myname); | |
193 | onintr(); | |
194 | } | |
195 | ws.ws_row = rows; | |
196 | ws.ws_col = cols; | |
197 | ioctl (tty, TIOCSWINSZ, &ws); | |
198 | } else if (ioctl (tty, TIOCGWINSZ, &ws) != -1) { | |
199 | /* we don't have any way of directly finding out | |
200 | the current height & width of the window in pixels. We try | |
201 | our best by computing the font height and width from the "old" | |
202 | struct winsize values, and multiplying by these ratios...*/ | |
203 | if (ws.ws_xpixel != 0) | |
204 | ws.ws_xpixel = cols * (ws.ws_xpixel / ws.ws_col); | |
205 | if (ws.ws_ypixel != 0) | |
206 | ws.ws_ypixel = rows * (ws.ws_ypixel / ws.ws_row); | |
207 | ws.ws_row = rows; | |
208 | ws.ws_col = cols; | |
209 | ioctl (tty, TIOCSWINSZ, &ws); | |
210 | } | |
211 | #endif TIOCGWINSZ | |
212 | #endif sun | |
213 | ||
214 | ioctl (tty, TIOCSETP, &sgorig); | |
215 | signal(SIGINT, SIG_DFL); | |
216 | signal(SIGQUIT, SIG_DFL); | |
217 | signal(SIGTERM, SIG_DFL); | |
218 | ||
219 | /* update termcap string */ | |
220 | /* first do columns */ | |
221 | if ((ptr = strindex (termcap, "co#")) == NULL) { | |
222 | fprintf(stderr, "%s: No `co#'\n", myname); | |
223 | exit (1); | |
224 | } | |
225 | strncpy (newtc, termcap, ptr - termcap + 3); | |
226 | sprintf (newtc + strlen (newtc), "%d", cols); | |
227 | ptr = index (ptr, ':'); | |
228 | strcat (newtc, ptr); | |
229 | ||
230 | /* now do lines */ | |
231 | if ((ptr = strindex (newtc, "li#")) == NULL) { | |
232 | fprintf(stderr, "%s: No `li#'\n", myname); | |
233 | exit (1); | |
234 | } | |
235 | strncpy (termcap, newtc, ptr - newtc + 3); | |
236 | sprintf (termcap + ((int) ptr - (int) newtc + 3), "%d", rows); | |
237 | ptr = index (ptr, ':'); | |
238 | strcat (termcap, ptr); | |
239 | ||
240 | if(stdsh) | |
241 | printf ("%sTERMCAP='%s'\n", | |
242 | setname, termcap); | |
243 | else printf ("set noglob;\n%ssetenv TERMCAP '%s';\nunset noglob;\n", | |
244 | setname, termcap); | |
245 | exit(0); | |
246 | } | |
247 | ||
248 | char *strindex (s1, s2) | |
249 | /* | |
250 | returns a pointer to the first occurrence of s2 in s1, or NULL if there are | |
251 | none. | |
252 | */ | |
253 | register char *s1, *s2; | |
254 | { | |
255 | register char *s3; | |
256 | ||
257 | while ((s3 = index (s1, *s2)) != NULL) | |
258 | { | |
259 | if (strncmp (s3, s2, strlen (s2)) == 0) return (s3); | |
260 | s1 = ++s3; | |
261 | } | |
262 | return (NULL); | |
263 | } | |
264 | ||
265 | checkdigits(str) | |
266 | register char *str; | |
267 | { | |
268 | while(*str) { | |
269 | if(!isdigit(*str)) | |
270 | return(0); | |
271 | str++; | |
272 | } | |
273 | return(1); | |
274 | } | |
275 | ||
276 | readstring(fp, buf, str) | |
277 | register FILE *fp; | |
278 | register char *buf; | |
279 | char *str; | |
280 | { | |
281 | register int i, last; | |
282 | struct itimerval it; | |
283 | int timeout(); | |
284 | ||
285 | signal(SIGALRM, timeout); | |
286 | bzero((char *)&it, sizeof(struct itimerval)); | |
287 | it.it_value.tv_sec = TIMEOUT; | |
288 | setitimer(ITIMER_REAL, &it, (struct itimerval *)NULL); | |
289 | if((*buf++ = getc(fp)) != *str) { | |
290 | fprintf(stderr, "%s: unknown character, exiting.\r\n", myname); | |
291 | onintr(); | |
292 | } | |
293 | last = str[i = strlen(str) - 1]; | |
294 | while((*buf++ = getc(fp)) != last); | |
295 | bzero((char *)&it, sizeof(struct itimerval)); | |
296 | setitimer(ITIMER_REAL, &it, (struct itimerval *)NULL); | |
297 | *buf = 0; | |
298 | } | |
299 | ||
300 | Usage() | |
301 | { | |
302 | fprintf(stderr, strcmp(myname, sunname) == 0 ? | |
303 | "Usage: %s [rows cols]\n" : | |
304 | "Usage: %s [-u] [-s [rows cols]]\n", myname); | |
305 | exit(1); | |
306 | } | |
307 | ||
308 | timeout() | |
309 | { | |
310 | fprintf(stderr, "%s: Time out occurred\r\n", myname); | |
311 | onintr(); | |
312 | } | |
313 | ||
314 | onintr() | |
315 | { | |
316 | ioctl (tty, TIOCSETP, &sgorig); | |
317 | exit(1); | |
318 | } |