home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume9 / xterm / part06 / misc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-04-20  |  32.1 KB  |  1,335 lines

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