home *** CD-ROM | disk | FTP | other *** search
/ The Best of Mecomp Multimedia 2 / MECOMP-CD-II.iso / amiga / tools / workbench / fv-220 / screen.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-01-17  |  19.2 KB  |  909 lines

  1. /* fv is a binary file editor written by Chris Hooper (cdh@mtu.edu)
  2.  *    on 6-2-91 and has gone through many revisions since then.
  3.  *      Much inspiration was given by Bill Moore, the first real user!
  4.  *
  5.  *   Author:  CHRISTOPHER D HOOPER
  6.  *
  7.  *   fv source Copyright (c) 1992 - 1998  Chris Hooper
  8.  *
  9.  *   Modification and redistribution is strictly prohibited.
  10.  *   Sale of this software above media cost is prohibited.
  11.  *
  12.  *   Except for above two restrictions, this software may be used for
  13.  *       any purpose, commercial or private.
  14.  *
  15.  *   Disclaimer:  This product is fit for no use, foreign or domestic.
  16.  *                Use implies knowledge you intend to destroy something.
  17.  */
  18.  
  19. #include <stdio.h>
  20. #include <curses.h>
  21. #include "main.h"
  22. #include "screen.h"
  23. #include "io.h"
  24.  
  25. #include "pcurses.h"
  26.  
  27. #ifdef LINT
  28. #    include "lint.h"
  29. #endif
  30.  
  31. int (*xaddstr)();
  32. int (*xmove)();
  33. int (*xdelwin)();
  34. int (*xrefresh)();
  35. int (*xtouchwin)();
  36. int (*xstandout)();
  37. int (*xstandend)();
  38. int (*xclrtoeol)();
  39. int (*xclrtobot)();
  40. int (*xclear)();
  41. int (*xaddch)();
  42. int (*xgetch)();
  43. WINDOW *(*xnewwin)();
  44.  
  45. WINDOW  *main_window;        /* main display window */
  46. WINDOW  *status_window;        /* lower single row status window */
  47. int    status_line;
  48. extern    int zmode;
  49. extern    int Zmode;
  50. extern    ulong cursor_address;
  51. ulong    inbuf_size;
  52. uchar    ascii[256];        /* ascii translation map */
  53. uchar    zmodes[] = ". _~!@#$%^&*";
  54. char    *hex = "0123456789abcdef";    /* hexadecimal translation map */
  55. char    *divmsg[] = {
  56.  "    ", "   2", "   4", "   8", "  16", "  32", "  64", " 128", " 256", " 512",
  57.  "  1K", "  2K", "  4K", "  8K", " 16K", " 32K", " 64K", "128K", "256K", "512K",
  58.  "  1M", "  2M", "  4M", "  8M", " 16M", " 32M", " 64M", "128M", "256M", "512M"
  59. };
  60.  
  61. int curses_up = 0;
  62. static void strhex8();
  63. static void strhex32();
  64.  
  65. void show_addr(address)
  66. ulong address;
  67. {
  68.     register int index;
  69.     ulong temp;
  70.  
  71.     status_range(address, address + buf_size);
  72.     
  73. #if defined(CURSES_UPDATE_BUG)
  74.     /* evil hack because curses for Linux is broken */
  75.     xclear(stdscr);
  76.     xmove(stdscr, 0, 0);
  77.     xclrtobot(stdscr);
  78.     xtouchwin(main_window);
  79.     xtouchwin(status_window);
  80. #endif
  81.  
  82.     if (swapbytes | Swapbytes | SWAPBYTES) {
  83.         if (chdis) {
  84. #ifdef CHAR_COLOR
  85.         wattron(main_window, CHAR_COLOR);
  86. #endif
  87.         temp = addis * 10 + wpline * 9 * wdis;
  88.             for (index = 0; index < buf_size; index++) {
  89.             if (index % cpline == 0)
  90.                  xmove(main_window, index / cpline, temp);
  91.             if (index < inbuf_size)
  92.             xaddch_filt(buffer[index ^ Swapbytes ^ SWAPBYTES]);
  93.             else
  94.             xaddch(main_window, ' ');
  95.         }
  96.         }
  97.  
  98.         for (index = 0; index < (buf_size + 3) / 4; index++) {
  99.         if (addis && ((index % wpline) == 0)) {
  100. #ifdef ADDR_COLOR
  101.             wattron(main_window, ADDR_COLOR);
  102. #endif
  103.             xmove(main_window, index / wpline, 0);
  104.             if (index >= (inbuf_size + 3) / 4)
  105.                 xaddstr(main_window, "          ");
  106.             else {
  107.                 if (divmod2)
  108.                 temp = (index * 4 + address) &
  109.                        ((1 << divisor2) - 1);
  110.                 else
  111.                 temp = (index * 4 + address) >> divisor2;
  112.  
  113.                 if (wdismode)
  114.                 sprintf(out_string, "%8d: ", (int) temp);
  115.                 else
  116.                 sprintf(out_string, "%08x: ", (int) temp);
  117.                 xaddstr(main_window, out_string);
  118.             }
  119.         }
  120.         if (wdis) {
  121. #ifdef WORD_COLOR
  122.             wattron(main_window, WORD_COLOR);
  123. #endif
  124.             xmove(main_window, index / wpline, addis * 10 +
  125.                                 (index % wpline) * 9 * wdis);
  126.             if (index < (inbuf_size + 3) / 4)
  127.             switch (wdismode) {
  128.                 case 0:    /* hex */
  129.                 strhex32(out_string, swap32(ibuffer[index ^ (SWAPBYTES | swapbytes) >> 2]));
  130.                 out_string[8] = ' ';
  131.                 out_string[9] = '\0';
  132.                 xaddstr(main_window, out_string);
  133.                 break;
  134.                 case 1:    /* decimal */
  135.                 sprintf(out_string, "%8d ", (int)
  136.                     swap32(ibuffer[index ^ (swapbytes | SWAPBYTES) >> 2]));
  137.                 out_string[9] = '\0';
  138.                 xaddstr(main_window, out_string);
  139.                 break;
  140.                 case 2:    /* float */
  141.                 (void) sprintf(out_string, "%-9f ",
  142.                         *((float *) &ibuffer[index]));
  143.                 out_string[9] = '\0';
  144.                 xaddstr(main_window, out_string);
  145.                 break;
  146.                 case 3:    /* double */
  147.                 if ((index & 1) == 0) {
  148.                     (void) sprintf(out_string, "%-17f ",
  149.                             *((double *) &ibuffer[index]));
  150.                     out_string[17] = '\0';
  151.                     xaddstr(main_window, out_string);
  152.                 }
  153.                 break;
  154.             }
  155.             else
  156.             xaddstr(main_window, "         ");
  157.         }
  158.         }
  159.     } else {
  160.         if (chdis) {
  161. #ifdef CHAR_COLOR
  162.         wattron(main_window, CHAR_COLOR);
  163. #endif
  164.         temp = addis * 10 + wpline * 9 * wdis;
  165.             for (index = 0; index < buf_size; index++) {
  166.             if (index % cpline == 0)
  167.                  xmove(main_window, index / cpline, temp);
  168.             if (index < inbuf_size)
  169.             xaddch_filt(buffer[index]);
  170.             else
  171.             xaddch(main_window, ' ');
  172.         }
  173.         }
  174.  
  175.         for (index = 0; index < (buf_size + 3) / 4; index++) {
  176.         if (addis && ((index % wpline) == 0)) {
  177. #ifdef ADDR_COLOR
  178.             wattron(main_window, ADDR_COLOR);
  179. #endif
  180.             xmove(main_window, index / wpline, 0);
  181.             if (index >= (inbuf_size + 3) / 4)
  182.                 xaddstr(main_window, "          ");
  183.             else {
  184.                 if (divmod2)
  185.                 temp = (index * 4 + address) &
  186.                        ((1 << divisor2) - 1);
  187.                 else
  188.                 temp = (index * 4 + address) >> divisor2;
  189.  
  190.                 if (wdismode)
  191.                 sprintf(out_string, "%8d: ", (int) temp);
  192.                 else
  193.                 sprintf(out_string, "%08x: ", (int) temp);
  194.                 xaddstr(main_window, out_string);
  195.             }
  196.         }
  197.         if (wdis) {
  198. #ifdef WORD_COLOR
  199.             wattron(main_window, WORD_COLOR);
  200. #endif
  201.             xmove(main_window, index / wpline, addis * 10 + (index % wpline) * 9 * wdis);
  202.             if (index < (inbuf_size + 3) / 4)
  203.             switch (wdismode) {
  204.                 case 0:
  205.                 strhex32(out_string, ibuffer[index]);
  206.                 out_string[8] = ' ';
  207.                 out_string[9] = '\0';
  208.                 xaddstr(main_window, out_string);
  209.                 break;
  210.                 case 1:
  211.                 (void) sprintf(out_string, "%8d ", (uint) ibuffer[index]);
  212.                 out_string[8] = '\0';
  213.                 xaddstr(main_window, out_string);
  214.                 break;
  215.                 case 2:
  216.                 (void) sprintf(out_string, "%-9f ",
  217.                         *((float *) &ibuffer[index]));
  218.                 out_string[8] = '\0';
  219.                 xaddstr(main_window, out_string);
  220.                 break;
  221.                 case 3:
  222.                 if ((index & 1) == 0) {
  223.                     (void) sprintf(out_string, "%-17f ",
  224.                             *((double *) &ibuffer[index]));
  225.                     out_string[17] = '\0';
  226.                     xaddstr(main_window, out_string);
  227.                 }
  228.                 break;
  229.             }
  230.             else
  231.             xaddstr(main_window, "         ");
  232.         }
  233.         }
  234.     }
  235.     if (!kbuffer_size)
  236.         xrefresh(main_window);
  237.  
  238. #ifdef NO_COLOR
  239.     wattrset(main_window, 0);
  240. #endif
  241. }
  242.  
  243. void init()
  244. {
  245.     init_ascii();
  246.  
  247.     if (noscreen) {
  248.         wpline   = 8;
  249.         cpline   = 32;
  250.         buf_size = 8192;
  251. #ifdef HUGE_BUFFER
  252.         wpline   *= 8;
  253.         cpline   *= 8;
  254.         buf_size *= 8;
  255. #endif
  256.         return;
  257.     }
  258.  
  259. #if defined(COLOR_CURSES) && defined(Amiga)
  260.     start_color();
  261. #endif
  262.  
  263. #ifdef OS9
  264.     if (initscr() == 0)
  265.         LINES = 0;
  266. #else
  267.     initscr();
  268. #endif
  269.  
  270. #if defined(COLOR_CURSES) && !defined(Amiga)
  271.     start_color();
  272. #endif
  273.  
  274.     if (LINES == 0)
  275.         error_exit("Curses initialization failed.");
  276.  
  277.     curses_up = 1;
  278. #if defined(COLOR_CURSES)
  279.             /* COLOR 1-7   RED  GRN  BLUE  1-1000 */
  280.     init_color(WORD_COLOR, 900, 900, 200);    /* word disp is yellow */
  281.     init_color(CHAR_COLOR, 900, 900, 900);    /* char disp is white */
  282.     init_color(ADDR_COLOR, 420, 920, 840);    /* address column is cyan */
  283.     init_color(STAT_COLOR, 1000, 240, 80);    /* status area is red */
  284.     init_color(CRSR_COLOR, 688, 859, 984);    /* cursor color is blue */
  285. #endif
  286.  
  287. #ifdef Dynix
  288.     raw();
  289. #else
  290.     cbreak();
  291. #endif
  292.     noecho();
  293.     nonl();
  294.     wclear(stdscr);
  295.     wrefresh(stdscr);
  296.  
  297.     wpline   = (COLS - addis * 10 - 1) / (9 * wdis + chdis * 4);
  298.     cpline   = wpline << 2;
  299.     buf_size = (LINES - 1) * cpline;
  300.  
  301.     status_line = LINES - 1;
  302.  
  303.     main_window = xnewwin(LINES - 1, COLS, status_line ? 0 : 1, 0);
  304.     status_window = xnewwin(1, COLS, status_line, 0);
  305.  
  306. #if defined(Solaris2) || defined(Amiga) || defined(SYSV)
  307.     keypad(stdscr, TRUE);
  308.     keypad(main_window, TRUE);
  309. #endif
  310.  
  311. #ifdef STAT_COLOR
  312.     wattrset(status_window, STAT_COLOR);
  313. #endif
  314.  
  315. #if defined(Solaris2) || defined(Amiga) || defined(SYSV)
  316.     leaveok(main_window, TRUE);
  317. #endif
  318.     leaveok(status_window, TRUE);
  319.  
  320.     status_mode();
  321. }
  322.  
  323. void de_init()
  324. {
  325.     if (!curses_up)
  326.         return;
  327.  
  328.     wclear(stdscr);
  329.     wrefresh(stdscr);
  330.     echo();
  331.     nl();
  332.     endwin();
  333.     curses_up = 0;
  334. }
  335.  
  336. void update_cursor(mode)
  337. int mode;
  338. {
  339.     int index;
  340.     int row;
  341.     int offset;
  342.     int ioffset;
  343.     int column;
  344.     int icoffset;
  345.  
  346.     if (noscreen)
  347.         return;
  348.  
  349.     if (mode == ON) {
  350. #ifdef CRSR_COLOR
  351.         wattrset(main_window, CRSR_COLOR);
  352. #endif
  353.         xstandout(main_window);
  354.     } else
  355.         xstandend(main_window);
  356.  
  357.     offset = ALIGNED(cursor_address - view_address);
  358.  
  359.     if (chdis) {
  360. #ifdef CHAR_COLOR
  361.         if (mode == OFF)
  362.         wattron(main_window, CHAR_COLOR);
  363. #endif
  364.         for (index = 0; index < alignment; index++) {
  365.         ioffset = (offset + index) ^ Swapbytes;
  366.         xmove(main_window, ioffset / cpline, addis * 10 +
  367.               wpline * 9 * wdis + (ioffset % cpline));
  368.         xaddch_filt(buffer[(offset + index) ^ SWAPBYTES]);
  369.         }
  370.     }
  371.  
  372.  
  373.     if (wdis) {
  374. #ifdef WORD_COLOR
  375.         if (mode == OFF)
  376.         wattron(main_window, WORD_COLOR);
  377. #endif
  378.         ioffset = offset ^ swapbytes;
  379.  
  380.         if (alignment == 8)
  381.             icoffset = (ioffset % cpline) & ~3;
  382.         else
  383.             icoffset = ALIGNED(ioffset % cpline);
  384.  
  385.         column = (icoffset >> 2) + (icoffset << 1) + addis * 10;
  386.         row    = ioffset / cpline;
  387.  
  388.         xmove(main_window, row, column);
  389.         switch (wdismode) {
  390.         case 0:            /* hex */
  391.             if (alignment == 1)
  392.             strhex8(out_string, (ulong) buffer[offset ^ SWAPBYTES]);
  393.             else if (alignment == 2)
  394.             if (swapbytes & 1) {
  395. #ifdef LITTLE_ENDIAN
  396.               strhex8(out_string + 2, (ulong) buffer[offset ^ SWAPBYTES]);
  397. #endif
  398.               strhex8(out_string, (ulong) buffer[(offset + 1) ^ SWAPBYTES]);
  399. #ifndef LITTLE_ENDIAN
  400.               strhex8(out_string + 2, (ulong) buffer[offset ^ SWAPBYTES]);
  401. #endif
  402.             } else {
  403. #ifdef LITTLE_ENDIAN
  404.               strhex8(out_string + 2, (ulong) buffer[(offset + 1) ^ SWAPBYTES]);
  405. #endif
  406.               strhex8(out_string, (ulong) buffer[offset ^ SWAPBYTES]);
  407. #ifndef LITTLE_ENDIAN
  408.               strhex8(out_string + 2, (ulong) buffer[(offset + 1) ^ SWAPBYTES]);
  409. #endif
  410.             }
  411.             else if (alignment == 4)
  412.             strhex32(out_string, 
  413.                      swap32(ibuffer[(offset ^ SWAPBYTES) >> 2]));
  414.             else {    /* alignment == 8 */
  415.             strhex32(out_string, 
  416.                      swap32(ibuffer[(offset ^ SWAPBYTES) >> 2]));
  417.             offset  += 4;
  418.             ioffset  = offset ^ swapbytes;
  419.             if (ioffset < buf_size) {
  420.                 xaddstr(main_window, out_string);
  421.                 icoffset = (ioffset % cpline) & ~3;
  422.                 column  = (icoffset >> 2) + (icoffset << 1) +
  423.                            addis * 10;
  424.                 row      = ioffset / cpline;
  425.                 xmove(main_window, row, column);
  426.                 strhex32(out_string, 
  427.                          swap32(ibuffer[(offset ^ SWAPBYTES) >> 2]));
  428.             }
  429.             }
  430.             break;
  431.         case 1:            /* integer */
  432.             (void) sprintf(out_string, "%8d", (int)
  433.                    swap32(ibuffer[(ioffset ^ SWAPBYTES) >> 2]));
  434.             out_string[8] = '\0';
  435.             break;
  436.         case 2:            /* float */
  437.             (void) sprintf(out_string, "%-8f",
  438.                    *((float *) &ibuffer[offset >> 2]));
  439.             if (strlen(out_string) > 8) {
  440.             if (mode == ON)
  441.                 out_string[7] = '*';
  442.             out_string[8] = '\0';
  443.             }
  444.             break;
  445.         case 3:            /* double */
  446.             (void) sprintf(out_string, "%-17f",
  447.                    *((double *) &ibuffer[offset >> 2]));
  448.             if (strlen(out_string) > 17) {
  449.             if (mode == ON)
  450.                 out_string[16] = '*';
  451.                 out_string[17] = '\0';
  452.             }
  453.             break;
  454.         }
  455.  
  456.         xaddstr(main_window, out_string);
  457.     }
  458.  
  459.     if (mode == ON) {
  460. #ifdef NO_COLOR
  461.         wattrset(main_window, 0);
  462. #endif
  463.         xstandend(main_window);
  464.     }
  465. }
  466.  
  467.  
  468. void init_ascii()
  469. {
  470.     uchar dot;
  471.     int index;
  472.  
  473.     dot = zmodes[zmode];
  474.     
  475.     ascii[0] = zmodes[Zmode];
  476.  
  477.     for (index = 1; index < 32; index++)
  478.         ascii[index] = dot;
  479.  
  480.     ascii['\011'] = ' ';
  481.     ascii['\012'] = ' ';
  482.     ascii['\015'] = ' ';
  483.  
  484.     for (; index < 128; index++)
  485.         ascii[index] = index;
  486.  
  487. #ifdef SHOW_EXTASCII
  488.     for (; index < 161; index++)
  489.         ascii[index] = dot;
  490.  
  491.     do {
  492.         index++;
  493.         ascii[index] = index;
  494.     } while (index < 255);
  495. #else
  496.     for (index = 127; index <= 255; index++)
  497.         ascii[index] = dot;
  498. #endif
  499. }
  500.  
  501. void status_range(range1, range2)
  502. ulong range1;
  503. ulong range2;
  504. {
  505.     char out_string[32];
  506.  
  507.     if (noscreen)
  508.         return;
  509.  
  510.     if (COLS < 28)
  511.         return;
  512.  
  513.         leaveok(status_window, FALSE);
  514.  
  515.     if (divmod) {
  516.         range1 &= ((1 << divisor) - 1);
  517.         range2 &= ((1 << divisor) - 1);
  518.         xstandout(status_window);
  519.     } else {
  520.         range1 >>= divisor;
  521.         range2 >>= divisor;
  522.     }
  523.     xmove(status_window, 0, COLS - 21);
  524.     xaddstr(status_window, divmsg[divisor]);
  525.     if (divmod && !divmod2)
  526.         xstandend(status_window);
  527.     else if (!divmod && divmod2)
  528.         xstandout(status_window);
  529.  
  530.     xaddch(status_window, ' ');
  531.     xaddstr(status_window, divmsg[divisor2]);
  532.     if (divmod2)
  533.         xstandend(status_window);
  534.  
  535.     xmove(status_window, 0, 19);
  536.     xaddch(status_window, ' ');
  537.     xmove(status_window, 0, 0);
  538.     if (wdismode)
  539.         sprintf(out_string, "[%8d-%8d]", (uint) range1, (uint) range2);
  540.     else 
  541.         sprintf(out_string, "[%08x-%08x]", (uint) range1, (uint) range2);
  542.     xaddstr(status_window, out_string);
  543.  
  544.     xrefresh(status_window);
  545.  
  546.         leaveok(status_window, TRUE);
  547. }
  548.  
  549. void status_filename()
  550. {
  551.     int len;
  552.     int namelen;
  553.     int tildes = 0;
  554.     char *ptr = filename[filenum];
  555.  
  556.     if (COLS < 28)
  557.         return;
  558.  
  559.     xmove(status_window, 0, 20);
  560.     switch (wdismode) {
  561.         case 0:     /* hex */
  562.         sprintf(out_string, "(%x of %x) ",
  563.             (uint) cursor_address, (uint) fend);
  564.         break;
  565.         case 1:     /* decimal */
  566.         default:    /* all other types */
  567.         sprintf(out_string, "(%d of %d) ",
  568.             (uint) cursor_address, (uint) fend);
  569.         break;
  570.     }
  571.     len = strlen(out_string);
  572.     namelen = strlen(ptr);
  573.     while ((len + namelen + tildes > COLS - 42) && namelen) {
  574.         tildes = 2;
  575.         ptr++;
  576.         namelen--;
  577.     }
  578.     xaddstr(status_window, out_string);
  579.     if (tildes)
  580.         xaddstr(status_window, "~~");
  581.     xaddstr(status_window, ptr);
  582.     xrefresh(status_window);
  583. }
  584.  
  585.  
  586. void status_mode()
  587. {
  588.     if (noscreen)
  589.         return;
  590.  
  591.     if (COLS < 18)
  592.         return;
  593.  
  594.     xmove(status_window, 0, COLS - 11);
  595.  
  596.     if (Swapbytes | SWAPBYTES)
  597.         xstandout(status_window);
  598.     xaddch(status_window, " w?l???q w?l???q W?L???Q????????"[
  599.            swapbytes | Swapbytes | SWAPBYTES | (swapmode << 3)]);
  600.     if (Swapbytes | SWAPBYTES)
  601.         xstandend(status_window);
  602.  
  603.     xaddch(status_window, '0' + alignment);
  604.     if ((ronly | force_ronly) && !force_write)
  605.         xaddstr(status_window, "R");
  606.     else
  607.         xaddstr(status_window, "W");
  608.  
  609.     xaddstr(status_window, " ");
  610.  
  611.     if (mode == STRING)
  612.         xaddstr(status_window, "Str");
  613.     else
  614.         xaddstr(status_window, "Num");
  615.     switch (wdismode) {
  616.         case 0:
  617.         xaddstr(status_window, "Hex");
  618.         break;
  619.         case 1:
  620.         xaddstr(status_window, "Dec");
  621.         break;
  622.         case 2:
  623.         xaddstr(status_window, "Flt");
  624.         break;
  625.         case 3:
  626.         xaddstr(status_window, "Dbl");
  627.         break;
  628.         case 4:
  629.         xaddstr(status_window, "Oct");
  630.         break;
  631.     }
  632.  
  633.     xtouchwin(status_window);
  634.     xrefresh(status_window);
  635. }
  636.  
  637.  
  638. ulong swap32(x)
  639. ulong x;
  640. {
  641.     if ((swapbytes | SWAPBYTES) == 0)
  642.         return(x);
  643.  
  644.     if ((swapbytes | SWAPBYTES) > 1)   /* long and quad */
  645.         return((x >> 24) | (x << 24) |
  646.                ((x << 8) & (255 << 16)) |
  647.                ((x >> 8) & (255 << 8)));
  648.  
  649.     /* must be swap words */
  650.     return(((x >> 8) & 0x00ff00ff) |
  651.            ((x << 8) & 0xff00ff00));
  652. }
  653.  
  654. int select_file()
  655. {
  656.     char ch;
  657.     int index;
  658.     int count;
  659.     int tlen;
  660.     int current = filenum;
  661.     static int lowest = 0;
  662.  
  663.     if (noscreen)
  664.         return(filenum);
  665.  
  666.     leaveok(status_window, FALSE);
  667.  
  668.     do {
  669.         xmove(status_window, 0, 0);
  670.         xclrtoeol(status_window);
  671.         xmove(status_window, 0, 0);
  672.         xaddstr(status_window, "File: ");
  673.         if (current < lowest)
  674.         lowest = current;
  675.         count = strlen(filename[current]) + 1;
  676.         for (index = current - 1; index >= lowest; index--) {
  677.         tlen = strlen(filename[index]) + 1;
  678.         if (tlen + count > COLS - 6) {
  679.             lowest = index + 1;
  680.             break;
  681.         } else
  682.             count += tlen;
  683.         }
  684.  
  685.         for (index = lowest; index < current; index++) {
  686.         xaddstr(status_window, filename[index]);
  687.         xaddch(status_window, ' ');
  688.         }
  689.         xstandout(status_window);
  690.         xaddstr(status_window, filename[current]);
  691.         xstandend(status_window);
  692.  
  693.         for (index = current + 1; index < filenames; index++) {
  694.         tlen = strlen(filename[index]) + 1;
  695.         if (tlen + count > COLS - 6)
  696.             break;
  697.         else {
  698.             count += tlen;
  699.             xaddch(status_window, ' ');
  700.             xaddstr(status_window, filename[index]);
  701.         }
  702.         }
  703.         xmove(status_window, 0, COLS - 1);
  704.         xrefresh(status_window);
  705.  
  706.         ch = get_key();
  707.         switch (ch) {
  708.         case 'h':    /* left one file */
  709.         case 'k':
  710.         case 'b':
  711.         case 2:        /* ^B */
  712.         case 8:        /* ^H - backspace */
  713.             if (current > 0)
  714.             current--;
  715.             break;
  716.         case 'l':    /* right one file */
  717.         case 'j':
  718.         case 'f':
  719.         case ' ':    /* space */
  720.         case 6:        /* ^F */
  721.             if (current < filenames - 1)
  722.             current++;
  723.             break;
  724.         case 'q':    /* quit without selecting */
  725.         case 24:    /* ^X */
  726.         case 27:    /* ESC */
  727.             leaveok(status_window, TRUE);
  728.             return(filenum);
  729.         case 10:    /* ^J */
  730.             ch = 13;    /* ^M */
  731.             break;
  732.         case '0':
  733.         case '^':
  734.             current = 0;
  735.             break;
  736.         case '$':
  737.             current = filenames - 1;
  738.             break;
  739.         case '%':
  740.             current = filenum;
  741.             break;
  742.         case 9:        /* ^I - Tab */
  743.             current = (current + 1) % filenames;
  744.             break;
  745.         case '?':
  746.             help_me(4);
  747.             xtouchwin(status_window);
  748.             xrefresh(status_window);
  749.             xtouchwin(main_window);
  750.             xrefresh(main_window);
  751.             break;
  752.         case 12:    /* ^L */
  753.             xclear(stdscr);
  754.             xmove(stdscr, 0, 0);
  755.             xclrtobot(stdscr);
  756.             xtouchwin(main_window);
  757.             xtouchwin(status_window);
  758.             xrefresh(stdscr);
  759.             xrefresh(main_window);
  760.             xrefresh(status_window);
  761.             break;
  762.         }
  763.     } while (ch != 13);    /* ^M selects */
  764.  
  765.     leaveok(status_window, TRUE);
  766.  
  767.     return(current);
  768. }
  769.  
  770. int dummy()
  771. {
  772.     return(0);
  773. }
  774.  
  775.  
  776. WINDOW *wdummy()
  777. {
  778.     return(0);
  779. }
  780.  
  781. int getdummy()
  782. {
  783.     static last = 0;
  784.  
  785.     last = !last;
  786.  
  787.     if (last)
  788.         return(27);     /* ESC */
  789.     else
  790.         return(24);     /* ^X */
  791. }
  792.  
  793. void assign_dummy()
  794. {
  795.     xaddstr = dummy;
  796.     xmove = dummy;
  797.     xdelwin = dummy;
  798.     xrefresh = dummy;
  799.     xtouchwin = dummy;
  800.     xstandout = dummy;
  801.     xstandend = dummy;
  802.     xclrtoeol = dummy;
  803.     xclrtobot = dummy;
  804.     xclear = dummy;
  805.     xaddch = dummy;
  806.     xgetch = getdummy;
  807.     xnewwin = wdummy;
  808. }
  809.  
  810. void assign_curses()
  811. {
  812.     xaddstr = lwaddstr;
  813.     xmove = wmove;
  814.     xdelwin = delwin;
  815.     xrefresh = wrefresh;
  816.     xtouchwin = touchwin;
  817.     xstandout = lwstandout;
  818.     xstandend = lwstandend;
  819.     xclrtoeol = wclrtoeol;
  820.     xclrtobot = wclrtobot;
  821.     xclear = wclear;
  822.     xaddch = lwaddch;
  823.     xgetch = wgetch;
  824.     xnewwin = newwin;
  825. }
  826.  
  827. static void strhex8(optr, value)
  828. char *optr;
  829. ulong value;
  830. {
  831.     optr[2] = '\0';
  832.     optr[1] = hex[value & 15];
  833.     value >>= 4;
  834.     optr[0] = hex[value & 15];
  835. }
  836.  
  837. static void strhex32(optr, value)
  838. char *optr;
  839. ulong value;
  840. {
  841. #ifdef LITTLE_ENDIAN
  842.     value = (value >> 24) | (value << 24) |
  843.             ((value << 8) & (255 << 16)) |
  844.             ((value >> 8) & (255 << 8));
  845. #endif
  846.     optr[8] = '\0';
  847.     optr[7] = hex[value & 15];
  848.     value >>= 4;
  849.     optr[6] = hex[value & 15];
  850.     value >>= 4;
  851.     optr[5] = hex[value & 15];
  852.     value >>= 4;
  853.     optr[4] = hex[value & 15];
  854.     value >>= 4;
  855.     optr[3] = hex[value & 15];
  856.     value >>= 4;
  857.     optr[2] = hex[value & 15];
  858.     value >>= 4;
  859.     optr[1] = hex[value & 15];
  860.     value >>= 4;
  861.     optr[0] = hex[value & 15];
  862. }
  863.  
  864. #ifdef OS9
  865. int wstandout(WINDOW *win)
  866. {
  867.     return(wattron(win, W_STANDOUT));
  868. }
  869.  
  870. int wstandend(WINDOW *win)
  871. {
  872.     return(wattrset(win, 0));
  873. }
  874. #endif
  875.  
  876. #if defined(Linux) || defined(FreeBSD)
  877. int lwaddstr(WINDOW *win, char *str)
  878. {
  879.     return(waddstr(win, str));
  880. }
  881. #endif    /* Linux || FreeBSD */
  882.  
  883. #if defined(Win32)
  884. int lwclear(WINDOW *win)
  885. {
  886.     return(wclear(win));
  887. }
  888.  
  889. int lwaddch(WINDOW *win, chtype ch)
  890. {
  891.     return(waddch(win, ch));
  892. }
  893.  
  894. int ltouchwin(WINDOW *win)
  895. {
  896.     return(touchwin(win));
  897. }
  898.  
  899. int lwstandout(WINDOW *win)
  900. {
  901.     return(wstandout(win));
  902. }
  903.  
  904. int lwstandend(WINDOW *win)
  905. {
  906.     return(wstandend(win));
  907. }
  908. #endif    /* Win32 */
  909.