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)  

notify.c
Go to the documentation of this file.
1 /* $OpenBSD$ */
2 
3 /*
4  * Copyright (c) 2012 George Nachman <tmux@georgester.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 struct notify_entry {
27  const char *name;
28 
29  struct client *client;
30  struct session *session;
31  struct window *window;
32  int pane;
33 
34  struct cmd_find_state fs;
35 };
36 
37 static void
38 notify_hook_formats(struct cmdq_state *state, struct session *s,
39  struct window *w, int pane)
40 {
41  if (s != NULL) {
42  cmdq_add_format(state, "hook_session", "$%u", s->id);
43  cmdq_add_format(state, "hook_session_name", "%s", s->name);
44  }
45  if (w != NULL) {
46  cmdq_add_format(state, "hook_window", "@%u", w->id);
47  cmdq_add_format(state, "hook_window_name", "%s", w->name);
48  }
49  if (pane != -1)
50  cmdq_add_format(state, "hook_pane", "%%%d", pane);
51 }
52 
53 static void
54 notify_insert_hook(struct cmdq_item *item, struct notify_entry *ne)
55 {
56  struct cmd_find_state fs;
57  struct options *oo;
58  struct cmdq_item *new_item;
59  struct cmdq_state *new_state;
60  struct session *s = ne->session;
61  struct window *w = ne->window;
62  struct options_entry *o;
63  struct options_array_item *a;
64  struct cmd_list *cmdlist;
65 
66  log_debug("%s: %s", __func__, ne->name);
67 
68  cmd_find_clear_state(&fs, 0);
69  if (cmd_find_empty_state(&ne->fs) || !cmd_find_valid_state(&ne->fs))
70  cmd_find_from_nothing(&fs, 0);
71  else
72  cmd_find_copy_state(&fs, &ne->fs);
73 
74  if (fs.s == NULL)
75  oo = global_s_options;
76  else
77  oo = fs.s->options;
78  o = options_get(oo, ne->name);
79  if (o == NULL && fs.wp != NULL) {
80  oo = fs.wp->options;
81  o = options_get(oo, ne->name);
82  }
83  if (o == NULL && fs.wl != NULL) {
84  oo = fs.wl->window->options;
85  o = options_get(oo, ne->name);
86  }
87  if (o == NULL)
88  return;
89 
90  new_state = cmdq_new_state(&fs, NULL, CMDQ_STATE_NOHOOKS);
91  cmdq_add_format(new_state, "hook", "%s", ne->name);
92  notify_hook_formats(new_state, s, w, ne->pane);
93 
94  a = options_array_first(o);
95  while (a != NULL) {
96  cmdlist = options_array_item_value(a)->cmdlist;
97  if (cmdlist != NULL) {
98  new_item = cmdq_get_command(cmdlist, new_state);
99  item = cmdq_insert_after(item, new_item);
100  }
101  a = options_array_next(a);
102  }
103 
104  cmdq_free_state(new_state);
105 }
106 
107 static enum cmd_retval
108 notify_callback(struct cmdq_item *item, void *data)
109 {
110  struct notify_entry *ne = data;
111 
112  log_debug("%s: %s", __func__, ne->name);
113 
114  if (strcmp(ne->name, "pane-mode-changed") == 0)
116  if (strcmp(ne->name, "window-layout-changed") == 0)
118  if (strcmp(ne->name, "window-pane-changed") == 0)
120  if (strcmp(ne->name, "window-unlinked") == 0)
122  if (strcmp(ne->name, "window-linked") == 0)
124  if (strcmp(ne->name, "window-renamed") == 0)
126  if (strcmp(ne->name, "client-session-changed") == 0)
128  if (strcmp(ne->name, "client-detached") == 0)
130  if (strcmp(ne->name, "session-renamed") == 0)
132  if (strcmp(ne->name, "session-created") == 0)
134  if (strcmp(ne->name, "session-closed") == 0)
136  if (strcmp(ne->name, "session-window-changed") == 0)
138 
139  notify_insert_hook(item, ne);
140 
141  if (ne->client != NULL)
143  if (ne->session != NULL)
144  session_remove_ref(ne->session, __func__);
145  if (ne->window != NULL)
146  window_remove_ref(ne->window, __func__);
147 
148  if (ne->fs.s != NULL)
149  session_remove_ref(ne->fs.s, __func__);
150 
151  free((void *)ne->name);
152  free(ne);
153 
154  return (CMD_RETURN_NORMAL);
155 }
156 
157 static void
158 notify_add(const char *name, struct cmd_find_state *fs, struct client *c,
159  struct session *s, struct window *w, struct window_pane *wp)
160 {
161  struct notify_entry *ne;
162  struct cmdq_item *item;
163 
164  item = cmdq_running(NULL);
165  if (item != NULL && (cmdq_get_flags(item) & CMDQ_STATE_NOHOOKS))
166  return;
167 
168  ne = xcalloc(1, sizeof *ne);
169  ne->name = xstrdup(name);
170 
171  ne->client = c;
172  ne->session = s;
173  ne->window = w;
174 
175  if (wp != NULL)
176  ne->pane = wp->id;
177  else
178  ne->pane = -1;
179 
180  if (c != NULL)
181  c->references++;
182  if (s != NULL)
183  session_add_ref(s, __func__);
184  if (w != NULL)
185  window_add_ref(w, __func__);
186 
187  cmd_find_copy_state(&ne->fs, fs);
188  if (ne->fs.s != NULL) /* cmd_find_valid_state needs session */
189  session_add_ref(ne->fs.s, __func__);
190 
192 }
193 
194 void
195 notify_hook(struct cmdq_item *item, const char *name)
196 {
197  struct cmd_find_state *target = cmdq_get_target(item);
198  struct notify_entry ne;
199 
200  memset(&ne, 0, sizeof ne);
201 
202  ne.name = name;
203  cmd_find_copy_state(&ne.fs, target);
204 
205  ne.client = cmdq_get_client(item);
206  ne.session = target->s;
207  ne.window = target->w;
208  ne.pane = target->wp->id;
209 
210  notify_insert_hook(item, &ne);
211 }
212 
213 void
214 notify_client(const char *name, struct client *c)
215 {
216  struct cmd_find_state fs;
217 
218  cmd_find_from_client(&fs, c, 0);
219  notify_add(name, &fs, c, NULL, NULL, NULL);
220 }
221 
222 void
223 notify_session(const char *name, struct session *s)
224 {
225  struct cmd_find_state fs;
226 
227  if (session_alive(s))
228  cmd_find_from_session(&fs, s, 0);
229  else
230  cmd_find_from_nothing(&fs, 0);
231  notify_add(name, &fs, NULL, s, NULL, NULL);
232 }
233 
234 void
235 notify_winlink(const char *name, struct winlink *wl)
236 {
237  struct cmd_find_state fs;
238 
239  cmd_find_from_winlink(&fs, wl, 0);
240  notify_add(name, &fs, NULL, wl->session, wl->window, NULL);
241 }
242 
243 void
244 notify_session_window(const char *name, struct session *s, struct window *w)
245 {
246  struct cmd_find_state fs;
247 
248  cmd_find_from_session_window(&fs, s, w, 0);
249  notify_add(name, &fs, NULL, s, w, NULL);
250 }
251 
252 void
253 notify_window(const char *name, struct window *w)
254 {
255  struct cmd_find_state fs;
256 
257  cmd_find_from_window(&fs, w, 0);
258  notify_add(name, &fs, NULL, NULL, w, NULL);
259 }
260 
261 void
262 notify_pane(const char *name, struct window_pane *wp)
263 {
264  struct cmd_find_state fs;
265 
266  cmd_find_from_pane(&fs, wp, 0);
267  notify_add(name, &fs, NULL, NULL, NULL, wp);
268 }
int cmd_find_from_nothing(struct cmd_find_state *fs, int flags)
Definition: cmd-find.c:819
void cmd_find_copy_state(struct cmd_find_state *dst, struct cmd_find_state *src)
Definition: cmd-find.c:689
int cmd_find_valid_state(struct cmd_find_state *fs)
Definition: cmd-find.c:664
void cmd_find_clear_state(struct cmd_find_state *fs, int flags)
Definition: cmd-find.c:644
int cmd_find_from_window(struct cmd_find_state *fs, struct window *w, int flags)
Definition: cmd-find.c:770
int cmd_find_empty_state(struct cmd_find_state *fs)
Definition: cmd-find.c:655
void cmd_find_from_winlink(struct cmd_find_state *fs, struct winlink *wl, int flags)
Definition: cmd-find.c:737
int cmd_find_from_session_window(struct cmd_find_state *fs, struct session *s, struct window *w, int flags)
Definition: cmd-find.c:751
int cmd_find_from_pane(struct cmd_find_state *fs, struct window_pane *wp, int flags)
Definition: cmd-find.c:807
int cmd_find_from_client(struct cmd_find_state *fs, struct client *c, int flags)
Definition: cmd-find.c:859
void cmd_find_from_session(struct cmd_find_state *fs, struct session *s, int flags)
Definition: cmd-find.c:723
struct client * cmdq_get_client(struct cmdq_item *item)
Definition: cmd-queue.c:150
int cmdq_get_flags(struct cmdq_item *item)
Definition: cmd-queue.c:199
void cmdq_free_state(struct cmdq_state *state)
Definition: cmd-queue.c:244
struct cmd_find_state * cmdq_get_target(struct cmdq_item *item)
Definition: cmd-queue.c:171
struct cmdq_item * cmdq_get_command(struct cmd_list *cmdlist, struct cmdq_state *state)
Definition: cmd-queue.c:474
struct cmdq_item * cmdq_append(struct client *c, struct cmdq_item *item)
Definition: cmd-queue.c:288
void cmdq_add_format(struct cmdq_state *state, const char *key, const char *fmt,...)
Definition: cmd-queue.c:256
struct cmdq_state * cmdq_new_state(struct cmd_find_state *current, struct key_event *event, int flags)
Definition: cmd-queue.c:206
struct cmdq_item * cmdq_insert_after(struct cmdq_item *after, struct cmdq_item *item)
Definition: cmd-queue.c:312
struct cmdq_item * cmdq_running(struct client *c)
Definition: cmd-queue.c:767
void control_notify_session_created(struct session *s)
void control_notify_session_renamed(struct session *s)
void control_notify_window_renamed(struct window *w)
void control_notify_client_session_changed(struct client *cc)
void control_notify_window_pane_changed(struct window *w)
void control_notify_pane_mode_changed(int pane)
void control_notify_window_linked(struct session *s, struct window *w)
void control_notify_window_layout_changed(struct window *w)
void control_notify_window_unlinked(struct session *s, struct window *w)
void control_notify_session_window_changed(struct session *s)
void control_notify_client_detached(struct client *cc)
void control_notify_session_closed(struct session *s)
const char * name
Definition: layout-set.c:38
void log_debug(const char *msg,...)
Definition: log.c:130
void notify_session(const char *name, struct session *s)
Definition: notify.c:223
static void notify_add(const char *name, struct cmd_find_state *fs, struct client *c, struct session *s, struct window *w, struct window_pane *wp)
Definition: notify.c:158
void notify_session_window(const char *name, struct session *s, struct window *w)
Definition: notify.c:244
void notify_client(const char *name, struct client *c)
Definition: notify.c:214
void notify_hook(struct cmdq_item *item, const char *name)
Definition: notify.c:195
static enum cmd_retval notify_callback(struct cmdq_item *item, void *data)
Definition: notify.c:108
static void notify_insert_hook(struct cmdq_item *item, struct notify_entry *ne)
Definition: notify.c:54
void notify_pane(const char *name, struct window_pane *wp)
Definition: notify.c:262
void notify_window(const char *name, struct window *w)
Definition: notify.c:253
static void notify_hook_formats(struct cmdq_state *state, struct session *s, struct window *w, int pane)
Definition: notify.c:38
void notify_winlink(const char *name, struct winlink *wl)
Definition: notify.c:235
union options_value * options_array_item_value(struct options_array_item *a)
Definition: options.c:549
struct options_array_item * options_array_first(struct options_entry *o)
Definition: options.c:529
struct options_array_item * options_array_next(struct options_array_item *a)
Definition: options.c:537
struct options_entry * options_get(struct options *oo, const char *name)
Definition: options.c:229
void server_client_unref(struct client *c)
void session_add_ref(struct session *s, const char *from)
Definition: session.c:165
int session_alive(struct session *s)
Definition: session.c:62
void session_remove_ref(struct session *s, const char *from)
Definition: session.c:173
Definition: tmux.h:1608
int references
Definition: tmux.h:1746
struct window_pane * wp
Definition: tmux.h:1454
struct window * w
Definition: tmux.h:1453
struct session * s
Definition: tmux.h:1451
struct winlink * wl
Definition: tmux.h:1452
Definition: notify.c:26
struct window * window
Definition: notify.c:31
struct session * session
Definition: notify.c:30
struct cmd_find_state fs
Definition: notify.c:34
int pane
Definition: notify.c:32
struct client * client
Definition: notify.c:29
const char * name
Definition: notify.c:27
Definition: options.c:50
Definition: tmux.h:1179
char * name
Definition: tmux.h:1182
u_int id
Definition: tmux.h:1180
struct options * options
Definition: tmux.h:1199
struct options * options
Definition: tmux.h:963
u_int id
Definition: tmux.h:959
Definition: tmux.h:1041
u_int id
Definition: tmux.h:1042
char * name
Definition: tmux.h:1045
struct options * options
Definition: tmux.h:1085
struct options * global_s_options
Definition: tmux.c:37
#define CMDQ_STATE_NOHOOKS
Definition: tmux.h:1512
#define cmdq_get_callback(cb, data)
Definition: tmux.h:2364
void window_remove_ref(struct window *, const char *)
Definition: window.c:391
cmd_retval
Definition: tmux.h:1475
@ CMD_RETURN_NORMAL
Definition: tmux.h:1477
void window_add_ref(struct window *, const char *)
Definition: window.c:384
struct cmd_list * cmdlist
Definition: tmux.h:1806
void * xcalloc(size_t nmemb, size_t size)
Definition: xmalloc.c:41
char * xstrdup(const char *str)
Definition: xmalloc.c:89