Annotation of src/usr.bin/tmux/notify.c, Revision 1.16
1.16 ! nicm 1: /* $OpenBSD: notify.c,v 1.15 2016/10/16 19:15:02 nicm Exp $ */
1.1 nicm 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:
1.2 nicm 19: #include <sys/types.h>
20: #include <sys/queue.h>
21:
22: #include <stdlib.h>
23:
1.1 nicm 24: #include "tmux.h"
25:
1.2 nicm 26: enum notify_type {
27: NOTIFY_WINDOW_LAYOUT_CHANGED,
28: NOTIFY_WINDOW_UNLINKED,
29: NOTIFY_WINDOW_LINKED,
30: NOTIFY_WINDOW_RENAMED,
31: NOTIFY_ATTACHED_SESSION_CHANGED,
32: NOTIFY_SESSION_RENAMED,
33: NOTIFY_SESSION_CREATED,
34: NOTIFY_SESSION_CLOSED
35: };
36:
1.11 nicm 37: static const char *notify_hooks[] = {
38: "window-layout-changed",
39: NULL, /* "window-unlinked", */
40: NULL, /* "window-linked", */
41: "window-renamed",
42: NULL, /* "attached-session-changed", */
43: "session-renamed",
44: NULL, /* "session-created", */
45: NULL, /* "session-closed" */
46: };
47:
1.2 nicm 48: struct notify_entry {
49: enum notify_type type;
50:
51: struct client *client;
52: struct session *session;
53: struct window *window;
54: };
55:
1.9 nicm 56: static void
1.15 nicm 57: notify_hook(struct cmdq_item *item, struct notify_entry *ne)
1.11 nicm 58: {
59: const char *name;
60: struct cmd_find_state fs;
61: struct hook *hook;
1.16 ! nicm 62: struct cmdq_item *new_item;
1.11 nicm 63:
64: name = notify_hooks[ne->type];
65: if (name == NULL)
66: return;
67:
68: cmd_find_clear_state(&fs, NULL, 0);
69: if (ne->session != NULL && ne->window != NULL)
70: cmd_find_from_session_window(&fs, ne->session, ne->window);
71: else if (ne->window != NULL)
72: cmd_find_from_window(&fs, ne->window);
73: else if (ne->session != NULL)
74: cmd_find_from_session(&fs, ne->session);
1.15 nicm 75: else
76: cmd_find_current(&fs, item, CMD_FIND_QUIET);
1.11 nicm 77: if (cmd_find_empty_state(&fs) || !cmd_find_valid_state(&fs))
78: return;
79:
80: hook = hooks_find(fs.s->hooks, name);
81: if (hook == NULL)
82: return;
83: log_debug("notify hook %s", name);
84:
1.14 nicm 85: new_item = cmdq_get_command(hook->cmdlist, &fs, NULL, CMDQ_NOHOOKS);
1.16 ! nicm 86: cmdq_format(new_item, "hook", "%s", name);
1.15 nicm 87: cmdq_insert_after(item, new_item);
88: }
89:
90: static enum cmd_retval
91: notify_callback(struct cmdq_item *item, void *data)
92: {
93: struct notify_entry *ne = data;
94:
95: switch (ne->type) {
96: case NOTIFY_WINDOW_LAYOUT_CHANGED:
97: control_notify_window_layout_changed(ne->window);
98: break;
99: case NOTIFY_WINDOW_UNLINKED:
100: control_notify_window_unlinked(ne->session, ne->window);
101: break;
102: case NOTIFY_WINDOW_LINKED:
103: control_notify_window_linked(ne->session, ne->window);
104: break;
105: case NOTIFY_WINDOW_RENAMED:
106: control_notify_window_renamed(ne->window);
107: break;
108: case NOTIFY_ATTACHED_SESSION_CHANGED:
109: control_notify_attached_session_changed(ne->client);
110: break;
111: case NOTIFY_SESSION_RENAMED:
112: control_notify_session_renamed(ne->session);
113: break;
114: case NOTIFY_SESSION_CREATED:
115: control_notify_session_created(ne->session);
116: break;
117: case NOTIFY_SESSION_CLOSED:
118: control_notify_session_closed(ne->session);
119: break;
120: }
121: notify_hook(item, ne);
122:
123: if (ne->client != NULL)
124: server_client_unref(ne->client);
125: if (ne->session != NULL)
126: session_unref(ne->session);
127: if (ne->window != NULL)
128: window_remove_ref(ne->window);
129: free(ne);
130:
131: return (CMD_RETURN_NORMAL);
1.11 nicm 132: }
133:
134: static void
1.2 nicm 135: notify_add(enum notify_type type, struct client *c, struct session *s,
136: struct window *w)
137: {
138: struct notify_entry *ne;
1.15 nicm 139: struct cmdq_item *new_item;
1.2 nicm 140:
141: ne = xcalloc(1, sizeof *ne);
142: ne->type = type;
143: ne->client = c;
144: ne->session = s;
145: ne->window = w;
146:
147: if (c != NULL)
148: c->references++;
149: if (s != NULL)
150: s->references++;
151: if (w != NULL)
152: w->references++;
153:
1.15 nicm 154: new_item = cmdq_get_callback(notify_callback, ne);
155: cmdq_append(NULL, new_item);
1.5 nicm 156: }
157:
158: void
159: notify_input(struct window_pane *wp, struct evbuffer *input)
160: {
161: struct client *c;
162:
1.6 nicm 163: TAILQ_FOREACH(c, &clients, entry) {
164: if (c->flags & CLIENT_CONTROL)
1.5 nicm 165: control_notify_input(c, wp, input);
1.2 nicm 166: }
167: }
168:
1.1 nicm 169: void
1.2 nicm 170: notify_window_layout_changed(struct window *w)
1.1 nicm 171: {
1.2 nicm 172: notify_add(NOTIFY_WINDOW_LAYOUT_CHANGED, NULL, NULL, w);
1.1 nicm 173: }
174:
175: void
1.2 nicm 176: notify_window_unlinked(struct session *s, struct window *w)
1.1 nicm 177: {
1.2 nicm 178: notify_add(NOTIFY_WINDOW_UNLINKED, NULL, s, w);
1.1 nicm 179: }
180:
181: void
1.2 nicm 182: notify_window_linked(struct session *s, struct window *w)
1.1 nicm 183: {
1.2 nicm 184: notify_add(NOTIFY_WINDOW_LINKED, NULL, s, w);
1.1 nicm 185: }
186:
187: void
1.2 nicm 188: notify_window_renamed(struct window *w)
1.1 nicm 189: {
1.2 nicm 190: notify_add(NOTIFY_WINDOW_RENAMED, NULL, NULL, w);
1.1 nicm 191: }
192:
193: void
1.2 nicm 194: notify_attached_session_changed(struct client *c)
1.1 nicm 195: {
1.2 nicm 196: notify_add(NOTIFY_ATTACHED_SESSION_CHANGED, c, NULL, NULL);
1.1 nicm 197: }
198:
199: void
1.2 nicm 200: notify_session_renamed(struct session *s)
1.1 nicm 201: {
1.2 nicm 202: notify_add(NOTIFY_SESSION_RENAMED, NULL, s, NULL);
1.1 nicm 203: }
204:
205: void
1.2 nicm 206: notify_session_created(struct session *s)
1.1 nicm 207: {
1.2 nicm 208: notify_add(NOTIFY_SESSION_CREATED, NULL, s, NULL);
1.1 nicm 209: }
210:
211: void
1.2 nicm 212: notify_session_closed(struct session *s)
1.1 nicm 213: {
1.2 nicm 214: notify_add(NOTIFY_SESSION_CLOSED, NULL, s, NULL);
1.1 nicm 215: }