xref: /minix3/external/bsd/tmux/dist/cmd-swap-pane.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc /* Id */
2eda6f593SDavid van Moolenbroek 
3eda6f593SDavid van Moolenbroek /*
4eda6f593SDavid van Moolenbroek  * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
5eda6f593SDavid van Moolenbroek  *
6eda6f593SDavid van Moolenbroek  * Permission to use, copy, modify, and distribute this software for any
7eda6f593SDavid van Moolenbroek  * purpose with or without fee is hereby granted, provided that the above
8eda6f593SDavid van Moolenbroek  * copyright notice and this permission notice appear in all copies.
9eda6f593SDavid van Moolenbroek  *
10eda6f593SDavid van Moolenbroek  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11eda6f593SDavid van Moolenbroek  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12eda6f593SDavid van Moolenbroek  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13eda6f593SDavid van Moolenbroek  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14eda6f593SDavid van Moolenbroek  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15eda6f593SDavid van Moolenbroek  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16eda6f593SDavid van Moolenbroek  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17eda6f593SDavid van Moolenbroek  */
18eda6f593SDavid van Moolenbroek 
19eda6f593SDavid van Moolenbroek #include <sys/types.h>
20eda6f593SDavid van Moolenbroek 
21eda6f593SDavid van Moolenbroek #include <stdlib.h>
22eda6f593SDavid van Moolenbroek 
23eda6f593SDavid van Moolenbroek #include "tmux.h"
24eda6f593SDavid van Moolenbroek 
25eda6f593SDavid van Moolenbroek /*
26eda6f593SDavid van Moolenbroek  * Swap two panes.
27eda6f593SDavid van Moolenbroek  */
28eda6f593SDavid van Moolenbroek 
29eda6f593SDavid van Moolenbroek void		 cmd_swap_pane_key_binding(struct cmd *, int);
30*0a6a1f1dSLionel Sambuc enum cmd_retval	 cmd_swap_pane_exec(struct cmd *, struct cmd_q *);
31eda6f593SDavid van Moolenbroek 
32eda6f593SDavid van Moolenbroek const struct cmd_entry cmd_swap_pane_entry = {
33eda6f593SDavid van Moolenbroek 	"swap-pane", "swapp",
34eda6f593SDavid van Moolenbroek 	"dDs:t:U", 0, 0,
35eda6f593SDavid van Moolenbroek 	"[-dDU] " CMD_SRCDST_PANE_USAGE,
36eda6f593SDavid van Moolenbroek 	0,
37eda6f593SDavid van Moolenbroek 	cmd_swap_pane_key_binding,
38eda6f593SDavid van Moolenbroek 	cmd_swap_pane_exec
39eda6f593SDavid van Moolenbroek };
40eda6f593SDavid van Moolenbroek 
41eda6f593SDavid van Moolenbroek void
cmd_swap_pane_key_binding(struct cmd * self,int key)42eda6f593SDavid van Moolenbroek cmd_swap_pane_key_binding(struct cmd *self, int key)
43eda6f593SDavid van Moolenbroek {
44eda6f593SDavid van Moolenbroek 	self->args = args_create(0);
45eda6f593SDavid van Moolenbroek 	if (key == '{')
46eda6f593SDavid van Moolenbroek 		args_set(self->args, 'U', NULL);
47eda6f593SDavid van Moolenbroek 	else if (key == '}')
48eda6f593SDavid van Moolenbroek 		args_set(self->args, 'D', NULL);
49eda6f593SDavid van Moolenbroek }
50eda6f593SDavid van Moolenbroek 
51*0a6a1f1dSLionel Sambuc enum cmd_retval
cmd_swap_pane_exec(struct cmd * self,struct cmd_q * cmdq)52*0a6a1f1dSLionel Sambuc cmd_swap_pane_exec(struct cmd *self, struct cmd_q *cmdq)
53eda6f593SDavid van Moolenbroek {
54eda6f593SDavid van Moolenbroek 	struct args		*args = self->args;
55eda6f593SDavid van Moolenbroek 	struct winlink		*src_wl, *dst_wl;
56eda6f593SDavid van Moolenbroek 	struct window		*src_w, *dst_w;
57eda6f593SDavid van Moolenbroek 	struct window_pane	*tmp_wp, *src_wp, *dst_wp;
58eda6f593SDavid van Moolenbroek 	struct layout_cell	*src_lc, *dst_lc;
59eda6f593SDavid van Moolenbroek 	u_int			 sx, sy, xoff, yoff;
60eda6f593SDavid van Moolenbroek 
61*0a6a1f1dSLionel Sambuc 	dst_wl = cmd_find_pane(cmdq, args_get(args, 't'), NULL, &dst_wp);
62eda6f593SDavid van Moolenbroek 	if (dst_wl == NULL)
63*0a6a1f1dSLionel Sambuc 		return (CMD_RETURN_ERROR);
64eda6f593SDavid van Moolenbroek 	dst_w = dst_wl->window;
65*0a6a1f1dSLionel Sambuc 	server_unzoom_window(dst_w);
66eda6f593SDavid van Moolenbroek 
67eda6f593SDavid van Moolenbroek 	if (!args_has(args, 's')) {
68eda6f593SDavid van Moolenbroek 		src_w = dst_w;
69eda6f593SDavid van Moolenbroek 		if (args_has(self->args, 'D')) {
70eda6f593SDavid van Moolenbroek 			src_wp = TAILQ_NEXT(dst_wp, entry);
71eda6f593SDavid van Moolenbroek 			if (src_wp == NULL)
72eda6f593SDavid van Moolenbroek 				src_wp = TAILQ_FIRST(&dst_w->panes);
73eda6f593SDavid van Moolenbroek 		} else if (args_has(self->args, 'U')) {
74eda6f593SDavid van Moolenbroek 			src_wp = TAILQ_PREV(dst_wp, window_panes, entry);
75eda6f593SDavid van Moolenbroek 			if (src_wp == NULL)
76eda6f593SDavid van Moolenbroek 				src_wp = TAILQ_LAST(&dst_w->panes, window_panes);
77eda6f593SDavid van Moolenbroek 		} else {
78*0a6a1f1dSLionel Sambuc 			src_wl = cmd_find_pane(cmdq, NULL, NULL, &src_wp);
79eda6f593SDavid van Moolenbroek 			if (src_wl == NULL)
80*0a6a1f1dSLionel Sambuc 				return (CMD_RETURN_ERROR);
81eda6f593SDavid van Moolenbroek 			src_w = src_wl->window;
82eda6f593SDavid van Moolenbroek 		}
83*0a6a1f1dSLionel Sambuc 	} else {
84*0a6a1f1dSLionel Sambuc 		src_wl = cmd_find_pane(cmdq, args_get(args, 's'), NULL, &src_wp);
85*0a6a1f1dSLionel Sambuc 		if (src_wl == NULL)
86*0a6a1f1dSLionel Sambuc 			return (CMD_RETURN_ERROR);
87*0a6a1f1dSLionel Sambuc 		src_w = src_wl->window;
88*0a6a1f1dSLionel Sambuc 	}
89*0a6a1f1dSLionel Sambuc 	server_unzoom_window(src_w);
90eda6f593SDavid van Moolenbroek 
91eda6f593SDavid van Moolenbroek 	if (src_wp == dst_wp)
92*0a6a1f1dSLionel Sambuc 		return (CMD_RETURN_NORMAL);
93eda6f593SDavid van Moolenbroek 
94eda6f593SDavid van Moolenbroek 	tmp_wp = TAILQ_PREV(dst_wp, window_panes, entry);
95eda6f593SDavid van Moolenbroek 	TAILQ_REMOVE(&dst_w->panes, dst_wp, entry);
96eda6f593SDavid van Moolenbroek 	TAILQ_REPLACE(&src_w->panes, src_wp, dst_wp, entry);
97eda6f593SDavid van Moolenbroek 	if (tmp_wp == src_wp)
98eda6f593SDavid van Moolenbroek 		tmp_wp = dst_wp;
99eda6f593SDavid van Moolenbroek 	if (tmp_wp == NULL)
100eda6f593SDavid van Moolenbroek 		TAILQ_INSERT_HEAD(&dst_w->panes, src_wp, entry);
101eda6f593SDavid van Moolenbroek 	else
102eda6f593SDavid van Moolenbroek 		TAILQ_INSERT_AFTER(&dst_w->panes, tmp_wp, src_wp, entry);
103eda6f593SDavid van Moolenbroek 
104eda6f593SDavid van Moolenbroek 	src_lc = src_wp->layout_cell;
105eda6f593SDavid van Moolenbroek 	dst_lc = dst_wp->layout_cell;
106eda6f593SDavid van Moolenbroek 	src_lc->wp = dst_wp;
107eda6f593SDavid van Moolenbroek 	dst_wp->layout_cell = src_lc;
108eda6f593SDavid van Moolenbroek 	dst_lc->wp = src_wp;
109eda6f593SDavid van Moolenbroek 	src_wp->layout_cell = dst_lc;
110eda6f593SDavid van Moolenbroek 
111eda6f593SDavid van Moolenbroek 	src_wp->window = dst_w;
112eda6f593SDavid van Moolenbroek 	dst_wp->window = src_w;
113eda6f593SDavid van Moolenbroek 
114eda6f593SDavid van Moolenbroek 	sx = src_wp->sx; sy = src_wp->sy;
115eda6f593SDavid van Moolenbroek 	xoff = src_wp->xoff; yoff = src_wp->yoff;
116eda6f593SDavid van Moolenbroek 	src_wp->xoff = dst_wp->xoff; src_wp->yoff = dst_wp->yoff;
117eda6f593SDavid van Moolenbroek 	window_pane_resize(src_wp, dst_wp->sx, dst_wp->sy);
118eda6f593SDavid van Moolenbroek 	dst_wp->xoff = xoff; dst_wp->yoff = yoff;
119eda6f593SDavid van Moolenbroek 	window_pane_resize(dst_wp, sx, sy);
120eda6f593SDavid van Moolenbroek 
121eda6f593SDavid van Moolenbroek 	if (!args_has(self->args, 'd')) {
122eda6f593SDavid van Moolenbroek 		if (src_w != dst_w) {
123eda6f593SDavid van Moolenbroek 			window_set_active_pane(src_w, dst_wp);
124eda6f593SDavid van Moolenbroek 			window_set_active_pane(dst_w, src_wp);
125eda6f593SDavid van Moolenbroek 		} else {
126eda6f593SDavid van Moolenbroek 			tmp_wp = dst_wp;
127eda6f593SDavid van Moolenbroek 			if (!window_pane_visible(tmp_wp))
128eda6f593SDavid van Moolenbroek 				tmp_wp = src_wp;
129eda6f593SDavid van Moolenbroek 			window_set_active_pane(src_w, tmp_wp);
130eda6f593SDavid van Moolenbroek 		}
131eda6f593SDavid van Moolenbroek 	} else {
132eda6f593SDavid van Moolenbroek 		if (src_w->active == src_wp)
133eda6f593SDavid van Moolenbroek 			window_set_active_pane(src_w, dst_wp);
134eda6f593SDavid van Moolenbroek 		if (dst_w->active == dst_wp)
135eda6f593SDavid van Moolenbroek 			window_set_active_pane(dst_w, src_wp);
136eda6f593SDavid van Moolenbroek 	}
137eda6f593SDavid van Moolenbroek 	if (src_w != dst_w) {
138eda6f593SDavid van Moolenbroek 		if (src_w->last == src_wp)
139eda6f593SDavid van Moolenbroek 			src_w->last = NULL;
140eda6f593SDavid van Moolenbroek 		if (dst_w->last == dst_wp)
141eda6f593SDavid van Moolenbroek 			dst_w->last = NULL;
142eda6f593SDavid van Moolenbroek 	}
143eda6f593SDavid van Moolenbroek 	server_redraw_window(src_w);
144eda6f593SDavid van Moolenbroek 	server_redraw_window(dst_w);
145eda6f593SDavid van Moolenbroek 
146*0a6a1f1dSLionel Sambuc 	return (CMD_RETURN_NORMAL);
147eda6f593SDavid van Moolenbroek }
148