/* * Reference: The Unicode Standard 2.0 * * No surrogates supported (we're storing only one 16-bit Unicode value per * cell). */ int _nc_utf8_outch(int ch) { static const unsigned byteMask = 0xBF; static const unsigned otherMark = 0x80; static const unsigned firstMark[] = {0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC}; int result[7], *ptr; int count = 0; if ((unsigned int) ch < 0x80) count = 1; else if ((unsigned int) ch < 0x800) count = 2; else if ((unsigned int) ch < 0x10000) count = 3; else if ((unsigned int) ch < 0x200000) count = 4; else if ((unsigned int) ch < 0x4000000) count = 5; else if ((unsigned int) ch <= 0x7FFFFFFF) count = 6; else { count = 3; ch = 0xFFFD; } ptr = result + count; switch (count) { case 6: *--ptr = (ch | otherMark) & byteMask; ch >>= 6; /* FALLTHRU */ case 5: *--ptr = (ch | otherMark) & byteMask; ch >>= 6; /* FALLTHRU */ case 4: *--ptr = (ch | otherMark) & byteMask; ch >>= 6; /* FALLTHRU */ case 3: *--ptr = (ch | otherMark) & byteMask; ch >>= 6; /* FALLTHRU */ case 2: *--ptr = (ch | otherMark) & byteMask; ch >>= 6; /* FALLTHRU */ case 1: *--ptr = (ch | firstMark[count]); break; } while (count--) _nc_outch(*ptr++); return OK; }
_nc_mvcur_wrap(void) /* wrap up cursor-addressing mode */ { /* leave cursor at screen bottom */ mvcur(-1, -1, screen_lines - 1, 0); /* set cursor to normal mode */ if (SP->_cursor != -1) curs_set(1); if (exit_ca_mode) { TPUTS_TRACE("exit_ca_mode"); putp(exit_ca_mode); } /* * Reset terminal's tab counter. There's a long-time bug that * if you exit a "curses" program such as vi or more, tab * forward, and then backspace, the cursor doesn't go to the * right place. The problem is that the kernel counts the * escape sequences that reset things as column positions. * Utter a \r to reset this invisibly. */ _nc_outch('\r'); }
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); }