1*0a6a1f1dSLionel Sambuc /* Id */
2*0a6a1f1dSLionel Sambuc
3*0a6a1f1dSLionel Sambuc /*
4*0a6a1f1dSLionel Sambuc * Copyright (c) 2012 George Nachman <tmux@georgester.com>
5*0a6a1f1dSLionel Sambuc *
6*0a6a1f1dSLionel Sambuc * Permission to use, copy, modify, and distribute this software for any
7*0a6a1f1dSLionel Sambuc * purpose with or without fee is hereby granted, provided that the above
8*0a6a1f1dSLionel Sambuc * copyright notice and this permission notice appear in all copies.
9*0a6a1f1dSLionel Sambuc *
10*0a6a1f1dSLionel Sambuc * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11*0a6a1f1dSLionel Sambuc * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12*0a6a1f1dSLionel Sambuc * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13*0a6a1f1dSLionel Sambuc * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14*0a6a1f1dSLionel Sambuc * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15*0a6a1f1dSLionel Sambuc * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16*0a6a1f1dSLionel Sambuc * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*0a6a1f1dSLionel Sambuc */
18*0a6a1f1dSLionel Sambuc
19*0a6a1f1dSLionel Sambuc #include <sys/types.h>
20*0a6a1f1dSLionel Sambuc
21*0a6a1f1dSLionel Sambuc #include <stdlib.h>
22*0a6a1f1dSLionel Sambuc
23*0a6a1f1dSLionel Sambuc #include "tmux.h"
24*0a6a1f1dSLionel Sambuc
25*0a6a1f1dSLionel Sambuc enum notify_type {
26*0a6a1f1dSLionel Sambuc NOTIFY_WINDOW_LAYOUT_CHANGED,
27*0a6a1f1dSLionel Sambuc NOTIFY_WINDOW_UNLINKED,
28*0a6a1f1dSLionel Sambuc NOTIFY_WINDOW_LINKED,
29*0a6a1f1dSLionel Sambuc NOTIFY_WINDOW_RENAMED,
30*0a6a1f1dSLionel Sambuc NOTIFY_ATTACHED_SESSION_CHANGED,
31*0a6a1f1dSLionel Sambuc NOTIFY_SESSION_RENAMED,
32*0a6a1f1dSLionel Sambuc NOTIFY_SESSION_CREATED,
33*0a6a1f1dSLionel Sambuc NOTIFY_SESSION_CLOSED
34*0a6a1f1dSLionel Sambuc };
35*0a6a1f1dSLionel Sambuc
36*0a6a1f1dSLionel Sambuc struct notify_entry {
37*0a6a1f1dSLionel Sambuc enum notify_type type;
38*0a6a1f1dSLionel Sambuc
39*0a6a1f1dSLionel Sambuc struct client *client;
40*0a6a1f1dSLionel Sambuc struct session *session;
41*0a6a1f1dSLionel Sambuc struct window *window;
42*0a6a1f1dSLionel Sambuc
43*0a6a1f1dSLionel Sambuc TAILQ_ENTRY(notify_entry) entry;
44*0a6a1f1dSLionel Sambuc };
45*0a6a1f1dSLionel Sambuc TAILQ_HEAD(, notify_entry) notify_queue = TAILQ_HEAD_INITIALIZER(notify_queue);
46*0a6a1f1dSLionel Sambuc int notify_enabled = 1;
47*0a6a1f1dSLionel Sambuc
48*0a6a1f1dSLionel Sambuc void notify_drain(void);
49*0a6a1f1dSLionel Sambuc void notify_add(enum notify_type, struct client *, struct session *,
50*0a6a1f1dSLionel Sambuc struct window *);
51*0a6a1f1dSLionel Sambuc
52*0a6a1f1dSLionel Sambuc void
notify_enable(void)53*0a6a1f1dSLionel Sambuc notify_enable(void)
54*0a6a1f1dSLionel Sambuc {
55*0a6a1f1dSLionel Sambuc notify_enabled = 1;
56*0a6a1f1dSLionel Sambuc notify_drain();
57*0a6a1f1dSLionel Sambuc }
58*0a6a1f1dSLionel Sambuc
59*0a6a1f1dSLionel Sambuc void
notify_disable(void)60*0a6a1f1dSLionel Sambuc notify_disable(void)
61*0a6a1f1dSLionel Sambuc {
62*0a6a1f1dSLionel Sambuc notify_enabled = 0;
63*0a6a1f1dSLionel Sambuc }
64*0a6a1f1dSLionel Sambuc
65*0a6a1f1dSLionel Sambuc void
notify_add(enum notify_type type,struct client * c,struct session * s,struct window * w)66*0a6a1f1dSLionel Sambuc notify_add(enum notify_type type, struct client *c, struct session *s,
67*0a6a1f1dSLionel Sambuc struct window *w)
68*0a6a1f1dSLionel Sambuc {
69*0a6a1f1dSLionel Sambuc struct notify_entry *ne;
70*0a6a1f1dSLionel Sambuc
71*0a6a1f1dSLionel Sambuc ne = xcalloc(1, sizeof *ne);
72*0a6a1f1dSLionel Sambuc ne->type = type;
73*0a6a1f1dSLionel Sambuc ne->client = c;
74*0a6a1f1dSLionel Sambuc ne->session = s;
75*0a6a1f1dSLionel Sambuc ne->window = w;
76*0a6a1f1dSLionel Sambuc TAILQ_INSERT_TAIL(¬ify_queue, ne, entry);
77*0a6a1f1dSLionel Sambuc
78*0a6a1f1dSLionel Sambuc if (c != NULL)
79*0a6a1f1dSLionel Sambuc c->references++;
80*0a6a1f1dSLionel Sambuc if (s != NULL)
81*0a6a1f1dSLionel Sambuc s->references++;
82*0a6a1f1dSLionel Sambuc if (w != NULL)
83*0a6a1f1dSLionel Sambuc w->references++;
84*0a6a1f1dSLionel Sambuc }
85*0a6a1f1dSLionel Sambuc
86*0a6a1f1dSLionel Sambuc void
notify_drain(void)87*0a6a1f1dSLionel Sambuc notify_drain(void)
88*0a6a1f1dSLionel Sambuc {
89*0a6a1f1dSLionel Sambuc struct notify_entry *ne, *ne1;
90*0a6a1f1dSLionel Sambuc
91*0a6a1f1dSLionel Sambuc if (!notify_enabled)
92*0a6a1f1dSLionel Sambuc return;
93*0a6a1f1dSLionel Sambuc
94*0a6a1f1dSLionel Sambuc TAILQ_FOREACH_SAFE(ne, ¬ify_queue, entry, ne1) {
95*0a6a1f1dSLionel Sambuc switch (ne->type) {
96*0a6a1f1dSLionel Sambuc case NOTIFY_WINDOW_LAYOUT_CHANGED:
97*0a6a1f1dSLionel Sambuc control_notify_window_layout_changed(ne->window);
98*0a6a1f1dSLionel Sambuc break;
99*0a6a1f1dSLionel Sambuc case NOTIFY_WINDOW_UNLINKED:
100*0a6a1f1dSLionel Sambuc control_notify_window_unlinked(ne->session, ne->window);
101*0a6a1f1dSLionel Sambuc break;
102*0a6a1f1dSLionel Sambuc case NOTIFY_WINDOW_LINKED:
103*0a6a1f1dSLionel Sambuc control_notify_window_linked(ne->session, ne->window);
104*0a6a1f1dSLionel Sambuc break;
105*0a6a1f1dSLionel Sambuc case NOTIFY_WINDOW_RENAMED:
106*0a6a1f1dSLionel Sambuc control_notify_window_renamed(ne->window);
107*0a6a1f1dSLionel Sambuc break;
108*0a6a1f1dSLionel Sambuc case NOTIFY_ATTACHED_SESSION_CHANGED:
109*0a6a1f1dSLionel Sambuc control_notify_attached_session_changed(ne->client);
110*0a6a1f1dSLionel Sambuc break;
111*0a6a1f1dSLionel Sambuc case NOTIFY_SESSION_RENAMED:
112*0a6a1f1dSLionel Sambuc control_notify_session_renamed(ne->session);
113*0a6a1f1dSLionel Sambuc break;
114*0a6a1f1dSLionel Sambuc case NOTIFY_SESSION_CREATED:
115*0a6a1f1dSLionel Sambuc control_notify_session_created(ne->session);
116*0a6a1f1dSLionel Sambuc break;
117*0a6a1f1dSLionel Sambuc case NOTIFY_SESSION_CLOSED:
118*0a6a1f1dSLionel Sambuc control_notify_session_close(ne->session);
119*0a6a1f1dSLionel Sambuc break;
120*0a6a1f1dSLionel Sambuc }
121*0a6a1f1dSLionel Sambuc
122*0a6a1f1dSLionel Sambuc if (ne->client != NULL)
123*0a6a1f1dSLionel Sambuc ne->client->references--;
124*0a6a1f1dSLionel Sambuc if (ne->session != NULL)
125*0a6a1f1dSLionel Sambuc ne->session->references--;
126*0a6a1f1dSLionel Sambuc if (ne->window != NULL)
127*0a6a1f1dSLionel Sambuc window_remove_ref(ne->window);
128*0a6a1f1dSLionel Sambuc
129*0a6a1f1dSLionel Sambuc TAILQ_REMOVE(¬ify_queue, ne, entry);
130*0a6a1f1dSLionel Sambuc free(ne);
131*0a6a1f1dSLionel Sambuc }
132*0a6a1f1dSLionel Sambuc }
133*0a6a1f1dSLionel Sambuc
134*0a6a1f1dSLionel Sambuc void
notify_input(struct window_pane * wp,struct evbuffer * input)135*0a6a1f1dSLionel Sambuc notify_input(struct window_pane *wp, struct evbuffer *input)
136*0a6a1f1dSLionel Sambuc {
137*0a6a1f1dSLionel Sambuc struct client *c;
138*0a6a1f1dSLionel Sambuc u_int i;
139*0a6a1f1dSLionel Sambuc
140*0a6a1f1dSLionel Sambuc /*
141*0a6a1f1dSLionel Sambuc * notify_input() is not queued and only does anything when
142*0a6a1f1dSLionel Sambuc * notifications are enabled.
143*0a6a1f1dSLionel Sambuc */
144*0a6a1f1dSLionel Sambuc if (!notify_enabled)
145*0a6a1f1dSLionel Sambuc return;
146*0a6a1f1dSLionel Sambuc
147*0a6a1f1dSLionel Sambuc for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
148*0a6a1f1dSLionel Sambuc c = ARRAY_ITEM(&clients, i);
149*0a6a1f1dSLionel Sambuc if (c != NULL && (c->flags & CLIENT_CONTROL))
150*0a6a1f1dSLionel Sambuc control_notify_input(c, wp, input);
151*0a6a1f1dSLionel Sambuc }
152*0a6a1f1dSLionel Sambuc }
153*0a6a1f1dSLionel Sambuc
154*0a6a1f1dSLionel Sambuc void
notify_window_layout_changed(struct window * w)155*0a6a1f1dSLionel Sambuc notify_window_layout_changed(struct window *w)
156*0a6a1f1dSLionel Sambuc {
157*0a6a1f1dSLionel Sambuc notify_add(NOTIFY_WINDOW_LAYOUT_CHANGED, NULL, NULL, w);
158*0a6a1f1dSLionel Sambuc notify_drain();
159*0a6a1f1dSLionel Sambuc }
160*0a6a1f1dSLionel Sambuc
161*0a6a1f1dSLionel Sambuc void
notify_window_unlinked(struct session * s,struct window * w)162*0a6a1f1dSLionel Sambuc notify_window_unlinked(struct session *s, struct window *w)
163*0a6a1f1dSLionel Sambuc {
164*0a6a1f1dSLionel Sambuc notify_add(NOTIFY_WINDOW_UNLINKED, NULL, s, w);
165*0a6a1f1dSLionel Sambuc notify_drain();
166*0a6a1f1dSLionel Sambuc }
167*0a6a1f1dSLionel Sambuc
168*0a6a1f1dSLionel Sambuc void
notify_window_linked(struct session * s,struct window * w)169*0a6a1f1dSLionel Sambuc notify_window_linked(struct session *s, struct window *w)
170*0a6a1f1dSLionel Sambuc {
171*0a6a1f1dSLionel Sambuc notify_add(NOTIFY_WINDOW_LINKED, NULL, s, w);
172*0a6a1f1dSLionel Sambuc notify_drain();
173*0a6a1f1dSLionel Sambuc }
174*0a6a1f1dSLionel Sambuc
175*0a6a1f1dSLionel Sambuc void
notify_window_renamed(struct window * w)176*0a6a1f1dSLionel Sambuc notify_window_renamed(struct window *w)
177*0a6a1f1dSLionel Sambuc {
178*0a6a1f1dSLionel Sambuc notify_add(NOTIFY_WINDOW_RENAMED, NULL, NULL, w);
179*0a6a1f1dSLionel Sambuc notify_drain();
180*0a6a1f1dSLionel Sambuc }
181*0a6a1f1dSLionel Sambuc
182*0a6a1f1dSLionel Sambuc void
notify_attached_session_changed(struct client * c)183*0a6a1f1dSLionel Sambuc notify_attached_session_changed(struct client *c)
184*0a6a1f1dSLionel Sambuc {
185*0a6a1f1dSLionel Sambuc notify_add(NOTIFY_ATTACHED_SESSION_CHANGED, c, NULL, NULL);
186*0a6a1f1dSLionel Sambuc notify_drain();
187*0a6a1f1dSLionel Sambuc }
188*0a6a1f1dSLionel Sambuc
189*0a6a1f1dSLionel Sambuc void
notify_session_renamed(struct session * s)190*0a6a1f1dSLionel Sambuc notify_session_renamed(struct session *s)
191*0a6a1f1dSLionel Sambuc {
192*0a6a1f1dSLionel Sambuc notify_add(NOTIFY_SESSION_RENAMED, NULL, s, NULL);
193*0a6a1f1dSLionel Sambuc notify_drain();
194*0a6a1f1dSLionel Sambuc }
195*0a6a1f1dSLionel Sambuc
196*0a6a1f1dSLionel Sambuc void
notify_session_created(struct session * s)197*0a6a1f1dSLionel Sambuc notify_session_created(struct session *s)
198*0a6a1f1dSLionel Sambuc {
199*0a6a1f1dSLionel Sambuc notify_add(NOTIFY_SESSION_CREATED, NULL, s, NULL);
200*0a6a1f1dSLionel Sambuc notify_drain();
201*0a6a1f1dSLionel Sambuc }
202*0a6a1f1dSLionel Sambuc
203*0a6a1f1dSLionel Sambuc void
notify_session_closed(struct session * s)204*0a6a1f1dSLionel Sambuc notify_session_closed(struct session *s)
205*0a6a1f1dSLionel Sambuc {
206*0a6a1f1dSLionel Sambuc notify_add(NOTIFY_SESSION_CLOSED, NULL, s, NULL);
207*0a6a1f1dSLionel Sambuc notify_drain();
208*0a6a1f1dSLionel Sambuc }
209