15494e770Schristos /* $OpenBSD$ */
2698d5317Sjmmv
3698d5317Sjmmv /*
4ed4e6cd4Schristos * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
5698d5317Sjmmv *
6698d5317Sjmmv * Permission to use, copy, modify, and distribute this software for any
7698d5317Sjmmv * purpose with or without fee is hereby granted, provided that the above
8698d5317Sjmmv * copyright notice and this permission notice appear in all copies.
9698d5317Sjmmv *
10698d5317Sjmmv * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11698d5317Sjmmv * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12698d5317Sjmmv * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13698d5317Sjmmv * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14698d5317Sjmmv * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15698d5317Sjmmv * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16698d5317Sjmmv * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17698d5317Sjmmv */
18698d5317Sjmmv
19698d5317Sjmmv #include <sys/types.h>
20698d5317Sjmmv
21698d5317Sjmmv #include <stdlib.h>
22698d5317Sjmmv #include <string.h>
23698d5317Sjmmv
24698d5317Sjmmv #include "tmux.h"
25698d5317Sjmmv
26698d5317Sjmmv /*
27698d5317Sjmmv * Switch client to a different session.
28698d5317Sjmmv */
29698d5317Sjmmv
304e179ddaSchristos static enum cmd_retval cmd_switch_client_exec(struct cmd *,
314e179ddaSchristos struct cmdq_item *);
32698d5317Sjmmv
33698d5317Sjmmv const struct cmd_entry cmd_switch_client_entry = {
34ed4e6cd4Schristos .name = "switch-client",
35ed4e6cd4Schristos .alias = "switchc",
36ed4e6cd4Schristos
37*6db26757Swiz .args = { "lc:EFnpt:rT:Z", 0, 0, NULL },
38aa83ff61Schristos .usage = "[-ElnprZ] [-c target-client] [-t target-session] "
39ed4e6cd4Schristos "[-T key-table]",
40ed4e6cd4Schristos
41c9ad075bSchristos /* -t is special */
42ed4e6cd4Schristos
439fb66d81Schristos .flags = CMD_READONLY|CMD_CLIENT_CFLAG,
44ed4e6cd4Schristos .exec = cmd_switch_client_exec
45698d5317Sjmmv };
46698d5317Sjmmv
474e179ddaSchristos static enum cmd_retval
cmd_switch_client_exec(struct cmd * self,struct cmdq_item * item)484e179ddaSchristos cmd_switch_client_exec(struct cmd *self, struct cmdq_item *item)
49698d5317Sjmmv {
509fb66d81Schristos struct args *args = cmd_get_args(self);
519fb66d81Schristos struct cmd_find_state *current = cmdq_get_current(item);
529fb66d81Schristos struct cmd_find_state target;
53c9ad075bSchristos const char *tflag = args_get(args, 't');
54c9ad075bSchristos enum cmd_find_type type;
55c9ad075bSchristos int flags;
569fb66d81Schristos struct client *tc = cmdq_get_target_client(item);
57c9ad075bSchristos struct session *s;
58c9ad075bSchristos struct winlink *wl;
59aa83ff61Schristos struct window *w;
60ed4e6cd4Schristos struct window_pane *wp;
614e179ddaSchristos const char *tablename;
625494e770Schristos struct key_table *table;
63698d5317Sjmmv
646483eba0Schristos if (tflag != NULL && tflag[strcspn(tflag, ":.%")] != '\0') {
65c9ad075bSchristos type = CMD_FIND_PANE;
66c9ad075bSchristos flags = 0;
67c9ad075bSchristos } else {
68c9ad075bSchristos type = CMD_FIND_SESSION;
69c9ad075bSchristos flags = CMD_FIND_PREFER_UNATTACHED;
70c9ad075bSchristos }
719fb66d81Schristos if (cmd_find_target(&target, item, tflag, type, flags) != 0)
72c9ad075bSchristos return (CMD_RETURN_ERROR);
739fb66d81Schristos s = target.s;
749fb66d81Schristos wl = target.wl;
759fb66d81Schristos wp = target.wp;
76c9ad075bSchristos
779fb66d81Schristos if (args_has(args, 'r')) {
789fb66d81Schristos if (tc->flags & CLIENT_READONLY)
799fb66d81Schristos tc->flags &= ~(CLIENT_READONLY|CLIENT_IGNORESIZE);
809fb66d81Schristos else
819fb66d81Schristos tc->flags |= (CLIENT_READONLY|CLIENT_IGNORESIZE);
829fb66d81Schristos }
835494e770Schristos
845494e770Schristos tablename = args_get(args, 'T');
855494e770Schristos if (tablename != NULL) {
865494e770Schristos table = key_bindings_get_table(tablename, 0);
875494e770Schristos if (table == NULL) {
884e179ddaSchristos cmdq_error(item, "table %s doesn't exist", tablename);
895494e770Schristos return (CMD_RETURN_ERROR);
905494e770Schristos }
915494e770Schristos table->references++;
929fb66d81Schristos key_bindings_unref_table(tc->keytable);
939fb66d81Schristos tc->keytable = table;
94ed4e6cd4Schristos return (CMD_RETURN_NORMAL);
95928fc495Schristos }
96928fc495Schristos
97d530c4d0Sjmmv if (args_has(args, 'n')) {
989fb66d81Schristos if ((s = session_next_session(tc->session)) == NULL) {
994e179ddaSchristos cmdq_error(item, "can't find next session");
100928fc495Schristos return (CMD_RETURN_ERROR);
101698d5317Sjmmv }
102d530c4d0Sjmmv } else if (args_has(args, 'p')) {
1039fb66d81Schristos if ((s = session_previous_session(tc->session)) == NULL) {
1044e179ddaSchristos cmdq_error(item, "can't find previous session");
105928fc495Schristos return (CMD_RETURN_ERROR);
106698d5317Sjmmv }
107d530c4d0Sjmmv } else if (args_has(args, 'l')) {
1089fb66d81Schristos if (tc->last_session != NULL && session_alive(tc->last_session))
1099fb66d81Schristos s = tc->last_session;
110ed4e6cd4Schristos else
111ed4e6cd4Schristos s = NULL;
112698d5317Sjmmv if (s == NULL) {
1134e179ddaSchristos cmdq_error(item, "can't find last session");
114928fc495Schristos return (CMD_RETURN_ERROR);
115698d5317Sjmmv }
116928fc495Schristos } else {
1179fb66d81Schristos if (cmdq_get_client(item) == NULL)
118928fc495Schristos return (CMD_RETURN_NORMAL);
1199fb66d81Schristos if (wl != NULL && wp != NULL && wp != wl->window->active) {
1209fb66d81Schristos w = wl->window;
1219fb66d81Schristos if (window_push_zoom(w, 0, args_has(args, 'Z')))
122aa83ff61Schristos server_redraw_window(w);
123aa83ff61Schristos window_redraw_active_switch(w, wp);
124aa83ff61Schristos window_set_active_pane(w, wp, 1);
125aa83ff61Schristos if (window_pop_zoom(w))
126aa83ff61Schristos server_redraw_window(w);
127ef36e747Schristos }
128aa83ff61Schristos if (wl != NULL) {
129c9ad075bSchristos session_set_current(s, wl);
1309fb66d81Schristos cmd_find_from_session(current, s, 0);
131928fc495Schristos }
132928fc495Schristos }
133698d5317Sjmmv
1344e179ddaSchristos if (!args_has(args, 'E'))
1359fb66d81Schristos environ_update(s->options, tc->environ, s->environ);
1365494e770Schristos
137*6db26757Swiz server_client_set_session(tc, s);
1389fb66d81Schristos if (~cmdq_get_flags(item) & CMDQ_STATE_REPEAT)
1399fb66d81Schristos server_client_set_key_table(tc, NULL);
140698d5317Sjmmv
141928fc495Schristos return (CMD_RETURN_NORMAL);
142698d5317Sjmmv }
143