Lines Matching refs:tty
40 static void tty_set_italics(struct tty *);
41 static int tty_try_colour(struct tty *, int, const char *);
42 static void tty_force_cursor_colour(struct tty *, int);
43 static void tty_cursor_pane(struct tty *, const struct tty_ctx *, u_int,
45 static void tty_cursor_pane_unless_wrap(struct tty *,
47 static void tty_colours(struct tty *, const struct grid_cell *);
48 static void tty_check_fg(struct tty *, struct colour_palette *,
50 static void tty_check_bg(struct tty *, struct colour_palette *,
52 static void tty_check_us(struct tty *, struct colour_palette *,
54 static void tty_colours_fg(struct tty *, const struct grid_cell *);
55 static void tty_colours_bg(struct tty *, const struct grid_cell *);
56 static void tty_colours_us(struct tty *, const struct grid_cell *);
58 static void tty_region_pane(struct tty *, const struct tty_ctx *, u_int,
60 static void tty_region(struct tty *, u_int, u_int);
61 static void tty_margin_pane(struct tty *, const struct tty_ctx *);
62 static void tty_margin(struct tty *, u_int, u_int);
63 static int tty_large_region(struct tty *, const struct tty_ctx *);
64 static int tty_fake_bce(const struct tty *, const struct grid_cell *,
66 static void tty_redraw_region(struct tty *, const struct tty_ctx *);
67 static void tty_emulate_repeat(struct tty *, enum tty_code_code,
69 static void tty_repeat_space(struct tty *, u_int);
70 static void tty_draw_pane(struct tty *, const struct tty_ctx *, u_int);
71 static void tty_default_attributes(struct tty *, const struct grid_cell *,
73 static int tty_check_overlay(struct tty *, u_int, u_int);
74 static void tty_check_overlay_range(struct tty *, u_int, u_int, u_int,
78 static void tty_write_one(void (*)(struct tty *, const struct tty_ctx *),
82 #define tty_use_margin(tty) \
83 (tty->term->flags & TERM_DECSLRM)
84 #define tty_full_width(tty, ctx) \
85 ((ctx)->xoff == 0 && (ctx)->sx >= (tty)->sx)
88 #define TTY_BLOCK_START(tty) (1 + ((tty)->sx * (tty)->sy) * 8)
89 #define TTY_BLOCK_STOP(tty) (1 + ((tty)->sx * (tty)->sy) / 8)
107 tty_init(struct tty *tty, struct client *c)
112 memset(tty, 0, sizeof *tty);
113 tty->client = c;
115 tty->cstyle = SCREEN_CURSOR_DEFAULT;
116 tty->ccolour = -1;
117 tty->fg = tty->bg = -1;
119 if (tcgetattr(c->fd, &tty->tio) != 0)
125 tty_resize(struct tty *tty)
127 struct client *c = tty->client;
146 tty->out != NULL &&
147 !(tty->flags & TTY_WINSIZEQUERY) &&
148 (tty->term->flags & TERM_VT100LIKE)) {
149 tty_puts(tty, "\033[18t\033[14t");
150 tty->flags |= TTY_WINSIZEQUERY;
160 tty_set_size(tty, sx, sy, xpixel, ypixel);
161 tty_invalidate(tty);
165 tty_set_size(struct tty *tty, u_int sx, u_int sy, u_int xpixel, u_int ypixel)
167 tty->sx = sx;
168 tty->sy = sy;
169 tty->xpixel = xpixel;
170 tty->ypixel = ypixel;
176 struct tty *tty = data;
177 struct client *c = tty->client;
179 size_t size = EVBUFFER_LENGTH(tty->in);
182 nread = evbuffer_read(tty->in, c->fd, -1);
188 event_del(&tty->event_in);
189 server_client_lost(tty->client);
194 while (tty_keys_next(tty))
201 struct tty *tty = data;
202 struct client *c = tty->client;
205 log_debug("%s: %zu discarded", c->name, tty->discarded);
208 c->discarded += tty->discarded;
210 if (tty->discarded < TTY_BLOCK_STOP(tty)) {
211 tty->flags &= ~TTY_BLOCK;
212 tty_invalidate(tty);
215 tty->discarded = 0;
216 evtimer_add(&tty->timer, &tv);
220 tty_block_maybe(struct tty *tty)
222 struct client *c = tty->client;
223 size_t size = EVBUFFER_LENGTH(tty->out);
227 tty->flags &= ~TTY_NOBLOCK;
228 else if (tty->flags & TTY_NOBLOCK)
231 if (size < TTY_BLOCK_START(tty))
234 if (tty->flags & TTY_BLOCK)
236 tty->flags |= TTY_BLOCK;
240 evbuffer_drain(tty->out, size);
243 tty->discarded = 0;
244 evtimer_add(&tty->timer, &tv);
251 struct tty *tty = data;
252 struct client *c = tty->client;
253 size_t size = EVBUFFER_LENGTH(tty->out);
256 nwrite = evbuffer_write(tty->out, c->fd);
268 } else if (tty_block_maybe(tty))
271 if (EVBUFFER_LENGTH(tty->out) != 0)
272 event_add(&tty->event_out, NULL);
276 tty_open(struct tty *tty, char **cause)
278 struct client *c = tty->client;
280 tty->term = tty_term_create(tty, c->term_name, c->term_caps,
282 if (tty->term == NULL) {
283 tty_close(tty);
286 tty->flags |= TTY_OPENED;
288 tty->flags &= ~(TTY_NOCURSOR|TTY_FREEZE|TTY_BLOCK|TTY_TIMER);
290 event_set(&tty->event_in, c->fd, EV_PERSIST|EV_READ,
291 tty_read_callback, tty);
292 tty->in = evbuffer_new();
293 if (tty->in == NULL)
296 event_set(&tty->event_out, c->fd, EV_WRITE, tty_write_callback, tty);
297 tty->out = evbuffer_new();
298 if (tty->out == NULL)
301 evtimer_set(&tty->clipboard_timer, tty_clipboard_query_callback, tty);
302 evtimer_set(&tty->start_timer, tty_start_timer_callback, tty);
303 evtimer_set(&tty->timer, tty_timer_callback, tty);
305 tty_start_tty(tty);
306 tty_keys_build(tty);
314 struct tty *tty = data;
315 struct client *c = tty->client;
319 if ((tty->flags & (TTY_HAVEDA|TTY_HAVEDA2|TTY_HAVEXDA)) == 0)
320 tty_update_features(tty);
321 tty->flags |= TTY_ALL_REQUEST_FLAGS;
323 tty->flags &= ~(TTY_WAITBG|TTY_WAITFG);
327 tty_start_start_timer(struct tty *tty)
329 struct client *c = tty->client;
333 evtimer_del(&tty->start_timer);
334 evtimer_add(&tty->start_timer, &tv);
338 tty_start_tty(struct tty *tty)
340 struct client *c = tty->client;
344 event_add(&tty->event_in, NULL);
346 memcpy(&tio, &tty->tio, sizeof tio);
357 tty_putcode(tty, TTYC_SMCUP);
359 tty_putcode(tty, TTYC_SMKX);
360 tty_putcode(tty, TTYC_CLEAR);
362 if (tty_acs_needed(tty)) {
364 tty_putcode(tty, TTYC_ENACS);
368 tty_putcode(tty, TTYC_CNORM);
369 if (tty_term_has(tty->term, TTYC_KMOUS)) {
370 tty_puts(tty, "\033[?1000l\033[?1002l\033[?1003l");
371 tty_puts(tty, "\033[?1006l\033[?1005l");
373 if (tty_term_has(tty->term, TTYC_ENBP))
374 tty_putcode(tty, TTYC_ENBP);
376 if (tty->term->flags & TERM_VT100LIKE) {
378 tty_puts(tty, "\033[?2031h\033[?996n");
381 tty_start_start_timer(tty);
383 tty->flags |= TTY_STARTED;
384 tty_invalidate(tty);
386 if (tty->ccolour != -1)
387 tty_force_cursor_colour(tty, -1);
389 tty->mouse_drag_flag = 0;
390 tty->mouse_drag_update = NULL;
391 tty->mouse_drag_release = NULL;
395 tty_send_requests(struct tty *tty)
397 if (~tty->flags & TTY_STARTED)
400 if (tty->term->flags & TERM_VT100LIKE) {
401 if (~tty->flags & TTY_HAVEDA)
402 tty_puts(tty, "\033[c");
403 if (~tty->flags & TTY_HAVEDA2)
404 tty_puts(tty, "\033[>c");
405 if (~tty->flags & TTY_HAVEXDA)
406 tty_puts(tty, "\033[>q");
407 tty_puts(tty, "\033]10;?\033\\\033]11;?\033\\");
408 tty->flags |= (TTY_WAITBG|TTY_WAITFG);
410 tty->flags |= TTY_ALL_REQUEST_FLAGS;
411 tty->last_requests = time(NULL);
415 tty_repeat_requests(struct tty *tty, int force)
417 struct client *c = tty->client;
419 u_int n = t - tty->last_requests;
421 if (~tty->flags & TTY_STARTED)
431 tty->last_requests = t;
433 if (tty->term->flags & TERM_VT100LIKE) {
434 tty_puts(tty, "\033]10;?\033\\\033]11;?\033\\");
435 tty->flags |= (TTY_WAITBG|TTY_WAITFG);
437 tty_start_start_timer(tty);
441 tty_stop_tty(struct tty *tty)
443 struct client *c = tty->client;
446 if (!(tty->flags & TTY_STARTED))
448 tty->flags &= ~TTY_STARTED;
450 evtimer_del(&tty->start_timer);
451 evtimer_del(&tty->clipboard_timer);
453 event_del(&tty->timer);
454 tty->flags &= ~TTY_BLOCK;
456 event_del(&tty->event_in);
457 event_del(&tty->event_out);
462 * with a dead tty.
466 if (tcsetattr(c->fd, TCSANOW, &tty->tio) == -1)
469 tty_raw(tty, tty_term_string_ii(tty->term, TTYC_CSR, 0, ws.ws_row - 1));
470 if (tty_acs_needed(tty))
471 tty_raw(tty, tty_term_string(tty->term, TTYC_RMACS));
472 tty_raw(tty, tty_term_string(tty->term, TTYC_SGR0));
473 tty_raw(tty, tty_term_string(tty->term, TTYC_RMKX));
474 tty_raw(tty, tty_term_string(tty->term, TTYC_CLEAR));
475 if (tty->cstyle != SCREEN_CURSOR_DEFAULT) {
476 if (tty_term_has(tty->term, TTYC_SE))
477 tty_raw(tty, tty_term_string(tty->term, TTYC_SE));
478 else if (tty_term_has(tty->term, TTYC_SS))
479 tty_raw(tty, tty_term_string_i(tty->term, TTYC_SS, 0));
481 if (tty->ccolour != -1)
482 tty_raw(tty, tty_term_string(tty->term, TTYC_CR));
484 tty_raw(tty, tty_term_string(tty->term, TTYC_CNORM));
485 if (tty_term_has(tty->term, TTYC_KMOUS)) {
486 tty_raw(tty, "\033[?1000l\033[?1002l\033[?1003l");
487 tty_raw(tty, "\033[?1006l\033[?1005l");
489 if (tty_term_has(tty->term, TTYC_DSBP))
490 tty_raw(tty, tty_term_string(tty->term, TTYC_DSBP));
492 if (tty->term->flags & TERM_VT100LIKE)
493 tty_raw(tty, "\033[?7727l");
494 tty_raw(tty, tty_term_string(tty->term, TTYC_DSFCS));
495 tty_raw(tty, tty_term_string(tty->term, TTYC_DSEKS));
497 if (tty_use_margin(tty))
498 tty_raw(tty, tty_term_string(tty->term, TTYC_DSMG));
499 tty_raw(tty, tty_term_string(tty->term, TTYC_RMCUP));
501 if (tty->term->flags & TERM_VT100LIKE)
502 tty_raw(tty, "\033[?2031l");
508 tty_close(struct tty *tty)
510 if (event_initialized(&tty->key_timer))
511 evtimer_del(&tty->key_timer);
512 tty_stop_tty(tty);
514 if (tty->flags & TTY_OPENED) {
515 evbuffer_free(tty->in);
516 event_del(&tty->event_in);
517 evbuffer_free(tty->out);
518 event_del(&tty->event_out);
520 tty_term_free(tty->term);
521 tty_keys_free(tty);
523 tty->flags &= ~TTY_OPENED;
528 tty_free(struct tty *tty)
530 tty_close(tty);
534 tty_update_features(struct tty *tty)
536 struct client *c = tty->client;
538 if (tty_apply_features(tty->term, c->term_features))
539 tty_term_apply_overrides(tty->term);
541 if (tty_use_margin(tty))
542 tty_putcode(tty, TTYC_ENMG);
544 tty_puts(tty, tty_term_string(tty->term, TTYC_ENEKS));
546 tty_puts(tty, tty_term_string(tty->term, TTYC_ENFCS));
547 if (tty->term->flags & TERM_VT100LIKE)
548 tty_puts(tty, "\033[?7727h");
556 tty_invalidate(tty);
560 tty_raw(struct tty *tty, const char *s)
562 struct client *c = tty->client;
581 tty_putcode(struct tty *tty, enum tty_code_code code)
583 tty_puts(tty, tty_term_string(tty->term, code));
587 tty_putcode_i(struct tty *tty, enum tty_code_code code, int a)
591 tty_puts(tty, tty_term_string_i(tty->term, code, a));
595 tty_putcode_ii(struct tty *tty, enum tty_code_code code, int a, int b)
599 tty_puts(tty, tty_term_string_ii(tty->term, code, a, b));
603 tty_putcode_iii(struct tty *tty, enum tty_code_code code, int a, int b, int c)
607 tty_puts(tty, tty_term_string_iii(tty->term, code, a, b, c));
611 tty_putcode_s(struct tty *tty, enum tty_code_code code, const char *a)
614 tty_puts(tty, tty_term_string_s(tty->term, code, a));
618 tty_putcode_ss(struct tty *tty, enum tty_code_code code, const char *a,
622 tty_puts(tty, tty_term_string_ss(tty->term, code, a, b));
626 tty_add(struct tty *tty, const char *buf, size_t len)
628 struct client *c = tty->client;
630 if (tty->flags & TTY_BLOCK) {
631 tty->discarded += len;
635 evbuffer_add(tty->out, buf, len);
641 if (tty
642 event_add(&tty->event_out, NULL);
646 tty_puts(struct tty *tty, const char *s)
649 tty_add(tty, s, strlen(s));
653 tty_putc(struct tty *tty, u_char ch)
657 if ((tty->term->flags & TERM_NOAM) &&
659 tty->cy == tty->sy - 1 &&
660 tty->cx + 1 >= tty->sx)
663 if (tty->cell.attr & GRID_ATTR_CHARSET) {
664 acs = tty_acs_get(tty, ch);
666 tty_add(tty, acs, strlen(acs));
668 tty_add(tty, (char *)&ch, 1);
670 tty_add(tty, (char *)&ch, 1);
673 if (tty->cx >= tty->sx) {
674 tty->cx = 1;
675 if (tty->cy != tty->rlower)
676 tty->cy++;
683 if (tty->term->flags & TERM_NOAM)
684 tty_putcode_ii(tty, TTYC_CUP, tty->cy, tty->cx);
686 tty->cx++;
691 tty_putn(struct tty *tty, const void *buf, size_t len, u_int width)
693 if ((tty->term->flags & TERM_NOAM) &&
694 tty->cy == tty->sy - 1 &&
695 tty->cx + len >= tty->sx)
696 len = tty->sx - tty->cx - 1;
698 tty_add(tty, buf, len);
699 if (tty->cx + width > tty->sx) {
700 tty->cx = (tty->cx + width) - tty->sx;
701 if (tty->cx <= tty->sx)
702 tty->cy++;
704 tty->cx = tty->cy = UINT_MAX;
706 tty->cx += width;
710 tty_set_italics(struct tty *tty)
714 if (tty_term_has(tty->term, TTYC_SITM)) {
717 tty_putcode(tty, TTYC_SITM);
721 tty_putcode(tty, TTYC_SMSO);
725 tty_set_title(struct tty *tty, const char *title)
727 if (!tty_term_has(tty->term, TTYC_TSL) ||
728 !tty_term_has(tty->term, TTYC_FSL))
731 tty_putcode(tty, TTYC_TSL);
732 tty_puts(tty, title);
733 tty_putcode(tty, TTYC_FSL);
737 tty_set_path(struct tty *tty, const char *title)
739 if (!tty_term_has(tty->term, TTYC_SWD) ||
740 !tty_term_has(tty->term, TTYC_FSL))
743 tty_putcode(tty, TTYC_SWD);
744 tty_puts(tty, title);
745 tty_putcode(tty, TTYC_FSL);
749 tty_force_cursor_colour(struct tty *tty, int c)
756 if (c == tty->ccolour)
759 tty_putcode(tty, TTYC_CR);
763 tty_putcode_s(tty, TTYC_CS, s);
765 tty->ccolour = c;
769 tty_update_cursor(struct tty *tty, int mode, struct screen *s)
779 tty_force_cursor_colour(tty, ccolour);
784 if (tty->mode & MODE_CURSOR)
785 tty_putcode(tty, TTYC_CIVIS);
791 cstyle = tty->cstyle;
806 changed = cmode ^ tty->mode;
807 if ((changed & CURSOR_MODES) == 0 && cstyle == tty->cstyle)
817 tty_putcode(tty, TTYC_CNORM);
820 if (tty->cstyle != SCREEN_CURSOR_DEFAULT) {
821 if (tty_term_has(tty->term, TTYC_SE))
822 tty_putcode(tty, TTYC_SE);
824 tty_putcode_i(tty, TTYC_SS, 0);
827 tty_putcode(tty, TTYC_CVVIS);
830 if (tty_term_has(tty->term, TTYC_SS)) {
832 tty_putcode_i(tty, TTYC_SS, 1);
834 tty_putcode_i(tty, TTYC_SS, 2);
836 tty_putcode(tty, TTYC_CVVIS);
839 if (tty_term_has(tty->term, TTYC_SS)) {
841 tty_putcode_i(tty, TTYC_SS, 3);
843 tty_putcode_i(tty, TTYC_SS, 4);
845 tty_putcode(tty, TTYC_CVVIS);
848 if (tty_term_has(tty->term, TTYC_SS)) {
850 tty_putcode_i(tty, TTYC_SS, 5);
852 tty_putcode_i(tty, TTYC_SS, 6);
854 tty_putcode(tty, TTYC_CVVIS);
857 tty->cstyle = cstyle;
862 tty_update_mode(struct tty *tty, int mode, struct screen *s)
864 struct tty_term *term = tty->term;
865 struct client *c = tty->client;
868 if (tty->flags & TTY_NOCURSOR)
871 if (tty_update_cursor(tty, mode, s) & MODE_CURSOR_BLINKING)
876 changed = mode ^ tty->mode;
879 screen_mode_to_string(tty->mode));
890 tty_puts(tty, "\033[?1006l\033[?1000l\033[?1002l\033[?1003l");
892 tty_puts(tty, "\033[?1006h");
894 tty_puts(tty, "\033[?1000h\033[?1002h\033[?1003h");
896 tty_puts(tty, "\033[?1000h\033[?1002h");
898 tty_puts(tty, "\033[?1000h");
900 tty->mode = mode;
904 tty_emulate_repeat(struct tty *tty, enum tty_code_code code,
907 if (tty_term_has(tty->term, code))
908 tty_putcode_i(tty, code, n);
911 tty_putcode(tty, code1);
916 tty_repeat_space(struct tty *tty, u_int n)
924 tty_putn(tty, s, sizeof s, sizeof s);
928 tty_putn(tty, s, n, n);
933 tty_window_bigger(struct tty *tty)
935 struct client *c = tty->client;
938 return (tty->sx < w->sx || tty->sy - status_line_size(c) < w->sy);
943 tty_window_offset(struct tty *tty, u_int *ox, u_int *oy, u_int *sx, u_int *sy)
945 *ox = tty->oox;
946 *oy = tty->ooy;
947 *sx = tty->osx;
948 *sy = tty->osy;
950 return (tty->oflag);
955 tty_window_offset1(struct tty *tty, u_int *ox, u_int *oy, u_int *sx, u_int *sy)
957 struct client *c = tty->client;
964 if (tty->sx >= w->sx && tty->sy - lines >= w->sy) {
974 *sx = tty->sx;
975 *sy = tty->sy - lines;
1040 c->tty.oflag = tty_window_offset1(&c->tty, &ox, &oy, &sx, &sy);
1041 if (ox == c->tty.oox &&
1042 oy == c->tty.ooy &&
1043 sx == c->tty.osx &&
1044 sy == c->tty.osy)
1048 __func__, c->name, c->tty.oox, c->tty.ooy, c->tty.osx, c->tty.osy,
1051 c->tty.oox = ox;
1052 c->tty.ooy = oy;
1053 c->tty.osx = sx;
1054 c->tty.osy = sy;
1065 tty_large_region(__unused struct tty *tty, const struct tty_ctx *ctx)
1075 tty_fake_bce(const struct tty *tty, const struct grid_cell *gc, u_int bg)
1077 if (tty_term_flag(tty->term, TTYC_BCE))
1090 tty_redraw_region(struct tty *tty, const struct tty_ctx *ctx)
1092 struct client *c = tty->client;
1099 if (tty_large_region(tty, ctx)) {
1106 tty_draw_pane(tty, ctx, i);
1111 tty_is_visible(__unused struct tty *tty, const struct tty_ctx *ctx, u_int px,
1127 tty_clamp_line(struct tty *tty, const struct tty_ctx *ctx, u_int px, u_int py,
1132 if (!tty_is_visible(tty, ctx, px, py, nx, 1))
1165 tty_clear_line(struct tty *tty, const struct grid_cell *defaults, u_int py,
1168 struct client *c = tty->client;
1179 if (c->overlay_check == NULL && !tty_fake_bce(tty, defaults, bg)) {
1181 if (px + nx >= tty->sx && tty_term_has(tty->term, TTYC_EL)) {
1182 tty_cursor(tty, px, py);
1183 tty_putcode(tty, TTYC_EL);
1188 if (px == 0 && tty_term_has(tty->term, TTYC_EL1)) {
1189 tty_cursor(tty, px + nx - 1, py);
1190 tty_putcode(tty, TTYC_EL1);
1195 if (tty_term_has(tty->term, TTYC_ECH)) {
1196 tty_cursor(tty, px, py);
1197 tty_putcode_i(tty, TTYC_ECH, nx);
1206 tty_check_overlay_range(tty, px, py, nx, &r);
1210 tty_cursor(tty, r.px[i], py);
1211 tty_repeat_space(tty, r.nx[i]);
1217 tty_clear_pane_line(struct tty *tty, const struct tty_ctx *ctx, u_int py,
1220 struct client *c = tty->client;
1225 if (tty_clamp_line(tty, ctx, px, py, nx, &i, &x, &rx, &ry))
1226 tty_clear_line(tty, &ctx->defaults, ry, x, rx, bg);
1231 tty_clamp_area(struct tty *tty, const struct tty_ctx *ctx, u_int px, u_int py,
1237 if (!tty_is_visible(tty, ctx, px, py, nx, ny))
1293 tty_clear_area(struct tty *tty, const struct grid_cell *defaults, u_int py,
1296 struct client *c = tty->client;
1307 if (c->overlay_check == NULL && !tty_fake_bce(tty, defaults, bg)) {
1310 px + nx >= tty->sx &&
1311 py + ny >= tty->sy &&
1312 tty_term_has(tty->term, TTYC_ED)) {
1313 tty_cursor(tty, 0, py);
1314 tty_putcode(tty, TTYC_ED);
1323 if ((tty->term->flags & TERM_DECFRA) && !COLOUR_DEFAULT(bg)) {
1326 tty_puts(tty, tmp);
1332 px + nx >= tty->sx &&
1334 tty_term_has(tty->term, TTYC_CSR) &&
1335 tty_term_has(tty->term, TTYC_INDN)) {
1336 tty_region(tty, py, py + ny - 1);
1337 tty_margin_off(tty);
1338 tty_putcode_i(tty, TTYC_INDN, ny);
1348 tty_term_has(tty->term, TTYC_CSR) &&
1349 tty_use_margin(tty) &&
1350 tty_term_has(tty->term, TTYC_INDN)) {
1351 tty_region(tty, py, py + ny - 1);
1352 tty_margin(tty, px, px + nx - 1);
1353 tty_putcode_i(tty, TTYC_INDN, ny);
1360 tty_clear_line(tty, defaults, yy, px, nx, bg);
1365 tty_clear_pane_area(struct tty *tty, const struct tty_ctx *ctx, u_int py,
1370 if (tty_clamp_area(tty, ctx, px, py, nx, ny, &i, &j, &x, &y, &rx, &ry))
1371 tty_clear_area(tty, &ctx->defaults, y, ry, x, rx, bg);
1375 tty_draw_pane(struct tty *tty, const struct tty_ctx *ctx, u_int py)
1380 log_debug("%s: %s %u %d", __func__, tty->client->name, py, ctx->bigger);
1383 tty_draw_line(tty, s, 0, py, nx, ctx->xoff, ctx->yoff + py,
1387 if (tty_clamp_line(tty, ctx, 0, py, nx, &i, &x, &rx, &ry)) {
1388 tty_draw_line(tty, s, i, py, rx, x, ry, &ctx->defaults,
1394 tty_check_codeset(struct tty *tty, const struct grid_cell *gc)
1406 if (tty->client->flags & CLIENT_UTF8)
1411 c = tty_acs_reverse_get(tty, (const char *)gc->data.data, gc->data.size);
1431 tty_check_overlay(struct tty *tty, u_int px, u_int py)
1440 tty_check_overlay_range(tty, px, py, 1, &r);
1448 tty_check_overlay_range(struct tty *tty, u_int px, u_int py, u_int nx,
1451 struct client *c = tty->client;
1467 tty_draw_line(struct tty *tty, struct screen *s, u_int px, u_int py, u_int nx,
1475 struct client *c = tty->client;
1494 flags = (tty->flags & TTY_NOCURSOR);
1495 tty->flags |= TTY_NOCURSOR;
1496 tty_update_mode(tty, tty->mode, s);
1498 tty_region_off(tty);
1499 tty_margin_off(tty);
1511 if (sx > tty->sx)
1512 sx = tty->sx;
1524 tty->cx < tty->sx ||
1525 nx < tty->sx) {
1526 if (nx < tty->sx &&
1529 tty_term_has(tty->term, TTYC_EL1) &&
1530 !tty_fake_bce(tty, defaults, 8) &&
1532 tty_default_attributes(tty, defaults, palette, 8,
1534 tty_cursor(tty, nx - 1, aty);
1535 tty_putcode(tty, TTYC_EL1);
1549 gcp = tty_check_codeset(tty, &gc);
1551 (!tty_check_overlay(tty, atx + ux + width, aty) ||
1561 tty_attributes(tty, &last, defaults, palette,
1565 tty_clear_line(tty, defaults, aty, atx + ux,
1569 tty_cursor(tty, atx + ux, aty);
1570 tty_putn(tty, buf, len, width);
1584 tty_check_overlay_range(tty, atx + ux, aty, gcp->data.width,
1595 tty_attributes(tty, &last, defaults, palette,
1603 tty_cursor(tty, r.px[j], aty);
1607 tty_repeat_space(tty, r.nx[j]);
1613 tty_attributes(tty, &last, defaults, palette,
1615 tty_cursor(tty, atx + ux, aty);
1617 tty_putc(tty, gcp->data.data[j]);
1626 tty_attributes(tty, &last, defaults, palette, s->hyperlinks);
1629 tty_clear_line(tty, defaults, aty, atx + ux, width,
1633 tty_cursor(tty, atx + ux, aty);
1634 tty_putn(tty, buf, len, width);
1642 tty_default_attributes(tty, defaults, palette, 8,
1644 tty_clear_line(tty, defaults, aty, atx + ux, nx - ux, 8);
1647 tty->flags = (tty->flags & ~TTY_NOCURSOR) | flags;
1648 tty_update_mode(tty, tty->mode, s);
1664 ttyctx->bigger = tty_window_offset(&c->tty, &ttyctx->wox, &ttyctx->woy,
1704 tty_sync_start(struct tty *tty)
1706 if (tty->flags & TTY_BLOCK)
1708 if (tty->flags & TTY_SYNCING)
1710 tty->flags |= TTY_SYNCING;
1712 if (tty_term_has(tty->term, TTYC_SYNC)) {
1713 log_debug("%s sync start", tty->client->name);
1714 tty_putcode_i(tty, TTYC_SYNC, 1);
1719 tty_sync_end(struct tty *tty)
1721 if (tty->flags & TTY_BLOCK)
1723 if (~tty->flags & TTY_SYNCING)
1725 tty->flags &= ~TTY_SYNCING;
1727 if (tty_term_has(tty->term, TTYC_SYNC)) {
1728 log_debug("%s sync end", tty->client->name);
1729 tty_putcode_i(tty, TTYC_SYNC, 2);
1736 if (c->session == NULL || c->tty.term == NULL)
1750 if (c->tty.flags & TTY_FREEZE)
1756 tty_write(void (*cmdfn)(struct tty *, const struct tty_ctx *),
1771 cmdfn(&c->tty, ctx);
1777 /* Only write to the incoming tty instead of every client. */
1779 tty_write_one(void (*cmdfn)(struct tty *, const struct tty_ctx *),
1785 cmdfn(&c->tty, ctx);
1790 tty_cmd_insertcharacter(struct tty *tty, const struct tty_ctx *ctx)
1792 struct client *c = tty->client;
1795 !tty_full_width(tty, ctx) ||
1796 tty_fake_bce(tty, &ctx->defaults, ctx->bg) ||
1797 (!tty_term_has(tty->term, TTYC_ICH) &&
1798 !tty_term_has(tty->term, TTYC_ICH1)) ||
1800 tty_draw_pane(tty, ctx, ctx->ocy);
1804 tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg,
1807 tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
1809 tty_emulate_repeat(tty, TTYC_ICH, TTYC_ICH1, ctx->num);
1813 tty_cmd_deletecharacter(struct tty *tty, const struct tty_ctx *ctx)
1815 struct client *c = tty->client;
1818 !tty_full_width(tty, ctx) ||
1819 tty_fake_bce(tty, &ctx->defaults, ctx->bg) ||
1820 (!tty_term_has(tty->term, TTYC_DCH) &&
1821 !tty_term_has(tty->term, TTYC_DCH1)) ||
1823 tty_draw_pane(tty, ctx, ctx->ocy);
1827 tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg,
1830 tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
1832 tty_emulate_repeat(tty, TTYC_DCH, TTYC_DCH1, ctx->num);
1836 tty_cmd_clearcharacter(struct tty *tty, const struct tty_ctx *ctx)
1838 tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg,
1841 tty_clear_pane_line(tty, ctx, ctx->ocy, ctx->ocx, ctx->num, ctx->bg);
1845 tty_cmd_insertline(struct tty *tty, const struct tty_ctx *ctx)
1847 struct client *c = tty->client;
1850 !tty_full_width(tty, ctx) ||
1851 tty_fake_bce(tty, &ctx->defaults, ctx->bg) ||
1852 !tty_term_has(tty->term, TTYC_CSR) ||
1853 !tty_term_has(tty->term, TTYC_IL1) ||
1857 tty_redraw_region(tty, ctx);
1861 tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg,
1864 tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
1865 tty_margin_off(tty);
1866 tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
1868 tty_emulate_repeat(tty, TTYC_IL, TTYC_IL1, ctx->num);
1869 tty->cx = tty->cy = UINT_MAX;
1873 tty_cmd_deleteline(struct tty *tty, const struct tty_ctx *ctx)
1875 struct client *c = tty->client;
1878 !tty_full_width(tty, ctx) ||
1879 tty_fake_bce(tty, &ctx->defaults, ctx->bg) ||
1880 !tty_term_has(tty->term, TTYC_CSR) ||
1881 !tty_term_has(tty->term, TTYC_DL1) ||
1885 tty_redraw_region(tty, ctx);
1889 tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg,
1892 tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
1893 tty_margin_off(tty);
1894 tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
1896 tty_emulate_repeat(tty, TTYC_DL, TTYC_DL1, ctx->num);
1897 tty->cx = tty->cy = UINT_MAX;
1901 tty_cmd_clearline(struct tty *tty, const struct tty_ctx *ctx)
1903 tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg,
1906 tty_clear_pane_line(tty, ctx, ctx->ocy, 0, ctx->sx, ctx->bg);
1910 tty_cmd_clearendofline(struct tty *tty, const struct tty_ctx *ctx)
1914 tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg,
1917 tty_clear_pane_line(tty, ctx, ctx->ocy, ctx->ocx, nx, ctx->bg);
1921 tty_cmd_clearstartofline(struct tty *tty, const struct tty_ctx *ctx)
1923 tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg,
1926 tty_clear_pane_line(tty, ctx, ctx->ocy, 0, ctx->ocx + 1, ctx->bg);
1930 tty_cmd_reverseindex(struct tty *tty, const struct tty_ctx *ctx)
1932 struct client *c = tty->client;
1938 (!tty_full_width(tty, ctx) && !tty_use_margin(tty)) ||
1939 tty_fake_bce(tty, &ctx->defaults, 8) ||
1940 !tty_term_has(tty->term, TTYC_CSR) ||
1941 (!tty_term_has(tty->term, TTYC_RI) &&
1942 !tty_term_has(tty->term, TTYC_RIN)) ||
1946 tty_redraw_region(tty, ctx);
1950 tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg,
1953 tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
1954 tty_margin_pane(tty, ctx);
1955 tty_cursor_pane(tty, ctx, ctx->ocx, ctx->orupper);
1957 if (tty_term_has(tty->term, TTYC_RI))
1958 tty_putcode(tty, TTYC_RI);
1960 tty_putcode_i(tty, TTYC_RIN, 1);
1964 tty_cmd_linefeed(struct tty *tty, const struct tty_ctx *ctx)
1966 struct client *c = tty->client;
1972 (!tty_full_width(tty, ctx) && !tty_use_margin(tty)) ||
1973 tty_fake_bce(tty, &ctx->defaults, 8) ||
1974 !tty_term_has(tty->term, TTYC_CSR) ||
1978 tty_redraw_region(tty, ctx);
1982 tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg,
1985 tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
1986 tty_margin_pane(tty, ctx);
1995 if (ctx->xoff + ctx->ocx > tty->rright) {
1996 if (!tty_use_margin(tty))
1997 tty_cursor(tty, 0, ctx->yoff + ctx->ocy);
1999 tty_cursor(tty, tty->rright, ctx->yoff + ctx->ocy);
2001 tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
2003 tty_putc(tty, '\n');
2007 tty_cmd_scrollup(struct tty *tty, const struct tty_ctx *ctx)
2009 struct client *c = tty->client;
2013 (!tty_full_width(tty, ctx) && !tty_use_margin(tty)) ||
2014 tty_fake_bce(tty, &ctx->defaults, 8) ||
2015 !tty_term_has(tty->term, TTYC_CSR) ||
2019 tty_redraw_region(tty, ctx);
2023 tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg,
2026 tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
2027 tty_margin_pane(tty, ctx);
2029 if (ctx->num == 1 || !tty_term_has(tty->term, TTYC_INDN)) {
2030 if (!tty_use_margin(tty))
2031 tty_cursor(tty, 0, tty->rlower);
2033 tty_cursor(tty, tty->rright, tty->rlower);
2035 tty_putc(tty, '\n');
2037 if (tty->cy == UINT_MAX)
2038 tty_cursor(tty, 0, 0);
2040 tty_cursor(tty, 0, tty->cy);
2041 tty_putcode_i(tty, TTYC_INDN, ctx->num);
2046 tty_cmd_scrolldown(struct tty *tty, const struct tty_ctx *ctx)
2049 struct client *c = tty->client;
2052 (!tty_full_width(tty, ctx) && !tty_use_margin(tty)) ||
2053 tty_fake_bce(tty, &ctx->defaults, 8) ||
2054 !tty_term_has(tty->term, TTYC_CSR) ||
2055 (!tty_term_has(tty->term, TTYC_RI) &&
2056 !tty_term_has(tty->term, TTYC_RIN)) ||
2060 tty_redraw_region(tty, ctx);
2064 tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg,
2067 tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
2068 tty_margin_pane(tty, ctx);
2069 tty_cursor_pane(tty, ctx, ctx->ocx, ctx->orupper);
2071 if (tty_term_has(tty->term, TTYC_RIN))
2072 tty_putcode_i(tty, TTYC_RIN, ctx->num);
2075 tty_putcode(tty, TTYC_RI);
2080 tty_cmd_clearendofscreen(struct tty *tty, const struct tty_ctx *ctx)
2084 tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg,
2087 tty_region_pane(tty, ctx, 0, ctx->sy - 1);
2088 tty_margin_off(tty);
2095 tty_clear_pane_area(tty, ctx, py, ny, px, nx, ctx->bg);
2101 tty_clear_pane_line(tty, ctx, py, px, nx, ctx->bg);
2105 tty_cmd_clearstartofscreen(struct tty *tty, const struct tty_ctx *ctx)
2109 tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg,
2112 tty_region_pane(tty, ctx, 0, ctx->sy - 1);
2113 tty_margin_off(tty);
2120 tty_clear_pane_area(tty, ctx, py, ny, px, nx, ctx->bg);
2126 tty_clear_pane_line(tty, ctx, py, px, nx, ctx->bg);
2130 tty_cmd_clearscreen(struct tty *tty, const struct tty_ctx *ctx)
2134 tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg,
2137 tty_region_pane(tty, ctx, 0, ctx->sy - 1);
2138 tty_margin_off(tty);
2145 tty_clear_pane_area(tty, ctx, py, ny, px, nx, ctx->bg);
2149 tty_cmd_alignmenttest(struct tty *tty, const struct tty_ctx *ctx)
2158 tty_attributes(tty, &grid_default_cell, &ctx->defaults, ctx->palette,
2161 tty_region_pane(tty, ctx, 0, ctx->sy - 1);
2162 tty_margin_off(tty);
2165 tty_cursor_pane(tty, ctx, 0, j);
2167 tty_putc(tty, 'E');
2172 tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx)
2181 if (!tty_is_visible(tty, ctx, ctx->ocx, ctx->ocy, 1, 1) ||
2182 (gcp->data.width == 1 && !tty_check_overlay(tty, px, py)))
2187 tty_check_overlay_range(tty, px, py, gcp->data.width, &r);
2191 tty_draw_line(tty, s, s->cx, s->cy, gcp->data.width,
2197 if (ctx->xoff + ctx->ocx - ctx->wox > tty->sx - 1 &&
2199 tty_full_width(tty, ctx))
2200 tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
2202 tty_margin_off(tty);
2203 tty_cursor_pane_unless_wrap(tty, ctx, ctx->ocx, ctx->ocy);
2205 tty_cell(tty, ctx->cell, &ctx->defaults, ctx->palette,
2209 tty_invalidate(tty);
2213 tty_cmd_cells(struct tty *tty, const struct tty_ctx *ctx)
2219 if (!tty_is_visible(tty, ctx, ctx->ocx, ctx->ocy, ctx->num, 1))
2226 !tty_full_width(tty, ctx) ||
2227 (tty->term->flags & TERM_NOAM) ||
2229 ctx->yoff + ctx->ocy != tty->cy + 1 ||
2230 tty->cx < tty->sx ||
2231 tty->cy == tty->rlower)
2232 tty_draw_pane(tty, ctx, ctx->ocy);
2238 tty_margin_off(tty);
2239 tty_cursor_pane_unless_wrap(tty, ctx, ctx->ocx, ctx->ocy);
2240 tty_attributes(tty, ctx->cell, &ctx->defaults, ctx->palette, ctx->s->hyperlinks);
2242 /* Get tty position from pane position for overlay check. */
2246 tty_check_overlay_range(tty, px, py, ctx->num, &r);
2252 tty_cursor_pane_unless_wrap(tty, ctx, cx, ctx->ocy);
2253 tty_putn(tty, cp + r.px[i] - px, r.nx[i], r.nx[i]);
2258 tty_cmd_setselection(struct tty *tty, const struct tty_ctx *ctx)
2260 tty_set_selection(tty, ctx->ptr2, ctx->ptr, ctx->num);
2264 tty_set_selection(struct tty *tty, const char *flags, const char *buf,
2270 if (~tty->flags & TTY_STARTED)
2272 if (!tty_term_has(tty->term, TTYC_MS))
2279 tty->flags |= TTY_NOBLOCK;
2280 tty_putcode_ss(tty, TTYC_MS, flags, encoded);
2286 tty_cmd_rawstring(struct tty *tty, const struct tty_ctx *ctx)
2288 tty->flags |= TTY_NOBLOCK;
2289 tty_add(tty, ctx->ptr, ctx->num);
2290 tty_invalidate(tty);
2295 tty_cmd_sixelimage(struct tty *tty, const struct tty_ctx *ctx)
2306 if ((~tty->term->flags & TERM_SIXEL) &&
2307 !tty_term_has(tty->term, TTYC_SXL))
2309 if (tty->xpixel == 0 || tty->ypixel == 0)
2314 if (!tty_clamp_area(tty, ctx, cx, cy, sx, sy, &i, &j, &x, &y, &rx, &ry))
2322 new = sixel_scale(si, tty->xpixel, tty->ypixel, i, j, rx, ry, 0);
2330 tty_region_off(tty);
2331 tty_margin_off(tty);
2332 tty_cursor(tty, x, y);
2334 tty->flags |= TTY_NOBLOCK;
2335 tty_add(tty, data, size);
2336 tty_invalidate(tty);
2346 tty_cmd_syncstart(struct tty *tty, const struct tty_ctx *ctx)
2353 tty_sync_start(tty);
2359 if (ctx->num || tty->client->overlay_draw != NULL)
2360 tty_sync_start(tty);
2365 tty_cell(struct tty *tty, const struct grid_cell *gc,
2372 if ((tty->term->flags & TERM_NOAM) &&
2373 tty->cy == tty->sy - 1 &&
2374 tty->cx == tty->sx - 1)
2382 gcp = tty_check_codeset(tty, gc);
2383 tty_attributes(tty, gcp, defaults, palette, hl);
2387 tty_attributes(tty, gcp, defaults, palette, hl);
2390 tty_putc(tty, *gcp->data.data);
2395 tty_putn(tty, gcp->data.data, gcp->data.size, gcp->data.width);
2399 tty_reset(struct tty *tty)
2401 struct grid_cell *gc = &tty->cell;
2405 tty_putcode_ss(tty, TTYC_HLS, "", "");
2406 if ((gc->attr & GRID_ATTR_CHARSET) && tty_acs_needed(tty))
2407 tty_putcode(tty, TTYC_RMACS);
2408 tty_putcode(tty, TTYC_SGR0);
2411 memcpy(&tty->last_cell, &grid_default_cell, sizeof tty->last_cell);
2415 tty_invalidate(struct tty *tty)
2417 memcpy(&tty->cell, &grid_default_cell, sizeof tty->cell);
2418 memcpy(&tty->last_cell, &grid_default_cell, sizeof tty->last_cell);
2420 tty->cx = tty->cy = UINT_MAX;
2421 tty->rupper = tty->rleft = UINT_MAX;
2422 tty->rlower = tty->rright = UINT_MAX;
2424 if (tty->flags & TTY_STARTED) {
2425 if (tty_use_margin(tty))
2426 tty_putcode(tty, TTYC_ENMG);
2427 tty_putcode(tty, TTYC_SGR0);
2429 tty->mode = ALL_MODES;
2430 tty_update_mode(tty, MODE_CURSOR, NULL);
2432 tty_cursor(tty, 0, 0);
2433 tty_region_off(tty);
2434 tty_margin_off(tty);
2436 tty->mode = MODE_CURSOR;
2441 tty_region_off(struct tty *tty)
2443 tty_region(tty, 0, tty->sy - 1);
2448 tty_region_pane(struct tty *tty, const struct tty_ctx *ctx, u_int rupper,
2451 tty_region(tty, ctx->yoff + rupper - ctx->woy,
2457 tty_region(struct tty *tty, u_int rupper, u_int rlower)
2459 if (tty->rlower == rlower && tty->rupper == rupper)
2461 if (!tty_term_has(tty->term, TTYC_CSR))
2464 tty->rupper = rupper;
2465 tty->rlower = rlower;
2473 if (tty->cx >= tty->sx) {
2474 if (tty->cy == UINT_MAX)
2475 tty_cursor(tty, 0, 0);
2477 tty_cursor(tty, 0, tty->cy);
2480 tty_putcode_ii(tty, TTYC_CSR, tty->rupper, tty->rlower);
2481 tty->cx = tty->cy = UINT_MAX;
2486 tty_margin_off(struct tty *tty)
2488 tty_margin(tty, 0, tty->sx - 1);
2493 tty_margin_pane(struct tty *tty, const struct tty_ctx *ctx)
2495 tty_margin(tty, ctx->xoff - ctx->wox,
2501 tty_margin(struct tty *tty, u_int rleft, u_int rright)
2503 if (!tty_use_margin(tty))
2505 if (tty->rleft == rleft && tty->rright == rright)
2508 tty_putcode_ii(tty, TTYC_CSR, tty->rupper, tty->rlower);
2510 tty->rleft = rleft;
2511 tty->rright = rright;
2513 if (rleft == 0 && rright == tty->sx - 1)
2514 tty_putcode(tty, TTYC_CLMG);
2516 tty_putcode_ii(tty, TTYC_CMG, rleft, rright);
2517 tty->cx = tty->cy = UINT_MAX;
2525 tty_cursor_pane_unless_wrap(struct tty *tty, const struct tty_ctx *ctx,
2529 !tty_full_width(tty, ctx) ||
2530 (tty->term->flags & TERM_NOAM) ||
2532 ctx->yoff + cy != tty->cy + 1 ||
2533 tty->cx < tty->sx ||
2534 tty->cy == tty->rlower)
2535 tty_cursor_pane(tty, ctx, cx, cy);
2537 log_debug("%s: will wrap at %u,%u", __func__, tty->cx, tty->cy);
2542 tty_cursor_pane(struct tty *tty, const struct tty_ctx *ctx, u_int cx, u_int cy)
2544 tty_cursor(tty, ctx->xoff + cx - ctx->wox, ctx->yoff + cy - ctx->woy);
2549 tty_cursor(struct tty *tty, u_int cx, u_int cy)
2551 struct tty_term *term = tty->term;
2555 if (tty->flags & TTY_BLOCK)
2558 thisx = tty->cx;
2559 thisy = tty->cy;
2565 if (cx == thisx && cy == thisy && cx == tty->sx)
2567 if (cx > tty->sx - 1) {
2568 log_debug("%s: x too big %u > %u", __func__, cx, tty->sx - 1);
2569 cx = tty->sx - 1;
2577 if (thisx > tty->sx - 1)
2582 tty_putcode(tty, TTYC_HOME);
2587 if (cx == 0 && cy == thisy + 1 && thisy != tty->rlower &&
2588 (!tty_use_margin(tty) || tty->rleft == 0)) {
2589 tty_putc(tty, '\r');
2590 tty_putc(tty, '\n');
2601 if (cx == 0 && (!tty_use_margin(tty) || tty->rleft == 0)) {
2602 tty_putc(tty, '\r');
2608 tty_putcode(tty, TTYC_CUB1);
2614 tty_putcode(tty, TTYC_CUF1);
2626 tty_putcode_i(tty, TTYC_HPA, cx);
2630 !tty_use_margin(tty)) {
2632 tty_putcode(tty, TTYC_CUB1);
2633 tty_putcode(tty, TTYC_CUB1);
2636 tty_putcode_i(tty, TTYC_CUB, change);
2640 !tty_use_margin(tty)) {
2641 tty_putcode_i(tty, TTYC_CUF, -change);
2650 if (thisy != tty->rupper &&
2652 tty_putcode(tty, TTYC_CUU1);
2657 if (thisy != tty->rlower &&
2659 tty_putcode(tty, TTYC_CUD1);
2671 (change < 0 && cy - change > tty->rlower) ||
2672 (change > 0 && cy - change < tty->rupper)) {
2674 tty_putcode_i(tty, TTYC_VPA, cy);
2678 tty_putcode_i(tty, TTYC_CUU, change);
2681 tty_putcode_i(tty, TTYC_CUD, -change);
2688 tty_putcode_ii(tty, TTYC_CUP, cy, cx);
2691 tty->cx = cx;
2692 tty->cy = cy;
2696 tty_hyperlink(struct tty *tty, const struct grid_cell *gc,
2701 if (gc->link == tty->cell.link)
2703 tty->cell.link = gc->link;
2709 tty_putcode_ss(tty, TTYC_HLS, "", "");
2711 tty_putcode_ss(tty, TTYC_HLS, id, uri);
2715 tty_attributes(struct tty *tty, const struct grid_cell *gc,
2719 struct grid_cell *tc = &tty->cell, gc2;
2732 if (gc2.attr == tty->last_cell.attr &&
2733 gc2.fg == tty->last_cell.fg &&
2734 gc2.bg == tty->last_cell.bg &&
2735 gc2.us == tty->last_cell.us &&
2736 gc2.link == tty->last_cell.link)
2744 if (!tty_term_has(tty->term, TTYC_SETAB)) {
2755 tty_check_fg(tty, palette, &gc2);
2756 tty_check_bg(tty, palette, &gc2);
2757 tty_check_us(tty, palette, &gc2);
2764 tty_reset(tty);
2770 tty_colours(tty, &gc2);
2778 tty_putcode(tty, TTYC_BOLD);
2780 tty_putcode(tty, TTYC_DIM);
2782 tty_set_italics(tty);
2785 tty_putcode(tty, TTYC_SMUL);
2787 tty_putcode_i(tty, TTYC_SMULX, 2);
2789 tty_putcode_i(tty, TTYC_SMULX, 3);
2791 tty_putcode_i(tty, TTYC_SMULX, 4);
2793 tty_putcode_i(tty, TTYC_SMULX, 5);
2796 tty_putcode(tty, TTYC_BLINK);
2798 if (tty_term_has(tty->term, TTYC_REV))
2799 tty_putcode(tty, TTYC_REV);
2800 else if (tty_term_has(tty->term, TTYC_SMSO))
2801 tty_putcode(tty, TTYC_SMSO);
2804 tty_putcode(tty, TTYC_INVIS);
2806 tty_putcode(tty, TTYC_SMXX);
2808 tty_putcode(tty, TTYC_SMOL);
2809 if ((changed & GRID_ATTR_CHARSET) && tty_acs_needed(tty))
2810 tty_putcode(tty, TTYC_SMACS);
2813 tty_hyperlink(tty, gc, hl);
2815 memcpy(&tty->last_cell, &gc2, sizeof tty->last_cell);
2819 tty_colours(struct tty *tty, const struct grid_cell *gc)
2821 struct grid_cell *tc = &tty->cell;
2838 if (!tty_term_flag(tty->term, TTYC_AX))
2839 tty_reset(tty);
2842 tty_puts(tty, "\033[39m");
2846 tty_puts(tty, "\033[49m");
2854 tty_colours_fg(tty, gc);
2861 tty_colours_bg(tty, gc);
2865 tty_colours_us(tty, gc);
2869 tty_check_fg(struct tty *tty, struct colour_palette *palette,
2885 !tty_term_has(tty->term, TTYC_NOBR))
2894 if (tty->term->flags & TERM_RGBCOLOURS)
2901 if (tty->term->flags & TERM_256COLOURS)
2904 colours = tty_term_number(tty->term, TTYC_COLORS);
2938 tty_check_bg(struct tty *tty, struct colour_palette *palette,
2954 if (tty->term->flags & TERM_RGBCOLOURS)
2961 if (tty->term->flags & TERM_256COLOURS)
2964 colours = tty_term_number(tty->term, TTYC_COLORS);
2990 tty_check_us(__unused struct tty *tty, struct colour_palette *palette,
3002 if (!tty_term_has(tty->term, TTYC_SETULC1)) {
3011 tty_colours_fg(struct tty *tty, const struct grid_cell *gc)
3013 struct grid_cell *tc = &tty->cell;
3020 if (tty->cell.fg >= 90 &&
3021 tty->cell.bg <= 97 &&
3023 tty_reset(tty);
3027 if (tty_try_colour(tty, gc->fg, "38") == 0)
3035 if (tty->term->flags & TERM_256COLOURS) {
3037 tty_puts(tty, s);
3039 tty_putcode_i(tty, TTYC_SETAF, gc->fg - 90 + 8);
3044 tty_putcode_i(tty, TTYC_SETAF, gc->fg);
3052 tty_colours_bg(struct tty *tty, const struct grid_cell *gc)
3054 struct grid_cell *tc = &tty->cell;
3059 if (tty_try_colour(tty, gc->bg, "48") == 0)
3067 if (tty->term->flags & TERM_256COLOURS) {
3069 tty_puts(tty, s);
3071 tty_putcode_i(tty, TTYC_SETAB, gc->bg - 90 + 8);
3076 tty_putcode_i(tty, TTYC_SETAB, gc->bg);
3084 tty_colours_us(struct tty *tty, const struct grid_cell *gc)
3086 struct grid_cell *tc = &tty->cell;
3092 tty_putcode(tty, TTYC_OL);
3104 tty_putcode_i(tty, TTYC_SETULC1, c & ~COLOUR_FLAG_256);
3119 if (tty_term_has(tty->term, TTYC_SETULC))
3120 tty_putcode_i(tty, TTYC_SETULC, c);
3121 else if (tty_term_has(tty->term, TTYC_SETAL) &&
3122 tty_term_has(tty->term, TTYC_RGB))
3123 tty_putcode_i(tty, TTYC_SETAL, c);
3131 tty_try_colour(struct tty *tty, int colour, const char *type)
3136 if (*type == '3' && tty_term_has(tty->term, TTYC_SETAF))
3137 tty_putcode_i(tty, TTYC_SETAF, colour & 0xff);
3138 else if (tty_term_has(tty->term, TTYC_SETAB))
3139 tty_putcode_i(tty, TTYC_SETAB, colour & 0xff);
3145 if (*type == '3' && tty_term_has(tty->term, TTYC_SETRGBF))
3146 tty_putcode_iii(tty, TTYC_SETRGBF, r, g, b);
3147 else if (tty_term_has(tty->term, TTYC_SETRGBB))
3148 tty_putcode_iii(tty, TTYC_SETRGBB, r, g, b);
3201 tty_default_attributes(struct tty *tty, const struct grid_cell *defaults,
3208 tty_attributes(tty, &gc, defaults, palette, hl);
3214 struct tty *tty = data;
3215 struct client *c = tty->client;
3222 tty->flags &= ~TTY_OSC52QUERY;
3226 tty_clipboard_query(struct tty *tty)
3230 if ((~tty->flags & TTY_STARTED) || (tty->flags & TTY_OSC52QUERY))
3232 tty_putcode_ss(tty, TTYC_MS, "", "?");
3234 tty->flags |= TTY_OSC52QUERY;
3235 evtimer_add(&tty->clipboard_timer, &tv);