int wclrtoeol(WINDOW *win) { char *sp, *end; int y, x; char *maxx; ptrdiff_t minx; y = win->_cury; x = win->_curx; end = &win->_y[y][win->_maxx]; minx = _NOCHANGE; maxx = &win->_y[y][x]; for (sp = maxx; sp < end; sp++) if (*sp != ' ') { maxx = sp; if (minx == _NOCHANGE) minx = sp - win->_y[y]; *sp = ' '; } /* * update firstch and lastch for the line */ (void) touchline(win, y, win->_curx, win->_maxx - 1); #ifdef DEBUG fprintf(outf, "CLRTOEOL: minx = %d, maxx = %d, firstch = %d," " lastch = %d\n", minx, maxx - win->_y[y], win->_firstch[y], win->_lastch[y]); #endif return (OK); }
int touchoverlap(WINDOW *win1, WINDOW *win2) { int y, endy, endx, starty, startx; #ifdef DEBUG fprintf(outf, "TOUCHOVERLAP(%0.2o, %0.2o);\n", win1, win2); #endif starty = max(win1->_begy, win2->_begy); startx = max(win1->_begx, win2->_begx); endy = min(win1->_maxy + win1->_begy, win2->_maxy + win2->_begy); endx = min(win1->_maxx + win1->_begx, win2->_maxx + win2->_begx); #ifdef DEBUG fprintf(outf, "TOUCHOVERLAP:from (%d,%d) to (%d,%d)\n", starty, startx, endy, endx); fprintf(outf, "TOUCHOVERLAP:win1 (%d,%d) to (%d,%d)\n", win1->_begy, win1->_begx, win1->_begy + win1->_maxy, win1->_begx + win1->_maxx); fprintf(outf, "TOUCHOVERLAP:win2 (%d,%d) to (%d,%d)\n", win2->_begy, win2->_begx, win2->_begy + win2->_maxy, win2->_begx + win2->_maxx); #endif if (starty >= endy || startx >= endx) return (OK); starty -= win2->_begy; startx -= win2->_begx; endy -= win2->_begy; endx -= win2->_begx; endx--; for (y = starty; y < endy; y++) (void) touchline(win2, y, startx, endx); return (OK); }
/* * std_touch_top * Touch the line in all windows which is visible above a given line. * This routine is almost identical to touch_top, except that the "panel" * is stdscr in this case. The "obscured" list is the list of panels. */ static void std_touch_top(int line, PANEL *obs_pnl, int start_x, int end_x) { PANEL *next_obs; do { next_obs = obs_pnl -> below; if (line >= obs_pnl->wstarty && line <= obs_pnl->wendy && obs_pnl->wstartx <= end_x && obs_pnl->wendx >= start_x) { (void) touchline(obs_pnl->win, line - obs_pnl->wstarty, 1); if (obs_pnl->wstartx > start_x && obs_pnl->wendx < end_x) { if (next_obs) std_touch_top(line, next_obs, obs_pnl->wendx+1, end_x); end_x = obs_pnl -> wstartx - 1; } else { if (obs_pnl->wstartx <= start_x) start_x = obs_pnl -> wendx + 1; if (obs_pnl->wendx >= end_x) end_x = obs_pnl -> wstartx - 1; if (start_x > end_x) return; } } } while ((obs_pnl = next_obs) != 0); }
static void update_status(WINDOW *win, STATUS * sp) { switch (sp->ch) { case ' ': /* next test-iteration */ if (has_colors()) { if ((sp->c_msg = color_params(++(sp->c), &(sp->pair))) == 0) { sp->c_msg = color_params(sp->c = 0, &(sp->pair)); if ((sp->v_msg = video_params(++(sp->v), &(sp->attr))) == 0) { sp->v_msg = video_params(sp->v = 0, &(sp->attr)); } } } else { if ((sp->v_msg = video_params(++(sp->v), &(sp->attr))) == 0) { sp->v_msg = video_params(sp->v = 0, &(sp->attr)); } } sp->count = 0; show_status(win, sp); break; case KEY_LEFT: case 'h': if (sp->x_val > 0) wmove(win, sp->y_val, --(sp->x_val)); break; case KEY_DOWN: case 'j': if (sp->y_val < sp->y_max) wmove(win, ++(sp->y_val), sp->x_val); break; case KEY_UP: case 'k': if (sp->y_val > 0) wmove(win, --(sp->y_val), sp->x_val); break; case KEY_RIGHT: case 'l': if (sp->x_val < sp->x_max) wmove(win, sp->y_val, ++(sp->x_val)); break; case 't': touchline(win, sp->y_val, 1); break; case '=': sp->count = 0; show_status(win, sp); break; case '?': do_subwindow(win, sp, show_help); break; default: if (isdigit(sp->ch)) { sp->count = (sp->count * 10) + (sp->ch - '0'); show_status(win, sp); } else { beep(); } break; } }
void ScrollText(void) { #ifdef UNIX register int i; /* * Ugh, is this dirty. * A better approach would be to use subwin() and * scroll the subwindow, but this doesn't work * very well in some versions of ncurses. */ // for (i = 5; i < ScrnHeight - 2; i++) /* This is actually ncurses/curses dependant */ //#if defined(linux) || defined(_linux) // memcpy(stdscr->_line[i].text, stdscr->_line[i+1].text, //#else // memcpy(stdscr->_line[i], stdscr->_line[i + 1], //#endif // 42 * sizeof(chtype)); touchline(stdscr, 5, ScrnHeight - 2); SetColor(); FillBox(1, ScrnHeight - 2, 42, 1, ' '); refresh(); #else CopyText(2, 8, 42, ScrnHeight - 9, 2, 7); FillBox(1, ScrnHeight - 2, 42, 1, ' '); #endif }
/* * touch_top - Touch the line in all windows * which is visible above a given line */ static void touch_top(PANEL *panel, int line, _obscured_list *obs, int start_x, int end_x) { PANEL *pnl; _obscured_list *next_obs; do { pnl = obs -> panel_p; if ((next_obs = obs->next) == panel -> obscured -> next) next_obs = 0; if (line >= obs -> start && line <= obs -> end && pnl->wstartx <= end_x && pnl->wendx >= start_x) { (void) touchline(pnl->win, line - pnl->wstarty, 1); if (pnl->wstartx > start_x && pnl->wendx < end_x) { if (next_obs) touch_top(panel, line, next_obs, pnl->wendx+1, end_x); end_x = pnl -> wstartx - 1; } else { if (pnl->wstartx <= start_x) start_x = pnl -> wendx + 1; if (pnl->wendx >= end_x) end_x = pnl -> wstartx - 1; if (start_x > end_x) return; } } } while ((obs = next_obs) != 0); }
static void Touchline(PANEL *pan, int start, int count) { char s80[80]; sprintf(s80, "Touchline s=%d c=%d", start, count); dPanel(s80, pan); touchline(pan->win, start, count); }
wredrawln(WINDOW *win, int beg, int num) { int i; int end; size_t len; T((T_CALLED("wredrawln(%p,%d,%d)"), win, beg, num)); if (win == 0) returnCode(ERR); if (beg < 0) beg = 0; if (touchline(win, beg, num) == ERR) returnCode(ERR); if (touchline(curscr, beg + win->_begy, num) == ERR) returnCode(ERR); end = beg + num; if (end > curscr->_maxy + 1) end = curscr->_maxy + 1; if (end > win->_maxy + 1) end = win->_maxy + 1; len = (win->_maxx + 1); if (len > (size_t) (curscr->_maxx + 1)) len = (size_t) (curscr->_maxx + 1); len *= sizeof(curscr->_line[0].text[0]); for (i = beg; i < end; i++) { int crow = i + win->_begy; memset(curscr->_line[crow].text + win->_begx, 0, len); _nc_make_oldhash(crow); } returnCode(OK); }
/* * This routine performs an insert-char on the line, leaving * (_cury,_curx) unchanged. * */ int wdelch(reg WINDOW *win ) { reg char *temp1, *temp2; reg char *end; end = &win->_y[win->_cury][win->_maxx - 1]; temp1 = &win->_y[win->_cury][win->_curx]; temp2 = temp1 + 1; while (temp1 < end) *temp1++ = *temp2++; *temp1 = ' '; touchline(win, win->_cury, win->_curx, win->_maxx - 1); return OK; }
int wscrl(WINDOW *win, int n) { int i, l, dir, start, end; chtype blank, *temp; /* Check if window scrolls. Valid for window AND pad */ if (!win || !win->_scroll || !n) return ERR; blank = win->_bkgd; if (n > 0) { start = win->_tmarg; end = win->_bmarg; dir = 1; } else { start = win->_bmarg; end = win->_tmarg; dir = -1; } for (l = 0; l < (n * dir); l++) { temp = win->_y[start]; /* re-arrange line pointers */ for (i = start; i != end; i += dir) win->_y[i] = win->_y[i + dir]; win->_y[end] = temp; /* make a blank line */ for (i = 0; i < win->_maxx; i++) *temp++ = blank; } touchline(win, win->_tmarg, win->_bmarg - win->_tmarg + 1); PDC_sync(win); return OK; }
/* * This routine erases everything on the window. * */ void wclrtobot(reg WINDOW * win ) { reg int y; reg char *sp, *end, *maxx; reg int startx, minx; startx = win->_curx; for (y = win->_cury; y < win->_maxy; y++) { minx = _NOCHANGE; end = &win->_y[y][win->_maxx]; for (maxx = sp = &win->_y[y][startx]; sp < end; sp++) if (*sp != ' ') { maxx = sp; if (minx == _NOCHANGE) minx = sp - win->_y[y]; *sp = ' '; } if (minx != _NOCHANGE) touchline(win, y, minx, maxx - &win->_y[y][0]); startx = 0; } }
int wredrawln(WINDOW *win, int beg, int num) { int i; T((T_CALLED("wredrawln(%p,%d,%d)"), win, beg, num)); if (touchline(win, beg, num) == OK) { size_t len = win->_maxx * sizeof(chtype); /* * XSI says that wredrawln() tells the library not to base * optimization on the contents of the lines that are marked. * We do that by changing the contents to nulls after touching * the corresponding lines to get the optimizer's attention. * * FIXME: this won't work if the application makes further * updates before the next refresh. */ for (i = beg; (i < beg + num) && (i < win->_maxy); i++) { memset(win->_line[i].text, 0, len); } } returnCode(OK); }
/* * __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; }
copywin(const WINDOW *src, WINDOW *dst, int sminrow, int smincol, int dminrow, int dmincol, int dmaxrow, int dmaxcol, int over) { int rc = ERR; int sx, sy, dx, dy; bool touched; attr_t bk; attr_t mask; T((T_CALLED("copywin(%p, %p, %d, %d, %d, %d, %d, %d, %d)"), src, dst, sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol, over)); if (src && dst) { _nc_lock_global(curses); bk = AttrOf(dst->_nc_bkgd); mask = ~(attr_t) ((bk & A_COLOR) ? A_COLOR : 0); /* make sure rectangle exists in source */ if ((sminrow + dmaxrow - dminrow) <= (src->_maxy + 1) && (smincol + dmaxcol - dmincol) <= (src->_maxx + 1)) { T(("rectangle exists in source")); /* make sure rectangle fits in destination */ if (dmaxrow <= dst->_maxy && dmaxcol <= dst->_maxx) { T(("rectangle fits in destination")); for (dy = dminrow, sy = sminrow; dy <= dmaxrow; sy++, dy++) { touched = FALSE; for (dx = dmincol, sx = smincol; dx <= dmaxcol; sx++, dx++) { if (over) { if ((CharOf(src->_line[sy].text[sx]) != L(' ')) && (!CharEq(dst->_line[dy].text[dx], src->_line[sy].text[sx]))) { dst->_line[dy].text[dx] = src->_line[sy].text[sx]; SetAttr(dst->_line[dy].text[dx], ((AttrOf(src->_line[sy].text[sx]) & mask) | bk)); touched = TRUE; } } else { if (!CharEq(dst->_line[dy].text[dx], src->_line[sy].text[sx])) { dst->_line[dy].text[dx] = src->_line[sy].text[sx]; touched = TRUE; } } } if (touched) { touchline(dst, dminrow, (dmaxrow - dminrow + 1)); } } T(("finished copywin")); rc = OK; } } _nc_unlock_global(curses); } returnCode(rc); }
/* * __wgetnstr -- * The actual implementation. * Note that we include a trailing '\0' for safety, so str will contain * at most n - 1 other characters. * XXX: character deletion from screen is based on how the characters * are displayed by wgetch(). */ int __wgetnstr(WINDOW *win, char *str, int n) { char *ostr, ec, kc; int c, xpos, oldx, remain; ostr = str; ec = erasechar(); kc = killchar(); xpos = oldx = win->curx; _DIAGASSERT(n == -1 || n > 1); remain = n - 1; while ((c = wgetch(win)) != ERR && c != '\n' && c != '\r') { #ifdef DEBUG __CTRACE(__CTRACE_INPUT, "__wgetnstr: win %p, char 0x%x, remain %d\n", win, c, remain); #endif *str = c; touchline(win, win->cury, 1); if (c == ec || c == KEY_BACKSPACE || c == KEY_LEFT) { *str = '\0'; if (str != ostr) { if ((char) c == ec) { mvwaddch(win, win->cury, xpos, ' '); if (xpos > oldx) mvwaddch(win, win->cury, xpos - 1, ' '); if (win->curx > xpos - 1) wmove(win, win->cury, xpos - 1); xpos--; } if (c == KEY_BACKSPACE || c == KEY_LEFT) { /* getch() displays the key sequence */ mvwaddch(win, win->cury, win->curx, ' '); mvwaddch(win, win->cury, win->curx - 1, ' '); if (win->curx > xpos) wmove(win, win->cury, xpos - 1); xpos--; } str--; if (n != -1) { /* We're counting chars */ remain++; } } else { /* str == ostr */ /* getch() displays the other keys */ if (win->curx > oldx) mvwaddch(win, win->cury, win->curx - 1, ' '); wmove(win, win->cury, oldx); xpos = oldx; } } else if (c == kc) { *str = '\0'; if (str != ostr) { /* getch() displays the kill character */ mvwaddch(win, win->cury, win->curx - 1, ' '); /* Clear the characters from screen and str */ while (str != ostr) { mvwaddch(win, win->cury, win->curx - 1, ' '); wmove(win, win->cury, win->curx - 1); str--; if (n != -1) /* We're counting chars */ remain++; } mvwaddch(win, win->cury, win->curx - 1, ' '); wmove(win, win->cury, win->curx - 1); } else /* getch() displays the kill character */ mvwaddch(win, win->cury, oldx, ' '); wmove(win, win->cury, oldx); } else if (c >= KEY_MIN && c <= KEY_MAX) { /* getch() displays these characters */ mvwaddch(win, win->cury, xpos, ' '); wmove(win, win->cury, xpos); } else { if (remain) { if (iscntrl((unsigned char)c)) mvwaddch(win, win->cury, xpos, ' '); str++; xpos++; remain--; } else mvwaddch(win, win->cury, xpos, ' '); wmove(win, win->cury, xpos); } } if (c == ERR) { *str = '\0'; return (ERR); } *str = '\0'; 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; } } }) }
int wscrl(WINDOW *win, int n) { int physical = FALSE; int i; T(("wscrl(%x,%d) called", win, n)); if (! win->_scroll) return ERR; if (n == 0) return OK; /* as an optimization, if the scrolling region is the entire screen scroll the physical screen */ if ( win->_begx == 0 && win->_maxx == columns - 1 && !memory_above && !memory_below && ((((win->_begy+win->_regtop == 0 && win->_begy+win->_regbottom == lines - 1) || change_scroll_region) && ( (n < 0 && (parm_rindex || scroll_reverse)) || (n > 0 && (parm_index || scroll_forward)) ) ) || (win->_idlok && (parm_insert_line || insert_line) && (parm_delete_line || delete_line) ) ) ) physical = TRUE; if (physical == TRUE) { wrefresh(win); scroll_window(curscr, n, win->_begy+win->_regtop, win->_begy+win->_regbottom); scroll_window(newscr, n, win->_begy+win->_regtop, win->_begy+win->_regbottom); } scroll_window(win, n, win->_regtop, win->_regbottom); if (physical == TRUE) { if (n < 0) { if ( (( win->_begy+win->_regtop == 0 && win->_begy+win->_regbottom == lines - 1) || change_scroll_region) && (parm_rindex || scroll_reverse) ) { if (change_scroll_region && (win->_begy+win->_regtop != 0 || win->_begy+win->_regbottom != lines - 1) ) putp(tparm(change_scroll_region, win->_begy+win->_regtop, win->_begy+win->_regbottom)); i = abs(n); mvcur(-1, -1, win->_begy+win->_regtop, 0); if (parm_rindex) { putp(tparm(parm_rindex, i)); } else if (scroll_reverse) { while (i--) putp(scroll_reverse); } if (change_scroll_region && (win->_begy+win->_regtop != 0 || win->_begy+win->_regbottom != lines - 1) ) putp(tparm(change_scroll_region, 0, lines-1)); } else { i = abs(n); if (win->_begy+win->_regbottom < lines - 1) { mvcur(-1, -1, win->_begy+win->_regbottom, 0); if (parm_delete_line) { putp(tparm(parm_delete_line, i)); } else if (delete_line) { while (i--) putp(delete_line); i = abs(n); } } mvcur(-1, -1, win->_begy+win->_regtop, 0); if (parm_insert_line) { putp(tparm(parm_insert_line, i)); } else if (insert_line) { while (i--) putp(insert_line); } } } else { if ( (( win->_begy+win->_regtop == 0 && win->_begy+win->_regbottom == lines - 1) || change_scroll_region) && (parm_index || scroll_forward) ) { if (change_scroll_region && (win->_begy+win->_regtop != 0 || win->_begy+win->_regbottom != lines - 1) ) putp(tparm(change_scroll_region, win->_begy+win->_regtop, win->_begy+win->_regbottom)); mvcur(-1, -1, win->_begy+win->_regbottom, 0); if (parm_index) { putp(tparm(parm_index, n)); } else if (scroll_forward) { i = n; while (i--) putp(scroll_forward); } if (change_scroll_region && (win->_begy+win->_regtop != 0 || win->_begy+win->_regbottom != lines - 1) ) putp(tparm(change_scroll_region, 0, lines-1)); } else { mvcur(-1, -1, win->_begy+win->_regtop, 0); if (parm_delete_line) { putp(tparm(parm_delete_line, n)); } else if (delete_line) { i = n; while (i--) putp(delete_line); } if (win->_begy+win->_regbottom < lines - 1) { mvcur(win->_begy+win->_regtop, 0, win->_begy+win->_regbottom, 0); if (parm_insert_line) { putp(tparm(parm_insert_line, n)); } else if (insert_line) { i = n; while (i--) putp(insert_line); } } } } mvcur(-1, -1, win->_begy+win->_cury, win->_begx+win->_curx); } else touchline(win, win->_regtop, win->_regbottom - win->_regtop + 1); return OK; }