|
|
1.1 root 1: /*
2: * $Source: /u1/X/xterm/RCS/misc.c,v $
3: * $Header: misc.c,v 10.101 86/12/02 08:49:20 swick Exp $
4: */
5:
6: #include <stdio.h>
7: #include <setjmp.h>
8: #include <signal.h>
9: #include <ctype.h>
10: #include <pwd.h>
11: #include <sys/time.h>
12: #include <sys/file.h>
13: #include <X/Xlib.h>
14: #include "scrollbar.h"
15: #include "ptyx.h"
16: #include "data.h"
17: #include "error.h"
18: #include "gray.ic"
19: #include "hilite.ic"
20: #include "icon.ic"
21: #include "tek_icon.ic"
22: #include "wait.ic"
23: #include "waitmask.ic"
24: #include "../cursors/left_ptr.cursor"
25: #include "../cursors/left_ptr_mask.cursor"
26: #include "../cursors/tcross.cursor"
27: #include "../cursors/tcross_mask.cursor"
28: #include "../cursors/xterm.cursor"
29: #include "../cursors/xterm_mask.cursor"
30:
31: #ifndef lint
32: static char csrg_id[] = "@(#)misc.c 1.8\t(Berkeley/CSRG)\t9/18/87";
33: static char sccs_id[] = "@(#)misc.c\tX10/6.6B\t1/9/87";
34: #endif lint
35:
36: xevents()
37: {
38: XEvent reply;
39: register XEvent *rep = & reply;
40: register Screen *screen = &term.screen;
41:
42: if(screen->scroll_amt)
43: FlushScroll(screen);
44: XPending ();
45: do {
46: XNextEvent (&reply);
47: xeventpass(&reply);
48: } while (QLength() > 0);
49: }
50:
51: xeventpass(rep)
52: register XEvent *rep;
53: {
54: register Screen *screen = &term.screen;
55: register Window window = rep->window;
56: register Window w;
57: register int i;
58:
59: switch ((int)rep->type) {
60: case KeyPressed:
61: Input (&term.keyboard, &term.screen,
62: (XKeyPressedEvent *)rep);
63: break;
64:
65: case ExposeWindow:
66: if(screen->sb && window == screen->sb->bar) {
67: #ifdef DEBUG
68: if(debug)
69: fputs("ExposeWindow scrollbar\n", stderr);
70: #endif DEBUG
71: if(((XExposeEvent *)rep)->subwindow ==
72: screen->sb->button) {
73: screen->sb->buttonstate = -1;
74: DrawButton(screen->sb);
75: } else if(((XExposeEvent *)rep)->subwindow ==
76: screen->sb->save) {
77: screen->sb->savestate = -1;
78: DrawSave(screen->sb);
79: }
80: break;
81: }
82: if (screen->active_icon) {
83: #ifdef DEBUG
84: fputs( "ExposeWindow icon\n", stderr );
85: #endif DEBUG
86: if (window == screen->iconVwin.window) {
87: if (!screen->icon_show) {
88: screen->mappedVwin = &screen->iconVwin;
89: screen->icon_show = TRUE;
90: screen->show = FALSE;
91: screen->timer = 0;
92: screen->holdoff = FALSE;
93: if(screen->fullTwin.window)
94: moveiconwindow( screen->fullTwin.window,
95: screen->fullVwin.window );
96: }
97: if (screen->TekEmu)
98: VTUnselect();
99: if (term.flags & ICONINPUT)
100: reselectwindow(screen);
101: else
102: unselectwindow(screen, INWINDOW);
103: screen->iconinput = FALSE;
104: VTExpose(rep);
105: } else if (window == screen->iconTwin.window) {
106: if (!screen->icon_show) {
107: screen->mappedTwin = &screen->iconTwin;
108: screen->icon_show = TRUE;
109: screen->Tshow = FALSE;
110: screen->timer = 0;
111: screen->holdoff = FALSE;
112: if (screen->fullVwin.window)
113: moveiconwindow( screen->fullVwin.window,
114: screen->fullTwin.window );
115: }
116: if (!screen->TekEmu)
117: TekUnselect();
118: if (term.flags & ICONINPUT)
119: reselectwindow(screen);
120: else
121: unselectwindow(screen, INWINDOW);
122: screen->iconinput = FALSE;
123: TekExpose(rep);
124: }
125: } else if (window == screen->iconVwin.window ||
126: window == screen->iconTwin.window) {
127: #ifdef DEBUG
128: if(debug)
129: fprintf(stderr, "ExposeWindow %s\n", window ==
130: screen->iconVwin.window ? "icon" : "Ticon");
131: #endif DEBUG
132: RefreshIcon(screen, window);
133: break;
134: }
135: if(Titlebar(screen) || screen->icon_show) {
136: /* icon_show is a kludge as the titlebar exposure event
137: * frequently arrives before the full window exposure event */
138: if(window == screen->title.tbar) {
139: #ifdef DEBUG
140: if(debug)
141: fputs("ExposeWindow title\n", stderr);
142: #endif DEBUG
143: VTTitleExpose((XExposeWindowEvent *)rep);
144: break;
145: } else if(window == screen->Ttitle.tbar) {
146: #ifdef DEBUG
147: if(debug)
148: fputs("ExposeWindow Ttitle\n", stderr);
149: #endif DEBUG
150: TekTitleExpose((XExposeWindowEvent *)rep);
151: break;
152: }
153: }
154: if(window == screen->fullVwin.window) {
155: #ifdef DEBUG
156: if(debug)
157: fputs("ExposeWindow VT\n", stderr);
158: #endif DEBUG
159: if(!screen->show) {
160: screen->mappedVwin = &screen->fullVwin;
161: if(screen->Ticonunmap) {
162: screen->Ticonunmap = FALSE;
163: XMapWindow( screen->fullTwin.window );
164: screen->Tshow = TRUE;
165: if(!screen->TekEmu) {
166: screen->holdoff = TRUE;
167: XUnmapTransparent(VWindow(screen));
168: XMapWindow(VWindow(screen));
169: break;
170: }
171: } else {
172: screen->timer = 0;
173: screen->holdoff = FALSE;
174: }
175: screen->show = TRUE;
176: reselectwindow(screen);
177: if(screen->icon_show && screen->deiconwarp)
178: DeiconWarp(screen);
179:
180: screen->icon_show = FALSE;
181: screen->iconinput = FALSE;
182: }
183: VTExpose(rep);
184: } else if(window == screen->fullTwin.window) {
185: #ifdef DEBUG
186: if(debug)
187: fputs("ExposeWindow Tek\n", stderr);
188: #endif DEBUG
189: if(!screen->Tshow) {
190: screen->mappedTwin = &screen->fullTwin;
191: if(screen->iconunmap) {
192: screen->iconunmap = FALSE;
193: XMapWindow( screen->fullVwin.window );
194: screen->show = TRUE;
195: if(screen->TekEmu) {
196: screen->holdoff = TRUE;
197: XUnmapTransparent(TWindow(screen));
198: XMapWindow(TWindow(screen));
199: break;
200: }
201: } else {
202: screen->timer = 0;
203: screen->holdoff = FALSE;
204: }
205: screen->Tshow = TRUE;
206: reselectwindow(screen);
207: if(screen->icon_show && screen->deiconwarp)
208: DeiconWarp(screen);
209: screen->icon_show = FALSE;
210: screen->iconinput = FALSE;
211: }
212: TekExpose(rep);
213: }
214: break;
215:
216: case ExposeRegion:
217: if (!screen->active_icon && window == screen->iconVwin.window ||
218: window == screen->iconTwin.window) {
219: #ifdef DEBUG
220: if(debug)
221: fprintf(stderr, "ExposeRegion %s\n", window ==
222: screen->iconVwin.window ? "icon" : "Ticon");
223: #endif DEBUG
224: RefreshIcon(screen, window);
225: break;
226: }
227: #ifdef DEBUG
228: if(debug)
229: fputs("ExposeRegion\n", stderr);
230: #endif DEBUG
231: if (((XExposeWindowEvent *)rep)->detail == ExposeCopy &&
232: screen->incopy <= 0) {
233: screen->incopy = 1;
234: if (screen->scrolls > 0)
235: screen->scrolls--;
236: }
237: if (HandleExposure (screen, rep))
238: screen->cursor_state = OFF;
239: break;
240:
241: case ExposeCopy:
242: #ifdef DEBUG
243: if(debug)
244: fputs("ExposeCopy\n", stderr);
245: #endif DEBUG
246: if (screen->incopy <= 0 && screen->scrolls > 0)
247: screen->scrolls--;
248: if (screen->scrolls)
249: screen->incopy = -1;
250: else
251: screen->incopy = 0;
252: break;
253:
254: case ButtonPressed:
255: if (screen->incopy)
256: CopyWait (screen);
257: if(window == screen->iconVwin.window) {
258: #ifdef DEBUG
259: if(debug)
260: fputs("ButtonPressed icon\n", stderr);
261: #endif DEBUG
262: XUnmapWindow(window);
263: if(screen->Ticonunmap && !screen->TekEmu) {
264: screen->Ticonunmap = FALSE;
265: XMapWindow(TWindow(screen));
266: screen->Tshow = TRUE;
267: screen->holdoff = TRUE;
268: }
269: XMapWindow(screen->fullVwin.window);
270: break;
271: } else if(window == screen->iconTwin.window) {
272: #ifdef DEBUG
273: if(debug)
274: fputs("ButtonPressed Ticon\n", stderr);
275: #endif DEBUG
276: XUnmapWindow(window);
277: if(screen->iconunmap && screen->TekEmu) {
278: screen->iconunmap = FALSE;
279: XMapWindow(VWindow(screen));
280: screen->show = TRUE;
281: screen->holdoff = TRUE;
282: }
283: XMapWindow(screen->fullTwin.window);
284: break;
285: }
286: /* drop through */
287: case ButtonReleased:
288: #ifdef DEBUG
289: if(debug)
290: fputs("ButtonPressed or ButtonReleased\n",
291: stderr);
292: #endif DEBUG
293: HandleButtons(&term, rep, screen->respond);
294: break;
295:
296: case UnmapWindow: /* full windows */
297: if (window == screen->fullVwin.window) {
298: #ifdef DEBUG
299: if(debug)
300: fputs("UnmapWindow VT\n", stderr);
301: #endif DEBUG
302: if (screen->fullVwin.titlebar)
303: VTTitleUnhilite();
304: screen->show = FALSE;
305: if(screen->Tshow) {
306: screen->Ticonunmap = TRUE;
307: screen->Tshow = FALSE;
308: XUnmapWindow( screen->fullTwin.window );
309: SyncUnmap( screen->fullTwin.window,
310: TWINDOWEVENTS );
311: }
312: } else if(window == screen->fullTwin.window) {
313: #ifdef DEBUG
314: if(debug)
315: fputs("UnmapWindow Tek\n", stderr);
316: #endif DEBUG
317: if (screen->fullTwin.titlebar)
318: TekTitleUnhilite();
319: screen->Tshow = FALSE;
320: if(screen->show) {
321: screen->iconunmap = TRUE;
322: screen->show = FALSE;
323: XUnmapWindow( screen->fullVwin.window );
324: SyncUnmap( screen->fullVwin.window,
325: WINDOWEVENTS );
326: }
327: }
328: reselectwindow(screen);
329: screen->timer = 0;
330: break;
331: case EnterWindow:
332: if(screen->sb) {
333: if(window == screen->sb->button) {
334: if((i = GetButtonState(screen->sb)) !=
335: BUTTON_NORMAL)
336: SetButtonState(screen->sb, i | HILITED);
337: break;
338: } else if(window == screen->sb->bar)
339: break;
340: }
341: if((window == VWindow(screen) || window == TWindow(screen)) &&
342: (((XEnterWindowEvent *)rep)->detail & 0xff) !=
343: IntoOrFromSubwindow) {
344: #ifdef DEBUG
345: if(debug)
346: fprintf(stderr, "EnterWindow %s\n", window ==
347: VWindow(screen) ? "VT" : "Tek");
348: #endif DEBUG
349: screen->autowindow = window;
350: DoEnterLeave(screen, EnterWindow);
351: }
352: break;
353: case LeaveWindow:
354: if(screen->sb) {
355: if(window == screen->sb->button) {
356: if((i = GetButtonState(screen->sb)) !=
357: BUTTON_NORMAL)
358: SetButtonState(screen->sb, i& ~HILITED);
359: break;
360: } else if(window == screen->sb->bar)
361: break;
362: }
363: if((window == VWindow(screen) || window == TWindow(screen)) &&
364: (((XEnterWindowEvent *)rep)->detail & 0xff) !=
365: IntoOrFromSubwindow)
366: #ifdef DEBUG
367: {
368: if(debug)
369: fprintf(stderr, "LeaveWindow %s\n", window ==
370: VWindow(screen) ? "VT" : "Tek");
371: #endif DEBUG
372: DoEnterLeave(screen, LeaveWindow);
373: #ifdef DEBUG
374: }
375: #endif DEBUG
376: break;
377: case FocusChange:
378: if(((XFocusChangeEvent *)rep)->detail == EnterWindow)
379: selectwindow(screen, FOCUS);
380: else
381: unselectwindow(screen, FOCUS);
382: break;
383: default:
384: break;
385: }
386: }
387:
388: selectwindow(screen, flag)
389: register Screen *screen;
390: register int flag;
391: {
392: if(screen->TekEmu) {
393: TekSelect();
394: if(!Ttoggled)
395: TCursorToggle(TOGGLE);
396: if(screen->cellsused) {
397: screen->colorcells[2].pixel =
398: screen->Tcursorcolor;
399: XStoreColor(&screen->colorcells[2]);
400: }
401: screen->select |= flag;
402: if(!Ttoggled)
403: TCursorToggle(TOGGLE);
404: return;
405: } else {
406: VTSelect();
407: if(screen->cursor_state &&
408: (screen->cursor_col != screen->cur_col ||
409: screen->cursor_row != screen->cur_row))
410: HideCursor();
411: screen->select |= flag;
412: if(screen->cursor_state)
413: ShowCursor();
414: return;
415: }
416: }
417:
418: unselectwindow(screen, flag)
419: register Screen *screen;
420: register int flag;
421: {
422: register int i;
423:
424: screen->select &= ~flag;
425: if(!screen->select) {
426: if(screen->TekEmu) {
427: TekUnselect();
428: if(!Ttoggled)
429: TCursorToggle(TOGGLE);
430: if(screen->cellsused) {
431: i = (term.flags & REVERSE_VIDEO) == 0;
432: screen->colorcells[i].pixel =
433: screen->Tcursorcolor;
434: XStoreColor(
435: &screen->colorcells[i]);
436: }
437: if(!Ttoggled)
438: TCursorToggle(TOGGLE);
439: return;
440: } else {
441: VTUnselect();
442: if(screen->cursor_state &&
443: (screen->cursor_col != screen->cur_col ||
444: screen->cursor_row != screen->cur_row))
445: HideCursor();
446: if(screen->cursor_state)
447: ShowCursor();
448: return;
449: }
450: }
451: }
452:
453: reselectwindow(screen)
454: register Screen *screen;
455: {
456: Window win;
457: int x, y;
458:
459: if(XQueryMouse(RootWindow, &x, &y, &win)) {
460: if(win && (win == VWindow(screen) || win == TWindow(screen))
461: && (!screen->icon_show
462: || (screen->active_icon && term.flags & ICONINPUT)))
463: selectwindow(screen, INWINDOW);
464: else unselectwindow(screen, INWINDOW);
465: }
466: }
467:
468: DeiconWarp(screen)
469: register Screen *screen;
470: {
471: if(screen->TekEmu)
472: XWarpMouse(TWindow(screen), TFullWidth(screen) / 2,
473: TFullHeight(screen) / 2);
474: else
475: XWarpMouse(VWindow(screen), FullWidth(screen) / 2,
476: FullHeight(screen) / 2);
477: }
478:
479: #define ENTERLEAVE 500000L
480:
481: DoEnterLeave(screen, type)
482: register Screen *screen;
483: int type;
484: {
485: if (!screen->autoraise && !screen->holdoff) {
486: if (type == EnterWindow)
487: selectwindow( screen, INWINDOW );
488: else unselectwindow( screen, INWINDOW );
489: return;
490: }
491:
492: screen->timer = type;
493: if(!screen->holdoff)
494: Timer(ENTERLEAVE);
495: }
496:
497: Timer(val)
498: long val;
499: {
500: struct itimerval it;
501:
502: bzero(&it, sizeof(it));
503: it.it_value.tv_usec = val;
504: setitimer(ITIMER_REAL, &it, (struct itimerval *)0);
505: }
506:
507: /*
508: * Handle window select/unselect.
509: *
510: * We enter from a SIGALRM; X I/O may be in progress,
511: * so just set a flag which is polled in in_put().
512: */
513: onalarm()
514: {
515: register Screen *screen = &term.screen;
516:
517: if(screen->timer == 0 || screen->holdoff) { /* extraneous alarm */
518: Timer(0L);
519: return;
520: }
521: doonalarmcode++;
522: }
523:
524: onalarmcode()
525: {
526: register Screen *screen = &term.screen;
527:
528: if(screen->timer == EnterWindow) {
529: #ifdef DEBUG
530: if(debug)
531: fprintf(stderr, "onalarm: EnterWindow %s\n",
532: screen->autoraise ? (screen->autowindow ==
533: VWindow(screen) ? "VT" : "Tek") : "");
534: #endif DEBUG
535: selectwindow(screen, INWINDOW);
536: if(screen->autoraise)
537: XRaiseWindow(screen->autowindow);
538: } else /* LeaveWindow */
539: #ifdef DEBUG
540: {
541: if(debug)
542: fputs("onalarm: LeaveWindow\n", stderr);
543: #endif DEBUG
544: unselectwindow(screen, INWINDOW);
545: #ifdef DEBUG
546: }
547: #endif DEBUG
548: screen->timer = 0;
549: doonalarmcode = 0;
550: }
551:
552: Pixmap make_hilite(fg, bg)
553: int fg, bg;
554: {
555: extern Pixmap Make_tile();
556:
557: return(Make_tile(hilite_width, hilite_height, hilite_bits, fg,
558: bg));
559: }
560:
561: Pixmap make_gray()
562: {
563: extern Pixmap Make_tile();
564:
565: return(Make_tile(gray_width, gray_height, gray_bits, BlackPixel,
566: WhitePixel));
567: }
568:
569: Cursor make_tcross(fg, bg, func)
570: int fg, bg, func;
571: {
572: return(XCreateCursor(tcross_width, tcross_height, tcross_bits,
573: tcross_mask_bits, tcross_x_hot, tcross_y_hot, fg, bg, func));
574: }
575:
576: Cursor make_xterm(fg, bg, func)
577: int fg, bg, func;
578: {
579: return(XCreateCursor(xterm_width, xterm_height, xterm_bits,
580: xterm_mask_bits, xterm_x_hot, xterm_y_hot, fg, bg, func));
581: }
582:
583: Cursor make_wait(fg, bg, func)
584: int fg, bg, func;
585: {
586: return(XCreateCursor(wait_width, wait_height, wait_bits, waitmask_bits,
587: wait_x_hot, wait_y_hot, fg, bg, func));
588: }
589:
590: Cursor make_arrow(fg, bg, func)
591: int fg, bg, func;
592: {
593: return(XCreateCursor(left_ptr_width, left_ptr_height, left_ptr_bits,
594: left_ptr_mask_bits, left_ptr_x_hot, left_ptr_y_hot, fg, bg, func));
595: }
596:
597: char *uniquesuffix(name)
598: char *name;
599: {
600: register int *np, *fp, i;
601: register Window *cp;
602: register int temp, j, k, exact, *number;
603: char *wname;
604: Window *children, parent;
605: int nchildren;
606: static char *suffix, sufbuf[10];
607: char *malloc();
608:
609: if(suffix)
610: return(suffix);
611: suffix = sufbuf;
612: if(!XQueryTree(RootWindow, &parent, &nchildren, &children) ||
613: nchildren < 1 || (number = (int *)malloc(nchildren * sizeof(int)))
614: == NULL)
615: return(suffix);
616: exact = FALSE;
617: i = strlen(name);
618: for(np = number, cp = children, j = nchildren ; j > 0 ; cp++, j--) {
619: if(!XFetchName(*cp, &wname) || wname == NULL)
620: continue;
621: if(strncmp(name, wname, i) == 0) {
622: if(wname[i] == 0 || strcmp(&wname[i], " (Tek)") == 0)
623: exact = TRUE;
624: else if(strncmp(&wname[i], " #", 2) == 0)
625: *np++ = atoi(&wname[i + 2]);
626: }
627: free(wname);
628: }
629: free((char *)children);
630: if(exact) {
631: if(np <= number)
632: strcpy(suffix, " #2");
633: else {
634: exact = np - number;
635: np = number;
636: /* shell sort */
637: for(i = exact / 2 ; i > 0 ; i /= 2)
638: for(k = i ; k < exact ; k++)
639: for(j = k - i ; j >= 0 &&
640: np[j] > np[j + i] ; j -= i) {
641: temp = np[j];
642: np[j] = np[j + i];
643: np[j + i] = temp;
644: }
645: /* make numbers unique */
646: for(fp = np + 1, i = exact - 1 ; i > 0 ; fp++, i--)
647: if(*fp != *np)
648: *++np = *fp;
649: /* find least unique number */
650: for(i = 2, fp = number ; fp <= np ; fp++) {
651: if(i < *fp)
652: break;
653: if(i == *fp)
654: i++;
655: }
656: sprintf(suffix, " #%d", i);
657: }
658: }
659: free((char *)number);
660: return(suffix);
661: }
662:
663: Bell()
664: {
665: extern Terminal term;
666: register Screen *screen = &term.screen;
667: register Window w;
668: register int width, height, xorPixel;
669:
670: if (screen->audiblebell)
671: XFeep(0);
672:
673: if (screen->visualbell) {
674: if (screen->TekEmu) {
675: if (screen->icon_show && !screen->active_icon) {
676: w = screen->iconTwin.window;
677: width = screen->iconTwin.width;
678: height = screen->iconTwin.height;
679: } else {
680: w = TWindow(screen);
681: width = TFullWidth(screen);
682: height = TFullHeight(screen);
683: }
684: } else {
685: if (screen->icon_show && !screen->active_icon) {
686: w = screen->iconVwin.window;
687: width = screen->iconVwin.width;
688: height = screen->iconVwin.height;
689: } else {
690: w = VWindow(screen);
691: width = FullWidth(screen);
692: height = FullHeight(screen);
693: }
694: }
695: xorPixel = screen->foreground ^ screen->background;
696: XPixFill(w, 0, 0, width, height, xorPixel, 0, GXxor, AllPlanes);
697: XFlush();
698: usleep(screen->visbelldelay * 1000);
699: XPixFill(w, 0, 0, width, height, xorPixel, 0, GXxor, AllPlanes);
700: }
701: }
702:
703: Redraw()
704: {
705: extern Terminal term;
706: register Screen *screen = &term.screen;
707:
708: if(VWindow(screen) && screen->show) {
709: VTExpose(NULL);
710: if(screen->scrollbar) {
711: XClear(screen->sb->bar);
712: XClear(screen->sb->region);
713: screen->sb->buttonstate = -1;
714: DrawButton(screen->sb);
715: screen->sb->savestate = -1;
716: DrawSave(screen->sb);
717: }
718: if(Titlebar(screen)) {
719: XClear(screen->title.tbar);
720: XClear(screen->title.left);
721: XClear(screen->title.right);
722: VTTitleExpose(NULL);
723: }
724: }
725: if(TWindow(screen) && screen->Tshow) {
726: TekExpose(NULL);
727: if(Titlebar(screen)) {
728: XClear(screen->Ttitle.tbar);
729: XClear(screen->Ttitle.left);
730: XClear(screen->Ttitle.right);
731: TekTitleExpose(NULL);
732: }
733: }
734: }
735:
736: IconInit(screen, bm, Tbm)
737: register Screen *screen;
738: char *bm, *Tbm;
739: {
740: register int w;
741:
742: again:
743: if(!bm && !Tbm) { /* use default bitmaps */
744: screen->iconbitmap.bits = icon_bits;
745: screen->Ticonbitmap.bits = tek_icon_bits;
746: screen->bitmapwidth = screen->iconbitmap.width =
747: screen->Ticonbitmap.width = icon_width;
748: screen->bitmapheight = screen->iconbitmap.height =
749: screen->Ticonbitmap.height = icon_height;
750: } else if(bm && !*bm && Tbm && !*Tbm) /* both empty means no bitmap */
751: screen->bitmapwidth = screen->bitmapheight = 0;
752: else { /* user defined bitmap(s) */
753: if(bm && *bm) {
754: if((w = XReadBitmapFile(bm, &screen->iconbitmap.width,
755: &screen->iconbitmap.height, &screen->iconbitmap.bits,
756: NULL, NULL)) == 0) {
757: /*
758: * Pretend there wasn't an icon specified
759: * and try for the default icon.
760: */
761: fprintf(stderr, "%s: Can't open %s\n",
762: xterm_name, bm);
763: bm = 0;
764: goto again;
765: } else if(w < 0) {
766: syntaxerror:
767: fprintf(stderr, "%s: Syntax error in %s\n",
768: xterm_name, bm);
769: Exit(ERROR_SYNTAXBITMAP);
770: }
771: screen->bitmapwidth = screen->iconbitmap.width;
772: screen->bitmapheight = screen->iconbitmap.height;
773: }
774: if(Tbm && *Tbm) {
775: if((w = XReadBitmapFile(Tbm, &screen->Ticonbitmap.width,
776: &screen->Ticonbitmap.height, &screen->Ticonbitmap.bits,
777: NULL, NULL)) == 0) {
778: /*
779: * Pretend there wasn't an icon specified
780: * and try for the default icon.
781: */
782: fprintf(stderr, "%s: Can't open %s\n",
783: xterm_name, Tbm);
784: Tbm = 0;
785: goto again;
786: } else if (w < 0)
787: goto syntaxerror;
788: if(screen->bitmapwidth < screen->Ticonbitmap.width)
789: screen->bitmapwidth = screen->Ticonbitmap.width;
790: if(screen->bitmapheight < screen->Ticonbitmap.height)
791: screen->bitmapheight =
792: screen->Ticonbitmap.height;
793: }
794: if(!screen->iconbitmap.bits) {
795: if(!screen->Ticonbitmap.bits) {
796: screen->Ticonbitmap.bits = tek_icon_bits;
797: screen->bitmapwidth = screen->Ticonbitmap.width
798: = icon_width;
799: screen->bitmapheight =
800: screen->Ticonbitmap.height = icon_height;
801: }
802: screen->iconbitmap.bits = screen->Ticonbitmap.bits;
803: screen->iconbitmap.width = screen->Ticonbitmap.width;
804: screen->iconbitmap.height = screen->Ticonbitmap.height;
805: } else if(!screen->Ticonbitmap.bits) {
806: if(!screen->iconbitmap.bits) {
807: screen->iconbitmap.bits = icon_bits;
808: screen->bitmapwidth = screen->iconbitmap.width
809: = icon_width;
810: screen->bitmapheight =
811: screen->iconbitmap.height = icon_height;
812: }
813: screen->Ticonbitmap.bits = screen->iconbitmap.bits;
814: screen->Ticonbitmap.width = screen->iconbitmap.width;
815: screen->Ticonbitmap.height = screen->iconbitmap.height;
816: }
817: }
818: if((screen->winname = malloc(strlen(win_name) + 10)) == NULL)
819: Error(ERROR_WINNAME);
820: strcpy(screen->winname, win_name);
821: if (douniquesuffix)
822: strcat(screen->winname, uniquesuffix(win_name));
823: screen->winnamelen = strlen(screen->winname);
824: IconRecalc(screen);
825: }
826:
827: IconRecalc(screen)
828: register Screen *screen;
829: {
830: register int i, w;
831:
832: if (screen->active_icon) return;
833:
834: w = XQueryWidth(screen->winname, screen->titlefont->id);
835: if(screen->bitmapwidth > 0) {
836: if(screen->textundericon) {
837: screen->icon_text_x = TITLEPAD;
838: screen->icon_text_y = screen->bitmapheight +
839: 2 * TITLEPAD;
840: screen->iconVwin.height = screen->bitmapheight +
841: screen->titlefont->height + 3 * TITLEPAD;
842: screen->iconbitmap.x = screen->Ticonbitmap.x =
843: screen->iconbitmap.y = screen->Ticonbitmap.y =
844: TITLEPAD;
845: if((i = screen->bitmapwidth - w) >= 0) {
846: screen->iconVwin.width = screen->bitmapwidth +
847: 2 * TITLEPAD;
848: screen->icon_text_x += i / 2;
849: } else {
850: screen->iconVwin.width = w + 2 * TITLEPAD;
851: i = (-i) / 2;
852: screen->iconbitmap.x += i;
853: screen->Ticonbitmap.x += i;
854: }
855: } else {
856: screen->icon_text_x = screen->bitmapwidth +
857: 2 * TITLEPAD;
858: screen->icon_text_y = TITLEPAD;
859: screen->iconVwin.width = w + screen->bitmapwidth +
860: 3 * TITLEPAD;
861: screen->iconbitmap.x = screen->Ticonbitmap.x =
862: screen->iconbitmap.y = screen->Ticonbitmap.y =
863: TITLEPAD;
864: if((i = screen->bitmapheight -
865: screen->titlefont->height) >= 0) {
866: screen->iconVwin.height = screen->bitmapheight +
867: 2 * TITLEPAD;
868: screen->icon_text_y += i / 2;
869: } else {
870: screen->iconVwin.height = screen->titlefont->height
871: + 2 * TITLEPAD;
872: i = (-i) / 2;
873: screen->iconbitmap.y += i;
874: screen->Ticonbitmap.y += i;
875: }
876: }
877: if((i = screen->iconbitmap.width - screen->Ticonbitmap.width)
878: >= 0)
879: screen->Ticonbitmap.x += i / 2;
880: else
881: screen->iconbitmap.x += (-i) / 2;
882: if((i = screen->iconbitmap.height - screen->Ticonbitmap.height)
883: >= 0)
884: screen->Ticonbitmap.y += i / 2;
885: else
886: screen->iconbitmap.y += (-i) / 2;
887: } else {
888: screen->icon_text_x = TITLEPAD;
889: screen->iconVwin.width = w + 2 * TITLEPAD;
890: screen->iconVwin.height = screen->titlefont->height + 2 * TITLEPAD;
891: }
892:
893: if (screen->iconVwin.window)
894: XChangeWindow( screen->iconVwin.window, screen->iconVwin.width,
895: screen->iconVwin.height );
896:
897: if (screen->iconTwin.window) {
898: screen->iconTwin.width = screen->iconVwin.width;
899: screen->iconTwin.height = screen->iconVwin.height;
900: XChangeWindow( screen->iconTwin.window, screen->iconTwin.width,
901: screen->iconTwin.height );
902: }
903:
904: icon_box[0].x = screen->icon_text_x - 2;
905: icon_box[0].y = screen->icon_text_y - 2;
906: icon_box[3].x = -(icon_box[1].x = w + 3);
907: icon_box[4].y = -(icon_box[2].y = screen->titlefont->height + 3);
908: }
909:
910: RefreshIcon(screen, window)
911: register Screen *screen;
912: Window window;
913: {
914: register BitmapBits *bb;
915: register int fg, bg;
916:
917: bb = screen->TekEmu ? &screen->Ticonbitmap : &screen->iconbitmap;
918: fg = screen->foreground;
919: bg = screen->background;
920: if(screen->bitmapwidth > 0)
921: XBitmapBitsPut(window, bb->x, bb->y, bb->width, bb->height,
922: bb->bits, fg, bg, (Bitmap)0, GXcopy, AllPlanes);
923: XText(window, screen->icon_text_x, screen->icon_text_y,
924: screen->winname, screen->winnamelen, screen->titlefont->id, fg, bg);
925: screen->icon_show = TRUE;
926: if(screen->iconinput)
927: IconBox(screen);
928: }
929:
930: IconBox(screen)
931: register Screen *screen;
932: {
933: if (screen->active_icon) return;
934:
935: XDraw(screen->TekEmu ? screen->iconTwin.window : screen->iconVwin.window,
936: icon_box, NBOX, 1, 1, screen->foreground, GXcopy, AllPlanes);
937: }
938:
939: /*
940: * Move win1's icon window to where win2's icon window is.
941: */
942: moveiconwindow(win1, win2)
943: register Window win1, win2;
944: {
945: WindowInfo wininfo1, wininfo2;
946:
947: XQueryWindow(win1, &wininfo1);
948: XQueryWindow(win2, &wininfo2);
949: if(wininfo1.assoc_wind && wininfo2.assoc_wind) {
950: XQueryWindow(wininfo2.assoc_wind, &wininfo2);
951: XMoveWindow(wininfo1.assoc_wind, wininfo2.x, wininfo2.y);
952: }
953: }
954:
955: IconGeometry(screen, ix, iy)
956: register Screen *screen;
957: register int *ix, *iy;
958: {
959: register int i;
960: int w, h;
961:
962: if(icon_geom) {
963: i = XParseGeometry(icon_geom, ix, iy, &w, &h);
964: /*
965: * XParseGeometry returns negative values in addition to
966: * setting the bitmask.
967: */
968: if((i & XValue) && (i & XNegative))
969: *ix = DisplayWidth() + *ix - screen->iconVwin.width - 2 *
970: screen->borderwidth;
971: if((i & YValue) && (i & YNegative))
972: *iy = DisplayHeight() + *iy - screen->iconVwin.height - 2 *
973: screen->borderwidth;
974: }
975: }
976:
977: InTitle(screen, window, x)
978: register Screen *screen;
979: Window window;
980: int x;
981: {
982: register int i, j;
983:
984: if(window == screen->title.tbar) {
985: i = (j = FullWidth(screen) / 2) - (screen->title.x -
986: screen->title_n_size);
987: j = x - j;
988: if(j < 0)
989: j = -j;
990: if(j < i) {
991: XUnmapWindow(VWindow(screen));
992: XMapWindow(screen->iconVwin.window);
993: return(TRUE);
994: }
995: } else {
996: i = (j = TFullWidth(screen) / 2) - (screen->Ttitle.x -
997: screen->title_n_size);
998: j = x - j;
999: if(j < 0)
1000: j = -j;
1001: if(j < i) {
1002: XUnmapWindow(TWindow(screen));
1003: XMapWindow(screen->iconTwin.window);
1004: return(TRUE);
1005: }
1006: }
1007: return(FALSE);
1008: }
1009:
1010: SyncUnmap(win, mask)
1011: register Window win;
1012: register int mask;
1013: {
1014: XEvent ev;
1015: register XEvent *rep = &ev;
1016:
1017: do { /* ignore events through unmap */
1018: XWindowEvent(win, mask, rep);
1019: } while(rep->type != UnmapWindow);
1020: }
1021:
1022: StartLog(screen)
1023: register Screen *screen;
1024: {
1025: register char *cp;
1026: register int i;
1027: static char *log_default;
1028: char *malloc(), *rindex();
1029: extern logpipe();
1030:
1031: if(screen->logging || (screen->inhibit & I_LOG))
1032: return;
1033: if(screen->logfile == NULL || *screen->logfile == 0) {
1034: if(screen->logfile)
1035: free(screen->logfile);
1036: if(log_default == NULL)
1037: mktemp(log_default = log_def_name);
1038: if((screen->logfile = malloc(strlen(log_default) + 1)) == NULL)
1039: return;
1040: strcpy(screen->logfile, log_default);
1041: }
1042: if(*screen->logfile == '|') { /* exec command */
1043: int p[2];
1044: static char *shell;
1045:
1046: if(pipe(p) < 0 || (i = fork()) < 0)
1047: return;
1048: if(i == 0) { /* child */
1049: close(p[1]);
1050: dup2(p[0], 0);
1051: close(p[0]);
1052: dup2(fileno(stderr), 1);
1053: dup2(fileno(stderr), 2);
1054: close(fileno(stderr));
1055: fileno(stderr) = 2;
1056: close(screen->display->fd);
1057: close(screen->respond);
1058: if(!shell) {
1059: register struct passwd *pw;
1060: char *getenv(), *malloc();
1061: struct passwd *getpwuid();
1062:
1063: if(((cp = getenv("SHELL")) == NULL || *cp == 0)
1064: && ((pw = getpwuid(screen->uid)) == NULL ||
1065: *(cp = pw->pw_shell) == 0) ||
1066: (shell = malloc(strlen(cp) + 1)) == NULL)
1067: shell = "/bin/sh";
1068: else
1069: strcpy(shell, cp);
1070: }
1071: signal(SIGHUP, SIG_DFL);
1072: signal(SIGCHLD, SIG_DFL);
1073: setgid(screen->gid);
1074: setuid(screen->uid);
1075: execl(shell, shell, "-c", &screen->logfile[1], 0);
1076: fprintf(stderr, "%s: Can't exec `%s'\n", xterm_name,
1077: &screen->logfile[1]);
1078: exit(ERROR_LOGEXEC);
1079: }
1080: close(p[0]);
1081: screen->logfd = p[1];
1082: signal(SIGPIPE, logpipe);
1083: } else {
1084: if(access(screen->logfile, F_OK) == 0) {
1085: if(access(screen->logfile, W_OK) < 0)
1086: return;
1087: } else if(cp = rindex(screen->logfile, '/')) {
1088: *cp = 0;
1089: i = access(screen->logfile, W_OK);
1090: *cp = '/';
1091: if(i < 0)
1092: return;
1093: } else if(access(".", W_OK) < 0)
1094: return;
1095: if((screen->logfd = open(screen->logfile, O_WRONLY | O_APPEND |
1096: O_CREAT, 0644)) < 0)
1097: return;
1098: chown(screen->logfile, screen->uid, screen->gid);
1099:
1100: }
1101: screen->logstart = screen->TekEmu ? Tbptr : bptr;
1102: screen->logging = TRUE;
1103: }
1104:
1105: CloseLog(screen)
1106: register Screen *screen;
1107: {
1108: if(!screen->logging || (screen->inhibit & I_LOG))
1109: return;
1110: FlushLog(screen);
1111: close(screen->logfd);
1112: screen->logging = FALSE;
1113: }
1114:
1115: FlushLog(screen)
1116: register Screen *screen;
1117: {
1118: register char *cp;
1119: register int i;
1120:
1121: cp = screen->TekEmu ? Tbptr : bptr;
1122: if((i = cp - screen->logstart) > 0)
1123: write(screen->logfd, screen->logstart, i);
1124: screen->logstart = screen->TekEmu ? Tbuffer : buffer;
1125: }
1126:
1127: logpipe()
1128: {
1129: register Screen *screen = &term.screen;
1130:
1131: if(screen->logging)
1132: CloseLog(screen);
1133: }
1134:
1135: do_osc(func)
1136: int (*func)();
1137: {
1138: register Screen *screen = &term.screen;
1139: register int mode, c;
1140: register char *cp;
1141: char buf[512];
1142: extern char *malloc();
1143:
1144: mode = 0;
1145: while(isdigit(c = (*func)()))
1146: mode = 10 * mode + (c - '0');
1147: cp = buf;
1148: while(isprint(c = (*func)()))
1149: *cp++ = c;
1150: *cp = 0;
1151: switch(mode) {
1152: case 0: /* new title */
1153: Retitle(buf);
1154: break;
1155: case 46: /* new log file */
1156: if((cp = malloc(strlen(buf) + 1)) == NULL)
1157: break;
1158: strcpy(cp, buf);
1159: if(screen->logfile)
1160: free(screen->logfile);
1161: screen->logfile = cp;
1162: break;
1163: #ifdef CHANGEFONT
1164: case 47: /* new screen font */
1165: if (VTChangeFont(screen, buf)) {
1166: XChangeWindow (VWindow(screen),
1167: FontWidth(screen) * (screen->max_col + 1) +
1168: 2 * screen->border + screen->scrollbar,
1169: FontHeight(screen) * (screen->max_row + 1) +
1170: screen->statusheight + Titlebar(screen)
1171: + 2 * screen->border);
1172: XSync(FALSE); /* synchronize */
1173: if(QLength() > 0)
1174: xevents();
1175: }
1176: break;
1177: }
1178: #endif
1179: }
1180:
1181: Retitle(name)
1182: register char *name;
1183: {
1184: register Screen *screen = &term.screen;
1185: register int w, i, j;
1186: char icon[512];
1187:
1188: free(screen->winname);
1189: if((screen->winname = malloc((screen->winnamelen = strlen(name)) + 1))
1190: == NULL)
1191: Error(ERROR_RTMALLOC1);
1192: strcpy(screen->winname, name);
1193: strcpy(icon, name);
1194: strcat(icon, " (icon)");
1195: IconRecalc(screen);
1196: if(screen->fullVwin.window) {
1197: XStoreName(screen->fullVwin.window, name);
1198: XStoreName(screen->iconVwin.window, icon);
1199: XChangeWindow(screen->iconVwin.window, screen->iconVwin.width,
1200: screen->iconVwin.height);
1201: if(screen->title.tbar) {
1202: w = FullWidth(screen);
1203: screen->title.fullwidth = XQueryWidth(name,
1204: screen->titlefont->id);
1205: if((screen->title.width = i = screen->title.fullwidth)
1206: > (j = w - 2 * (MINHILITE + screen->title_n_size + 1)))
1207: screen->title.width = (i = j) +
1208: screen->title_n_size;
1209: j = w - i - 2 * (screen->title_n_size + 1);
1210: i = j / 2;
1211: j -= i;
1212: screen->title.x = i + 1 + screen->title_n_size;
1213: screen->title.y = TITLEPAD;
1214: XClear(screen->title.tbar);
1215: XChangeWindow(screen->title.left, i,
1216: screen->titlefont->height);
1217: XConfigureWindow(screen->title.right, w - j - 1,
1218: TITLEPAD, j, screen->titlefont->height);
1219: VTTitleExpose((XExposeWindowEvent *)NULL);
1220: }
1221: }
1222: if(screen->fullTwin.window) {
1223: free(screen->Twinname);
1224: if((screen->Twinname = malloc((screen->Twinnamelen =
1225: screen->winnamelen + 6) + 1)) == NULL)
1226: Error(ERROR_RTMALLOC2);
1227: strcpy(screen->Twinname, name);
1228: strcat(screen->Twinname, " (Tek)");
1229: XStoreName(screen->fullTwin.window, screen->Twinname);
1230: XStoreName(screen->iconTwin.window, icon);
1231: XChangeWindow(screen->iconTwin.window, screen->iconTwin.width,
1232: screen->iconTwin.height);
1233: if(screen->Ttitle.tbar) {
1234: w = TFullWidth(screen);
1235: screen->Ttitle.fullwidth = XQueryWidth(screen->Twinname,
1236: screen->titlefont->id);
1237: if((screen->Ttitle.width = i = screen->Ttitle.fullwidth)
1238: > (j = w - 2 * (MINHILITE + screen->title_n_size + 1)))
1239: screen->Ttitle.width = (i = j) +
1240: screen->title_n_size;
1241: j = w - i - 2 * (screen->title_n_size + 1);
1242: i = j / 2;
1243: j -= i;
1244: screen->Ttitle.x = i + 1 + screen->title_n_size;
1245: screen->Ttitle.y = TITLEPAD;
1246: XClear(screen->Ttitle.tbar);
1247: XChangeWindow(screen->Ttitle.left, i,
1248: screen->titlefont->height);
1249: XConfigureWindow(screen->Ttitle.right, w - j - 1,
1250: TITLEPAD, j, screen->titlefont->height);
1251: TekTitleExpose((XExposeWindowEvent *)NULL);
1252: }
1253: }
1254: }
1255:
1256: Panic(s, a)
1257: char *s;
1258: int a;
1259: {
1260: #ifdef DEBUG
1261: if(debug) {
1262: fprintf(stderr, "%s: PANIC! ", xterm_name);
1263: fprintf(stderr, s, a);
1264: fputs("\r\n", stderr);
1265: fflush(stderr);
1266: }
1267: #endif DEBUG
1268: }
1269:
1270: SysError (i)
1271: int i;
1272: {
1273: fprintf (stderr, "%s: Error %d, errno %d:", xterm_name, i, errno);
1274: perror ("");
1275: Cleanup(i);
1276: }
1277:
1278: Error (i)
1279: int i;
1280: {
1281: fprintf (stderr, "%s: Error %d\n", xterm_name, i);
1282: Cleanup(i);
1283: }
1284:
1285: /*
1286: * cleanup by sending SIGHUP to client processes
1287: */
1288: Cleanup (code)
1289: int code;
1290: {
1291: #ifdef notdef
1292: extern Terminal term;
1293: register Screen *screen;
1294:
1295: screen = &term.screen;
1296: if (screen->pid > 1)
1297: killpg(getpgrp(screen->pid), SIGHUP);
1298: #endif
1299: Exit (code);
1300: }
1301:
1302: /*
1303: * sets the value of var to be arg in the Unix 4.2 BSD environment env.
1304: * Var should end with '=' (bindings are of the form "var=value").
1305: * This procedure assumes the memory for the first level of environ
1306: * was allocated using calloc, with enough extra room at the end so not
1307: * to have to do a realloc().
1308: */
1309: Setenv (var, value)
1310: register char *var, *value;
1311: {
1312: extern char **environ;
1313: register int index = 0;
1314: register int len = strlen(var);
1315:
1316: while (environ [index] != NULL) {
1317: if (strncmp (environ [index], var, len) == 0) {
1318: /* found it */
1319: environ[index] = (char *)malloc (len + strlen (value) + 1);
1320: strcpy (environ [index], var);
1321: strcat (environ [index], value);
1322: return;
1323: }
1324: index ++;
1325: }
1326:
1327: #ifdef DEBUG
1328: if (debug) fputs ("expanding env\n", stderr);
1329: #endif DEBUG
1330:
1331: environ [index] = (char *) malloc (len + strlen (value) + 1);
1332: strcpy (environ [index], var);
1333: strcat (environ [index], value);
1334: environ [++index] = NULL;
1335: }
1336:
1337: /*
1338: * returns a pointer to the first occurrence of s2 in s1,
1339: * or NULL if there are none.
1340: */
1341: char *strindex (s1, s2)
1342: register char *s1, *s2;
1343: {
1344: register char *s3;
1345: char *index();
1346:
1347: while ((s3=index(s1, *s2)) != NULL) {
1348: if (strncmp(s3, s2, strlen(s2)) == 0)
1349: return (s3);
1350: s1 = ++s3;
1351: }
1352: return (NULL);
1353: }
1354:
1355: xerror(d, ev)
1356: Display *d;
1357: register XErrorEvent *ev;
1358: {
1359: fprintf(stderr, "%s: %s\n", xterm_name,
1360: XErrDescrip(ev->error_code));
1361: fprintf(stderr, "Request code %d, func %d, serial #%ld, window %ld\n",
1362: ev->request_code, ev->func, ev->serial, (long)ev->window);
1363: Exit(ERROR_XERROR);
1364: }
1365:
1366: xioerror(d)
1367: Display *d;
1368: {
1369: perror(xterm_name);
1370: Exit(ERROR_XIOERROR);
1371: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.