void window_copy_scroll_up(struct window_pane *wp, u_int ny) { struct window_copy_mode_data *data = wp->modedata; struct screen *s = &data->screen; struct screen_write_ctx ctx; if (data->oy < ny) ny = data->oy; if (ny == 0) return; data->oy -= ny; screen_write_start(&ctx, wp, NULL); screen_write_cursormove(&ctx, 0, 0); screen_write_deleteline(&ctx, ny); window_copy_write_lines(wp, &ctx, screen_size_y(s) - ny, ny); window_copy_write_line(wp, &ctx, 0); if (screen_size_y(s) > 1) window_copy_write_line(wp, &ctx, 1); if (screen_size_y(s) > 3) window_copy_write_line(wp, &ctx, screen_size_y(s) - 2); if (s->sel.flag && screen_size_y(s) > ny) { window_copy_update_selection(wp); window_copy_write_line(wp, &ctx, screen_size_y(s) - ny - 1); } screen_write_cursormove(&ctx, data->cx, data->cy); window_copy_update_selection(wp); screen_write_stop(&ctx); }
void input_parse(struct window_pane *wp) { struct input_ctx *ictx = &wp->ictx; u_char ch; if (BUFFER_USED(wp->in) == 0) return; ictx->buf = BUFFER_OUT(wp->in); ictx->len = BUFFER_USED(wp->in); ictx->off = 0; ictx->wp = wp; log_debug2("entry; buffer=%zu", ictx->len); if (wp->mode == NULL) screen_write_start(&ictx->ctx, wp, &wp->base); else screen_write_start(&ictx->ctx, NULL, &wp->base); if (ictx->off != ictx->len) wp->window->flags |= WINDOW_ACTIVITY; while (ictx->off < ictx->len) { ch = ictx->buf[ictx->off++]; ictx->state(ch, ictx); } screen_write_stop(&ictx->ctx); buffer_remove(wp->in, ictx->len); }
void window_copy_scroll_down(struct window_pane *wp, u_int ny) { struct window_copy_mode_data *data = wp->modedata; struct screen *s = &data->screen; struct screen_write_ctx ctx; if (ny > screen_hsize(&wp->base)) return; if (data->oy > screen_hsize(&wp->base) - ny) ny = screen_hsize(&wp->base) - data->oy; if (ny == 0) return; data->oy += ny; screen_write_start(&ctx, wp, NULL); screen_write_cursormove(&ctx, 0, 0); screen_write_insertline(&ctx, ny); window_copy_write_lines(wp, &ctx, 0, ny); if (s->sel.flag && screen_size_y(s) > ny) { window_copy_update_selection(wp); window_copy_write_line(wp, &ctx, ny); } else if (ny == 1) /* nuke position */ window_copy_write_line(wp, &ctx, 1); screen_write_cursormove(&ctx, data->cx, data->cy); window_copy_update_selection(wp); screen_write_stop(&ctx); }
void window_copy_resize(struct window_pane *wp, u_int sx, u_int sy) { struct window_copy_mode_data *data = wp->modedata; struct screen *s = &data->screen; struct screen_write_ctx ctx; screen_resize(s, sx, sy); if (data->backing != &wp->base) screen_resize(data->backing, sx, sy); if (data->cy > sy - 1) data->cy = sy - 1; if (data->cx > sx) data->cx = sx; if (data->oy > screen_hsize(data->backing)) data->oy = screen_hsize(data->backing); window_copy_clear_selection(wp); screen_write_start(&ctx, NULL, s); window_copy_write_lines(wp, &ctx, 0, screen_size_y(s) - 1); screen_write_stop(&ctx); window_copy_redraw_screen(wp); }
void window_copy_vadd(struct window_pane *wp, const char *fmt, va_list ap) { struct window_copy_mode_data *data = wp->modedata; struct screen *backing = data->backing; struct screen_write_ctx back_ctx, ctx; struct grid_cell gc; int utf8flag; u_int old_hsize; if (backing == &wp->base) return; utf8flag = options_get_number(&wp->window->options, "utf8"); memcpy(&gc, &grid_default_cell, sizeof gc); old_hsize = screen_hsize(data->backing); screen_write_start(&back_ctx, NULL, backing); if (data->backing_written) { /* * On the second or later line, do a CRLF before writing * (so it's on a new line). */ screen_write_carriagereturn(&back_ctx); screen_write_linefeed(&back_ctx, 0); } else data->backing_written = 1; screen_write_vnputs(&back_ctx, 0, &gc, utf8flag, fmt, ap); screen_write_stop(&back_ctx); data->oy += screen_hsize(data->backing) - old_hsize; screen_write_start(&ctx, wp, &data->screen); /* * If the history has changed, draw the top line. * (If there's any history at all, it has changed.) */ if (screen_hsize(data->backing)) window_copy_redraw_lines(wp, 0, 1); /* Write the line, if it's visible. */ if (backing->cy + data->oy < screen_size_y(backing)) window_copy_redraw_lines(wp, backing->cy, 1); screen_write_stop(&ctx); }
void window_copy_search_down(struct window_pane *wp, const char *searchstr) { struct window_copy_mode_data *data = wp->modedata; struct screen *s = &wp->base, ss; struct screen_write_ctx ctx; struct grid *gd = s->grid, *sgd; struct grid_cell gc; size_t searchlen; u_int i, first, fx, fy, px; int utf8flag, n, wrapped; if (*searchstr == '\0') return; utf8flag = options_get_number(&wp->window->options, "utf8"); searchlen = screen_write_strlen(utf8flag, "%s", searchstr); screen_init(&ss, searchlen, 1, 0); screen_write_start(&ctx, NULL, &ss); memcpy(&gc, &grid_default_cell, sizeof gc); screen_write_nputs(&ctx, -1, &gc, utf8flag, "%s", searchstr); screen_write_stop(&ctx); fx = data->cx; fy = gd->hsize - data->oy + data->cy; if (fx == gd->sx - 1) { if (fy == gd->hsize + gd->sy) return; fx = 0; fy++; } else fx++; n = wrapped = 0; retry: sgd = ss.grid; for (i = fy + 1; i < gd->hsize + gd->sy; i++) { first = 0; if (i == fy + 1) first = fx; n = window_copy_search_lr(gd, sgd, &px, i - 1, first, gd->sx); if (n) { window_copy_scroll_to(wp, px, i - 1); break; } } if (!n && !wrapped) { fx = 0; fy = 0; wrapped = 1; goto retry; } screen_free(&ss); }
enum cmd_retval cmd_send_keys_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct window_pane *wp; struct session *s; struct input_ctx *ictx; const u_char *str; int i, key; if (cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp) == NULL) return (CMD_RETURN_ERROR); if (self->entry == &cmd_send_prefix_entry) { if (args_has(args, '2')) key = options_get_number(&s->options, "prefix2"); else key = options_get_number(&s->options, "prefix"); window_pane_key(wp, s, key); return (CMD_RETURN_NORMAL); } if (args_has(args, 'R')) { ictx = &wp->ictx; memcpy(&ictx->cell, &grid_default_cell, sizeof ictx->cell); memcpy(&ictx->old_cell, &ictx->cell, sizeof ictx->old_cell); ictx->old_cx = 0; ictx->old_cy = 0; if (wp->mode == NULL) screen_write_start(&ictx->ctx, wp, &wp->base); else screen_write_start(&ictx->ctx, NULL, &wp->base); screen_write_reset(&ictx->ctx); screen_write_stop(&ictx->ctx); } for (i = 0; i < args->argc; i++) { str = args->argv[i]; if (!args_has(args, 'l') && (key = key_string_lookup_string(str)) != KEYC_NONE) { window_pane_key(wp, s, key); } else { for (; *str != '\0'; str++) window_pane_key(wp, s, *str); } } return (CMD_RETURN_NORMAL); }
struct screen * window_copy_init(struct window_pane *wp) { struct window_copy_mode_data *data; struct screen *s; struct screen_write_ctx ctx; u_int i; int keys; wp->modedata = data = xmalloc(sizeof *data); data->oy = 0; data->cx = wp->base.cx; data->cy = wp->base.cy; data->lastcx = 0; data->lastsx = 0; data->rectflag = 0; data->inputtype = WINDOW_COPY_OFF; data->inputprompt = NULL; data->inputstr = xstrdup(""); data->numprefix = 0; data->searchtype = WINDOW_COPY_OFF; data->searchstr = NULL; wp->flags |= PANE_FREEZE; bufferevent_disable(wp->event, EV_READ|EV_WRITE); s = &data->screen; screen_init(s, screen_size_x(&wp->base), screen_size_y(&wp->base), 0); if (options_get_number(&wp->window->options, "mode-mouse")) s->mode |= MODE_MOUSE; keys = options_get_number(&wp->window->options, "mode-keys"); if (keys == MODEKEY_EMACS) mode_key_init(&data->mdata, &mode_key_tree_emacs_copy); else mode_key_init(&data->mdata, &mode_key_tree_vi_copy); s->cx = data->cx; s->cy = data->cy; screen_write_start(&ctx, NULL, s); for (i = 0; i < screen_size_y(s); i++) window_copy_write_line(wp, &ctx, i); screen_write_cursormove(&ctx, data->cx, data->cy); screen_write_stop(&ctx); return (s); }
void window_copy_redraw_lines(struct window_pane *wp, u_int py, u_int ny) { struct window_copy_mode_data *data = wp->modedata; struct screen_write_ctx ctx; u_int i; screen_write_start(&ctx, wp, NULL); for (i = py; i < py + ny; i++) window_copy_write_line(wp, &ctx, i); screen_write_cursormove(&ctx, data->cx, data->cy); screen_write_stop(&ctx); }
void window_more_redraw_screen(struct window_pane *wp) { struct window_more_mode_data *data = wp->modedata; struct screen *s = &data->screen; struct screen_write_ctx ctx; u_int i; screen_write_start(&ctx, wp, NULL); for (i = 0; i < screen_size_y(s); i++) window_more_write_line(wp, &ctx, i); screen_write_stop(&ctx); }
void window_clock_draw_screen(struct window_pane *wp) { struct window_clock_mode_data *data = wp->modedata; struct screen_write_ctx ctx; int colour, style; colour = options_get_number(&wp->window->options, "clock-mode-colour"); style = options_get_number(&wp->window->options, "clock-mode-style"); screen_write_start(&ctx, NULL, &data->screen); clock_draw(&ctx, colour, style); screen_write_stop(&ctx); }
/* Reset input state and clear screen. */ void input_reset(struct window_pane *wp) { struct input_ctx *ictx = wp->ictx; input_reset_cell(ictx); if (wp->mode == NULL) screen_write_start(&ictx->ctx, wp, &wp->base); else screen_write_start(&ictx->ctx, NULL, &wp->base); screen_write_reset(&ictx->ctx); screen_write_stop(&ictx->ctx); }
void window_more_scroll_up(struct window_pane *wp) { struct window_more_mode_data *data = wp->modedata; struct screen_write_ctx ctx; if (data->top == 0) return; data->top--; screen_write_start(&ctx, wp, NULL); screen_write_cursormove(&ctx, 0, 0); screen_write_insertline(&ctx, 1); window_more_write_line(wp, &ctx, 0); window_more_write_line(wp, &ctx, 1); screen_write_stop(&ctx); }
void window_more_scroll_down(struct window_pane *wp) { struct window_more_mode_data *data = wp->modedata; struct screen *s = &data->screen; struct screen_write_ctx ctx; if (data->top >= ARRAY_LENGTH(&data->list)) return; data->top++; screen_write_start(&ctx, wp, NULL); screen_write_cursormove(&ctx, 0, 0); screen_write_deleteline(&ctx, 1); window_more_write_line(wp, &ctx, screen_size_y(s) - 1); window_more_write_line(wp, &ctx, 0); screen_write_stop(&ctx); }
void window_copy_update_cursor(struct window_pane *wp, u_int cx, u_int cy) { struct window_copy_mode_data *data = wp->modedata; struct screen *s = &data->screen; struct screen_write_ctx ctx; u_int old_cx, old_cy; old_cx = data->cx; old_cy = data->cy; data->cx = cx; data->cy = cy; if (old_cx == screen_size_x(s)) window_copy_redraw_lines(wp, old_cy, 1); if (data->cx == screen_size_x(s)) window_copy_redraw_lines(wp, data->cy, 1); else { screen_write_start(&ctx, wp, NULL); screen_write_cursormove(&ctx, data->cx, data->cy); screen_write_stop(&ctx); } }
void window_more_vadd(struct window_pane *wp, const char *fmt, va_list ap) { struct window_more_mode_data *data = wp->modedata; struct screen *s = &data->screen; struct screen_write_ctx ctx; char *msg; u_int size; xvasprintf(&msg, fmt, ap); ARRAY_ADD(&data->list, msg); screen_write_start(&ctx, wp, NULL); size = ARRAY_LENGTH(&data->list) - 1; if (size >= data->top && size <= data->top + screen_size_y(s) - 1) { window_more_write_line(wp, &ctx, size - data->top); if (size != data->top) window_more_write_line(wp, &ctx, 0); } else window_more_write_line(wp, &ctx, 0); screen_write_stop(&ctx); }
void window_copy_init_from_pane(struct window_pane *wp) { struct window_copy_mode_data *data = wp->modedata; struct screen *s = &data->screen; struct screen_write_ctx ctx; u_int i; if (wp->mode != &window_copy_mode) fatalx("not in copy mode"); data->backing = &wp->base; data->cx = data->backing->cx; data->cy = data->backing->cy; s->cx = data->cx; s->cy = data->cy; screen_write_start(&ctx, NULL, s); for (i = 0; i < screen_size_y(s); i++) window_copy_write_line(wp, &ctx, i); screen_write_cursormove(&ctx, data->cx, data->cy); screen_write_stop(&ctx); }
/* Parse input. */ void input_parse(struct window_pane *wp) { struct input_ctx *ictx = &wp->ictx; const struct input_transition *itr; struct evbuffer *evb = wp->event->input; u_char *buf; size_t len, off; if (EVBUFFER_LENGTH(evb) == 0) return; wp->window->flags |= WINDOW_ACTIVITY; wp->window->flags &= ~WINDOW_SILENCE; /* * Open the screen. Use NULL wp if there is a mode set as don't want to * update the tty. */ if (wp->mode == NULL) screen_write_start(&ictx->ctx, wp, &wp->base); else screen_write_start(&ictx->ctx, NULL, &wp->base); ictx->wp = wp; buf = EVBUFFER_DATA(evb); len = EVBUFFER_LENGTH(evb); notify_input(wp, evb); off = 0; /* Parse the input. */ while (off < len) { ictx->ch = buf[off++]; log_debug("%s: '%c' %s", __func__, ictx->ch, ictx->state->name); /* Find the transition. */ itr = ictx->state->transitions; while (itr->first != -1 && itr->last != -1) { if (ictx->ch >= itr->first && ictx->ch <= itr->last) break; itr++; } if (itr->first == -1 || itr->last == -1) { /* No transition? Eh? */ fatalx("No transition from state!"); } /* * Execute the handler, if any. Don't switch state if it * returns non-zero. */ if (itr->handler != NULL && itr->handler(ictx) != 0) continue; /* And switch state, if necessary. */ if (itr->state != NULL) input_set_state(wp, itr); /* If not in ground state, save input. */ if (ictx->state != &input_state_ground) evbuffer_add(ictx->since_ground, &ictx->ch, 1); } /* Close the screen. */ screen_write_stop(&ictx->ctx); evbuffer_drain(evb, len); }
void window_clock_draw_screen(struct window_pane *wp) { struct window_clock_mode_data *data = wp->modedata; struct screen_write_ctx ctx; int colour, style; struct screen *s = &data->screen; struct grid_cell gc; char tim[64], *ptr; time_t t; struct tm *tm; u_int i, j, x, y, idx; colour = options_get_number(&wp->window->options, "clock-mode-colour"); style = options_get_number(&wp->window->options, "clock-mode-style"); screen_write_start(&ctx, NULL, s); t = time(NULL); tm = localtime(&t); if (style == 0) { strftime(tim, sizeof tim, "%l:%M ", localtime(&t)); if (tm->tm_hour >= 12) strlcat(tim, "PM", sizeof tim); else strlcat(tim, "AM", sizeof tim); } else strftime(tim, sizeof tim, "%H:%M", tm); screen_write_clearscreen(&ctx); if (screen_size_x(s) < 6 * strlen(tim) || screen_size_y(s) < 6) { if (screen_size_x(s) >= strlen(tim) && screen_size_y(s) != 0) { x = (screen_size_x(s) / 2) - (strlen(tim) / 2); y = screen_size_y(s) / 2; screen_write_cursormove(&ctx, x, y); memcpy(&gc, &grid_default_cell, sizeof gc); colour_set_fg(&gc, colour); screen_write_puts(&ctx, &gc, "%s", tim); } screen_write_stop(&ctx); return; } x = (screen_size_x(s) / 2) - 3 * strlen(tim); y = (screen_size_y(s) / 2) - 3; memcpy(&gc, &grid_default_cell, sizeof gc); colour_set_bg(&gc, colour); for (ptr = tim; *ptr != '\0'; ptr++) { if (*ptr >= '0' && *ptr <= '9') idx = *ptr - '0'; else if (*ptr == ':') idx = 10; else if (*ptr == 'A') idx = 11; else if (*ptr == 'P') idx = 12; else if (*ptr == 'M') idx = 13; else { x += 6; continue; } for (j = 0; j < 5; j++) { for (i = 0; i < 5; i++) { screen_write_cursormove(&ctx, x + i, y + j); if (window_clock_table[idx][j][i]) screen_write_putc(&ctx, &gc, ' '); } } x += 6; } screen_write_stop(&ctx); }