home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume25 / screen3 / part03 / help.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-18  |  12.6 KB  |  520 lines

  1. /* Copyright (c) 1991
  2.  *      Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
  3.  *      Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
  4.  * Copyright (c) 1987 Oliver Laumann
  5.  *
  6.  * This program is free software; you can redistribute it and/or modify
  7.  * it under the terms of the GNU General Public License as published by
  8.  * the Free Software Foundation; either version 1, or (at your option)
  9.  * any later version.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program (see the file COPYING); if not, write to the
  18.  * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  *
  20.  * Noteworthy contributors to screen's design and implementation:
  21.  *    Wayne Davison (davison@borland.com)
  22.  *    Patrick Wolfe (pat@kai.com, kailand!pat)
  23.  *    Bart Schaefer (schaefer@cse.ogi.edu)
  24.  *    Nathan Glasser (nathan@brokaw.lcs.mit.edu)
  25.  *    Larry W. Virden (lwv27%cas.BITNET@CUNYVM.CUNY.Edu)
  26.  *    Howard Chu (hyc@hanauma.jpl.nasa.gov)
  27.  *    Tim MacKenzie (tym@dibbler.cs.monash.edu.au)
  28.  *    Markku Jarvinen (mta@{cc,cs,ee}.tut.fi)
  29.  *    Marc Boucher (marc@CAM.ORG)
  30.  *
  31.  ****************************************************************
  32.  */
  33.  
  34. #ifndef lint
  35.   static char rcs_id[] = "$Id: help.c,v 1.42 91/10/11 11:42:09 jnweiger Exp $ FAU";
  36. #endif
  37.  
  38. #include "config.h"
  39. #include <stdio.h>
  40. #include <sys/types.h>
  41. #if defined(BSD) || defined(sequent) || defined(pyr)
  42. # include <strings.h>
  43. #else
  44. # include <string.h>
  45. #endif
  46.  
  47. #include "screen.h"
  48. #include "ansi.h"
  49. #include "extern.h"
  50. #include "patchlevel.h"
  51.  
  52. int help_page = 0;
  53. int command_search, command_bindings = 0;
  54. extern char Esc, MetaEsc;
  55. extern char *KeyNames[];
  56. extern struct key ktab[];
  57. extern int screenwidth, screenheight;
  58. extern char *blank, *null, *CE;
  59. extern struct win *fore;
  60.  
  61. static void centerline __P((char *));
  62. static void HelpRedisplayLine __P((int, int, int, int));
  63. static void process_help_input __P((char **, int *));
  64. static void AbortHelp __P((void));
  65. static void add_key_to_buf __P((char *, int));
  66.  
  67. void
  68. exit_with_usage(myname)
  69. char *myname;
  70. {
  71.   printf("Use: %s [-opts] [cmd [args]]\n", myname);
  72.   printf(" or: %s -r [host.tty]\n\nOptions:\n", myname);
  73.   printf("-a           Force all capabilities into each window's termcap\n");
  74.   printf("-A -[r|R]    Adapt all windows to the new display width & height\n");
  75.   printf("-c file      Read configuration file instead of .screenrc\n");
  76. #ifdef REMOTE_DETACH
  77.   printf("-d (-r)      Detach the elsewhere running screen (and reattach here)\n");
  78.   printf("-D (-r)      Detach and logout remote (and reattach here)\n");
  79. #endif
  80.   printf("-e xy        Change command characters\n");
  81.   printf("-f           Flow control on, -fn = off, -fa = auto\n");
  82.   printf("-h lines     Set the size of the scrollback history buffer\n");
  83.   printf("-i           Interrupt output sooner when flow control is on\n");
  84.   printf("-l           Login mode on (update /etc/utmp), -ln = off\n");
  85.   printf("-list        or -ls. Do nothing, just list our SockDir\n");
  86.   printf("-L           Terminal's last character can be safely updated\n");
  87.   printf("-O           Choose optimal output rather than exact vt100 emulation\n");
  88.   printf("-q           Quiet startup. Sets $status if unsuccessful.\n");
  89.   printf("-r           Reattach to a detached screen process\n");
  90.   printf("-R           Reattach if possible, otherwise start a new session\n");
  91.   printf("-s shell     Shell to execute rather than $SHELL\n");
  92.   printf("-T term      Use term as $TERM for windows, rather than \"screen\"\n");
  93.   printf("-t title     Set command's a.k.a. (window title)\n");
  94.   printf("-wipe        Do nothing, just clean up SockDir\n");
  95.   exit(1);
  96. }
  97.  
  98. /* Esc-char is not consumed. All others are. Esc-char, space, and return end */
  99. static void
  100. process_help_input(ppbuf, plen)
  101. char **ppbuf;
  102. int *plen;
  103. {
  104.   int done = 0;
  105.  
  106.   if (ppbuf == 0)
  107.     {
  108.       AbortHelp();
  109.       return;
  110.     }
  111.   while (!done && *plen > 0)
  112.     {
  113.       switch (**ppbuf)
  114.     {
  115.     case ' ':
  116.       if (display_help() == 0)
  117.             break;
  118.       /* FALLTHROUGH */
  119.     case '\r':
  120.     case '\n':
  121.       done = 1;
  122.       break;
  123.     default:
  124.       if (**ppbuf == Esc)
  125.         {
  126.           done = 1;
  127.           continue;
  128.         }
  129.       break;
  130.     }
  131.       ++*ppbuf;
  132.       --*plen;
  133.     }
  134.   if (done)
  135.     AbortHelp();
  136. }
  137.  
  138. static void
  139. AbortHelp()
  140. {
  141.   help_page = 0;
  142.   ExitOverlayPage();
  143.   Activate();
  144. }
  145.  
  146. static int maxrow, grow, numcols, numrows, num_names;
  147. static int numskip, numpages;
  148.  
  149. int
  150. display_help()
  151. {
  152.   int col, crow, n, key = 0;
  153.   enum keytype typ = ktab[0].type;
  154.   char buf[256], Esc_buf[5], cbuf[256];
  155.  
  156.   if (!help_page++)
  157.     {
  158.       if (screenwidth < 26 || screenheight < 6)
  159.         {
  160.       Msg(0, "Window size too small for help page");
  161.       help_page = 0;
  162.       return -1;
  163.         }
  164.       InitOverlayPage(process_help_input, HelpRedisplayLine, 0, 0);
  165.  
  166.       command_bindings = 0;
  167.       for (key = 0; key < 256; key++)
  168.         if ((typ = ktab[key].type) == KEY_CREATE
  169.         || typ == KEY_SCREEN
  170.         || typ == KEY_SET
  171.         || (typ == KEY_AKA && ktab[key].args))
  172.       command_bindings++;
  173.       debug1("help: command_bindings counted: %d\n",command_bindings);
  174.       for (n = 0; KeyNames[n] != NULL; n++)
  175.     ; /* we dont know "sizeof * KeyNames" */
  176.       num_names = n - 1;
  177.       debug1("help: we find %d named keys (+1).\n", num_names);
  178.       command_search = 0;
  179.  
  180.       numcols = screenwidth/26;
  181.       if (numcols == 0)
  182.         numcols = 1;
  183.       numrows = (num_names + numcols -1) / numcols;
  184.       debug1("Numrows: %d\n", numrows);
  185.       numskip = screenheight-5 - (2 + numrows);
  186.       while (numskip < 0)
  187.     numskip += screenheight-5;
  188.       numskip %= screenheight-5;
  189.       debug1("Numskip: %d\n", numskip);
  190.       if (numskip > screenheight/3 || numskip > command_bindings)
  191.     numskip = 1;
  192.       maxrow = 2 + numrows + numskip + command_bindings;
  193.       grow = 0;
  194.  
  195.       numpages = (maxrow + screenheight-6) / (screenheight-5);
  196.     }
  197.  
  198.   if (grow >= maxrow)
  199.     { 
  200.       return(-1);
  201.     }
  202.  
  203.   /* Clear the help screen */
  204.   ClearDisplay();
  205.   
  206.   sprintf(cbuf,"Screen key bindings, page %d of %d.", help_page, numpages);
  207.   centerline(cbuf);
  208.   printf("\n");
  209.   crow = 2;
  210.  
  211.   *Esc_buf = '\0';
  212.   add_key_to_buf(Esc_buf, Esc);
  213.   Esc_buf[strlen(Esc_buf) - 1] = '\0';
  214.  
  215.   for (; crow < screenheight - 3; crow++)
  216.     {
  217.       if (grow < 1)
  218.         {
  219.          *buf = '\0';
  220.           add_key_to_buf(buf, MetaEsc);
  221.           buf[strlen(buf) - 1] = '\0';
  222.           sprintf(cbuf,"Command key:  %s   Literal %s:  %s", Esc_buf, Esc_buf, buf);
  223.           centerline(cbuf);
  224.       grow++;
  225.         }
  226.       else if (grow >= 2 && grow-2 < numrows)
  227.     {
  228.       for (col = 0; col < numcols && (n = numrows * col + (grow-2)) < num_names; col++)
  229.         {
  230.           debug1("help: searching key %d\n", n);
  231.           buf[0] = '\0';
  232.           for (key = 0; key < 128; key++)
  233.         if (ktab[key].type == (enum keytype) (n + 2)
  234.             && ((enum keytype) (n + 2) != KEY_AKA || !ktab[key].args) )
  235.           add_key_to_buf(buf, key);
  236.           buf[14] = '\0';
  237.           /*
  238.            * Format is up to 10 chars of name, 1 spaces, 14 chars of key
  239.            * bindings, and a space.
  240.            */
  241.           printf("%-10.10s %-14.14s ", KeyNames[n + 1], buf);
  242.         }
  243.       printf("\r\n");
  244.           grow++;
  245.         }
  246.       else if (grow-2-numrows >= numskip 
  247.                && grow-2-numrows-numskip < command_bindings)
  248.         {
  249.           char **pp, *cp;
  250.  
  251.       while (command_search < 128
  252.          && (typ = ktab[command_search].type) != KEY_CREATE
  253.          && typ != KEY_SCREEN
  254.          && typ != KEY_SET
  255.          && (typ != KEY_AKA || !ktab[command_search].args))
  256.         command_search++;
  257.       buf[0] = '\0';
  258.       add_key_to_buf(buf, command_search);
  259.       printf("%-4s", buf);
  260.       col = 4;
  261.       if (typ != KEY_CREATE)
  262.         {
  263.           col += strlen(KeyNames[(int)typ - 1]) + 1;
  264.           printf("%s ", KeyNames[(int)typ - 1]);
  265.         }
  266.       pp = ktab[command_search++].args;
  267.       while (pp && (cp = *pp) != NULL)
  268.         {
  269.           if (!*cp || (index(cp, ' ') != NULL))
  270.         {
  271.           if (index(cp, '\'') != NULL)
  272.             *buf = '"';
  273.           else
  274.             *buf = '\'';
  275.           sprintf(buf + 1, "%s%c", cp, *buf);
  276.           cp = buf;
  277.         }
  278.           if ((col += (unsigned)strlen(cp) + 1) >= screenwidth)
  279.         {
  280.           col = screenwidth - (col - (strlen(cp) + 1)) - 2;
  281.           if (col >= 0)
  282.             {
  283.               n = cp[col];
  284.               cp[col] = '\0';
  285.               printf("%s$", *pp);
  286.               cp[col] = (char) n;
  287.               }
  288.               break;
  289.             }
  290.           printf("%s%c", cp, (screenwidth - col != 1 || !pp[1]) ? ' ' : '$');
  291.           pp++;
  292.         }
  293.       printf("\r\n");
  294.       grow++;
  295.     }
  296.       else
  297.     {
  298.           putchar('\n');
  299.       grow++;
  300.     }
  301.     }
  302.   printf("\n");
  303.   sprintf(cbuf,"[Press Space %s Return to end; %s to begin a command.]",
  304.      grow < maxrow ? "for next page;" : "or", Esc_buf);
  305.   centerline(cbuf);
  306.   fflush(stdout);
  307.   SetLastPos(0, screenheight-1);
  308.   return(0);
  309. }
  310.  
  311. static void
  312. add_key_to_buf(buf, key)
  313. char *buf;
  314. int key;
  315. {
  316.   debug1("help: key found: %c\n", key);
  317.   switch (key)
  318.     {
  319.     case ' ':
  320.       strcat(buf, "sp ");
  321.       break;
  322.     case 0x7f:
  323.       strcat(buf, "^? ");
  324.       break;
  325.     default:
  326.       if (key < ' ')
  327.     sprintf(buf + strlen(buf), "^%c ", (key | 0x40));
  328.       else
  329.     sprintf(buf + strlen(buf), "%c ", key);
  330.       break;
  331.     }
  332. }
  333.  
  334. static void
  335. centerline(str)
  336. char *str;
  337. {
  338.   int l;
  339.   l = (screenwidth - 1 + (unsigned)strlen(str)) / 2;
  340.   if (l > screenwidth - 1)
  341.     l = screenwidth - 1;
  342.   printf("%*.*s\r\n", l, l, str);
  343. }
  344.  
  345. static void
  346. HelpRedisplayLine(y, xs, xe, isblank)
  347. int y, xs, xe, isblank;
  348. {
  349.   if (isblank)
  350.     return;
  351.   if (CE)
  352.     {
  353.       GotoPos(xs, y);
  354.       PutStr(CE);
  355.       return;
  356.     }
  357.   DisplayLine(null, null, null, blank, null, null, y, xs, xe);
  358. }
  359.  
  360. /*
  361.  * here all the copyright stuff 
  362.  */
  363.  
  364.  
  365. static char version[40];
  366.  
  367. static char cpmsg[] = "\
  368. \n\
  369. iScreen version %v\n\
  370. \n\
  371. Copyright (c) 1991\n\
  372.     Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)\n\
  373.     Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)\n\
  374. Copyright (c) 1987 Oliver Laumann\n\
  375. \n\
  376. This program is free software; you can redistribute it and/or \
  377. modify it under the terms of the GNU General Public License as published \
  378. by the Free Software Foundation; either version 1, or (at your option) \
  379. any later version.\n\
  380. \n\
  381. This program is distributed in the hope that it will be useful, \
  382. but WITHOUT ANY WARRANTY; without even the implied warranty of \
  383. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the \
  384. GNU General Public License for more details.\n\
  385. \n\
  386. You should have received a copy of the GNU General Public License \
  387. along with this program (see the file COPYING); if not, write to the \
  388. Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n";
  389.  
  390.  
  391. static void process_copyright_input __P((char **, int *));
  392. static void AbortCopyright __P((void));
  393. static void copypage __P((void));
  394.  
  395. static char *cps, *savedcps;
  396.  
  397. static void
  398. process_copyright_input(ppbuf, plen)
  399. char **ppbuf;
  400. int *plen;
  401. {
  402.   int done = 0;
  403.  
  404.   if (ppbuf == 0)
  405.     {
  406.       AbortCopyright();
  407.       return;
  408.     }
  409.   while (!done && *plen > 0)
  410.     {
  411.       switch (**ppbuf)
  412.     {
  413.     case ' ':
  414.           if (*cps)
  415.         {
  416.           copypage();
  417.           break;
  418.         }
  419.       /* FALLTHROUGH */
  420.     case '\r':
  421.     case '\n':
  422.       AbortCopyright();
  423.       done = 1;
  424.       break;
  425.     default:
  426.       break;
  427.     }
  428.       ++*ppbuf;
  429.       --*plen;
  430.     }
  431. }
  432.  
  433. static void
  434. AbortCopyright()
  435. {
  436.   ExitOverlayPage();
  437.   Activate();
  438. }
  439.  
  440. void
  441. display_copyright()
  442. {
  443.   if (screenwidth < 10 || screenheight < 5)
  444.     {
  445.       Msg(0, "Window size too small for copyright page");
  446.       return;
  447.     }
  448.   InitOverlayPage(process_copyright_input, HelpRedisplayLine, 0, 0);
  449.   sprintf(version, "%d.%.2d.%.2d%s (%s) %s", REV, VERS, PATCHLEVEL, STATE, ORIGIN, DATE);
  450.   cps = cpmsg;
  451.   savedcps = 0;
  452.   copypage();
  453. }
  454.  
  455.  
  456. static void
  457. copypage()
  458. {
  459.   char *ws;
  460.   int x, y, l;
  461.   char cbuf[80];
  462.  
  463.   ClearDisplay();
  464.   x = y = 0;
  465.   while(*cps)
  466.     {
  467.       ws = cps;
  468.       while (*cps == ' ')
  469.     cps++;
  470.       if (strncmp(cps, "%v", 2) == 0)
  471.     {
  472.       savedcps = cps + 2;
  473.       ws = cps = version;
  474.     }
  475.       while (*cps && *cps != ' ' && *cps != '\n')
  476.     cps++;
  477.       l = cps - ws;
  478.       cps = ws;
  479.       if (l > screenwidth - 1)
  480.     l = screenwidth - 1;
  481.       if (x && x + l >= screenwidth - 2)
  482.     {
  483.       printf("\r\n");
  484.       x = 0;
  485.       if (++y > screenheight - 4)
  486.             break;
  487.     }
  488.       if (x)
  489.     {
  490.       putchar(' ');
  491.       x++;
  492.     }
  493.       printf("%*.*s", l, l, ws);
  494.       x += l;
  495.       cps += l;
  496.       if (*cps == 0 && savedcps)
  497.     {
  498.       cps = savedcps;
  499.       savedcps = 0;
  500.     }
  501.       if (*cps == '\n')
  502.     {
  503.       printf("\r\n");
  504.       x = 0;
  505.       if (++y > screenheight - 4)
  506.             break;
  507.     }
  508.       if (*cps == ' ' || *cps == '\n')
  509.     cps++;
  510.     }
  511.   while (y++ < screenheight - 2)
  512.     printf("\r\n");
  513.   sprintf(cbuf,"[Press Space %s Return to end.]",
  514.      *cps ? "for next page;" : "or");
  515.   centerline(cbuf);
  516.   fflush(stdout);
  517.   SetLastPos(0, screenheight-1);
  518. }
  519.   
  520.