home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / prgramer / unix / emx / test / wm_test.c < prev   
Encoding:
C/C++ Source or Header  |  1992-12-25  |  20.7 KB  |  776 lines

  1. /* wm_test.c (emx+gcc) */
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <sys/video.h>
  7. #include <sys/winmgr.h>
  8. #include <sys/kbdscan.h>
  9.  
  10. #define FALSE 0
  11. #define TRUE  1
  12.  
  13. #define MAX_WINDOWS 100
  14. #define PUTSA_LEN 20
  15.  
  16. extern char *_v_mem;
  17.  
  18. static wm_handle w[MAX_WINDOWS];
  19. static int c, top, sel, n, windows, auto_mode, auto_win;
  20. static int width, height;
  21. static char auto_c;
  22. static wm_handle helpw = NULL;
  23. static int move_flag;
  24. static int counter = 1;
  25. static int title_flag, wrap_flag;
  26. static int cursor_flag;
  27. static int putca_flag;
  28. static int find_x, find_y;
  29. static char putsa_str[2*PUTSA_LEN] =
  30. {
  31.   'H', 7, 'e', 6, 'l', 5, 'l', 4, 'o', 3, '*', 0,
  32.   'w', 7, 'i', 6, 'n', 5, 'd', 4, 'o', 3, 'w', 2, '*', 0,
  33.   'm', 7, 'a', 6, 'n', 5, 'a', 4, 'g', 3, 'e', 2, 'r', 1
  34. };
  35.  
  36.  
  37. char buffer[22];
  38.  
  39. static void error (const char *msg)
  40. {
  41.   printf ("\n%s\n\a", msg);
  42.   exit (1);
  43. }
  44.  
  45.  
  46. static int last_key = -1;
  47.  
  48. static int getch (void)
  49. {
  50.   int c;
  51.  
  52.   if (last_key >= 0)
  53.     {
  54.       c = last_key;
  55.       last_key = -1;
  56.     }
  57.   else
  58.     c = _read_kbd (0, 1, 0);
  59.   return (c);
  60. }
  61.  
  62.  
  63. static int ready (void)
  64. {
  65.   if (last_key < 0)
  66.     last_key = _read_kbd (0, 0, 0);
  67.   return (last_key >= 0);
  68. }
  69.  
  70.  
  71. static void beep (int f, int d)
  72. {
  73.   putchar ('\a');
  74. }
  75.  
  76.  
  77. static void move (int xi, int yi)
  78. {
  79.   int x, y;
  80.  
  81.   if (move_flag)
  82.     {
  83.       wm_get_pos (w[sel], &x, &y);
  84.       wm_move (w[sel], x+xi, y+yi);
  85.     }
  86.   else
  87.     {
  88.       wm_getxy (w[sel], &x, &y);
  89.       wm_gotoxy (w[sel], x+xi, y+yi);
  90.     }
  91. }
  92.  
  93.  
  94. static void disp (void)
  95. {
  96.   if (w[1] != NULL)
  97.     {
  98.       wm_gotoxy (w[1], 0, 14);
  99.       wm_printf (w[1], "Selected: %2d, top: %2d, counter: %2d",
  100.                  sel, top, counter);
  101.     }
  102. }
  103.  
  104.  
  105. static void disp_move (void)
  106. {
  107.   int a;
  108.  
  109.   if (w[1] != NULL)
  110.     {
  111.       a = wm_get_attrib (w[1]);
  112.       if (!move_flag)
  113.         wm_attrib (w[1], F_BLUE|B_BLACK|INTENSITY);
  114.       else
  115.         wm_attrib (w[1], F_WHITE|B_BLACK);
  116.       wm_puts_at (w[1], 15, 13, "cursor");
  117.       wm_attrib (w[1], a);
  118.       wm_puta_at (w[1], 24, 13,
  119.                   move_flag ? F_BLUE|B_BLACK|INTENSITY : F_WHITE|B_BLACK,
  120.                   6);
  121.     }
  122. }
  123.  
  124.  
  125. static void help_clear (void)
  126. {
  127.   if (helpw != NULL)
  128.     {
  129.       wm_clear (helpw);
  130.       wm_gotoxy (helpw, 0, 0);
  131.     }
  132. }
  133.  
  134.  
  135. static void help_disp (const char *s)
  136. {
  137.   if (helpw != NULL)
  138.     wm_puts (helpw, s);
  139. }
  140.  
  141.  
  142. static void help_open (void)
  143. {
  144.   helpw = wm_create (20, 8, 60, 16, ' ', B_RED|F_BLACK,
  145.                      F_BLUE|B_BLACK|INTENSITY);
  146.   if (helpw != NULL)
  147.     wm_open (helpw);
  148. }
  149.  
  150.  
  151. static void help_close (void)
  152. {
  153.   if (helpw != NULL)
  154.     {
  155.       wm_close (helpw);
  156.       wm_delete (helpw);
  157.       helpw = NULL;
  158.     }
  159. }
  160.  
  161.  
  162. static int get_xy (int *xx, int *yy, int minx, int maxx, int miny, int maxy)
  163. {
  164.   int c;
  165.   int x, y;
  166.  
  167.   x = *xx; y = *yy;
  168.   wm_chide (FALSE);
  169.   do
  170.     {
  171.       v_gotoxy (x, y);
  172.       c = getch ();
  173.       switch (c)
  174.         {
  175.         case 0:
  176.           switch (getch ())
  177.             {
  178.             case K_UP:
  179.               if (y >= miny+1)
  180.                 --y;
  181.               break;
  182.             case K_DOWN:
  183.               if (y <= maxy-1)
  184.                 ++y;
  185.               break;
  186.             case K_LEFT:
  187.               if (x >= minx+1)
  188.                 --x;
  189.               break;
  190.             case K_RIGHT:
  191.               if (x <= maxx-1)
  192.                 ++x;
  193.               break;
  194.             case K_PAGEUP:
  195.               if (y >= miny+4)
  196.                 y -= 4;
  197.               else
  198.                 y = miny;
  199.               break;
  200.             case K_PAGEDOWN:
  201.               if (y <= maxy-4)
  202.                 y += 4;
  203.               else
  204.                 y = maxy;
  205.               break;
  206.             case K_CTRL_LEFT:
  207.               if (x >= minx+8)
  208.                 x -= 8;
  209.               else
  210.                 x = minx;
  211.               break;
  212.             case K_CTRL_RIGHT:
  213.               if (x <= maxx-8)
  214.                 x += 8;
  215.               else
  216.                 x = maxx;
  217.               break;
  218.             case K_HOME:
  219.               x = minx;
  220.               break;
  221.             case K_END:
  222.               x = maxx;
  223.               break;
  224.             case K_CTRL_HOME:
  225.             case K_CTRL_PAGEUP:
  226.               y = miny;
  227.               break;
  228.             case K_CTRL_END:
  229.             case K_CTRL_PAGEDOWN:
  230.               y = maxy;
  231.               break;
  232.             }
  233.           break;
  234.         case 0x1b:
  235.           wm_chide (cursor_flag);
  236.           return (FALSE);
  237.         }
  238.     } while (c != '\r');
  239.   *xx = x; *yy = y;
  240.   wm_chide (cursor_flag);
  241.   return (TRUE);
  242. }
  243.  
  244.  
  245. static int get_attr (int *dst)
  246. {
  247.   int color[2];
  248.   int i, intens, c;
  249.  
  250.   for (i = 0; i < 2; ++i)
  251.     {
  252.       if (i == 0)
  253.         help_disp ("Background color");
  254.       else
  255.         help_disp ("Foreground color");
  256.       help_disp (" (0..7): ");
  257.       do
  258.         {
  259.           c = getch ();
  260.           if (c == 0x1b)
  261.             return (FALSE);
  262.         } while (c < '0' || c > '7');
  263.       color[i] = c-'0';
  264.       if (helpw != NULL)
  265.         {
  266.           wm_putc (helpw, (char)c);
  267.           wm_putc (helpw, '\n');
  268.         }
  269.     }
  270.   help_disp ("Intensified or Normal:");
  271.   intens = -1;
  272.   do
  273.     {
  274.       c = getch ();
  275.       switch (c)
  276.         {
  277.         case 0x1b:
  278.           return (FALSE);
  279.         case 'i':
  280.         case 'I':
  281.           intens = 8;
  282.           break;
  283.         case 'n':
  284.         case 'N':
  285.           intens = 0;
  286.           break;
  287.         }
  288.     } while (intens < 0);
  289.   if (helpw != NULL)
  290.     {
  291.       wm_putc (helpw, (char)c);
  292.       wm_putc (helpw, '\n');
  293.     }
  294.   *dst = 16*color[0]+color[1]+intens;
  295.   return (TRUE);
  296. }
  297.  
  298.  
  299. static void new_window (void)
  300. {
  301.   int x0, y0, x, y, border, battr, wattr, c;
  302.   wm_handle neww;
  303.  
  304.   if (windows >= MAX_WINDOWS)
  305.     return;
  306.   help_open ();
  307.   help_clear ();
  308.   help_disp ("Use arrow keys to move cursor\n");
  309.   help_disp ("to upper left corner of the \n");
  310.   help_disp ("new window, then press return.");
  311.   x0 = 0; y0 = 0;
  312.   if (!get_xy (&x0, &y0, 0, width-11, 0, height-5))
  313.     {
  314.       help_close ();
  315.       return;
  316.     }
  317.   help_clear ();
  318.   help_disp ("Use arrow keys to move cursor\n");
  319.   help_disp ("to lower right corner of the\n");
  320.   help_disp ("new window, then press return.");
  321.   x = x0+9; y = y0+3;
  322.   if (!get_xy (&x, &y, x, width-1, y, height-1))
  323.     {
  324.       help_close ();
  325.       return;
  326.     }
  327.   help_clear ();
  328.   help_disp ("Enter border style:\n");
  329.   help_disp ("            ┌─┐     ╔═╗     ╒═╕     ╓─╖\n");
  330.   help_disp ("F10=none F1=└─┘  F2=╚═╝  F3=╘═╛  F4=╙─╜\n");
  331.   help_disp ("Any other character is used as\n");
  332.   help_disp ("border character\n");
  333.   border = -1;
  334.   do
  335.     {
  336.       c = getch ();
  337.       switch (c)
  338.         {
  339.         case 0:
  340.           c = getch ();
  341.           switch (c)
  342.             {
  343.             case K_F10:
  344.               border = 0;
  345.               break;
  346.             case K_F1:
  347.               border = 1;
  348.               break;
  349.             case K_F2:
  350.               border = 2;
  351.               break;
  352.             case K_F3:
  353.               border = 3;
  354.               break;
  355.             case K_F4:
  356.               border = 4;
  357.               break;
  358.             }
  359.           break;
  360.         case 0x1b:
  361.           help_close ();
  362.           return;
  363.         default:
  364.           border = c;
  365.           break;
  366.         }
  367.     } while (border < 0);
  368.   if (border != 0)
  369.     {
  370.       help_clear ();
  371.       help_disp ("Border attribute:\n");
  372.       if (!get_attr (&battr))
  373.         {
  374.           help_close ();
  375.           return;
  376.         }
  377.     }
  378.   help_clear ();
  379.   help_disp ("Text attribute:\n");
  380.   if (!get_attr (&wattr))
  381.     {
  382.       help_close ();
  383.       return;
  384.     }
  385.   help_close ();
  386.   neww = wm_create (x0, y0, x, y, border, battr, wattr);
  387.   if (neww != NULL)
  388.     {
  389.       sel = windows;
  390.       w[windows++] = neww;
  391.       disp ();
  392.     }
  393. }
  394.  
  395.  
  396. static void do_putc (int win, char c)
  397. {
  398.   if (putca_flag)
  399.     wm_putca (w[win], c, BW_REVERSE);
  400.   else
  401.     wm_putc (w[win], c);
  402. }
  403.  
  404.  
  405. static void do_auto (void)
  406. {
  407.   if (auto_win >= windows)
  408.     auto_win = 0;
  409.   if (auto_win == 1)
  410.     ++auto_win;
  411.   if (auto_win < windows && w[auto_win] != NULL)
  412.     {
  413.       do_putc (auto_win, auto_c);
  414.       if (auto_c >= (char)126)
  415.         auto_c = ' ';
  416.       else
  417.         ++auto_c;
  418.     }
  419.   ++auto_win;
  420. }
  421.  
  422.  
  423. static int rnd_attr (int old)
  424. {
  425.   int f, b, i, a;
  426.  
  427.   do
  428.     {
  429.       f = rand () % 8;
  430.       b = rand () % 8;
  431.       i = rand () % 2;
  432.       a = f+i*8+b*16;
  433.     } while ((f == b && i == 0) || a == old);
  434.   return (a);
  435. }
  436.  
  437.  
  438. static void rnd_window (void)
  439. {
  440.   wm_handle neww;
  441.   int x0, y0, x1, y1, border, battr, wattr;
  442.  
  443.   do
  444.     {
  445.       x0 = rand () % width; x1 = rand () % width;
  446.       y0 = rand () % height; y1 = rand () % height;
  447.     } while (x0+x1 >= width || y0+y1 >= height || x1 < 1 || y1 < 1);
  448.   border = rand () % 5;
  449.   battr = rnd_attr (0);
  450.   wattr = rnd_attr (battr);
  451.   if (windows < MAX_WINDOWS)
  452.     {
  453.       neww = wm_create (x0, y0, x0+x1, y0+y1, border, battr, wattr);
  454.       if (neww != NULL)
  455.         {
  456.           sel = windows;
  457.           w[windows++] = neww;
  458.           wm_open (neww);
  459.           wm_cursor (neww);
  460.           disp ();
  461.         }
  462.     }
  463. }
  464.  
  465.  
  466. static void make_top (void)
  467. {
  468.   do
  469.     {
  470.       ++top;
  471.       if (top >= windows)
  472.         top = 0;
  473.     } while (w[top] == NULL);
  474.   wm_top (w[top]);
  475.   disp ();
  476. }
  477.  
  478.  
  479. static void next_window (void)
  480. {
  481.   do
  482.     {
  483.       ++sel;
  484.       if (sel >= windows)
  485.         sel = 0;
  486.     } while (w[sel] == NULL);
  487.   wm_cursor (w[sel]);
  488.   disp ();
  489. }
  490.  
  491.  
  492. int main (int argc, char *argv[])
  493. {
  494.   int i, x, y, a, f, no_mem_flag;
  495.  
  496.   no_mem_flag = 0;
  497.   if (argc == 2 && strcmp (argv[1], "-n") == 0)
  498.     no_mem_flag = 1;
  499.   auto_mode = FALSE; move_flag = 0; helpw = NULL;
  500.   title_flag = TRUE; wrap_flag = TRUE; cursor_flag = TRUE;
  501.   strcpy (buffer, "<No input>");
  502.   v_init (); v_dimen (&width, &height);
  503.   find_x = width/2; find_y = height/2;
  504.   if (!wm_init (MAX_WINDOWS))
  505.     error ("wm_init failed");
  506.   if (no_mem_flag)
  507.     _v_mem = NULL;
  508.   windows = 9; counter = 1;
  509.   w[0] = wm_create (10, 5, 60, 15, 3, B_BLACK|F_GREEN, B_BLACK|F_WHITE);
  510.   w[1] = wm_create (15, 9, 65, 23, 1, B_BLACK|F_CYAN, B_BLACK|F_WHITE);
  511.   w[2] = wm_create (0, 0, 14, 13, 2, B_CYAN|F_RED, B_CYAN|F_WHITE|INTENSITY);
  512.   w[3] = wm_create (-10, -10, 100, 30, 2, B_BROWN|F_YELLOW|INTENSITY,
  513.                     B_GREEN|F_YELLOW|INTENSITY);
  514.   w[4] = wm_create (30, 18, 55, 23, 0, B_BLACK|F_WHITE,
  515.                     B_GREEN|F_WHITE|INTENSITY);
  516.   w[5] = wm_create (25, 8, 70, 18, 2, B_BLACK|F_YELLOW, B_BLACK|F_RED);
  517.   w[6] = wm_create (0, 19, 14, 24, 2, B_CYAN|F_RED, B_CYAN|F_WHITE|INTENSITY);
  518.   w[7] = wm_create (60, 0, 79, 13, 2, B_CYAN|F_RED, B_CYAN|F_WHITE|INTENSITY);
  519.   w[8] = wm_create (60, 19, 79, 24, 4, B_CYAN|F_RED, B_CYAN|F_WHITE|INTENSITY);
  520.   for (i = 0; i < windows; ++i)
  521.     if (w[i] == NULL)
  522.       error ("wm_create failed");
  523.   top = 1; sel = 0;
  524.   wm_top (w[top]);
  525.   for (i = 0; i < windows; i++)
  526.     if (i != 3)
  527.       wm_open (w[i]);
  528.   wm_puts (w[1], "Esc #Q #A Quit; wm_close_all; set attribute\n");
  529.   wm_puts (w[1], "#T ^Pg Pg Next to top; top/bottom; up/down\n");
  530.   wm_puts (w[1], "^F ^B     Forward/back one window (select)\n");
  531.   wm_puts (w[1], "#O #C #F  Open/close current window; find\n");
  532.   wm_puts (w[1], "^D #B     Delete current window; change border\n");
  533.   wm_puts (w[1], "#S ^L #G  Clr window; clr to eol; wm_attrib_all\n");
  534.   wm_puts (w[1], "^H ^I ^E  Backspace; input/display string\n");
  535.   wm_puts (w[1], "F2 F3 F4  Cursor mode; Cursor off/on\n");
  536.   wm_puts (w[1], "^A ^N ^R  Auto mode; create new/random window\n");
  537.   wm_puts (w[1], "Ins Del   Insert/delete character\n");
  538.   wm_puts (w[1], "#I #D     Insert/delete line\n");
  539.   wm_puts (w[1], "#P #M #W  Inc/dec counter; toggle wrap\n");
  540.   wm_puts (w[1], "F5 F6 F7  wm_putc[a]; update false; true\n");
  541.   wm_puts (w[1], "Arrows    Move cursor / window (F1)\n");
  542.   wm_putc_at (w[6], 1, 1, '1');
  543.   wm_putca_at (w[6], 2, 2, '2', BW_REVERSE);
  544.   wm_gotoxy (w[7], 8, 1);
  545.   wm_putsa (w[7], putsa_str, PUTSA_LEN);
  546.   wm_putsa_at (w[7], 8, 4, putsa_str, PUTSA_LEN);
  547.   wm_putsa_at (w[7], 8, 13, putsa_str, PUTSA_LEN);
  548.   disp_move ();
  549.   wm_attrib (w[1], B_RED|F_YELLOW|INTENSITY);
  550.   wm_cursor (w[sel]);
  551.   disp ();
  552.   do
  553.     {
  554.       while (!ready ())
  555.         {
  556.           if (auto_mode)
  557.             do_auto ();
  558.         }
  559.       c = getch ();
  560.       if (auto_mode)
  561.         wm_cursor (w[sel]);
  562.       switch (c)
  563.         {
  564.         case 0:
  565.           switch (getch ())
  566.             {
  567.             case K_ALT_A:                                          /* Alt-A */
  568.               help_open ();
  569.               help_clear ();
  570.               help_disp ("New attribute:\n");
  571.               if (get_attr (&a))
  572.                 wm_attrib (w[sel], a);
  573.               help_close ();
  574.               break;
  575.             case K_ALT_B:                                          /* Alt-B */
  576.               f = getch ();
  577.               if (f == 0) getch ();
  578.               a = getch ();
  579.               if (a == 0) getch ();
  580.               wm_border (w[sel], f, a, buffer, title_flag, 15);
  581.               title_flag = !title_flag;
  582.               break;
  583.             case K_ALT_C:                                          /* Alt-C */
  584.               wm_close (w[sel]);
  585.               break;
  586.             case K_ALT_D:                                          /* Alt-D */
  587.               wm_del_line (w[sel], wm_gety (w[sel]), counter);
  588.               break;
  589.             case K_ALT_F:                                          /* Alt-F */
  590.               if (get_xy (&find_x, &find_y, 0, width-1, 0, height-1))
  591.                 {
  592.                   wm_handle wh;
  593.                   int i, wx, wy;
  594.  
  595.                   wh = wm_find (find_x, find_y);
  596.                   if (wh == NULL)
  597.                     beep (880, 200);
  598.                   else
  599.                     {
  600.                       for (i = 0; i < windows; ++i)
  601.                         if (w[i] == wh)
  602.                           break;
  603.                       if (i >= windows)
  604.                         beep (440, 400);
  605.                       else
  606.                         {
  607.                           wm_get_pos (wh, &wx, &wy);
  608.                           wm_putc_at (wh, find_x-wx, find_y-wy, '*');
  609.                         }
  610.                     }
  611.                 }
  612.               break;
  613.             case K_ALT_G:                                          /* Alt-G */
  614.               wm_attrib_all (w[sel], wm_get_attrib (w[sel]));
  615.               break;
  616.             case K_ALT_I:                                          /* Alt-I */
  617.               wm_ins_line (w[sel], wm_gety (w[sel]), counter);
  618.               break;
  619.             case K_ALT_M:                                          /* Alt-M */
  620.               if (counter > 1)
  621.                 --counter;
  622.               disp ();
  623.               break;
  624.             case K_ALT_O:                                          /* Alt-O */
  625.               wm_open (w[sel]);
  626.               break;
  627.             case K_ALT_P:                                          /* Alt-P */
  628.               if (counter < 99)
  629.                 ++counter;
  630.               disp ();
  631.               break;
  632.             case K_ALT_Q:                                          /* Alt-Q */
  633.               wm_close_all ();
  634.               break;
  635.             case K_ALT_S:                                          /* Alt-S */
  636.               wm_clear (w[sel]);
  637.               break;
  638.             case K_ALT_T:                                          /* Alt-T */
  639.               make_top ();
  640.               break;
  641.             case K_ALT_W:                                          /* Alt-W */
  642.               wrap_flag = !wrap_flag;
  643.               wm_wrap (w[sel], wrap_flag);
  644.               break;
  645.             case K_UP:                                          /* Up arrow */
  646.               move (0, -1);
  647.               break;
  648.             case K_DOWN:                                      /* Down arrow */
  649.               move (0, 1);
  650.               break;
  651.             case K_LEFT:                                      /* Left arrow */
  652.               move (-1, 0);
  653.               break;
  654.             case K_RIGHT:                                    /* Right arrow */
  655.               move (1, 0);
  656.               break;
  657.             case K_HOME:                                            /* Home */
  658.               wm_gotoxy (w[sel], 0, 0);
  659.               break;
  660.             case K_END:                                              /* End */
  661.               wm_dimen (w[sel], &x, &y);
  662.               wm_gotoxy (w[sel], x-1, y-1);
  663.               break;
  664.             case K_PAGEDOWN:                                   /* Page Down */
  665.               wm_down (w[sel]);
  666.               break;
  667.             case K_PAGEUP:                                       /* Page Up */
  668.               wm_up (w[sel]);
  669.               break;
  670.             case K_INS:                                              /* Ins */
  671.               wm_getxy (w[sel], &x, &y);
  672.               wm_ins_char (w[sel], x, y, counter);
  673.               break;
  674.             case K_DEL:                                              /* Del */
  675.               wm_getxy (w[sel], &x, &y);
  676.               wm_del_char (w[sel], x, y, counter);
  677.               break;
  678.             case K_CTRL_PAGEUP:                                /* Ctrl-PgUp */
  679.               top = sel-1;
  680.               make_top ();
  681.               break;
  682.             case K_CTRL_PAGEDOWN:                              /* Ctrl-PgDn */
  683.               wm_bottom (w[sel]);
  684.               break;
  685.             case K_F1:                                                /* F1 */
  686.               move_flag = !move_flag;
  687.               disp_move ();
  688.               break;
  689.             case K_F2:                                                /* F2 */
  690.               cursor_flag = !cursor_flag;
  691.               wm_chide (cursor_flag);
  692.               break;
  693.             case K_F3:                                                /* F3 */
  694.               wm_cvis (w[sel], FALSE);
  695.               break;
  696.             case K_F4:                                                /* F4 */
  697.               wm_cvis (w[sel], TRUE);
  698.               break;
  699.             case K_F5:                                                /* F5 */
  700.               putca_flag = !putca_flag;
  701.               break;
  702.             case K_F6:                                                /* F6 */
  703.               wm_update (w[sel], FALSE);
  704.               break;
  705.             case K_F7:                                                /* F7 */
  706.               wm_update (w[sel], TRUE);
  707.               break;
  708.             }
  709.           break;
  710.         case 0x01:                                            /* Ctrl-A */
  711.           auto_mode = !auto_mode;
  712.           auto_win = 1;
  713.           auto_c = ' ';
  714.           break;
  715.         case 0x02:                                            /* Ctrl-B */
  716.           do
  717.             {
  718.               --sel;
  719.               if (sel < 0)
  720.                 sel = windows-1;
  721.             } while (w[sel] == NULL);
  722.           wm_cursor (w[sel]);
  723.           disp ();
  724.           break;
  725.         case 0x04:                                            /* Ctrl-D */
  726.           wm_close (w[sel]);
  727.           wm_delete (w[sel]);
  728.           w[sel] = NULL;
  729.           n = 0;
  730.           for (i = 0; i < windows; i++)
  731.             if (w[i] != NULL)
  732.               ++n;
  733.           if (n > 0)
  734.             next_window ();
  735.           else
  736.             c = 0x1b;
  737.           break;
  738.         case 0x05:                                            /* Ctrl-E */
  739.           wm_puts (w[sel], buffer);
  740.           break;
  741.         case 0x06:                                            /* Ctrl-F */
  742.           next_window ();
  743.           break;
  744.         case 0x08:                                            /* Ctrl-H */
  745.           wm_backsp (w[sel], 1);
  746.           break;
  747.         case 0x09:                                            /* Ctrl-I */
  748.           /* not yet implemented */
  749.           break;
  750.         case 0x0c:                                            /* Ctrl-L */
  751.           wm_getxy (w[sel], &x, &y);
  752.           wm_clr_eol (w[sel], x, y);
  753.           break;
  754.         case '\r':                                                /* CR */
  755.           do_putc (sel, '\n');
  756.           break;
  757.         case 0x0e:                                            /* Ctrl-N */
  758.           new_window ();
  759.           break;
  760.         case 0x12:                                            /* Ctrl-R */
  761.           rnd_window ();
  762.           break;
  763.         case 0x1b:                                               /* Esc */
  764.           break;
  765.         default:
  766.           if (c < 0x100 && c >= ' ')
  767.             do_putc (sel, (char)c);
  768.           else
  769.             beep (880, 100);
  770.           break;
  771.         }
  772.     } while (c != 0x1b);
  773.   wm_exit ();
  774.   return (0);
  775. }
  776.