void tty_colours_fg(struct tty *tty, const struct grid_cell *gc) { struct grid_cell *tc = &tty->cell; u_char fg = gc->fg; char s[32]; /* Is this a 256-colour colour? */ if (gc->flags & GRID_FLAG_FG256) { /* Try as 256 colours or translating to 88. */ if (tty_try_256(tty, fg, "38") == 0) goto save_fg; if (tty_try_88(tty, fg, "38") == 0) goto save_fg; /* Else already handled by tty_check_fg. */ return; } /* Is this an aixterm bright colour? */ if (fg >= 90 && fg <= 97) { xsnprintf(s, sizeof s, "\033[%dm", fg); tty_puts(tty, s); goto save_fg; } /* Otherwise set the foreground colour. */ tty_putcode1(tty, TTYC_SETAF, fg); save_fg: /* Save the new values in the terminal current cell. */ tc->fg = fg; tc->flags &= ~GRID_FLAG_FG256; tc->flags |= gc->flags & GRID_FLAG_FG256; }
void tty_attributes_bg(struct tty *tty, const struct grid_cell *gc) { u_char bg; bg = gc->bg; if (gc->flags & GRID_FLAG_BG256) { if (tty_try_256(tty, bg, "48") == 0) return; if (tty_try_88(tty, bg, "48") == 0) return; bg = colour_256to16(bg); if (bg & 8) bg &= 7; } if (bg == 8 && !(tty->term->flags & TERM_HASDEFAULTS) && !(tty->term_flags & TERM_HASDEFAULTS)) bg = 0; if (bg == 8) tty_puts(tty, "\033[49m"); else tty_putcode1(tty, TTYC_SETAB, bg); }
void tty_attributes_fg(struct tty *tty, const struct grid_cell *gc) { u_char fg; fg = gc->fg; if (gc->flags & GRID_FLAG_FG256) { if (tty_try_256(tty, fg, "38") == 0) return; if (tty_try_88(tty, fg, "38") == 0) return; fg = colour_256to16(fg); if (fg & 8) { fg &= 7; tty_putcode(tty, TTYC_BOLD); tty->cell.attr |= GRID_ATTR_BRIGHT; } else if (tty->cell.attr & GRID_ATTR_BRIGHT) tty_reset(tty); } if (fg == 8 && !(tty->term->flags & TERM_HASDEFAULTS) && !(tty->term_flags & TERM_HASDEFAULTS)) fg = 7; if (fg == 8) tty_puts(tty, "\033[39m"); else tty_putcode1(tty, TTYC_SETAF, fg); }
void tty_update_mode(struct tty *tty, int mode, struct screen *s) { int changed; if (strcmp(s->ccolour, tty->ccolour)) tty_force_cursor_colour(tty, s->ccolour); if (tty->flags & TTY_NOCURSOR) mode &= ~MODE_CURSOR; changed = mode ^ tty->mode; if (changed & MODE_CURSOR) { if (mode & MODE_CURSOR) tty_putcode(tty, TTYC_CNORM); else tty_putcode(tty, TTYC_CIVIS); } if (tty->cstyle != s->cstyle) { if (tty_term_has(tty->term, TTYC_CS1)) { if (s->cstyle == 0 && tty_term_has(tty->term, TTYC_CSR1)) tty_putcode(tty, TTYC_CSR1); else tty_putcode1(tty, TTYC_CS1, s->cstyle); } tty->cstyle = s->cstyle; } if (changed & ALL_MOUSE_MODES) { if (mode & ALL_MOUSE_MODES) { if (mode & MODE_MOUSE_UTF8) tty_puts(tty, "\033[?1005h"); if (mode & MODE_MOUSE_ANY) tty_puts(tty, "\033[?1003h"); else if (mode & MODE_MOUSE_BUTTON) tty_puts(tty, "\033[?1002h"); else if (mode & MODE_MOUSE_STANDARD) tty_puts(tty, "\033[?1000h"); } else { if (tty->mode & MODE_MOUSE_ANY) tty_puts(tty, "\033[?1003l"); else if (tty->mode & MODE_MOUSE_BUTTON) tty_puts(tty, "\033[?1002l"); else if (tty->mode & MODE_MOUSE_STANDARD) tty_puts(tty, "\033[?1000l"); if (tty->mode & MODE_MOUSE_UTF8) tty_puts(tty, "\033[?1005l"); } } if (changed & MODE_KKEYPAD) { if (mode & MODE_KKEYPAD) tty_putcode(tty, TTYC_SMKX); else tty_putcode(tty, TTYC_RMKX); } tty->mode = mode; }
void tty_emulate_repeat( struct tty *tty, enum tty_code_code code, enum tty_code_code code1, u_int n) { if (tty_term_has(tty->term, code)) tty_putcode1(tty, code, n); else { while (n-- > 0) tty_putcode(tty, code1); } }
void tty_colours_bg(struct tty *tty, const struct grid_cell *gc) { struct grid_cell *tc = &tty->cell; u_char bg = gc->bg; char s[32]; /* Is this a 256-colour colour? */ if (gc->flags & GRID_FLAG_BG256) { /* Try as 256 colours or translating to 88. */ if (tty_try_256(tty, bg, "48") == 0) goto save_bg; if (tty_try_88(tty, bg, "48") == 0) goto save_bg; /* Else already handled by tty_check_bg. */ return; } /* Is this an aixterm bright colour? */ if (bg >= 100 && bg <= 107) { /* 16 colour terminals or above only. */ if (tty_term_number(tty->term, TTYC_COLORS) >= 16) { xsnprintf(s, sizeof s, "\033[%dm", bg); tty_puts(tty, s); goto save_bg; } bg -= 100; /* no such thing as a bold background */ } /* Otherwise set the background colour. */ tty_putcode1(tty, TTYC_SETAB, bg); save_bg: /* Save the new values in the terminal current cell. */ tc->bg = bg; tc->flags &= ~GRID_FLAG_BG256; tc->flags |= gc->flags & GRID_FLAG_BG256; }
void tty_colours(struct tty *tty, const struct grid_cell *gc) { struct grid_cell *tc = &tty->cell; u_char fg = gc->fg, bg = gc->bg, flags = gc->flags; int have_ax, fg_default, bg_default; /* No changes? Nothing is necessary. */ if (fg == tc->fg && bg == tc->bg && ((flags ^ tc->flags) & (GRID_FLAG_FG256|GRID_FLAG_BG256)) == 0) return; /* * Is either the default colour? This is handled specially because the * best solution might be to reset both colours to default, in which * case if only one is default need to fall onward to set the other * colour. */ fg_default = (fg == 8 && !(flags & GRID_FLAG_FG256)); bg_default = (bg == 8 && !(flags & GRID_FLAG_BG256)); if (fg_default || bg_default) { /* * If don't have AX but do have op, send sgr0 (op can't * actually be used because it is sometimes the same as sgr0 * and sometimes isn't). This resets both colours to default. * * Otherwise, try to set the default colour only as needed. */ have_ax = tty_term_has(tty->term, TTYC_AX); if (!have_ax && tty_term_has(tty->term, TTYC_OP)) tty_reset(tty); else { if (fg_default && (tc->fg != 8 || tc->flags & GRID_FLAG_FG256)) { if (have_ax) tty_puts(tty, "\033[39m"); else if (tc->fg != 7 || tc->flags & GRID_FLAG_FG256) tty_putcode1(tty, TTYC_SETAF, 7); tc->fg = 8; tc->flags &= ~GRID_FLAG_FG256; } if (bg_default && (tc->bg != 8 || tc->flags & GRID_FLAG_BG256)) { if (have_ax) tty_puts(tty, "\033[49m"); else if (tc->bg != 0 || tc->flags & GRID_FLAG_BG256) tty_putcode1(tty, TTYC_SETAB, 0); tc->bg = 8; tc->flags &= ~GRID_FLAG_BG256; } } } /* Set the foreground colour. */ if (!fg_default && (fg != tc->fg || ((flags & GRID_FLAG_FG256) != (tc->flags & GRID_FLAG_FG256)))) tty_colours_fg(tty, gc); /* * Set the background colour. This must come after the foreground as * tty_colour_fg() can call tty_reset(). */ if (!bg_default && (bg != tc->bg || ((flags & GRID_FLAG_BG256) != (tc->flags & GRID_FLAG_BG256)))) tty_colours_bg(tty, gc); }
/* Move cursor to absolute position. */ void tty_cursor(struct tty *tty, u_int cx, u_int cy) { struct tty_term *term = tty->term; u_int thisx, thisy; int change; if (cx > tty->sx - 1) cx = tty->sx - 1; thisx = tty->cx; thisy = tty->cy; /* No change. */ if (cx == thisx && cy == thisy) return; /* Very end of the line, just use absolute movement. */ if (thisx > tty->sx - 1) goto absolute; /* Move to home position (0, 0). */ if (cx == 0 && cy == 0 && tty_term_has(term, TTYC_HOME)) { tty_putcode(tty, TTYC_HOME); goto out; } /* Zero on the next line. */ if (cx == 0 && cy == thisy + 1 && thisy != tty->rlower) { tty_putc(tty, '\r'); tty_putc(tty, '\n'); goto out; } /* Moving column or row. */ if (cy == thisy) { /* * Moving column only, row staying the same. */ /* To left edge. */ if (cx == 0) { tty_putc(tty, '\r'); goto out; } /* One to the left. */ if (cx == thisx - 1 && tty_term_has(term, TTYC_CUB1)) { tty_putcode(tty, TTYC_CUB1); goto out; } /* One to the right. */ if (cx == thisx + 1 && tty_term_has(term, TTYC_CUF1)) { tty_putcode(tty, TTYC_CUF1); goto out; } /* Calculate difference. */ change = thisx - cx; /* +ve left, -ve right */ /* * Use HPA if change is larger than absolute, otherwise move * the cursor with CUB/CUF. */ if ((u_int) abs(change) > cx && tty_term_has(term, TTYC_HPA)) { tty_putcode1(tty, TTYC_HPA, cx); goto out; } else if (change > 0 && tty_term_has(term, TTYC_CUB)) { tty_putcode1(tty, TTYC_CUB, change); goto out; } else if (change < 0 && tty_term_has(term, TTYC_CUF)) { tty_putcode1(tty, TTYC_CUF, -change); goto out; } } else if (cx == thisx) { /* * Moving row only, column staying the same. */ /* One above. */ if (thisy != tty->rupper && cy == thisy - 1 && tty_term_has(term, TTYC_CUU1)) { tty_putcode(tty, TTYC_CUU1); goto out; } /* One below. */ if (thisy != tty->rlower && cy == thisy + 1 && tty_term_has(term, TTYC_CUD1)) { tty_putcode(tty, TTYC_CUD1); goto out; } /* Calculate difference. */ change = thisy - cy; /* +ve up, -ve down */ /* * Try to use VPA if change is larger than absolute or if this * change would cross the scroll region, otherwise use CUU/CUD. */ if ((u_int) abs(change) > cy || (change < 0 && cy - change > tty->rlower) || (change > 0 && cy - change < tty->rupper)) { if (tty_term_has(term, TTYC_VPA)) { tty_putcode1(tty, TTYC_VPA, cy); goto out; } } else if (change > 0 && tty_term_has(term, TTYC_CUU)) { tty_putcode1(tty, TTYC_CUU, change); goto out; } else if (change < 0 && tty_term_has(term, TTYC_CUD)) { tty_putcode1(tty, TTYC_CUD, -change); goto out; } } absolute: /* Absolute movement. */ tty_putcode2(tty, TTYC_CUP, cy, cx); out: tty->cx = cx; tty->cy = cy; }