]> git.decadent.org.uk Git - ap-utils.git/blobdiff - lib/input.c
Imported Upstream version 1.5
[ap-utils.git] / lib / input.c
index 2e918ee83cf33b8324a0d0c64b6eabe079bcc89f..b966f12558d5c303a803101723e544ad83510cdb 100644 (file)
@@ -1,8 +1,9 @@
 /*
- *      scr.c from Access Point SNMP Utils for Linux
+ *      input.c from Access Point SNMP Utils for Linux
  *     program input & screen related functions
  *
  * Copyright (c) 2002 Roman Festchook <roma at polesye dot net>
+ * Copyright (c) 2005 Jan Rafaj <jr-aputils at cedric dot unob dot cz>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License Version 2 from
 #include <string.h>
 #include <unistd.h>
 #include <menu.h>
+#include <errno.h>
 #include "ap-utils.h"
-#include "ap-curses.h"
 
-extern WINDOW *main_sub, *win_for_help, *main_win;
+extern WINDOW *main_sub, *win_for_help;
 
 #define GEN_IV_MSG _("Invalid value. Press any key to continue.")
-#define OOR_IV_MSG _("Value must be in range %i - %i. Press any key to continue.")
+#define OOR_IV_MSG _("Value must be in range %u - %u. Press any key to continue.")
 
 #define MAC_LEN 12
 #define MAC_BYTES 6
@@ -40,8 +41,9 @@ get_mac(char *mac, int row, int col)
     char message[MAC_LEN+1], mess[MAC_LEN/MAC_BYTES+1];
     int i;
 
-    get_value(message, row, col, MAC_LEN+1, HEX_STRING, 0, 0, NULL);
-    if (strlen(message) < 12) i = 255;
+    message[0] = '\0';
+    while (strlen(message) != 12)
+       get_value(message, row, col, MAC_LEN+1, HEX_STRING, 0, 0, NULL);
 
     for (i = 0; i < MAC_BYTES; i++) {
        mess[0] = message[2 * i];
@@ -75,9 +77,10 @@ get_ip_again:
 void
 get_mask(struct in_addr *ip, int row, int col, char *helpmsg)
 {
-    int i, bit, hmask, trans_count = 0;
+    int i, bit, hmask, trans_count;
 
 get_mask_again:
+    trans_count = 0;
     get_ip(ip, row, col, helpmsg);
     hmask = ntohl(ip->s_addr);
     bit = hmask & 0x00000001;
@@ -103,14 +106,15 @@ get_mask_again:
  * value ....... this should keep the value, entered by the user,
  *              in ascii string notation
  * row
- * col ......... the begin coordinate, relative to the current window,
+ * col ......... the begin coordinates, relative to the current window,
  *              at which the string entered by the user will appear
  * len ......... maximum length of the entered string, including the
- *              tailing '\0' character
+ *              tailing '\0' character. Negative value along with
+ *              vt=ANY_STRING means that zero-length string is allowed.
  * vt .......... desired input value type (types INT_STRING, HEX_STRING,
  *              ANY_STRING)
  * minv, maxv .. min/max bounds in case of integer value input. Each can be
- *              of value 0 - maxint. If both are 0, it means no value bounds
+ *              of value 0-0xFFFFFFFF. If both are 0, it means no value bounds
  *              checking will be performed. Used only with vt=INT_STRING.
  * helpmsg ..... pointer to string that will be printed after OOR_IV_MSG
  *              message if the entered integer value is out of range.
@@ -120,25 +124,31 @@ get_mask_again:
  */
 void
 get_value(char *value, int row, int col, int len,
-         char vt, int minv, int maxv, char *helpmsg)
+         char vt, unsigned int minv, unsigned int maxv, char *helpmsg)
 {
-    int i;
-    unsigned char c, acs;
-    char iv_msg[128];
+    int c, i, x, y;
+    unsigned char acs;
+    char iv_msg[128], zerolen_perm = 0;
+    enum { INSERT, OVERWRITE } mode;
+    WINDOW *gv_win;
+
+    if (vt == ANY_STRING && len < 0) {
+       zerolen_perm = 1;
+       len = -len;
+    }
+
+    gv_win = derwin(main_sub, 1, len - 1, row, col);
+    wbkgdset(gv_win, A_REVERSE);
 
-    echo();
-    wattrset(main_sub, COLOR_PAIR(2));
 get_value_again:
-    wmove(main_sub, row, col);
-    for (i = 0; i < len - 1; i++)
-       waddch(main_sub, ' ');
+    mode = INSERT;
     curs_set(1);
-    wmove(main_sub, row, col);
-    wrefresh(main_sub);
+    werase(gv_win);
+    wrefresh(gv_win);
 
-    i = 0;
+    i = 0; /* means 'character count' here */
     while (1) {
-       c = getchar();
+       c = getch();
        acs = 0;
        switch (vt) {
            case INT_STRING:
@@ -152,53 +162,116 @@ get_value_again:
            case ANY_STRING:
                acs = 1;
        }
-       if (c == 0x7F) {
-           /* DELETE KEY */
-           if (i > 0) {
-               value[i--] = 0;
-               wmove(main_sub, row, col + i);
-               waddch(main_sub, ' ');
-               /* put backspace to move cursor back */
-               wechochar(main_sub, 0x08);
-           }
-           continue;
-       } else if (c == 0x0D) {
-           /* ENTER KEY */
-           if (i > 0)
+       /* rather do not ask, how this works... */
+       getyx(gv_win, y, x);
+       switch (c) {
+           case KEY_BACKSPACE:
+               /* lefthandside DELETE */
+               if (x > 0) {
+                   /*
+                    * do not step cursor back only if window is filled AND
+                    * cursor is totally on RHS
+                    */
+                   if ((i < len - 1) || (x < len - 2))
+                       x--;
+                   mvwdelch(gv_win, 0, x);
+                   wrefresh(gv_win);
+                   i--;
+               }
                break;
-           continue;
-       } else if (c == 0x1B) {
-           /* ESCAPE KEY */
-           continue;
-       } else if (acs && (i < len - 1)) {
-           value[i++] = c;
-           wechochar(main_sub, c);
+           case KEY_DC:
+               /* righthandside DELETE */
+               if (i > 0) {
+                   if (x == i)
+                       x--;
+                   mvwdelch(gv_win, 0, x);
+                   wrefresh(gv_win);
+                   i--;
+               }
+               break;
+           case KEY_LEFT:
+               if (x > 0) {
+                   wmove(gv_win, 0, --x);
+                   wrefresh(gv_win);
+               }
+               break;
+           case KEY_RIGHT:
+               if (x < i) {
+                   wmove(gv_win, 0, ++x);
+                   wrefresh(gv_win);
+               }
+               break;
+           case KEY_HOME:
+               wmove(gv_win, 0, 0);
+               wrefresh(gv_win);
+               break;
+           case KEY_END:
+               wmove(gv_win, 0, (i == len - 1 ? i - 1 : i));
+               wrefresh(gv_win);
+               break;
+           case KEY_IC:
+               mode = (mode == INSERT ? OVERWRITE : INSERT);
+               curs_set(mode == INSERT ? 1 : 2);
+               break;
+           case 0x0A:
+               /* ENTER KEY */
+               if (i > 0 || zerolen_perm)
+                   goto away;
+
+               break;
+           default:
+               if (acs && (c < 0x100)) {
+                   if (mode == INSERT) {
+                       if (i < len - 1) {
+                           winsch(gv_win, c);
+                           i++;
+                           wmove(gv_win, 0, ++x);
+                           wrefresh(gv_win);
+                       }
+                   } else {
+                       if (i <= len - 1) {
+//                         wechochar(gv_win, c);
+                           waddch(gv_win, c);
+                           if (x == i)
+                               i++;
+                           wmove(gv_win, 0, ++x);
+                           wrefresh(gv_win);
+                       }
+                   }
+               }
        }
     }
+
+away:
+    wmove(gv_win, 0, 0);
+    winnstr(gv_win, value, i);
     value[i] = 0;
+    curs_set(0);
 
-    noecho();
-    if (vt == INT_STRING && (minv | maxv)) {
-       i = atoi(value);
-       if (i < minv || i > maxv) {
-           if (helpmsg) {
-               snprintf(iv_msg, sizeof(iv_msg) - 1, OOR_IV_MSG, minv, maxv);
-               print_helperr(iv_msg);
-               getch();
-               print_help(helpmsg);
+    if (vt == INT_STRING) {
+       i = strtoul(value, (char **)NULL, 10);
+       sprintf(value, "%i", i); /* eat leading zeros */
+       if (minv | maxv) {
+           errno = 0;
+           if ((unsigned)i < minv || (unsigned)i > maxv || errno == ERANGE) {
+               if (helpmsg) {
+                   snprintf(iv_msg, sizeof(iv_msg) -1, OOR_IV_MSG, minv, maxv);
+                   print_helperr(iv_msg);
+                   getch();
+                   print_help(helpmsg);
+               }
+               goto get_value_again;
            }
-           goto get_value_again;
        }
     }
 
-    curs_set(0);
-    wattrset(main_sub, A_BOLD);
-    wmove(main_sub, row, col);
-    for (i = 0; i < len - 1; i++)
-       waddch(main_sub, ' ');
-    mvwaddstr(main_sub, row, col, value);
-    wattrset(main_sub, A_NORMAL);
-    wrefresh(main_sub);
+    wbkgdset(gv_win, A_BOLD);
+    werase(gv_win);
+    waddstr(gv_win, value);
+    wrefresh(gv_win);
+//    mvwprintw(main_sub, 18, 1, "length: %i", i);
+//    wrefresh(main_sub);
+    delwin(gv_win);
 }
 
 /*
@@ -211,7 +284,7 @@ get_pass(char *value, int row, int col, int len)
 {
     int i, j = 0;
 
-    wattrset(main_sub, COLOR_PAIR(2));
+    wattrset(main_sub, COLOR_PAIR(12));
     wmove(main_sub, row, col);
     for (i = 0; i < len - 1; i++)
        waddch(main_sub, ' ');
@@ -284,7 +357,7 @@ int menu_choose(int brow, int bcol, char **names, unsigned int num)
     else
        choose_menu = newwin(nrow, ncol, brow - nrow + 3, bcol + MCOLS);
     sub_choose_menu = derwin(choose_menu, nrow - 2, ncol - 2, 1, 1);
-    attrset(COLOR_PAIR(1));
+    attrset(COLOR_PAIR(11));
 
     mvwaddch(choose_menu, 0, 0, ACS_ULCORNER);
     mvwaddch(choose_menu, 0, ncol - 1, ACS_URCORNER);
@@ -353,3 +426,43 @@ int menu_choose(int brow, int bcol, char **names, unsigned int num)
     }
 }
 
+/*
+ * Reads key by either no-delay getch() (WAIT_FOREVER mode) or using
+ * getch() with tval tenths of second timeout (WAIT_TIMEOUT mode).
+ * Returns 0 for timeout, or pressed key code.
+ */
+int wait_key(int tval)
+{
+    int i;
+    extern int wait_mode;
+
+    if (wait_mode == WAIT_TIMEOUT)
+       timeout(tval * 100);
+
+    i = getch();
+
+    if (wait_mode == WAIT_TIMEOUT) {
+       timeout(-1);
+//     nocbreak();
+//     cbreak();
+    }
+
+    if (i == ERR)
+       i = 0;
+
+    return i;
+}
+
+int help_ysn()
+{
+    char c;
+
+    print_help (_("Y - Yes; Any other key - No (it's safer to answer No)"));
+    c = getch();
+    clear_main(0);
+    if (c == 'y' || c == 'Y')
+       return 0;
+
+    return 1;
+}
+