int wgetch(WINDOW *win) { static int buffer[_INBUFSIZ]; /* character buffer */ int key, waitcount; PDC_LOG(("wgetch() - called\n")); if (!win) return ERR; waitcount = 0; /* set the number of 1/20th second napms() calls */ if (SP->delaytenths) waitcount = 2 * SP->delaytenths; else if (win->_delayms) { /* Can't really do millisecond intervals, so delay in 1/20ths of a second (50ms) */ waitcount = win->_delayms / 50; if (!waitcount) waitcount = 1; } /* refresh window when wgetch is called if there have been changes to it and it is not a pad */ if (!(win->_flags & _PAD) && ((!win->_leaveit && (win->_begx + win->_curx != SP->curscol || win->_begy + win->_cury != SP->cursrow)) || is_wintouched(win))) wrefresh(win); /* if ungotten char exists, remove and return it */ if (c_ungind) return c_ungch[--c_ungind]; /* if normal and data in buffer */ if ((!SP->raw_inp && !SP->cbreak) && (c_gindex < c_pindex)) return buffer[c_gindex++]; /* prepare to buffer data */ c_pindex = 0; c_gindex = 0; /* to get here, no keys are buffered. go and get one. */ for (;;) /* loop for any buffering */ { /* is there a keystroke ready? */ if (!PDC_check_key()) { /* if not, handle timeout() and halfdelay() */ if (SP->delaytenths || win->_delayms) { if (!waitcount) return ERR; waitcount--; } else if (win->_nodelay) return ERR; napms(50); /* sleep for 1/20th second */ continue; /* then check again */ } /* if there is, fetch it */ key = PDC_get_key(); if (SP->key_code) { /* filter special keys if not in keypad mode */ if (!win->_use_keypad) key = -1; /* filter mouse events; translate mouse clicks in the slk area to function keys */ else if (key == KEY_MOUSE) key = _mouse_key(); } /* unwanted key? loop back */ if (key == -1) continue; /* translate CR */ if (key == '\r' && SP->autocr && !SP->raw_inp) key = '\n'; /* if echo is enabled */ if (SP->echo && !SP->key_code) { waddch(win, key); wrefresh(win); } /* if no buffering */ if (SP->raw_inp || SP->cbreak) return key; /* if no overflow, put data in buffer */ if (key == '\b') { if (c_pindex > c_gindex) c_pindex--; } else if (c_pindex < _INBUFSIZ - 2) buffer[c_pindex++] = key; /* if we got a line */ if (key == '\n' || key == '\r') return buffer[c_gindex++]; } }
wgetn_wstr(WINDOW *win, wint_t *str, int maxlen) { SCREEN *sp = _nc_screen_of(win); TTY buf; bool oldnl, oldecho, oldraw, oldcbreak; wint_t erasec; wint_t killc; wint_t *oldstr = str; wint_t *tmpstr = str; wint_t ch; int y, x, code; T((T_CALLED("wgetn_wstr(%p,%p, %d)"), (void *) win, (void *) str, maxlen)); if (!win) returnCode(ERR); _nc_get_tty_mode(&buf); oldnl = sp->_nl; oldecho = sp->_echo; oldraw = sp->_raw; oldcbreak = sp->_cbreak; nl(); noecho(); noraw(); cbreak(); erasec = (wint_t) erasechar(); killc = (wint_t) killchar(); getyx(win, y, x); if (is_wintouched(win) || (win->_flags & _HASMOVED)) wrefresh(win); while ((code = wget_wch(win, &ch)) != ERR) { /* * Map special characters into key-codes. */ if (ch == '\r') ch = '\n'; if (ch == '\n') { code = KEY_CODE_YES; ch = KEY_ENTER; } if (ch < KEY_MIN) { if (ch == erasec) { ch = KEY_BACKSPACE; code = KEY_CODE_YES; } if (ch == killc) { ch = KEY_EOL; code = KEY_CODE_YES; } } if (code == KEY_CODE_YES) { /* * Some terminals (the Wyse-50 is the most common) generate a \n * from the down-arrow key. With this logic, it's the user's * choice whether to set kcud=\n for wget_wch(); terminating * *getn_wstr() with \n should work either way. */ if (ch == KEY_DOWN || ch == KEY_ENTER) { if (oldecho == TRUE && win->_cury == win->_maxy && win->_scroll) wechochar(win, (chtype) '\n'); break; } if (ch == KEY_LEFT || ch == KEY_BACKSPACE) { if (tmpstr > oldstr) { tmpstr = WipeOut(win, y, x, oldstr, tmpstr, oldecho); } } else if (ch == KEY_EOL) { while (tmpstr > oldstr) { tmpstr = WipeOut(win, y, x, oldstr, tmpstr, oldecho); } } else { beep(); } } else if (maxlen >= 0 && tmpstr - oldstr >= maxlen) { beep(); } else { *tmpstr++ = ch; *tmpstr = 0; if (oldecho == TRUE) { int oldy = win->_cury; if (wadd_wint(win, tmpstr - 1) == ERR) { /* * We can't really use the lower-right corner for input, * since it'll mess up bookkeeping for erases. */ win->_flags &= ~_WRAPPED; waddch(win, (chtype) ' '); tmpstr = WipeOut(win, y, x, oldstr, tmpstr, oldecho); continue; } else if (win->_flags & _WRAPPED) { /* * If the last waddch forced a wrap & scroll, adjust our * reference point for erasures. */ if (win->_scroll && oldy == win->_maxy && win->_cury == win->_maxy) { if (--y <= 0) { y = 0; } } win->_flags &= ~_WRAPPED; } wrefresh(win); } } } win->_curx = 0; win->_flags &= ~_WRAPPED; if (win->_cury < win->_maxy) win->_cury++; wrefresh(win); /* Restore with a single I/O call, to fix minor asymmetry between * raw/noraw, etc. */ sp->_nl = oldnl; sp->_echo = oldecho; sp->_raw = oldraw; sp->_cbreak = oldcbreak; (void) _nc_set_tty_mode(&buf); *tmpstr = 0; if (code == ERR) { if (tmpstr == oldstr) { *tmpstr++ = WEOF; *tmpstr = 0; } returnCode(ERR); } T(("wgetn_wstr returns %s", _nc_viswibuf(oldstr))); returnCode(OK); }