static NCURSES_INLINE void #endif wbkgrndset(WINDOW *win, const ARG_CH_T ch) { T((T_CALLED("wbkgdset(%p,%s)"), (void *) win, _tracech_t(ch))); if (win) { attr_t off = AttrOf(win->_nc_bkgd); attr_t on = AttrOf(CHDEREF(ch)); toggle_attr_off(WINDOW_ATTRS(win), off); toggle_attr_on(WINDOW_ATTRS(win), on); #if NCURSES_EXT_COLORS { int pair; if ((pair = GetPair(win->_nc_bkgd)) != 0) SET_WINDOW_PAIR(win, 0); if ((pair = GetPair(CHDEREF(ch))) != 0) SET_WINDOW_PAIR(win, pair); } #endif if (CharOf(CHDEREF(ch)) == L('\0')) { SetChar(win->_nc_bkgd, BLANK_TEXT, AttrOf(CHDEREF(ch))); if_EXT_COLORS(SetPair(win->_nc_bkgd, GetPair(CHDEREF(ch)))); } else { win->_nc_bkgd = CHDEREF(ch); } #if USE_WIDEC_SUPPORT /* * If we're compiled for wide-character support, _bkgrnd is the * preferred location for the background information since it stores * more than _bkgd. Update _bkgd each time we modify _bkgrnd, so the * macro getbkgd() will work. */ { cchar_t wch; int tmp; (void) wgetbkgrnd(win, &wch); tmp = _nc_to_char((wint_t) CharOf(wch)); win->_bkgd = (((tmp == EOF) ? ' ' : (chtype) tmp) | (AttrOf(wch) & ALL_BUT_COLOR) | ColorPair(GET_WINDOW_PAIR(win))); } #endif } returnVoid; }
getcchar(const cchar_t *wcval, wchar_t *wch, attr_t *attrs, short *color_pair, void *opts) { wchar_t *wp; int len; int code = ERR; TR(TRACE_CCALLS, (T_CALLED("getcchar(%p,%p,%p,%p,%p)"), wcval, wch, attrs, color_pair, opts)); if (opts == NULL) { len = (wp = wmemchr(wcval->chars, L'\0', CCHARW_MAX)) ? wp - wcval->chars : CCHARW_MAX; if (wch == NULL) { code = len; } else if (attrs == 0 || color_pair == 0) { code = ERR; } else if (len >= 0) { *attrs = AttrOf(*wcval) & A_ATTRIBUTES; *color_pair = GetPair(*wcval); wmemcpy(wch, wcval->chars, (unsigned) len); wch[len] = L'\0'; code = OK; } } TR(TRACE_CCALLS, (T_RETURN("%d"), code)); return (code); }
static NCURSES_INLINE NCURSES_CH_T render_char(WINDOW *win, NCURSES_CH_T ch) /* compute a rendition of the given char correct for the current context */ { attr_t a = WINDOW_ATTRS(win); int pair = GetPair(ch); if (ISBLANK(ch) && AttrOf(ch) == A_NORMAL && pair == 0) { /* color/pair in attrs has precedence over bkgrnd */ ch = win->_nc_bkgd; SetAttr(ch, a | AttrOf(win->_nc_bkgd)); if ((pair = GET_WINDOW_PAIR(win)) == 0) pair = GetPair(win->_nc_bkgd); SetPair(ch, pair); } else { /* color in attrs has precedence over bkgrnd */ a |= AttrOf(win->_nc_bkgd) & COLOR_MASK(a); /* color in ch has precedence */ if (pair == 0) { if ((pair = GET_WINDOW_PAIR(win)) == 0) pair = GetPair(win->_nc_bkgd); } #if 0 if (pair > 255) { NCURSES_CH_T fixme = ch; SetPair(fixme, pair); } #endif AddAttr(ch, (a & COLOR_MASK(AttrOf(ch)))); SetPair(ch, pair); } TR(TRACE_VIRTPUT, ("render_char bkg %s (%d), attrs %s (%d) -> ch %s (%d)", _tracech_t2(1, CHREF(win->_nc_bkgd)), GetPair(win->_nc_bkgd), _traceattr(WINDOW_ATTRS(win)), GET_WINDOW_PAIR(win), _tracech_t2(3, CHREF(ch)), GetPair(ch))); return (ch); }
slk_attr(void) { T((T_CALLED("slk_attr()"))); if (SP != 0 && SP->_slk != 0) { attr_t result = AttrOf(SP->_slk->attr) & ALL_BUT_COLOR; int pair = GetPair(SP->_slk->attr); result |= COLOR_PAIR(pair); returnAttr(result); } else returnAttr(0); }
static int update_cost_from_blank(NCURSES_CH_T * to) { int cost = 0; int i; NCURSES_CH_T blank = blankchar; if (back_color_erase) SetPair(blank, GetPair(stdscr->_nc_bkgd)); for (i = TEXTWIDTH; i > 0; i--) if (!(CharEq(blank, *to++))) cost++; return cost; }
_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; }
getcchar(const cchar_t *wcval, wchar_t *wch, attr_t *attrs, short *color_pair, void *opts) { wchar_t *wp; int len; int code = ERR; TR(TRACE_CCALLS, (T_CALLED("getcchar(%p,%p,%p,%p,%p)"), (const void *) wcval, (void *) wch, (void *) attrs, (void *) color_pair, opts)); if (opts == NULL) { len = ((wp = wmemchr(wcval->chars, L'\0', CCHARW_MAX)) ? (int) (wp - wcval->chars) : CCHARW_MAX); if (wch == NULL) { /* * If the value is a null, set the length to 1. * If the value is not a null, return the length plus 1 for null. */ code = (len < CCHARW_MAX) ? (len + 1) : CCHARW_MAX; } else if (attrs == 0 || color_pair == 0) { code = ERR; } else if (len >= 0) { *attrs = AttrOf(*wcval) & A_ATTRIBUTES; *color_pair = (short) GetPair(*wcval); wmemcpy(wch, wcval->chars, (unsigned) len); wch[len] = L'\0'; code = OK; } } TR(TRACE_CCALLS, (T_RETURN("%d"), code)); return (code); }
_tracedump(const char *name, WINDOW *win) { int i, j, n, width; /* compute narrowest possible display width */ for (width = i = 0; i <= win->_maxy; ++i) { n = 0; for (j = 0; j <= win->_maxx; ++j) { if (CharOf(win->_line[i].text[j]) != L(' ') || AttrOf(win->_line[i].text[j]) != A_NORMAL || GetPair(win->_line[i].text[j]) != 0) { n = j; } } if (n > width) width = n; } if (width < win->_maxx) ++width; if (++width + 1 > (int) my_length) { my_length = 2 * (width + 1); my_buffer = typeRealloc(char, my_length, my_buffer); }
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; }
mvcur(int yold, int xold, int ynew, int xnew) /* optimized cursor move from (yold, xold) to (ynew, xnew) */ { NCURSES_CH_T oldattr; int code; TR(TRACE_CALLS | TRACE_MOVE, (T_CALLED("mvcur(%d,%d,%d,%d)"), yold, xold, ynew, xnew)); if (SP == 0) { code = ERR; } else if (yold == ynew && xold == xnew) { code = OK; } else { /* * Most work here is rounding for terminal boundaries getting the * column position implied by wraparound or the lack thereof and * rolling up the screen to get ynew on the screen. */ if (xnew >= screen_columns) { ynew += xnew / screen_columns; xnew %= screen_columns; } /* * Force restore even if msgr is on when we're in an alternate * character set -- these have a strong tendency to screw up the CR & * LF used for local character motions! */ oldattr = SCREEN_ATTRS(SP); if ((AttrOf(oldattr) & A_ALTCHARSET) || (AttrOf(oldattr) && !move_standout_mode)) { TR(TRACE_CHARPUT, ("turning off (%#lx) %s before move", (unsigned long) AttrOf(oldattr), _traceattr(AttrOf(oldattr)))); (void) VIDATTR(A_NORMAL, 0); } if (xold >= screen_columns) { int l; if (SP->_nl) { l = (xold + 1) / screen_columns; yold += l; if (yold >= screen_lines) l -= (yold - screen_lines - 1); if (l > 0) { if (carriage_return) { TPUTS_TRACE("carriage_return"); putp(carriage_return); } else _nc_outch('\r'); xold = 0; while (l > 0) { if (newline) { TPUTS_TRACE("newline"); putp(newline); } else _nc_outch('\n'); l--; } } } else { /* * If caller set nonl(), we cannot really use newlines to * position to the next row. */ xold = -1; yold = -1; } } if (yold > screen_lines - 1) yold = screen_lines - 1; if (ynew > screen_lines - 1) ynew = screen_lines - 1; /* destination location is on screen now */ code = onscreen_mvcur(yold, xold, ynew, xnew, TRUE); /* * Restore attributes if we disabled them before moving. */ if (!SameAttrOf(oldattr, SCREEN_ATTRS(SP))) { TR(TRACE_CHARPUT, ("turning on (%#lx) %s after move", (unsigned long) AttrOf(oldattr), _traceattr(AttrOf(oldattr)))); (void) VIDATTR(AttrOf(oldattr), GetPair(oldattr)); } } returnCode(code); }
NCURSES_SP_NAME(init_pair) (NCURSES_SP_DCLx NCURSES_PAIRS_T pair, NCURSES_COLOR_T f, NCURSES_COLOR_T b) { colorpair_t result; colorpair_t previous; int maxcolors; T((T_CALLED("init_pair(%p,%d,%d,%d)"), (void *) SP_PARM, (int) pair, (int) f, (int) b)); if (!ValidPair(pair)) returnCode(ERR); maxcolors = MaxColors; previous = SP_PARM->_color_pairs[pair]; #if NCURSES_EXT_FUNCS if (SP_PARM->_default_color || SP_PARM->_assumed_color) { bool isDefault = FALSE; bool wasDefault = FALSE; int default_pairs = SP_PARM->_default_pairs; /* * Map caller's color number, e.g., -1, 0, 1, .., 7, etc., into * internal unsigned values which we will store in the _color_pairs[] * table. */ if (isDefaultColor(f)) { f = COLOR_DEFAULT; isDefault = TRUE; } else if (!OkColorHi(f)) { returnCode(ERR); } if (isDefaultColor(b)) { b = COLOR_DEFAULT; isDefault = TRUE; } else if (!OkColorHi(b)) { returnCode(ERR); } /* * Check if the table entry that we are going to init/update used * default colors. */ if ((FORE_OF(previous) == COLOR_DEFAULT) || (BACK_OF(previous) == COLOR_DEFAULT)) wasDefault = TRUE; /* * Keep track of the number of entries in the color pair table which * used a default color. */ if (isDefault && !wasDefault) { ++default_pairs; } else if (wasDefault && !isDefault) { --default_pairs; } /* * As an extension, ncurses allows the pair number to exceed the * terminal's color_pairs value for pairs using a default color. * * Note that updating a pair which used a default color with one * that does not will decrement the count - and possibly interfere * with sequentially adding new pairs. */ if (pair > (SP_PARM->_pair_count + default_pairs)) { returnCode(ERR); } SP_PARM->_default_pairs = default_pairs; } else #endif { if ((f < 0) || !OkColorHi(f) || (b < 0) || !OkColorHi(b) || (pair < 1)) { returnCode(ERR); } } /* * When a pair's content is changed, replace its colors (if pair was * initialized before a screen update is performed replacing original * pair colors with the new ones). */ result = PAIR_OF(f, b); if (previous != 0 && previous != result) { int y, x; for (y = 0; y <= CurScreen(SP_PARM)->_maxy; y++) { struct ldat *ptr = &(CurScreen(SP_PARM)->_line[y]); bool changed = FALSE; for (x = 0; x <= CurScreen(SP_PARM)->_maxx; x++) { if (GetPair(ptr->text[x]) == pair) { /* Set the old cell to zero to ensure it will be updated on the next doupdate() */ SetChar(ptr->text[x], 0, 0); CHANGED_CELL(ptr, x); changed = TRUE; } } if (changed) NCURSES_SP_NAME(_nc_make_oldhash) (NCURSES_SP_ARGx y); } } SP_PARM->_color_pairs[pair] = result; if (GET_SCREEN_PAIR(SP_PARM) == pair) SET_SCREEN_PAIR(SP_PARM, (int) (~0)); /* force attribute update */ #ifdef USE_TERM_DRIVER CallDriver_3(SP_PARM, td_initpair, pair, f, b); #else if (initialize_pair && InPalette(f) && InPalette(b)) { const color_t *tp = DefaultPalette; TR(TRACE_ATTRS, ("initializing pair: pair = %d, fg=(%d,%d,%d), bg=(%d,%d,%d)", (int) pair, (int) tp[f].red, (int) tp[f].green, (int) tp[f].blue, (int) tp[b].red, (int) tp[b].green, (int) tp[b].blue)); NCURSES_PUTP2("initialize_pair", TPARM_7(initialize_pair, pair, (int) tp[f].red, (int) tp[f].green, (int) tp[f].blue, (int) tp[b].red, (int) tp[b].green, (int) tp[b].blue)); } #endif returnCode(OK); }