1 /* $Id: cmd-select-window.c,v 1.1.1.2 2011/08/17 18:40:04 jmmv Exp $ */
2 
3 /*
4  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
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  * Select window by index.
27  */
28 
29 void	cmd_select_window_key_binding(struct cmd *, int);
30 int	cmd_select_window_exec(struct cmd *, struct cmd_ctx *);
31 
32 const struct cmd_entry cmd_select_window_entry = {
33 	"select-window", "selectw",
34 	"lnpt:", 0, 0,
35 	"[-lnp] " CMD_TARGET_WINDOW_USAGE,
36 	0,
37 	cmd_select_window_key_binding,
38 	NULL,
39 	cmd_select_window_exec
40 };
41 
42 const struct cmd_entry cmd_next_window_entry = {
43 	"next-window", "next",
44 	"at:", 0, 0,
45 	"[-a] " CMD_TARGET_SESSION_USAGE,
46 	0,
47 	cmd_select_window_key_binding,
48 	NULL,
49 	cmd_select_window_exec
50 };
51 
52 const struct cmd_entry cmd_previous_window_entry = {
53 	"previous-window", "prev",
54 	"at:", 0, 0,
55 	"[-a] " CMD_TARGET_SESSION_USAGE,
56 	0,
57 	cmd_select_window_key_binding,
58 	NULL,
59 	cmd_select_window_exec
60 };
61 
62 const struct cmd_entry cmd_last_window_entry = {
63 	"last-window", "last",
64 	"t:", 0, 0,
65 	CMD_TARGET_SESSION_USAGE,
66 	0,
67 	NULL,
68 	NULL,
69 	cmd_select_window_exec
70 };
71 
72 void
73 cmd_select_window_key_binding(struct cmd *self, int key)
74 {
75 	char	tmp[16];
76 
77 	self->args = args_create(0);
78 	if (key >= '0' && key <= '9') {
79 		xsnprintf(tmp, sizeof tmp, ":%d", key - '0');
80 		args_set(self->args, 't', tmp);
81 	}
82 	if (key == ('n' | KEYC_ESCAPE) || key == ('p' | KEYC_ESCAPE))
83 		args_set(self->args, 'a', NULL);
84 }
85 
86 int
87 cmd_select_window_exec(struct cmd *self, struct cmd_ctx *ctx)
88 {
89 	struct args	*args = self->args;
90 	struct winlink	*wl;
91 	struct session	*s;
92 	int		 next, previous, last, activity;
93 
94 	next = self->entry == &cmd_next_window_entry;
95 	if (args_has(self->args, 'n'))
96 		next = 1;
97 	previous = self->entry == &cmd_previous_window_entry;
98 	if (args_has(self->args, 'p'))
99 		previous = 1;
100 	last = self->entry == &cmd_last_window_entry;
101 	if (args_has(self->args, 'l'))
102 		last = 1;
103 
104 	if (next || previous || last) {
105 		s = cmd_find_session(ctx, args_get(args, 't'), 0);
106 		if (s == NULL)
107 			return (-1);
108 
109 		activity = args_has(self->args, 'a');
110 		if (next) {
111 			if (session_next(s, activity) != 0) {
112 				ctx->error(ctx, "no next window");
113 				return (-1);
114 			}
115 		} else if (previous) {
116 			if (session_previous(s, activity) != 0) {
117 				ctx->error(ctx, "no previous window");
118 				return (-1);
119 			}
120 		} else {
121 			if (session_last(s) != 0) {
122 				ctx->error(ctx, "no last window");
123 				return (-1);
124 			}
125 		}
126 
127 		server_redraw_session(s);
128 	} else {
129 		wl = cmd_find_window(ctx, args_get(args, 't'), &s);
130 		if (wl == NULL)
131 			return (-1);
132 
133 		if (session_select(s, wl->idx) == 0)
134 			server_redraw_session(s);
135 	}
136 	recalculate_sizes();
137 
138 	return (0);
139 }
140