xref: /minix3/external/bsd/tmux/dist/notify.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
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(&notify_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, &notify_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(&notify_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