summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpiaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2009-10-15 13:41:24 +0800
committerpiaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2009-10-15 13:41:24 +0800
commit3fef3758c320822ddd9e84c45111b1eeb7acbea6 (patch)
tree6039aaccbc2ee67e206348a3de25808026de2a81
parent4d3e5543720103679f6150891a61b290a7ed0728 (diff)
downloadpttbbs-3fef3758c320822ddd9e84c45111b1eeb7acbea6.tar
pttbbs-3fef3758c320822ddd9e84c45111b1eeb7acbea6.tar.gz
pttbbs-3fef3758c320822ddd9e84c45111b1eeb7acbea6.tar.bz2
pttbbs-3fef3758c320822ddd9e84c45111b1eeb7acbea6.tar.lz
pttbbs-3fef3758c320822ddd9e84c45111b1eeb7acbea6.tar.xz
pttbbs-3fef3758c320822ddd9e84c45111b1eeb7acbea6.tar.zst
pttbbs-3fef3758c320822ddd9e84c45111b1eeb7acbea6.zip
* refine vgetstring: add 'redraw' callback and change 'post' to 'change'.
* fix: history navigation in namecomplete caused incorrect further complete git-svn-id: http://opensvn.csie.org/pttbbs/trunk@4934 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
-rw-r--r--pttbbs/include/vtuikit.h9
-rw-r--r--pttbbs/mbbsd/io.c2
-rw-r--r--pttbbs/mbbsd/name.c19
-rw-r--r--pttbbs/mbbsd/vtuikit.c250
4 files changed, 151 insertions, 129 deletions
diff --git a/pttbbs/include/vtuikit.h b/pttbbs/include/vtuikit.h
index 7a2080a9..4866db4f 100644
--- a/pttbbs/include/vtuikit.h
+++ b/pttbbs/include/vtuikit.h
@@ -56,7 +56,11 @@
#define VGET_DIGITS (0x04)
#define VGET_TRANSPARENT (0x08)
#define VGET_ASCII_ONLY (0x10)
-#define VGET_PASSWORD (VGET_NOECHO | VGET_ASCII_ONLY)
+#define VGET_NO_NAV_HISTORY (0x20) // disable UP/DOWN
+#define VGET_NO_NAV_EDIT (0x40) // disable LEFT/RIGHT/HOME/END/DEL
+
+#define VGETSET_DUMB_TERM (VGET_NO_NAV_HISTORY | VGET_NO_NAV_EDIT)
+#define VGETSET_PASSWORD (VGET_NOECHO | VGET_ASCII_ONLY | VGETSET_DUMB_TERM)
// DATATYPE DEFINITION -------------------------------------------------
typedef void * VREFSCR;
@@ -95,7 +99,8 @@ typedef int (*VGET_FCALLBACK)(int key, VGET_RUNTIME *prt, void *instance);
typedef struct {
VGET_FCALLBACK peek; // called immediately after key hit
VGET_FCALLBACK data; // called before inserting character data
- VGET_FCALLBACK post; // called after every data inserted into buffer.
+ VGET_FCALLBACK change; // called after buffer changed (the key may be an editing key)
+ VGET_FCALLBACK redraw; // called before drawing input box unless VGET_NOECHO
} VGET_CALLBACKS;
// API DEFINITION ----------------------------------------------------
diff --git a/pttbbs/mbbsd/io.c b/pttbbs/mbbsd/io.c
index 42e24f10..e0b017ba 100644
--- a/pttbbs/mbbsd/io.c
+++ b/pttbbs/mbbsd/io.c
@@ -713,7 +713,7 @@ getdata2vgetflag(int echo)
else if (echo == NUMECHO)
echo = VGET_DIGITS;
else if (echo == NOECHO)
- echo = VGET_PASSWORD;
+ echo = VGETSET_PASSWORD;
else
echo = VGET_DEFAULT;
diff --git a/pttbbs/mbbsd/name.c b/pttbbs/mbbsd/name.c
index 803434b8..d4cef005 100644
--- a/pttbbs/mbbsd/name.c
+++ b/pttbbs/mbbsd/name.c
@@ -108,20 +108,12 @@ nc_cb_peek(int key, VGET_RUNTIME *prt, void *instance)
return VGETCB_NEXT;
break;
- case KEY_BS: /* backspace */
+ case KEY_BS: /* backspace */
+ case KEY_UP: /* history */
+ case KEY_DOWN: /* history */
nc_int->dirty = -1;
break;
- case KEY_HOME: case Ctrl('A'):
- case KEY_END: case Ctrl('E'):
- case KEY_LEFT: case Ctrl('B'):
- case KEY_RIGHT: case Ctrl('F'):
- case KEY_DEL: case Ctrl('D'):
- case Ctrl('Y'):
- case Ctrl('K'):
- return VGETCB_NEXT;
- break;
-
default:
if (isprint(key)) {
struct Vector tmplist;
@@ -158,14 +150,15 @@ namecomplete2(const struct Vector *namelist, const char *prompt, char *data)
VGET_CALLBACKS vcb = {
.peek = nc_cb_peek,
.data = NULL,
- .post = NULL,
+ .change = NULL,
+ .redraw = NULL,
};
outs(prompt);
clrtoeol();
Vector_init(&nc_int.sublist, IDLEN+1);
Vector_sublist(namelist, &nc_int.sublist, "");
- vgetstring(data, IDLEN + 1, VGET_ASCII_ONLY, NULL, &vcb, &nc_int);
+ vgetstring(data, IDLEN + 1, VGET_ASCII_ONLY|VGET_NO_NAV_EDIT, NULL, &vcb, &nc_int);
Vector_delete(&nc_int.sublist);
}
diff --git a/pttbbs/mbbsd/vtuikit.c b/pttbbs/mbbsd/vtuikit.c
index a18df7a1..351c3d4e 100644
--- a/pttbbs/mbbsd/vtuikit.c
+++ b/pttbbs/mbbsd/vtuikit.c
@@ -971,8 +971,8 @@ vgetstring(char *_buf, int len, int flags, const char *defstr, const VGET_CALLBA
// rt.iend points to NUL address, and
// rt.icurr points to cursor.
int line, col;
- int abort = 0;
- int c;
+ int abort = 0, dirty = 0;
+ int c = 0;
char ismsgline = 0;
// callback
@@ -990,6 +990,10 @@ vgetstring(char *_buf, int len, int flags, const char *defstr, const VGET_CALLBA
if (len > STRLEN) len = STRLEN;
assert(len <= sizeof(buf) && len >= 2);
+ // adjust flags
+ if (flags & (VGET_NOECHO | VGET_DIGITS))
+ flags |= VGET_NO_NAV_HISTORY;
+
// memset(buf, 0, len);
if (defstr && *defstr)
{
@@ -1014,8 +1018,20 @@ vgetstring(char *_buf, int len, int flags, const char *defstr, const VGET_CALLBA
// main loop
while (!abort)
{
+ if (dirty)
+ {
+ dirty = 0;
+ // callback: change
+ if (_vgetcbhandler(cb.change, &abort, c, &rt, instance))
+ continue;
+ }
+
if (!(flags & VGET_NOECHO))
{
+ // callback: redraw
+ if (_vgetcbhandler(cb.redraw, &abort, c, &rt, instance))
+ continue;
+
// print current buffer
move(line, col);
clrtoeol();
@@ -1038,74 +1054,43 @@ vgetstring(char *_buf, int len, int flags, const char *defstr, const VGET_CALLBA
}
c = vkey();
- // callback 1: peek
+ // callback: peek
if (_vgetcbhandler(cb.peek, &abort, c, &rt, instance))
continue;
// standard key bindings
- switch(c) {
- // history navigation
- case KEY_DOWN: case Ctrl('N'):
- c = KEY_DOWN;
- // let UP do the magic.
- case KEY_UP: case Ctrl('P'):
- if ((flags & VGET_NOECHO) ||
- (flags & VGET_DIGITS))
- {
- bell();
- continue;
- }
+ // note: if you processed anything, you must use 'continue' instead of 'break'.
- // NOECHO is already checked...
- if (!InputHistoryExists(buf))
- InputHistoryAdd(buf);
-
- if (c == KEY_DOWN)
- InputHistoryNext(buf, len);
- else
- InputHistoryPrev(buf, len);
-
- rt.icurr = rt.iend = strlen(buf);
- break;
-
- // exiting keys
- case KEY_ENTER:
- abort = 1;
- break;
-
- case Ctrl('C'):
- rt.icurr = rt.iend = 0;
- buf[0] = 0;
- buf[1] = c;
- abort = 1;
- break;
+ if (flags & VGET_NO_NAV_EDIT) {
+ // skip navigation editing keys
+ } else switch (c) {
// standard navigation
case KEY_HOME: case Ctrl('A'):
rt.icurr = 0;
- break;
+ continue;
case KEY_END: case Ctrl('E'):
rt.icurr = rt.iend;
- break;
+ continue;
case KEY_LEFT: case Ctrl('B'):
if (rt.icurr > 0)
- rt.icurr--;
+ rt.icurr--;
else
bell();
if (rt.icurr > 0 && CHKDBCSTRAIL(buf, rt.icurr))
rt.icurr--;
- break;
+ continue;
case KEY_RIGHT: case Ctrl('F'):
if (rt.icurr < rt.iend)
- rt.icurr++;
+ rt.icurr++;
else
bell();
if (rt.icurr < rt.iend && CHKDBCSTRAIL(buf, rt.icurr))
rt.icurr++;
- break;
+ continue;
// editing keys
case KEY_DEL: case Ctrl('D'):
@@ -1113,101 +1098,140 @@ vgetstring(char *_buf, int len, int flags, const char *defstr, const VGET_CALLBA
// kill next one character.
memmove(buf+rt.icurr, buf+rt.icurr+1, rt.iend-rt.icurr);
rt.iend--;
+ dirty = 1;
}
if (rt.icurr < rt.iend) {
// kill next one character.
memmove(buf+rt.icurr, buf+rt.icurr+1, rt.iend-rt.icurr);
rt.iend--;
+ dirty = 1;
}
- break;
+ continue;
+
+ case Ctrl('Y'):
+ rt.icurr = 0;
+ // reuse Ctrl-K code
+ case Ctrl('K'):
+ rt.iend = rt.icurr;
+ if (!buf[rt.iend])
+ continue;
+ buf[rt.iend] = 0;
+ dirty = 1;
+ continue;
+ }
+
+ if (flags & VGET_NO_NAV_HISTORY) {
+ // skip navigation history keys
+ } else switch (c) {
+ // history navigation
+ case KEY_DOWN: case Ctrl('N'):
+ c = KEY_DOWN;
+ // let UP do the magic.
+ case KEY_UP: case Ctrl('P'):
+ // NOECHO is already checked...
+ if (!InputHistoryExists(buf))
+ InputHistoryAdd(buf);
+ if (c == KEY_DOWN)
+ InputHistoryNext(buf, len);
+ else
+ InputHistoryPrev(buf, len);
+
+ rt.icurr = rt.iend = strlen(buf);
+ dirty = 1;
+ continue;
+ }
+
+ // the basic keys
+ switch(c)
+ {
+ // exiting keys
+ case KEY_ENTER:
+ abort = 1;
+ continue;
+
+ case Ctrl('C'):
+ rt.icurr = rt.iend = 0;
+ buf[0] = 0;
+ buf[1] = c; // XXX this is a dirty hack...
+ abort = 1;
+ continue;
+
+ // standard editing keys: backspace
case KEY_BS:
if (rt.icurr > 0) {
// kill previous one charracter.
memmove(buf+rt.icurr-1, buf+rt.icurr, rt.iend-rt.icurr+1);
rt.icurr--; rt.iend--;
+ dirty = 1;
} else
bell();
if (rt.icurr > 0 && CHKDBCSTRAIL(buf, rt.icurr)) {
// kill previous one charracter.
memmove(buf+rt.icurr-1, buf+rt.icurr, rt.iend-rt.icurr+1);
rt.icurr--; rt.iend--;
+ dirty = 1;
}
- break;
-
- case Ctrl('Y'):
- rt.icurr = 0;
- // reuse Ctrl-K code
- case Ctrl('K'):
- rt.iend = rt.icurr;
- buf[rt.iend] = 0;
- break;
-
- // defaults
- default:
-
- // content filter
- if (c < ' ' || c >= 0xFF)
- {
- bell(); continue;
- }
- if ((flags & VGET_DIGITS) &&
- ( !isascii(c) || !isdigit(c)))
- {
- bell(); continue;
- }
- if (flags & VGET_LOWERCASE)
- {
- if (!isascii(c))
- {
- bell(); continue;
- }
- c = tolower(c);
- }
- if (flags & VGET_ASCII_ONLY)
- {
- if (!isprint(c))
- {
- bell(); continue;
- }
- }
+ continue;
+ }
- // size check
- if(rt.iend+1 >= len)
- {
- bell(); continue;
- }
+ // all special keys were processed, now treat as 'input data'.
- // prevent incomplete DBCS
- if (c > 0x80 && num_in_buf() &&
- len - rt.iend < 3) // we need 3 for DBCS+NUL.
- {
- drop_input();
- bell();
- continue;
- }
-
- // callback 2: data
- if (_vgetcbhandler(cb.data, &abort, c, &rt, instance))
- continue;
+ // content filter
+ if (c < ' ' || c >= 0xFF)
+ {
+ bell(); continue;
+ }
+ if ((flags & VGET_DIGITS) &&
+ ( !isascii(c) || !isdigit(c)))
+ {
+ bell(); continue;
+ }
+ if (flags & VGET_LOWERCASE)
+ {
+ if (!isascii(c))
+ {
+ bell(); continue;
+ }
+ c = tolower(c);
+ }
+ if (flags & VGET_ASCII_ONLY)
+ {
+ if (!isascii(c) || !isprint(c))
+ {
+ bell(); continue;
+ }
+ }
- // size check again, due to data callback.
- if(rt.iend+1 >= len)
- {
- bell(); continue;
- }
+ // size check
+ if(rt.iend+1 >= len)
+ {
+ bell(); continue;
+ }
- // add one character.
- memmove(buf+rt.icurr+1, buf+rt.icurr, rt.iend-rt.icurr+1);
- buf[rt.icurr++] = c;
- rt.iend++;
+ // prevent incomplete DBCS
+ if (c > 0x80 && num_in_buf() &&
+ len - rt.iend < 3) // we need 3 for DBCS+NUL.
+ {
+ drop_input();
+ bell(); continue;
+ }
- // callback 3: post
- if (_vgetcbhandler(cb.post, &abort, c, &rt, instance))
- continue;
+ // callback: data
+ if (_vgetcbhandler(cb.data, &abort, c, &rt, instance))
+ continue;
- break;
+ // size check again, due to data callback.
+ if(rt.iend+1 >= len)
+ {
+ bell(); continue;
}
+
+ // add one character.
+ memmove(buf+rt.icurr+1, buf+rt.icurr, rt.iend-rt.icurr+1);
+ buf[rt.icurr++] = c;
+ rt.iend++;
+ dirty = 1;
}
assert(rt.iend >= 0 && rt.iend < len);