GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/tmux/notify.c Lines: 0 63 0.0 %
Date: 2016-12-06 Branches: 0 33 0.0 %

Line Branch Exec Source
1
/* $OpenBSD: notify.c,v 1.8 2015/06/05 18:18:32 nicm Exp $ */
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
19
#include <sys/types.h>
20
#include <sys/queue.h>
21
22
#include <stdlib.h>
23
24
#include "tmux.h"
25
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(&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++;
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, &notify_queue, entry, ne1) {
96
		switch (ne->type) {
97
		case NOTIFY_WINDOW_LAYOUT_CHANGED:
98
			control_notify_window_layout_changed(ne->window);
99
			break;
100
		case NOTIFY_WINDOW_UNLINKED:
101
			control_notify_window_unlinked(ne->session, ne->window);
102
			break;
103
		case NOTIFY_WINDOW_LINKED:
104
			control_notify_window_linked(ne->session, ne->window);
105
			break;
106
		case NOTIFY_WINDOW_RENAMED:
107
			control_notify_window_renamed(ne->window);
108
			break;
109
		case NOTIFY_ATTACHED_SESSION_CHANGED:
110
			control_notify_attached_session_changed(ne->client);
111
			break;
112
		case NOTIFY_SESSION_RENAMED:
113
			control_notify_session_renamed(ne->session);
114
			break;
115
		case NOTIFY_SESSION_CREATED:
116
			control_notify_session_created(ne->session);
117
			break;
118
		case NOTIFY_SESSION_CLOSED:
119
			control_notify_session_close(ne->session);
120
			break;
121
		}
122
123
		if (ne->client != NULL)
124
			server_client_unref(ne->client);
125
		if (ne->session != NULL)
126
			session_unref(ne->session);
127
		if (ne->window != NULL)
128
			window_remove_ref(ne->window);
129
130
		TAILQ_REMOVE(&notify_queue, ne, entry);
131
		free(ne);
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
147
	TAILQ_FOREACH(c, &clients, entry) {
148
		if (c->flags & CLIENT_CONTROL)
149
			control_notify_input(c, wp, input);
150
	}
151
}
152
153
void
154
notify_window_layout_changed(struct window *w)
155
{
156
	notify_add(NOTIFY_WINDOW_LAYOUT_CHANGED, NULL, NULL, w);
157
	notify_drain();
158
}
159
160
void
161
notify_window_unlinked(struct session *s, struct window *w)
162
{
163
	notify_add(NOTIFY_WINDOW_UNLINKED, NULL, s, w);
164
	notify_drain();
165
}
166
167
void
168
notify_window_linked(struct session *s, struct window *w)
169
{
170
	notify_add(NOTIFY_WINDOW_LINKED, NULL, s, w);
171
	notify_drain();
172
}
173
174
void
175
notify_window_renamed(struct window *w)
176
{
177
	notify_add(NOTIFY_WINDOW_RENAMED, NULL, NULL, w);
178
	notify_drain();
179
}
180
181
void
182
notify_attached_session_changed(struct client *c)
183
{
184
	notify_add(NOTIFY_ATTACHED_SESSION_CHANGED, c, NULL, NULL);
185
	notify_drain();
186
}
187
188
void
189
notify_session_renamed(struct session *s)
190
{
191
	notify_add(NOTIFY_SESSION_RENAMED, NULL, s, NULL);
192
	notify_drain();
193
}
194
195
void
196
notify_session_created(struct session *s)
197
{
198
	notify_add(NOTIFY_SESSION_CREATED, NULL, s, NULL);
199
	notify_drain();
200
}
201
202
void
203
notify_session_closed(struct session *s)
204
{
205
	notify_add(NOTIFY_SESSION_CLOSED, NULL, s, NULL);
206
	notify_drain();
207
}