/* Prints line onto a window highlighting it according to attrs, which should * specify 0-9 color groups for every character in line. */ static void print_with_attrs(WINDOW *win, const char line[], const char attrs[], const cchar_t *default_attr) { cchar_t attr = *default_attr; while(*line != '\0') { if(*attrs == '0') { attr = *default_attr; } else if(*attrs != ' ') { const int color = (USER1_COLOR + (*attrs - '1')); col_attr_t col = cfg.cs.color[STATUS_LINE_COLOR]; cs_mix_colors(&col, &cfg.cs.color[color]); setcchar(&attr, L" ", col.attr, colmgr_get_pair(col.fg, col.bg), NULL); } const size_t len = utf8_chrw(line); char char_buf[len + 1]; copy_str(char_buf, sizeof(char_buf), line); wprinta(win, char_buf, &attr, 0); line += len; attrs += utf8_chrsw(char_buf); } }
static char * decode_cchar(char *source, cchar_t *fillin, cchar_t *target) { int color; attr_t attr = fillin->attr; wchar_t chars[CCHARW_MAX]; int append = 0; int value = 0; T(("decode_cchar '%s'", source)); *target = blank; #if NCURSES_EXT_COLORS color = fillin->ext_color; #else color = (int) PAIR_NUMBER(attr); #endif source = decode_attr(source, &attr, &color); memset(chars, 0, sizeof(chars)); source = decode_char(source, &value); chars[0] = (wchar_t) value; /* handle combining characters */ while (source[0] == MARKER && source[1] == APPEND) { source += 2; source = decode_char(source, &value); if (++append < CCHARW_MAX) { chars[append] = (wchar_t) value; } } setcchar(target, chars, attr, (short) color, NULL); return source; }
static void send_bytes(int portfd, const unsigned char* buf, int n, WINDOW* win) { ssize_t written = 0; while (written < n) { ssize_t rc = write(portfd, &buf[written], n - written); if (rc >= 0) written += rc; else if (errno != EINTR) exit_error("send bytes", errno); } int xmax, ymax; getmaxyx(win, ymax, xmax); --xmax; if (n > xmax) { buf += n - xmax; n = xmax; } int x, y; getyx(win, y, x); int ndel = x + n - xmax; if (ndel > 0) { wmove(win, y, 0); for (int i = 0; i < ndel; ++i) wdelch(win); wmove(win, y, x - ndel); } for (int i = 0; i < n; ++i) { cchar_t cc; wchar_t wc[CCHARW_MAX]; attr_t attrs; short color_pair; wgetbkgrnd(win, &cc); getcchar(&cc, wc, &attrs, &color_pair, 0); wc[0] = kc_to_wide_char(buf[i]); setcchar(&cc, wc, attrs, color_pair, 0); wadd_wch(win, &cc); } while (tcdrain(portfd) < 0) { if (errno != EINTR) exit_error("send bytes", errno); } }
static void make_fullwidth_digit(cchar_t *target, int digit) { wchar_t source[2]; source[0] = (wchar_t) (digit + 0xff10); source[1] = 0; setcchar(target, source, A_NORMAL, 0, 0); }
bool ncurses_init(struct gol *g) { initscr(); if (!validate_rows_and_columns(g)) return false; cbreak(); noecho(); curs_set(0); nodelay(stdscr, true); clear(); refresh(); setcchar(&g->ncurses_alive_character, (wchar_t*) &g->alive_character, 0, 0, 0); setcchar(&g->ncurses_not_alive_character, (wchar_t*) &g->not_alive_character, 0, 0, 0); return true; }
static void char_for_tile(Tile tile, cchar_t *pic) { switch (tile) { case TILE_WALL: setcchar(pic, FULL_BLOCK, WA_NORMAL, COLOR_PAIR(1), NULL); break; case TILE_WALL_DARK: setcchar(pic, DARK_SHADE, WA_NORMAL, COLOR_PAIR(1), NULL); break; case TILE_EMPTY: setcchar(pic, MEDIUM_SHADE, WA_NORMAL, COLOR_PAIR(1), NULL); break; case TILE_EMPTY_DARK: setcchar(pic, LIGHT_SHADE, WA_NORMAL, COLOR_PAIR(1), NULL); break; case TILE_UNKNOWN: default: setcchar(pic, EMPTY_BLOCK, WA_NORMAL, COLOR_PAIR(1), NULL); } }
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, 0, NULL); return wadd_wch(win, &tmp); }
static int ConvertCh(chtype source, cchar_t *target) { wchar_t tmp_wchar[2]; tmp_wchar[0] = (wchar_t) source; tmp_wchar[1] = 0; if (setcchar(target, tmp_wchar, A_NORMAL, 0, (void *) 0) == ERR) { beep(); return FALSE; } return TRUE; }
void build_gpkg(struct gpkg *g) { int n, i; n = g->n; while (n-->0) { g->len[n] = (sizeof(wchar_t))*(wcslen(g->wch[n])+1); g->cch[n] = malloc(g->len[n] * sizeof(cchar_t)); for (i=0; i<(g->len[n]); i++) { setcchar(&g->cch[n][i], &g->wch[n][i], 0, g->pair, NULL); } } }
void hftirc_waddwch(WINDOW *w, unsigned int mask, wchar_t wch) { cchar_t cch; wchar_t wstr[2] = { wch }; wattron(w, mask); if(setcchar(&cch, wstr, A_NORMAL, 0, NULL) == OK) (void)wadd_wch(w, &cch); wattroff(w, mask); }
static cchar_t * makecchar(wchar_t in) { static cchar_t cc; wchar_t wc[2]; wc[0] = in; wc[1] = L'\0'; if (setcchar(&cc, wc, A_NORMAL, 0, NULL) != OK) p_error("settchar(3) failure"); return (&cc); }
WINDOW* window_create_shadow(WINDOW *window,WINDOW *window_below) { /* WINDOW *window_below; */ extern WINDOW *SCREEN_WINDOW; WINDOW *shadow_window; gint width,height; gint beg_x,beg_y; gint x,y; #ifdef _VIPER_WIDE cchar_t wcval; wchar_t wch; attr_t attrs; short color_pair; #else chtype char_attr; #endif if(window==NULL) return window; getmaxyx(window,height,width); getbegyx(window,beg_y,beg_x); if(window_below==NULL) window_below=SCREEN_WINDOW; shadow_window=newwin(height,width,beg_y+1,beg_x+1); for(y=0;y<height;y++) { for(x=0;x<width;x++) { #ifdef _VIPER_WIDE mvwin_wch(window_below,beg_y+y+1,beg_x+x+1,&wcval); getcchar(&wcval,&wch,&attrs,&color_pair,NULL); setcchar(&wcval,&wch,attrs, viper_color_pair(COLOR_WHITE,COLOR_BLACK),NULL); mvwadd_wch(shadow_window,y,x,&wcval); #else char_attr=mvwinch(window_below,beg_y+y+1,beg_x+x+1); mvwaddch(shadow_window,y,x,char_attr & A_CHARTEXT); if((char_attr & A_ALTCHARSET)==A_ALTCHARSET) mvwchgat(shadow_window,y,x,1,A_NORMAL | A_ALTCHARSET, viper_color_pair(COLOR_WHITE,COLOR_BLACK),NULL); else mvwchgat(shadow_window,y,x,1,A_NORMAL, viper_color_pair(COLOR_WHITE,COLOR_BLACK),NULL); #endif } } return shadow_window; }
int addch_unicode(int c) { wchar_t wch; cchar_t cch; if (unicode_mode) { // We can do this because we've already verified // that __STDC_ISO_10646__ is set. wch = c; setcchar(&cch, &wch, 0, 0, NULL); return add_wch(&cch); } else { return addch(lookup_unicode_hack(c)); } }
wins_nwstr(WINDOW *win, const wchar_t *wstr, int n) { int code = ERR; NCURSES_SIZE_T oy; NCURSES_SIZE_T ox; const wchar_t *cp; T((T_CALLED("wins_nwstr(%p,%s,%d)"), (void *) win, _nc_viswbufn(wstr, n), n)); if (win != 0 && wstr != 0) { if (n < 1) n = (int) wcslen(wstr); code = OK; if (n > 0) { SCREEN *sp = _nc_screen_of(win); oy = win->_cury; ox = win->_curx; for (cp = wstr; *cp && ((cp - wstr) < n); cp++) { int len = wcwidth(*cp); if ((len >= 0 && len != 1) || !is7bits(*cp)) { cchar_t tmp_cchar; wchar_t tmp_wchar = *cp; memset(&tmp_cchar, 0, sizeof(tmp_cchar)); (void) setcchar(&tmp_cchar, &tmp_wchar, WA_NORMAL, (short) 0, (void *) 0); code = _nc_insert_wch(win, &tmp_cchar); } else { /* tabs, other ASCII stuff */ code = _nc_insert_ch(sp, win, (chtype) (*cp)); } if (code != OK) break; } win->_curx = ox; win->_cury = oy; _nc_synchook(win); } } returnCode(code); }
void FalloutDisplay::print_attempts(int attempts, int delay_ms) { cchar_t block_char; setcchar(&block_char, L"█ ", 0, COLOR_PAIR(1), NULL); std::string out = std::to_string(attempts) + " ATTEMPT(S) LEFT: "; // position needs to be made adjustable move_print_string_char_dly(out, 1, 4, delay_ms); for (int i = 0; i < (attempts * 2); i+= 2) { mvadd_wch(4, 20 + i, &block_char); usleep((delay_ms * 1000)); refresh(); } }
void ui_stat_update(view_t *view, int lazy_redraw) { if(!cfg.display_statusline || view != curr_view) { return; } /* Don't redraw anything until :restart command is finished. */ if(curr_stats.restart_in_progress) { return; } ui_stat_job_bar_check_for_updates(); if(cfg.status_line[0] == '\0') { update_stat_window_old(view, lazy_redraw); return; } const int width = getmaxx(stdscr); wresize(stat_win, 1, width); ui_set_bg(stat_win, &cfg.cs.color[STATUS_LINE_COLOR], cfg.cs.pair[STATUS_LINE_COLOR]); werase(stat_win); checked_wmove(stat_win, 0, 0); cchar_t default_attr; setcchar(&default_attr, L" ", cfg.cs.color[STATUS_LINE_COLOR].attr, cfg.cs.pair[STATUS_LINE_COLOR], NULL); LineWithAttrs result = expand_status_line_macros(view, cfg.status_line); assert(strlen(result.attrs) == utf8_strsw(result.line) && "Broken attrs!"); result.line = break_in_two(result.line, width, "%="); result.attrs = break_in_two(result.attrs, width, "="); print_with_attrs(stat_win, result.line, result.attrs, &default_attr); free(result.line); free(result.attrs); refresh_window(stat_win, lazy_redraw); }
static void receive_kctext(int portfd, WINDOW* win) { unsigned char buf[64]; ssize_t count; while ((count = read(portfd, buf, sizeof buf)) < 0) switch (errno) { case EINTR: continue; #if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN) case EWOULDBLOCK: #endif case EAGAIN: return; default: exit_error("receive KC text", errno); } cchar_t cc; wchar_t wc[CCHARW_MAX]; attr_t attrs; short color_pair; wgetbkgrnd(win, &cc); getcchar(&cc, wc, &attrs, &color_pair, 0); for (ssize_t i = 0; i < count; ++i) { unsigned int byte = buf[i]; if (byte != 0x00 && byte != 0x03 && byte != 0x0D) { wc[0] = (byte == 0x0A) ? L'\n' : kc_to_wide_char(byte); setcchar(&cc, wc, attrs, color_pair, 0); wadd_wch(win, &cc); } } wnoutrefresh(win); }
int Window::PrintChar(gunichar uc) { /** * @todo Error checking (setcchar). */ if (uc >= 0x7f && uc < 0xa0) { // filter out C1 (8-bit) control characters waddch(p->win, '?'); return 1; } // get a unicode character from the next few bytes wchar_t wch[2]; cchar_t cc; wch[0] = uc; wch[1] = L'\0'; // invalid utf-8 sequence if (wch[0] < 0) return 0; // tab character if (wch[0] == '\t') { int w = onscreen_width(wch[0]); for (int i = 0; i < w; i++) waddch(p->win, ' '); return w; } // control char symbols if (wch[0] < 32) wch[0] = 0x2400 + wch[0]; setcchar(&cc, wch, A_NORMAL, 0, NULL); wadd_wch(p->win, &cc); return onscreen_width(wch[0]); }
/* input:addch(ch) put a wide character */ int lui_addch_input(lua_State *L) { INPUT *i; wchar_t *wstr; size_t len; cchar_t ch; luasoul_checkclass(L, 1, INPUT_CLASS, i); /* get input */ luasoul_checklwcstr(L, 2, wstr, len); /* get wstring */ /* FIXME: correct attributs to setcchar() ? */ if (setcchar(&ch, wstr, WA_NORMAL, 0, NULL) == OK && wins_wch(i->pad, &ch) == OK) { /* man setcchar() ...contain at most one spacing character, which must be the first */ len = (size_t) wcwidth(*wstr); if (len != (size_t) -1 && len) /* don't move for 0 width */ set_current_position(i, get_current_position(i) + len); } return 0; }
cchar_t *mkcch(const wchar_t *wch, attr_t attr, short pair) { setcchar(&SHARED_CCH, wch, attr, pair, NULL); return (&SHARED_CCH); }
/* * Create and return a pointer to a new window or pad. * * For a window, provide the dimensions and location of the upper * left hand corner of the window. If either dimension is zero (0) * then the default sizes will be LINES-begy and COLS-begx. * * For a pad, provide the dimensions and -1 for begy and begx. * If either dimension is zero (0) then the default sizes will be * LINES and COLS. * * If parent is not null, then create a sub-window of the parent * window. */ WINDOW * __m_newwin(WINDOW *parent, int nlines, int ncols, int begy, int begx) { WINDOW *w; int x, y, dx, dy; int isPad; isPad = ((begy < 0) && (begx < 0)) || (parent && (parent->_flags & W_IS_PAD)); if (parent == NULL) { /* Check for default dimensions. */ if (nlines == 0) { nlines = lines; if (0 <= begy) nlines -= begy; } if (ncols == 0) { ncols = columns; if (0 <= begx) ncols -= begx; } } else { /* * Make sure window dimensions remain within parent's * window so that the new subwindow is a proper subset * of the parent. */ if (begy < parent->_begy || begx < parent->_begx || parent->_maxy < (begy-parent->_begy) + nlines || parent->_maxx < (begx-parent->_begx) + ncols) goto error_1; /* * If either dimension is zero (0), use the max size * for the dimension from the parent window less the * subwindow's starting location. */ if (nlines == 0) nlines = parent->_maxy - (begy - parent->_begy); if (ncols == 0) ncols = parent->_maxx - (begx - parent->_begx); } if (!isPad) { /* Check that a window fits on the screen. */ if (0 <= begy) { if (lines < begy + nlines) { goto error_1; } } if (0 <= begx) { if (columns < begx + ncols) { goto error_1; } } } w = (WINDOW *) calloc(1, sizeof (*w)); if (w == NULL) goto error_1; w->_first = (short *) calloc((size_t) (nlines + nlines), sizeof (*w->_first)); if (w->_first == NULL) goto error_2; w->_last = &w->_first[nlines]; w->_line = (cchar_t **) calloc((size_t) nlines, sizeof (*w->_line)); if (w->_line == NULL) goto error_2; /* Window rendition. */ (void) setcchar(&w->_bg, L" ", WA_NORMAL, 0, (void *) 0); (void) setcchar(&w->_fg, L" ", WA_NORMAL, 0, (void *) 0); if (parent == NULL) { w->_base = (cchar_t *) malloc((size_t) (nlines * ncols) * sizeof (*w->_base)); if (w->_base == NULL) goto error_2; w->_line[0] = w->_base; for (y = 0; y < nlines; y++) { if (y) w->_line[y] = &w->_line[y-1][ncols]; for (x = 0; x < ncols; ++x) { w->_line[y][x] = w->_bg; } } } else { /* * The new window's origin (0,0) maps to (begy, begx) in the * parent's window. In effect, subwin() is a method by which * a portion of a parent's window can be addressed using a * (0,0) origin. */ dy = begy - parent->_begy; dx = begx - parent->_begx; w->_base = NULL; for (y = 0; y < nlines; ++y) w->_line[y] = &parent->_line[dy++][dx]; } w->_begy = (short) begy; w->_begx = (short) begx; w->_cury = w->_curx = 0; w->_maxy = (short) nlines; w->_maxx = (short) ncols; w->_parent = parent; /* Software scroll region. */ w->_top = 0; w->_bottom = (short) nlines; w->_scroll = 0; /* Window initially blocks for input. */ w->_vmin = 1; w->_vtime = 0; w->_flags = W_USE_TIMEOUT; /* Determine window properties. */ if (isPad) { /* This window is a PAD */ w->_flags |= W_IS_PAD; /* Inherit PAD attribute */ if (((begy < 0) && (begx < 0)) || (parent && !(parent->_flags & W_IS_PAD))) { /* Child of a normal window */ w->_begy = w->_begx = 0; /* * Map to upper left portion of * display by default (???) */ w->_sminy = w->_sminx = 0; w->_smaxx = w->_maxx; w->_smaxy = w->_maxy; } } else if (begx + ncols == columns) { /* Writing to last column should trigger auto-margin wrap. */ w->_flags |= W_END_LINE; if (begx == 0) { w->_flags |= W_FULL_LINE; if (begy == 0 && nlines == lines) w->_flags |= W_FULL_WINDOW; } /* Will writing to bottom-right triggers scroll? */ if (begy + nlines == lines) w->_flags |= W_SCROLL_WINDOW; } /* Initial screen clear for full screen windows only. */ if (w->_flags & W_FULL_WINDOW) { w->_flags |= W_CLEAR_WINDOW; /* Reset dirty region markers. */ (void) wtouchln(w, 0, w->_maxy, 0); } else { if (!parent) { /* Do not erase sub windows */ (void) werase(w); } } return (w); error_2: (void) delwin(w); error_1: return (NULL); }
int main(int argc, char *argv[]) { int optc; int option_differences = 0, option_differences_cumulative = 0, option_help = 0, option_version = 0; double interval = 2; char *command; int command_length = 0; /* not including final \0 */ setlocale(LC_ALL, ""); progname = argv[0]; while ((optc = getopt_long(argc, argv, "+d::hn:vt", longopts, (int *) 0)) != EOF) { switch (optc) { case 'd': option_differences = 1; if (optarg) option_differences_cumulative = 1; break; case 'h': option_help = 1; break; case 't': show_title = 0; break; case 'n': { char *str; interval = strtod(optarg, &str); if (!*optarg || *str) do_usage(); if(interval < 0.1) interval = 0.1; if(interval > ~0u/1000000) interval = ~0u/1000000; } break; case 'v': option_version = 1; break; default: do_usage(); break; } } if (option_version) { fprintf(stderr, "%s\n", VERSION); if (!option_help) exit(0); } if (option_help) { fprintf(stderr, usage, progname); fputs(" -d, --differences[=cumulative]\thighlight changes between updates\n", stderr); fputs("\t\t(cumulative means highlighting is cumulative)\n", stderr); fputs(" -h, --help\t\t\t\tprint a summary of the options\n", stderr); fputs(" -n, --interval=<seconds>\t\tseconds to wait between updates\n", stderr); fputs(" -v, --version\t\t\t\tprint the version number\n", stderr); fputs(" -t, --no-title\t\t\tturns off showing the header\n", stderr); exit(0); } if (optind >= argc) do_usage(); command = strdup(argv[optind++]); command_length = strlen(command); for (; optind < argc; optind++) { char *endp; int s = strlen(argv[optind]); command = realloc(command, command_length + s + 2); /* space and \0 */ endp = command + command_length; *endp = ' '; memcpy(endp + 1, argv[optind], s); command_length += 1 + s; /* space then string length */ command[command_length] = '\0'; } get_terminal_size(); /* Catch keyboard interrupts so we can put tty back in a sane state. */ signal(SIGINT, die); signal(SIGTERM, die); signal(SIGHUP, die); signal(SIGWINCH, winch_handler); /* Set up tty for curses use. */ curses_started = 1; initscr(); nonl(); noecho(); cbreak(); for (;;) { time_t t = time(NULL); char *ts = ctime(&t); int tsl = strlen(ts); char *header; FILE *p; int x, y; int oldeolseen = 1; mbstate_t mbs; if (screen_size_changed) { get_terminal_size(); resizeterm(height, width); clear(); /* redrawwin(stdscr); */ screen_size_changed = 0; first_screen = 1; } if (show_title) { // left justify interval and command, // right justify time, clipping all to fit window width asprintf(&header, "Every %.1fs: %.*s", interval, min(width - 1, command_length), command); mvaddstr(0, 0, header); if (strlen(header) > (size_t) (width - tsl - 1)) mvaddstr(0, width - tsl - 4, "... "); mvaddstr(0, width - tsl + 1, ts); free(header); } if (!(p = popen(command, "r"))) { perror("popen"); do_exit(2); } memset(&mbs, 0, sizeof(mbs)); for (y = show_title; y < height; y++) { int eolseen = 0, tabpending = 0; for (x = 0; x < width; x++) { wint_t c = L' '; int attr = 0, c_width; cchar_t cc; wchar_t wstr[2]; if (!eolseen) { /* if there is a tab pending, just spit spaces until the next stop instead of reading characters */ if (!tabpending) do c = readwc(p, &mbs); while (c != WEOF && !iswprint(c) && c != L'\n' && c != L'\t'); if (c == L'\n') if (!oldeolseen && x == 0) { x = -1; continue; } else eolseen = 1; else if (c == L'\t') tabpending = 1; if (c == WEOF || c == L'\n' || c == L'\t') c = L' '; if (tabpending && (((x + 1) % 8) == 0)) tabpending = 0; } wstr[0] = c; wstr[1] = 0; setcchar (&cc, wstr, 0, 0, NULL); move(y, x); if (option_differences) { cchar_t oldc; wchar_t oldwstr[2]; attr_t attrs; short colors; in_wch(&oldc); getcchar(&oldc, oldwstr, &attrs, &colors, NULL); attr = !first_screen && (wstr[0] != oldwstr[0] || (option_differences_cumulative && attrs)); } if (attr) standout(); add_wch(&cc); if (attr) standend(); c_width = wcwidth(c); if (c_width > 1) x += c_width - 1; } oldeolseen = eolseen; } pclose(p); first_screen = 0; refresh(); usleep(interval * 1000000); } endwin(); return 0; }
/* * __wgetn_wstr -- * The actual implementation. * Note that we include a trailing L'\0' for safety, so str will contain * at most n - 1 other characters. */ int __wgetn_wstr(WINDOW *win, wchar_t *wstr, int n) { wchar_t *ostr, ec, kc, sc[ 2 ]; int oldx, remain; wint_t wc; cchar_t cc; ostr = wstr; if ( erasewchar( &ec ) == ERR ) return ERR; if ( killwchar( &kc ) == ERR ) return ERR; sc[ 0 ] = ( wchar_t )btowc( ' ' ); sc[ 1 ] = L'\0'; setcchar( &cc, sc, win->wattr, 0, NULL ); oldx = win->curx; remain = n - 1; while (wget_wch(win, &wc) != ERR && wc != L'\n' && wc != L'\r') { #ifdef DEBUG __CTRACE(__CTRACE_INPUT, "__wgetn_wstr: win %p, char 0x%x, remain %d\n", win, wc, remain); #endif *wstr = wc; touchline(win, win->cury, 1); if (wc == ec || wc == KEY_BACKSPACE || wc == KEY_LEFT) { *wstr = L'\0'; if (wstr != ostr) { if ((wchar_t)wc == ec) { mvwadd_wch(win, win->cury, win->curx, &cc); wmove(win, win->cury, win->curx - 1); } if (wc == KEY_BACKSPACE || wc == KEY_LEFT) { /* getch() displays the key sequence */ mvwadd_wch(win, win->cury, win->curx - 1, &cc); mvwadd_wch(win, win->cury, win->curx - 2, &cc); wmove(win, win->cury, win->curx - 1); } wstr--; if (n != -1) { /* We're counting chars */ remain++; } } else { /* str == ostr */ if (wc == KEY_BACKSPACE || wc == KEY_LEFT) /* getch() displays the other keys */ mvwadd_wch(win, win->cury, win->curx - 1, &cc); wmove(win, win->cury, oldx); } } else if (wc == kc) { *wstr = L'\0'; if (wstr != ostr) { /* getch() displays the kill character */ mvwadd_wch(win, win->cury, win->curx - 1, &cc); /* Clear the characters from screen and str */ while (wstr != ostr) { mvwadd_wch(win, win->cury, win->curx - 1, &cc); wmove(win, win->cury, win->curx - 1); wstr--; if (n != -1) /* We're counting chars */ remain++; } mvwadd_wch(win, win->cury, win->curx - 1, &cc); wmove(win, win->cury, win->curx - 1); } else /* getch() displays the kill character */ mvwadd_wch( win, win->cury, oldx, &cc ); wmove(win, win->cury, oldx); } else if (wc >= KEY_MIN && wc <= KEY_MAX) { /* get_wch() displays these characters */ mvwadd_wch( win, win->cury, win->curx - 1, &cc ); wmove(win, win->cury, win->curx - 1); } else { if (remain) { wstr++; remain--; } else { mvwadd_wch(win, win->cury, win->curx - 1, &cc); wmove(win, win->cury, win->curx - 1); } } } if (wc == ERR) { *wstr = L'\0'; return ERR; } *wstr = L'\0'; return OK; }