static void remove_window_from_screen(WINDOW *win) { SCREEN *sp; #ifdef USE_SP_WINDOWLIST if ((sp = _nc_screen_of(win)) != 0) { if (window_is(curscr)) { remove_window(curscr); } else if (window_is(stdscr)) { remove_window(stdscr); } else if (window_is(newscr)) { remove_window(newscr); } } #else for (each_screen(sp)) { if (window_is(curscr)) { remove_window(curscr); break; } else if (window_is(stdscr)) { remove_window(stdscr); break; } else if (window_is(newscr)) { remove_window(newscr); break; } } #endif }
wrefresh(WINDOW *win) { int code; #if NCURSES_SP_FUNCS SCREEN *SP_PARM = _nc_screen_of(win); #endif T((T_CALLED("wrefresh(%p)"), (void *) win)); if (win == 0) { code = ERR; } else if (win == CurScreen(SP_PARM)) { CurScreen(SP_PARM)->_clear = TRUE; code = NCURSES_SP_NAME(doupdate) (NCURSES_SP_ARG); } else if ((code = wnoutrefresh(win)) == OK) { if (win->_clear) NewScreen(SP_PARM)->_clear = TRUE; code = NCURSES_SP_NAME(doupdate) (NCURSES_SP_ARG); /* * Reset the clearok() flag in case it was set for the special * case in hardscroll.c (if we don't reset it here, we'll get 2 * refreshes because the flag is copied from stdscr to newscr). * Resetting the flag shouldn't do any harm, anyway. */ win->_clear = FALSE; } returnCode(code); }
delwin(WINDOW *win) { int result = ERR; T((T_CALLED("delwin(%p)"), (void *) win)); if (_nc_try_global(curses) == 0) { if (win == 0 || cannot_delete(win)) { result = ERR; } else { #if NCURSES_SP_FUNCS SCREEN *sp = _nc_screen_of(win); #endif if (win->_flags & _SUBWIN) touchwin(win->_parent); else if (CurScreen(SP_PARM) != 0) touchwin(CurScreen(SP_PARM)); result = _nc_freewin(win); } _nc_unlock_global(curses); } returnCode(result); }
set_menu_win(MENU * menu, WINDOW *win) { T((T_CALLED("set_menu_win(%p,%p)"), (void *)menu, (void *)win)); if (menu) { if (menu->status & _POSTED) RETURN(E_POSTED); else #if NCURSES_SP_FUNCS { /* We ensure that userwin is never null. So even if a null WINDOW parameter is passed, we store the SCREENS stdscr. The only MENU that can have a null userwin is the static _nc_default_Menu. */ SCREEN *sp = _nc_screen_of(menu->userwin); menu->userwin = win ? win : sp->_stdscr; _nc_Calculate_Item_Length_and_Width(menu); } #else menu->userwin = win; #endif } else _nc_Default_Menu.userwin = win; RETURN(E_OK); }
idcok(WINDOW *win, bool flag) { T((T_CALLED("idcok(%p,%d)"), (void *) win, flag)); if (win) { SCREEN *sp = _nc_screen_of(win); sp->_nc_sp_idcok = win->_idcok = (flag && NCURSES_SP_NAME(has_ic) (NCURSES_SP_ARG)); } returnVoid; }
keypad(WINDOW *win, bool flag) { T((T_CALLED("keypad(%p,%d)"), (void *) win, flag)); if (win) { win->_use_keypad = flag; returnCode(_nc_keypad(_nc_screen_of(win), flag)); } else returnCode(ERR); }
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); }
/* * Paint the info line for the PC style SLK emulation. */ static void slk_paint_info(WINDOW *win) { SCREEN *sp = _nc_screen_of(win); if (win && sp && (sp->slk_format == 4)) { int i; mvwhline(win, 0, 0, 0, getmaxx(win)); wmove(win, 0, 0); for (i = 0; i < sp->_slk->maxlab; i++) { mvwprintw(win, 0, sp->_slk->ent[i].ent_x, "F%d", i + 1); } } }
vwprintw(WINDOW *win, const char *fmt, va_list argp) { char *buf; int code = ERR; #if NCURSES_SP_FUNCS SCREEN *sp = _nc_screen_of(win); #endif T((T_CALLED("vwprintw(%p,%s,va_list)"), (void *) win, _nc_visbuf(fmt))); buf = NCURSES_SP_NAME(_nc_printf_string) (NCURSES_SP_ARGx fmt, argp); if (buf != 0) { code = waddstr(win, buf); } returnCode(code); }
idlok(WINDOW *win, bool flag) { int res = ERR; T((T_CALLED("idlok(%p,%d)"), (void *) win, flag)); if (win) { SCREEN *sp = _nc_screen_of(win); if (sp != 0 #ifdef USE_TERM_DRIVER && IsTermInfo(sp) #endif ) { sp->_nc_sp_idlok = win->_idlok = (flag && (NCURSES_SP_NAME(has_il) (NCURSES_SP_ARG) || change_scroll_region)); res = OK; } } returnCode(res); }
static bool cannot_delete(WINDOW *win) { WINDOWLIST *p; bool result = TRUE; #ifdef USE_SP_WINDOWLIST SCREEN *sp = _nc_screen_of(win); #endif for (each_window(SP_PARM, p)) { if (&(p->win) == win) { result = FALSE; } else if ((p->win._flags & _SUBWIN) != 0 && p->win._parent == win) { result = TRUE; break; } } return result; }
prefresh(WINDOW *win, int pminrow, int pmincol, int sminrow, int smincol, int smaxrow, int smaxcol) { #if NCURSES_SP_FUNCS SCREEN *sp = _nc_screen_of(win); #endif T((T_CALLED("prefresh()"))); if (pnoutrefresh(win, pminrow, pmincol, sminrow, smincol, smaxrow, smaxcol) != ERR && NCURSES_SP_NAME(doupdate) (NCURSES_SP_ARG) != ERR) { returnCode(OK); } returnCode(ERR); }
_nc_freewin(WINDOW *win) { WINDOWLIST *p, *q; int i; int result = ERR; #ifdef USE_SP_WINDOWLIST SCREEN *sp = _nc_screen_of(win); /* pretend this is parameter */ #endif T((T_CALLED("_nc_freewin(%p)"), (void *) win)); if (win != 0) { if (_nc_nonsp_try_global(curses) == 0) { q = 0; for (each_window(SP_PARM, p)) { if (&(p->win) == win) { remove_window_from_screen(win); if (q == 0) WindowList(SP_PARM) = p->next; else q->next = p->next; if (!(win->_flags & _SUBWIN)) { for (i = 0; i <= win->_maxy; i++) FreeIfNeeded(win->_line[i].text); } free(win->_line); free(p); result = OK; T(("...deleted win=%p", (void *) win)); break; } q = p; } _nc_nonsp_unlock_global(curses); } }
wnoutrefresh(WINDOW *win) { int limit_x; int src_row, src_col; int begx; int begy; int dst_row, dst_col; #if USE_SCROLL_HINTS bool wide; #endif #if NCURSES_SP_FUNCS SCREEN *SP_PARM = _nc_screen_of(win); #endif T((T_CALLED("wnoutrefresh(%p)"), (void *) win)); #ifdef TRACE if (USE_TRACEF(TRACE_UPDATE)) { _tracedump("...win", win); _nc_unlock_global(tracef); } #endif /* TRACE */ /* * This function will break badly if we try to refresh a pad. */ if ((win == 0) || (win->_flags & _ISPAD)) returnCode(ERR); /* put them here so "win == 0" won't break our code */ begx = win->_begx; begy = win->_begy; NewScreen(SP_PARM)->_nc_bkgd = win->_nc_bkgd; WINDOW_ATTRS(NewScreen(SP_PARM)) = WINDOW_ATTRS(win); /* merge in change information from all subwindows of this window */ wsyncdown(win); #if USE_SCROLL_HINTS /* * For pure efficiency, we'd want to transfer scrolling information * from the window to newscr whenever the window is wide enough that * its update will dominate the cost of the update for the horizontal * band of newscr that it occupies. Unfortunately, this threshold * tends to be complex to estimate, and in any case scrolling the * whole band and rewriting the parts outside win's image would look * really ugly. So. What we do is consider the window "wide" if it * either (a) occupies the whole width of newscr, or (b) occupies * all but at most one column on either vertical edge of the screen * (this caters to fussy people who put boxes around full-screen * windows). Note that changing this formula will not break any code, * merely change the costs of various update cases. */ wide = (begx <= 1 && win->_maxx >= (NewScreen(SP_PARM)->_maxx - 1)); #endif win->_flags &= ~_HASMOVED; /* * Microtweaking alert! This double loop is one of the genuine * hot spots in the code. Even gcc doesn't seem to do enough * common-subexpression chunking to make it really tense, * so we'll force the issue. */ /* limit(dst_col) */ limit_x = win->_maxx; /* limit(src_col) */ if (limit_x > NewScreen(SP_PARM)->_maxx - begx) limit_x = NewScreen(SP_PARM)->_maxx - begx; for (src_row = 0, dst_row = begy + win->_yoffset; src_row <= win->_maxy && dst_row <= NewScreen(SP_PARM)->_maxy; src_row++, dst_row++) { struct ldat *nline = &(NewScreen(SP_PARM)->_line[dst_row]); struct ldat *oline = &win->_line[src_row]; if (oline->firstchar != _NOCHANGE) { int last_src = oline->lastchar; if (last_src > limit_x) last_src = limit_x; src_col = oline->firstchar; dst_col = src_col + begx; if_WIDEC({ int j; /* * Ensure that we will copy complete multi-column characters * on the left-boundary. */ if (isWidecExt(oline->text[src_col])) { j = 1 + dst_col - WidecExt(oline->text[src_col]); if (j < 0) j = 0; if (dst_col > j) { src_col -= (dst_col - j); dst_col = j; } } /* * Ensure that we will copy complete multi-column characters * on the right-boundary. */ j = last_src; if (WidecExt(oline->text[j])) { ++j; while (j <= limit_x) { if (isWidecBase(oline->text[j])) { break; } else { last_src = j; } ++j; } } }); if_WIDEC({ static cchar_t blank = BLANK; int last_dst = begx + ((last_src < win->_maxx) ? last_src : win->_maxx); int fix_left = dst_col; int fix_right = last_dst; int j; /* * Check for boundary cases where we may overwrite part of a * multi-column character. For those, wipe the remainder of * the character to blanks. */ j = dst_col; if (isWidecExt(nline->text[j])) { /* * On the left, we only care about multi-column characters * that extend into the changed region. */ fix_left = 1 + j - WidecExt(nline->text[j]); if (fix_left < 0) fix_left = 0; /* only if cell is corrupt */ } j = last_dst; if (WidecExt(nline->text[j]) != 0) { /* * On the right, any multi-column character is a problem, * unless it happens to be contained in the change, and * ending at the right boundary of the change. The * computation for 'fix_left' accounts for the left-side of * this character. Find the end of the character. */ ++j; while (j <= NewScreen(SP_PARM)->_maxx && isWidecExt(nline->text[j])) { fix_right = j++; } } /* * The analysis is simpler if we do the clearing afterwards. * Do that now. */ if (fix_left < dst_col || fix_right > last_dst) { for (j = fix_left; j <= fix_right; ++j) { nline->text[j] = blank; CHANGED_CELL(nline, j); } } });
static int _nc_use_meta(WINDOW *win) { SCREEN *sp = _nc_screen_of(win); return (sp ? sp->_use_meta : 0); }
static NCURSES_INLINE int wadd_wch_nosync(WINDOW *win, cchar_t ch) /* the workhorse function -- add a character to the given window */ { NCURSES_SIZE_T x, y; wchar_t *s; int tabsize = 8; #if USE_REENTRANT SCREEN *sp = _nc_screen_of(win); #endif /* * If we are using the alternate character set, forget about locale. * Otherwise, if the locale claims the code is printable, treat it that * way. */ if ((AttrOf(ch) & A_ALTCHARSET) || iswprint((wint_t) CharOf(ch))) return wadd_wch_literal(win, ch); /* * Handle carriage control and other codes that are not printable, or are * known to expand to more than one character according to unctrl(). */ x = win->_curx; y = win->_cury; switch (CharOf(ch)) { case '\t': #if USE_REENTRANT tabsize = *ptrTabsize(sp); #else tabsize = TABSIZE; #endif x = (NCURSES_SIZE_T) (x + (tabsize - (x % tabsize))); /* * Space-fill the tab on the bottom line so that we'll get the * "correct" cursor position. */ if ((!win->_scroll && (y == win->_regbottom)) || (x <= win->_maxx)) { cchar_t blank = blankchar; AddAttr(blank, AttrOf(ch)); while (win->_curx < x) { if (wadd_wch_literal(win, blank) == ERR) return (ERR); } break; } else { wclrtoeol(win); win->_flags |= _WRAPPED; if (newline_forces_scroll(win, &y)) { x = win->_maxx; if (win->_scroll) { scroll(win); x = 0; } } else { x = 0; } } break; case '\n': wclrtoeol(win); if (newline_forces_scroll(win, &y)) { if (win->_scroll) scroll(win); else return (ERR); } /* FALLTHRU */ case '\r': x = 0; win->_flags &= ~_WRAPPED; break; case '\b': if (x == 0) return (OK); x--; win->_flags &= ~_WRAPPED; break; default: if ((s = wunctrl(&ch)) != 0) { while (*s) { cchar_t sch; SetChar(sch, *s++, AttrOf(ch)); if_EXT_COLORS(SetPair(sch, GetPair(ch))); if (wadd_wch_literal(win, sch) == ERR) return ERR; } return OK; } return ERR; } win->_curx = x; win->_cury = y; return OK; }
keypad(WINDOW *win, bool flag) { T((T_CALLED("keypad(%p,%d)"), (void *) win, flag)); if (win) { win->_use_keypad = flag; returnCode(_nc_keypad(_nc_screen_of(win), flag)); } else returnCode(ERR); } NCURSES_EXPORT(int) meta(WINDOW *win GCC_UNUSED, bool flag) { int result = ERR; SCREEN *sp = (win == 0) ? CURRENT_SCREEN : _nc_screen_of(win); /* Ok, we stay relaxed and don't signal an error if win is NULL */ T((T_CALLED("meta(%p,%d)"), (void *) win, flag)); /* Ok, we stay relaxed and don't signal an error if win is NULL */ if (sp != 0) { sp->_use_meta = flag; #ifdef USE_TERM_DRIVER if (IsTermInfo(sp)) { if (flag) { NCURSES_PUTP2("meta_on", meta_on); } else { NCURSES_PUTP2("meta_off", meta_off); }
pnoutrefresh(WINDOW *win, int pminrow, int pmincol, int sminrow, int smincol, int smaxrow, int smaxcol) { NCURSES_SIZE_T i, j; NCURSES_SIZE_T m, n; NCURSES_SIZE_T pmaxrow; NCURSES_SIZE_T pmaxcol; SCREEN *sp; #if USE_SCROLL_HINTS const int my_len = 2; /* parameterize the threshold for hardscroll */ NCURSES_SIZE_T displaced; bool wide; #endif T((T_CALLED("pnoutrefresh(%p, %d, %d, %d, %d, %d, %d)"), (void *) win, pminrow, pmincol, sminrow, smincol, smaxrow, smaxcol)); if (win == 0) returnCode(ERR); if (!(win->_flags & _ISPAD)) returnCode(ERR); sp = _nc_screen_of(win); /* negative values are interpreted as zero */ if (pminrow < 0) pminrow = 0; if (pmincol < 0) pmincol = 0; if (sminrow < 0) sminrow = 0; if (smincol < 0) smincol = 0; pmaxrow = pminrow + smaxrow - sminrow; pmaxcol = pmincol + smaxcol - smincol; T((" pminrow + smaxrow - sminrow %ld, win->_maxy %ld", (long) pmaxrow, (long) win->_maxy)); T((" pmincol + smaxcol - smincol %ld, win->_maxx %ld", (long) pmaxcol, (long) win->_maxx)); /* * Trim the caller's screen size back to the actual limits. */ if (pmaxrow > win->_maxy) { smaxrow -= (pmaxrow - win->_maxy); pmaxrow = pminrow + smaxrow - sminrow; } if (pmaxcol > win->_maxx) { smaxcol -= (pmaxcol - win->_maxx); pmaxcol = pmincol + smaxcol - smincol; } if (smaxrow >= screen_lines(sp) || smaxcol >= screen_columns(sp) || sminrow > smaxrow || smincol > smaxcol) returnCode(ERR); T(("pad being refreshed")); #if USE_SCROLL_HINTS if (win->_pad._pad_y >= 0) { displaced = pminrow - win->_pad._pad_y - (sminrow - win->_pad._pad_top); T(("pad being shifted by %d line(s)", displaced)); } else displaced = 0; #endif /* * For pure efficiency, we'd want to transfer scrolling information * from the pad to newscr whenever the window is wide enough that * its update will dominate the cost of the update for the horizontal * band of newscr that it occupies. Unfortunately, this threshold * tends to be complex to estimate, and in any case scrolling the * whole band and rewriting the parts outside win's image would look * really ugly. So. What we do is consider the pad "wide" if it * either (a) occupies the whole width of newscr, or (b) occupies * all but at most one column on either vertical edge of the screen * (this caters to fussy people who put boxes around full-screen * windows). Note that changing this formula will not break any code, * merely change the costs of various update cases. */ #if USE_SCROLL_HINTS wide = (smincol < my_len && smaxcol > (NewScreen(sp)->_maxx - my_len)); #endif for (i = pminrow, m = sminrow + win->_yoffset; i <= pmaxrow && m <= NewScreen(sp)->_maxy; i++, m++) { register struct ldat *nline = &NewScreen(sp)->_line[m]; register struct ldat *oline = &win->_line[i]; for (j = pmincol, n = smincol; j <= pmaxcol; j++, n++) { NCURSES_CH_T ch = oline->text[j]; #if USE_WIDEC_SUPPORT /* * Special case for leftmost character of the displayed area. * Only half of a double-width character may be visible. */ if (j == pmincol && j > 0 && isWidecExt(ch)) { SetChar(ch, L(' '), AttrOf(oline->text[j - 1])); } #endif if (!CharEq(ch, nline->text[n])) { nline->text[n] = ch; CHANGED_CELL(nline, n); } } #if USE_SCROLL_HINTS if (wide) { int nind = m + displaced; if (oline->oldindex < 0 || nind < sminrow || nind > smaxrow) { nind = _NEWINDEX; } else if (displaced) { register struct ldat *pline = &CurScreen(sp)->_line[nind]; for (j = 0; j <= my_len; j++) { int k = NewScreen(sp)->_maxx - j; if (pline->text[j] != nline->text[j] || pline->text[k] != nline->text[k]) { nind = _NEWINDEX; break; } } } nline->oldindex = nind; } #endif /* USE_SCROLL_HINTS */ oline->firstchar = oline->lastchar = _NOCHANGE; if_USE_SCROLL_HINTS(oline->oldindex = i); } /* * Clean up debris from scrolling or resizing the pad, so we do not * accidentally pick up the index value during the next call to this * procedure. The only rows that should have an index value are those * that are displayed during this cycle. */ #if USE_SCROLL_HINTS for (i = pminrow - 1; (i >= 0) && (win->_line[i].oldindex >= 0); i--) win->_line[i].oldindex = _NEWINDEX; for (i = pmaxrow + 1; (i <= win->_maxy) && (win->_line[i].oldindex >= 0); i++) win->_line[i].oldindex = _NEWINDEX; #endif win->_begx = smincol; win->_begy = sminrow; if (win->_clear) { win->_clear = FALSE; NewScreen(sp)->_clear = TRUE; } /* * Use the pad's current position, if it will be visible. * If not, don't do anything; it's not an error. */ if (win->_leaveok == FALSE && win->_cury >= pminrow && win->_curx >= pmincol && win->_cury <= pmaxrow && win->_curx <= pmaxcol) { NewScreen(sp)->_cury = win->_cury - pminrow + win->_begy + win->_yoffset; NewScreen(sp)->_curx = win->_curx - pmincol + win->_begx; } NewScreen(sp)->_leaveok = win->_leaveok; win->_flags &= ~_HASMOVED; /* * Update our cache of the line-numbers that we displayed from the pad. * We will use this on subsequent calls to this function to derive * values to stuff into 'oldindex[]' -- for scrolling optimization. */ win->_pad._pad_y = pminrow; win->_pad._pad_x = pmincol; win->_pad._pad_top = sminrow; win->_pad._pad_left = smincol; win->_pad._pad_bottom = smaxrow; win->_pad._pad_right = smaxcol; returnCode(OK); }
wget_wch(WINDOW *win, wint_t *result) { SCREEN *sp; int code; char buffer[(MB_LEN_MAX * 9) + 1]; /* allow some redundant shifts */ int status; size_t count = 0; int value = 0; wchar_t wch; #ifndef state_unused mbstate_t state; #endif T((T_CALLED("wget_wch(%p)"), (void *) win)); /* * We can get a stream of single-byte characters and KEY_xxx codes from * _nc_wgetch(), while we want to return a wide character or KEY_xxx code. */ _nc_lock_global(curses); sp = _nc_screen_of(win); if (sp != 0) { for (;;) { T(("reading %d of %d", (int) count + 1, (int) sizeof(buffer))); code = _nc_wgetch(win, &value, TRUE EVENTLIST_2nd((_nc_eventlist *) 0)); if (code == ERR) { break; } else if (code == KEY_CODE_YES) { /* * If we were processing an incomplete multibyte character, * return an error since we have a KEY_xxx code which * interrupts it. For some cases, we could improve this by * writing a new version of lib_getch.c(!), but it is not clear * whether the improvement would be worth the effort. */ if (count != 0) { safe_ungetch(SP_PARM, value); code = ERR; } break; } else if (count + 1 >= sizeof(buffer)) { safe_ungetch(SP_PARM, value); code = ERR; break; } else { buffer[count++] = (char) UChar(value); reset_mbytes(state); status = count_mbytes(buffer, count, state); if (status >= 0) { reset_mbytes(state); if (check_mbytes(wch, buffer, count, state) != status) { code = ERR; /* the two calls should match */ safe_ungetch(SP_PARM, value); } value = wch; break; } } } } else { code = ERR; } *result = (wint_t) value; _nc_unlock_global(curses); T(("result %#o", value)); returnCode(code); }
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)"), win, 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); }
dupwin(WINDOW *win) /* make an exact duplicate of the given window */ { WINDOW *nwin = 0; size_t linesize; int i; T((T_CALLED("dupwin(%p)"), (void *) win)); if (win != 0) { #if NCURSES_SP_FUNCS SCREEN *sp = _nc_screen_of(win); #endif _nc_lock_global(curses); if (win->_flags & _ISPAD) { nwin = NCURSES_SP_NAME(newpad) (NCURSES_SP_ARGx win->_maxy + 1, win->_maxx + 1); } else { nwin = NCURSES_SP_NAME(newwin) (NCURSES_SP_ARGx win->_maxy + 1, win->_maxx + 1, win->_begy, win->_begx); } if (nwin != 0) { nwin->_curx = win->_curx; nwin->_cury = win->_cury; nwin->_maxy = win->_maxy; nwin->_maxx = win->_maxx; nwin->_begy = win->_begy; nwin->_begx = win->_begx; nwin->_yoffset = win->_yoffset; nwin->_flags = win->_flags & ~_SUBWIN; /* Due to the use of newwin(), the clone is not a subwindow. * The text is really copied into the clone. */ WINDOW_ATTRS(nwin) = WINDOW_ATTRS(win); nwin->_nc_bkgd = win->_nc_bkgd; nwin->_notimeout = win->_notimeout; nwin->_clear = win->_clear; nwin->_leaveok = win->_leaveok; nwin->_scroll = win->_scroll; nwin->_idlok = win->_idlok; nwin->_idcok = win->_idcok; nwin->_immed = win->_immed; nwin->_sync = win->_sync; nwin->_use_keypad = win->_use_keypad; nwin->_delay = win->_delay; nwin->_parx = 0; nwin->_pary = 0; nwin->_parent = (WINDOW *) 0; /* See above: the clone isn't a subwindow! */ nwin->_regtop = win->_regtop; nwin->_regbottom = win->_regbottom; if (win->_flags & _ISPAD) nwin->_pad = win->_pad; linesize = (unsigned) (win->_maxx + 1) * sizeof(NCURSES_CH_T); for (i = 0; i <= nwin->_maxy; i++) { memcpy(nwin->_line[i].text, win->_line[i].text, linesize); nwin->_line[i].firstchar = win->_line[i].firstchar; nwin->_line[i].lastchar = win->_line[i].lastchar; } } _nc_unlock_global(curses); } returnWin(nwin); }
_nc_slk_initialize(WINDOW *stwin, int cols) { int i; int res = OK; unsigned max_length; SCREEN *sp; TERMINAL *term; int numlab; T((T_CALLED("_nc_slk_initialize()"))); assert(stwin); sp = _nc_screen_of(stwin); if (0 == sp) returnCode(ERR); term = TerminalOf(SP_PARM); assert(term); numlab = NumLabels; if (SP_PARM->_slk) { /* we did this already, so simply return */ returnCode(OK); } else if ((SP_PARM->_slk = typeCalloc(SLK, 1)) == 0) returnCode(ERR); if (!SP_PARM->slk_format) SP_PARM->slk_format = _nc_globals.slk_format; /* * If we use colors, vidputs() will suppress video attributes that conflict * with colors. In that case, we're still guaranteed that "reverse" would * work. */ if ((NoColorVideo & 1) == 0) SetAttr(SP_PARM->_slk->attr, A_STANDOUT); else SetAttr(SP_PARM->_slk->attr, A_REVERSE); SP_PARM->_slk->maxlab = ((numlab > 0) ? numlab : MAX_SKEY(SP_PARM->slk_format)); SP_PARM->_slk->maxlen = ((numlab > 0) ? LabelWidth * LabelHeight : MAX_SKEY_LEN(SP_PARM->slk_format)); SP_PARM->_slk->labcnt = ((SP_PARM->_slk->maxlab < MAX_SKEY(SP_PARM->slk_format)) ? MAX_SKEY(SP_PARM->slk_format) : SP_PARM->_slk->maxlab); if (SP_PARM->_slk->maxlen <= 0 || SP_PARM->_slk->labcnt <= 0 || (SP_PARM->_slk->ent = typeCalloc(slk_ent, (unsigned) SP_PARM->_slk->labcnt)) == NULL) returnCode(slk_failed(NCURSES_SP_ARG)); max_length = SP_PARM->_slk->maxlen; for (i = 0; i < SP_PARM->_slk->labcnt; i++) { size_t used = max_length + 1; SP_PARM->_slk->ent[i].ent_text = (char *) _nc_doalloc(0, used); if (SP_PARM->_slk->ent[i].ent_text == 0) returnCode(slk_failed(NCURSES_SP_ARG)); memset(SP_PARM->_slk->ent[i].ent_text, 0, used); SP_PARM->_slk->ent[i].form_text = (char *) _nc_doalloc(0, used); if (SP_PARM->_slk->ent[i].form_text == 0) returnCode(slk_failed(NCURSES_SP_ARG)); memset(SP_PARM->_slk->ent[i].form_text, 0, used); memset(SP_PARM->_slk->ent[i].form_text, ' ', max_length); SP_PARM->_slk->ent[i].visible = (char) (i < SP_PARM->_slk->maxlab); } res = _nc_format_slks(NCURSES_SP_ARGx cols); if ((SP_PARM->_slk->win = stwin) == NULL) { returnCode(slk_failed(NCURSES_SP_ARG)); } /* We now reset the format so that the next newterm has again * per default no SLK keys and may call slk_init again to * define a new layout. (juergen 03-Mar-1999) */ _nc_globals.slk_format = 0; returnCode(res); }
wgetnstr_events(WINDOW *win, char *str, int maxlen, EVENTLIST_1st(_nc_eventlist * evl)) { SCREEN *sp = _nc_screen_of(win); TTY buf; bool oldnl, oldecho, oldraw, oldcbreak; char erasec; char killc; char *oldstr; int ch; int y, x; T((T_CALLED("wgetnstr(%p,%p, %d)"), win, 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 = erasechar(); killc = killchar(); oldstr = str; getyx(win, y, x); if (is_wintouched(win) || (win->_flags & _HASMOVED)) wrefresh(win); while ((ch = wgetch_events(win, evl)) != ERR) { /* * 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 wgetch(); * terminating *getstr() with \n should work either way. */ if (ch == '\n' || ch == '\r' || ch == KEY_DOWN || ch == KEY_ENTER) { if (oldecho == TRUE && win->_cury == win->_maxy && win->_scroll) wechochar(win, (chtype) '\n'); break; } #ifdef KEY_EVENT if (ch == KEY_EVENT) break; #endif #ifdef KEY_RESIZE if (ch == KEY_RESIZE) break; #endif if (ch == erasec || ch == KEY_LEFT || ch == KEY_BACKSPACE) { if (str > oldstr) { str = WipeOut(win, y, x, oldstr, str, oldecho); } } else if (ch == killc) { while (str > oldstr) { str = WipeOut(win, y, x, oldstr, str, oldecho); } } else if (ch >= KEY_MIN || (maxlen >= 0 && str - oldstr >= maxlen)) { beep(); } else { *str++ = (char) ch; if (oldecho == TRUE) { int oldy = win->_cury; if (waddch(win, (chtype) ch) == 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) ' '); str = WipeOut(win, y, x, oldstr, str, 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; _nc_set_tty_mode(&buf); *str = '\0'; if (ch == ERR) returnCode(ch); T(("wgetnstr returns %s", _nc_visbuf(oldstr))); #ifdef KEY_EVENT if (ch == KEY_EVENT) returnCode(ch); #endif #ifdef KEY_RESIZE if (ch == KEY_RESIZE) returnCode(ch); #endif returnCode(OK); }