X-Git-Url: https://ncurses.scripts.mit.edu/?p=ncurses.git;a=blobdiff_plain;f=ncurses%2Fwidechar%2Flib_get_wstr.c;h=695b5263946ab32569e2e76bae8a189fdf3ab474;hp=9467e53fc9e11e073d86164f1dc0980782127010;hb=a6ff7e087fd944fd0035075d0bb528e95e498d81;hpb=46722468f47c2b77b3987729b4bcf2321cccfd01 diff --git a/ncurses/widechar/lib_get_wstr.c b/ncurses/widechar/lib_get_wstr.c index 9467e53f..695b5263 100644 --- a/ncurses/widechar/lib_get_wstr.c +++ b/ncurses/widechar/lib_get_wstr.c @@ -1,5 +1,6 @@ /**************************************************************************** - * Copyright (c) 2002 Free Software Foundation, Inc. * + * Copyright 2018,2020 Thomas E. Dickey * + * Copyright 2002-2009,2011 Free Software Foundation, Inc. * * * * Permission is hereby granted, free of charge, to any person obtaining a * * copy of this software and associated documentation files (the * @@ -27,7 +28,7 @@ ****************************************************************************/ /**************************************************************************** - * Author: Thomas E. Dickey 2002 * + * Author: Thomas E. Dickey * ****************************************************************************/ /* @@ -38,25 +39,39 @@ */ #include -#include -MODULE_ID("$Id: lib_get_wstr.c,v 1.4 2002/07/20 19:28:29 tom Exp $") +MODULE_ID("$Id: lib_get_wstr.c,v 1.16 2020/02/02 23:34:34 tom Exp $") + +static int +wadd_wint(WINDOW *win, wint_t *src) +{ + cchar_t tmp; + wchar_t wch[2]; + + wch[0] = (wchar_t) (*src); + wch[1] = 0; + setcchar(&tmp, wch, A_NORMAL, (short) 0, NULL); + return wadd_wch(win, &tmp); +} /* * This wipes out the last character, no matter whether it was a tab, control * or other character, and handles reverse wraparound. */ -static wchar_t * -WipeOut(WINDOW *win, int y, int x, wchar_t * first, wchar_t * last, bool echoed) +static wint_t * +WipeOut(WINDOW *win, int y, int x, wint_t *first, wint_t *last, int echoed) { if (last > first) { *--last = '\0'; if (echoed) { int y1 = win->_cury; int x1 = win->_curx; + int n; wmove(win, y, x); - waddwstr(win, first); + for (n = 0; first[n] != 0; ++n) { + wadd_wint(win, first + n); + } getyx(win, y, x); while (win->_cury < y1 || (win->_cury == y1 && win->_curx < x1)) @@ -69,39 +84,38 @@ WipeOut(WINDOW *win, int y, int x, wchar_t * first, wchar_t * last, bool echoed) } NCURSES_EXPORT(int) -wgetn_wstr(WINDOW *win, wint_t * str, int maxlen) +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; - wchar_t *oldstr; - wchar_t *tmpstr; + wint_t *oldstr = str; + wint_t *tmpstr = str; wint_t ch; int y, x, code; - T((T_CALLED("wgetn_wstr(%p,%p, %d)"), win, str, maxlen)); + T((T_CALLED("wgetn_wstr(%p,%p, %d)"), (void *) win, (void *) str, maxlen)); if (!win) returnCode(ERR); + maxlen = _nc_getstr_limit(maxlen); + _nc_get_tty_mode(&buf); - oldnl = SP->_nl; - oldecho = SP->_echo; - oldraw = SP->_raw; - oldcbreak = SP->_cbreak; + oldnl = sp->_nl; + oldecho = sp->_echo; + oldraw = sp->_raw; + oldcbreak = sp->_cbreak; nl(); noecho(); noraw(); cbreak(); - erasec = erasechar(); - killc = killchar(); - - assert(sizeof(wchar_t) == sizeof(wint_t)); - oldstr = (wchar_t *) str; - tmpstr = (wchar_t *) str; + erasec = (wint_t) erasechar(); + killc = (wint_t) killchar(); getyx(win, y, x); @@ -109,6 +123,25 @@ wgetn_wstr(WINDOW *win, wint_t * str, int maxlen) 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 @@ -116,37 +149,33 @@ wgetn_wstr(WINDOW *win, wint_t * str, int maxlen) * choice whether to set kcud=\n for wget_wch(); terminating * *getn_wstr() with \n should work either way. */ - if (ch == '\n' - || ch == '\r' - || ch == KEY_DOWN - || ch == KEY_ENTER) { + if (ch == KEY_DOWN || ch == KEY_ENTER) { if (oldecho == TRUE && win->_cury == win->_maxy && win->_scroll) wechochar(win, (chtype) '\n'); break; } - if (ch == erasec || ch == KEY_LEFT || ch == KEY_BACKSPACE) { + if (ch == KEY_LEFT || ch == KEY_BACKSPACE) { if (tmpstr > oldstr) { tmpstr = WipeOut(win, y, x, oldstr, tmpstr, oldecho); } - } else if (ch == killc) { + } 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) { + } else if (tmpstr - oldstr >= maxlen) { beep(); } else { *tmpstr++ = ch; + *tmpstr = 0; if (oldecho == TRUE) { int oldy = win->_cury; - cchar_t tmp; - setcchar(&tmp, tmpstr - 1, A_NORMAL, 0, NULL); - if (wadd_wch(win, &tmp) == ERR) { + 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. @@ -183,23 +212,23 @@ wgetn_wstr(WINDOW *win, wint_t * str, int maxlen) /* 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; + 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++ = (wchar_t)WEOF; + *tmpstr++ = WEOF; *tmpstr = 0; } returnCode(ERR); } - T(("wgetn_wstr returns %s", _nc_viswbuf(oldstr))); + T(("wgetn_wstr returns %s", _nc_viswibuf(oldstr))); returnCode(OK); }