home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / CONTRIB / MBASE / MBASE50.TAR / mbase / src / input.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-21  |  13.3 KB  |  439 lines

  1. /*
  2.  * METALBASE 5.0
  3.  *
  4.  * Released October 1st, 1992 by Huan-Ti [ richid@owlnet.rice.edu ]
  5.  *                                       [ t-richj@microsoft.com ]
  6.  */
  7.  
  8.    /**********************************************************************/
  9.    /* Compile with -DTROUBLE if you have usleep() and your arrows act up */
  10.    /**//**************************************************************//**/
  11.        /* Compile with -DVI_EMU if you really want some vi emulation */
  12.        /**************************************************************/
  13.  
  14. #define INPUT_C
  15. #include "mbase.h"
  16.  
  17. #ifndef linux
  18. #ifndef MSDOS 
  19. #ifdef LONGARGS
  20.    extern long   atol(char *);
  21.    extern double atof(char *);
  22. #else
  23.    extern long   atol();
  24.    extern double atof();
  25. #endif
  26. #endif
  27. #endif
  28.  
  29. #ifdef LONGARGS
  30.    void display (dataptr, int, int);
  31.    char getarr  (void);
  32.    char input   (dataptr, int, int);
  33. #else
  34.    void display();
  35.    char getarr();
  36.    char input();
  37. #endif
  38.  
  39. /*
  40.  * An option at compile time:  if you want the field to be accepted (as with
  41.  * a down arrow) automatically when the user has filled it completely, define
  42.  * ADVANCE_AT_END as below.  This makes DE a bit more natural for Choice
  43.  * fields and the like.
  44.  *
  45.  */
  46.  
  47. #define ADVANCE_AT_END
  48.  
  49. #define DELAY_TIME 10
  50.  
  51. #define movech(c,y,x)  move(y,x);refresh();c=getarr();
  52.  
  53. #ifndef ESC
  54. #define ESC (char)27
  55. #endif
  56.  
  57. static int  ins = 1;
  58.  
  59. char  str[150], org[150];
  60. int   pos,y,x,len,tgt,inslt,cln,esc;
  61.  
  62. /*
  63.  * getarr() functions like getch(), but returns special codes for arrow
  64.  * keys as well.
  65.  *
  66.  */
  67.  
  68. #ifdef USE_CURKEY
  69.  
  70. char
  71. getarr ()
  72. {
  73.    int   ch;
  74.  
  75.    do  ch = (int)getch();
  76.    while (ch == 0);
  77.  
  78.    if (ch == KEY_UP)     return (char)AR_UP;
  79.    if (ch == KEY_DOWN)   return (char)AR_DOWN;
  80.    if (ch == KEY_LEFT)   return (char)AR_LEFT;
  81.    if (ch == KEY_RIGHT)  return (char)AR_RIGHT;
  82.    if (ch == KEY_IC)     return (char)AR_INS;
  83.    if (ch == KEY_DC)     return (char)AR_DEL;
  84.    if (ch == KEY_HOME)   return (char)AR_HOME;
  85.    if (ch == KEY_LL)     return (char)AR_END;
  86.    if (ch == KEY_PPAGE)  return (char)AR_PGUP;
  87.    if (ch == KEY_NPAGE)  return (char)AR_PGDN;
  88.  
  89.    return (char)ch;
  90. }
  91.  
  92. #else
  93.  
  94. char
  95. getarr ()
  96. {
  97.    register int   x;
  98.    char          *a,*b,*c,*d,*e,*f,*g,*h,*i,*j,ch;
  99.    static char   *up="\033[A";
  100.    static char   *down="\033[B";
  101.    static char   *left="\033[D";
  102.    static char   *right="\033[C";
  103.    static char   *ins="\033[@";
  104.    static char   *del="\033[P";
  105.    static char   *home="\033[H";
  106.    static char   *end="\033[24H";
  107.    static char   *pgup="\033[V";
  108.    static char   *pgdn="\033[U";
  109.  
  110.    do
  111.     { ch = (char)getch();  if (ch < 0)  ch = 0;
  112.  
  113.       if (ch != *(a= up))     a=NULL;  else a++;
  114.       if (ch != *(b= down))   b=NULL;  else b++;
  115.       if (ch != *(c= left))   c=NULL;  else c++;
  116.       if (ch != *(d= right))  d=NULL;  else d++;
  117.       if (ch != *(e= ins))    e=NULL;  else e++;
  118.       if (ch != *(f= del))    f=NULL;  else f++;
  119.       if (ch != *(g= home))   g=NULL;  else g++;
  120.       if (ch != *(h= end))    h=NULL;  else h++;
  121.       if (ch != *(i= pgup))   i=NULL;  else i++;
  122.       if (ch != *(j= pgdn))   j=NULL;  else j++;
  123.  
  124.       if (!a && !b && !c && !d && !e && !f && !g && !h && !i && !j)  break;
  125.  
  126. #if !defined(MSDOS) || !defined(AMIGA)
  127.       fcntl (0, F_SETFL, O_NDELAY);  /* Turn off waiting for keys */
  128. #endif
  129.  
  130.       for (;;)
  131.        { if (a && !*a) { ch = AR_UP;     break; }
  132.          if (b && !*b) { ch = AR_DOWN;   break; }
  133.          if (c && !*c) { ch = AR_LEFT;   break; }
  134.          if (d && !*d) { ch = AR_RIGHT;  break; }
  135.          if (e && !*e) { ch = AR_INS;    break; }
  136.          if (f && !*f) { ch = AR_DEL;    break; }
  137.          if (g && !*g) { ch = AR_HOME;   break; }
  138.          if (h && !*h) { ch = AR_END;    break; }
  139.          if (i && !*i) { ch = AR_PGUP;   break; }
  140.          if (j && !*j) { ch = AR_PGDN;   break; }
  141.  
  142.          if (!a && !b && !c && !d && !e && !f && !g && !h && !i && !j)
  143.           { ch=*(up);
  144.             break;
  145.           }
  146.          for (x=0; x < DELAY_TIME; x++)       /* DELAY_TIME quick reads */
  147.           {
  148.             if ((ch = (char)getch()) > 0)  break;
  149. #ifdef TROUBLE
  150.             usleep (100);
  151. #endif
  152.           }
  153.          if (x == DELAY_TIME)
  154.           { ch=*(up);
  155.             break;
  156.           }
  157.          a=(a==NULL || ch != *a) ? NULL : a+1;
  158.          b=(b==NULL || ch != *b) ? NULL : b+1;
  159.          c=(c==NULL || ch != *c) ? NULL : c+1;
  160.          d=(d==NULL || ch != *d) ? NULL : d+1;
  161.          e=(e==NULL || ch != *e) ? NULL : e+1;
  162.          f=(f==NULL || ch != *f) ? NULL : f+1;
  163.          g=(g==NULL || ch != *g) ? NULL : g+1;
  164.          h=(h==NULL || ch != *h) ? NULL : h+1;
  165.          i=(i==NULL || ch != *i) ? NULL : i+1;
  166.          j=(j==NULL || ch != *j) ? NULL : j+1;
  167.        }
  168.  
  169. #if !defined(MSDOS) || !defined(AMIGA)
  170.       fcntl (0, F_SETFL, 0);
  171. #endif
  172.     } while (! ch);
  173.  
  174.    return ch;
  175. }
  176.  
  177. #endif
  178.  
  179. void
  180. display (buf, typ, siz)
  181. dataptr  buf;
  182. int      typ;
  183. int      siz;
  184. {
  185.    int   b, a;
  186.    long  ac, num, pre, ext;
  187.    long  tlong;
  188.    char  temp[22];
  189.  
  190.    getyx    (win,b,a);
  191.    sprintf  (str, "%-132.132s", "");  str[siz] = 0;
  192.    mvaddstr (b,a, str);
  193.  
  194.    switch (typ)
  195.       {
  196.       case T_CHAR:    strzcpy (str, buf,   siz);                      break;
  197.       case T_SHORT:   sprintf (str, "%d",  (int)*(short  *)buf);      break;
  198.       case T_USHORT:  sprintf (str, "%u",  (int)*(ushort *)buf);      break;
  199.       case T_LONG:    sprintf (str, "%ld", *(long   *)buf);           break;
  200.       case T_ULONG:   sprintf (str, "%lu", *(ulong  *)buf);           break;
  201.       case T_FLOAT:   sprintf (str, "%f",  *(float  *)buf);           break;
  202.       case T_DOUBLE:  sprintf (str, "%lf", *(double *)buf);           break;
  203.       case T_MONEY:   tlong = (long)(*(double *)buf * 100.0);
  204.                       sprintf (str, "%-.2lf", (double)tlong / 100.0); break;
  205.       case T_TIME:    strcpy (str, fmt_time (*(mb_time *)buf, 0));    break;
  206.       case T_DATE:    strcpy (str, fmt_date (*(mb_date *)buf, 0));    break;
  207.       case T_SERIAL:  sprintf (str, "%ld", *(long   *)buf);           break;
  208.       case T_PHONE:   strzcpy (temp, buf, 20);
  209.                       scn_phone (&ac, &pre, &num, &ext, temp);
  210.                       strcpy (str, fmt_phone (ac,pre,num,ext, 0));    break;
  211.       }
  212.    str[siz] = 0;
  213.    mvaddstr (b,a, str);
  214.    move     (b,a);
  215.    refresh  ();
  216. }
  217.  
  218. /*
  219.  * Returns:     0 -- Continue to next field
  220.  *              1 -- Finished with DE
  221.  *             -1 -- Abort DE
  222.  *          other -- Field control (-/+/j/k)
  223.  *
  224.  */
  225.  
  226. char
  227. input   (buf, typ, siz)
  228. dataptr  buf;
  229. int      typ;
  230. int      siz;
  231. {
  232.    register int  i;
  233.    char          c;
  234.    int           y1,x1, start;
  235.    long          tlong;
  236.    long          ac, num, pre, ext;
  237.    char          temp[22];
  238.  
  239.    inslt=pos=tgt=cln=esc=start=0;  raw();noecho();getyx(win,y,x);
  240.    display (buf, typ, siz);        len=strlen(str);  strcpy (org,str);
  241.  
  242.    for (;;)
  243.     { movech (c,y,x+pos);
  244.       if (strchr (quit_chars, c))  break;
  245. #ifdef VI_EMU
  246.       if (c == ESC)
  247.        { if (tgt)           tgt=0;
  248.          else if (ins)      ins=0,pos--;
  249.          else esc++;
  250.          if (esc == 2)  { c = 'q'; break; }  /* Two ESC's aborts too */
  251.          if (pos==-1)  pos=0;
  252.          continue;
  253.        }
  254. #else
  255.       if (c != ESC)  esc = 0;
  256.       else
  257.        { esc++;
  258.          if (esc == 2)   { c = 'q';  break; }
  259.        }
  260. #endif
  261.       if (c == CTRL_C)   { c = 'q';  break; }  /* Ctrl-C aborts */
  262.       if (c == CTRL_Q)   { c = 'q';  break; }  /* Ctrl-Q aborts */
  263.       if (c == AR_PGUP)  { c = 'k';  break; }
  264.       if (c == AR_UP)    { c = 'k';  break; }
  265.       if (c == AR_PGDN)  { c = 'j';  break; }
  266.       if (c == AR_DOWN)  { c = 'j';  break; }
  267.       if (c == CTRL_L)   { clearok (win, TRUE);  refresh();  continue; }
  268.       if (c == AR_END)   { pos = len;  continue; }
  269.       if (c == CTRL_U)   { strcpy  (str, org);
  270.                            move (y, x); display (buf, typ, siz);
  271.                            len=strlen(str); start = 0;
  272.                            c = AR_HOME;  /* Pretend they hit HOME afterward. */
  273.                          }
  274.       if (c == AR_HOME)  { pos = 0;    continue; }
  275.  
  276.       if (c == AR_RIGHT)
  277.        { if (pos < len)  pos++;
  278.          continue;
  279.        }
  280. #ifndef VI_EMU
  281.       if (c == AR_LEFT)
  282.        { if (pos > 0)  pos--;
  283.          continue;
  284.        }
  285. #endif
  286.       esc = 0;
  287.       if (ins)
  288.        { if (c == '\b' || c == 127 || c == AR_LEFT || c == AR_DEL)
  289.             if (pos != inslt)
  290.              { pos--,len--,mvdelch(y,x+pos),mvinsch(y,x+siz-1,' ');
  291.                for (i=pos; i<len; i++)
  292.                   str[i] = str[i+1];
  293.                str[i] = 0;
  294.              }
  295.          if (c == '\r' || c == '\n' || c == CTRL_A)  break;
  296.          if (c < ' ' || c > 'z')  continue;
  297. #ifndef VI_EMU
  298.          if (pos == 0 && ! start)
  299.           {
  300.             for (i=0; i<len; i++)
  301.                mvdelch(y,x),mvinsch(y,x+siz-1,' ');
  302.             str[0] = 0;  len = 0;  move(y,x);  refresh();
  303.           }
  304.          start = 1;
  305. #endif
  306.          if (len == siz)  continue;
  307.          insch(c);  mvdelch(y,x+siz);
  308.          for (i=len-1; i>=pos; i--)
  309.             str[i+1] = str[i];
  310.          len++;  str[len] = 0;
  311.          str[pos] = c;  pos++;
  312. #ifdef ADVANCE_AT_END
  313.          if (len == siz) { c = 'j'; break; }
  314. #endif
  315.          continue;
  316.        }
  317.       if (tgt)
  318.        { if (c < ' ' || c > 'z' || len <= 1) { tgt=0; continue; }
  319.          if (tgt < 3)
  320.             for (i=pos-1; i>=0; i--)
  321.                if (str[i] == c)  break;
  322.          if (tgt > 2)
  323.             for (i=pos+1; i<len; i++)
  324.                if (str[i] == c)  break;
  325.          if (i < 0 || i == len) { tgt=0; continue; }
  326.          pos=i;
  327.          if (tgt == 2) pos++;
  328.          if (tgt == 3) pos--;
  329.          tgt=0; continue;
  330.        }
  331.       if (cln==2) { move(23,0); clrtoeol(); cln=0; continue; }
  332.       if (cln==1)
  333.        { if (c > ' ' && c < 'z')
  334.           { mvaddch (23, 1, c);
  335.             c = (char)tolower (c);
  336.             if (c == 'w' || c == 'x') { c = 'x'; break; }
  337.             if (c == 'q')                        break;
  338.           }
  339.          cln=2; y=y1; x=x1;
  340.          continue;
  341.        }
  342.  
  343.       if (c=='\r' || c=='j' || c=='k' || c=='z' || c=='q' || c == CTRL_A ||
  344.           c=='\n' || c=='+' || c=='-' || c=='Z' || c=='Q')  break;
  345.  
  346.       switch (c)
  347.        { case 'F':  tgt = 1;  break;
  348.          case 'T':  tgt = 2;  break;
  349.          case 't':  tgt = 3;  break;
  350.          case 'f':  tgt = 4;  break;
  351.          case 'A':  pos=len;  ins=1;  break;
  352.          case 'a':  if (pos != len)
  353.                        pos++; ins=1;  break;
  354.          case 'i':            ins=1;  break;
  355.          case 'I':  pos=0;    ins=1;  break;
  356.          case 'x':  if (len != 0)
  357.                        len--,mvdelch(y,x+pos),mvinsch(y,x+siz-1,' ');
  358.                     for (i=pos; i<len; i++)
  359.                        str[i] = str[i+1];
  360.                     str[i] = 0;
  361.                     if (pos == len && pos != 0)  pos--;
  362.                    break;
  363.          case 'X':  if (pos != 0)
  364.                      { pos--,len--,mvdelch(y,x+pos),mvinsch(y,x+siz-1,' ');
  365.                        for (i=pos; i<len; i++)
  366.                           str[i] = str[i+1];
  367.                        str[i] = 0;
  368.                      }
  369.                    break;
  370.          case ':':  cln=1; y1=y; x1=x; y=23; x=1;
  371.                     move(23,0); clrtoeol(); mvaddch(23,0,':');  break;
  372.          case '^':  pos=0;     break;
  373.          case '_':  pos=0;     break;
  374.          case '0':  pos=0;     break;
  375.          case '$':  pos=len-1; if (pos==-1)  pos = 0;  break;
  376.          case AR_RIGHT:
  377.          case 'l':  if (pos < len-1)  pos++;  break;
  378.          case ' ':  if (pos < len-1)  pos++;  break;
  379.          case AR_LEFT:
  380.          case 'h':  if (pos > 0)      pos--;  break;
  381.          case 127:  if (pos > 0)      pos--;  break;
  382.          case '\b': if (pos > 0)      pos--;  break;
  383.          case 'D':  for (i=pos; i<len; i++)
  384.                        mvdelch(y,x+pos),mvinsch(y,x+siz-1,' ');
  385.                     len = pos;  pos--;  if (pos == -1)  pos = 0;
  386.                     str[len] = 0;
  387.                    break;
  388.          case 'U':
  389.          case 'u':  strcpy  (str, org);       move (y, x);
  390.                     display (buf, typ, siz);  len=strlen(str);
  391.                    break;
  392.        }
  393.       if (ins)  inslt=pos;
  394.     }
  395.    if (cln) { move(23,0);  clrtoeol();  }
  396.  
  397.    switch (typ)
  398.       {
  399.       case T_CHAR:    strncpy (buf, str, siz);                 break;
  400.       case T_SHORT:   *(short  *)buf  = (short) atoi(str);     break;
  401.       case T_USHORT:  *(ushort *)buf  = (ushort)atoi(str);     break;
  402.       case T_LONG:    *(long   *)buf  = (long)  atol(str);     break;
  403.       case T_ULONG:   *(ulong  *)buf  = (ulong) atol(str);     break;
  404.       case T_FLOAT:   *(float  *)buf  = (float) atof(str);     break;
  405.       case T_DOUBLE:  *(double *)buf  = (double)atof(str);     break;
  406.       case T_MONEY:   tlong = (long)(atof(str) * 100.0);
  407.                       *(double  *)buf  = (double)tlong / 100.0; break;
  408.       case T_SERIAL:  *(long   *)buf  = (long)  atoi(str);     break;
  409.       case T_TIME:    *(mb_time *)buf = scn_time (str);        break;
  410.       case T_DATE:    *(mb_date *)buf = scn_date (str);        break;
  411.       case T_PHONE:   strzcpy (temp, str, 20);
  412.                       scn_phone (&ac, &pre, &num, &ext, temp);
  413.                       strcpy (buf, fmt_phone (ac,pre,num,ext, 0));  break;
  414.       }
  415.  
  416.    move    (y, x);
  417.    display (buf, typ, siz);
  418.  
  419.    return (char) ( (c=='\r') ? (char)0
  420.                  : (c=='x'||c=='Z'||c=='\n'||c==CTRL_A) ? (char)1
  421.                  : (c=='q'||c=='Q') ? (char)-1
  422.                  : tolower(c) );
  423. }
  424.  
  425. void
  426. init_curses ()
  427. {
  428. #if defined(MSDOS) || defined(AMIGA)
  429.    initscr();
  430.    win = stdscr;
  431. #else
  432.    win = initscr();
  433. #endif
  434. #ifdef USE_CURKEY
  435.    keypad(win, TRUE);
  436. #endif
  437. }
  438.  
  439.