xref: /openbsd-src/usr.bin/tmux/cmd-refresh-client.c (revision f6b75673f6c960a9743bfd16c1e52dd100265c68)
1 /* $OpenBSD: cmd-refresh-client.c,v 1.28 2018/10/18 08:38:01 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 
23 #include "tmux.h"
24 
25 /*
26  * Refresh client.
27  */
28 
29 static enum cmd_retval	cmd_refresh_client_exec(struct cmd *,
30 			    struct cmdq_item *);
31 
32 const struct cmd_entry cmd_refresh_client_entry = {
33 	.name = "refresh-client",
34 	.alias = "refresh",
35 
36 	.args = { "cC:DlLRSt:U", 0, 1 },
37 	.usage = "[-cDlLRSU] [-C size] " CMD_TARGET_CLIENT_USAGE " [adjustment]",
38 
39 	.flags = CMD_AFTERHOOK,
40 	.exec = cmd_refresh_client_exec
41 };
42 
43 static enum cmd_retval
44 cmd_refresh_client_exec(struct cmd *self, struct cmdq_item *item)
45 {
46 	struct args	*args = self->args;
47 	struct client	*c;
48 	struct tty	*tty;
49 	struct window	*w;
50 	const char	*size, *errstr;
51 	u_int		 x, y, adjust;
52 
53 	if ((c = cmd_find_client(item, args_get(args, 't'), 0)) == NULL)
54 		return (CMD_RETURN_ERROR);
55 	tty = &c->tty;
56 
57 	if (args_has(args, 'c') ||
58 	    args_has(args, 'L') ||
59 	    args_has(args, 'R') ||
60 	    args_has(args, 'U') ||
61 	    args_has(args, 'D'))
62 	{
63 		if (args->argc == 0)
64 			adjust = 1;
65 		else {
66 			adjust = strtonum(args->argv[0], 1, INT_MAX, &errstr);
67 			if (errstr != NULL) {
68 				cmdq_error(item, "adjustment %s", errstr);
69 				return (CMD_RETURN_ERROR);
70 			}
71 		}
72 
73 		if (args_has(args, 'c'))
74 		    c->pan_window = NULL;
75 		else {
76 			w = c->session->curw->window;
77 			if (c->pan_window != w) {
78 				c->pan_window = w;
79 				c->pan_ox = tty->oox;
80 				c->pan_oy = tty->ooy;
81 			}
82 			if (args_has(args, 'L')) {
83 				if (c->pan_ox > adjust)
84 					c->pan_ox -= adjust;
85 				else
86 					c->pan_ox = 0;
87 			} else if (args_has(args, 'R')) {
88 				c->pan_ox += adjust;
89 				if (c->pan_ox > w->sx - tty->osx)
90 					c->pan_ox = w->sx - tty->osx;
91 			} else if (args_has(args, 'U')) {
92 				if (c->pan_oy > adjust)
93 					c->pan_oy -= adjust;
94 				else
95 					c->pan_oy = 0;
96 			} else if (args_has(args, 'D')) {
97 				c->pan_oy += adjust;
98 				if (c->pan_oy > w->sy - tty->osy)
99 					c->pan_oy = w->sy - tty->osy;
100 			}
101 		}
102 		tty_update_client_offset(c);
103 		server_redraw_client(c);
104 		return (CMD_RETURN_NORMAL);
105 	}
106 
107 	if (args_has(args, 'l')) {
108 		if (c->session != NULL)
109 			tty_putcode_ptr2(&c->tty, TTYC_MS, "", "?");
110 	} else if (args_has(args, 'C')) {
111 		if ((size = args_get(args, 'C')) == NULL) {
112 			cmdq_error(item, "missing size");
113 			return (CMD_RETURN_ERROR);
114 		}
115 		if (sscanf(size, "%u,%u", &x, &y) != 2 &&
116 		    sscanf(size, "%ux%u", &x, &y)) {
117 			cmdq_error(item, "bad size argument");
118 			return (CMD_RETURN_ERROR);
119 		}
120 		if (x < WINDOW_MINIMUM || x > WINDOW_MAXIMUM ||
121 		    y < WINDOW_MINIMUM || y > WINDOW_MAXIMUM) {
122 			cmdq_error(item, "size too small or too big");
123 			return (CMD_RETURN_ERROR);
124 		}
125 		if (!(c->flags & CLIENT_CONTROL)) {
126 			cmdq_error(item, "not a control client");
127 			return (CMD_RETURN_ERROR);
128 		}
129 		tty_set_size(&c->tty, x, y);
130 		c->flags |= CLIENT_SIZECHANGED;
131 		recalculate_sizes();
132 		return (CMD_RETURN_NORMAL);
133 	}
134 
135 	if (args_has(args, 'S')) {
136 		c->flags |= CLIENT_STATUSFORCE;
137 		server_status_client(c);
138 	} else {
139 		c->flags |= CLIENT_STATUSFORCE;
140 		server_redraw_client(c);
141 	}
142 	return (CMD_RETURN_NORMAL);
143 }
144