home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 13 / 13.iso / s / s001 / 1.ddi / PFC / SRC / PLEDT0.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-04-26  |  14.7 KB  |  614 lines

  1. /* 88-05-07 Jahns    kbnec() -> GETCHR()                */
  2. /* 01-Aug-1988 Jahns    plitmhilit() with ATROFS            */
  3. /* 01-Aug-1988 Jahns    pledt() select with char            */
  4. /* 02-Aug-1988 Jahns    pledt() f_end included                */
  5. /* 16-Sep-1988 Jahns    MOUSES() included                */
  6. /* 20-Sep-1988 Jahns    SET_MOUSE_WND() included            */
  7. /* 88-10-04 Vogt N.    ATROFS replaced by TASK->PTERM->ATROFS        */
  8. /* 88-10-20 Jahns    if F1 return 0x21                */
  9. /* 89-06-13 Jahns    return all functionkey's                        */
  10. /* 89-11-23 Vogt N.    GETCHR() --> GET_CHR()                */
  11.  
  12.  
  13.  
  14. /* (c) 1985, Phoenix Computer Products Corp. and Novum Organum, Inc. */
  15. /***
  16. * name :    plist - create an instance of a pick-list object.
  17. *
  18. * synopsis:    plist(h_wnd,get_fnc,ttl)
  19. *        h_wnd    - the window in which the pick-list appears
  20. *        ttl    - a string which will appear on the first line
  21. *              of the list.    this line will not be scrolled.
  22. *              if no comment is desired, then pass a NULLPTR.
  23. *        get_fnc - address of function which will be called to get
  24. *              formatted elements which will appear in the
  25. *              list.
  26. *
  27. * description:    create a new object and set its attributes.
  28. *
  29. * returns:    handle of newly created object.
  30. *
  31. * name :    plrls - release an instance of a pick-list object.
  32. *
  33. * synopsis:    plrls(h_pl)
  34. *        h_pl    handle to a pick list object.
  35. *
  36. * name :    pllstkey - return key which terminated input.
  37. *        pldsp - display a set of elements in a pick-list
  38. *        pledt - let the user choose an element in the list.
  39. *
  40. * synopsis:    pldsp(h_pl)
  41. *        h_pl    handle to pick-list to be displayed.
  42. *
  43. *        pledt(h_pl, &chc, str)
  44. *        h_pl    handle to pick-list
  45. *        chc    the number of the element in the list
  46. *                which the user chose.
  47. *        str    string buffer in which the text of the
  48. *                chosen element will be placed.
  49. *                if you do not wish text returned, make
  50. *                this argument a NULLPTR.
  51. *
  52. *        key = pllstkey()
  53. *        <type,code> - the type code of the key which caused input
  54. *            to terminate
  55. *
  56. * description:    pick-lists are for allowing the user to chose from a list
  57. *        of items which is longer than the number of lines in
  58. *        a given screen area.  the cursor keys allow the user
  59. *        to scroll the elements of the list in and out of the
  60. *        screen area.
  61. *
  62. * returns:    pldsp() return RC_FAIL if no elements were displayed.
  63. *            othewise SUCCEED is returned.
  64. *        pllstkey() returns a word containing the <type,code> pair
  65. *            of the key which caused input to terminate.
  66. *        pledt() return
  67. *            RC_FAIL - no elements in list.
  68. *            RC_ESC - user pressed <ESC>
  69. *            RC_SPECIAL - user pressed special key, e.g. function key.
  70. *            RC_ENTER - the user pressed the <enter> key.
  71. *
  72. * (C) novum organum, inc. 1985
  73. *
  74. ***/
  75. #include "compiler.h"
  76.  
  77. #define f_new
  78.  
  79. #include "tskenv0.h"
  80. #include "cptpdf.h"
  81.  
  82. extern    struct tsk_env    *TSKENV;
  83.  
  84. extern    char8        trtinp[256];
  85.  
  86. #include "psys.h"
  87.  
  88.  
  89.  
  90. static plitmhilit (short row, short f_hilit)
  91. {
  92.   if (f_hilit) vstsetinvrs();
  93.   _vdspa(row, 0, vidncols(), VD_CURSTAT);
  94.   if (f_hilit) vstsetnorml();
  95. }
  96.  
  97.  
  98.  
  99.  
  100. GLOBAL HDL plist (HDL h_wnd, PFI get_fnc, char8 *ttl)
  101. {
  102.   HDL       h_pl;
  103.   char8    *memgive();
  104.  
  105.   h_pl = (HDL) memgive(sizeof(PICKLIST));
  106.  
  107.   H_PL->tag       = ADT_PL;
  108.   H_PL->h_wnd       = h_wnd;
  109.   H_PL->ttl       = ttl;
  110.   H_PL->get_fnc    = get_fnc;
  111.   H_PL->fst_on_scr = 0;
  112.   H_PL->csr_off    = 0;
  113.   return (h_pl);
  114.  
  115. }    /* plist */
  116.  
  117.  
  118.  
  119. GLOBAL void SetPlmax (HDL h_pl, short max_cnt)
  120. {
  121.  
  122.   adtverify (h_pl, ADT_PL);          /* verify that really a pick-list*/
  123.   H_PL->max_cnt = max_cnt;
  124.  
  125. }    /* SetPlmax */
  126.  
  127.  
  128.  
  129. GLOBAL HDL plrls(FAST HDL h_pl)
  130. {
  131.   HDL h_wnd;
  132.  
  133.   adtverify (h_pl, ADT_PL);   /* verify that this is a pick-list object.*/
  134.   H_PL->tag = DEAD_TAG;       /* zap tag.                  */
  135.   h_wnd = H_PL->h_wnd;
  136.   memtake(h_pl);          /* zap pick-list.               */
  137.  
  138.   return (h_wnd);
  139. }
  140.  
  141.  
  142. GLOBAL void plsetchc(FAST HDL h_pl, int fst_on_scr, int chc)
  143.  
  144. {
  145.   adtverify (h_pl, ADT_PL);
  146.   if (chc < 0) chc = 0;
  147.   if (fst_on_scr > chc) fst_on_scr = chc;
  148.   else
  149.     if (fst_on_scr < 0) fst_on_scr = 0;
  150.   H_PL->fst_on_scr = fst_on_scr;
  151.   H_PL->csr_off    = chc - fst_on_scr;
  152.  
  153. }    /* plsetchc */
  154.  
  155.  
  156.  
  157. static short fillplist( HDL   h_pl,
  158.             short row,
  159.             short lst_row,
  160.             char8 *buf,
  161.             short nxt_itm )
  162. {
  163.   register short  n_dspd, ncols;
  164.  
  165.   n_dspd = 0;
  166.   ncols  = vidncols() + 1;
  167.  
  168.   while (row < lst_row)
  169.   {
  170.     /* if another string is returned, then add to window.        */
  171.     /* but if at end-of-list (RC_FAIL), then stop on this line.        */
  172.     if ((*H_PL->get_fnc)(nxt_itm, buf, ncols) == RC_FAIL)
  173.       break;
  174.     vdsplns(row++, 0, ncols, buf);
  175.     nxt_itm++;            /* actual number displayed in list        */
  176.     n_dspd++;
  177.   }
  178.   while(row < lst_row)
  179.     vdsplns(row++, 0, ncols, "");
  180.   return (n_dspd);
  181.  
  182. }    /* fillplist */
  183.  
  184.  
  185.  
  186. static short _pldsp (HDL h_pl, short nrows, char8 *buf, short *pfst_row)
  187. {
  188.   register short  max_itms, n_on_scr;
  189.  
  190.   wndtotop(H_PL->h_wnd);
  191.   max_itms = nrows;
  192.  
  193.   if  (H_PL->ttl)
  194.   {
  195.     vdspls(0, 0, H_PL->ttl);
  196.     max_itms--;
  197.     *pfst_row = 1;
  198.   }
  199.   else
  200.     *pfst_row = 0;
  201.     /* fill the box with as many choices a possible, starting with FST_ON_SCR*/
  202.  
  203.   if  (H_PL->csr_off >= max_itms)
  204.   {
  205.     H_PL->fst_on_scr -= (H_PL->csr_off - max_itms + 1);
  206.     if (H_PL->fst_on_scr < 0)
  207.       H_PL->fst_on_scr = 0;
  208.   }
  209.  
  210.   FOREVER
  211.   {
  212.     n_on_scr = fillplist(h_pl, *pfst_row, nrows, buf, H_PL->fst_on_scr);
  213.  
  214.     if (H_PL->csr_off >= n_on_scr)       /* make certain cursor is over  */
  215.       H_PL->csr_off = n_on_scr - 1;       /* a choice in the window.       */
  216.     if    (n_on_scr > 0)
  217.        break;
  218.     /* nothing was successfully put in the pick-list.  however maybe*/
  219.     /* we are past the end of the list.  if we are not at the first*/
  220.     /* (zero'th) element of the list, let's try from the beginning  */
  221.     /*  if we are already there, then just quit.            */
  222.     H_PL->csr_off = 0;
  223.     if (H_PL->fst_on_scr > 0)
  224.       H_PL->fst_on_scr = 0;
  225.     else
  226.       break;      /* already at begin.    nothing in list.      */
  227.   }
  228.  
  229.   return (n_on_scr);
  230.  
  231. }    /* _pldsp */
  232.  
  233.  
  234.  
  235. #ifdef use
  236.  
  237. GLOBAL short pldsp(HDL h_pl)
  238. {
  239.   register short   rc, prv_attr;
  240.   short        fst_row;
  241.   HDL           prv_pl, prv_wnd, wndsetactv();
  242.   char8        s[81];
  243.  
  244.   adtverify (h_pl, ADT_PL);          /* verify that really a pick-list*/
  245.   rc        = RC_SUCCESS;
  246.   prv_wnd   = wndsetactv(H_PL->h_wnd);
  247.   prv_attr  = vstsetattr(VA_NORMAL);
  248.   if (_pldsp (h_pl, vidnrows(), s, &fst_row) > 0)
  249.     plitmhilit(fst_row + H_PL->csr_off, NO);
  250.   else
  251.     rc = RC_FAIL;
  252.   vstsetattr(prv_attr);
  253.   wndsetactv(prv_wnd);
  254.  
  255.   return(rc);
  256.  
  257. }    /* pldsp */
  258.  
  259. #endif
  260.  
  261.  
  262. static char8 TEST_CH(char8 *s)
  263. {
  264.   register short I;
  265.  
  266.   for (I = 0; I < vidncols() + 1; ++I)
  267.   {
  268.     if (s[I] != SP) break;
  269.   }
  270.   return(s[I]);
  271.  
  272. }    /*TEST_CH */
  273.  
  274.  
  275.  
  276. static BOOLEAN MORE(HDL h_pl, char CH, char *s)
  277. {
  278.   register short i, cnt, ncols;
  279.  
  280.   ncols = vidncols() + 1;
  281.   cnt = 0;
  282.   i = -1;
  283.   for(;;)
  284.   {
  285.     if((*H_PL->get_fnc)(++i, s, ncols) == RC_FAIL) break;
  286.     if (CH == TEST_CH(s)) ++cnt;
  287.     if (cnt > 1) break;
  288.   }
  289.   return ((cnt > 1) ? TRUE : FALSE);
  290.  
  291. }    /* MORE */
  292.  
  293.  
  294.  
  295. GLOBAL short pledt (HDL h_pl, short *pchc)
  296. {
  297.   register short i, k, row, rc;
  298.   short      csr_off,  csr_typ, chc, nrows, fst_row, max_itms;
  299.   short      ncols, fst_on_scr, n_on_scr, prv_attr, f_fill;
  300.   HDL         prv_pl, prv_wnd, wndsetactv();
  301.   short      pos, pos_sav;
  302.   BOOLEAN     cont, more, TERM;
  303.   short      CH, CHR;
  304.   short      MROW, MCOL;
  305.   struct _WND     *act_wnd;
  306.   short      min_col, min_row;
  307.   short      max_col, max_row;
  308.   short      min_c, max_c, min_r, max_r;
  309.   short      func_key;
  310.   struct pc_kbd  *PKBRD;
  311.   char8      s[81];
  312.   short      savdev;
  313.   short      SAV_APA;
  314.   PFI         get_fnc;
  315.  
  316.   savdev  = SET_DSP(TSKENV, TXTDSP);
  317.  
  318.   PKBRD        = TSKENV->PKBRD;
  319.   SAV_APA      = PKBRD->f_APA;
  320.   PKBRD->f_APA = FALSE;
  321.  
  322.   adtverify (h_pl, ADT_PL);          /* verify that really a pick-list*/
  323.  
  324.   get_fnc   = H_PL->get_fnc;
  325.   prv_wnd   = wndsetactv(H_PL->h_wnd);
  326.   act_wnd   = (struct _WND *) H_PL->h_wnd;
  327.   ncols     = vidncols() + 1;
  328.   prv_attr  = vstsetattr(VA_NORMAL);
  329.   nrows     = vidnrows();
  330.   csr_typ   = vidcsrtyp(CSR_HIDDEN);
  331.  
  332.   rc = RC_FAIL;
  333.  
  334.   if  ((n_on_scr = _pldsp (h_pl, nrows, s, &fst_row)) > 0)
  335.   {
  336.     rc           = RC_LOOP;
  337.     max_itms   = nrows - fst_row;
  338.     csr_off    = H_PL->csr_off;
  339.     fst_on_scr = H_PL->fst_on_scr;
  340.     f_fill     = NO;
  341.   }
  342.  
  343.   if (PKBRD->XMOUSE)
  344.   {
  345.     MOUSE_CLR(TSKENV);
  346.     min_c = min_col = act_wnd->pcol;
  347.     max_c = max_col = act_wnd->pcol + act_wnd->pncols + 1;
  348.     min_r = min_row = act_wnd->prow;
  349.     max_r = max_row = act_wnd->prow + act_wnd->pnrows + 1;
  350.     SET_MOUSE_WND(TSKENV, &min_c, &max_c, &min_r, &max_r);
  351.   }
  352.  
  353.   while(rc == RC_LOOP)        /* fails without executing loop if list is empty.*/
  354.   {
  355.     plitmhilit(fst_row + csr_off, YES);         /*display current choice.*/
  356.  
  357.  
  358.     for (;;)
  359.     {
  360.       chc = fst_on_scr + csr_off;
  361.  
  362.       if (CHKKBD(TSKENV))
  363.       {
  364.     if (PKBRD->XMOUSE && PKBRD->MOUSE_ON) MOUSEOFF(TSKENV);
  365.     CH = GET_KBD(TSKENV);
  366.     if (CH) break;
  367.       }
  368.  
  369.       if (PKBRD->XMOUSE)
  370.       {
  371.     MOUSE_POS(TSKENV, min_row + fst_row + csr_off, min_col + 1);
  372.  
  373.     TERM = TRUE;
  374.  
  375.     switch(MOUSE_INP(TSKENV, &MROW, &MCOL))
  376.     {
  377.       case 0 : TERM = FALSE;
  378.            break;
  379.  
  380.       case 2 :
  381.            CH = 0x0121;
  382.            WRITE_BTC(TSKENV, CH);
  383.            break;
  384.  
  385.       case 3 :
  386.            CH = ESC;
  387.            WRITE_BTC(TSKENV, CH);
  388.            break;
  389.  
  390.       case 1 :
  391.            if (MROW == min_row || MROW == max_row)
  392.            {
  393.              CH = (MROW == min_row) ? f_prev : f_next;
  394.              WRITE_BTC(TSKENV, CH);
  395.              break;
  396.            }
  397.            if (MCOL == max_col)
  398.              { CH = f_end; WRITE_BTC(TSKENV, CH); break; }
  399.            if (MCOL == min_col)
  400.              { CH = APH; WRITE_BTC(TSKENV, CH); break; }
  401.  
  402.            row = MROW - min_row - 1;
  403.  
  404.            if (row < n_on_scr)
  405.            {
  406.              MOUSEOFF(TSKENV);           /* mouse cursor off       */
  407.              plitmhilit(fst_row + csr_off, NO);
  408.              csr_off = row;
  409.              plitmhilit(fst_row + csr_off, YES);
  410.              MOUSE_POS(TSKENV, min_row + fst_row + csr_off, min_col + 1);
  411.              pos = fst_on_scr + csr_off;
  412.              if (chc == pos)
  413.              {
  414.                CH = CR;
  415.                WRITE_BTC(TSKENV, CH);
  416.                break;
  417.              }
  418.              else
  419.              {
  420.                if (PKBRD->BATCHPR)
  421.                {
  422.              (*get_fnc)(pos, s, ncols);
  423.              CHR = TEST_CH(s);
  424.              WRITE_BTC(TSKENV, APH);
  425.              k = 0;
  426.              i = max_itms - 1;
  427.              for(;;)
  428.              {
  429.                if ((pos - k) >= i)
  430.                {
  431.                  WRITE_BTC(TSKENV, f_next);
  432.                  k += i;
  433.                }
  434.                else break;
  435.              }
  436.              if (k) ++k;
  437.              for(i = k; i <= pos; ++i)
  438.              {
  439.                (*get_fnc)(i, s, ncols);
  440.                if (TEST_CH(s) == CHR) WRITE_BTC(TSKENV, CHR);
  441.              }
  442.                }
  443.              }
  444.            }    /* if (row < n_on_scr) */
  445.            TERM = FALSE;
  446.            break;
  447.     }
  448.     if (TERM) break;
  449.       }
  450.  
  451.       guc();
  452.  
  453.     } /* for (;;)   */
  454.  
  455.     if (PKBRD->XMOUSE && PKBRD->MOUSE_ON) MOUSEOFF(TSKENV);
  456.  
  457.     func_key = (CH >= f_fun) ? TRUE : FALSE;
  458.  
  459.     plitmhilit(fst_row + csr_off, NO);
  460.  
  461.     switch (CH)
  462.     {
  463.       case ESC      :
  464.             rc = RC_ESC;
  465.             break;
  466.       case CR      :
  467.             rc = RC_ENTER;
  468.             break;
  469.       case SP      :
  470.       case APD      :
  471.             if    (csr_off < n_on_scr - 1)     /* in middle of window? */
  472.             csr_off++;    /* yes, just go to next window line. */
  473.             else      /* at bottom of screen, any more elements? */
  474.             if ((*get_fnc)(fst_on_scr + n_on_scr, s, ncols)!=RC_FAIL)
  475.             {
  476.              /* yes, more elements, so scroll up             */
  477.              /* add new element to bottom of window.         */
  478.               vidareascroll(fst_row, 0, max_itms, ncols, 1);
  479.                          /* put new choice on last line  */
  480.               vdsplns(fst_row + csr_off, 0, ncols, s);
  481.               fst_on_scr++;
  482.             }
  483.             else
  484.             sybeep();
  485.             break;
  486.       case APU      :
  487.             if    (csr_off > 0)          /* in middle of screen?         */
  488.             csr_off--;          /* yes, just move up one line. */
  489.             else
  490.             if    ((fst_on_scr > 0)     /* are we in middle of list?   */
  491.              &&              /* got previous element ok?    */
  492.              ((*get_fnc)(fst_on_scr - 1, s, ncols) != RC_FAIL))
  493.             {
  494.               vidareascroll(fst_row, 0, max_itms, ncols, -1);
  495.               fst_on_scr--;
  496.               n_on_scr++;
  497.               if  (n_on_scr > max_itms)
  498.               n_on_scr = max_itms;
  499.                          /* put new elm on first line. */
  500.               vdsplns(fst_row, 0, ncols, s);
  501.             }
  502.             else
  503.             sybeep();
  504.             break;
  505.       case APH      :
  506.             fst_on_scr = 0;            /*move to begin of list. */
  507.             csr_off    = 0;            /* then fill window.     */
  508.             f_fill     = YES;
  509.             break;
  510.       case f_prev :                    /* Pg-Up */
  511.             if    (fst_on_scr > 0)   /* if not at first element of list*/
  512.             {               /* then move up NLNS-1 and refill */
  513.               i       = MIN(max_itms - 1, fst_on_scr);
  514.               fst_on_scr -= i; /* compute first now on screen, number*/
  515.               f_fill      = YES;
  516.             }
  517.             else         /* move to first element in window. */
  518.             if    (csr_off > 0) csr_off = 0;
  519.             else sybeep();
  520.             break;
  521.       case f_next :                    /* Pg-Dn */
  522.             fst_on_scr += (n_on_scr - 1); /*last elm now on first line*/
  523.             f_fill = YES;
  524.             break;
  525.       case f_end  :
  526.             if (H_PL->max_cnt)
  527.             {
  528.               pos = H_PL->max_cnt;
  529.               (*get_fnc)(pos - 1, s, ncols);
  530.             }
  531.             else {
  532.               pos = fst_on_scr + csr_off;
  533.               while((*get_fnc)(++pos, s, ncols) != RC_FAIL);
  534.             }
  535.             fst_on_scr = pos - max_itms;
  536.             if (fst_on_scr < 0) fst_on_scr = 0;
  537.             f_fill = YES;
  538.             break;
  539.  
  540.       default      :
  541.             if (func_key)
  542.             {
  543.               rc = CH;
  544.               break;
  545.             }
  546.  
  547.             CH        = toupper(CH);
  548.             pos     = fst_on_scr + csr_off;
  549.             pos_sav = pos;
  550.             cont    = TRUE;
  551.             more    = MORE(h_pl, CH, s);
  552.  
  553.             for (;;)
  554.             {
  555.               if((*get_fnc)(++pos, s, ncols) != RC_FAIL)
  556.               {
  557.             if (CH == toupper(TEST_CH(s)))
  558.             {
  559.               if (! PKBRD->BATCH && ! PKBRD->BATCHPR &&
  560.                 ! more && pos == pos_sav)
  561.                  rc = RC_ENTER;
  562.               i = pos - fst_on_scr;
  563.               if (i > 0 && i < n_on_scr)
  564.               {
  565.                 csr_off = i;
  566.                 break;
  567.               }
  568.               fst_on_scr = pos;
  569.               csr_off    = 0;
  570.               f_fill     = YES;
  571.               break;
  572.             }
  573.               }
  574.               else
  575.               {
  576.             if (cont)
  577.             {
  578.               pos  = -1;
  579.               cont = FALSE;
  580.             }
  581.             else {
  582.               sybeep();
  583.               break;
  584.             }
  585.               }
  586.             }
  587.             break;
  588.     }    /* switch */
  589.  
  590.     if    (f_fill)
  591.     {
  592.       n_on_scr = fillplist(h_pl, fst_row, nrows, s, fst_on_scr);
  593.       if  (csr_off >= n_on_scr)
  594.       csr_off = n_on_scr-1;
  595.       f_fill = NO;
  596.     }
  597.   }    /* while(rc==RC_LOOP) */
  598.  
  599.   vidcsrtyp(csr_typ);
  600.   chc           = fst_on_scr + csr_off;
  601.   H_PL->fst_on_scr = fst_on_scr;    /* save the num. of first in window */
  602.   H_PL->csr_off    = csr_off;        /* save offset of cursor in window. */
  603.   *pchc        = chc;        /* return choice number.        */
  604.   vstsetattr(prv_attr);
  605.   wndsetactv(prv_wnd);
  606.  
  607.   if (PKBRD->XMOUSE) SET_MOUSE_WND(TSKENV, &min_c, &max_c, &min_r, &max_r);
  608.  
  609.   PKBRD->f_APA = SAV_APA;
  610.   SET_DSP(TSKENV, savdev);
  611.  
  612.   return (rc);
  613. }
  614.