blob: 75a16de935ae973a6d25eb51f45df1917a8bf2c1 [file] [log] [blame] [raw]
Nicholas Marriott46210342012-03-17 22:35:09 +00001/* $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
Nicholas Marriott5385a9b2012-07-13 06:27:41 +000019#include <sys/types.h>
20#include <sys/queue.h>
21
22#include <stdlib.h>
23
Nicholas Marriott46210342012-03-17 22:35:09 +000024#include "tmux.h"
25
Nicholas Marriott5385a9b2012-07-13 06:27:41 +000026enum 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
37struct 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};
46TAILQ_HEAD(, notify_entry) notify_queue = TAILQ_HEAD_INITIALIZER(notify_queue);
47int notify_enabled = 1;
48
49void notify_drain(void);
50void notify_add(enum notify_type, struct client *, struct session *,
51 struct window *);
52
Nicholas Marriott46210342012-03-17 22:35:09 +000053void
Nicholas Marriott5385a9b2012-07-13 06:27:41 +000054notify_enable(void)
Nicholas Marriott46210342012-03-17 22:35:09 +000055{
Nicholas Marriott5385a9b2012-07-13 06:27:41 +000056 notify_enabled = 1;
57 notify_drain();
Nicholas Marriott46210342012-03-17 22:35:09 +000058}
59
60void
Nicholas Marriott5385a9b2012-07-13 06:27:41 +000061notify_disable(void)
Nicholas Marriott46210342012-03-17 22:35:09 +000062{
Nicholas Marriott5385a9b2012-07-13 06:27:41 +000063 notify_enabled = 0;
Nicholas Marriott46210342012-03-17 22:35:09 +000064}
65
66void
Nicholas Marriott5385a9b2012-07-13 06:27:41 +000067notify_add(enum notify_type type, struct client *c, struct session *s,
68 struct window *w)
Nicholas Marriott46210342012-03-17 22:35:09 +000069{
Nicholas Marriott5385a9b2012-07-13 06:27:41 +000070 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(&notify_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++;
Nicholas Marriott46210342012-03-17 22:35:09 +000085}
86
87void
Nicholas Marriott5385a9b2012-07-13 06:27:41 +000088notify_drain(void)
Nicholas Marriott46210342012-03-17 22:35:09 +000089{
Nicholas Marriott5385a9b2012-07-13 06:27:41 +000090 struct notify_entry *ne, *ne1;
91
92 if (!notify_enabled)
93 return;
94
95 TAILQ_FOREACH_SAFE(ne, &notify_queue, entry, ne1) {
96 switch (ne->type) {
97 case NOTIFY_WINDOW_LAYOUT_CHANGED:
Nicholas Marriott9247c902012-09-03 09:32:38 +000098 control_notify_window_layout_changed(ne->window);
Nicholas Marriott5385a9b2012-07-13 06:27:41 +000099 break;
100 case NOTIFY_WINDOW_UNLINKED:
Nicholas Marriott9247c902012-09-03 09:32:38 +0000101 control_notify_window_unlinked(ne->session, ne->window);
Nicholas Marriott5385a9b2012-07-13 06:27:41 +0000102 break;
103 case NOTIFY_WINDOW_LINKED:
Nicholas Marriott9247c902012-09-03 09:32:38 +0000104 control_notify_window_linked(ne->session, ne->window);
Nicholas Marriott5385a9b2012-07-13 06:27:41 +0000105 break;
106 case NOTIFY_WINDOW_RENAMED:
Nicholas Marriott9247c902012-09-03 09:32:38 +0000107 control_notify_window_renamed(ne->window);
Nicholas Marriott5385a9b2012-07-13 06:27:41 +0000108 break;
109 case NOTIFY_ATTACHED_SESSION_CHANGED:
Nicholas Marriott9247c902012-09-03 09:32:38 +0000110 control_notify_attached_session_changed(ne->client);
Nicholas Marriott5385a9b2012-07-13 06:27:41 +0000111 break;
112 case NOTIFY_SESSION_RENAMED:
Nicholas Marriott9247c902012-09-03 09:32:38 +0000113 control_notify_session_renamed(ne->session);
Nicholas Marriott5385a9b2012-07-13 06:27:41 +0000114 break;
115 case NOTIFY_SESSION_CREATED:
Nicholas Marriott9247c902012-09-03 09:32:38 +0000116 control_notify_session_created(ne->session);
Nicholas Marriott5385a9b2012-07-13 06:27:41 +0000117 break;
118 case NOTIFY_SESSION_CLOSED:
Nicholas Marriott9247c902012-09-03 09:32:38 +0000119 control_notify_session_close(ne->session);
Nicholas Marriott5385a9b2012-07-13 06:27:41 +0000120 break;
121 }
122
123 if (ne->client != NULL)
124 ne->client->references--;
125 if (ne->session != NULL)
126 ne->session->references--;
127 if (ne->window != NULL)
Nicholas Marriott58e8e0e2012-08-21 10:00:33 +0000128 window_remove_ref(ne->window);
129
Nicholas Marriott5385a9b2012-07-13 06:27:41 +0000130 TAILQ_REMOVE(&notify_queue, ne, entry);
131 free(ne);
132 }
Nicholas Marriott46210342012-03-17 22:35:09 +0000133}
134
135void
Nicholas Marriott17bbf902012-09-25 07:41:22 +0000136notify_input(struct window_pane *wp, struct evbuffer *input)
137{
138 struct client *c;
139 u_int i;
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
148 for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
149 c = ARRAY_ITEM(&clients, i);
150 if (c != NULL && (c->flags & CLIENT_CONTROL))
151 control_notify_input(c, wp, input);
152 }
153}
154
155void
Nicholas Marriott5385a9b2012-07-13 06:27:41 +0000156notify_window_layout_changed(struct window *w)
Nicholas Marriott46210342012-03-17 22:35:09 +0000157{
Nicholas Marriott5385a9b2012-07-13 06:27:41 +0000158 notify_add(NOTIFY_WINDOW_LAYOUT_CHANGED, NULL, NULL, w);
159 notify_drain();
Nicholas Marriott46210342012-03-17 22:35:09 +0000160}
161
162void
Nicholas Marriott5385a9b2012-07-13 06:27:41 +0000163notify_window_unlinked(struct session *s, struct window *w)
Nicholas Marriott46210342012-03-17 22:35:09 +0000164{
Nicholas Marriott5385a9b2012-07-13 06:27:41 +0000165 notify_add(NOTIFY_WINDOW_UNLINKED, NULL, s, w);
166 notify_drain();
Nicholas Marriott46210342012-03-17 22:35:09 +0000167}
168
169void
Nicholas Marriott5385a9b2012-07-13 06:27:41 +0000170notify_window_linked(struct session *s, struct window *w)
Nicholas Marriott46210342012-03-17 22:35:09 +0000171{
Nicholas Marriott5385a9b2012-07-13 06:27:41 +0000172 notify_add(NOTIFY_WINDOW_LINKED, NULL, s, w);
173 notify_drain();
Nicholas Marriott46210342012-03-17 22:35:09 +0000174}
175
176void
Nicholas Marriott5385a9b2012-07-13 06:27:41 +0000177notify_window_renamed(struct window *w)
Nicholas Marriott46210342012-03-17 22:35:09 +0000178{
Nicholas Marriott5385a9b2012-07-13 06:27:41 +0000179 notify_add(NOTIFY_WINDOW_RENAMED, NULL, NULL, w);
180 notify_drain();
181}
182
183void
184notify_attached_session_changed(struct client *c)
185{
186 notify_add(NOTIFY_ATTACHED_SESSION_CHANGED, c, NULL, NULL);
187 notify_drain();
188}
189
190void
191notify_session_renamed(struct session *s)
192{
193 notify_add(NOTIFY_SESSION_RENAMED, NULL, s, NULL);
194 notify_drain();
195}
196
197void
198notify_session_created(struct session *s)
199{
200 notify_add(NOTIFY_SESSION_CREATED, NULL, s, NULL);
201 notify_drain();
202}
203
204void
205notify_session_closed(struct session *s)
206{
207 notify_add(NOTIFY_SESSION_CLOSED, NULL, s, NULL);
208 notify_drain();
Nicholas Marriott46210342012-03-17 22:35:09 +0000209}