Annotation of src/usr.bin/tmux/notify.c, Revision 1.9
1.9 ! nicm 1: /* $OpenBSD: notify.c,v 1.8 2015/06/05 18:18:32 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:
37: struct notify_entry {
38: enum notify_type type;
39:
40: struct client *client;
41: struct session *session;
42: struct window *window;
43:
44: TAILQ_ENTRY(notify_entry) entry;
45: };
1.9 ! nicm 46: TAILQ_HEAD(notify_queue, notify_entry);
! 47: static struct notify_queue notify_queue = TAILQ_HEAD_INITIALIZER(notify_queue);
! 48: static int notify_enabled = 1;
! 49:
! 50: static void notify_drain(void);
! 51: static void notify_add(enum notify_type, struct client *, struct session *,
! 52: struct window *);
1.2 nicm 53:
54: void
55: notify_enable(void)
56: {
57: notify_enabled = 1;
58: notify_drain();
59: }
60:
61: void
62: notify_disable(void)
63: {
64: notify_enabled = 0;
65: }
66:
1.9 ! nicm 67: static void
1.2 nicm 68: notify_add(enum notify_type type, struct client *c, struct session *s,
69: struct window *w)
70: {
71: struct notify_entry *ne;
72:
73: ne = xcalloc(1, sizeof *ne);
74: ne->type = type;
75: ne->client = c;
76: ne->session = s;
77: ne->window = w;
78: TAILQ_INSERT_TAIL(¬ify_queue, ne, entry);
79:
80: if (c != NULL)
81: c->references++;
82: if (s != NULL)
83: s->references++;
84: if (w != NULL)
85: w->references++;
86: }
87:
1.9 ! nicm 88: static void
1.2 nicm 89: notify_drain(void)
90: {
91: struct notify_entry *ne, *ne1;
92:
93: if (!notify_enabled)
94: return;
95:
96: TAILQ_FOREACH_SAFE(ne, ¬ify_queue, entry, ne1) {
97: switch (ne->type) {
98: case NOTIFY_WINDOW_LAYOUT_CHANGED:
1.4 nicm 99: control_notify_window_layout_changed(ne->window);
1.2 nicm 100: break;
101: case NOTIFY_WINDOW_UNLINKED:
1.4 nicm 102: control_notify_window_unlinked(ne->session, ne->window);
1.2 nicm 103: break;
104: case NOTIFY_WINDOW_LINKED:
1.4 nicm 105: control_notify_window_linked(ne->session, ne->window);
1.2 nicm 106: break;
107: case NOTIFY_WINDOW_RENAMED:
1.4 nicm 108: control_notify_window_renamed(ne->window);
1.2 nicm 109: break;
110: case NOTIFY_ATTACHED_SESSION_CHANGED:
1.4 nicm 111: control_notify_attached_session_changed(ne->client);
1.2 nicm 112: break;
113: case NOTIFY_SESSION_RENAMED:
1.4 nicm 114: control_notify_session_renamed(ne->session);
1.2 nicm 115: break;
116: case NOTIFY_SESSION_CREATED:
1.4 nicm 117: control_notify_session_created(ne->session);
1.2 nicm 118: break;
119: case NOTIFY_SESSION_CLOSED:
1.4 nicm 120: control_notify_session_close(ne->session);
1.2 nicm 121: break;
122: }
123:
124: if (ne->client != NULL)
1.7 nicm 125: server_client_unref(ne->client);
1.2 nicm 126: if (ne->session != NULL)
1.8 nicm 127: session_unref(ne->session);
1.2 nicm 128: if (ne->window != NULL)
1.3 nicm 129: window_remove_ref(ne->window);
130:
1.2 nicm 131: TAILQ_REMOVE(¬ify_queue, ne, entry);
132: free(ne);
1.5 nicm 133: }
134: }
135:
136: void
137: notify_input(struct window_pane *wp, struct evbuffer *input)
138: {
139: struct client *c;
140:
141: /*
142: * notify_input() is not queued and only does anything when
143: * notifications are enabled.
144: */
145: if (!notify_enabled)
146: return;
147:
1.6 nicm 148: TAILQ_FOREACH(c, &clients, entry) {
149: if (c->flags & CLIENT_CONTROL)
1.5 nicm 150: control_notify_input(c, wp, input);
1.2 nicm 151: }
152: }
153:
1.1 nicm 154: void
1.2 nicm 155: notify_window_layout_changed(struct window *w)
1.1 nicm 156: {
1.2 nicm 157: notify_add(NOTIFY_WINDOW_LAYOUT_CHANGED, NULL, NULL, w);
158: notify_drain();
1.1 nicm 159: }
160:
161: void
1.2 nicm 162: notify_window_unlinked(struct session *s, struct window *w)
1.1 nicm 163: {
1.2 nicm 164: notify_add(NOTIFY_WINDOW_UNLINKED, NULL, s, w);
165: notify_drain();
1.1 nicm 166: }
167:
168: void
1.2 nicm 169: notify_window_linked(struct session *s, struct window *w)
1.1 nicm 170: {
1.2 nicm 171: notify_add(NOTIFY_WINDOW_LINKED, NULL, s, w);
172: notify_drain();
1.1 nicm 173: }
174:
175: void
1.2 nicm 176: notify_window_renamed(struct window *w)
1.1 nicm 177: {
1.2 nicm 178: notify_add(NOTIFY_WINDOW_RENAMED, NULL, NULL, w);
179: notify_drain();
1.1 nicm 180: }
181:
182: void
1.2 nicm 183: notify_attached_session_changed(struct client *c)
1.1 nicm 184: {
1.2 nicm 185: notify_add(NOTIFY_ATTACHED_SESSION_CHANGED, c, NULL, NULL);
186: notify_drain();
1.1 nicm 187: }
188:
189: void
1.2 nicm 190: notify_session_renamed(struct session *s)
1.1 nicm 191: {
1.2 nicm 192: notify_add(NOTIFY_SESSION_RENAMED, NULL, s, NULL);
193: notify_drain();
1.1 nicm 194: }
195:
196: void
1.2 nicm 197: notify_session_created(struct session *s)
1.1 nicm 198: {
1.2 nicm 199: notify_add(NOTIFY_SESSION_CREATED, NULL, s, NULL);
200: notify_drain();
1.1 nicm 201: }
202:
203: void
1.2 nicm 204: notify_session_closed(struct session *s)
1.1 nicm 205: {
1.2 nicm 206: notify_add(NOTIFY_SESSION_CLOSED, NULL, s, NULL);
207: notify_drain();
1.1 nicm 208: }