4 * Copyright (c) 2012 George Nachman <tmux@georgester.com>
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.
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.
19 #include <sys/types.h>
20 #include <sys/queue.h>
29 struct cmd_find_state fs
;
30 struct format_tree
*formats
;
32 struct client
*client
;
33 struct session
*session
;
34 struct window
*window
;
39 notify_insert_hook(struct cmdq_item
*item
, struct notify_entry
*ne
)
41 struct cmd_find_state fs
;
43 struct cmdq_item
*new_item
;
44 struct cmdq_state
*new_state
;
45 struct options_entry
*o
;
46 struct options_array_item
*a
;
47 struct cmd_list
*cmdlist
;
49 log_debug("%s: %s", __func__
, ne
->name
);
51 cmd_find_clear_state(&fs
, 0);
52 if (cmd_find_empty_state(&ne
->fs
) || !cmd_find_valid_state(&ne
->fs
))
53 cmd_find_from_nothing(&fs
, 0);
55 cmd_find_copy_state(&fs
, &ne
->fs
);
58 oo
= global_s_options
;
61 o
= options_get(oo
, ne
->name
);
62 if (o
== NULL
&& fs
.wp
!= NULL
) {
64 o
= options_get(oo
, ne
->name
);
66 if (o
== NULL
&& fs
.wl
!= NULL
) {
67 oo
= fs
.wl
->window
->options
;
68 o
= options_get(oo
, ne
->name
);
73 new_state
= cmdq_new_state(&fs
, NULL
, CMDQ_STATE_NOHOOKS
);
74 cmdq_add_formats(new_state
, ne
->formats
);
76 a
= options_array_first(o
);
78 cmdlist
= options_array_item_value(a
)->cmdlist
;
79 if (cmdlist
!= NULL
) {
80 new_item
= cmdq_get_command(cmdlist
, new_state
);
81 item
= cmdq_insert_after(item
, new_item
);
83 a
= options_array_next(a
);
86 cmdq_free_state(new_state
);
89 static enum cmd_retval
90 notify_callback(struct cmdq_item
*item
, void *data
)
92 struct notify_entry
*ne
= data
;
94 log_debug("%s: %s", __func__
, ne
->name
);
96 if (strcmp(ne
->name
, "pane-mode-changed") == 0)
97 control_notify_pane_mode_changed(ne
->pane
);
98 if (strcmp(ne
->name
, "window-layout-changed") == 0)
99 control_notify_window_layout_changed(ne
->window
);
100 if (strcmp(ne
->name
, "window-pane-changed") == 0)
101 control_notify_window_pane_changed(ne
->window
);
102 if (strcmp(ne
->name
, "window-unlinked") == 0)
103 control_notify_window_unlinked(ne
->session
, ne
->window
);
104 if (strcmp(ne
->name
, "window-linked") == 0)
105 control_notify_window_linked(ne
->session
, ne
->window
);
106 if (strcmp(ne
->name
, "window-renamed") == 0)
107 control_notify_window_renamed(ne
->window
);
108 if (strcmp(ne
->name
, "client-session-changed") == 0)
109 control_notify_client_session_changed(ne
->client
);
110 if (strcmp(ne
->name
, "client-detached") == 0)
111 control_notify_client_detached(ne
->client
);
112 if (strcmp(ne
->name
, "session-renamed") == 0)
113 control_notify_session_renamed(ne
->session
);
114 if (strcmp(ne
->name
, "session-created") == 0)
115 control_notify_session_created(ne
->session
);
116 if (strcmp(ne
->name
, "session-closed") == 0)
117 control_notify_session_closed(ne
->session
);
118 if (strcmp(ne
->name
, "session-window-changed") == 0)
119 control_notify_session_window_changed(ne
->session
);
121 notify_insert_hook(item
, ne
);
123 if (ne
->client
!= NULL
)
124 server_client_unref(ne
->client
);
125 if (ne
->session
!= NULL
)
126 session_remove_ref(ne
->session
, __func__
);
127 if (ne
->window
!= NULL
)
128 window_remove_ref(ne
->window
, __func__
);
130 if (ne
->fs
.s
!= NULL
)
131 session_remove_ref(ne
->fs
.s
, __func__
);
133 format_free(ne
->formats
);
134 free((void *)ne
->name
);
137 return (CMD_RETURN_NORMAL
);
141 notify_add(const char *name
, struct cmd_find_state
*fs
, struct client
*c
,
142 struct session
*s
, struct window
*w
, struct window_pane
*wp
)
144 struct notify_entry
*ne
;
145 struct cmdq_item
*item
;
147 item
= cmdq_running(NULL
);
148 if (item
!= NULL
&& (cmdq_get_flags(item
) & CMDQ_STATE_NOHOOKS
))
151 ne
= xcalloc(1, sizeof *ne
);
152 ne
->name
= xstrdup(name
);
157 ne
->pane
= (wp
!= NULL
? wp
->id
: -1);
159 ne
->formats
= format_create(NULL
, NULL
, 0, FORMAT_NOJOBS
);
160 format_add(ne
->formats
, "hook", "%s", name
);
162 format_add(ne
->formats
, "hook_client", "%s", c
->name
);
164 format_add(ne
->formats
, "hook_session", "$%u", s
->id
);
165 format_add(ne
->formats
, "hook_session_name", "%s", s
->name
);
168 format_add(ne
->formats
, "hook_window", "@%u", w
->id
);
169 format_add(ne
->formats
, "hook_window_name", "%s", w
->name
);
172 format_add(ne
->formats
, "hook_pane", "%%%d", wp
->id
);
173 format_log_debug(ne
->formats
, __func__
);
178 session_add_ref(s
, __func__
);
180 window_add_ref(w
, __func__
);
182 cmd_find_copy_state(&ne
->fs
, fs
);
183 if (ne
->fs
.s
!= NULL
) /* cmd_find_valid_state needs session */
184 session_add_ref(ne
->fs
.s
, __func__
);
186 cmdq_append(NULL
, cmdq_get_callback(notify_callback
, ne
));
190 notify_hook(struct cmdq_item
*item
, const char *name
)
192 struct cmd_find_state
*target
= cmdq_get_target(item
);
193 struct notify_entry ne
;
195 memset(&ne
, 0, sizeof ne
);
198 cmd_find_copy_state(&ne
.fs
, target
);
200 ne
.client
= cmdq_get_client(item
);
201 ne
.session
= target
->s
;
202 ne
.window
= target
->w
;
203 ne
.pane
= (target
->wp
!= NULL
? target
->wp
->id
: -1);
205 ne
.formats
= format_create(NULL
, NULL
, 0, FORMAT_NOJOBS
);
206 format_add(ne
.formats
, "hook", "%s", name
);
207 format_log_debug(ne
.formats
, __func__
);
209 notify_insert_hook(item
, &ne
);
210 format_free(ne
.formats
);
214 notify_client(const char *name
, struct client
*c
)
216 struct cmd_find_state fs
;
218 cmd_find_from_client(&fs
, c
, 0);
219 notify_add(name
, &fs
, c
, NULL
, NULL
, NULL
);
223 notify_session(const char *name
, struct session
*s
)
225 struct cmd_find_state fs
;
227 if (session_alive(s
))
228 cmd_find_from_session(&fs
, s
, 0);
230 cmd_find_from_nothing(&fs
, 0);
231 notify_add(name
, &fs
, NULL
, s
, NULL
, NULL
);
235 notify_winlink(const char *name
, struct winlink
*wl
)
237 struct cmd_find_state fs
;
239 cmd_find_from_winlink(&fs
, wl
, 0);
240 notify_add(name
, &fs
, NULL
, wl
->session
, wl
->window
, NULL
);
244 notify_session_window(const char *name
, struct session
*s
, struct window
*w
)
246 struct cmd_find_state fs
;
248 cmd_find_from_session_window(&fs
, s
, w
, 0);
249 notify_add(name
, &fs
, NULL
, s
, w
, NULL
);
253 notify_window(const char *name
, struct window
*w
)
255 struct cmd_find_state fs
;
257 cmd_find_from_window(&fs
, w
, 0);
258 notify_add(name
, &fs
, NULL
, NULL
, w
, NULL
);
262 notify_pane(const char *name
, struct window_pane
*wp
)
264 struct cmd_find_state fs
;
266 cmd_find_from_pane(&fs
, wp
, 0);
267 notify_add(name
, &fs
, NULL
, NULL
, NULL
, wp
);