#include <sys/types.h>
#include "curses_inc.h"
#define LENGTH 256
int
wgetstr(WINDOW *win, char *str)
{
return ((wgetnstr(win, str, LENGTH) == ERR) ? ERR : OK);
}
int
wgetnstr(WINDOW *win, char *str, int n)
{
int cpos = 0, ch;
int nbyte = 0;
int tbyte = 0;
int byte[LENGTH];
int eucw, scrw;
int docont = 0;
char *cp = str;
int i = 0;
int total = 0;
char myerase, mykill;
char rownum[LENGTH], colnum[LENGTH], length[LENGTH];
int doecho = SP->fl_echoit;
int savecb = cur_term->_fl_rawmode;
bool savsync, savimmed, savleave;
#ifdef DEBUG
if (outf)
fprintf(outf, "doecho %d, savecb %d\n", doecho, savecb);
#endif
myerase = erasechar();
mykill = killchar();
if (!savecb)
(void) cbreak();
if (doecho) {
SP->fl_echoit = FALSE;
savsync = win->_sync;
savimmed = win->_immed;
savleave = win->_leave;
win->_immed = win->_sync = win->_leave = FALSE;
(void) wrefresh(win);
if (n > LENGTH)
n = LENGTH;
}
n--;
while (nbyte < n) {
if (doecho && !docont) {
rownum[cpos] = win->_cury;
colnum[cpos] = win->_curx;
}
ch = wgetch(win);
if (docont)
goto cont;
if ((ch == ERR) || (ch == '\n') || (ch == '\r') ||
(ch == KEY_ENTER))
break;
if ((ch == myerase) || (ch == KEY_LEFT) ||
(ch == KEY_BACKSPACE) || (ch == mykill)) {
if (cpos > 0) {
if (ch == mykill) {
i = total;
total = cpos = 0;
nbyte = 0;
cp = str;
} else {
cpos--;
cp -= byte[cpos];
if (doecho)
total -= (i = length[cpos]);
}
if (doecho) {
(void) wmove(win, rownum[cpos],
colnum[cpos]);
for (; i > 0; i--)
(void) waddch(win, ' ');
(void) wmove(win, rownum[cpos],
colnum[cpos]);
(void) wrefresh(win);
}
} else
if (doecho)
(void) beep();
} else if ((KEY_MIN <= ch) && (ch <= KEY_MAX))
(void) beep();
else {
cont:
*cp++ = (char)ch;
if (docont) {
tbyte++;
} else if (ISMBIT(ch)) {
docont = 1;
tbyte = 1;
scrw = mbscrw(ch);
eucw = mbeucw(ch);
}
if (docont && (tbyte >= eucw)) {
docont = 0;
tbyte = 0;
if (doecho) {
byte[cpos] = eucw;
length[cpos] = (char)scrw;
(void) wechochar(win,
(chtype) ch);
}
} else if (doecho) {
byte[cpos] = 1;
if (ch >= ' ')
length[cpos] = 1;
else
if (ch == '\t')
length[cpos] = TABSIZE-
(colnum[cpos] %
TABSIZE);
else
length[cpos] = 2;
total += length[cpos];
(void) wechochar(win, (chtype) ch);
}
if (!docont)
cpos++;
nbyte++;
}
}
*cp = '\0';
if (!savecb)
(void) nocbreak();
if (doecho) {
SP->fl_echoit = TRUE;
win->_curx = 0;
if (win->_cury + 1 > win->_bmarg)
(void) wscrl(win, 1);
else
win->_cury++;
win->_sync = savsync;
win->_immed = savimmed;
win->_leave = savleave;
(void) wrefresh(win);
}
return (ch);
}