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