_nc_screen_of(WINDOW *win) { SCREEN *sp = 0; if (win != 0) { sp = WINDOW_EXT(win, screen); } return (sp); }
static #if !USE_WIDEC_SUPPORT /* cannot be inline if it is recursive */ NCURSES_INLINE #endif int waddch_literal(WINDOW *win, NCURSES_CH_T ch) { int x; int y; struct ldat *line; x = win->_curx; y = win->_cury; CHECK_POSITION(win, x, y); ch = render_char(win, ch); line = win->_line + y; CHANGED_CELL(line, x); /* * Build up multibyte characters until we have a wide-character. */ if_WIDEC({ if (WINDOW_EXT(win, addch_used) != 0 || !Charable(ch)) { int len = _nc_build_wch(win, CHREF(ch)); if (len >= -1) { /* handle EILSEQ */ if (is8bits(CharOf(ch))) { const char *s = unctrl((chtype) CharOf(ch)); if (s[1] != 0) { return waddstr(win, s); } } if (len == -1) return waddch(win, ' '); } else { return OK; } } });
_nc_scroll_window(WINDOW *win, int const n, int const top, int const bottom, NCURSES_CH_T blank) { int limit; int line; int j; size_t to_copy = (sizeof(NCURSES_CH_T) * (size_t) (win->_maxx + 1)); TR(TRACE_MOVE, ("_nc_scroll_window(%p, %d, %ld, %ld)", (void *) win, n, (long) top, (long) bottom)); if (top < 0 || bottom < top || bottom > win->_maxy) { TR(TRACE_MOVE, ("nothing to scroll")); return; } /* * This used to do a line-text pointer-shuffle instead of text copies. * That (a) doesn't work when the window is derived and doesn't have * its own storage, (b) doesn't save you a lot on modern machines * anyway. Your typical memcpy implementations are coded in * assembler using a tight BLT loop; for the size of copies we're * talking here, the total execution time is dominated by the one-time * setup cost. So there is no point in trying to be excessively * clever -- esr. */ /* shift n lines downwards */ if (n < 0) { limit = top - n; for (line = bottom; line >= limit && line >= 0; line--) { TR(TRACE_MOVE, ("...copying %d to %d", line + n, line)); memcpy(win->_line[line].text, win->_line[line + n].text, to_copy); if_USE_SCROLL_HINTS(win->_line[line].oldindex = win->_line[line + n].oldindex); } for (line = top; line < limit && line <= win->_maxy; line++) { TR(TRACE_MOVE, ("...filling %d", line)); for (j = 0; j <= win->_maxx; j++) win->_line[line].text[j] = blank; if_USE_SCROLL_HINTS(win->_line[line].oldindex = _NEWINDEX); } } /* shift n lines upwards */ if (n > 0) { limit = bottom - n; for (line = top; line <= limit && line <= win->_maxy; line++) { memcpy(win->_line[line].text, win->_line[line + n].text, to_copy); if_USE_SCROLL_HINTS(win->_line[line].oldindex = win->_line[line + n].oldindex); } for (line = bottom; line > limit && line >= 0; line--) { for (j = 0; j <= win->_maxx; j++) win->_line[line].text[j] = blank; if_USE_SCROLL_HINTS(win->_line[line].oldindex = _NEWINDEX); } } touchline(win, top, bottom - top + 1); if_WIDEC({ if (WINDOW_EXT(win, addch_used) != 0) { int next = WINDOW_EXT(win, addch_y) + n; if (next < 0 || next > win->_maxy) { TR(TRACE_VIRTPUT, ("Alert discarded multibyte on scroll")); WINDOW_EXT(win, addch_y) = 0; } else { TR(TRACE_VIRTPUT, ("scrolled working position to %d,%d", WINDOW_EXT(win, addch_y), WINDOW_EXT(win, addch_x))); WINDOW_EXT(win, addch_y) = next; } } }) }
static #if !USE_WIDEC_SUPPORT /* cannot be inline if it is recursive */ NCURSES_INLINE #endif int waddch_literal(WINDOW *win, NCURSES_CH_T ch) { int x; int y; struct ldat *line; x = win->_curx; y = win->_cury; CHECK_POSITION(win, x, y); ch = render_char(win, ch); line = win->_line + y; CHANGED_CELL(line, x); /* * Build up multibyte characters until we have a wide-character. */ #if NCURSES_SP_FUNCS #define DeriveSP() SCREEN *sp = _nc_screen_of(win); #else #define DeriveSP() /*nothing */ #endif if_WIDEC({ DeriveSP(); if (WINDOW_EXT(win, addch_used) != 0 || !Charable(ch)) { int len = _nc_build_wch(win, CHREF(ch)); if (len >= -1) { attr_t attr = AttrOf(ch); /* handle EILSEQ (i.e., when len >= -1) */ if (len == -1 && is8bits(CharOf(ch))) { int rc = OK; const char *s = NCURSES_SP_NAME(unctrl) (NCURSES_SP_ARGx (chtype) CharOf(ch)); if (s[1] != '\0') { while (*s != '\0') { rc = waddch(win, UChar(*s) | attr); if (rc != OK) break; ++s; } return rc; } } if (len == -1) return waddch(win, ' ' | attr); } else { return OK; } } });
_nc_build_wch(WINDOW *win, ARG_CH_T ch) { char *buffer = WINDOW_EXT(win, addch_work); int len; int x = win->_curx; int y = win->_cury; mbstate_t state; wchar_t result; if ((WINDOW_EXT(win, addch_used) != 0) && (WINDOW_EXT(win, addch_x) != x || WINDOW_EXT(win, addch_y) != y)) { /* discard the incomplete multibyte character */ WINDOW_EXT(win, addch_used) = 0; TR(TRACE_VIRTPUT, ("Alert discarded multibyte on move (%d,%d) -> (%d,%d)", WINDOW_EXT(win, addch_y), WINDOW_EXT(win, addch_x), y, x)); } WINDOW_EXT(win, addch_x) = x; WINDOW_EXT(win, addch_y) = y; init_mb(state); buffer[WINDOW_EXT(win, addch_used)] = (char) CharOf(CHDEREF(ch)); WINDOW_EXT(win, addch_used) += 1; buffer[WINDOW_EXT(win, addch_used)] = '\0'; if ((len = (int) mbrtowc(&result, buffer, (size_t) WINDOW_EXT(win, addch_used), &state)) > 0) { attr_t attrs = AttrOf(CHDEREF(ch)); if_EXT_COLORS(int pair = GetPair(CHDEREF(ch))); SetChar(CHDEREF(ch), result, attrs); if_EXT_COLORS(SetPair(CHDEREF(ch), pair)); WINDOW_EXT(win, addch_used) = 0; } else if (len == -1) { /* * An error occurred. We could either discard everything, * or assume that the error was in the previous input. * Try the latter. */ TR(TRACE_VIRTPUT, ("Alert! mbrtowc returns error")); /* handle this with unctrl() */ WINDOW_EXT(win, addch_used) = 0; } return len; }