1 /*--------------------------------*-C-*---------------------------------*
2 * File: init.c
3 *----------------------------------------------------------------------*
4 *
5 * All portions of code are copyright by their respective author/s.
6 * Copyright (c) 1992 John Bovey <jdb@ukc.ac.uk>
7 * Copyright (c) 1994 Robert Nation <nation@rocket.sanders.lockheed.com>
8 * Copyright (c) 1998-2001 Geoff Wing <gcw@pobox.com>
9 * Copyright (c) 1999 D J Hawkey Jr <hawkeyd@visi.com>
10 * Copyright (c) 2003 marcus at #fluxbox on freenode.net
11 * Copyright (c) 2004 Mr. Dobalina <losermcloser@users.sourceforge.net>
12 * Copyright (c) 2003-2004 Marc Lehmann <pcg@goof.com>
13 * Copyright (c) 2004-2005 Jingmin Zhou <jimmyzhou@users.sourceforge.net>
14 * Copyright (c) 2005 Gautam Iyer <gautam@math.uchicago.edu>
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 *----------------------------------------------------------------------*/
30 /*
31 ** $Id: init.c,v 1.165 2005/10/08 01:07:45 cvs Exp $
32 */
33
34 #include "../config.h"
35 #include "rxvt.h"
36
37
38 #ifdef DEBUG_VERBOSE
39 # define DEBUG_LEVEL 1
40 # define DEBUG_X
41 #else
42 # define DEBUG_LEVEL 0
43 # undef DEBUG_X
44 #endif
45
46 #if DEBUG_LEVEL
47 # define DBG_MSG(d,x) if(d <= DEBUG_LEVEL) fprintf x
48 #else
49 # define DBG_MSG(d,x)
50 #endif
51
52 /* #define XTERM_REVERSE_VIDEO 1 */
53
54
55 /*--------------------------------------------------------------------*
56 * BEGIN `INTERNAL' ROUTINE PROTOTYPES *
57 *--------------------------------------------------------------------*/
58 #if defined(OS_SVR4) && !defined(_POSIX_VERSION)
59 int rxvt_getdtablesize ();
60 #endif
61 int rxvt_xerror_handler (const Display*, const XErrorEvent*);
62 void rxvt_init_colors (rxvt_t*);
63 void rxvt_init_win_size (rxvt_t*);
64 char** rxvt_string_to_argv (char*, int*);
65 void rxvt_color_aliases (rxvt_t*, int);
66 void rxvt_get_ourmods (rxvt_t*);
67 int rxvt_run_child (rxvt_t*, int, const char**);
68 void rxvt_get_ttymode (ttymode_t*, int);
69 /*--------------------------------------------------------------------*
70 * END `INTERNAL' ROUTINE PROTOTYPES *
71 *--------------------------------------------------------------------*/
72
73
74
75 const char *const def_colorName[] = {
76 COLOR_FOREGROUND,
77 COLOR_BACKGROUND,
78 /* low-intensity colors */
79 "black", /* 0: black (#000000) */
80 #ifndef NO_BRIGHTCOLOR
81 "red3", /* 1: red (#CD0000) */
82 "green3", /* 2: green (#00CD00) */
83 "yellow3", /* 3: yellow (#CDCD00) */
84 "blue3", /* 4: blue (#0000CD) */
85 "magenta3", /* 5: magenta (#CD00CD) */
86 "cyan3", /* 6: cyan (#00CDCD) */
87 # ifdef XTERM_COLORS
88 "grey90", /* 7: white (#E5E5E5) */
89 # else
90 "antiquewhite", /* 7: white (#FAEBD7) */
91 # endif
92 /* high-intensity colors */
93 # ifdef XTERM_COLORS
94 "grey30", /* 8: bright black (#4D4D4D) */
95 # else
96 "grey25", /* 8: bright black (#404040) */
97 # endif
98 #endif /* NO_BRIGHTCOLOR */
99 "red", /* 1/9: bright red (#FF0000) */
100 "green", /* 2/10: bright green (#00FF00) */
101 "yellow", /* 3/11: bright yellow (#FFFF00) */
102 "blue", /* 4/12: bright blue (#0000FF) */
103 "magenta", /* 5/13: bright magenta (#FF00FF) */
104 "cyan", /* 6/14: bright cyan (#00FFFF) */
105 "white", /* 7/15: bright white (#FFFFFF) */
106 #ifdef TTY_256COLOR
107 # ifdef XTERM_COLORS
108 /* use the same color cube as xterm. 16-231 is a more or less uniform
109 * rgb ramp, and 231-255 is a greyscale ramp */
110 "rgb:00/00/00", /* default ff6-255 color table */
111 "rgb:00/00/5f", /* consists of 6 6x6 colour cubes */
112 "rgb:00/00/87", /* and a 24 greyscale ramp w/o */
113 "rgb:00/00/af", /* black or white */
114 "rgb:00/00/d7",
115 "rgb:00/00/ff",
116 "rgb:00/5f/00",
117 "rgb:00/5f/5f",
118 "rgb:00/5f/87",
119 "rgb:00/5f/af",
120 "rgb:00/5f/d7",
121 "rgb:00/5f/ff",
122 "rgb:00/87/00",
123 "rgb:00/87/5f",
124 "rgb:00/87/87",
125 "rgb:00/87/af",
126 "rgb:00/87/d7",
127 "rgb:00/87/ff",
128 "rgb:00/af/00",
129 "rgb:00/af/5f",
130 "rgb:00/af/87",
131 "rgb:00/af/af",
132 "rgb:00/af/d7",
133 "rgb:00/af/ff",
134 "rgb:00/d7/00",
135 "rgb:00/d7/5f",
136 "rgb:00/d7/87",
137 "rgb:00/d7/af",
138 "rgb:00/d7/d7",
139 "rgb:00/d7/ff",
140 "rgb:00/ff/00",
141 "rgb:00/ff/5f",
142 "rgb:00/ff/87",
143 "rgb:00/ff/af",
144 "rgb:00/ff/d7",
145 "rgb:00/ff/ff",
146 "rgb:5f/00/00",
147 "rgb:5f/00/5f",
148 "rgb:5f/00/87",
149 "rgb:5f/00/af",
150 "rgb:5f/00/d7",
151 "rgb:5f/00/ff",
152 "rgb:5f/5f/00",
153 "rgb:5f/5f/5f",
154 "rgb:5f/5f/87",
155 "rgb:5f/5f/af",
156 "rgb:5f/5f/d7",
157 "rgb:5f/5f/ff",
158 "rgb:5f/87/00",
159 "rgb:5f/87/5f",
160 "rgb:5f/87/87",
161 "rgb:5f/87/af",
162 "rgb:5f/87/d7",
163 "rgb:5f/87/ff",
164 "rgb:5f/af/00",
165 "rgb:5f/af/5f",
166 "rgb:5f/af/87",
167 "rgb:5f/af/af",
168 "rgb:5f/af/d7",
169 "rgb:5f/af/ff",
170 "rgb:5f/d7/00",
171 "rgb:5f/d7/5f",
172 "rgb:5f/d7/87",
173 "rgb:5f/d7/af",
174 "rgb:5f/d7/d7",
175 "rgb:5f/d7/ff",
176 "rgb:5f/ff/00",
177 "rgb:5f/ff/5f",
178 "rgb:5f/ff/87",
179 "rgb:5f/ff/af",
180 "rgb:5f/ff/d7",
181 "rgb:5f/ff/ff",
182 "rgb:87/00/00",
183 "rgb:87/00/5f",
184 "rgb:87/00/87",
185 "rgb:87/00/af",
186 "rgb:87/00/d7",
187 "rgb:87/00/ff",
188 "rgb:87/5f/00",
189 "rgb:87/5f/5f",
190 "rgb:87/5f/87",
191 "rgb:87/5f/af",
192 "rgb:87/5f/d7",
193 "rgb:87/5f/ff",
194 "rgb:87/87/00",
195 "rgb:87/87/5f",
196 "rgb:87/87/87",
197 "rgb:87/87/af",
198 "rgb:87/87/d7",
199 "rgb:87/87/ff",
200 "rgb:87/af/00",
201 "rgb:87/af/5f",
202 "rgb:87/af/87",
203 "rgb:87/af/af",
204 "rgb:87/af/d7",
205 "rgb:87/af/ff",
206 "rgb:87/d7/00",
207 "rgb:87/d7/5f",
208 "rgb:87/d7/87",
209 "rgb:87/d7/af",
210 "rgb:87/d7/d7",
211 "rgb:87/d7/ff",
212 "rgb:87/ff/00",
213 "rgb:87/ff/5f",
214 "rgb:87/ff/87",
215 "rgb:87/ff/af",
216 "rgb:87/ff/d7",
217 "rgb:87/ff/ff",
218 "rgb:af/00/00",
219 "rgb:af/00/5f",
220 "rgb:af/00/87",
221 "rgb:af/00/af",
222 "rgb:af/00/d7",
223 "rgb:af/00/ff",
224 "rgb:af/5f/00",
225 "rgb:af/5f/5f",
226 "rgb:af/5f/87",
227 "rgb:af/5f/af",
228 "rgb:af/5f/d7",
229 "rgb:af/5f/ff",
230 "rgb:af/87/00",
231 "rgb:af/87/5f",
232 "rgb:af/87/87",
233 "rgb:af/87/af",
234 "rgb:af/87/d7",
235 "rgb:af/87/ff",
236 "rgb:af/af/00",
237 "rgb:af/af/5f",
238 "rgb:af/af/87",
239 "rgb:af/af/af",
240 "rgb:af/af/d7",
241 "rgb:af/af/ff",
242 "rgb:af/d7/00",
243 "rgb:af/d7/5f",
244 "rgb:af/d7/87",
245 "rgb:af/d7/af",
246 "rgb:af/d7/d7",
247 "rgb:af/d7/ff",
248 "rgb:af/ff/00",
249 "rgb:af/ff/5f",
250 "rgb:af/ff/87",
251 "rgb:af/ff/af",
252 "rgb:af/ff/d7",
253 "rgb:af/ff/ff",
254 "rgb:d7/00/00",
255 "rgb:d7/00/5f",
256 "rgb:d7/00/87",
257 "rgb:d7/00/af",
258 "rgb:d7/00/d7",
259 "rgb:d7/00/ff",
260 "rgb:d7/5f/00",
261 "rgb:d7/5f/5f",
262 "rgb:d7/5f/87",
263 "rgb:d7/5f/af",
264 "rgb:d7/5f/d7",
265 "rgb:d7/5f/ff",
266 "rgb:d7/87/00",
267 "rgb:d7/87/5f",
268 "rgb:d7/87/87",
269 "rgb:d7/87/af",
270 "rgb:d7/87/d7",
271 "rgb:d7/87/ff",
272 "rgb:d7/af/00",
273 "rgb:d7/af/5f",
274 "rgb:d7/af/87",
275 "rgb:d7/af/af",
276 "rgb:d7/af/d7",
277 "rgb:d7/af/ff",
278 "rgb:d7/d7/00",
279 "rgb:d7/d7/5f",
280 "rgb:d7/d7/87",
281 "rgb:d7/d7/af",
282 "rgb:d7/d7/d7",
283 "rgb:d7/d7/ff",
284 "rgb:d7/ff/00",
285 "rgb:d7/ff/5f",
286 "rgb:d7/ff/87",
287 "rgb:d7/ff/af",
288 "rgb:d7/ff/d7",
289 "rgb:d7/ff/ff",
290 "rgb:ff/00/00",
291 "rgb:ff/00/5f",
292 "rgb:ff/00/87",
293 "rgb:ff/00/af",
294 "rgb:ff/00/d7",
295 "rgb:ff/00/ff",
296 "rgb:ff/5f/00",
297 "rgb:ff/5f/5f",
298 "rgb:ff/5f/87",
299 "rgb:ff/5f/af",
300 "rgb:ff/5f/d7",
301 "rgb:ff/5f/ff",
302 "rgb:ff/87/00",
303 "rgb:ff/87/5f",
304 "rgb:ff/87/87",
305 "rgb:ff/87/af",
306 "rgb:ff/87/d7",
307 "rgb:ff/87/ff",
308 "rgb:ff/af/00",
309 "rgb:ff/af/5f",
310 "rgb:ff/af/87",
311 "rgb:ff/af/af",
312 "rgb:ff/af/d7",
313 "rgb:ff/af/ff",
314 "rgb:ff/d7/00",
315 "rgb:ff/d7/5f",
316 "rgb:ff/d7/87",
317 "rgb:ff/d7/af",
318 "rgb:ff/d7/d7",
319 "rgb:ff/d7/ff",
320 "rgb:ff/ff/00",
321 "rgb:ff/ff/5f",
322 "rgb:ff/ff/87",
323 "rgb:ff/ff/af",
324 "rgb:ff/ff/d7",
325 "rgb:ff/ff/ff",
326 # else /* XTERM_COLORS */
327 "rgbi:0/0/0", /* default 16-255 color table */
328 "rgbi:0/0/.2", /* consists of 6 6x6 colour cubes */
329 "rgbi:0/0/.4", /* and a 24 greyscale ramp w/o */
330 "rgbi:0/0/.6", /* black or white */
331 "rgbi:0/0/.8",
332 "rgbi:0/0/1",
333 "rgbi:0/.2/0",
334 "rgbi:0/.2/.2",
335 "rgbi:0/.2/.4",
336 "rgbi:0/.2/.6",
337 "rgbi:0/.2/.8",
338 "rgbi:0/.2/1",
339 "rgbi:0/.4/0",
340 "rgbi:0/.4/.2",
341 "rgbi:0/.4/.4",
342 "rgbi:0/.4/.6",
343 "rgbi:0/.4/.8",
344 "rgbi:0/.4/1",
345 "rgbi:0/.6/0",
346 "rgbi:0/.6/.2",
347 "rgbi:0/.6/.4",
348 "rgbi:0/.6/.6",
349 "rgbi:0/.6/.8",
350 "rgbi:0/.6/1",
351 "rgbi:0/.8/0",
352 "rgbi:0/.8/.2",
353 "rgbi:0/.8/.4",
354 "rgbi:0/.8/.6",
355 "rgbi:0/.8/.8",
356 "rgbi:0/.8/1",
357 "rgbi:0/1/0",
358 "rgbi:0/1/.2",
359 "rgbi:0/1/.4",
360 "rgbi:0/1/.6",
361 "rgbi:0/1/.8",
362 "rgbi:0/1/1",
363 "rgbi:.2/0/0",
364 "rgbi:.2/0/.2",
365 "rgbi:.2/0/.4",
366 "rgbi:.2/0/.6",
367 "rgbi:.2/0/.8",
368 "rgbi:.2/0/1",
369 "rgbi:.2/.2/0",
370 "rgbi:.2/.2/.2",
371 "rgbi:.2/.2/.4",
372 "rgbi:.2/.2/.6",
373 "rgbi:.2/.2/.8",
374 "rgbi:.2/.2/1",
375 "rgbi:.2/.4/0",
376 "rgbi:.2/.4/.2",
377 "rgbi:.2/.4/.4",
378 "rgbi:.2/.4/.6",
379 "rgbi:.2/.4/.8",
380 "rgbi:.2/.4/1",
381 "rgbi:.2/.6/0",
382 "rgbi:.2/.6/.2",
383 "rgbi:.2/.6/.4",
384 "rgbi:.2/.6/.6",
385 "rgbi:.2/.6/.8",
386 "rgbi:.2/.6/1",
387 "rgbi:.2/.8/0",
388 "rgbi:.2/.8/.2",
389 "rgbi:.2/.8/.4",
390 "rgbi:.2/.8/.6",
391 "rgbi:.2/.8/.8",
392 "rgbi:.2/.8/1",
393 "rgbi:.2/1/0",
394 "rgbi:.2/1/.2",
395 "rgbi:.2/1/.4",
396 "rgbi:.2/1/.6",
397 "rgbi:.2/1/.8",
398 "rgbi:.2/1/1",
399 "rgbi:.4/0/0",
400 "rgbi:.4/0/.2",
401 "rgbi:.4/0/.4",
402 "rgbi:.4/0/.6",
403 "rgbi:.4/0/.8",
404 "rgbi:.4/0/1",
405 "rgbi:.4/.2/0",
406 "rgbi:.4/.2/.2",
407 "rgbi:.4/.2/.4",
408 "rgbi:.4/.2/.6",
409 "rgbi:.4/.2/.8",
410 "rgbi:.4/.2/1",
411 "rgbi:.4/.4/0",
412 "rgbi:.4/.4/.2",
413 "rgbi:.4/.4/.4",
414 "rgbi:.4/.4/.6",
415 "rgbi:.4/.4/.8",
416 "rgbi:.4/.4/1",
417 "rgbi:.4/.6/0",
418 "rgbi:.4/.6/.2",
419 "rgbi:.4/.6/.4",
420 "rgbi:.4/.6/.6",
421 "rgbi:.4/.6/.8",
422 "rgbi:.4/.6/1",
423 "rgbi:.4/.8/0",
424 "rgbi:.4/.8/.2",
425 "rgbi:.4/.8/.4",
426 "rgbi:.4/.8/.6",
427 "rgbi:.4/.8/.8",
428 "rgbi:.4/.8/1",
429 "rgbi:.4/1/0",
430 "rgbi:.4/1/.2",
431 "rgbi:.4/1/.4",
432 "rgbi:.4/1/.6",
433 "rgbi:.4/1/.8",
434 "rgbi:.4/1/1",
435 "rgbi:.6/0/0",
436 "rgbi:.6/0/.2",
437 "rgbi:.6/0/.4",
438 "rgbi:.6/0/.6",
439 "rgbi:.6/0/.8",
440 "rgbi:.6/0/1",
441 "rgbi:.6/.2/0",
442 "rgbi:.6/.2/.2",
443 "rgbi:.6/.2/.4",
444 "rgbi:.6/.2/.6",
445 "rgbi:.6/.2/.8",
446 "rgbi:.6/.2/1",
447 "rgbi:.6/.4/0",
448 "rgbi:.6/.4/.2",
449 "rgbi:.6/.4/.4",
450 "rgbi:.6/.4/.6",
451 "rgbi:.6/.4/.8",
452 "rgbi:.6/.4/1",
453 "rgbi:.6/.6/0",
454 "rgbi:.6/.6/.2",
455 "rgbi:.6/.6/.4",
456 "rgbi:.6/.6/.6",
457 "rgbi:.6/.6/.8",
458 "rgbi:.6/.6/1",
459 "rgbi:.6/.8/0",
460 "rgbi:.6/.8/.2",
461 "rgbi:.6/.8/.4",
462 "rgbi:.6/.8/.6",
463 "rgbi:.6/.8/.8",
464 "rgbi:.6/.8/1",
465 "rgbi:.6/1/0",
466 "rgbi:.6/1/.2",
467 "rgbi:.6/1/.4",
468 "rgbi:.6/1/.6",
469 "rgbi:.6/1/.8",
470 "rgbi:.6/1/1",
471 "rgbi:.8/0/0",
472 "rgbi:.8/0/.2",
473 "rgbi:.8/0/.4",
474 "rgbi:.8/0/.6",
475 "rgbi:.8/0/.8",
476 "rgbi:.8/0/1",
477 "rgbi:.8/.2/0",
478 "rgbi:.8/.2/.2",
479 "rgbi:.8/.2/.4",
480 "rgbi:.8/.2/.6",
481 "rgbi:.8/.2/.8",
482 "rgbi:.8/.2/1",
483 "rgbi:.8/.4/0",
484 "rgbi:.8/.4/.2",
485 "rgbi:.8/.4/.4",
486 "rgbi:.8/.4/.6",
487 "rgbi:.8/.4/.8",
488 "rgbi:.8/.4/1",
489 "rgbi:.8/.6/0",
490 "rgbi:.8/.6/.2",
491 "rgbi:.8/.6/.4",
492 "rgbi:.8/.6/.6",
493 "rgbi:.8/.6/.8",
494 "rgbi:.8/.6/1",
495 "rgbi:.8/.8/0",
496 "rgbi:.8/.8/.2",
497 "rgbi:.8/.8/.4",
498 "rgbi:.8/.8/.6",
499 "rgbi:.8/.8/.8",
500 "rgbi:.8/.8/1",
501 "rgbi:.8/1/0",
502 "rgbi:.8/1/.2",
503 "rgbi:.8/1/.4",
504 "rgbi:.8/1/.6",
505 "rgbi:.8/1/.8",
506 "rgbi:.8/1/1",
507 "rgbi:1/0/0",
508 "rgbi:1/0/.2",
509 "rgbi:1/0/.4",
510 "rgbi:1/0/.6",
511 "rgbi:1/0/.8",
512 "rgbi:1/0/1",
513 "rgbi:1/.2/0",
514 "rgbi:1/.2/.2",
515 "rgbi:1/.2/.4",
516 "rgbi:1/.2/.6",
517 "rgbi:1/.2/.8",
518 "rgbi:1/.2/1",
519 "rgbi:1/.4/0",
520 "rgbi:1/.4/.2",
521 "rgbi:1/.4/.4",
522 "rgbi:1/.4/.6",
523 "rgbi:1/.4/.8",
524 "rgbi:1/.4/1",
525 "rgbi:1/.6/0",
526 "rgbi:1/.6/.2",
527 "rgbi:1/.6/.4",
528 "rgbi:1/.6/.6",
529 "rgbi:1/.6/.8",
530 "rgbi:1/.6/1",
531 "rgbi:1/.8/0",
532 "rgbi:1/.8/.2",
533 "rgbi:1/.8/.4",
534 "rgbi:1/.8/.6",
535 "rgbi:1/.8/.8",
536 "rgbi:1/.8/1",
537 "rgbi:1/1/0",
538 "rgbi:1/1/.2",
539 "rgbi:1/1/.4",
540 "rgbi:1/1/.6",
541 "rgbi:1/1/.8",
542 "rgbi:1/1/1",
543 # endif /* XTERM_COLORS */
544 "rgb:08/08/08", /* xterm, rxvt, mrxvt use the same greyscale ramp */
545 "rgb:12/12/12",
546 "rgb:1c/1c/1c",
547 "rgb:26/26/26",
548 "rgb:30/30/30",
549 "rgb:3a/3a/3a",
550 "rgb:44/44/44",
551 "rgb:4e/4e/4e",
552 "rgb:58/58/58",
553 "rgb:62/62/62",
554 "rgb:6c/6c/6c",
555 "rgb:76/76/76",
556 "rgb:80/80/80",
557 "rgb:8a/8a/8a",
558 "rgb:94/94/94",
559 "rgb:9e/9e/9e",
560 "rgb:a8/a8/a8",
561 "rgb:b2/b2/b2",
562 "rgb:bc/bc/bc",
563 "rgb:c6/c6/c6",
564 "rgb:d0/d0/d0",
565 "rgb:da/da/da",
566 "rgb:e4/e4/e4",
567 "rgb:ee/ee/ee",
568 #endif /* TTY_256COLOR */
569 #ifndef NO_CURSORCOLOR
570 COLOR_CURSOR_BACKGROUND,
571 COLOR_CURSOR_FOREGROUND,
572 #endif /* ! NO_CURSORCOLOR */
573 NULL, /* Color_pointer */
574 NULL, /* Color_border */
575 NULL, /* Color_ufbg */
576 #ifndef NO_BOLD_UNDERLINE_REVERSE
577 NULL, /* Color_BD */
578 NULL, /* Color_UL */
579 NULL, /* Color_RV */
580 #endif /* ! NO_BOLD_UNDERLINE_REVERSE */
581 #ifdef OPTION_HC
582 NULL,
583 #endif
584 #ifdef KEEP_SCROLLCOLOR
585 COLOR_SCROLLBAR,
586 COLOR_SCROLLTROUGH,
587 #endif /* KEEP_SCROLLCOLOR */
588 #ifdef TINTING_SUPPORT
589 NULL,
590 #endif
591 };
592
593
594 /*
595 ** MUST sync with rxvt.h:enum XA_XXXX
596 */
597 const char *const xa_names[NUM_XA] = {
598 "COMPOUND_TEXT",
599 "UTF8_STRING",
600 "TEXT",
601 "MULTIPLE",
602 "TARGETS",
603 "TIMESTAMP",
604 "VT_SELECTION",
605 "INCR",
606 "WM_DELETE_WINDOW",
607 "_NET_WM_DESKTOP",
608 "_WIN_WORKSPACE",
609 "_NET_WM_NAME",
610 "_NET_WM_ICON_NAME",
611 "WM_CLIENT_LEADER",
612 "_NET_WM_WINDOW_OPACITY",
613 #ifndef NO_FRILLS
614 "_NET_WM_PID",
615 #endif
616 #ifdef HAVE_X11_SM_SMLIB_H
617 "SM_CLIENT_ID",
618 #endif
619 #ifdef USE_XIM
620 "WM_LOCALE_NAME",
621 #endif
622 #ifdef TRANSPARENT
623 "_XROOTPMAP_ID",
624 #endif
625 #ifdef OFFIX_DND
626 "DndProtocol",
627 "DndSelection",
628 #endif
629 "CLIPBOARD"
630 };
631
632 /*----------------------------------------------------------------------*/
633 /* substitute system functions */
634 #if defined(OS_SVR4) && ! defined(_POSIX_VERSION)
635 /* INTPROTO */
636 int
rxvt_getdtablesize(void)637 rxvt_getdtablesize(void)
638 {
639 struct rlimit rlim;
640
641 getrlimit(RLIMIT_NOFILE, &rlim);
642 return rlim.rlim_cur;
643 }
644 #endif
645 /*----------------------------------------------------------------------*/
646 /* EXTPROTO */
647 int
rxvt_init_vars(rxvt_t * r)648 rxvt_init_vars(rxvt_t *r)
649 {
650 register int i;
651 struct rxvt_hidden* h;
652
653
654 MEMSET(r, 0, sizeof(rxvt_t));
655
656 h = r->h = (struct rxvt_hidden *)rxvt_calloc(1, sizeof(struct rxvt_hidden));
657
658 for (i = 0; i < MAX_PAGES; i ++) {
659 /* Initialize vts_idx for each term_t structure */
660 r->vterm[i].vts_idx = -1;
661 /* Initialize each vts pointer */
662 r->vts[i] = NULL;
663 }
664
665 /*
666 ** hotkeys[MAX_HOTKEYS] is a valid entry!!! it will be used to
667 ** save the first hotkey entry if we toggle disableHotkeys
668 */
669 r->hotkeys = (hotkeys_t*) rxvt_malloc(
670 sizeof(hotkeys_t) * (MAX_HOTKEYS + 1));
671
672 r->PixColors = (unsigned long*) rxvt_malloc(
673 sizeof(unsigned long) * (TOTAL_COLORS + 2 * MAX_PAGES));
674 #ifdef OFF_FOCUS_FADING
675 r->PixColorsUnfocus = (unsigned long*) rxvt_malloc(
676 sizeof(unsigned long) * (TOTAL_COLORS + 2 * MAX_PAGES));
677 #endif
678 #ifdef XFT_SUPPORT
679 r->XftColors = (XftColor*) rxvt_malloc (
680 sizeof (XftColor) * (TOTAL_COLORS + 2 * MAX_PAGES));
681 #endif
682 if (NULL == r->h ||
683 NULL == r->hotkeys ||
684 NULL == r->PixColors
685 #ifdef OFF_FOCUS_FADING
686 || NULL == r->PixColorsUnfocus
687 #endif
688 #ifdef XFT_SUPPORT
689 || NULL == r->XftColors
690 #endif
691 )
692 return -1;
693
694
695 r->Xdisplay = NULL;
696 #ifdef USE_XIM
697 r->TermWin.fontset = NULL;
698 #endif
699 r->TermWin.font = NULL;
700 #ifdef MULTICHAR_SET
701 r->TermWin.mfont = NULL;
702 #endif
703 #ifndef NO_BOLDFONT
704 r->TermWin.bfont = NULL;
705 #endif
706
707 #ifdef XFT_SUPPORT
708 r->TermWin.xftpattern = NULL;
709 r->TermWin.xftfont = NULL;
710 # ifndef NO_BOLDFONT
711 r->TermWin.xftbpattern = NULL;
712 r->TermWin.xftbfont = NULL;
713 r->TermWin.bf_switched = 0;
714 # endif /* NO_BOLDFONT */
715 # ifdef MULTICHAR_SET
716 # ifdef HAVE_ICONV_H
717 r->TermWin.xfticonv = (iconv_t) -1;
718 # endif
719 r->TermWin.xftmpattern = NULL;
720 r->TermWin.xftmfont = NULL;
721 # endif /* MULTICHAR_SET */
722 #endif /* XFT_SUPPORT */
723
724 #ifdef OFF_FOCUS_FADING
725 r->color_switched = 0; /* color is not switched */
726 #endif
727 h->xa[XA_COMPOUND_TEXT] =
728 h->xa[XA_MULTIPLE] =
729 h->xa[XA_TARGETS] =
730 h->xa[XA_TEXT] =
731 h->xa[XA_TIMESTAMP] =
732 h->xa[XA_VT_SELECTION] =
733 h->xa[XA_INCR] = None;
734 h->locale = NULL;
735 # ifdef HAVE_MENUBAR
736 h->BuildMenu = NULL; /* the menu currently being built */
737 # if (MENUBAR_MAX > 1)
738 h->CurrentBar = NULL;
739 # endif /* (MENUBAR_MAX > 1) */
740 # endif
741 # ifdef USE_XIM
742 h->Input_Context = NULL;
743 # endif
744 /* h->v_bufstr = NULL; */
745 h->buffer = NULL;
746 h->compose.compose_ptr = NULL;
747 #ifdef TRANSPARENT
748 h->am_pixmap_trans = 0;
749 h->am_transparent = 0;
750 #endif
751
752
753 h->MEvent.time = CurrentTime;
754 h->MEvent.button = AnyButton;
755 r->Options = DEFAULT_OPTIONS;
756 r->Options2 = DEFAULT_OPTIONS2;
757 h->want_refresh = 1;
758 h->ttygid = -1;
759 r->Xfd = -1;
760 r->vt_died = 0;
761
762 /* default values */
763 #ifdef NO_FRILLS
764 r->TermWin.int_bwidth = DEFAULT_INTERNALBORDERWIDTH;
765 r->TermWin.ext_bwidth = DEFAULT_EXTERNALBORDERWIDTH;
766 #else
767 r->TermWin.int_bwidth = (INTERNALBORDERWIDTH >= 0 && INTERNALBORDERWIDTH <= MAX_INTERNALBORDERWIDTH) ? INTERNALBORDERWIDTH : DEFAULT_INTERNALBORDERWIDTH;
768 r->TermWin.ext_bwidth = (EXTERNALBORDERWIDTH >= 0 && EXTERNALBORDERWIDTH <= MAX_EXTERNALBORDERWIDTH) ? EXTERNALBORDERWIDTH : DEFAULT_EXTERNALBORDERWIDTH;
769 #endif
770
771 #ifndef NO_LINESPACE
772 r->TermWin.lineSpace = (LINESPACE >= 0 && LINESPACE <= MAX_LINESPACE) ? LINESPACE : DEFAULT_LINESPACE;
773 #endif
774
775 #ifdef CURSOR_BLINK
776 r->h->blinkInterval = DEFAULT_BLINK_TIME;
777 #endif
778 #ifdef POINTER_BLANK
779 r->h->pointerBlankDelay = DEFAULT_BLANKDELAY;
780 #endif
781
782 r->numPixColors = TOTAL_COLORS;
783
784 /* Initialize selection data */
785 #ifndef NO_NEW_SELECTION
786 r->selection_style = NEW_SELECT;
787 #else
788 r->selection_style = OLD_SELECT;
789 #endif
790 r->selection.vt = -1;
791 r->selection.op = SELECTION_CLEAR;
792 r->selection.screen = PRIMARY;
793 r->selection.clicks = 0;
794 r->selection.text = NULL;
795 r->selection.len = 0;
796 r->selection.beg.row = 0;
797 r->selection.beg.col = 0;
798 r->selection.end.row = 0;
799 r->selection.end.col = 0;
800
801 #ifndef NO_BRIGHTCOLOR
802 h->colorfgbg = DEFAULT_RSTYLE;
803 #endif
804 #if defined (HOTKEY_CTRL) || defined (HOTKEY_META)
805 h->ks_bigfont = XK_greater;
806 h->ks_smallfont = XK_less;
807 #endif
808 #ifdef GREEK_SUPPORT
809 h->ks_greekmodeswith = GREEK_KEYBOARD_MODESWITCH;
810 #endif
811 h->refresh_limit = 1;
812 h->refresh_type = SLOW_REFRESH;
813 h->prev_nrow = h->prev_ncol = 0;
814
815 r->encoding_method = ENC_NOENC;
816 h->multichar_decode = rxvt_decode_dummy;
817
818 h->oldcursor.row = h->oldcursor.col = -1;
819 h->last_bot = h->last_state = -1;
820 #ifdef HAVE_MENUBAR
821 h->menu_readonly = 1;
822 # if !(MENUBAR_MAX > 1)
823 h->CurrentBar = &(h->BarList);
824 # endif /* (MENUBAR_MAX > 1) */
825 #endif
826
827 #ifdef HAVE_X11_SM_SMLIB_H
828 r->TermWin.sm_conn = NULL;
829 r->TermWin.ice_conn = NULL;
830 r->TermWin.ice_fd = -1;
831 r->TermWin.sm_client_id = NULL;
832 #endif
833
834 return 0;
835 }
836
837
838 /* EXTPROTO */
839 void
rxvt_init_secondary(rxvt_t * r)840 rxvt_init_secondary(rxvt_t *r)
841 {
842 int i, num_fds;
843 #ifdef TTY_GID_SUPPORT
844 struct group *gr = getgrnam("tty");
845
846 if (gr) { /* change group ownership of tty to "tty" */
847 r->h->ttygid = gr->gr_gid;
848 }
849 else
850 #endif /* TTY_GID_SUPPORT */
851 {
852 r->h->ttygid = getgid();
853 }
854
855 rxvt_set_default_locale (r);
856
857 /* get number of available file descriptors */
858 #if defined(_POSIX_VERSION) || ! defined(OS_SVR4)
859 num_fds = (int)sysconf(_SC_OPEN_MAX);
860 #else
861 num_fds = rxvt_getdtablesize();
862 #endif
863
864 /*
865 ** Close all unused file descriptors
866 ** We don't want them, we don't need them.
867 */
868 if ((i = open("/dev/null", O_RDONLY)) < 0) {
869 /* TODO: BOO HISS */
870 dup2(STDERR_FILENO, STDIN_FILENO);
871 }
872 else if (i > STDIN_FILENO) {
873 dup2(i, STDIN_FILENO);
874 close(i);
875 }
876 dup2(STDERR_FILENO, STDOUT_FILENO);
877 for (i = STDERR_FILENO + 1; i < num_fds; i++) {
878 /* #ifdef __sgi */
879 #ifdef OS_IRIX
880 /* Alex Coventry says we need 4 & 7 too */
881 if (i == 4 || i == 7)
882 continue;
883 #endif
884 close(i);
885 }
886
887 /* Now set the correct num_fds */
888 r->num_fds = STDERR_FILENO + 1;
889 #ifdef OS_IRIX
890 r->num_fds = 7 + 1;
891 #endif
892 }
893
894
895 /* INTPROTO */
896 hotkeys_t
make_hotkeys_t(unsigned short func,unsigned short flag,KeySym keysym)897 make_hotkeys_t (unsigned short func, unsigned short flag, KeySym keysym)
898 {
899 hotkeys_t value;
900 value.func = func;
901 value.flag = flag;
902 value.keysym = keysym;
903 return (value);
904 }
905
906
907 /* EXTPROTO */
908 void
rxvt_init_hotkeys(rxvt_t * r)909 rxvt_init_hotkeys (rxvt_t* r)
910 {
911 register int i = 0;
912 hotkeys_t* hk;
913
914
915 /* initialize hotkey handlers */
916 rxvt_init_hotkey_handlers (r);
917
918 assert (NULL != r->hotkeys);
919 hk = r->hotkeys;
920
921 /* if shft is 1, keysym must be upper case!!! */
922
923 /* gnome-terminal hotkeys */
924 hk[i++] = make_hotkeys_t (HKF_NEW_TAB, (HK_INTERNAL|HK_CTRL|HK_SHFT), XK_T);
925 hk[i++] = make_hotkeys_t (HKF_KILL_TAB, (HK_INTERNAL|HK_CTRL|HK_SHFT), XK_W);
926 hk[i++] = make_hotkeys_t (HKF_PREV_TAB, (HK_INTERNAL|HK_CTRL), XK_Prior);
927 hk[i++] = make_hotkeys_t (HKF_NEXT_TAB, (HK_INTERNAL|HK_CTRL), XK_Next);
928 hk[i++] = make_hotkeys_t (HKF_TAB_1, (HK_INTERNAL|HK_META), XK_1);
929 hk[i++] = make_hotkeys_t (HKF_TAB_2, (HK_INTERNAL|HK_META), XK_2);
930 hk[i++] = make_hotkeys_t (HKF_TAB_3, (HK_INTERNAL|HK_META), XK_3);
931 hk[i++] = make_hotkeys_t (HKF_TAB_4, (HK_INTERNAL|HK_META), XK_4);
932 hk[i++] = make_hotkeys_t (HKF_TAB_5, (HK_INTERNAL|HK_META), XK_5);
933 hk[i++] = make_hotkeys_t (HKF_TAB_6, (HK_INTERNAL|HK_META), XK_6);
934 hk[i++] = make_hotkeys_t (HKF_TAB_7, (HK_INTERNAL|HK_META), XK_7);
935 hk[i++] = make_hotkeys_t (HKF_TAB_8, (HK_INTERNAL|HK_META), XK_8);
936 hk[i++] = make_hotkeys_t (HKF_TAB_9, (HK_INTERNAL|HK_META), XK_9);
937 hk[i++] = make_hotkeys_t (HKF_SMALL_FONT, (HK_INTERNAL|HK_CTRL), XK_minus);
938 hk[i++] = make_hotkeys_t (HKF_LARGE_FONT, (HK_INTERNAL|HK_CTRL), XK_equal);
939 hk[i++] = make_hotkeys_t (HKF_SMALL_FONT, (HK_INTERNAL|HK_CTRL|HK_SHFT), XK_underscore);
940 hk[i++] = make_hotkeys_t (HKF_LARGE_FONT, (HK_INTERNAL|HK_CTRL|HK_SHFT), XK_plus);
941
942 /* konsole hotkeys */
943 hk[i++] = make_hotkeys_t (HKF_LMOVE_TAB, (HK_INTERNAL|HK_CTRL|HK_SHFT), XK_Left);
944 hk[i++] = make_hotkeys_t (HKF_RMOVE_TAB, (HK_INTERNAL|HK_CTRL|HK_SHFT), XK_Right);
945 hk[i++] = make_hotkeys_t (HKF_NEW_TAB, (HK_INTERNAL|HK_CTRL|HK_META), XK_n);
946 hk[i++] = make_hotkeys_t (HKF_NEW_TAB, (HK_INTERNAL|HK_CTRL|HK_SHFT), XK_N);
947 hk[i++] = make_hotkeys_t (HKF_PREV_TAB, (HK_INTERNAL|HK_SHFT), XK_Left);
948 hk[i++] = make_hotkeys_t (HKF_NEXT_TAB, (HK_INTERNAL|HK_SHFT), XK_Right);
949 hk[i++] = make_hotkeys_t (HKF_CHANGE_TITLE, (HK_INTERNAL|HK_CTRL|HK_META), XK_s);
950
951 /* vi-like hotkeys */
952 hk[i++] = make_hotkeys_t (HKF_PREV_TAB, (HK_INTERNAL|HK_CTRL|HK_META), XK_h);
953 hk[i++] = make_hotkeys_t (HKF_NEXT_TAB, (HK_INTERNAL|HK_CTRL|HK_META), XK_l);
954
955 /* screen-like hotkeys */
956 hk[i++] = make_hotkeys_t (HKF_PREV_ATAB, (HK_INTERNAL|HK_CTRL|HK_META), XK_p);
957
958 /* our own default hotkeys */
959 hk[i++] = make_hotkeys_t (HKF_CHANGE_TITLE, (HK_INTERNAL|HK_SHFT), XK_Delete);
960 hk[i++] = make_hotkeys_t (HKF_PREV_ATAB, (HK_INTERNAL|HK_CTRL), XK_Tab);
961 hk[i++] = make_hotkeys_t (HKF_KILL_TAB, (HK_INTERNAL|HK_CTRL|HK_SHFT), XK_K);
962 hk[i++] = make_hotkeys_t (HKF_TAB_1, (HK_INTERNAL|HK_CTRL|HK_META), XK_1);
963 hk[i++] = make_hotkeys_t (HKF_TAB_2, (HK_INTERNAL|HK_CTRL|HK_META), XK_2);
964 hk[i++] = make_hotkeys_t (HKF_TAB_3, (HK_INTERNAL|HK_CTRL|HK_META), XK_3);
965 hk[i++] = make_hotkeys_t (HKF_TAB_4, (HK_INTERNAL|HK_CTRL|HK_META), XK_4);
966 hk[i++] = make_hotkeys_t (HKF_TAB_5, (HK_INTERNAL|HK_CTRL|HK_META), XK_5);
967 hk[i++] = make_hotkeys_t (HKF_TAB_6, (HK_INTERNAL|HK_CTRL|HK_META), XK_6);
968 hk[i++] = make_hotkeys_t (HKF_TAB_7, (HK_INTERNAL|HK_CTRL|HK_META), XK_7);
969 hk[i++] = make_hotkeys_t (HKF_TAB_8, (HK_INTERNAL|HK_CTRL|HK_META), XK_8);
970 hk[i++] = make_hotkeys_t (HKF_TAB_9, (HK_INTERNAL|HK_CTRL|HK_META), XK_9);
971 hk[i++] = make_hotkeys_t (HKF_LMOVE_TAB, (HK_INTERNAL|HK_CTRL|HK_SHFT), XK_less);
972 hk[i++] = make_hotkeys_t (HKF_RMOVE_TAB, (HK_INTERNAL|HK_CTRL|HK_SHFT), XK_greater);
973 hk[i++] = make_hotkeys_t (HKF_DUMP_SCREEN, (HK_INTERNAL|HK_CTRL|HK_SHFT), XK_Z);
974 hk[i++] = make_hotkeys_t (HKF_INC_OPACITY, (HK_INTERNAL|HK_CTRL|HK_SHFT), XK_O);
975 hk[i++] = make_hotkeys_t (HKF_DEC_OPACITY, (HK_INTERNAL|HK_CTRL|HK_SHFT), XK_U);
976 hk[i++] = make_hotkeys_t (HKF_TRANSPARENCY, (HK_INTERNAL|HK_CTRL|HK_SHFT), XK_R);
977 hk[i++] = make_hotkeys_t (HKF_HIDE_TABBAR, (HK_INTERNAL|HK_CTRL|HK_SHFT), XK_H);
978 hk[i++] = make_hotkeys_t (HKF_HIDE_SCROLLBAR,(HK_INTERNAL|HK_CTRL|HK_SHFT), XK_S);
979 hk[i++] = make_hotkeys_t (HKF_HIDE_MENUBAR, (HK_INTERNAL|HK_CTRL|HK_SHFT), XK_M);
980 hk[i++] = make_hotkeys_t (HKF_HIDE_BUTTON, (HK_INTERNAL|HK_CTRL|HK_SHFT), XK_A);
981 hk[i++] = make_hotkeys_t (HKF_VERYBOLD, (HK_INTERNAL|HK_CTRL|HK_SHFT), XK_F);
982 hk[i++] = make_hotkeys_t (HKF_HOLD_EXIT, (HK_INTERNAL|HK_CTRL|HK_SHFT), XK_E);
983 hk[i++] = make_hotkeys_t (HKF_BROADCAST, (HK_INTERNAL|HK_CTRL|HK_SHFT), XK_B);
984 hk[i++] = make_hotkeys_t (HKF_SAVE_CONFIG, (HK_INTERNAL|HK_CTRL|HK_SHFT), XK_X);
985 hk[i++] = make_hotkeys_t (HKF_LARGE_FONT, (HK_INTERNAL|HK_SHFT), XK_Home);
986 hk[i++] = make_hotkeys_t (HKF_SMALL_FONT, (HK_INTERNAL|HK_SHFT), XK_End);
987 hk[i++] = make_hotkeys_t (HKF_SCROLL_UP, (HK_INTERNAL|HK_SHFT), XK_Up);
988 hk[i++] = make_hotkeys_t (HKF_SCROLL_DOWN, (HK_INTERNAL|HK_SHFT), XK_Down);
989 hk[i++] = make_hotkeys_t (HKF_SCROLL_PGUP, (HK_INTERNAL|HK_SHFT), XK_Prior);
990 hk[i++] = make_hotkeys_t (HKF_SCROLL_PGDOWN,(HK_INTERNAL|HK_SHFT), XK_Next);
991
992 /* rxvt/xterm hotkeys */
993
994 assert (i <= MAX_HOTKEYS);
995
996 /*
997 ** hotkeys[MAX_HOTKEYS] is a valid entry!!! it will be used to
998 ** save the first hotkey entry if we toggle disableHotkeys
999 */
1000 for (; i <= MAX_HOTKEYS; i ++) {
1001 hk[i] = make_hotkeys_t (HKF_DUMMY, 0, 0);
1002 }
1003 }
1004
1005
1006 /* EXTPROTO */
1007 void
rxvt_toggle_hotkeys(rxvt_t * r,int enable)1008 rxvt_toggle_hotkeys (rxvt_t* r, int enable)
1009 {
1010 if (enable) {
1011 if (HKF_DUMMY != r->hotkeys[0].func) /* already enabled */
1012 return;
1013
1014 SWAP_IT (r->hotkeys[0], r->hotkeys[MAX_HOTKEYS], hotkeys_t);
1015 }
1016 else {
1017 if (HKF_DUMMY == r->hotkeys[0].func) /* already disabled */
1018 return;
1019
1020 SWAP_IT (r->hotkeys[0], r->hotkeys[MAX_HOTKEYS], hotkeys_t);
1021 }
1022 }
1023
1024
1025 /* INTPROTO */
1026 int
rxvt_xerror_handler(const Display * display,const XErrorEvent * event)1027 rxvt_xerror_handler(const Display *display __attribute__((unused)), const XErrorEvent *event)
1028 {
1029 char error_msg[1024];
1030 rxvt_t* r = rxvt_get_r();
1031
1032 XGetErrorText (r->Xdisplay, event->error_code, error_msg, 1023);
1033 rxvt_print_error("%s", error_msg);
1034 if (r->h->allowedxerror == -1) {
1035 r->h->allowedxerror = event->error_code;
1036 }
1037 return 0; /* ignored anyway */
1038 }
1039
1040
1041
1042 #ifdef TEXT_SHADOW
1043 /* INTPROTO */
1044 void
rxvt_init_shadow_mode(rxvt_t * r,const char * shadow_mode)1045 rxvt_init_shadow_mode (rxvt_t* r, const char* shadow_mode)
1046 {
1047 if (!shadow_mode ||
1048 !STRCASECMP ("botright", shadow_mode) ||
1049 !STRCASECMP ("default", shadow_mode)) {
1050 r->TermWin.shadow_mode = SHADOW_BOTRIGHT;
1051 }
1052 else if (!STRCASECMP ("botleft", shadow_mode)) {
1053 r->TermWin.shadow_mode = SHADOW_BOTLEFT;
1054 }
1055 else if (!STRCASECMP ("topright", shadow_mode)) {
1056 r->TermWin.shadow_mode = SHADOW_TOPRIGHT;
1057 }
1058 else if (!STRCASECMP ("topleft", shadow_mode)) {
1059 r->TermWin.shadow_mode = SHADOW_TOPLEFT;
1060 }
1061 else if (!STRCASECMP ("top", shadow_mode)) {
1062 r->TermWin.shadow_mode = SHADOW_TOP;
1063 }
1064 else if (!STRCASECMP ("bottom", shadow_mode)) {
1065 r->TermWin.shadow_mode = SHADOW_BOTTOM;
1066 }
1067 else if (!STRCASECMP ("left", shadow_mode)) {
1068 r->TermWin.shadow_mode = SHADOW_LEFT;
1069 }
1070 else if (!STRCASECMP ("right", shadow_mode)) {
1071 r->TermWin.shadow_mode = SHADOW_RIGHT;
1072 }
1073 else if (!STRCASECMP ("none", shadow_mode)) {
1074 r->TermWin.shadow_mode = SHADOW_NONE;
1075 }
1076 else { /* no match == default */
1077 r->TermWin.shadow_mode = SHADOW_NONE;
1078 }
1079 }
1080 #endif
1081
1082
1083 /*----------------------------------------------------------------------*/
1084 /* EXTPROTO */
1085 const char**
rxvt_init_resources(rxvt_t * r,int argc,const char * const * argv)1086 rxvt_init_resources(rxvt_t* r, int argc, const char *const *argv)
1087 {
1088 register int i, r_argc;
1089 const char** cmd_argv;
1090 const char** r_argv;
1091 const char** rs;
1092
1093
1094 /*
1095 * Look for -exec option. Find => split and make cmd_argv[] of command args
1096 */
1097 for (r_argc = 0; r_argc < argc; r_argc++)
1098 if (!STRCMP(argv[r_argc], "-e") || !STRCMP(argv[r_argc], "-exec"))
1099 break;
1100 r_argv = (const char **)rxvt_malloc(sizeof(char*) * (r_argc + 1));
1101
1102 for (i = 0; i < r_argc; i++)
1103 r_argv[i] = (const char *)argv[i];
1104 r_argv[i] = NULL;
1105 if (r_argc == argc)
1106 cmd_argv = NULL;
1107 else {
1108 cmd_argv = (const char **)rxvt_malloc(sizeof(char*) * (argc - r_argc));
1109
1110 for (i = 0; i < argc - r_argc - 1; i++)
1111 cmd_argv[i] = (const char *)argv[i + r_argc + 1];
1112 cmd_argv[i] = NULL;
1113 }
1114
1115 /* clear all resources */
1116 rs = r->h->rs;
1117 for (i = 0; i < NUM_RESOURCES;)
1118 rs[i++] = NULL;
1119
1120 rs[Rs_name] = rxvt_r_basename(argv[0]);
1121
1122 /*
1123 ** Open display, get options/resources and create the window
1124 */
1125 if ((rs[Rs_display_name] = getenv("DISPLAY")) == NULL)
1126 rs[Rs_display_name] = ":0";
1127
1128 rxvt_get_options(r, r_argc, r_argv);
1129 free(r_argv);
1130
1131 #ifdef LOCAL_X_IS_UNIX
1132 if (rs[Rs_display_name][0] == ':') {
1133 int l = 5 + STRLEN(rs[Rs_display_name]);
1134 if (l <= 0 || l > 1024) /* possible integer overflow */
1135 l = 1024;
1136 val = rxvt_malloc(l);
1137 STRCPY(val, "unix");
1138 STRNCAT(val, rs[Rs_display_name], l-5);
1139 val[l-1] = (char) 0;
1140 DBG_MSG(1, (stderr, "Open X display %s\n", val));
1141 r->Xdisplay = XOpenDisplay(val);
1142 free(val);
1143 }
1144 #endif
1145
1146 if (r->Xdisplay == NULL) {
1147 DBG_MSG(1, (stderr, "Open X display %s\n", rs[Rs_display_name] ? rs[Rs_display_name] : "nil"));
1148 r->Xdisplay = XOpenDisplay(rs[Rs_display_name]);
1149 if (NULL == r->Xdisplay) {
1150 rxvt_print_error("can't open display %s", rs[Rs_display_name]);
1151 exit(EXIT_FAILURE);
1152 }
1153 }
1154
1155
1156 #ifdef DEBUG_X
1157 XSynchronize(r->Xdisplay, True);
1158 XSetErrorHandler((XErrorHandler) abort);
1159 /* XSetErrorHandler((XErrorHandler) rxvt_xerror_handler); */
1160 #else
1161 XSetErrorHandler((XErrorHandler) rxvt_xerror_handler);
1162 #endif
1163
1164 /* Initialize all atoms after establishing connection to X */
1165 for (i = 0; i < NUM_XA; i++) {
1166 r->h->xa[i] = XInternAtom(r->Xdisplay, xa_names[i], False);
1167 }
1168
1169
1170 rxvt_extract_resources(r, r->Xdisplay, rs[Rs_name]);
1171
1172 /*
1173 ** set any defaults not already set
1174 */
1175 if (cmd_argv && cmd_argv[0]) {
1176 if (!rs[Rs_title])
1177 rs[Rs_title] = rxvt_r_basename(cmd_argv[0]);
1178 if (!rs[Rs_iconName])
1179 rs[Rs_iconName] = rs[Rs_title];
1180 }
1181 else {
1182 if (!rs[Rs_title])
1183 rs[Rs_title] = rs[Rs_name];
1184 if (!rs[Rs_iconName])
1185 rs[Rs_iconName] = rs[Rs_name];
1186 }
1187
1188 if (rs[Rs_saveLinesAll]) {
1189 register int tmp = atoi(rs[Rs_saveLinesAll]);
1190 r->TermWin.saveLines = (tmp >=0 && tmp <= MAX_SAVELINES) ? tmp : DEFAULT_SAVELINES;
1191 }
1192
1193 #ifndef NO_FRILLS
1194 if (rs[Rs_int_bwidth]) {
1195 register int tmp = atoi (rs[Rs_int_bwidth]);
1196 r->TermWin.int_bwidth = (tmp >= 0 && tmp <= MAX_INTERNALBORDERWIDTH) ? tmp : DEFAULT_INTERNALBORDERWIDTH;
1197 }
1198
1199 if (rs[Rs_ext_bwidth]) {
1200 register int tmp = atoi (rs[Rs_ext_bwidth]);
1201 r->TermWin.ext_bwidth = (tmp >= 0 && tmp <= MAX_EXTERNALBORDERWIDTH) ? tmp : DEFAULT_EXTERNALBORDERWIDTH;
1202 }
1203 #endif
1204
1205 #ifndef NO_LINESPACE
1206 if (rs[Rs_lineSpace]) {
1207 register int tmp = atoi (rs[Rs_lineSpace]);
1208 r->TermWin.lineSpace = (tmp >= 0 && tmp <= MAX_LINESPACE) ? tmp : DEFAULT_LINESPACE;
1209 }
1210 #endif
1211
1212 #ifdef POINTER_BLANK
1213 if (rs[Rs_pointerBlankDelay]) {
1214 register int tmp = atoi (rs[Rs_pointerBlankDelay]);
1215 r->h->pointerBlankDelay = (tmp >= 0 && tmp <= MAX_BLANKDELAY) ? tmp : DEFAULT_BLANKDELAY;
1216 }
1217 #endif
1218
1219 /* Handle opacity of translucent window */
1220 if (rs[Rs_opacity]) {
1221 register int tmp = atoi (rs[Rs_opacity]);
1222 r->TermWin.opacity = (tmp >= 0 && tmp <= 100) ? 100 - tmp : 0;
1223
1224 #ifdef TRANSPARENT
1225 if (None != r->h->xa[XA_NET_WM_WINDOW_OPACITY] &&
1226 r->Options & Opt_transparent) {
1227 /* Override pseudo-transparent */
1228 r->Options &= ~Opt_transparent;
1229 }
1230 #endif
1231 }
1232 if (rs[Rs_opacityDegree]) {
1233 register int tmp = atoi (rs[Rs_opacityDegree]);
1234 r->TermWin.opacity_degree = (tmp > 0 && tmp <= 100) ? tmp : 1;
1235 }
1236
1237 #if defined(BACKGROUND_IMAGE) || defined(TRANSPARENT)
1238 if (rs[Rs_backgroundFade]) {
1239 register int fade;
1240 fade = atoi (rs[Rs_backgroundFade]);
1241 if (fade < 0 || fade > 100)
1242 fade = 100;
1243 r->TermWin.bgfade = 100 - fade;
1244 }
1245
1246 # ifdef TINTING_SUPPORT
1247 if (rs[Rs_shade]) {
1248 register int shade;
1249 shade = atoi (rs[Rs_shade]);
1250 if (shade < 0 || shade > 100)
1251 shade = 100;
1252 r->TermWin.shade = 100 - shade;
1253 }
1254 # endif
1255 #endif
1256
1257 #ifdef OFF_FOCUS_FADING
1258 if (rs[Rs_fade]) {
1259 register int fade;
1260 fade = atoi (rs[Rs_fade]);
1261 if (fade < 0 || fade > 100)
1262 fade = 100;
1263 r->TermWin.fade = 100 - fade;
1264 }
1265 #endif
1266
1267 #ifdef CURSOR_BLINK
1268 if (rs[Rs_cursorBlinkInterval]) {
1269 register long tmp = (long) atoi (rs[Rs_cursorBlinkInterval]);
1270 r->h->blinkInterval = (tmp >= MIN_BLINK_TIME && tmp <= MAX_BLINK_TIME) ? tmp : DEFAULT_BLINK_TIME;
1271 }
1272 /* convert msec to usec */
1273 r->h->blinkInterval *= 1000;
1274 #endif
1275
1276 #ifdef PRINTPIPE
1277 if (!rs[Rs_print_pipe])
1278 rs[Rs_print_pipe] = PRINTPIPE;
1279 #endif
1280 if (!rs[Rs_cutchars])
1281 rs[Rs_cutchars] = CUTCHARS;
1282 #ifdef ACS_ASCII
1283 if (!rs[Rs_acs_chars])
1284 rs[Rs_acs_chars] = ACS_CHARS;
1285 if ((i = STRLEN(rs[Rs_acs_chars])) < 0x20) {
1286 val = rxvt_realloc((void *)rs[Rs_acs_chars], 0x20);
1287 for (; i < 0x20; )
1288 val[i] = ' ';
1289 rs[Rs_acs_chars] = val;
1290 }
1291 #endif
1292 #ifndef NO_BACKSPACE_KEY
1293 if (!rs[Rs_backspace_key])
1294 # ifdef DEFAULT_BACKSPACE
1295 r->h->key_backspace = DEFAULT_BACKSPACE;
1296 # else
1297 r->h->key_backspace = "DEC"; /* can toggle between \010 or \177 */
1298 # endif
1299 else {
1300 char* val = STRDUP(rs[Rs_backspace_key]);
1301 rxvt_str_trim(val);
1302 rxvt_str_escaped(val);
1303 r->h->key_backspace = val;
1304 }
1305 #endif
1306 #ifndef NO_DELETE_KEY
1307 if (!rs[Rs_delete_key])
1308 # ifdef DEFAULT_DELETE
1309 r->h->key_delete = DEFAULT_DELETE;
1310 # else
1311 r->h->key_delete = "\033[3~";
1312 # endif
1313 else {
1314 char* val = STRDUP(rs[Rs_delete_key]);
1315 rxvt_str_trim(val);
1316 rxvt_str_escaped(val);
1317 r->h->key_delete = val;
1318 }
1319 #endif
1320 if (rs[Rs_answerbackstring]) {
1321 rxvt_str_trim((char *)rs[Rs_answerbackstring]);
1322 rxvt_str_escaped((char *)rs[Rs_answerbackstring]);
1323 }
1324
1325 if (rs[Rs_selectstyle]) {
1326 if (STRNCASECMP(rs[Rs_selectstyle], "oldword", 7) == 0)
1327 r->selection_style = OLD_WORD_SELECT;
1328 #ifndef NO_OLD_SELECTION
1329 else if (STRNCASECMP(rs[Rs_selectstyle], "old", 3) == 0)
1330 r->selection_style = OLD_SELECT;
1331 #endif
1332 }
1333
1334
1335 /* Set default X11 fonts */
1336 rxvt_set_default_font_x11 (r);
1337 #ifdef XFT_SUPPORT
1338 if (rs[Rs_xftsz]) {
1339 int sz = (int) atof (rs[Rs_xftsz]);
1340 r->TermWin.xftsize = (sz >= MIN_XFT_FONT_SIZE) ? sz : MIN_XFT_FONT_SIZE;
1341 }
1342 else /* default xft font size */
1343 r->TermWin.xftsize = DEFAULT_XFT_FONT_SIZE;
1344 # ifdef MULTICHAR_SET
1345 if (rs[Rs_xftmsz]) {
1346 int sz = (int) atof (rs[Rs_xftmsz]);
1347 r->TermWin.xftmsize = (sz >= MIN_XFT_FONT_SIZE) ? sz : MIN_XFT_FONT_SIZE;
1348 }
1349 else /* default xft font size */
1350 r->TermWin.xftmsize = DEFAULT_XFT_FONT_SIZE;
1351 # endif /* MULTICHAR_SET */
1352
1353 /* Set default Freetype fonts */
1354 rxvt_set_default_font_xft (r);
1355 #endif /* XFT_SUPPORT */
1356
1357
1358 #ifdef TEXT_SHADOW
1359 rxvt_init_shadow_mode (r, rs[Rs_textShadowMode]);
1360 #endif
1361
1362 #ifdef XTERM_REVERSE_VIDEO
1363 /* this is how xterm implements reverseVideo */
1364 if (r->Options & Opt_reverseVideo) {
1365 if (!rs[Rs_color + Color_fg])
1366 rs[Rs_color + Color_fg] = def_colorName[Color_bg];
1367 if (!rs[Rs_color + Color_bg])
1368 rs[Rs_color + Color_bg] = def_colorName[Color_fg];
1369
1370 for (i = 0; i < MAX_PAGES; i++) {
1371 int vtfg = Rs_color + TOTAL_COLORS + i;
1372 int vtbg = Rs_color + TOTAL_COLORS + MAX_PAGES + i;
1373 char* fg = (char*) rs[vtfg];
1374 char* bg = (char*) rs[vtbg];
1375 /* foreground color of i terminal */
1376 if (ISSET_VTFG(r, i))
1377 rs[vtfg] = ISSET_VTBG(r, i) ? bg :
1378 def_colorName[Color_bg];
1379 /* background color of i terminal */
1380 if (ISSET_VTBG(r, i))
1381 rs[vtbg] = ISSET_VTFG(r, i) ? fg :
1382 def_colorName[Color_fg];
1383 }
1384 }
1385 #endif
1386
1387 for (i = 0; i < NRS_COLORS; i++)
1388 if (!rs[Rs_color + i])
1389 rs[Rs_color + i] = def_colorName[i];
1390
1391 #ifndef XTERM_REVERSE_VIDEO
1392 /* this is how we implement reverseVideo */
1393 if (r->Options & Opt_reverseVideo) {
1394 SWAP_IT(rs[Rs_color + Color_fg], rs[Rs_color + Color_bg], const char *);
1395 for (i = 0; i < MAX_PAGES; i++) {
1396 int vtfg = Rs_color + TOTAL_COLORS + i;
1397 int vtbg = Rs_color + TOTAL_COLORS + MAX_PAGES + i;
1398 SWAP_IT(rs[vtfg], rs[vtbg], const char*);
1399 }
1400 }
1401 #endif
1402
1403 /* convenient aliases for setting fg/bg to colors */
1404 rxvt_color_aliases(r, Color_fg);
1405 rxvt_color_aliases(r, Color_bg);
1406 #ifndef NO_CURSORCOLOR
1407 rxvt_color_aliases(r, Color_cursor);
1408 rxvt_color_aliases(r, Color_cursor2);
1409 #endif /* NO_CURSORCOLOR */
1410 rxvt_color_aliases(r, Color_pointer);
1411 rxvt_color_aliases(r, Color_border);
1412 #ifndef NO_BOLD_UNDERLINE_REVERSE
1413 rxvt_color_aliases(r, Color_BD);
1414 rxvt_color_aliases(r, Color_UL);
1415 rxvt_color_aliases(r, Color_RV);
1416 #endif /* ! NO_BOLD_UNDERLINE_REVERSE */
1417
1418 return cmd_argv;
1419 }
1420
1421 /*----------------------------------------------------------------------*/
1422 /* EXTPROTO */
1423 void
rxvt_init_env(rxvt_t * r)1424 rxvt_init_env(rxvt_t *r)
1425 {
1426 int i;
1427 unsigned int u;
1428 char* val;
1429
1430
1431 #ifdef DISPLAY_IS_IP
1432 /* Fixup display_name for export over pty to any interested
1433 ** terminal clients via "ESC[7n" (e.g. shells). Note we use
1434 ** the pure IP number (for the first non-loopback interface)
1435 ** that we get from rxvt_network_display(). This is more
1436 ** "name-resolution-portable", if you will, and probably allows
1437 ** for faster x-client startup if your name server is beyond
1438 ** a slow link or overloaded at client startup. Of course that
1439 ** only helps the shell's child processes, not us.
1440 **
1441 ** Giving out the display_name also affords a potential
1442 ** security hole
1443 */
1444 val = rxvt_network_display(r->h->rs[Rs_display_name]);
1445 r->h->rs[Rs_display_name] = (const char *)val;
1446 if (val == NULL)
1447 #endif /* DISPLAY_IS_IP */
1448 val = XDisplayString(r->Xdisplay);
1449 if (r->h->rs[Rs_display_name] == NULL)
1450 r->h->rs[Rs_display_name] = val; /* use broken `:0' value */
1451
1452 i = STRLEN(val) + 9;
1453 if (i <= 0 || i > 1024) /* possible integer overflow */
1454 i = 1024;
1455 r->h->env_display = rxvt_malloc(i * sizeof(char));
1456 STRCPY (r->h->env_display, "DISPLAY=");
1457 STRNCAT (r->h->env_display, val, i-9);
1458 r->h->env_display[i-1] = (char) 0;
1459
1460 /* avoiding the math library:
1461 * i = (int)(ceil(log10((unsigned int)r->TermWin.parent))) */
1462 for (i = 0, u = (unsigned int)r->TermWin.parent; u; u /= 10, i++)
1463 ;
1464 MAX_IT(i, 1);
1465 r->h->env_windowid = rxvt_malloc((i + 10) * sizeof(char));
1466
1467 sprintf(r->h->env_windowid, "WINDOWID=%u",
1468 (unsigned int)r->TermWin.parent);
1469
1470 /*
1471 ** add entries to the environment:
1472 ** @ DISPLAY: in case we started with -display
1473 ** @ WINDOWID: X window id number of the window
1474 ** @ COLORTERM: terminal sub-name and also indicates its color
1475 ** @ TERM: terminal name
1476 ** @ TERMINFO: path to terminfo directory
1477 */
1478 #ifdef HAVE_PUTENV
1479 putenv(r->h->env_display);
1480 putenv(r->h->env_windowid);
1481
1482 # ifdef RXVT_TERMINFO
1483 putenv("TERMINFO=" RXVT_TERMINFO);
1484 # endif
1485 if (XDEPTH <= 2)
1486 putenv("COLORTERM=" COLORTERMENV "-mono");
1487 else
1488 putenv("COLORTERM=" COLORTERMENVFULL);
1489 if (r->h->rs[Rs_term_name] != NULL) {
1490 int l = 6 + STRLEN(r->h->rs[Rs_term_name]);
1491 if (l <= 0 || l > 1024) /* possible integer overflow */
1492 l = 1024;
1493 r->h->env_term = rxvt_malloc(l * sizeof(char));
1494 STRCPY (r->h->env_term, "TERM=");
1495 STRNCAT (r->h->env_term, r->h->rs[Rs_term_name], l-6);
1496 r->h->env_term[l-1] = (char) 0;
1497 putenv(r->h->env_term);
1498 }
1499 else
1500 putenv("TERM=" TERMENV);
1501 #endif /* HAVE_PUTENV */
1502
1503 #ifdef HAVE_UNSETENV
1504 /* avoid passing old settings and confusing term size */
1505 unsetenv("LINES");
1506 unsetenv("COLUMNS");
1507 unsetenv("TERMCAP"); /* terminfo should be okay */
1508 #endif /* HAVE_UNSETENV */
1509
1510 /*
1511 ** allocate environment variable for MRXVT_TABTITLE, we will
1512 ** use it in rxvt_create_termwin later for each tab terminal
1513 */
1514 r->h->env_tabtitle = rxvt_malloc(sizeof(TABTITLEENV) + MAX_TAB_TXT + 1);
1515 }
1516
1517 /*----------------------------------------------------------------------*/
1518 /*
1519 * This is more or less stolen straight from XFree86 xterm.
1520 * This should support all European type languages.
1521 */
1522 /* EXTPROTO */
1523 void
rxvt_init_xlocale(rxvt_t * r)1524 rxvt_init_xlocale(rxvt_t *r)
1525 {
1526 #ifdef USE_XIM
1527 if (r->h->locale == NULL)
1528 rxvt_print_error("Setting locale failed.");
1529 else {
1530 XChangeProperty(r->Xdisplay, r->TermWin.parent,
1531 r->h->xa[XA_WM_LOCALE_NAME], XA_STRING, 8, PropModeReplace,
1532 (unsigned char *)r->h->locale, STRLEN(r->h->locale));
1533
1534 if (XSupportsLocale() != True) {
1535 rxvt_print_error("The locale is not supported by Xlib");
1536 return;
1537 }
1538 rxvt_IM_set_fontset (r, 0);
1539
1540 /* see if we can connect yet */
1541 rxvt_IM_init_callback (r->Xdisplay, NULL, NULL);
1542
1543 /* To avoid Segmentation Fault in C locale: Solaris only? */
1544 if (STRCMP(r->h->locale, "C"))
1545 XRegisterIMInstantiateCallback(r->Xdisplay, NULL, NULL,
1546 NULL, rxvt_IM_init_callback, NULL);
1547 }
1548 #endif
1549 }
1550
1551 /*----------------------------------------------------------------------*/
1552 /* EXTPROTO */
1553 void
rxvt_init_command(rxvt_t * r,const char * const * argv)1554 rxvt_init_command(rxvt_t* r, const char *const *argv)
1555 {
1556 /*
1557 ** Initialize the command connection. This should be called
1558 ** after the X server connection is established.
1559 */
1560 struct sigaction act;
1561
1562
1563 /*
1564 ** Enable delete window protocol so that if the top-level window
1565 ** of the terminal is destroyed by the Session Manager, we can
1566 ** receive a ClientMessage event and do something gracefully.
1567 */
1568 XSetWMProtocols (r->Xdisplay, r->TermWin.parent,
1569 &(r->h->xa[XA_WMDELETEWINDOW]), 1);
1570
1571 #ifdef META8_OPTION
1572 r->h->meta_char = (r->Options & Opt_meta8 ? 0x80 : C0_ESC);
1573 #endif
1574 rxvt_get_ourmods(r);
1575
1576 #ifdef GREEK_SUPPORT
1577 greek_init();
1578 #endif
1579
1580 r->Xfd = XConnectionNumber(r->Xdisplay);
1581
1582 #ifdef CURSOR_BLINK
1583 if (r->Options & Opt_cursorBlink)
1584 (void)gettimeofday(&r->h->lastcursorchange, NULL);
1585 #endif
1586
1587
1588 act.sa_handler = rxvt_Exit_signal;
1589 act.sa_flags = 0;
1590 sigemptyset (&act.sa_mask);
1591 sigaction (SIGHUP, &act, NULL);
1592 #ifndef OS_SVR4
1593 sigaction (SIGINT, &act, NULL);
1594 #endif
1595 sigaction (SIGQUIT, &act, NULL);
1596 sigaction (SIGTERM, &act, NULL);
1597
1598 act.sa_handler = rxvt_Child_signal;
1599 act.sa_flags = 0;
1600 sigaction (SIGCHLD, &act, NULL);
1601
1602 /*
1603 signal(SIGHUP, rxvt_Exit_signal);
1604 #ifndef OS_SVR4
1605 signal(SIGINT, rxvt_Exit_signal);
1606 #endif
1607 signal(SIGQUIT, rxvt_Exit_signal);
1608 signal(SIGTERM, rxvt_Exit_signal);
1609 signal(SIGCHLD, rxvt_Child_signal);
1610 */
1611
1612 /* need to trap SIGURG for SVR4 (Unixware) rlogin */
1613 /* signal (SIGURG, SIG_DFL); */
1614 }
1615
1616
1617
1618 #ifdef OFF_FOCUS_FADING
1619 /* EXTPROTO */
1620 unsigned long
rxvt_fade_color(rxvt_t * r,unsigned long pixel)1621 rxvt_fade_color (rxvt_t* r, unsigned long pixel)
1622 {
1623 if (r->h->rs[Rs_fade]) {
1624 XColor faded_xcol;
1625
1626 faded_xcol.pixel = pixel;
1627 XQueryColor (r->Xdisplay, XCMAP, &faded_xcol);
1628 faded_xcol.red = (faded_xcol.red / 100) * r->TermWin.fade;
1629 faded_xcol.green = (faded_xcol.green / 100) * r->TermWin.fade;
1630 faded_xcol.blue = (faded_xcol.blue / 100) * r->TermWin.fade;
1631
1632 rxvt_alloc_color (r, &faded_xcol, "Faded");
1633 return faded_xcol.pixel;
1634 }
1635
1636 return pixel;
1637 }
1638 #endif
1639
1640
1641 /*
1642 ** rxvt_restore_ufbg_color should always be called before
1643 ** rxvt_restore_pix_color.
1644 */
1645 /* EXTPROTO */
1646 int
rxvt_restore_ufbg_color(rxvt_t * r)1647 rxvt_restore_ufbg_color (rxvt_t* r)
1648 {
1649 /* Restore bg and ufbg color state now */
1650 if (ISSET_PIXCOLOR(r->h, Color_ufbg) && r->ufbg_switched) {
1651 DBG_MSG(2, (stderr, "switch back to bg color\n"));
1652 SWAP_IT (r->PixColors[Color_bg], r->PixColors[Color_ufbg],
1653 unsigned long);
1654 r->ufbg_switched = 0;
1655 return (1); /* switched */
1656 }
1657 return (0); /* no change */
1658 }
1659
1660
1661 /*
1662 ** rxvt_switch_pix_color should always be called before
1663 ** rxvt_switch_ufbg_color.
1664 */
1665 /* EXTPROTO */
1666 int
rxvt_switch_ufbg_color(rxvt_t * r)1667 rxvt_switch_ufbg_color (rxvt_t* r)
1668 {
1669 if (ISSET_PIXCOLOR(r->h, Color_ufbg) && !r->ufbg_switched) {
1670 DBG_MSG(2, (stderr, "switch to ufbg color\n"));
1671 SWAP_IT (r->PixColors[Color_bg], r->PixColors[Color_ufbg],
1672 unsigned long);
1673 r->ufbg_switched = 1;
1674 return (1); /* switched */
1675 }
1676 return (0); /* no change */
1677 }
1678
1679
1680 #ifdef OFF_FOCUS_FADING
1681 /* EXTPROTO */
1682 int
rxvt_restore_pix_color(rxvt_t * r)1683 rxvt_restore_pix_color (rxvt_t* r)
1684 {
1685 /* Restore off-focus color state now */
1686 if (r->h->rs[Rs_fade] && r->color_switched) {
1687 DBG_MSG(2, (stderr, "switch back to focus color\n"));
1688 SWAP_IT (r->PixColors, r->PixColorsUnfocus, unsigned long*);
1689 r->color_switched = 0;
1690 return (1); /* switched */
1691 }
1692 return (0); /* no change */
1693 }
1694
1695
1696 /* EXTPROTO */
1697 int
rxvt_switch_pix_color(rxvt_t * r)1698 rxvt_switch_pix_color (rxvt_t* r)
1699 {
1700 if (r->h->rs[Rs_fade] && !r->color_switched) {
1701 DBG_MSG(2, (stderr, "switch back to unfocus color\n"));
1702 SWAP_IT (r->PixColors, r->PixColorsUnfocus, unsigned long*);
1703 r->color_switched = 1;
1704 return (1); /* switched */
1705 }
1706 return (0); /* no change */
1707 }
1708 #endif
1709
1710
1711 /* INTPROTO */
1712 void
rxvt_init_colors(rxvt_t * r)1713 rxvt_init_colors (rxvt_t *r)
1714 {
1715 register int i;
1716
1717
1718 for (i = 0; i < (XDEPTH <= 2 ? 2 : NRS_COLORS); i++) {
1719 XColor xcol;
1720
1721 if (!r->h->rs[Rs_color + i])
1722 continue;
1723
1724 if (!rxvt_parse_alloc_color(r, &xcol, r->h->rs[Rs_color + i])) {
1725 #ifndef XTERM_REVERSE_VIDEO
1726 if (i < 2 && (r->Options & Opt_reverseVideo)) {
1727 r->h->rs[Rs_color + i] = def_colorName[!i];
1728 }
1729 else
1730 #endif
1731 r->h->rs[Rs_color + i] = def_colorName[i];
1732
1733 if (!r->h->rs[Rs_color + i])
1734 continue;
1735 if (!rxvt_parse_alloc_color (r, &xcol,
1736 r->h->rs[Rs_color + i])) {
1737 switch (i) {
1738 case Color_fg:
1739 case Color_bg:
1740 /* fatal: need bg/fg color */
1741 rxvt_print_error("aborting");
1742 exit(EXIT_FAILURE);
1743 /* NOTREACHED */
1744 break;
1745 #ifndef NO_CURSORCOLOR
1746 case Color_cursor2:
1747 xcol.pixel = r->PixColors[Color_fg];
1748 break;
1749 #endif /* ! NO_CURSORCOLOR */
1750 case Color_pointer:
1751 xcol.pixel = r->PixColors[Color_fg];
1752 break;
1753 default:
1754 xcol.pixel = r->PixColors[Color_bg]; /* None */
1755 break;
1756 }
1757 }
1758 }
1759 r->PixColors[i] = xcol.pixel;
1760 #ifdef OFF_FOCUS_FADING
1761 r->PixColorsUnfocus[i] = rxvt_fade_color (r, xcol.pixel);
1762 #endif
1763 #ifdef XFT_SUPPORT
1764 rxvt_alloc_xft_color (r, xcol.pixel, &(r->XftColors[i]));
1765 #endif
1766 SET_PIXCOLOR(r->h, i);
1767 }
1768
1769 if (XDEPTH <= 2 || !r->h->rs[Rs_color + Color_pointer]) {
1770 r->PixColors[Color_pointer] = r->PixColors[Color_fg];
1771 #ifdef XFT_SUPPORT
1772 r->XftColors[Color_pointer] = r->XftColors[Color_fg];
1773 #endif
1774 }
1775 if (XDEPTH <= 2 || !r->h->rs[Rs_color + Color_border]) {
1776 r->PixColors[Color_border] = r->PixColors[Color_fg];
1777 #ifdef XFT_SUPPORT
1778 r->XftColors[Color_border] = r->XftColors[Color_fg];
1779 #endif
1780 }
1781
1782
1783 /* we have not switched the bg/ufbg color */
1784 r->ufbg_switched = 0;
1785
1786 /* Save global foreground/background colors */
1787 r->h->global_fg = r->PixColors[Color_fg];
1788 r->h->global_bg = r->PixColors[Color_bg];
1789 #ifdef XFT_SUPPORT
1790 r->h->global_xftfg = r->XftColors[Color_fg];
1791 r->h->global_xftbg = r->XftColors[Color_bg];
1792 #endif
1793
1794
1795 /* Initialize fg/bg colors for individual terminals */
1796 for (i = 0; i < MAX_PAGES; i++) {
1797 XColor xcol;
1798 int vtfg = Rs_color + TOTAL_COLORS + i;
1799 int vtbg = Rs_color + TOTAL_COLORS + MAX_PAGES + i;
1800
1801 /* foreground color of i terminal */
1802 if (ISSET_VTFG(r, i) &&
1803 rxvt_parse_alloc_color(r, &xcol, r->h->rs[vtfg])) {
1804 VTFG(r, i) = xcol.pixel;
1805 #ifdef XFT_SUPPORT
1806 rxvt_alloc_xft_color (r, VTFG(r, i), &(VTXFTFG(r, i)));
1807 #endif
1808 }
1809
1810 /* background color of i terminal */
1811 if (ISSET_VTBG(r, i) &&
1812 rxvt_parse_alloc_color(r, &xcol, r->h->rs[vtbg])) {
1813 VTBG(r, i) = xcol.pixel;
1814 #ifdef XFT_SUPPORT
1815 rxvt_alloc_xft_color (r, VTBG(r, i), &(VTXFTBG(r, i)));
1816 #endif
1817 }
1818 }
1819
1820
1821 /*
1822 ** get scrollBar/menuBar shadow colors
1823 **
1824 ** The calculations of topShadow/bottomShadow values are adapted
1825 ** from the fvwm window manager.
1826 **/
1827 #ifdef KEEP_SCROLLCOLOR
1828 if (XDEPTH <= 2) { /* Monochrome */
1829 r->PixColors[Color_scroll] = r->PixColors[Color_fg];
1830 r->PixColors[Color_topShadow] = r->PixColors[Color_bg];
1831 r->PixColors[Color_bottomShadow] = r->PixColors[Color_bg];
1832 }
1833 else {
1834 XColor xcol[3];
1835 /* xcol[0] == white
1836 * xcol[1] == top shadow
1837 * xcol[2] == bot shadow */
1838
1839 xcol[1].pixel = r->PixColors[Color_scroll];
1840 # ifdef PREFER_24BIT
1841 xcol[0].red = xcol[0].green = xcol[0].blue = (unsigned short)~0;
1842 rxvt_alloc_color(r, &(xcol[0]), "White");
1843 /* XFreeColors(r->Xdisplay, XCMAP, &(xcol[0].pixel), 1, ~0); */
1844 XQueryColors(r->Xdisplay, XCMAP, &(xcol[1]), 1);
1845 # else
1846 xcol[0].pixel = WhitePixel(r->Xdisplay, XSCREEN);
1847 XQueryColors(r->Xdisplay, XCMAP, xcol, 2);
1848 # endif
1849
1850 /* bottomShadowColor */
1851 xcol[2].red = xcol[1].red / 2;
1852 xcol[2].green = xcol[1].green / 2;
1853 xcol[2].blue = xcol[1].blue / 2;
1854 if (!rxvt_alloc_color(r, &(xcol[2]), "Color_bottomShadow"))
1855 xcol[2].pixel = r->PixColors[Color_Black];
1856 r->PixColors[Color_bottomShadow] = xcol[2].pixel;
1857
1858 /* topShadowColor */
1859 xcol[1].red = max((xcol[0].red / 5), xcol[1].red);
1860 xcol[1].green = max((xcol[0].green / 5), xcol[1].green);
1861 xcol[1].blue = max((xcol[0].blue / 5), xcol[1].blue);
1862 xcol[1].red = min(xcol[0].red, (xcol[1].red * 7) / 5);
1863 xcol[1].green = min(xcol[0].green, (xcol[1].green * 7) / 5);
1864 xcol[1].blue = min(xcol[0].blue, (xcol[1].blue * 7) / 5);
1865
1866 if (!rxvt_alloc_color(r, &(xcol[1]), "Color_topShadow"))
1867 xcol[1].pixel = r->PixColors[Color_White];
1868 r->PixColors[Color_topShadow] = xcol[1].pixel;
1869 }
1870 #endif /* KEEP_SCROLLCOLOR */
1871
1872
1873 #ifdef TEXT_SHADOW
1874 if (r->h->rs[Rs_textShadow]) {
1875 XColor xcol;
1876 if (rxvt_parse_alloc_color (r, &xcol, r->h->rs[Rs_textShadow]))
1877 r->TermWin.shadow = xcol.pixel;
1878 else
1879 r->TermWin.shadow = r->PixColors[Color_Black];
1880 # ifdef XFT_SUPPORT
1881 rxvt_alloc_xft_color (r, r->TermWin.shadow, &(r->TermWin.xftshadow));
1882 # endif
1883 }
1884 #endif
1885 }
1886
1887
1888 /*----------------------------------------------------------------------*/
1889 /* color aliases, fg/bg bright-bold */
1890 /* INTPROTO */
1891 void
rxvt_color_aliases(rxvt_t * r,int idx)1892 rxvt_color_aliases(rxvt_t* r, int idx)
1893 {
1894 if (r->h->rs[Rs_color + idx] &&
1895 isdigit((int) *(r->h->rs[Rs_color + idx]))) {
1896 int i = atoi(r->h->rs[Rs_color + idx]);
1897
1898 if (i >= 8 && i <= 15) { /* bright colors */
1899 i -= 8;
1900 #ifndef NO_BRIGHTCOLOR
1901 r->h->rs[Rs_color + idx] = r->h->rs[Rs_color + minBrightCOLOR + i];
1902 return;
1903 #endif
1904 }
1905 if (i >= 0 && i <= 7) /* normal colors */
1906 r->h->rs[Rs_color + idx] = r->h->rs[Rs_color + minCOLOR +i];
1907 }
1908 }
1909
1910
1911 /* INTPROTO */
1912 void
rxvt_init_win_size(rxvt_t * r)1913 rxvt_init_win_size (rxvt_t* r)
1914 {
1915 int flags = 0; /* must initialize to 0!!! */
1916 short recalc_x = 0, recalc_y = 0;
1917 int x, y;
1918 unsigned int w, h;
1919
1920
1921 r->szHint.flags = PMinSize | PResizeInc | PBaseSize | PWinGravity;
1922 r->szHint.win_gravity = NorthWestGravity;
1923
1924 /* Set default terminal columns and rows */
1925 r->TermWin.ncol = 80;
1926 r->TermWin.nrow = 24;
1927 r->szHint.x = 0;
1928 r->szHint.y = 0;
1929
1930 /* Parse geometry */
1931 if (r->h->rs[Rs_geometry])
1932 flags = XParseGeometry(r->h->rs[Rs_geometry], &x, &y, &w, &h);
1933 if (flags & WidthValue) {
1934 r->TermWin.ncol = BOUND_POSITIVE_INT16(w);
1935 r->szHint.flags |= USSize;
1936 }
1937 if (flags & HeightValue) {
1938 r->TermWin.nrow = BOUND_POSITIVE_INT16(h);
1939 r->szHint.flags |= USSize;
1940 }
1941 if (flags & XValue) {
1942 r->szHint.x = x;
1943 r->szHint.flags |= USPosition;
1944 if (flags & XNegative) {
1945 recalc_x = 1;
1946 r->szHint.win_gravity = NorthEastGravity;
1947 }
1948 }
1949 if (flags & YValue) {
1950 r->szHint.y = y;
1951 r->szHint.flags |= USPosition;
1952 if (flags & YNegative) {
1953 recalc_y = 1;
1954 if (r->szHint.win_gravity == NorthEastGravity)
1955 r->szHint.win_gravity = SouthEastGravity;
1956 else
1957 r->szHint.win_gravity = SouthWestGravity;
1958 }
1959 }
1960
1961 /* Calculate the base width and height */
1962 r->szHint.base_width = 2 * r->TermWin.int_bwidth;
1963 r->szHint.base_height = 2 * r->TermWin.int_bwidth;
1964 #ifdef HAVE_SCROLLBARS
1965 if (r->Options & Opt_scrollBar)
1966 r->szHint.base_width += rxvt_scrollbar_rwidth (r);
1967 #endif
1968 #if defined(HAVE_MENUBAR) && (MENUBAR_MAX > 1)
1969 if (r->Options & Opt_showMenu)
1970 r->szHint.base_height += rxvt_menubar_rheight (r);
1971 #endif
1972 if (!(r->Options2 & Opt2_hideTabbar))
1973 r->szHint.base_height += rxvt_tabbar_rheight (r);
1974
1975 /* Calculate the terminal increment width and height */
1976 r->szHint.width_inc = r->TermWin.fwidth;
1977 r->szHint.height_inc = r->TermWin.fheight;
1978
1979 /* Set the terminal minimal width and height */
1980 r->szHint.min_width = r->szHint.base_width + r->szHint.width_inc;
1981 r->szHint.min_height = r->szHint.base_height + r->szHint.height_inc;
1982
1983 /* Set the terminal width and height */
1984 r->szHint.width = r->szHint.base_width + Width2Pixel (r->TermWin.ncol);
1985 r->szHint.height = r->szHint.base_height + Height2Pixel (r->TermWin.nrow);
1986
1987 /* Recalculate the starting position */
1988 if (recalc_x)
1989 r->szHint.x += (DisplayWidth(r->Xdisplay, XSCREEN)
1990 - r->szHint.width - 2 * r->TermWin.ext_bwidth);
1991 if (recalc_y)
1992 r->szHint.y += (DisplayHeight(r->Xdisplay, XSCREEN)
1993 - r->szHint.height - 2 * r->TermWin.ext_bwidth);
1994
1995 /* Set the terminal window starting position */
1996 r->h->window_vt_x = (r->Options & Opt_scrollBar_right) ?
1997 0 : r->szHint.base_width - 2*r->TermWin.int_bwidth;
1998 r->h->window_vt_y = r->szHint.base_height - 2*r->TermWin.int_bwidth;
1999 if ((r->Options2 & Opt2_bottomTabbar) &&
2000 !(r->Options2 & Opt2_hideTabbar))
2001 r->h->window_vt_y -= rxvt_tabbar_rheight (r);
2002 }
2003
2004
2005 /*----------------------------------------------------------------------*/
2006 /*
2007 * Probe the modifier keymap to get the Meta (Alt) and Num_Lock settings
2008 * Use resource ``modifier'' to override the Meta modifier
2009 */
2010 /* INTPROTO */
2011 void
rxvt_get_ourmods(rxvt_t * r)2012 rxvt_get_ourmods(rxvt_t *r)
2013 {
2014 int i, j, k;
2015 int requestedmeta, realmeta, realalt;
2016 const char* cm;
2017 const char* rsmod;
2018 XModifierKeymap* map;
2019 KeyCode* kc;
2020 const unsigned int modmasks[] = {
2021 Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask
2022 };
2023
2024
2025 requestedmeta = realmeta = realalt = 0;
2026
2027 rsmod = r->h->rs[Rs_modifier];
2028 if (rsmod &&
2029 STRCASECMP(rsmod, "mod1") >= 0 &&
2030 STRCASECMP(rsmod, "mod5") <= 0)
2031 requestedmeta = rsmod[3] - '0';
2032
2033 map = XGetModifierMapping(r->Xdisplay);
2034 kc = map->modifiermap;
2035 for (i = 1; i < 6; i++) {
2036 k = (i + 2) * map->max_keypermod; /* skip shift/lock/control */
2037 for (j = map->max_keypermod; j--; k++) {
2038 if (kc[k] == 0)
2039 break;
2040
2041 switch (XKeycodeToKeysym(r->Xdisplay, kc[k], 0)) {
2042 case XK_Num_Lock:
2043 r->h->ModNumLockMask = modmasks[i - 1];
2044 /* FALLTHROUGH */
2045 default:
2046 continue; /* for(;;) */
2047 case XK_Meta_L:
2048 case XK_Meta_R:
2049 cm = "meta";
2050 realmeta = i;
2051 break;
2052 case XK_Alt_L:
2053 case XK_Alt_R:
2054 cm = "alt";
2055 realalt = i;
2056 break;
2057 case XK_Super_L:
2058 case XK_Super_R:
2059 cm = "super";
2060 break;
2061 case XK_Hyper_L:
2062 case XK_Hyper_R:
2063 cm = "hyper";
2064 break;
2065 }
2066
2067 if (rsmod && STRNCASECMP(rsmod, cm, STRLEN(cm)) == 0)
2068 requestedmeta = i;
2069 }
2070 }
2071 XFreeModifiermap(map);
2072
2073 i = (requestedmeta ? requestedmeta : (
2074 realmeta ? realmeta : (
2075 realalt ? realalt : 0)));
2076
2077 if (i)
2078 r->h->ModMetaMask = modmasks[i - 1];
2079 }
2080
2081
2082
2083 /* INTPROTO */
2084 char**
rxvt_string_to_argv(char * string,int * argc)2085 rxvt_string_to_argv (char* string, int* argc)
2086 {
2087 register int i;
2088 char** pret;
2089 char* pbeg;
2090 char* pcur;
2091
2092 /* not implemented yet */
2093 *argc = 0;
2094 if (NULL == string)
2095 return NULL;
2096
2097 #define MAX_ARGV (64)
2098 /* Up to 64 argv */
2099 pret = (char**) rxvt_malloc (MAX_ARGV * sizeof (char*));
2100
2101 DBG_MSG(1, (stderr, "fetch command argv for the tab\n"));
2102 pbeg = pcur = string;
2103 for (i = 0; i < MAX_ARGV-1; i ++) {
2104 int dq = 0; /* double quote */
2105 int sq = 0; /* single quote */
2106 /* set default argument to NULL */
2107 pret[i] = NULL;
2108
2109 /* skip any spaces and non-printable */
2110 while (*pcur &&
2111 (isspace ((int) *pcur) || !isprint ((int) *pcur)))
2112 pcur ++;
2113 /* stop if reach end of string */
2114 if (!*pcur)
2115 break;
2116
2117 /* beginning of the token */
2118 if (isalnum ((int) *pcur) || ispunct ((int) *pcur)) {
2119 if ('\"' == *pcur) {
2120 /* beginning of double quote */
2121 dq = 1; pbeg = pcur + 1; pcur ++;
2122 }
2123 else if ('\'' == *pcur) {
2124 /* beginning of single quote */
2125 sq = 1; pbeg = pcur + 1; pcur ++;
2126 }
2127 else /* normal characters */
2128 pbeg = pcur;
2129 }
2130 #ifdef DEBUG
2131 else /* shouldn't happen */
2132 assert (0);
2133 #endif
2134
2135 /* move forward one character */
2136 pcur ++;
2137
2138 /* now fetch the new token */
2139 while (*pcur && /* not end of string */
2140 ((dq && *pcur != '\"') || /* not end of double quote */
2141 (sq && *pcur != '\'') || /* not end of single quote */
2142 (!dq && !sq && !isspace ((int) *pcur))))
2143 *pcur ++;
2144
2145 if (!*pcur && /* end of string */
2146 (dq || sq)) /* no match of quote is found */
2147 goto NotMatch;
2148
2149 if (!*pcur) { /* end of string */
2150 pret[i] = STRDUP (pbeg);
2151 DBG_MSG(1, (stderr, " argv[%d] = %s\n", i, pret[i]));
2152 break; /* ready to return */
2153 }
2154
2155 if ((dq && *pcur == '\"') || /* end of double quote */
2156 (sq && *pcur == '\'') || /* end of single quote */
2157 (!dq && !sq && isspace ((int) *pcur))) { /* space */
2158 int len = sizeof (char) * (pcur - pbeg) + 1;
2159
2160 assert (len > 0); /* possible integer overflow? */
2161 pret[i] = (char*) rxvt_malloc (len * sizeof(char));
2162 MEMCPY (pret[i], pbeg, len-1);
2163 pret[i][len-1] = (char) 0;
2164 DBG_MSG(1, (stderr, " argv[%d] = %s\n", i, pret[i]));
2165
2166 /* forward to next character */
2167 pcur ++;
2168
2169 /* fetch next token */
2170 continue;
2171 }
2172
2173 /* shouldn't get here */
2174 assert (0);
2175 }
2176
2177 #undef MAX_ARGV
2178 /* set the end of argv */
2179 if (pret[i]) {
2180 *argc = i+1;
2181 pret[i+1] = NULL;
2182 }
2183 else if (i) { /* non-empty argv */
2184 *argc = i;
2185 }
2186 else { /* empty argv */
2187 free (pret);
2188 return NULL;
2189 }
2190 return pret;
2191
2192 NotMatch:
2193 free (pret);
2194 return NULL;
2195 }
2196
2197
2198 /* EXTPROTO */
2199 void
rxvt_switch_fgbg_color(rxvt_t * r,int page)2200 rxvt_switch_fgbg_color (rxvt_t* r, int page)
2201 {
2202 /* Restore bg/ufbg color */
2203 rxvt_restore_ufbg_color (r);
2204 #ifdef OFF_FOCUS_FADING
2205 /* Restore off-focus color */
2206 rxvt_restore_pix_color (r);
2207 #endif
2208
2209 /*
2210 ** Set fg/bg color of individual terminal
2211 */
2212 r->PixColors[Color_fg] = *(PVTS(r, page)->p_fg);
2213 r->PixColors[Color_bg] = *(PVTS(r, page)->p_bg);
2214 #ifdef XFT_SUPPORT
2215 r->XftColors[Color_fg] = *(PVTS(r, page)->p_xftfg);
2216 r->XftColors[Color_bg] = *(PVTS(r, page)->p_xftbg);
2217 #endif /* XFT_SUPPORT */
2218
2219 /*
2220 ** Set foreground/background color for GC. This is necessary.
2221 ** Since all VTs share the same GC, if we do not set the color
2222 ** here, color from other VTs will be used to draw the following
2223 ** text till there is a color change.
2224 */
2225 XSetForeground (r->Xdisplay, r->TermWin.gc, r->PixColors[Color_fg]);
2226 XSetBackground (r->Xdisplay, r->TermWin.gc, r->PixColors[Color_bg]);
2227 }
2228
2229
2230 /* INTPROTO */
2231 termenv_t
rxvt_get_termenv(const char * env)2232 rxvt_get_termenv (const char* env)
2233 {
2234 if (NULL == env)
2235 return (TERMENV_XTERM);
2236 else if (0 == STRCASECMP (env, "xterm"))
2237 return (TERMENV_XTERM);
2238 else if (0 == STRCASECMP (env, "rxvt"))
2239 return (TERMENV_RXVT);
2240 else if (0 == STRCASECMP (env, "vt102"))
2241 return (TERMENV_VT102);
2242 else if (0 == STRCASECMP (env, "vt100"))
2243 return (TERMENV_VT100);
2244 else if (0 == STRCASECMP (env, "ansi"))
2245 return (TERMENV_ANSI);
2246 else if (0 == STRCASECMP (env, "dumb"))
2247 return (TERMENV_DUMB);
2248 else
2249 return (TERMENV_XTERM);
2250 }
2251
2252
2253 /* INTPROTO */
2254 void
rxvt_init_vts(rxvt_t * r,int page)2255 rxvt_init_vts (rxvt_t* r, int page)
2256 {
2257 #ifdef TTY_GID_SUPPORT
2258 struct group* gr = getgrnam("tty");
2259 #endif
2260 struct tms tp;
2261 register int i;
2262
2263
2264 assert (page < MAX_PAGES);
2265
2266 /* look for an unused term_t structure */
2267 for (i = 0; i < MAX_PAGES; i ++)
2268 if (-1 == r->vterm[i].vts_idx)
2269 break;
2270 assert (i != MAX_PAGES);
2271 DBG_MSG(1, (stderr, "Find vterm[%d] for pointer vts[%d]\n", i, page));
2272
2273 /* clear the term_t structure */
2274 r->vts[page] = &(r->vterm[i]);
2275 MEMSET (r->vts[page], 0, sizeof (r->vterm[0]));
2276 /* set vts_idx for the vterm */
2277 PVTS(r, page)->vts_idx = i;
2278
2279 #ifdef TTY_GID_SUPPORT
2280 /* change group ownership of tty to "tty" */
2281 if (gr) {
2282 PVTS(r, page)->ttymode = S_IRUSR | S_IWUSR | S_IWGRP;
2283 }
2284 else
2285 #endif /* TTY_GID_SUPPORT */
2286 {
2287 PVTS(r, page)->ttymode = S_IRUSR | S_IWUSR | S_IWGRP | S_IWOTH;
2288 }
2289
2290 /* Initialize term_t (vts) structure */
2291 /*
2292 ** How to get saveLines? Try the following sequence:
2293 ** . individual saveLines in .Xdefaults or command line option
2294 ** . saveLines for all tabs in .Xdefaults or command line option
2295 ** . Default saveLines
2296 */
2297 if (r->h->rs[Rs_saveLines+page]) {
2298 register int tmp = atoi(r->h->rs[Rs_saveLines+page]);
2299 PVTS(r, page)->saveLines = (tmp >=0 && tmp <= MAX_SAVELINES) ? tmp : DEFAULT_SAVELINES;
2300 }
2301 else if (r->h->rs[Rs_saveLinesAll]) {
2302 PVTS(r, page)->saveLines = r->TermWin.saveLines;
2303 }
2304 else
2305 PVTS(r, page)->saveLines = (SAVELINES >= 0 && SAVELINES <= MAX_SAVELINES) ? SAVELINES : DEFAULT_SAVELINES;
2306
2307 /* will be set in rxvt_create_termwin */
2308 PVTS(r, page)->vt = None;
2309 #ifdef XFT_SUPPORT
2310 PVTS(r, page)->xftvt = NULL;
2311 #endif
2312 PVTS(r, page)->tab_title = NULL;
2313 #ifdef BACKGROUND_IMAGE
2314 PVTS(r, page)->pixmap = None;
2315 PVTS(r, page)->bg.pixmap = None;
2316 PVTS(r, page)->bg.x = PVTS(r, page)->bg.y = 50;
2317 #endif
2318 PVTS(r, page)->cmd_pid = -1;
2319 PVTS(r, page)->cmd_fd = PVTS(r, page)->tty_fd = -1;
2320 #ifdef UTMP_SUPPORT
2321 PVTS(r, page)->next_utmp_action = SAVE;
2322 #endif
2323 #ifndef NO_SETOWNER_TTYDEV
2324 PVTS(r, page)->next_tty_action = SAVE;
2325 #endif
2326
2327 PVTS(r, page)->hold = 0; /* clear hold flag */
2328 PVTS(r, page)->dead = 0; /* clear dead flag */
2329 PVTS(r, page)->highlight = 0; /* clear highlight flag */
2330
2331 /* Get term_env type */
2332 PVTS(r, page)->termenv = rxvt_get_termenv (
2333 r->h->rs[Rs_term_name] ? r->h->rs[Rs_term_name] : TERMENV);
2334
2335 /* get command argv from resources */
2336 PVTS(r, page)->command_argv = rxvt_string_to_argv (
2337 (char*) r->h->rs[Rs_command+i],
2338 &(PVTS(r, page)->command_argc));
2339
2340 /* Initialize PrivateModes and SavedModes */
2341 PVTS(r, page)->PrivateModes = PVTS(r, page)->SavedModes =
2342 PrivMode_Default;
2343 if (r->Options & Opt_scrollTtyOutputInhibit)
2344 PVTS(r, page)->PrivateModes |= PrivMode_TtyOutputInh;
2345 if (r->Options & Opt_scrollTtyKeypress)
2346 PVTS(r, page)->PrivateModes |= PrivMode_Keypress;
2347 if (!(r->Options & Opt_jumpScroll))
2348 PVTS(r, page)->PrivateModes |= PrivMode_smoothScroll;
2349 #ifndef NO_BACKSPACE_KEY
2350 if (STRCMP(r->h->key_backspace, "DEC") == 0)
2351 PVTS(r, page)->PrivateModes |= PrivMode_HaveBackSpace;
2352 #endif
2353 #ifdef HAVE_SCROLLBARS
2354 if (rxvt_scrollbar_visible(r)) {
2355 PVTS(r, page)->PrivateModes |= PrivMode_scrollBar;
2356 PVTS(r, page)->SavedModes |= PrivMode_scrollBar;
2357 }
2358 #endif
2359 #ifdef HAVE_MENUBAR
2360 if (rxvt_menubar_visible(r)) {
2361 PVTS(r, page)->PrivateModes |= PrivMode_menuBar;
2362 PVTS(r, page)->SavedModes |= PrivMode_menuBar;
2363 }
2364 #endif
2365
2366 /* Now set VT fg/bg color */
2367 PVTS(r, page)->p_fg = ISSET_VTFG(r, page) ?
2368 &(VTFG(r, page)) : &(r->h->global_fg);
2369 PVTS(r, page)->p_bg = ISSET_VTBG(r, page) ?
2370 &(VTBG(r, page)) : &(r->h->global_bg);
2371 #ifdef XFT_SUPPORT
2372 PVTS(r, page)->p_xftfg = ISSET_VTFG(r, page) ?
2373 &(VTXFTFG(r, page)) : &(r->h->global_xftfg);
2374 PVTS(r, page)->p_xftbg = ISSET_VTBG(r, page) ?
2375 &(VTXFTBG(r, page)) : &(r->h->global_xftbg);
2376 #endif
2377
2378 /* Initialize input buffer */
2379 PVTS(r, page)->cmdbuf_ptr =
2380 PVTS(r, page)->cmdbuf_endp =
2381 PVTS(r, page)->cmdbuf_base;
2382
2383 /* Initialize write out buffer */
2384 PVTS(r, page)->v_buffer =
2385 PVTS(r, page)->v_bufstr =
2386 PVTS(r, page)->v_bufptr =
2387 PVTS(r, page)->v_bufend = NULL;
2388
2389 /* Initialize checksum */
2390 PVTS(r, page)->checksum = times (&tp);
2391
2392 /* Set screen structure initialization flag */
2393 PVTS(r, page)->init_screen = 0;
2394 }
2395
2396
2397 /*----------------------------------------------------------------------*/
2398 /* rxvt_destroy_termwin() - destroy a terminal window */
2399 /* EXTPROTO */
2400 void
rxvt_destroy_termwin(rxvt_t * r,int page)2401 rxvt_destroy_termwin(rxvt_t* r, int page)
2402 {
2403 assert (page < MAX_PAGES);
2404
2405 /* free command argv */
2406 if (PVTS(r, page)->command_argv && PVTS(r, page)->command_argc) {
2407 register int i;
2408 for (i = 0; i < PVTS(r, page)->command_argc; i ++)
2409 free (PVTS(r, page)->command_argv[i]);
2410 free (PVTS(r, page)->command_argv);
2411 PVTS(r, page)->command_argv = NULL;
2412 PVTS(r, page)->command_argc = 0;
2413 }
2414
2415 assert (PVTS(r, page)->tab_title);
2416 free (PVTS(r, page)->tab_title);
2417 PVTS(r, page)->tab_title = NULL;
2418
2419 #ifdef XFT_SUPPORT
2420 if (r->Options & Opt_xft) {
2421 if (PVTS(r, page)->xftvt)
2422 XftDrawDestroy (PVTS(r, page)->xftvt);
2423 PVTS(r, page)->xftvt = NULL;
2424 }
2425 #endif
2426 assert (None != PVTS(r, page)->vt);
2427 XDestroyWindow (r->Xdisplay, PVTS(r, page)->vt);
2428 PVTS(r, page)->vt = None;
2429
2430 #ifdef BACKGROUND_IMAGE
2431 if (None != PVTS(r, page)->pixmap) {
2432 XFreePixmap (r->Xdisplay, PVTS(r, page)->pixmap);
2433 PVTS(r, page)->pixmap = None;
2434 }
2435 if (None != PVTS(r, page)->bg.pixmap) {
2436 XFreePixmap (r->Xdisplay, PVTS(r, page)->bg.pixmap);
2437 PVTS(r, page)->bg.pixmap = None;
2438 }
2439 #endif
2440
2441 /* Set vterm index to -1, so that we know it's unused */
2442 PVTS(r, page)->vts_idx = -1;
2443 }
2444
2445
2446
2447 char* g_default_tab_title = "Terminal";
2448 /* rxvt_create_termwin() - create a terminal window */
2449 /* EXTPROTO */
2450 void
rxvt_create_termwin(rxvt_t * r,int page,const char TAINTED * title)2451 rxvt_create_termwin(rxvt_t* r, int page, const char TAINTED * title)
2452 {
2453 #ifdef DEBUG_X
2454 char vt_name[32];
2455 #endif
2456 long vt_emask;
2457 char TAINTED * t;
2458
2459
2460 assert (page < MAX_PAGES);
2461
2462 rxvt_init_vts (r, page);
2463
2464 /*
2465 ** How to get the tab title? Try the following steps in sequence:
2466 ** . runtime supplied tab title (e.g., escape sequence)
2467 ** . individual tab title in .Xdefaults or command line option
2468 ** . tab title for all tabs in .Xdefaults or command line option
2469 ** . default tab title
2470 */
2471 t = (char TAINTED *) title;
2472 if (NULL == t)
2473 t = (char*) r->h->rs[Rs_tabtitle+page];
2474 if (NULL == t)
2475 t = (char*) r->h->rs[Rs_tabtitleAll];
2476 if (NULL == t)
2477 t = g_default_tab_title;
2478 PVTS(r, page)->tab_title = (char UNTAINTED *) STRNDUP(t, MAX_TAB_TXT);
2479 #ifdef HAVE_PUTENV
2480 /* Set environment variable of tab title */
2481 sprintf (r->h->env_tabtitle, TABTITLEENV "%s", PVTS(r, page)->tab_title);
2482 putenv (r->h->env_tabtitle);
2483 #endif
2484
2485 PVTS(r, page)->tab_width = rxvt_tab_width (r, PVTS(r, page)->tab_title);
2486
2487 /*
2488 ** Now switch fg/bg colors before creating VT because this
2489 ** will use the fg/bg colors
2490 */
2491 rxvt_switch_fgbg_color (r, page);
2492
2493 /* create the terminal window */
2494 DBG_MSG (1, (stderr, "Create VT %d (%dx%d+%dx%d)\n", page, r->h->window_vt_x, r->h->window_vt_y, VT_WIDTH(r), VT_HEIGHT(r)));
2495 PVTS(r, page)->vt = XCreateSimpleWindow (r->Xdisplay,
2496 r->TermWin.parent,
2497 r->h->window_vt_x, r->h->window_vt_y,
2498 VT_WIDTH(r), VT_HEIGHT(r),
2499 0,
2500 r->PixColors[Color_fg],
2501 r->PixColors[Color_bg]);
2502 assert (None != PVTS(r, page)->vt);
2503 #ifdef XFT_SUPPORT
2504 if (r->Options & Opt_xft) {
2505 PVTS(r, page)->xftvt = XftDrawCreate (r->Xdisplay,
2506 PVTS(r, page)->vt, XVISUAL, XCMAP);
2507 assert (NULL != PVTS(r, page)->xftvt);
2508 }
2509 #endif
2510
2511
2512 #ifdef DEBUG_X
2513 sprintf (vt_name, "vt %d window", page);
2514 rxvt_set_win_title (r, PVTS(r, page)->vt, vt_name);
2515 #endif
2516
2517
2518 /* define cursor for the terminal window */
2519 rxvt_pointer_unblank(r, page);
2520
2521 /* define event mask fo the terminal window */
2522 vt_emask = (ExposureMask | ButtonPressMask | ButtonReleaseMask
2523 | PropertyChangeMask);
2524 #ifdef POINTER_BLANK
2525 if ((r->Options & Opt_pointerBlank))
2526 vt_emask |= PointerMotionMask;
2527 else
2528 #endif
2529 vt_emask |= (Button1MotionMask | Button3MotionMask);
2530 XSelectInput(r->Xdisplay, PVTS(r, page)->vt, vt_emask);
2531
2532 #ifdef TRANSPARENT
2533 /* Set transparent background */
2534 if (r->Options & Opt_transparent) {
2535 XSetWindowBackgroundPixmap (r->Xdisplay, PVTS(r, page)->vt,
2536 ParentRelative);
2537 }
2538 #endif
2539
2540 /*
2541 ** Load the background image for terminal window when not
2542 ** transparent
2543 */
2544 #ifdef BACKGROUND_IMAGE
2545 # ifdef TRANSPARENT
2546 if (!(r->Options & Opt_transparent))
2547 # endif
2548 if (r->h->rs[Rs_backgroundPixmap+page] ||
2549 r->h->rs[Rs_backgroundPixmapAll]) {
2550 /* Load pixmap for each individual tab */
2551 const char* pf = r->h->rs[Rs_backgroundPixmap+page];
2552 const char* p;
2553 /*
2554 ** If each individual pixmap is unset, load pixmap for all
2555 ** tabs
2556 */
2557 if (NULL == pf)
2558 pf = r->h->rs[Rs_backgroundPixmapAll];
2559
2560 p = pf;
2561 if ((p = STRCHR(p, ';')) != NULL) {
2562 p++;
2563 rxvt_scale_pixmap(r, page, p);
2564 }
2565 rxvt_load_bg_pixmap(r, page, pf);
2566 /* rxvt_scr_touch(r, page, True); */
2567 }
2568 #endif
2569
2570 XMapWindow (r->Xdisplay, PVTS(r, page)->vt);
2571 }
2572
2573
2574 /* INTPROTO */
2575 void
rxvt_set_borderless(rxvt_t * r)2576 rxvt_set_borderless (rxvt_t* r)
2577 {
2578 Atom prop;
2579 CARD32 hints; /* KDE/GNOME hints */
2580 MWMHints mwmhints; /* Motif hints */
2581
2582 hints = (CARD32) 0;
2583 mwmhints.flags = MWM_HINTS_DECORATIONS;
2584 mwmhints.decorations = MWM_DECOR_BORDER | MWM_DECOR_RESIZEH;
2585
2586 /* Motif compatible WM */
2587 prop = XInternAtom (r->Xdisplay, "_MOTIF_WM_HINTS", True);
2588 if (None != prop)
2589 XChangeProperty (r->Xdisplay, r->TermWin.parent, prop, prop,
2590 32, PropModeReplace, (unsigned char*) &mwmhints,
2591 PROP_MWM_HINTS_ELEMENTS);
2592
2593 /* GNOME compatible WM */
2594 prop = XInternAtom (r->Xdisplay, "_WIN_HINTS", True);
2595 if (None != prop)
2596 XChangeProperty (r->Xdisplay, r->TermWin.parent, prop, prop,
2597 32, PropModeReplace, (unsigned char*) &hints, 1);
2598
2599 /* KDE compatible WM */
2600 prop = XInternAtom (r->Xdisplay, "KWM_WIN_DECORATION", True);
2601 if (None != prop)
2602 XChangeProperty (r->Xdisplay, r->TermWin.parent, prop, prop,
2603 32, PropModeReplace, (unsigned char*) &hints, 1);
2604 }
2605
2606
2607 /* INTPROTO */
2608 void
rxvt_set_desktop(rxvt_t * r,CARD32 desktop)2609 rxvt_set_desktop (rxvt_t* r, CARD32 desktop)
2610 {
2611 /* GNOME compatible WM */
2612 if (desktop >= 0 && desktop <= 64 &&
2613 None != r->h->xa[XA_WIN_WORKSPACE])
2614 XChangeProperty(r->Xdisplay, r->TermWin.parent,
2615 r->h->xa[XA_WIN_WORKSPACE], XA_CARDINAL, 32,
2616 PropModeReplace, (unsigned char*) &desktop, 1L);
2617
2618 /* WindowMaker/FreeDesktop.org compatible WM */
2619 if (desktop >= 0 && desktop <= 64 &&
2620 None != r->h->xa[XA_NET_WM_DESKTOP])
2621 XChangeProperty(r->Xdisplay, r->TermWin.parent,
2622 r->h->xa[XA_NET_WM_DESKTOP], XA_CARDINAL, 32,
2623 PropModeReplace, (unsigned char*) &desktop, 1L);
2624 }
2625
2626
2627 /* EXTPROTO */
2628 CARD32
rxvt_get_desktop(rxvt_t * r)2629 rxvt_get_desktop (rxvt_t* r)
2630 {
2631 int result;
2632 Atom ret_type;
2633 int format;
2634 unsigned long nitems;
2635 unsigned long bytes_after;
2636 long* cardinals;
2637 CARD32 desktop;
2638
2639 if (None == r->h->xa[XA_NET_WM_DESKTOP])
2640 return 0;
2641
2642 result = XGetWindowProperty (r->Xdisplay, r->TermWin.parent,
2643 r->h->xa[XA_NET_WM_DESKTOP], 0L, LONG_MAX, False,
2644 XA_CARDINAL, &ret_type, &format, &nitems,
2645 &bytes_after, (unsigned char**) &cardinals);
2646 if (Success != result)
2647 return 0;
2648 if (XA_CARDINAL != ret_type || 0 == format)
2649 return 0;
2650
2651 desktop = (CARD32) cardinals[0];
2652 if (desktop < 0 || desktop > 64)
2653 desktop = 0;
2654
2655 XFree (cardinals);
2656 return desktop;
2657 }
2658
2659
2660 /*----------------------------------------------------------------------*/
2661 /* rxvt_create_show_windows() - Open and map the window */
2662 /* EXTPROTO */
2663 void
rxvt_create_show_windows(rxvt_t * r,int argc,const char * const * argv)2664 rxvt_create_show_windows(rxvt_t* r, int argc, const char *const *argv)
2665 {
2666 XClassHint class_hint;
2667 XWMHints wm_hint;
2668 XTextProperty win_prop;
2669 XTextProperty icon_prop;
2670 XGCValues gcvalue;
2671 unsigned long gcmask;
2672 #ifndef NO_FRILLS
2673 CARD32 pid = (CARD32) getpid ();
2674 #endif
2675 #ifdef TRANSPARENT
2676 register int i;
2677 #endif
2678 #ifdef POINTER_BLANK
2679 static const XColor blackcolour = { 0, 0, 0, 0, 0, 0 };
2680 #endif
2681
2682 #ifdef PREFER_24BIT
2683 XSetWindowAttributes attributes;
2684 XWindowAttributes gattr;
2685
2686
2687 XCMAP = DefaultColormap(r->Xdisplay, XSCREEN);
2688 XVISUAL = DefaultVisual(r->Xdisplay, XSCREEN);
2689
2690 if (r->Options & Opt_transparent) {
2691 XGetWindowAttributes(r->Xdisplay,
2692 RootWindow(r->Xdisplay, XSCREEN), &gattr);
2693 XDEPTH = gattr.depth;
2694 }
2695 else {
2696 XDEPTH = DefaultDepth(r->Xdisplay, XSCREEN);
2697 /*
2698 ** If depth is not 24, look for a 24bit visual.
2699 */
2700 if (XDEPTH != 24) {
2701 XVisualInfo vinfo;
2702
2703 if (XMatchVisualInfo(r->Xdisplay, XSCREEN, 24, TrueColor,
2704 &vinfo)) {
2705 XDEPTH = 24;
2706 XVISUAL = vinfo.visual;
2707 XCMAP = XCreateColormap(r->Xdisplay,
2708 RootWindow(r->Xdisplay, XSCREEN),
2709 XVISUAL, AllocNone);
2710 }
2711 }
2712 }
2713 #endif
2714
2715
2716 /* grab colors before netscape does */
2717 rxvt_init_colors (r);
2718
2719 /*
2720 ** Initialize fonts.
2721 ** . Always load X11 fonts since pointer_blank uses it
2722 ** . Load XFT font after X11 fonts. If succeeds, XFT font will
2723 ** update font width/height and be used by default
2724 */
2725 #ifdef XFT_SUPPORT
2726 if (r->Options & Opt_xft) {
2727 if (!rxvt_init_font_xft (r)) {
2728 DBG_MSG (1, (stderr, "Failed to load FreeType font, fallback to X11 font\n"));
2729 /* disable xft */
2730 r->Options &= ~Opt_xft;
2731 }
2732 }
2733 #endif
2734 /* init fallback X11 font */
2735 rxvt_init_font_x11 (r);
2736
2737
2738 /*
2739 ** must initialize scrollbar before initialize window size and
2740 ** create windows.
2741 */
2742 #ifdef HAVE_SCROLLBARS
2743 rxvt_scrollbar_init (r);
2744 #endif
2745 rxvt_init_win_size (r);
2746
2747 /*
2748 ** parent window - reverse video so we can see placement errors
2749 ** sub-window placement & size in rxvt_resize_subwindows()
2750 */
2751
2752 #ifdef PREFER_24BIT
2753 attributes.background_pixel = r->PixColors[Color_bg];
2754 attributes.border_pixel = r->PixColors[Color_border];
2755 attributes.colormap = XCMAP;
2756 r->TermWin.parent = XCreateWindow(r->Xdisplay, XROOT,
2757 r->szHint.x, r->szHint.y,
2758 r->szHint.width, r->szHint.height,
2759 r->TermWin.ext_bwidth,
2760 XDEPTH, InputOutput,
2761 XVISUAL,
2762 CWBackPixel | CWBorderPixel
2763 | CWColormap, &attributes);
2764 #else
2765 r->TermWin.parent = XCreateSimpleWindow(r->Xdisplay, XROOT,
2766 r->szHint.x, r->szHint.y,
2767 r->szHint.width,
2768 r->szHint.height,
2769 r->TermWin.ext_bwidth,
2770 r->PixColors[Color_border],
2771 r->PixColors[Color_bg]);
2772 #endif
2773 assert (None != r->TermWin.parent);
2774
2775
2776 #ifdef XFT_SUPPORT
2777 if (r->Options & Opt_xft) {
2778 /* create XFT draw, test only */
2779 XftDraw* xftdraw = XftDrawCreate (r->Xdisplay,
2780 r->TermWin.parent, XVISUAL, XCMAP);
2781 if (xftdraw) {
2782 XftDrawDestroy (xftdraw);
2783 /* some cleanup work if successfully create xft window */
2784 # ifdef POINTER_BLANK
2785 /* disable pointer blank */
2786 r->Options &= ~Opt_pointerBlank;
2787 # endif
2788 }
2789 }
2790 #endif
2791
2792
2793 # ifdef HAVE_X11_SM_SMLIB_H
2794 if (r->Options2 & Opt2_enableSessionMgt)
2795 rxvt_session_init (r);
2796 # endif
2797
2798
2799 /*
2800 ** Now set window properties, like title, icon name and hints
2801 */
2802 /* window title name */
2803 win_prop.value = (unsigned char*) r->h->rs[Rs_title];
2804 win_prop.nitems = STRLEN (win_prop.value);
2805 win_prop.encoding = XA_STRING;
2806 win_prop.format = 8;
2807 /* icon name */
2808 icon_prop.value = (unsigned char*) r->h->rs[Rs_iconName];
2809 icon_prop.nitems = STRLEN (icon_prop.value);
2810 icon_prop.encoding = XA_STRING;
2811 icon_prop.format = 8;
2812 /* window manager hints */
2813 wm_hint.flags = (InputHint | StateHint | WindowGroupHint);
2814 wm_hint.input = True;
2815 wm_hint.initial_state = (r->Options & Opt_iconic ? IconicState
2816 : NormalState);
2817 wm_hint.window_group = r->TermWin.parent;
2818 /* class hints */
2819 class_hint.res_name = (char*) r->h->rs[Rs_name];
2820 class_hint.res_class = (char*) APL_CLASS;
2821 XSetWMProperties (r->Xdisplay, r->TermWin.parent,
2822 &win_prop, &icon_prop, (char**)argv, argc,
2823 &r->szHint, &wm_hint, &class_hint);
2824
2825 /* set terminal title */
2826 rxvt_set_term_title (r, win_prop.value);
2827 /* set icon title */
2828 rxvt_set_icon_name (r, icon_prop.value);
2829 /* command line */
2830 XSetCommand (r->Xdisplay, r->TermWin.parent, (char**) argv, argc);
2831
2832 /* override redirect */
2833 if (r->Options2 & Opt2_overrideRedirect) {
2834 XSetWindowAttributes attrib;
2835 attrib.override_redirect = True;
2836 XChangeWindowAttributes(r->Xdisplay, r->TermWin.parent,
2837 CWOverrideRedirect, &attrib);
2838 }
2839
2840 #ifndef NO_FRILLS
2841 XChangeProperty (r->Xdisplay, r->TermWin.parent,
2842 r->h->xa[XA_NET_WM_PID], XA_CARDINAL, 32,
2843 PropModeReplace, (unsigned char*) &pid, 1);
2844 #endif
2845
2846 if (r->Options2 & Opt2_borderLess) {
2847 rxvt_set_borderless (r);
2848 }
2849 if (r->h->rs[Rs_desktop]) {
2850 CARD32 desktop = (CARD32) atoi (r->h->rs[Rs_desktop]);
2851 rxvt_set_desktop (r, desktop);
2852 }
2853
2854 /*
2855 ** set WM_CLIENT_LEADER property so that session management proxy
2856 ** can handle us even session management is not enabled.
2857 */
2858 if (None != r->h->xa[XA_WM_CLIENT_LEADER])
2859 XChangeProperty(r->Xdisplay, r->TermWin.parent,
2860 r->h->xa[XA_WM_CLIENT_LEADER], XA_WINDOW, 32,
2861 PropModeReplace, (unsigned char*) &(r->TermWin.parent), 1L);
2862
2863 # ifdef HAVE_X11_SM_SMLIB_H
2864 if (NULL != r->TermWin.sm_conn &&
2865 NULL != r->TermWin.sm_client_id &&
2866 STRCMP (r->TermWin.sm_client_id, "")) {
2867 if (None != r->h->xa[XA_SM_CLIENT_ID])
2868 XChangeProperty(r->Xdisplay, r->TermWin.parent,
2869 r->h->xa[XA_SM_CLIENT_ID], XA_STRING, 8,
2870 PropModeReplace,
2871 (unsigned char*) r->TermWin.sm_client_id,
2872 STRLEN(r->TermWin.sm_client_id));
2873 }
2874 # endif /* HAVE_X11_SM_SMLIB_H */
2875
2876
2877 #ifdef TRANSPARENT
2878 r->TermWin.pixmap = None; /* Initialize it to None */
2879 r->TermWin.parenttree[0] = r->TermWin.parent;
2880 for (i = 1; i < PARENT_NUMBER; i ++)
2881 r->TermWin.parenttree[i] = None;
2882
2883 if (r->Options & Opt_transparent) {
2884 XSetWindowBackgroundPixmap (r->Xdisplay, r->TermWin.parent,
2885 ParentRelative);
2886 }
2887 #endif /* TRANSPARENT */
2888
2889
2890 XSelectInput(r->Xdisplay, r->TermWin.parent,
2891 (KeyPressMask
2892 #if defined(MOUSE_WHEEL) && defined(MOUSE_SLIP_WHEELING)
2893 | KeyReleaseMask
2894 #endif
2895 | FocusChangeMask
2896 #ifdef MONITOR_ENTER_LEAVE
2897 | EnterWindowMask | LeaveWindowMask
2898 #endif
2899 | VisibilityChangeMask
2900 | StructureNotifyMask));
2901
2902
2903 /*
2904 ** vt cursor: Black-on-White is standard, but this is more
2905 ** popular
2906 */
2907 r->term_pointer = XCreateFontCursor(r->Xdisplay, XC_xterm);
2908 /* scrollbar/menubar/tabbar window pointer */
2909 r->h->bar_pointer = XCreateFontCursor(r->Xdisplay, XC_left_ptr);
2910
2911 #ifdef POINTER_BLANK
2912 if (!(r->Options & Opt_pointerBlank))
2913 r->h->blank_pointer = None;
2914 else
2915 r->h->blank_pointer = XCreateGlyphCursor(r->Xdisplay,
2916 r->TermWin.font->fid, r->TermWin.font->fid, ' ', ' ',
2917 (XColor*) &blackcolour, (XColor*) &blackcolour);
2918 #endif
2919
2920
2921 /* graphics context for the vt window */
2922 #ifdef XFT_SUPPORT
2923 if (!(r->Options & Opt_xft))
2924 #endif
2925 gcvalue.font = r->TermWin.font->fid;
2926 gcvalue.foreground = r->PixColors[Color_fg];
2927 gcvalue.background = r->PixColors[Color_bg];
2928 gcvalue.graphics_exposures = 1;
2929 gcmask = GCForeground | GCBackground | GCGraphicsExposures;
2930 #ifdef XFT_SUPPORT
2931 if (!(r->Options & Opt_xft))
2932 #endif
2933 gcmask |= GCFont;
2934 r->TermWin.gc = XCreateGC(r->Xdisplay, r->TermWin.parent,
2935 gcmask, &gcvalue);
2936
2937 #ifdef HAVE_SCROLLBARS
2938 rxvt_scrollbar_create (r);
2939 if (r->Options & Opt_scrollBar) {
2940 rxvt_scrollbar_show (r);
2941 }
2942 #endif
2943 #ifdef HAVE_MENUBAR
2944 rxvt_menubar_create (r);
2945 # if (MENUBAR_MAX)
2946 if (r->Options & Opt_showMenu)
2947 rxvt_menubar_show (r);
2948 if (r->h->rs[Rs_menu]) {
2949 rxvt_menubar_load_file (r, r->h->rs[Rs_menu]);
2950 }
2951 # endif
2952 #endif
2953 rxvt_tabbar_create (r);
2954 if (!(r->Options2 & Opt2_hideTabbar))
2955 rxvt_tabbar_show (r);
2956
2957 XMapWindow (r->Xdisplay, r->TermWin.parent);
2958 }
2959
2960 /*----------------------------------------------------------------------*/
2961 /*
2962 * Run the command in a subprocess and return a file descriptor for the
2963 * master end of the pseudo-teletype pair with the command talking to
2964 * the slave.
2965 */
2966 /* EXTPROTO */
2967 int
rxvt_run_command(rxvt_t * r,int page,const char ** argv)2968 rxvt_run_command(rxvt_t* r, int page, const char** argv)
2969 {
2970 int cfd, er;
2971 int i;
2972
2973 /* get master (pty) */
2974 if ((cfd = rxvt_get_pty(&(PVTS(r, page)->tty_fd),
2975 (char**) &(PVTS(r, page)->ttydev))) < 0) {
2976 rxvt_print_error("can't open pseudo-tty");
2977 return -1;
2978 }
2979 #ifdef FD_SETSIZE
2980 if (r->Xfd > FD_SETSIZE || cfd > FD_SETSIZE) {
2981 rxvt_print_error("fd too high: %d max", FD_SETSIZE);
2982 return -1;
2983 }
2984 #endif
2985 fcntl(cfd, F_SETFL, O_NDELAY);
2986
2987 /* get slave (tty) */
2988 if (PVTS(r, page)->tty_fd < 0) {
2989 #if !defined(NO_SETOWNER_TTYDEV) && !defined(OS_CYGWIN)
2990 rxvt_privileged_ttydev(r, page, SAVE);
2991 #endif
2992 if ((PVTS(r, page)->tty_fd = rxvt_get_tty(PVTS(r, page)->ttydev)) < 0) {
2993 close(cfd);
2994 rxvt_print_error("can't open slave tty %s", PVTS(r, page)->ttydev);
2995 return -1;
2996 }
2997 }
2998
2999 /* Get tty mode before fork */
3000 #ifndef NO_BACKSPACE_KEY
3001 if (r->h->key_backspace[0] && !r->h->key_backspace[1])
3002 er = r->h->key_backspace[0];
3003 else if (STRCMP(r->h->key_backspace, "DEC") == 0)
3004 er = '\177'; /* the initial state anyway */
3005 else
3006 #endif
3007 er = -1;
3008 rxvt_get_ttymode(&(PVTS(r, page)->tio), er);
3009
3010
3011 DBG_MSG(1,(stderr, "argv = 0x%x\n", (unsigned int) argv));
3012 #ifndef __QNX__
3013 /* spin off the command interpreter */
3014 switch (PVTS(r, page)->cmd_pid = fork()) {
3015 case -1:
3016 rxvt_print_error("can't fork");
3017 return -1;
3018 case 0:
3019 /*
3020 ** To debug the child, follow these steps:
3021 ** . enable sleep in the following
3022 ** . launch gdb, set breakpoint before fork
3023 ** . run the program, step over fork, then get child pid
3024 ** . launch another gdb, attach to child process via pid
3025 ** . in child's gdb, set breakpoint after sleep
3026 ** . run 'continue' in child's gdb, debug child process
3027 */
3028 /* sleep(10); */
3029 /*
3030 ** Close all file descriptors except PVTS(r, page)->tty_fd
3031 ** and STDERR
3032 */
3033 for (i = STDERR_FILENO + 1; i < r->num_fds; i ++)
3034 if (i != PVTS(r, page)->tty_fd)
3035 close (i);
3036
3037 if (rxvt_control_tty(PVTS(r, page)->tty_fd, PVTS(r, page)->ttydev) < 0)
3038 rxvt_print_error("could not obtain control of tty");
3039 else {
3040 /* Reopen stdin, stdout and stderr over the tty file descriptor */
3041 dup2(PVTS(r, page)->tty_fd, STDIN_FILENO);
3042 dup2(PVTS(r, page)->tty_fd, STDOUT_FILENO);
3043 dup2(PVTS(r, page)->tty_fd, STDERR_FILENO);
3044 if (PVTS(r, page)->tty_fd > 2)
3045 close(PVTS(r, page)->tty_fd);
3046 rxvt_run_child(r, page, argv);
3047 }
3048 return -1;
3049 /* exit(EXIT_FAILURE); */
3050 /* NOTREACHED */
3051 default:
3052 {
3053 #if defined(HAVE_STRUCT_UTMP) && defined(HAVE_TTYSLOT)
3054 int fdstdin;
3055
3056 fdstdin = dup(STDIN_FILENO);
3057 dup2(PVTS(r, page)->tty_fd, STDIN_FILENO);
3058 #endif
3059 #ifdef UTMP_SUPPORT
3060 # ifdef UTEMPTER_SUPPORT
3061 /* utempter hack, it needs cmd_fd */
3062 PVTS(r, page)->cmd_fd = cfd;
3063 # endif
3064 rxvt_privileged_utmp(r, page, SAVE);
3065 # ifdef UTEMPTER_SUPPORT
3066 /* utempter hack, restore cmd_fd */
3067 PVTS(r, page)->cmd_fd = -1;
3068 # endif
3069 #endif
3070 #if defined(HAVE_STRUCT_UTMP) && defined(HAVE_TTYSLOT)
3071 dup2(fdstdin, STDIN_FILENO);
3072 close(fdstdin);
3073 #endif
3074 }
3075 /* keep STDERR_FILENO, PVTS(r, page)->cmd_fd, r->Xfd open */
3076 close(PVTS(r, page)->tty_fd);
3077 PVTS(r, page)->tty_fd = -1;
3078 break;
3079 }
3080 #else /* __QNX__ uses qnxspawn() */
3081 fchmod(PVTS(r, page)->tty_fd, 0622);
3082 fcntl(PVTS(r, page)->tty_fd, F_SETFD, FD_CLOEXEC);
3083 fcntl(cfd, F_SETFD, FD_CLOEXEC);
3084
3085 if (rxvt_run_child(r, page, argv) == -1)
3086 /*exit(EXIT_FAILURE);*/
3087 return -1;
3088 #endif
3089
3090 return cfd;
3091 }
3092
3093 /* ------------------------------------------------------------------------- *
3094 * CHILD PROCESS OPERATIONS *
3095 * ------------------------------------------------------------------------- */
3096 /*
3097 * The only open file descriptor is the slave tty - so no error messages.
3098 * returns are fatal
3099 */
3100 /* INTPROTO */
3101 int
rxvt_run_child(rxvt_t * r,int page,const char ** argv)3102 rxvt_run_child(rxvt_t* r, int page, const char **argv)
3103 {
3104 #ifdef SIGTSTP
3105 struct sigaction ignore;
3106 #endif
3107 struct sigaction deflt;
3108 char* login;
3109
3110
3111 /* DBG_MSG(1,(stderr, "argv = %x\n", argv)); */
3112
3113 /* init terminal attributes */
3114 SET_TTYMODE(STDIN_FILENO, &(PVTS(r, page)->tio));
3115
3116 if (r->Options & Opt_console) { /* be virtual console, fail silently */
3117 #ifdef TIOCCONS
3118 unsigned int on = 1;
3119 ioctl(STDIN_FILENO, TIOCCONS, &on);
3120 #elif defined (SRIOCSREDIR)
3121 int fd;
3122 fd = open(CONSOLE, O_WRONLY, 0);
3123 if (fd >= 0) {
3124 if (ioctl(fd, SRIOCSREDIR, NULL) < 0)
3125 close(fd);
3126 }
3127 #endif /* SRIOCSREDIR */
3128 }
3129
3130 /* reset signals and spin off the command interpreter */
3131 deflt.sa_handler = SIG_DFL;
3132 deflt.sa_flags = 0;
3133 sigemptyset (&deflt.sa_mask);
3134 sigaction (SIGINT, &deflt, NULL);
3135 sigaction (SIGQUIT, &deflt, NULL);
3136 sigaction (SIGCHLD, &deflt, NULL);
3137 /*
3138 signal(SIGINT, SIG_DFL);
3139 signal(SIGQUIT, SIG_DFL);
3140 signal(SIGCHLD, SIG_DFL);
3141 */
3142
3143 /*
3144 ** mimick login's behavior by disabling the job control signals
3145 ** a shell that wants them can turn them back on
3146 */
3147 #ifdef SIGTSTP
3148 ignore.sa_handler = SIG_IGN;
3149 ignore.sa_flags = 0;
3150 sigemptyset (&ignore.sa_mask);
3151 sigaction (SIGTSTP, &ignore, NULL);
3152 sigaction (SIGTTIN, &ignore, NULL);
3153 sigaction (SIGTTOU, &ignore, NULL);
3154 /*
3155 signal(SIGTSTP, SIG_IGN);
3156 signal(SIGTTIN, SIG_IGN);
3157 signal(SIGTTOU, SIG_IGN);
3158 */
3159 #endif /* SIGTSTP */
3160
3161 /* set window size */
3162 rxvt_tt_winsize(STDIN_FILENO, r->TermWin.ncol, r->TermWin.nrow, 0);
3163
3164 #ifndef __QNX__
3165 /* command interpreter path */
3166 if (argv != NULL) {
3167 # ifdef DEBUG_VERBOSE
3168 int i;
3169 for (i = 0; argv[i]; i++)
3170 DBG_MSG(2,(stderr, "argv [%d] = \"%s\"\n", i, argv[i]));
3171 # endif
3172 execvp(argv[0], (char *const *)argv);
3173 /* no error message: STDERR is closed! */
3174 }
3175 else {
3176 const char *argv0, *shell;
3177
3178 if (NULL == (shell = getenv("SHELL")) ||
3179 ((char) 0 == *shell)) {
3180 # ifdef HAVE_GETPWUID
3181 struct passwd* pwent = getpwuid (getuid ());
3182 if ((NULL == pwent) ||
3183 (NULL == (shell = pwent->pw_shell)) ||
3184 ((char) 0 == *shell))
3185 # endif /* HAVE_GETPWUID */
3186 shell = "/bin/sh";
3187 }
3188
3189 argv0 = (const char *)rxvt_r_basename(shell);
3190 if (r->Options & Opt_loginShell) {
3191 int l = STRLEN(argv0) + 2;
3192 if (l <= 0 || l > 4096) /* possible integer overflow */
3193 l = 4096;
3194 login = rxvt_malloc(l * sizeof(char));
3195
3196 login[0] = '-';
3197 STRNCPY(&login[1], argv0, l-2);
3198 login[l-1] = (char) 0;
3199 argv0 = login;
3200 }
3201 execlp(shell, argv0, NULL);
3202 /* no error message: STDERR is closed! */
3203 }
3204 #else /* __QNX__ uses qnxspawn() */
3205 {
3206 char iov_a[10] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 };
3207 char* command = NULL, fullcommand[_MAX_PATH];
3208 char** arg_v, *arg_a[2] = { NULL, NULL };
3209
3210 if (argv != NULL) {
3211 if (access(argv[0], X_OK) == -1) {
3212 if (STRCHR(argv[0], '/') == NULL) {
3213 searchenv(argv[0], "PATH", fullcommand);
3214 if (fullcommand[0] != '\0')
3215 command = fullcommand;
3216 }
3217 if (access(command, X_OK) == -1)
3218 return -1;
3219 }
3220 else
3221 command = argv[0];
3222 arg_v = argv;
3223 }
3224 else {
3225 if ((command = getenv("SHELL")) == NULL || *command == '\0')
3226 command = "/bin/sh";
3227
3228 arg_a[0] = my_basename(command);
3229 if (r->Options & Opt_loginShell) {
3230 int l = STRLEN(arg_a[0]) + 2;
3231 if (l <= 0 || l > 4096) /* possible integer overflow */
3232 l = 4096;
3233 login = rxvt_malloc(l * sizeof(char));
3234
3235 login[0] = '-';
3236 STRNCPY(&login[1], arg_a[0], l-2);
3237 login[l-1] = (char) 0;
3238 arg_a[0] = login;
3239 }
3240 arg_v = arg_a;
3241 }
3242 iov_a[0] = iov_a[1] = iov_a[2] = PVTS(r, page)->tty_fd;
3243 PVTS(r, page)->cmd_pid = qnx_spawn(0, 0, 0, -1, -1,
3244 _SPAWN_SETSID | _SPAWN_TCSETPGRP,
3245 command, arg_v, environ, iov_a, 0);
3246 if (login)
3247 free(login);
3248 close(PVTS(r, page)->tty_fd);
3249 return PVTS(r, page)->cmd_fd;
3250 }
3251 #endif
3252 return -1;
3253 }
3254
3255 /* ------------------------------------------------------------------------- *
3256 * GET TTY CURRENT STATE *
3257 * ------------------------------------------------------------------------- */
3258 /* rxvt_get_ttymode() */
3259 /* INTPROTO */
3260 void
rxvt_get_ttymode(ttymode_t * tio,int erase)3261 rxvt_get_ttymode(ttymode_t *tio, int erase)
3262 {
3263 #ifdef HAVE_TERMIOS_H
3264 /*
3265 * standard System V termios interface
3266 */
3267 if (GET_TERMIOS(STDIN_FILENO, tio) < 0) {
3268 /* return error - use system defaults */
3269 tio->c_cc[VINTR] = CINTR;
3270 tio->c_cc[VQUIT] = CQUIT;
3271 tio->c_cc[VERASE] = CERASE;
3272 tio->c_cc[VKILL] = CKILL;
3273 tio->c_cc[VSTART] = CSTART;
3274 tio->c_cc[VSTOP] = CSTOP;
3275 tio->c_cc[VSUSP] = CSUSP;
3276 # ifdef VDSUSP
3277 tio->c_cc[VDSUSP] = CDSUSP;
3278 # endif
3279 # ifdef VREPRINT
3280 tio->c_cc[VREPRINT] = CRPRNT;
3281 # endif
3282 # ifdef VDISCRD
3283 tio->c_cc[VDISCRD] = CFLUSH;
3284 # endif
3285 # ifdef VWERSE
3286 tio->c_cc[VWERSE] = CWERASE;
3287 # endif
3288 # ifdef VLNEXT
3289 tio->c_cc[VLNEXT] = CLNEXT;
3290 # endif
3291 }
3292 tio->c_cc[VEOF] = CEOF;
3293 tio->c_cc[VEOL] = VDISABLE;
3294 # ifdef VEOL2
3295 tio->c_cc[VEOL2] = VDISABLE;
3296 # endif
3297 # ifdef VSWTC
3298 tio->c_cc[VSWTC] = VDISABLE;
3299 # endif
3300 # ifdef VSWTCH
3301 tio->c_cc[VSWTCH] = VDISABLE;
3302 # endif
3303 # if VMIN != VEOF
3304 tio->c_cc[VMIN] = 1;
3305 # endif
3306 # if VTIME != VEOL
3307 tio->c_cc[VTIME] = 0;
3308 # endif
3309 if (erase != -1)
3310 tio->c_cc[VERASE] = (char)erase;
3311
3312 /* input modes */
3313 tio->c_iflag = (BRKINT | IGNPAR | ICRNL
3314 # ifdef IMAXBEL
3315 | IMAXBEL
3316 # endif
3317 | IXON);
3318
3319 /* output modes */
3320 tio->c_oflag = (OPOST | ONLCR);
3321
3322 /* control modes */
3323 tio->c_cflag = (CS8 | CREAD);
3324
3325 /* line discipline modes */
3326 tio->c_lflag = (ISIG | ICANON | IEXTEN | ECHO
3327 # if defined (ECHOCTL) && defined (ECHOKE)
3328 | ECHOCTL | ECHOKE
3329 # endif
3330 | ECHOE | ECHOK);
3331 # else /* HAVE_TERMIOS_H */
3332
3333 /*
3334 * sgtty interface
3335 */
3336
3337 /* get parameters -- gtty */
3338 if (ioctl(STDIN_FILENO, TIOCGETP, &(tio->sg)) < 0) {
3339 tio->sg.sg_erase = CERASE; /* ^H */
3340 tio->sg.sg_kill = CKILL; /* ^U */
3341 }
3342 if (erase != -1)
3343 tio->sg.sg_erase = (char)erase;
3344
3345 tio->sg.sg_flags = (CRMOD | ECHO | EVENP | ODDP);
3346
3347 /* get special characters */
3348 if (ioctl(STDIN_FILENO, TIOCGETC, &(tio->tc)) < 0) {
3349 tio->tc.t_intrc = CINTR; /* ^C */
3350 tio->tc.t_quitc = CQUIT; /* ^\ */
3351 tio->tc.t_startc = CSTART; /* ^Q */
3352 tio->tc.t_stopc = CSTOP; /* ^S */
3353 tio->tc.t_eofc = CEOF; /* ^D */
3354 tio->tc.t_brkc = -1;
3355 }
3356 /* get local special chars */
3357 if (ioctl(STDIN_FILENO, TIOCGLTC, &(tio->lc)) < 0) {
3358 tio->lc.t_suspc = CSUSP; /* ^Z */
3359 tio->lc.t_dsuspc = CDSUSP; /* ^Y */
3360 tio->lc.t_rprntc = CRPRNT; /* ^R */
3361 tio->lc.t_flushc = CFLUSH; /* ^O */
3362 tio->lc.t_werasc = CWERASE; /* ^W */
3363 tio->lc.t_lnextc = CLNEXT; /* ^V */
3364 }
3365 /* get line discipline */
3366 ioctl(STDIN_FILENO, TIOCGETD, &(tio->line));
3367 # ifdef NTTYDISC
3368 tio->line = NTTYDISC;
3369 # endif /* NTTYDISC */
3370 tio->local = (LCRTBS | LCRTERA | LCTLECH | LPASS8 | LCRTKIL);
3371 #endif /* HAVE_TERMIOS_H */
3372
3373 /*
3374 * Debugging
3375 */
3376 #ifdef DEBUG_TTYMODE
3377 #ifdef HAVE_TERMIOS_H
3378 /* c_iflag bits */
3379 fprintf(stderr, "Input flags\n");
3380
3381 /* cpp token stringize doesn't work on all machines <sigh> */
3382 # define FOO(flag,name) \
3383 if ((tio->c_iflag) & flag) \
3384 fprintf (stderr, "%s ", name)
3385
3386 /* c_iflag bits */
3387 FOO(IGNBRK, "IGNBRK");
3388 FOO(BRKINT, "BRKINT");
3389 FOO(IGNPAR, "IGNPAR");
3390 FOO(PARMRK, "PARMRK");
3391 FOO(INPCK, "INPCK");
3392 FOO(ISTRIP, "ISTRIP");
3393 FOO(INLCR, "INLCR");
3394 FOO(IGNCR, "IGNCR");
3395 FOO(ICRNL, "ICRNL");
3396 FOO(IXON, "IXON");
3397 FOO(IXOFF, "IXOFF");
3398 # ifdef IUCLC
3399 FOO(IUCLC, "IUCLC");
3400 # endif
3401 # ifdef IXANY
3402 FOO(IXANY, "IXANY");
3403 # endif
3404 # ifdef IMAXBEL
3405 FOO(IMAXBEL, "IMAXBEL");
3406 # endif
3407 fprintf(stderr, "\n");
3408
3409 # undef FOO
3410 # define FOO(entry, name) \
3411 fprintf(stderr, "%-8s = %#04o\n", name, tio->c_cc [entry])
3412
3413 FOO(VINTR, "VINTR");
3414 FOO(VQUIT, "VQUIT");
3415 FOO(VERASE, "VERASE");
3416 FOO(VKILL, "VKILL");
3417 FOO(VEOF, "VEOF");
3418 FOO(VEOL, "VEOL");
3419 # ifdef VEOL2
3420 FOO(VEOL2, "VEOL2");
3421 # endif
3422 # ifdef VSWTC
3423 FOO(VSWTC, "VSWTC");
3424 # endif
3425 # ifdef VSWTCH
3426 FOO(VSWTCH, "VSWTCH");
3427 # endif
3428 FOO(VSTART, "VSTART");
3429 FOO(VSTOP, "VSTOP");
3430 FOO(VSUSP, "VSUSP");
3431 # ifdef VDSUSP
3432 FOO(VDSUSP, "VDSUSP");
3433 # endif
3434 # ifdef VREPRINT
3435 FOO(VREPRINT, "VREPRINT");
3436 # endif
3437 # ifdef VDISCRD
3438 FOO(VDISCRD, "VDISCRD");
3439 # endif
3440 # ifdef VWERSE
3441 FOO(VWERSE, "VWERSE");
3442 # endif
3443 # ifdef VLNEXT
3444 FOO(VLNEXT, "VLNEXT");
3445 # endif
3446 fprintf(stderr, "\n");
3447 # undef FOO
3448 # endif /* HAVE_TERMIOS_H */
3449 #endif /* DEBUG_TTYMODE */
3450 }
3451
3452 /*----------------------- end-of-file (C source) -----------------------*/
3453