/* Update status cache. */ void status_update_saved(struct session *s) { if (!options_get_number(s->options, "status")) s->statusat = -1; else if (options_get_number(s->options, "status-position") == 0) s->statusat = 0; else s->statusat = 1; }
/* Translate mouse and output. */ void input_mouse(struct window_pane *wp, struct session *s, struct mouse_event *m) { char buf[40]; size_t len; struct paste_buffer *pb; if (wp->screen->mode & ALL_MOUSE_MODES) { /* * Use the SGR (1006) extension only if the application * requested it and the underlying terminal also sent the event * in this format (this is because an old style mouse release * event cannot be converted into the new SGR format, since the * released button is unknown). Otherwise pretend that tmux * doesn't speak this extension, and fall back to the UTF-8 * (1005) extension if the application requested, or to the * legacy format. */ if (m->sgr && (wp->screen->mode & MODE_MOUSE_SGR)) { len = xsnprintf(buf, sizeof buf, "\033[<%d;%d;%d%c", m->sgr_xb, m->x + 1, m->y + 1, m->sgr_rel ? 'm' : 'M'); } else if (wp->screen->mode & MODE_MOUSE_UTF8) { len = xsnprintf(buf, sizeof buf, "\033[M"); len += utf8_split2(m->xb + 32, &buf[len]); len += utf8_split2(m->x + 33, &buf[len]); len += utf8_split2(m->y + 33, &buf[len]); } else { if (m->xb > 223 || m->x >= 222 || m->y > 222) return; len = xsnprintf(buf, sizeof buf, "\033[M"); buf[len++] = m->xb + 32; buf[len++] = m->x + 33; buf[len++] = m->y + 33; } bufferevent_write(wp->event, buf, len); return; } if (m->button == 1 && (m->event & MOUSE_EVENT_CLICK) && options_get_number(&wp->window->options, "mode-mouse") == 1) { pb = paste_get_top(&global_buffers); if (pb != NULL) { paste_send_pane(pb, wp, "\r", wp->screen->mode & MODE_BRACKETPASTE); } } else if ((m->xb & 3) != 1 && options_get_number(&wp->window->options, "mode-mouse") == 1) { if (window_pane_set_mode(wp, &window_copy_mode) == 0) { window_copy_init_from_pane(wp); if (wp->mode->mouse != NULL) wp->mode->mouse(wp, s, m); } } }
int window_copy_update_selection(struct window_pane *wp) { struct window_copy_mode_data *data = wp->modedata; struct screen *s = &data->screen; struct options *oo = &wp->window->options; struct grid_cell gc; u_int sx, sy, ty, cy; if (!s->sel.flag) return (0); /* Set colours. */ memcpy(&gc, &grid_default_cell, sizeof gc); colour_set_fg(&gc, options_get_number(oo, "mode-fg")); colour_set_bg(&gc, options_get_number(oo, "mode-bg")); gc.attr |= options_get_number(oo, "mode-attr"); /* Find top of screen. */ ty = screen_hsize(&wp->base) - data->oy; /* Adjust the selection. */ sx = data->selx; sy = data->sely; if (sy < ty) { /* above screen */ if (!data->rectflag) sx = 0; sy = 0; } else if (sy > ty + screen_size_y(s) - 1) { /* below screen */ if (!data->rectflag) sx = screen_size_x(s) - 1; sy = screen_size_y(s) - 1; } else sy -= ty; sy = screen_hsize(s) + sy; screen_set_selection(s, sx, sy, data->cx, screen_hsize(s) + data->cy, data->rectflag, &gc); if (data->rectflag) { /* * Can't rely on the caller to redraw the right lines for * rectangle selection - find the highest line and the number * of lines, and redraw just past that in both directions */ cy = data->cy; if (sy < cy) window_copy_redraw_lines(wp, sy, cy - sy + 1); else window_copy_redraw_lines(wp, cy, sy - cy + 1); } return (1); }
/* Get screen line of status line. -1 means off. */ int status_at_line(struct client *c) { struct session *s = c->session; if (!options_get_number(&s->options, "status")) return (-1); if (options_get_number(&s->options, "status-position") == 0) return (0); return (c->tty.sy - 1); }
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); }
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); }
/* Is there any status (main or aux) at line zero? (1 True, 0 False) */ int any_status_at_zero(struct client *c) { struct session *s = c->session; if (options_get_number(s->options, "status") && (options_get_number(s->options, "status-position")==0)) return 1; if (options_get_number(s->options, "aux-status") && (options_get_number(s->options, "aux-status-position")==0)) return 1; return 0; }
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); }
struct screen * window_copy_init(struct window_pane *wp) { struct window_copy_mode_data *data; struct screen *s; int keys; wp->modedata = data = xmalloc(sizeof *data); data->oy = 0; data->cx = 0; data->cy = 0; data->lastcx = 0; data->lastsx = 0; data->backing_written = 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; if (wp->fd != -1) bufferevent_disable(wp->event, EV_READ|EV_WRITE); data->jumptype = WINDOW_COPY_OFF; data->jumpchar = '\0'; 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_STANDARD; 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); data->backing = NULL; return (s); }
enum cmd_retval cmd_send_keys_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct mouse_event *m = &cmdq->item->mouse; struct window_pane *wp; struct session *s; const char *str; int i, key; if (args_has(args, 'M')) { wp = cmd_mouse_pane(m, &s, NULL); if (wp == NULL) { cmdq_error(cmdq, "no mouse target"); return (CMD_RETURN_ERROR); } window_pane_key(wp, NULL, s, m->key, m); return (CMD_RETURN_NORMAL); } 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, NULL, s, key, NULL); return (CMD_RETURN_NORMAL); } if (args_has(args, 'R')) input_reset(wp); 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, NULL, s, key, NULL); } else { for (; *str != '\0'; str++) window_pane_key(wp, NULL, s, *str, NULL); } } return (CMD_RETURN_NORMAL); }
void window_copy_write_line( struct window_pane *wp, struct screen_write_ctx *ctx, u_int py) { struct window_copy_mode_data *data = wp->modedata; struct screen *s = &data->screen; struct options *oo = &wp->window->options; struct grid_cell gc; char hdr[32]; size_t last, xoff = 0, size = 0; memcpy(&gc, &grid_default_cell, sizeof gc); colour_set_fg(&gc, options_get_number(oo, "mode-fg")); colour_set_bg(&gc, options_get_number(oo, "mode-bg")); gc.attr |= options_get_number(oo, "mode-attr"); last = screen_size_y(s) - 1; if (py == 0) { size = xsnprintf(hdr, sizeof hdr, "[%u/%u]", data->oy, screen_hsize(data->backing)); if (size > screen_size_x(s)) size = screen_size_x(s); screen_write_cursormove(ctx, screen_size_x(s) - size, 0); screen_write_puts(ctx, &gc, "%s", hdr); } else if (py == last && data->inputtype != WINDOW_COPY_OFF) { if (data->inputtype == WINDOW_COPY_NUMERICPREFIX) { xoff = size = xsnprintf(hdr, sizeof hdr, "Repeat: %u", data->numprefix); } else { xoff = size = xsnprintf(hdr, sizeof hdr, "%s: %s", data->inputprompt, data->inputstr); } screen_write_cursormove(ctx, 0, last); screen_write_puts(ctx, &gc, "%s", hdr); } else size = 0; screen_write_cursormove(ctx, xoff, py); screen_write_copy(ctx, data->backing, xoff, (screen_hsize(data->backing) - data->oy) + py, screen_size_x(s) - size, 1); if (py == data->cy && data->cx == screen_size_x(s)) { memcpy(&gc, &grid_default_cell, sizeof gc); screen_write_cursormove(ctx, screen_size_x(s) - 1, py); screen_write_putc(ctx, &gc, '$'); } }
void cmd_set_option_flag(struct cmd_ctx *ctx, struct options *oo, const struct set_option_entry *entry, char *value) { struct options_entry *o; int flag; if (value == NULL || *value == '\0') flag = !options_get_number(oo, entry->name); else { if ((value[0] == '1' && value[1] == '\0') || strcasecmp(value, "on") == 0 || strcasecmp(value, "yes") == 0) flag = 1; else if ((value[0] == '0' && value[1] == '\0') || strcasecmp(value, "off") == 0 || strcasecmp(value, "no") == 0) flag = 0; else { ctx->error(ctx, "bad value: %s", value); return; } } o = options_set_number(oo, entry->name, flag); ctx->info(ctx, "set option: %s -> %s", o->name, cmd_set_option_print(entry, o)); }
/* Translate mouse and output. */ void input_mouse(struct window_pane *wp, struct mouse_event *m) { char buf[10]; size_t len; if (wp->screen->mode & ALL_MOUSE_MODES) { if (wp->screen->mode & MODE_MOUSE_UTF8) { len = xsnprintf(buf, sizeof buf, "\033[M"); len += utf8_split2(m->b + 32, &buf[len]); len += utf8_split2(m->x + 33, &buf[len]); len += utf8_split2(m->y + 33, &buf[len]); } else { if (m->b > 223 || m->x >= 222 || m->y > 222) return; len = xsnprintf(buf, sizeof buf, "\033[M"); buf[len++] = m->b + 32; buf[len++] = m->x + 33; buf[len++] = m->y + 33; } bufferevent_write(wp->event, buf, len); } else if ((m->b & MOUSE_BUTTON) != MOUSE_2) { if (options_get_number(&wp->window->options, "mode-mouse") && window_pane_set_mode(wp, &window_copy_mode) == 0) { window_copy_init_from_pane(wp); if (wp->mode->mouse != NULL) wp->mode->mouse(wp, NULL, m); } } }
/* Set a flag option. */ struct options_entry * cmd_set_option_flag(struct cmd *self, struct cmd_ctx *ctx, const struct options_table_entry *oe, struct options *oo) { struct cmd_target_data *data = self->data; int flag; if (data->arg2 == NULL || *data->arg2 == '\0') flag = !options_get_number(oo, oe->name); else { if ((data->arg2[0] == '1' && data->arg2[1] == '\0') || strcasecmp(data->arg2, "on") == 0 || strcasecmp(data->arg2, "yes") == 0) flag = 1; else if ((data->arg2[0] == '0' && data->arg2[1] == '\0') || strcasecmp(data->arg2, "off") == 0 || strcasecmp(data->arg2, "no") == 0) flag = 0; else { ctx->error(ctx, "bad value: %s", data->arg2); return (NULL); } } return (options_set_number(oo, oe->name, flag)); }
void cmd_load_buffer_callback(struct client *c, void *data) { int *buffer = data; char *pdata; size_t psize; u_int limit; /* * Event callback has already checked client is not dead and reduced * its reference count. But tell it to exit. */ c->flags |= CLIENT_EXIT; psize = EVBUFFER_LENGTH(c->stdin_event->input); if (psize == 0 || (pdata = malloc(psize + 1)) == NULL) { xfree(data); return; } bufferevent_read(c->stdin_event, pdata, psize); pdata[psize] = '\0'; limit = options_get_number(&global_options, "buffer-limit"); if (*buffer == -1) paste_add(&global_buffers, pdata, psize, limit); else if (paste_replace(&global_buffers, *buffer, pdata, psize) != 0) { /* No context so can't use server_client_msg_error. */ evbuffer_add_printf( c->stderr_event->output, "no buffer %d\n", *buffer); bufferevent_enable(c->stderr_event, EV_WRITE); } xfree(data); }
/* Set a flag option. */ struct options_entry * cmd_set_option_flag(unused struct cmd *self, struct cmd_q *cmdq, const struct options_table_entry *oe, struct options *oo, const char *value) { int flag; if (value == NULL || *value == '\0') flag = !options_get_number(oo, oe->name); else { if ((value[0] == '1' && value[1] == '\0') || strcasecmp(value, "on") == 0 || strcasecmp(value, "yes") == 0) flag = 1; else if ((value[0] == '0' && value[1] == '\0') || strcasecmp(value, "off") == 0 || strcasecmp(value, "no") == 0) flag = 0; else { cmdq_error(cmdq, "bad value: %s", value); return (NULL); } } return (options_set_number(oo, oe->name, flag)); }
int cmd_set_buffer_exec(struct cmd *self, struct cmd_ctx *ctx) { struct args *args = self->args; u_int limit; char *pdata, *cause; size_t psize; int buffer; limit = options_get_number(&global_options, "buffer-limit"); pdata = xstrdup(args->argv[0]); psize = strlen(pdata); if (!args_has(args, 'b')) { paste_add(&global_buffers, pdata, psize, limit); return (0); } buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause); if (cause != NULL) { ctx->error(ctx, "buffer %s", cause); xfree(cause); xfree(pdata); return (-1); } if (paste_replace(&global_buffers, buffer, pdata, psize) != 0) { ctx->error(ctx, "no buffer %d", buffer); xfree(pdata); return (-1); } return (0); }
int cmd_set_buffer_exec(struct cmd *self, struct cmd_ctx *ctx) { struct cmd_buffer_data *data = self->data; struct session *s; u_int limit; char *pdata; size_t psize; if ((s = cmd_find_session(ctx, data->target)) == NULL) return (-1); limit = options_get_number(&s->options, "buffer-limit"); pdata = xstrdup(data->arg); psize = strlen(pdata); if (data->buffer == -1) { paste_add(&s->buffers, pdata, psize, limit); return (0); } if (paste_replace(&s->buffers, data->buffer, pdata, psize) != 0) { ctx->error(ctx, "no buffer %d", data->buffer); xfree(pdata); return (-1); } return (0); }
int cmd_break_pane_exec(struct cmd *self, struct cmd_ctx *ctx) { struct args *args = self->args; struct winlink *wl; struct session *s; struct window_pane *wp; struct window *w; char *name; char *cause; int base_idx; struct client *c; if ((wl = cmd_find_pane(ctx, args_get(args, 't'), &s, &wp)) == NULL) return (-1); if (window_count_panes(wl->window) == 1) { ctx->error(ctx, "can't break with only one pane"); return (-1); } w = wl->window; TAILQ_REMOVE(&w->panes, wp, entry); if (wp == w->active) { w->active = w->last; w->last = NULL; if (w->active == NULL) { w->active = TAILQ_PREV(wp, window_panes, entry); if (w->active == NULL) w->active = TAILQ_NEXT(wp, entry); } } else if (wp == w->last) w->last = NULL; layout_close_pane(wp); w = wp->window = window_create1(s->sx, s->sy); TAILQ_INSERT_HEAD(&w->panes, wp, entry); w->active = wp; name = default_window_name(w); window_set_name(w, name); xfree(name); layout_init(w); base_idx = options_get_number(&s->options, "base-index"); wl = session_attach(s, w, -1 - base_idx, &cause); /* can't fail */ if (!args_has(self->args, 'd')) session_select(s, wl->idx); server_redraw_session(s); server_status_session_group(s); /* Output the window ID for control clients. */ c = cmd_find_client(ctx, NULL); if (c->flags & CLIENT_CONTROL) { ctx->print(ctx, "%d", w->id); } return (0); }
/* Is there any status (main or aux) on last line? (1 True, 0 False) */ int any_status_on_last(struct client *c) { struct session *s = c->session; int status, aux_status; status = options_get_number(s->options, "status"); aux_status = options_get_number(s->options, "aux-status"); if (status && aux_status) return 1; if (status && options_get_number(s->options, "status-position")!=0) return 1; if (aux_status && options_get_number(s->options, "aux-status-position")!=0) return 1; return 0; }
enum cmd_retval cmd_break_pane_exec(struct cmd *self, struct cmd_q *cmdq) { #ifdef TMATE_SLAVE return (CMD_RETURN_ERROR); #else struct args *args = self->args; struct winlink *wl = cmdq->state.sflag.wl; struct session *src_s = cmdq->state.sflag.s; struct session *dst_s = cmdq->state.tflag.s; struct window_pane *wp = cmdq->state.sflag.wp; struct window *w = wl->window; char *name; char *cause; int idx = cmdq->state.tflag.idx; struct format_tree *ft; const char *template; char *cp; if (idx != -1 && winlink_find_by_index(&dst_s->windows, idx) != NULL) { cmdq_error(cmdq, "index %d already in use", idx); return (CMD_RETURN_ERROR); } if (window_count_panes(w) == 1) { cmdq_error(cmdq, "can't break with only one pane"); return (CMD_RETURN_ERROR); } server_unzoom_window(w); TAILQ_REMOVE(&w->panes, wp, entry); window_lost_pane(w, wp); layout_close_pane(wp); w = wp->window = window_create1(dst_s->sx, dst_s->sy); TAILQ_INSERT_HEAD(&w->panes, wp, entry); w->active = wp; name = default_window_name(w); window_set_name(w, name); free(name); layout_init(w, wp); wp->flags |= PANE_CHANGED; if (idx == -1) idx = -1 - options_get_number(dst_s->options, "base-index"); wl = session_attach(dst_s, w, idx, &cause); /* can't fail */ if (!args_has(self->args, 'd')) session_select(dst_s, wl->idx); server_redraw_session(src_s); if (src_s != dst_s) server_redraw_session(dst_s); server_status_session_group(src_s); if (src_s != dst_s) server_status_session_group(dst_s); if (args_has(args, 'P')) { if ((template = args_get(args, 'F')) == NULL)
enum cmd_retval cmd_break_pane_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct winlink *wl; struct session *s; struct window_pane *wp; struct window *w; char *name; char *cause; int base_idx; struct client *c; struct format_tree *ft; const char *template; char *cp; if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp)) == NULL) return (CMD_RETURN_ERROR); if (window_count_panes(wl->window) == 1) { cmdq_error(cmdq, "can't break with only one pane"); return (CMD_RETURN_ERROR); } w = wl->window; server_unzoom_window(w); TAILQ_REMOVE(&w->panes, wp, entry); if (wp == w->active) { w->active = w->last; w->last = NULL; if (w->active == NULL) { w->active = TAILQ_PREV(wp, window_panes, entry); if (w->active == NULL) w->active = TAILQ_NEXT(wp, entry); } } else if (wp == w->last) w->last = NULL; layout_close_pane(wp); w = wp->window = window_create1(s->sx, s->sy); TAILQ_INSERT_HEAD(&w->panes, wp, entry); w->active = wp; name = default_window_name(w); window_set_name(w, name); free(name); layout_init(w, wp); base_idx = options_get_number(&s->options, "base-index"); wl = session_attach(s, w, -1 - base_idx, &cause); /* can't fail */ if (!args_has(self->args, 'd')) session_select(s, wl->idx); server_redraw_session(s); server_status_session_group(s); if (args_has(args, 'P')) { if ((template = args_get(args, 'F')) == NULL)
enum cmd_retval cmd_capture_pane_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct client *c; struct window_pane *wp; char *buf, *cause; int buffer; u_int limit; size_t len; if (cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp) == NULL) return (CMD_RETURN_ERROR); len = 0; if (args_has(args, 'P')) buf = cmd_capture_pane_pending(args, wp, &len); else buf = cmd_capture_pane_history(args, cmdq, wp, &len); if (buf == NULL) return (CMD_RETURN_ERROR); if (args_has(args, 'p')) { c = cmdq->client; if (c == NULL || (c->session != NULL && !(c->flags & CLIENT_CONTROL))) { cmdq_error(cmdq, "can't write to stdout"); return (CMD_RETURN_ERROR); } evbuffer_add(c->stdout_data, buf, len); if (args_has(args, 'P') && len > 0) evbuffer_add(c->stdout_data, "\n", 1); server_push_stdout(c); } else { limit = options_get_number(&global_options, "buffer-limit"); if (!args_has(args, 'b')) { paste_add(buf, len, limit); return (CMD_RETURN_NORMAL); } buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause); if (cause != NULL) { cmdq_error(cmdq, "buffer %s", cause); free(buf); free(cause); return (CMD_RETURN_ERROR); } if (paste_replace(buffer, buf, len) != 0) { cmdq_error(cmdq, "no buffer %d", buffer); free(buf); return (CMD_RETURN_ERROR); } } return (CMD_RETURN_NORMAL); }
int cmd_load_buffer_exec(struct cmd *self, struct cmd_ctx *ctx) { struct cmd_buffer_data *data = self->data; struct session *s; FILE *f; char *pdata, *new_pdata; size_t psize; u_int limit; int ch; if ((s = cmd_find_session(ctx, data->target)) == NULL) return (-1); if ((f = fopen(data->arg, "rb")) == NULL) { ctx->error(ctx, "%s: %s", data->arg, strerror(errno)); return (-1); } pdata = NULL; psize = 0; while ((ch = getc(f)) != EOF) { /* Do not let the server die due to memory exhaustion. */ if ((new_pdata = realloc(pdata, psize + 2)) == NULL) { ctx->error(ctx, "realloc error: %s", strerror(errno)); goto error; } pdata = new_pdata; pdata[psize++] = ch; } if (ferror(f)) { ctx->error(ctx, "%s: read error", data->arg); goto error; } if (pdata != NULL) pdata[psize] = '\0'; fclose(f); limit = options_get_number(&s->options, "buffer-limit"); if (data->buffer == -1) { paste_add(&s->buffers, pdata, psize, limit); return (0); } if (paste_replace(&s->buffers, data->buffer, pdata, psize) != 0) { ctx->error(ctx, "no buffer %d", data->buffer); goto error; } return (0); error: if (pdata != NULL) xfree(pdata); fclose(f); return (-1); }
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_move_window_exec(struct cmd *self, struct cmd_q *cmdq) { #ifdef TMATE cmdq_error(cmdq, "move window is not supported with tmate"); return (CMD_RETURN_ERROR); #else struct args *args = self->args; struct session *src = cmdq->state.sflag.s; struct session *dst = cmdq->state.tflag.s; struct winlink *wl = cmdq->state.sflag.wl; char *cause; int idx = cmdq->state.tflag.idx, kflag, dflag, sflag; kflag = args_has(self->args, 'k'); dflag = args_has(self->args, 'd'); if (args_has(args, 'r')) { session_renumber_windows(dst); recalculate_sizes(); return (CMD_RETURN_NORMAL); } kflag = args_has(self->args, 'k'); dflag = args_has(self->args, 'd'); sflag = args_has(self->args, 's'); if (args_has(self->args, 'a')) { if ((idx = winlink_shuffle_up(dst, dst->curw)) == -1) return (CMD_RETURN_ERROR); } if (server_link_window(src, wl, dst, idx, kflag, !dflag, &cause) != 0) { cmdq_error(cmdq, "can't link window: %s", cause); free(cause); return (CMD_RETURN_ERROR); } if (self->entry == &cmd_move_window_entry) server_unlink_window(src, wl); /* * Renumber the winlinks in the src session only, the destination * session already has the correct winlink id to us, either * automatically or specified by -s. */ if (!sflag && options_get_number(src->options, "renumber-windows")) session_renumber_windows(src); recalculate_sizes(); return (CMD_RETURN_NORMAL); #endif }
enum cmd_retval cmd_set_buffer_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct paste_buffer *pb; u_int limit; char *pdata, *cause; size_t psize, newsize; int buffer; limit = options_get_number(&global_options, "buffer-limit"); psize = 0; pdata = NULL; pb = NULL; buffer = -1; if (args_has(args, 'b')) { buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause); if (cause != NULL) { cmdq_error(cmdq, "buffer %s", cause); free(cause); return (CMD_RETURN_ERROR); } pb = paste_get_index(&global_buffers, buffer); if (pb == NULL) { cmdq_error(cmdq, "no buffer %d", buffer); return (CMD_RETURN_ERROR); } } else if (args_has(args, 'a')) { pb = paste_get_top(&global_buffers); if (pb != NULL) buffer = 0; } if (args_has(args, 'a') && pb != NULL) { psize = pb->size; pdata = xmalloc(psize); memcpy(pdata, pb->data, psize); } newsize = strlen(args->argv[0]); pdata = xrealloc(pdata, 1, psize + newsize); memcpy(pdata + psize, args->argv[0], newsize); psize += newsize; if (buffer == -1) paste_add(&global_buffers, pdata, psize, limit); else paste_replace(&global_buffers, buffer, pdata, psize); return (CMD_RETURN_NORMAL); }
/* Translate mouse and output. */ void input_mouse(struct window_pane *wp, struct session *s, struct mouse_event *m) { char buf[10]; size_t len; struct paste_buffer *pb; if (wp->screen->mode & ALL_MOUSE_MODES) { if (wp->screen->mode & MODE_MOUSE_UTF8) { len = xsnprintf(buf, sizeof buf, "\033[M"); len += utf8_split2(m->xb + 32, &buf[len]); len += utf8_split2(m->x + 33, &buf[len]); len += utf8_split2(m->y + 33, &buf[len]); } else { if (m->xb > 223 || m->x >= 222 || m->y > 222) return; len = xsnprintf(buf, sizeof buf, "\033[M"); buf[len++] = m->xb + 32; buf[len++] = m->x + 33; buf[len++] = m->y + 33; } bufferevent_write(wp->event, buf, len); return; } if (m->button == 1 && (m->event & MOUSE_EVENT_CLICK) && options_get_number(&wp->window->options, "mode-mouse") == 1) { pb = paste_get_top(&global_buffers); if (pb != NULL) { paste_send_pane(pb, wp, "\r", wp->screen->mode & MODE_BRACKETPASTE); } } else if ((m->xb & 3) != 1 && options_get_number(&wp->window->options, "mode-mouse") == 1) { if (window_pane_set_mode(wp, &window_copy_mode) == 0) { window_copy_init_from_pane(wp); if (wp->mode->mouse != NULL) wp->mode->mouse(wp, s, m); } } }
void check_window_name(struct window *w) { struct timeval tv, next; char *name; int left; if (w->active == NULL) return; if (!options_get_number(w->options, "automatic-rename")) return; if (~w->active->flags & PANE_CHANGED) { log_debug("@%u active pane not changed", w->id); return; } log_debug("@%u active pane changed", w->id); gettimeofday(&tv, NULL); left = name_time_expired(w, &tv); if (left != 0) { if (!event_initialized(&w->name_event)) evtimer_set(&w->name_event, name_time_callback, w); if (!evtimer_pending(&w->name_event, NULL)) { log_debug("@%u name timer queued (%d left)", w->id, left); timerclear(&next); next.tv_usec = left; event_add(&w->name_event, &next); } else { log_debug("@%u name timer already queued (%d left)", w->id, left); } return; } memcpy(&w->name_time, &tv, sizeof w->name_time); if (event_initialized(&w->name_event)) evtimer_del(&w->name_event); w->active->flags &= ~PANE_CHANGED; name = format_window_name(w); if (strcmp(name, w->name) != 0) { log_debug("@%u new name %s (was %s)", w->id, name, w->name); window_set_name(w, name); server_status_window(w); } else log_debug("@%u name not changed (still %s)", w->id, w->name); free(name); }
/* Open UTF-8 character. */ int input_utf8_open(struct input_ctx *ictx) { if (!options_get_number(&ictx->wp->window->options, "utf8")) { /* Print, and do not switch state. */ input_print(ictx); return (-1); } log_debug("%s", __func__); utf8_open(&ictx->utf8data, ictx->ch); return (0); }