home *** CD-ROM | disk | FTP | other *** search
/ Jason Aller Floppy Collection / 125.img / PRO-C4.ZIP / BENCH1.ZIP / BENCH / SCROLL.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-05-28  |  17.7 KB  |  638 lines

  1. /***( scroll.c )****************************************************************
  2. *                                                                              *
  3. *  Contains scrolling window functions for generic lists.                      *
  4. *                                                                              *
  5. ********************************************************************************
  6. *                                                                              *
  7. * Written: Dec  6, 1989 - SBF                                                  *
  8. * Updated: Dec 13, 1989 - SBF ( Made dll_scroll() re-entrant                 ) *
  9. *          Dec 14, 1989 - SBF ( Added va_arg'ed special keys (like input_w ) ) *
  10. *          Dec 14, 1989 - SBF ( Changed to use dll_getpos & dll_setpos       ) *
  11. *          MMM DD, YYYY - XXX (                                              ) *
  12. *                                                                              *
  13. *******************************************************************************/
  14. #include <stdio.h>
  15. #include <bench.h>
  16. #include <dllist.h>
  17.  
  18. struct scroll_cb
  19. {
  20.     int *scbid;
  21.     struct dll_entry *firstptr;
  22.     struct dll_entry *selectptr;
  23.     int sel_handle;
  24.     int sel_mode;
  25. #ifdef ANSI
  26.     char *(*dsp)(generic *);
  27. #else
  28.     char *(*dsp)();
  29. #endif
  30. };
  31.  
  32. #ifdef ANSI
  33. static void dll_disp_entry(int, int, int, struct scroll_cb *, generic *, int, int);
  34. # ifdef MOUSE
  35. static void dll_mouse_off(void);
  36. static void dll_mouse_on(int, int, int, int);
  37. # endif
  38. static struct scroll_cb *dll_scroll_open(int *);
  39. static generic *dll_valid_entry(int, char *(*)(generic *), int);
  40. int sel_cmp(struct sel_entry *, struct sel_entry *);
  41. #else
  42. static void dll_disp_entry();
  43. # ifdef MOUSE
  44. static void dll_mouse_off();
  45. static void dll_mouse_on();
  46. # endif
  47. static struct scroll_cb *dll_scroll_open();
  48. static generic *dll_valid_entry();
  49. int sel_cmp();
  50. #endif
  51.  
  52. #define NUMSCROLLS 10
  53. #define MORESTR "..."
  54. #ifdef MSDOS
  55. #define MARKCHAR 0x10
  56. #else
  57. #define MARKCHAR '>'
  58. #endif
  59.  
  60. #define dll_valid_next(x, y)   dll_valid_entry(x, y, 0)
  61. #define dll_valid_prev(x, y)   dll_valid_entry(x, y, 1)
  62.  
  63. static struct scroll_cb *scb[NUMSCROLLS] = { 0 };
  64.  
  65. #ifdef MOUSE
  66. static void dll_mouse_on(r, c, h, w)
  67. int r, c, h, w;
  68. {
  69.     int i;
  70.  
  71.     mouse_level++;
  72.  
  73.     for(i = 0; i < h; i++)
  74.         mouse_add_object((unsigned char)(r + i), (unsigned char)(c + 1),
  75.                                 (unsigned char)(r + i), (unsigned char)(c + w - 1),
  76.                                 0, i + 1, NULL);
  77. }
  78.  
  79. static void dll_mouse_off()
  80. {
  81.     mouse_delete_level(mouse_level--);
  82. }
  83. #endif
  84.  
  85. static struct scroll_cb *dll_scroll_open(winhd)
  86. int *winhd;
  87. {
  88.     register int ctr;
  89.     register struct scroll_cb *tmpscb = NULL;
  90.  
  91.     if (sel_w(winhd))
  92.     {
  93.         for(ctr = 0; ctr < NUMSCROLLS; ctr++)
  94.         {
  95.             if ((tmpscb = scb[ctr]) == NULL)
  96.                 continue;
  97.             if (tmpscb->scbid == winhd)
  98.                 break;
  99.         }
  100.  
  101.         if (ctr == NUMSCROLLS)
  102.         {
  103.             for(ctr = 0; ctr < NUMSCROLLS; ctr++)
  104.                 if ((tmpscb = scb[ctr]) == NULL)
  105.                     break;
  106.  
  107.             if (ctr == NUMSCROLLS)
  108.                 tmpscb = NULL;
  109.             else
  110.             {
  111.                 tmpscb = scb[ctr] = (struct scroll_cb *)alloc(sizeof(struct scroll_cb));
  112.                 if (tmpscb != NULL)
  113.                     tmpscb->scbid = winhd;
  114.             }
  115.         }
  116.     }
  117.  
  118.     return(tmpscb);
  119. }
  120.  
  121. int dll_scroll_close(scbid)
  122. int *scbid;
  123. {
  124.     register int ctr;
  125.  
  126.     for(ctr = 0; ctr < NUMSCROLLS; ctr++)
  127.     {
  128.         if (scb[ctr] == NULL)
  129.             continue;
  130.         if (scbid == scb[ctr]->scbid)
  131.             break;
  132.     }
  133.  
  134.     if (ctr == NUMSCROLLS)
  135.         return(-1);
  136.  
  137.     scb[ctr]->scbid = NULL;
  138.     scb[ctr]->firstptr = NULL;
  139.     scb[ctr]->selectptr = NULL;
  140.     scb[ctr]->sel_handle = -1;
  141.     scb[ctr]->sel_mode = 0;
  142.     scb[ctr]->dsp = NULL;
  143.  
  144.     free(scb[ctr]);
  145.     scb[ctr] = NULL;
  146.  
  147.     return(0);
  148. }
  149.  
  150. static generic *dll_valid_entry(dll_d, dsp, previous)
  151. int dll_d;
  152. #ifdef ANSI
  153. char *(*dsp)(generic *);
  154. #else
  155. char *(*dsp)();
  156. #endif
  157. int previous;
  158. {
  159.     register generic *tmpptr;
  160.  
  161.     do
  162.     {
  163.         if (previous)
  164.             tmpptr = dll_prev(dll_d);
  165.         else
  166.             tmpptr = dll_next(dll_d);
  167.  
  168.         if (tmpptr == NULL)
  169.             break;
  170.     }
  171.     while((*dsp)(tmpptr) == NULL);
  172.  
  173.     return(tmpptr);
  174. }
  175.  
  176. static void dll_disp_entry(row, col, width, scbptr, entry, sel_flag, done)
  177. int row;
  178. int col;
  179. int width;
  180. struct scroll_cb *scbptr;
  181. generic *entry;
  182. int sel_flag;
  183. int done;
  184. {
  185.     struct sel_entry sel_find;
  186.     register struct sel_entry *septr;
  187.     register char *dspptr;
  188.  
  189.     if (entry == NULL)
  190.         disp_w(row, col, BOLD, " %-*s", width - 1, MORESTR);
  191.     else
  192.     {
  193.         dspptr = (*scbptr->dsp)(entry);
  194.  
  195.         if (scbptr->sel_mode == SEL_MULTI)
  196.         {
  197.             sel_find.sel_data = entry;
  198.             septr = (struct sel_entry *)dll_find(scbptr->sel_handle, &sel_find);
  199.     
  200.             if (septr != NULL)
  201.                 disp_w(row, col, sel_flag ? REVVID : BOLD, "%c%-*s", MARKCHAR,
  202.                             width - 1, dspptr);
  203.             else
  204.                 disp_w(row, col, sel_flag ? REVVID : NORMAL, " %-*s", width - 1,
  205.                             dspptr);
  206.         }
  207.         else
  208.             disp_w(row, col, sel_flag ? (done ? BOLD : REVVID) : NORMAL,
  209.                         " %-*s", width - 1, dspptr);
  210.     }
  211. }
  212.  
  213. /*
  214.  * dll_scroll() - Bring up a scrolling window displaying a list of items from
  215.  *                a dll_... type of list.
  216. */
  217. #ifdef UNIX
  218. int dll_scroll(row, col, height, width, winhd, dll_d, dsp, sel_mode, helpnum, srow, scol, va_alist)
  219. int row;                                  /* Row to display scrolling list at */
  220. int col;                               /* Column to display scrolling list at */
  221. int height;                               /* Maximum height of scrolling list */
  222. int width;                                         /* Width of scrolling list */
  223. int *winhd;                                       /* Pointer to window handle */
  224. int dll_d;                                         /* Handle for dll_... list */
  225. char *(*dsp)();            /* Pointer to function which extracts display info */
  226. int sel_mode;                                      /* SEL_SINGLE or SEL_MULTI */
  227. int helpnum;                        /* help number to use when K_HELP pressed */
  228. int srow;
  229. int scol;
  230. va_dcl
  231. #else
  232. int dll_scroll(int row, int col, int height, int width, int *winhd, int dll_d,
  233.                     char *(*dsp)(), int sel_mode,
  234.                     int helpnum, int srow, int scol, int va_alist, ...)
  235. #endif
  236. {
  237.     struct dll_entry *headptr;                       /* Pointer to list's head */
  238.     struct dll_entry *tailptr;                       /* Pointer to list's tail */
  239.     struct dll_entry *lastptr;                 /* Pointer to last item in list */
  240.     generic *genptr;                   /* General purpose pointer to list data */
  241.     int dspctr;                                             /* Display counter */
  242.     int cc;                                  /* Key value returned from inchar */
  243.     int done = 0;                                             /* Flag for done */
  244.     struct sel_entry sel_add;           /* Entry used to add to selection list */
  245.     struct sel_entry *septr;             /* Pointer to entry in selection list */
  246.     int numentries = 0;     /* Counter for number of entries in list to scroll */
  247.     int refresh = 1;                               /* Flag for refresh display */
  248.     int newscroll = 0;
  249.     int spkey;
  250.     va_list ap;
  251.     struct dll_entry *lstptr;
  252.     char *dspptr;
  253. #ifdef MOUSE
  254.     int mouse_sel;
  255. #endif
  256.     int r, c, h, w;
  257.     struct scroll_cb *currscb;
  258.     int  moretop;
  259.     int  morebot;
  260.     int pageheight;
  261.  
  262.     if ((currscb = dll_scroll_open(winhd)) == NULL)
  263.         return(-1);
  264.     if (currscb->firstptr == NULL)
  265.     {
  266.         newscroll = 1;
  267.         currscb->sel_mode = sel_mode;
  268.         currscb->dsp = dsp;
  269.     }
  270.  
  271.     abs_w(&r, &c, &w, &h);
  272.  
  273.     genptr = dll_seek(dll_d, 0, SEEK_SET);
  274.     if (genptr != NULL)
  275.     {
  276.         if ((*currscb->dsp)(genptr) == NULL)
  277.             genptr = dll_valid_next(dll_d, currscb->dsp);
  278.  
  279.         for( ; genptr != NULL; genptr = dll_valid_next(dll_d, currscb->dsp))
  280.             numentries++;  /* Count the entries in the list to scroll */
  281.     }
  282.     
  283.     if (numentries == 0)                               /* Return if no entries */
  284.         return(-2);
  285.  
  286.     if (numentries < height)        /* Adjust height if not enough entries */
  287.         height = numentries;
  288.  
  289.     if ((currscb->sel_handle != -1 && (currscb->sel_mode == SEL_SINGLE || newscroll)) || currscb->sel_handle == -1)
  290.     {
  291.         currscb->sel_handle = dll_open(sel_cmp, sizeof(struct sel_entry));
  292.         if (currscb->sel_handle == -1)
  293.             return(-1);
  294.     }
  295.  
  296.                                                      /* Find head, tail, etc. */
  297.     genptr = dll_seek(dll_d, 0, SEEK_SET);  
  298.     if ((*currscb->dsp)(genptr) == NULL)
  299.         genptr = dll_valid_next(dll_d, currscb->dsp);
  300.  
  301.     headptr = dll_getpos(dll_d);
  302.  
  303.     if (newscroll)
  304.         currscb->selectptr = currscb->firstptr = headptr;
  305.  
  306.     genptr = dll_seek(dll_d, 0, SEEK_END);
  307.     if ((*currscb->dsp)(genptr) == NULL)
  308.         genptr = dll_valid_prev(dll_d, currscb->dsp);
  309.     tailptr = dll_getpos(dll_d);
  310.  
  311. #ifdef MOUSE
  312.     dll_mouse_on(r + row, c + col - 1, height, width);
  313. #endif
  314.  
  315.     if (currscb->sel_mode == SEL_SINGLE)
  316.         keys_w(K_F1, help_prompt, K_CR, select_prompt, K_ESC, exit_prompt, 0);
  317.     else
  318.         keys_w(K_F1, help_prompt, ' ', select_prompt, K_CR, accept_prompt, K_ESC, exit_prompt, 0);
  319.  
  320.     while (!done)
  321.     {
  322.         if (srow && scol)
  323.         {
  324.             dll_setpos(dll_d, currscb->selectptr);
  325.             genptr = dll_curr(dll_d);
  326.             disp_w(srow, scol, REVVID, " %-*s", width - 1, (*currscb->dsp)(genptr));
  327.         }
  328.  
  329.         moretop = (currscb->firstptr != headptr);
  330.  
  331.         if (refresh)          /* Redraw the list entries if refresh flag is set */
  332.         {
  333.             dll_setpos(dll_d, currscb->firstptr);
  334.             genptr = dll_curr(dll_d);               /* Find the first to display */
  335.                                                            /* Fill the window */
  336.             for(dspctr = 0; dspctr < height; genptr = dll_valid_next(dll_d, currscb->dsp))
  337.             {
  338.                 if (moretop && dspctr == 0)
  339.                 {
  340.                     dll_disp_entry(row, col, width, NULL, NULL, 0, 0);
  341.                     dspctr++;
  342.                 }
  343.  
  344.                 lstptr = dll_getpos(dll_d);
  345.                 dll_disp_entry(dspctr + row, col, width, currscb, genptr,
  346.                                     (lstptr == currscb->selectptr), 0); 
  347.                 lastptr = lstptr;                    /* Keep last entry displayed */
  348.                 dspctr++;
  349.             }
  350.         }
  351.  
  352.         morebot = (lastptr != tailptr);
  353.  
  354.         if (morebot)
  355.         {
  356.             dll_disp_entry(row + height - 1, col, width, NULL, NULL, 0, 0);
  357.             dll_setpos(dll_d, lastptr);
  358.             dll_valid_prev(dll_d, currscb->dsp);
  359.             lastptr = dll_getpos(dll_d);
  360.         }
  361.  
  362.         cc = inchar();                     /* Get a key to determine what to do */
  363.         ichar = cc;
  364.  
  365. #ifdef UNIX
  366.         va_start(ap);
  367.         spkey = va_arg(ap, int);
  368. #else
  369.         va_start(ap, va_alist);
  370.         spkey = va_alist;
  371. #endif
  372.  
  373.         while (spkey != 0)
  374.         {
  375.             if (cc == spkey)
  376.             {
  377.                 cc = K_CR;
  378.                 break;
  379.             }
  380.             spkey = va_arg(ap, int);
  381.         }
  382.         va_end(ap);
  383.         
  384.         if (cc < 256)
  385.             if (islower(cc)) 
  386.                 cc = toupper(cc);          /* Convert lower case chars to upper case */
  387.  
  388.         refresh = 1;                                    /* Set the refresh flag */
  389.  
  390.         switch(cc)
  391.         {
  392. #ifdef MOUSE
  393.             case M_PRESS:
  394.                 if (!mouse_check_bounds())
  395.                     break;
  396.             case M_RELEASE:
  397.                 if (mouse_click(&mouse_sel, cc))
  398.                 {
  399.                     if (moretop && mouse_sel == 1 && cc == M_RELEASE)
  400.                         unget_inchar(K_UP);
  401.                     else if (morebot && mouse_sel == height && cc == M_RELEASE)
  402.                         unget_inchar(K_DOWN);
  403.                     else
  404.                     {
  405.                         if (((moretop && mouse_sel > 1) ||
  406.                                  (!moretop && mouse_sel >= 1)) &&
  407.                                 ((morebot && mouse_sel < height) ||
  408.                                  (!morebot && mouse_sel <= height)))
  409.                         {
  410.                             if (cc == M_RELEASE)
  411.                                 unget_inchar(currscb->sel_mode == SEL_MULTI ? ' ':K_CR);
  412.                             dll_setpos(dll_d, currscb->firstptr);
  413.                             for(dspctr = 0; dspctr < mouse_sel - 1 - moretop ? 1 : 0;
  414.                                  dspctr++)
  415.                                 dll_valid_next(dll_d, currscb->dsp);
  416.                             currscb->selectptr = dll_getpos(dll_d);
  417.                         }
  418.                     }
  419.                 }
  420.                 break;
  421. #endif
  422.             case '?':
  423.             case K_HELP:
  424.                 help_msg(helpnum);
  425.                 sel_w(winhd);
  426.                 break;
  427.             case K_DOWN:
  428.                 if (currscb->selectptr != tailptr) /* at the tail already? */
  429.                 {
  430.                     if (currscb->selectptr == lastptr) /* last on the screen? */
  431.                     {
  432.                         dll_setpos(dll_d, currscb->firstptr);
  433.                         dll_valid_next(dll_d, currscb->dsp); /* shift first by one */
  434.                         if (!moretop && morebot)
  435.                             dll_valid_next(dll_d, currscb->dsp);
  436.                         currscb->firstptr = dll_getpos(dll_d);
  437.                     }
  438.                     dll_setpos(dll_d, currscb->selectptr);
  439.                     dll_valid_next(dll_d, currscb->dsp); /* shift selected by one */
  440.                     currscb->selectptr = dll_getpos(dll_d);
  441.                 }
  442.                 break;
  443.             case K_UP:
  444.                 if (currscb->selectptr != headptr) /* at the head already? */
  445.                 {
  446.                     if (currscb->selectptr == currscb->firstptr) /* first one? */
  447.                     {
  448.                         dll_setpos(dll_d, currscb->firstptr);
  449.                         dll_valid_prev(dll_d, currscb->dsp); /* shift first back */
  450.                         currscb->firstptr = dll_getpos(dll_d);
  451.                         if (moretop)
  452.                         {
  453.                             genptr = dll_valid_prev(dll_d, currscb->dsp);
  454.                             lstptr = dll_getpos(dll_d);
  455.                             if (lstptr == headptr)
  456.                                 currscb->firstptr = headptr;
  457.                         }
  458.                     }
  459.                     dll_setpos(dll_d, currscb->selectptr);
  460.                     dll_valid_prev(dll_d, currscb->dsp); /* shift selected back */
  461.                     currscb->selectptr = dll_getpos(dll_d);
  462.                 }
  463.                 break;
  464.             case K_PGUP:
  465.                 if (currscb->selectptr != currscb->firstptr)
  466.                     currscb->selectptr = currscb->firstptr;    
  467.                 else
  468.                 {
  469. #ifdef UNIX
  470.                     dup_w();
  471. #endif
  472.                     pageheight = height - 3;
  473.                     if (!moretop || !morebot)
  474.                         pageheight++;
  475.                     for(dspctr = 0; dspctr < pageheight; dspctr++)
  476.                         unget_inchar(K_UP);
  477.                 }
  478.                 break;
  479.             case K_PGDN:
  480.                 if (currscb->selectptr != lastptr)
  481.                     currscb->selectptr = lastptr;
  482.                 else
  483.                 {
  484. #ifdef UNIX
  485.                     dup_w();
  486. #endif
  487.                     pageheight = height - 3;
  488.                     if (!moretop || !morebot)
  489.                         pageheight++;
  490.                     for(dspctr = 0; dspctr < pageheight; dspctr++)
  491.                         unget_inchar(K_DOWN);
  492.                 }
  493.                 break;
  494.             case K_HOME:
  495.                 currscb->selectptr = currscb->firstptr = headptr;   /* Shift select & first to head */
  496.                 break;
  497.             case K_END:
  498.                 currscb->selectptr = lastptr = tailptr;     /* Shift select & last to tail */
  499.                 dll_setpos(dll_d, tailptr);
  500.                 for(dspctr = 0; dspctr < height - 1; dspctr++)
  501.                 {
  502.                     genptr = dll_valid_prev(dll_d, currscb->dsp);
  503.                     if (genptr == NULL)
  504.                         break;
  505.                 }
  506.                 if (genptr == NULL)  /* Shift first to top of last page or head */
  507.                     currscb->firstptr = headptr;
  508.                 else
  509.                 {
  510.                     currscb->firstptr = dll_getpos(dll_d);
  511.                     if (currscb->firstptr != headptr)
  512.                     {
  513.                         dll_valid_next(dll_d, currscb->dsp);
  514.                         currscb->firstptr = dll_getpos(dll_d);
  515.                     }
  516.                 }
  517.                 break;
  518.             case ' ':
  519.                 if (currscb->sel_mode == SEL_MULTI)             /* If in multi-select mode */
  520.                 {
  521.                     dll_setpos(dll_d, currscb->selectptr);
  522.                     sel_add.sel_data = dll_curr(dll_d);
  523.                     /* Is entry selected? */
  524.                     septr = (struct sel_entry *)dll_find(currscb->sel_handle, &sel_add);
  525.                     if (septr != NULL)
  526.                     {
  527.                         if (dll_del(currscb->sel_handle) == -1)   /* If so then de-select it */
  528.                             return(-1);
  529.                     }
  530.                     else                 /* Otherwise add it to the selection list */
  531.                     {
  532.                         if (dll_add(currscb->sel_handle, &sel_add, ADD_NOSORT) != 0)
  533.                             return(-1);
  534.                     }
  535.                 }
  536.                 break;
  537.             case K_CR:
  538.                 if (currscb->sel_mode == SEL_SINGLE ||                /* If in single mode */
  539.                     (currscb->sel_mode == SEL_MULTI &&       /* Or multi with none selected */
  540.                      dll_seek(currscb->sel_handle, 0, SEEK_SET) == NULL))
  541.                 {
  542.                     dll_setpos(dll_d, currscb->selectptr);
  543.                     sel_add.sel_data = dll_curr(dll_d);   /* Add to selection list */
  544.                     if (dll_add(currscb->sel_handle, &sel_add, ADD_NOSORT) != 0)
  545.                         return(-1);
  546.                 }
  547.                 dll_setpos(dll_d, currscb->firstptr);
  548.                 genptr = dll_curr(dll_d);                /* Find first to display */
  549.                                                                /* Fill window */
  550.                 for(dspctr = 0; dspctr < height; genptr = dll_valid_next(dll_d, currscb->dsp))
  551.                 {
  552.                     if((moretop && dspctr == 0) || (morebot && dspctr == height - 1))
  553.                     {
  554.                         dll_disp_entry(dspctr + row, col, width, NULL, NULL, 0, 0);
  555.                         dspctr++;
  556.                         if (dspctr == height)
  557.                             continue;
  558.                     }
  559.  
  560.                     dll_disp_entry(dspctr + row, col, width, currscb, genptr, 0, 1);
  561.                     dspctr++;
  562.                 }
  563.                 done = 1;                                         /* Flag as done */
  564.                 break;
  565.             case K_ESC:
  566.                 dll_close(currscb->sel_handle);   /* Esc closes list and returns -1 handle */
  567.                 currscb->sel_handle = -1;
  568.                 done = 1;
  569.                 break;
  570.             default:
  571.                 refresh = 0;
  572.                 if (cc < 256 && isalpha(cc))
  573.                 {
  574.                     pageheight = 0;
  575.                     dll_setpos(dll_d, currscb->selectptr);
  576.                     while((genptr = dll_valid_next(dll_d, currscb->dsp)) != NULL)
  577.                     {
  578.                         pageheight++;
  579.                         dspptr = (*currscb->dsp)(genptr);
  580.  
  581.                         if ((islower((int)*dspptr) ? toupper((int)*dspptr) : *dspptr) == cc)
  582.                             break;
  583.                     }
  584.                     if (genptr == NULL)
  585.                     {
  586.                         lstptr = headptr;
  587.                         dll_setpos(dll_d, headptr);
  588.                         genptr = dll_curr(dll_d);
  589.                         while((lstptr = dll_getpos(dll_d)) != currscb->selectptr)
  590.                         {
  591.                             dspptr = (*currscb->dsp)(genptr);
  592.                             if ((islower((int)*dspptr) ? toupper((int)*dspptr) : *dspptr) == cc)
  593.                                 break;
  594.                             genptr = dll_valid_next(dll_d, currscb->dsp);
  595.                         }
  596.                         
  597.                         if (lstptr == currscb->selectptr)
  598.                             genptr = NULL;
  599.  
  600.                         pageheight = 0;
  601.                         dll_setpos(dll_d, currscb->selectptr);
  602.                         while(lstptr != dll_getpos(dll_d))
  603.                         {
  604.                             pageheight--;
  605.                             dll_valid_prev(dll_d, currscb->dsp);
  606.                         }
  607.                     }
  608.                     if (genptr != NULL)
  609.                     {
  610. #ifdef UNIX
  611.                         dup_w();
  612. #endif
  613.                         refresh++;
  614.                         for(dspctr = 0; dspctr < abs(pageheight); dspctr++)
  615.                             unget_inchar(pageheight < 0 ? K_UP : K_DOWN);
  616.                     }
  617.                 }
  618.                 break;
  619.         }
  620.     }
  621.  
  622. #ifdef MOUSE
  623.     dll_mouse_off();
  624. #endif
  625.  
  626.     return(currscb->sel_handle);       /* Return the list handle (or -1 if ESC pressed) */
  627. }
  628.  
  629. /*
  630.  * sel_cmp() - Comparison function for selection list
  631. */
  632. int sel_cmp(p1, p2)
  633. struct sel_entry *p1;
  634. struct sel_entry *p2;
  635. {
  636.     return(memcmp(p1, p2, sizeof(struct sel_entry)));
  637. }
  638.