home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume9 / xterm / part06 / resize.c < prev    next >
C/C++ Source or Header  |  1987-04-20  |  7KB  |  319 lines

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