1 /* $OpenBSD: cmd-refresh-client.c,v 1.30 2019/11/28 09:05:34 nicm Exp $ */ 2 3 /* 4 * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <sys/types.h> 20 21 #include <stdlib.h> 22 #include <string.h> 23 24 #include "tmux.h" 25 26 /* 27 * Refresh client. 28 */ 29 30 static enum cmd_retval cmd_refresh_client_exec(struct cmd *, 31 struct cmdq_item *); 32 33 const struct cmd_entry cmd_refresh_client_entry = { 34 .name = "refresh-client", 35 .alias = "refresh", 36 37 .args = { "cC:DF:lLRSt:U", 0, 1 }, 38 .usage = "[-cDlLRSU] [-C XxY] [-F flags] " CMD_TARGET_CLIENT_USAGE 39 " [adjustment]", 40 41 .flags = CMD_AFTERHOOK, 42 .exec = cmd_refresh_client_exec 43 }; 44 45 static enum cmd_retval 46 cmd_refresh_client_exec(struct cmd *self, struct cmdq_item *item) 47 { 48 struct args *args = self->args; 49 struct client *c; 50 struct tty *tty; 51 struct window *w; 52 const char *size, *errstr; 53 char *copy, *next, *s; 54 u_int x, y, adjust; 55 56 if ((c = cmd_find_client(item, args_get(args, 't'), 0)) == NULL) 57 return (CMD_RETURN_ERROR); 58 tty = &c->tty; 59 60 if (args_has(args, 'c') || 61 args_has(args, 'L') || 62 args_has(args, 'R') || 63 args_has(args, 'U') || 64 args_has(args, 'D')) 65 { 66 if (args->argc == 0) 67 adjust = 1; 68 else { 69 adjust = strtonum(args->argv[0], 1, INT_MAX, &errstr); 70 if (errstr != NULL) { 71 cmdq_error(item, "adjustment %s", errstr); 72 return (CMD_RETURN_ERROR); 73 } 74 } 75 76 if (args_has(args, 'c')) 77 c->pan_window = NULL; 78 else { 79 w = c->session->curw->window; 80 if (c->pan_window != w) { 81 c->pan_window = w; 82 c->pan_ox = tty->oox; 83 c->pan_oy = tty->ooy; 84 } 85 if (args_has(args, 'L')) { 86 if (c->pan_ox > adjust) 87 c->pan_ox -= adjust; 88 else 89 c->pan_ox = 0; 90 } else if (args_has(args, 'R')) { 91 c->pan_ox += adjust; 92 if (c->pan_ox > w->sx - tty->osx) 93 c->pan_ox = w->sx - tty->osx; 94 } else if (args_has(args, 'U')) { 95 if (c->pan_oy > adjust) 96 c->pan_oy -= adjust; 97 else 98 c->pan_oy = 0; 99 } else if (args_has(args, 'D')) { 100 c->pan_oy += adjust; 101 if (c->pan_oy > w->sy - tty->osy) 102 c->pan_oy = w->sy - tty->osy; 103 } 104 } 105 tty_update_client_offset(c); 106 server_redraw_client(c); 107 return (CMD_RETURN_NORMAL); 108 } 109 110 if (args_has(args, 'l')) { 111 if (c->session != NULL) 112 tty_putcode_ptr2(&c->tty, TTYC_MS, "", "?"); 113 return (CMD_RETURN_NORMAL); 114 } 115 116 if (args_has(args, 'C') || args_has(args, 'F')) { 117 if (args_has(args, 'C')) { 118 if (!(c->flags & CLIENT_CONTROL)) { 119 cmdq_error(item, "not a control client"); 120 return (CMD_RETURN_ERROR); 121 } 122 size = args_get(args, 'C'); 123 if (sscanf(size, "%u,%u", &x, &y) != 2 && 124 sscanf(size, "%ux%u", &x, &y) != 2) { 125 cmdq_error(item, "bad size argument"); 126 return (CMD_RETURN_ERROR); 127 } 128 if (x < WINDOW_MINIMUM || x > WINDOW_MAXIMUM || 129 y < WINDOW_MINIMUM || y > WINDOW_MAXIMUM) { 130 cmdq_error(item, "size too small or too big"); 131 return (CMD_RETURN_ERROR); 132 } 133 tty_set_size(&c->tty, x, y, 0, 0); 134 c->flags |= CLIENT_SIZECHANGED; 135 recalculate_sizes(); 136 } 137 if (args_has(args, 'F')) { 138 if (!(c->flags & CLIENT_CONTROL)) { 139 cmdq_error(item, "not a control client"); 140 return (CMD_RETURN_ERROR); 141 } 142 s = copy = xstrdup(args_get(args, 'F')); 143 while ((next = strsep(&s, ",")) != NULL) { 144 /* Unknown flags are ignored. */ 145 if (strcmp(next, "no-output") == 0) 146 c->flags |= CLIENT_CONTROL_NOOUTPUT; 147 } 148 free(copy); 149 } 150 return (CMD_RETURN_NORMAL); 151 } 152 153 if (args_has(args, 'S')) { 154 c->flags |= CLIENT_STATUSFORCE; 155 server_status_client(c); 156 } else { 157 c->flags |= CLIENT_STATUSFORCE; 158 server_redraw_client(c); 159 } 160 return (CMD_RETURN_NORMAL); 161 } 162