home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume2 / window / part2 / cmd.c next >
Encoding:
C/C++ Source or Header  |  1986-11-30  |  7.8 KB  |  342 lines

  1. /*
  2.  *************
  3.  * DISTRIBUTION NOTICE  July 30 1985
  4.  * A Revised Edition of WM, by Matt Lennon and Tom Truscott,
  5.  *        Research Triangle Institute, (919) 541-7005.
  6.  * Based on the original by Robert Jacob (decvax!nrl-css!jacob),
  7.  *        Naval Research Laboratory, (202) 767-3365.
  8.  * No claims or warranties of any sort are made for this distribution.
  9.  * General permission is granted to copy, but not for profit,
  10.  * any of this distribution, provided that this notice
  11.  * is always included in the copies.
  12.  *************
  13.  */
  14. /*
  15.  * Command interpreter for WM.
  16.  */
  17.  
  18. #include "wm.h"
  19.  
  20. /*
  21.  * Command definitions
  22.  */
  23. # define DUMPWINDOW    'd'    /* dump contents of current window to file */
  24. # define FITWINDOW    'f'    /* Find best unobscured place for a window */
  25. # define HELP2        'h'    /* Command summary */
  26. # define HELP1        '?'    /* Command summary */
  27. # define IDENTWINDOW    'i'    /* print name of current window */
  28. # define KILLWINDOW    'k'    /* get rid of this window forever */
  29. # define LASTWINDOW    'l'    /* change to Last-used window */
  30. # define MOVEWINDOW    'm'    /* Move locn and/or change size of window */
  31. # define NEWWINDOW    'n'    /* make New window */
  32. # define PREFIX        'p'    /* change prefix character */
  33. # define QUIT        'q'    /* close up everything and Quit */
  34. # define REDRAW        'r'    /* Redraw all windows */
  35. # define SAVEWINDOWS    's'    /* save current window configuration */
  36. # define TERMCAP    't'    /* Reset $TERM and $TERMCAP of current window */
  37. # define SUSPEND    'z'    /* suspend wm */
  38. # define NOOP1        ' '    /* no-op */
  39. # define NOOP2        '\n'    /* no-op */
  40. # define NOOP3        '\r'    /* no-op */
  41.  
  42.  
  43. /*
  44.  * Execute a WM command.
  45.  */
  46. docmd(cmd)
  47.  
  48. int cmd;    /* IN: command code */
  49. {
  50.     register int w, tmpw;
  51.     int begline, begcol, lines, cols;    /* window parameters */
  52.     char *s;
  53.     register WINDOW *wp;
  54.  
  55.  
  56.     switch (cmd)
  57.     {
  58.     case CANCEL1:
  59.     case CANCEL2:
  60.     showmsg("Canceled.");
  61.     break;
  62.  
  63.     case NEWWINDOW:
  64.     tmpw = topw;
  65.     if ((w = GetSlot()) < 0) {
  66.         showmsg("Sorry, can't create any more windows.");
  67.         break;
  68.     }
  69.     if (NewWindow(w,LINES-1,COLS,0,0))
  70.         break;
  71.     WListAdd(w);
  72.     if (getbounds(w, TRUE) != 0)
  73.         break;    /* getbounds will have freed the window */
  74.     lastw = tmpw;
  75.     showmsg("Created new window #%d.", w);
  76.     winchanged(w);
  77.     break;
  78.  
  79.     case '0':
  80.     case '1':
  81.     case '2':
  82.     case '3':
  83.     case '4':
  84.     case '5':
  85.     case '6':
  86.     case '7':
  87.     case '8':
  88.     case '9':
  89.     w = ctoi(cmd);
  90.     if ( ! iswindow(w))
  91.         showmsg("No such window #%d.", w);
  92.     else if (w == topw)
  93.         showmsg("You're already in window #%d.", w);
  94.     else
  95.     {
  96.         lastw = topw;
  97.         WListDelete(w);
  98.         WListAdd(w);
  99.         RedrawScreen();
  100.         showmsg("Changed to window #%d.", w);
  101.     }
  102.     break;
  103.  
  104.     case LASTWINDOW:
  105.     if (iswindow(lastw) && lastw!=topw)
  106.     {
  107.         w=lastw;
  108.         lastw=topw;
  109.         WListDelete(w);
  110.         WListAdd(w);
  111.         RedrawScreen();
  112.         showmsg("Changed back to window #%d.", w);
  113.     }
  114.     else
  115.         showmsg("No last window.");
  116.     break;
  117.  
  118.     case MOVEWINDOW:
  119.     w = topw;
  120.     wp = win[w].wptr;
  121.     lines = wlines(wp); cols = wcols(wp);
  122.     begline = wbegy(wp); begcol = wbegx(wp);
  123.     if (getbounds(w, FALSE) != 0)
  124.         break;
  125.     wp = win[w].wptr;
  126.     if (lines == wlines(wp) && cols == wcols(wp)) {
  127.         if (begline == wbegy(wp) && begcol == wbegx(wp)) {
  128.         showmsg("Window unchanged.");
  129.         break;
  130.         }
  131.     }
  132.     else
  133.         SetTerm(w, 2);
  134.     showmsg("Moved window #%d.", w);
  135.     winchanged(w);
  136.     break;
  137.  
  138.     case FITWINDOW:
  139.     showmsg("Fit which window?");
  140.     if ((w = askwindow()) < 0)
  141.         break;
  142.     if (fitwindow(w, &lines, &cols, &begline, &begcol) < 0) {
  143.         showmsg("Sorry, cannot find unobscured placement.");
  144.         break;
  145.     }
  146.     wp = win[w].wptr;
  147.     tmpw = 1;    /* shameless misuse of variable */
  148.     if (lines == wlines(wp) && cols == wcols(wp)) {
  149.         tmpw = 0;
  150.         if (begline == wbegy(wp) && begcol == wbegx(wp)) {
  151.         showmsg("Window already has best fit.");
  152.         break;
  153.         }
  154.     }
  155.     if (NewWindow(w,lines,cols,begline,begcol)) {
  156.         WListDelete(w);
  157.         break;
  158.     }
  159.     if (tmpw)
  160.         SetTerm(w, 2);
  161.     RedrawScreen();
  162.     showmsg("Moved window #%d.", w);
  163.     winchanged(w);
  164.     break;
  165.  
  166.     case KILLWINDOW:
  167.     showmsg("Kill which window?"); /* enter window name */
  168.     if ((w = askwindow())  < 0)
  169.         break;
  170.     if (w==topw)
  171.     {
  172.         showmsg("Can't kill the current window.");
  173.         break;
  174.     }
  175.     WListDelete(w); KillShell(w); FreeWindow(w);
  176.     RedrawScreen();
  177.     showmsg("Killed window #%d.", w);
  178.     if (w==lastw) lastw = -1;
  179.     configflag = TRUE;
  180.     break;
  181.  
  182.     case IDENTWINDOW:
  183.     IdentWindows();
  184.     break;
  185.  
  186.     case DUMPWINDOW:
  187.     if ((s = WPrompt("dump file", "wmdump")) == NULL)
  188.         break;
  189.     else if (DumpWindow(topw, s) == 0)
  190.         showmsg("Dumped contents of top window to file '%s'.", s);
  191.     else
  192.         showmsg("Sorry, can't open dump file '%s'.", s);
  193.     break;
  194.  
  195.     case REDRAW:
  196.     ClearScreen();
  197.     RedrawScreen();
  198.     break;
  199.  
  200.     case TERMCAP:
  201.     SetTerm(topw, 3);
  202.     break;
  203.  
  204.     case HELP1:
  205.     case HELP2:
  206.     ClearScreen();
  207.     helpmsg();
  208.     (void) tty_getch();
  209.     ClearScreen();
  210.     RedrawScreen();
  211.     break;
  212.  
  213.     case PREFIX:
  214.     showmsg("Enter new WM prefix character.");
  215.     prefix = tty_getch();
  216.     showmsg("New WM prefix character is '%s'.", mkprint(prefix));
  217.     configflag = TRUE;
  218.     break;
  219.  
  220.     case SUSPEND:
  221.     suspend();
  222.     break;
  223.  
  224.     case SAVEWINDOWS:
  225.     if ((s = WPrompt("save file", savefile))  == NULL)
  226.         break;
  227.     (void) strcpy(savefile, s);
  228.     if (Save(savefile) != 0)
  229.     {
  230.         showmsg("Saved current window configuration in '%s'.", savefile);
  231.         configflag = FALSE;
  232.     }
  233.     else showmsg("Sorry, can't save current window configuration.");
  234.     break;
  235.  
  236.     case QUIT:
  237.     return(TRUE);
  238.  
  239.     case NOOP1:
  240.     case NOOP2:
  241.     case NOOP3:
  242.     break;
  243.  
  244.     default:
  245.     showmsg("Invalid command '%s': use 'h' command for help.",mkprint(cmd));
  246.     break;
  247.     }
  248.  
  249.     return(FALSE);
  250. }
  251.  
  252. /*
  253.  * suspend w/ job control if using csh, otherwise spawn subshell.
  254.  * This could be integrated into curses tstp(),
  255.  * but I wasn't sure that could be done correctly,
  256.  * since it is impossible(?) to determine if the parent shell
  257.  * knows job control.
  258.  */
  259. suspend()
  260. {
  261.     register int rc;
  262. #ifndef TERMINFO
  263.     register int ttyflags;
  264. #endif
  265.  
  266.     /* If wm's parent is init, then we better not suspend with TSTP!
  267.      * Unfortunately, this heuristic fails if the user used rlogin,
  268.      * since wm's parent would then be rlogind.  We can only hope
  269.      * the user knows what he is doing.
  270.      */
  271.     if (getppid() != 1
  272.      && (rc = strlen(shellname)) >= 3
  273.      && strcmp(shellname+rc-3, "csh") == 0) {
  274.     showmsg("Suspending.");
  275.     tstp();
  276.     showmsg("WM resumed.");
  277.     return;
  278.     }
  279.  
  280.     showmsg("Spawning a sub-shell ...");
  281.     (void) movecursor(LINES-1, 0);
  282. #ifndef TERMINFO
  283.     ttyflags = _tty.sg_flags;
  284. #endif
  285.     endwin();
  286.     putchar('\n');    /* scroll up, for neatness */
  287.     (void) fflush(stdout);
  288.  
  289.     rc = system(shellpgm);
  290. #ifdef TERMINFO
  291. #ifdef BUGGYTERMINFO
  292.     /* Alas, buggyterminfo apparently does not re-remember the virgin state
  293.      * or correct for a baud-rate change */
  294. #endif
  295.     fixterm();
  296. #else
  297.     savetty();    /* re-remember the virgin state */
  298.     _tty.sg_flags = ttyflags;
  299.     (void) ioctl(_tty_ch, TIOCSETN, (char *)&_tty);
  300. #endif
  301.     if (enter_ca_mode)
  302.     putp(enter_ca_mode);
  303.     wrefresh(curscr);
  304.     /* we could diagnose things better here */
  305.     if (rc == 127)
  306.     showmsg("Cannot spawn a shell!");
  307.     else
  308.     showmsg("Returning to WM.");
  309. }
  310.  
  311. /*
  312.  * Set 'configflag' to indicate change affecting wmrc file.
  313.  * If this window is full-width or full-length,
  314.  * set the corresponding 'flex' flag.
  315.  * Warn user if this is a 'slow' window.
  316.  */
  317. winchanged(w)
  318. register int w;
  319. {
  320.     register WINDOW *wp;
  321.     static int full_width_warning = FALSE;
  322.  
  323.     configflag = TRUE;
  324.     win[w].flags &= ~(XFLEX|YFLEX);
  325.     wp = win[w].wptr;
  326.     if (wcols(wp) == COLS)
  327.     win[w].flags |= XFLEX;
  328.     if (wlines(wp) == LINES-1)
  329.     win[w].flags |= YFLEX;
  330.     WObscure();        /* recompute obscured window info */
  331.     if (!(win[w].flags&FAST)) {
  332.     if (wcols(wp) != COLS) {
  333.         showmsg("\007Non full-width window #%d will scroll slowly!", w);
  334.         return;
  335.     }
  336.     if (full_width_warning)
  337.         return;
  338.     full_width_warning = TRUE;
  339.     showmsg("\007This terminal scrolls split-screen windows slowly.");
  340.     }
  341. }
  342.