1/* $OpenBSD$ */
2
3/*
4 * Copyright (c) 2007 Nicholas Marriott <[email protected]>
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
30static enum cmd_retval cmd_refresh_client_exec(struct cmd *,
31 struct cmdq_item *);
32
33const 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
45static enum cmd_retval
46cmd_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