Annotation of embedaddon/tmux/notify.c, revision 1.1.1.1
1.1 misho 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(struct cmdq_item *item, struct notify_entry *ne)
39: {
40: struct cmd_find_state fs;
41: struct hook *hook;
42: struct cmdq_item *new_item;
43: struct session *s = ne->session;
44: struct window *w = ne->window;
45:
46: cmd_find_clear_state(&fs, NULL, 0);
47: if (cmd_find_empty_state(&ne->fs) || !cmd_find_valid_state(&ne->fs))
48: cmd_find_current(&fs, item, CMD_FIND_QUIET);
49: else
50: cmd_find_copy_state(&fs, &ne->fs);
51:
52: hook = hooks_find(hooks_get(fs.s), ne->name);
53: if (hook == NULL)
54: return;
55: log_debug("notify hook %s", ne->name);
56:
57: new_item = cmdq_get_command(hook->cmdlist, &fs, NULL, CMDQ_NOHOOKS);
58: cmdq_format(new_item, "hook", "%s", ne->name);
59:
60: if (s != NULL) {
61: cmdq_format(new_item, "hook_session", "$%u", s->id);
62: cmdq_format(new_item, "hook_session_name", "%s", s->name);
63: }
64: if (w != NULL) {
65: cmdq_format(new_item, "hook_window", "@%u", w->id);
66: cmdq_format(new_item, "hook_window_name", "%s", w->name);
67: }
68: if (ne->pane != -1)
69: cmdq_format(new_item, "hook_pane", "%%%d", ne->pane);
70:
71: cmdq_insert_after(item, new_item);
72: }
73:
74: static enum cmd_retval
75: notify_callback(struct cmdq_item *item, void *data)
76: {
77: struct notify_entry *ne = data;
78:
79: log_debug("%s: %s", __func__, ne->name);
80:
81: if (strcmp(ne->name, "window-layout-changed") == 0)
82: control_notify_window_layout_changed(ne->window);
83: if (strcmp(ne->name, "window-unlinked") == 0)
84: control_notify_window_unlinked(ne->session, ne->window);
85: if (strcmp(ne->name, "window-linked") == 0)
86: control_notify_window_linked(ne->session, ne->window);
87: if (strcmp(ne->name, "window-renamed") == 0)
88: control_notify_window_renamed(ne->window);
89: if (strcmp(ne->name, "client-session-changed") == 0)
90: control_notify_client_session_changed(ne->client);
91: if (strcmp(ne->name, "session-renamed") == 0)
92: control_notify_session_renamed(ne->session);
93: if (strcmp(ne->name, "session-created") == 0)
94: control_notify_session_created(ne->session);
95: if (strcmp(ne->name, "session-closed") == 0)
96: control_notify_session_closed(ne->session);
97:
98: notify_hook(item, ne);
99:
100: if (ne->client != NULL)
101: server_client_unref(ne->client);
102: if (ne->session != NULL)
103: session_unref(ne->session);
104: if (ne->window != NULL)
105: window_remove_ref(ne->window);
106:
107: if (ne->fs.s != NULL)
108: session_unref(ne->fs.s);
109:
110: free((void *)ne->name);
111: free(ne);
112:
113: return (CMD_RETURN_NORMAL);
114: }
115:
116: static void
117: notify_add(const char *name, struct cmd_find_state *fs, struct client *c,
118: struct session *s, struct window *w, struct window_pane *wp)
119: {
120: struct notify_entry *ne;
121: struct cmdq_item *new_item;
122:
123: ne = xcalloc(1, sizeof *ne);
124: ne->name = xstrdup(name);
125:
126: ne->client = c;
127: ne->session = s;
128: ne->window = w;
129:
130: if (wp != NULL)
131: ne->pane = wp->id;
132: else
133: ne->pane = -1;
134:
135: if (c != NULL)
136: c->references++;
137: if (s != NULL)
138: s->references++;
139: if (w != NULL)
140: w->references++;
141:
142: cmd_find_copy_state(&ne->fs, fs);
143: if (ne->fs.s != NULL)
144: ne->fs.s->references++; /* cmd_find_valid_state need session */
145:
146: new_item = cmdq_get_callback(notify_callback, ne);
147: cmdq_append(NULL, new_item);
148: }
149:
150: void
151: notify_input(struct window_pane *wp, struct evbuffer *input)
152: {
153: struct client *c;
154:
155: TAILQ_FOREACH(c, &clients, entry) {
156: if (c->flags & CLIENT_CONTROL)
157: control_notify_input(c, wp, input);
158: }
159: }
160:
161: void
162: notify_client(const char *name, struct client *c)
163: {
164: struct cmd_find_state fs;
165:
166: if (c->session != NULL)
167: cmd_find_from_session(&fs, c->session);
168: else
169: cmd_find_current(&fs, NULL, CMD_FIND_QUIET);
170: notify_add(name, &fs, c, NULL, NULL, NULL);
171: }
172:
173: void
174: notify_session(const char *name, struct session *s)
175: {
176: struct cmd_find_state fs;
177:
178: if (session_alive(s))
179: cmd_find_from_session(&fs, s);
180: else
181: cmd_find_current(&fs, NULL, CMD_FIND_QUIET);
182: notify_add(name, &fs, NULL, s, NULL, NULL);
183: }
184:
185: void
186: notify_winlink(const char *name, struct session *s, struct winlink *wl)
187: {
188: struct cmd_find_state fs;
189:
190: cmd_find_from_winlink(&fs, s, wl);
191: notify_add(name, &fs, NULL, s, wl->window, NULL);
192: }
193:
194: void
195: notify_session_window(const char *name, struct session *s, struct window *w)
196: {
197: struct cmd_find_state fs;
198:
199: cmd_find_from_session_window(&fs, s, w);
200: notify_add(name, &fs, NULL, s, w, NULL);
201: }
202:
203: void
204: notify_window(const char *name, struct window *w)
205: {
206: struct cmd_find_state fs;
207:
208: cmd_find_from_window(&fs, w);
209: notify_add(name, &fs, NULL, NULL, w, NULL);
210: }
211:
212: void
213: notify_pane(const char *name, struct window_pane *wp)
214: {
215: struct cmd_find_state fs;
216:
217: cmd_find_from_pane(&fs, wp);
218: notify_add(name, &fs, NULL, NULL, NULL, wp);
219: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>