home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / CONTRIB / MBASE / MBASE51.TAR / mbase51 / src / input.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-09-04  |  12.8 KB  |  476 lines

  1. /*
  2.  * METALBASE 5.1
  3.  *
  4.  * Released January 1st, 1993 by Huan-Ti [ t-richj@microsoft.com ]
  5.  *
  6.  */
  7.  
  8. /*
  9.  * Make sure you include "input.h" before <mbase.h>--see VR.C
  10.  *
  11.  */
  12.  
  13. #include "input.h"
  14. #include <mbase.h>
  15.  
  16.  
  17. WINDOW *win = (WINDOW *)0;
  18. char    editorname[128];
  19.  
  20. /*
  21.  * DEFINITIONS ----------------------------------------------------------------
  22.  *
  23.  */
  24.  
  25. #ifndef F_SETFL
  26.  
  27. #define DELAY_TIME   1
  28.  
  29. #else
  30.  
  31. #ifdef TROUBLE
  32. #define DELAY_TIME  40
  33. #else
  34. #define DELAY_TIME 100
  35. #endif
  36.  
  37. #endif
  38.  
  39.  
  40. /*
  41.  * PROTOTYPES -----------------------------------------------------------------
  42.  *
  43.  */
  44.  
  45. #ifndef MSDOS
  46.    extern long   atol  XARGS( (char *) );
  47.    extern double atof  XARGS( (char *) );
  48. #endif
  49.  
  50.    static int    GetPage XARGS( (char *, mchar *, int) );
  51.  
  52.  
  53.    char    str[160], str2[160];  /* Reenterable one time (for CTRL_E) */
  54.  
  55.  
  56. /*
  57.  * ROUTINES -------------------------------------------------------------------
  58.  *
  59.  */
  60.  
  61. /*
  62.  * getarr() functions like getch(), but returns special codes for arrow
  63.  * keys as well.  If we're compiling with USE_CURKEY, mbase.h has decided
  64.  * that the curses package is capable of returning keycodes directly;
  65.  * if so, we just map them to our defines.  If not, we have to try to snatch
  66.  * the escape codes ourselves.
  67.  *
  68.  */
  69.  
  70. #ifdef USE_CURKEY
  71.  
  72. char
  73. getarr ()
  74. {
  75.    int   ch;
  76.  
  77.    do  ch = (int)getch();
  78.    while (ch == 0);
  79.  
  80.    if (ch == KEY_UP)     return (char)AR_UP;
  81.    if (ch == KEY_DOWN)   return (char)AR_DOWN;
  82.    if (ch == KEY_LEFT)   return (char)AR_LEFT;
  83.    if (ch == KEY_RIGHT)  return (char)AR_RIGHT;
  84.    if (ch == KEY_IC)     return (char)AR_INS;
  85.    if (ch == KEY_DC)     return (char)AR_DEL;
  86.    if (ch == KEY_HOME)   return (char)AR_HOME;
  87.    if (ch == KEY_LL)     return (char)AR_END;
  88.    if (ch == KEY_PPAGE)  return (char)AR_PGUP;
  89.    if (ch == KEY_NPAGE)  return (char)AR_PGDN;
  90.  
  91.    return (char)ch;
  92. }
  93.  
  94. #else
  95.  
  96. char
  97. getarr ()
  98. {
  99.    register int   x;
  100.    char          *a,*b,*c,*d,*e,*f,*g,*h,*i,*j,ch;
  101.    static char   *up="\033[A";
  102.    static char   *down="\033[B";
  103.    static char   *left="\033[D";
  104.    static char   *right="\033[C";
  105.    static char   *ins="\033[@";
  106.    static char   *del="\033[P";
  107.    static char   *home="\033[H";
  108.    static char   *end="\033[24H";
  109.    static char   *pgup="\033[V";
  110.    static char   *pgdn="\033[U";
  111.  
  112.    do {
  113.       ch = (char)getch();  if (ch < 0)  ch = 0;
  114.  
  115.       if (ch != *(a= up))     a=NULL;  else a++;
  116.       if (ch != *(b= down))   b=NULL;  else b++;
  117.       if (ch != *(c= left))   c=NULL;  else c++;
  118.       if (ch != *(d= right))  d=NULL;  else d++;
  119.       if (ch != *(e= ins))    e=NULL;  else e++;
  120.       if (ch != *(f= del))    f=NULL;  else f++;
  121.       if (ch != *(g= home))   g=NULL;  else g++;
  122.       if (ch != *(h= end))    h=NULL;  else h++;
  123.       if (ch != *(i= pgup))   i=NULL;  else i++;
  124.       if (ch != *(j= pgdn))   j=NULL;  else j++;
  125.  
  126.       if (!a && !b && !c && !d && !e && !f && !g && !h && !i && !j)  break;
  127.  
  128. #ifdef F_SETFL
  129.       fcntl (0, F_SETFL, O_NDELAY);  /* Turn off waiting for keys */
  130. #endif
  131.  
  132.       for (;;)
  133.          {
  134.          if (a && !*a) { ch = AR_UP;     break; }
  135.          if (b && !*b) { ch = AR_DOWN;   break; }
  136.          if (c && !*c) { ch = AR_LEFT;   break; }
  137.          if (d && !*d) { ch = AR_RIGHT;  break; }
  138.          if (e && !*e) { ch = AR_INS;    break; }
  139.          if (f && !*f) { ch = AR_DEL;    break; }
  140.          if (g && !*g) { ch = AR_HOME;   break; }
  141.          if (h && !*h) { ch = AR_END;    break; }
  142.          if (i && !*i) { ch = AR_PGUP;   break; }
  143.          if (j && !*j) { ch = AR_PGDN;   break; }
  144.  
  145.          if (!a && !b && !c && !d && !e && !f && !g && !h && !i && !j)
  146.             {
  147.             ch = (*(up));
  148.             break;
  149.             }
  150.  
  151.          for (x=0; x < DELAY_TIME; x++)       /* DELAY_TIME quick reads */
  152.             {
  153.             if ((ch = (char)getch()) > 0)  break;
  154. #ifdef TROUBLE
  155.             usleep (100);
  156. #endif
  157.             }
  158.          if (x == DELAY_TIME)
  159.             {
  160.             ch = (*(up));
  161.             break;
  162.             }
  163.  
  164.          a = (a!=NULL && ch == *a) ? a+1 : NULL;
  165.          b = (b!=NULL && ch == *b) ? b+1 : NULL;
  166.          c = (c!=NULL && ch == *c) ? c+1 : NULL;
  167.          d = (d!=NULL && ch == *d) ? d+1 : NULL;
  168.          e = (e!=NULL && ch == *e) ? e+1 : NULL;
  169.          f = (f!=NULL && ch == *f) ? f+1 : NULL;
  170.          g = (g!=NULL && ch == *g) ? g+1 : NULL;
  171.          h = (h!=NULL && ch == *h) ? h+1 : NULL;
  172.          i = (i!=NULL && ch == *i) ? i+1 : NULL;
  173.          j = (j!=NULL && ch == *j) ? j+1 : NULL;
  174.          }
  175.  
  176. #ifdef F_SETFL
  177.       fcntl (0, F_SETFL, 0);
  178. #endif
  179.       } while (! ch);
  180.  
  181.    return ch;
  182. }
  183.  
  184. #endif
  185.  
  186. bool _fUpdateNow = TRUE;
  187.  
  188. void
  189. display (buf, typ, siz)
  190. dataptr  buf;
  191. ftype         typ;
  192. int                siz;
  193. {
  194.    int       b, a, i, n;
  195.    double    tdouble;
  196.    char      temp[21];
  197.  
  198.    getyx    (win,b,a);
  199.    sprintf  (str, "%-132.132s", "");  str[siz] = 0;
  200.    mvaddstr (b,a, str);
  201.  
  202.    switch (typ)
  203.       {
  204.       case T_CHAR:    strzcpy (str, buf,   siz);                      break;
  205.       case T_SHORT:   sprintf (str, "%d",  (int)*(short  *)buf);      break;
  206.       case T_USHORT:  sprintf (str, "%u",  (int)*(ushort *)buf);      break;
  207.       case T_LONG:    sprintf (str, "%ld", *(long   *)buf);           break;
  208.       case T_ULONG:   sprintf (str, "%lu", *(ulong  *)buf);           break;
  209.       case T_FLOAT:   sprintf (str, "%f",  *(float  *)buf);           break;
  210.       case T_DOUBLE:  sprintf (str, "%lf", *(double *)buf);           break;
  211.       case T_MONEY:   tdouble = *(double *)buf;
  212.                       sprintf (str, "%-.2lf", tomoney(tdouble));      break;
  213.       case T_TIME:    strcpy (str, fmt_time (*(mb_time *)buf, 1));    break;
  214.       case T_DATE:    strcpy (str, fmt_date (*(mb_date *)buf, 0));    break;
  215.       case T_SERIAL:  sprintf (str, "%ld", *(long   *)buf);           break;
  216.       case T_PHONE:   strcpy (str, fmt_phone ((mb_phone *)buf, 1));   break;
  217.       case T_BYTE:    hextostr (str, buf, min(20, siz));              break;
  218.  
  219.       case T_MBYTE:   siz = (int)GetPage (temp, (mchar *)buf, 20);
  220.                       hextostr (str, temp, min(20, siz));             break;
  221.       case T_MCHAR:   n = GetPage (str, (mchar *)buf, 60);
  222.                       for (i = 0; i < n; i++)
  223.                          if (str[i] < ' ')
  224.                             str[i] = '_';
  225.                      break;
  226.       }
  227.  
  228.    if (typ == T_BYTE)  str[3*min(20,siz) -1] = 0;
  229.    else                str[siz] = 0;
  230.  
  231.    mvaddstr (b,a, str);
  232.    move     (b,a);
  233.  
  234.    if (_fUpdateNow)
  235.       refresh ();
  236.    _fUpdateNow = TRUE;
  237. }
  238.  
  239. /*
  240.  * Returns:     0 -- Continue to next field
  241.  *              1 -- Finished with DE
  242.  *             -1 -- Abort DE
  243.  *          other -- Field control (-/+/j/k)
  244.  *
  245.  */
  246.  
  247. char
  248. input   (buf, typ, siz)
  249. dataptr  buf;
  250. ftype         typ;
  251. int                siz;
  252. {
  253.    register int  i;
  254.    double        tdouble;
  255.    char          c;                  /* Character read from keyboard      */
  256.    char         *org;                /* Working buffer, and backup string */
  257.    int           len;                /* Length of working buffer          */
  258.    int           y, x;               /* Position of left-edge on screen   */
  259.    bool          fStart = TRUE;      /* TRUE if just starting             */
  260.    int           pos = 0;            /* Working position within buffer    */
  261.    int           width;              /* Width of edit field (usually siz) */
  262.  
  263.    width = (typ == T_BYTE) ? (3*siz -1) : siz;
  264.  
  265.    raw(); noecho();           /* First we have to initialize the terminal */
  266.    getyx (win, y, x);         /* so we can ensure an active interface.    */
  267.  
  268.    if ((org = (char *)malloc (width+1)) == NULL)
  269.       {
  270.       SetError (MB_NO_MEMORY);
  271.       return -1;  /* Abort DE */
  272.       }
  273.  
  274.    display (buf, typ, siz);   /* Display the original string              */
  275.    len = strlen (str);        /* And remember how long the string is now. */
  276.    numcpy (org, str, width);  /* Then make a backup, so CTRL_U will work. */
  277.  
  278.    if ( (typ == T_MCHAR) || (typ == T_MBYTE) )
  279.       {
  280.       (void)CallService (svcIN_START);
  281.       }
  282.  
  283.    for (;;)
  284.       {
  285.       movech (c,y,x+pos);
  286.  
  287.       if (strchr (quit_chars, c))
  288.          break;
  289.  
  290.       if ( (c == CTRL_E) && ((typ == T_MCHAR) || (typ == T_MBYTE)) )
  291.          {
  292.          strcpy (str2, str);
  293.          strcpy (editorname, DEFAULT_EDITOR);
  294.  
  295.          if (! CallService (svcIN_EDITOR))     /* If aborted here, */
  296.             {
  297.             (void)CallService (svcIN_START);   /* return to editing field */
  298.             continue;
  299.             }
  300.  
  301.          strcpy (str, str2);
  302.          strcat (editorname, " ");
  303.          strcat (editorname, ((mchar *)buf)->name);
  304.  
  305.          system (editorname);
  306.  
  307.          clearok (win, TRUE);
  308.          refresh ();
  309.          move    (y, x);
  310.          display (buf, typ, siz);
  311.  
  312.          (void)CallService (svcIN_START);   /* return to editing field */
  313.          continue;
  314.          }
  315.  
  316.       if (c == ESC)      { c = 'q';  break; }  /* ESC    aborts */
  317.       if (c == CTRL_C)   { c = 'q';  break; }  /* Ctrl-C aborts */
  318.       if (c == CTRL_Q)   { c = 'q';  break; }  /* Ctrl-Q aborts */
  319.       if (c == AR_PGUP)  { c = 'k';  break; }
  320.       if (c == AR_UP)    { c = 'k';  break; }
  321.       if (c == AR_PGDN)  { c = 'j';  break; }
  322.       if (c == AR_DOWN)  { c = 'j';  break; }
  323.       if (c == CTRL_L)   { clearok (win, TRUE);  refresh();  continue; }
  324.       if (c == AR_END)   { pos = len;  continue; }
  325.       if (c == CTRL_U)   { strcpy  (str, org);
  326.                            move (y, x); display (buf, typ, siz);
  327.                            len=strlen(str); fStart = TRUE;
  328.                            c = AR_HOME;  /* Pretend they hit HOME afterward. */
  329.                          }
  330.       if (c == AR_HOME)  { pos = 0;
  331.                            continue;
  332.                          }
  333.       if (c == AR_RIGHT) { if (pos < len)  pos++;
  334.                            continue;
  335.                          }
  336.       if (c == AR_LEFT)  { if (pos > 0)  pos--;
  337.                            continue;
  338.                          }
  339.  
  340.       if (c == '\r' || c == '\n' || c == CTRL_A)
  341.          {
  342.          break;
  343.          }
  344.       if ( (typ == T_MCHAR) || (typ == T_MBYTE) )
  345.          {
  346.          continue;
  347.          }
  348.       if (c == '\b' || c == 127 || c == AR_LEFT || c == AR_DEL)
  349.          {
  350.          if (pos != 0)
  351.             {
  352.             pos--,len--,mvdelch(y,x+pos),mvinsch(y,x+width-1,' ');
  353.             for (i=pos; i<len; i++)
  354.                str[i] = str[i+1];
  355.             str[i] = 0;
  356.             }
  357.          }
  358.       if (c < ' ' || c > '~')
  359.          {
  360.          continue;
  361.          }
  362.  
  363.       if (pos == 0 && fStart)
  364.          {
  365.          for (i=0; i<len; i++)
  366.             mvdelch(y,x),mvinsch(y,x+width-1,' ');
  367.          str[0] = 0;  len = 0;  move(y,x);  refresh();
  368.          }
  369.       fStart = FALSE;
  370.       if (len == width)  continue;
  371.       insch(c);  mvdelch(y,x+width);
  372.       for (i=len-1; i>=pos; i--)
  373.          str[i+1] = str[i];
  374.       len++;  str[len] = 0;
  375.       str[pos] = c;  pos++;
  376. #ifdef ADVANCE_AT_END
  377.       if (len == width) { c = 'j'; break; }
  378. #endif
  379.       continue;
  380.       }
  381.  
  382.    if ( (typ == T_MCHAR) || (typ == T_MBYTE) )
  383.       {
  384.       (void)CallService (svcIN_END);
  385.       }
  386.  
  387.    if (c == 'q' || c == 'Q')  /* If backing out, restore original string. */
  388.       {
  389.       strcpy (str, org);
  390.       }
  391.  
  392.    switch (typ)
  393.       {
  394.       case T_CHAR:    strncpy (buf, str, siz);                 break;
  395.       case T_SHORT:   *(short  *)buf  = (short) atoi(str);     break;
  396.       case T_USHORT:  *(ushort *)buf  = (ushort)atoi(str);     break;
  397.       case T_LONG:    *(long   *)buf  = (long)  atol(str);     break;
  398.       case T_ULONG:   *(ulong  *)buf  = (ulong) atol(str);     break;
  399.       case T_FLOAT:   *(float  *)buf  = (float) atof(str);     break;
  400.       case T_DOUBLE:  *(double *)buf  = (double)atof(str);     break;
  401.       case T_MONEY:   tdouble = (double)atof(str);
  402.                       *(double  *)buf  = tomoney(tdouble);     break;
  403.       case T_SERIAL:  *(long   *)buf  = (long)  atoi(str);     break;
  404.       case T_TIME:    *(mb_time *)buf = scn_time (str);        break;
  405.       case T_DATE:    *(mb_date *)buf = scn_date (str);        break;
  406.       case T_PHONE:   scn_phone ((mb_phone *)buf, str);        break;
  407.       case T_BYTE:    strtohex (buf, str, siz);                break;
  408.       }
  409.  
  410.    free (org);
  411.  
  412.    move    (y, x);
  413.    display (buf, typ, siz);
  414.  
  415.    return (char) ( (c=='\r') ? (char)0
  416.                  : (c=='x'||c=='Z'||c=='\n'||c==CTRL_A) ? (char)1
  417.                  : (c=='q'||c=='Q') ? (char)-1
  418.                  : tolower(c) );
  419. }
  420.  
  421. void
  422. init_curses ()
  423. {
  424. #ifdef MSDOS
  425.    initscr();
  426.    win = stdscr;
  427. #else
  428. #ifdef AMIGA
  429.    initscr();
  430.    win = stdscr;
  431. #else
  432.    win = initscr();
  433. #endif
  434. #endif
  435. #ifdef USE_CURKEY
  436.    keypad(win, TRUE);
  437. #endif
  438.  
  439.    savetty();
  440.    raw();
  441.    noecho();
  442.    nl();
  443.    clear();
  444. }
  445.  
  446. void
  447. exit_curses ()
  448. {
  449.    clear   ();
  450.    refresh ();
  451.    endwin  ();
  452.    resetty ();
  453. }
  454.  
  455. static int
  456. GetPage (dest, ptr, n)
  457. char    *dest;
  458. mchar         *ptr;
  459. int                 n;
  460. {
  461.    file  fh;
  462.  
  463.    if ((fh = openx (ptr->name, READMODE)) <= 0)
  464.       n = 0;
  465.    else
  466.       {
  467.       lseek (fh, 0L, 0);
  468.       n = readx (fh, dest, n);
  469.       close (fh);
  470.       }
  471.  
  472.    dest[n] = 0;
  473.    return n;
  474. }
  475.  
  476.