tmux  3.2a
About: tmux is a terminal multiplexer that lets you switch easily between several programs in one terminal.
  Fossies Dox: tmux-3.2a.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

cmd-send-keys.c
Go to the documentation of this file.
1 /* $OpenBSD$ */
2 
3 /*
4  * Copyright (c) 2008 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 #include <string.h>
23 
24 #include "tmux.h"
25 
26 /*
27  * Send keys to client.
28  */
29 
30 static enum cmd_retval cmd_send_keys_exec(struct cmd *, struct cmdq_item *);
31 
32 const struct cmd_entry cmd_send_keys_entry = {
33  .name = "send-keys",
34  .alias = "send",
35 
36  .args = { "FHlMN:Rt:X", 0, -1 },
37  .usage = "[-FHlMRX] [-N repeat-count] " CMD_TARGET_PANE_USAGE
38  " key ...",
39 
40  .target = { 't', CMD_FIND_PANE, 0 },
41 
42  .flags = CMD_AFTERHOOK,
43  .exec = cmd_send_keys_exec
44 };
45 
46 const struct cmd_entry cmd_send_prefix_entry = {
47  .name = "send-prefix",
48  .alias = NULL,
49 
50  .args = { "2t:", 0, 0 },
51  .usage = "[-2] " CMD_TARGET_PANE_USAGE,
52 
53  .target = { 't', CMD_FIND_PANE, 0 },
54 
55  .flags = CMD_AFTERHOOK,
56  .exec = cmd_send_keys_exec
57 };
58 
59 static struct cmdq_item *
60 cmd_send_keys_inject_key(struct cmdq_item *item, struct cmdq_item *after,
61  key_code key)
62 {
63  struct cmd_find_state *target = cmdq_get_target(item);
64  struct client *tc = cmdq_get_target_client(item);
65  struct session *s = target->s;
66  struct winlink *wl = target->wl;
67  struct window_pane *wp = target->wp;
68  struct window_mode_entry *wme;
69  struct key_table *table;
70  struct key_binding *bd;
71 
72  wme = TAILQ_FIRST(&wp->modes);
73  if (wme == NULL || wme->mode->key_table == NULL) {
74  if (window_pane_key(wp, tc, s, wl, key, NULL) != 0)
75  return (NULL);
76  return (item);
77  }
78  table = key_bindings_get_table(wme->mode->key_table(wme), 1);
79 
80  bd = key_bindings_get(table, key & ~KEYC_MASK_FLAGS);
81  if (bd != NULL) {
82  table->references++;
83  after = key_bindings_dispatch(bd, after, tc, NULL, target);
85  }
86  return (after);
87 }
88 
89 static struct cmdq_item *
90 cmd_send_keys_inject_string(struct cmdq_item *item, struct cmdq_item *after,
91  struct args *args, int i)
92 {
93  const char *s = args->argv[i];
94  struct utf8_data *ud, *loop;
95  utf8_char uc;
96  key_code key;
97  char *endptr;
98  long n;
99  int literal;
100 
101  if (args_has(args, 'H')) {
102  n = strtol(s, &endptr, 16);
103  if (*s =='\0' || n < 0 || n > 0xff || *endptr != '\0')
104  return (item);
105  return (cmd_send_keys_inject_key(item, after, KEYC_LITERAL|n));
106  }
107 
108  literal = args_has(args, 'l');
109  if (!literal) {
111  if (key != KEYC_NONE && key != KEYC_UNKNOWN) {
112  after = cmd_send_keys_inject_key(item, after, key);
113  if (after != NULL)
114  return (after);
115  }
116  literal = 1;
117  }
118  if (literal) {
119  ud = utf8_fromcstr(s);
120  for (loop = ud; loop->size != 0; loop++) {
121  if (loop->size == 1 && loop->data[0] <= 0x7f)
122  key = loop->data[0];
123  else {
124  if (utf8_from_data(loop, &uc) != UTF8_DONE)
125  continue;
126  key = uc;
127  }
128  after = cmd_send_keys_inject_key(item, after, key);
129  }
130  free(ud);
131  }
132  return (after);
133 }
134 
135 static enum cmd_retval
136 cmd_send_keys_exec(struct cmd *self, struct cmdq_item *item)
137 {
138  struct args *args = cmd_get_args(self);
139  struct cmd_find_state *target = cmdq_get_target(item);
140  struct client *tc = cmdq_get_target_client(item);
141  struct session *s = target->s;
142  struct winlink *wl = target->wl;
143  struct window_pane *wp = target->wp;
144  struct key_event *event = cmdq_get_event(item);
145  struct mouse_event *m = &event->m;
146  struct window_mode_entry *wme = TAILQ_FIRST(&wp->modes);
147  struct cmdq_item *after = item;
148  int i;
149  key_code key;
150  u_int np = 1;
151  char *cause = NULL;
152 
153  if (args_has(args, 'N')) {
154  np = args_strtonum(args, 'N', 1, UINT_MAX, &cause);
155  if (cause != NULL) {
156  cmdq_error(item, "repeat count %s", cause);
157  free(cause);
158  return (CMD_RETURN_ERROR);
159  }
160  if (wme != NULL && (args_has(args, 'X') || args->argc == 0)) {
161  if (wme->mode->command == NULL) {
162  cmdq_error(item, "not in a mode");
163  return (CMD_RETURN_ERROR);
164  }
165  wme->prefix = np;
166  }
167  }
168 
169  if (args_has(args, 'X')) {
170  if (wme == NULL || wme->mode->command == NULL) {
171  cmdq_error(item, "not in a mode");
172  return (CMD_RETURN_ERROR);
173  }
174  if (!m->valid)
175  m = NULL;
176  wme->mode->command(wme, tc, s, wl, args, m);
177  return (CMD_RETURN_NORMAL);
178  }
179 
180  if (args_has(args, 'M')) {
181  wp = cmd_mouse_pane(m, &s, NULL);
182  if (wp == NULL) {
183  cmdq_error(item, "no mouse target");
184  return (CMD_RETURN_ERROR);
185  }
186  window_pane_key(wp, tc, s, wl, m->key, m);
187  return (CMD_RETURN_NORMAL);
188  }
189 
190  if (cmd_get_entry(self) == &cmd_send_prefix_entry) {
191  if (args_has(args, '2'))
192  key = options_get_number(s->options, "prefix2");
193  else
194  key = options_get_number(s->options, "prefix");
195  cmd_send_keys_inject_key(item, item, key);
196  return (CMD_RETURN_NORMAL);
197  }
198 
199  if (args_has(args, 'R')) {
201  input_reset(wp->ictx, 1);
202  }
203 
204  for (; np != 0; np--) {
205  for (i = 0; i < args->argc; i++) {
206  after = cmd_send_keys_inject_string(item, after, args,
207  i);
208  }
209  }
210 
211  return (CMD_RETURN_NORMAL);
212 }
int args_has(struct args *args, u_char flag)
Definition: arguments.c:259
long long args_strtonum(struct args *args, u_char flag, long long minval, long long maxval, char **cause)
Definition: arguments.c:355
struct client * cmdq_get_target_client(struct cmdq_item *item)
Definition: cmd-queue.c:157
struct cmd_find_state * cmdq_get_target(struct cmdq_item *item)
Definition: cmd-queue.c:171
struct key_event * cmdq_get_event(struct cmdq_item *item)
Definition: cmd-queue.c:185
void cmdq_error(struct cmdq_item *item, const char *fmt,...)
Definition: cmd-queue.c:833
const struct cmd_entry cmd_send_keys_entry
Definition: cmd-send-keys.c:32
static struct cmdq_item * cmd_send_keys_inject_string(struct cmdq_item *item, struct cmdq_item *after, struct args *args, int i)
Definition: cmd-send-keys.c:90
const struct cmd_entry cmd_send_prefix_entry
Definition: cmd-send-keys.c:46
static struct cmdq_item * cmd_send_keys_inject_key(struct cmdq_item *item, struct cmdq_item *after, key_code key)
Definition: cmd-send-keys.c:60
static enum cmd_retval cmd_send_keys_exec(struct cmd *, struct cmdq_item *)
struct args * cmd_get_args(struct cmd *cmd)
Definition: cmd.c:393
const struct cmd_entry * cmd_get_entry(struct cmd *cmd)
Definition: cmd.c:386
struct window_pane * cmd_mouse_pane(struct mouse_event *m, struct session **sp, struct winlink **wlp)
Definition: cmd.c:758
void input_reset(struct input_ctx *ictx, int clear)
Definition: input.c:842
struct cmdq_item * key_bindings_dispatch(struct key_binding *bd, struct cmdq_item *item, struct client *c, struct key_event *event, struct cmd_find_state *fs)
Definition: key-bindings.c:650
void key_bindings_unref_table(struct key_table *table)
Definition: key-bindings.c:133
struct key_table * key_bindings_get_table(const char *name, int create)
Definition: key-bindings.c:100
struct key_binding * key_bindings_get(struct key_table *table, key_code key)
Definition: key-bindings.c:155
key_code key_string_lookup_string(const char *string)
Definition: key-string.c:165
key_code key
Definition: key-string.c:32
long long options_get_number(struct options *oo, const char *name)
Definition: options.c:699
Definition: tmux.h:1435
int argc
Definition: tmux.h:1437
char ** argv
Definition: tmux.h:1438
Definition: tmux.h:1608
Definition: tmux.h:1525
const char * name
Definition: tmux.h:1526
struct window_pane * wp
Definition: tmux.h:1454
struct session * s
Definition: tmux.h:1451
struct winlink * wl
Definition: tmux.h:1452
Definition: cmd.c:212
u_int references
Definition: tmux.h:1793
int valid
Definition: tmux.h:1238
key_code key
Definition: tmux.h:1241
Definition: tmux.h:1179
struct options * options
Definition: tmux.h:1199
u_char data[21]
Definition: tmux.h:629
u_char size
Definition: tmux.h:632
Definition: tmux.h:927
const struct window_mode * mode
Definition: tmux.h:931
struct window_pane * wp
Definition: tmux.h:928
u_int prefix
Definition: tmux.h:935
void(* command)(struct window_mode_entry *, struct client *, struct session *, struct winlink *, struct args *, struct mouse_event *)
Definition: tmux.h:919
const char *(* key_table)(struct window_mode_entry *)
Definition: tmux.h:918
struct input_ctx * ictx
Definition: tmux.h:1010
#define KEYC_UNKNOWN
Definition: tmux.h:114
cmd_retval
Definition: tmux.h:1475
@ CMD_RETURN_NORMAL
Definition: tmux.h:1477
@ CMD_RETURN_ERROR
Definition: tmux.h:1476
u_int utf8_char
Definition: tmux.h:620
int window_pane_key(struct window_pane *, struct client *, struct session *, struct winlink *, key_code, struct mouse_event *)
Definition: window.c:1158
#define CMD_AFTERHOOK
Definition: tmux.h:1541
enum utf8_state utf8_from_data(const struct utf8_data *, utf8_char *)
Definition: utf8.c:127
struct utf8_data * utf8_fromcstr(const char *)
Definition: utf8.c:472
#define KEYC_LITERAL
Definition: tmux.h:129
unsigned long long key_code
Definition: tmux.h:177
#define KEYC_NONE
Definition: tmux.h:113
#define CMD_TARGET_PANE_USAGE
Definition: tmux.h:1858
#define KEYC_MASK_FLAGS
Definition: tmux.h:137
@ UTF8_DONE
Definition: tmux.h:638
@ CMD_FIND_PANE
Definition: tmux.h:1443
void window_pane_reset_palette(struct window_pane *)
Definition: window.c:1037