Mercurial > audlegacy
annotate audacious/controlsocket.c @ 1938:1d9c1026d9f8 trunk
[svn] - DoubleSize support.
This has bugs, the most notable one being that DoubleSize only works
right if you restart the player.
The second bug is rather obvious too. No osmosis skinengine. No
TinyPlayer. Classic-esque skinengine only. This is because the
doublesize algorithm hates you and wants you to go die in a fire.
author | nenolod |
---|---|
date | Sun, 05 Nov 2006 04:43:16 -0800 |
parents | 6cbb9360e8e2 |
children | 0985452d1962 |
rev | line source |
---|---|
0 | 1 /* BMP - Cross-platform multimedia player |
2 * Copyright (C) 2003-2004 BMP development team. | |
3 * | |
4 * Based on XMMS: | |
5 * Copyright (C) 1998-2003 XMMS development team. | |
6 * | |
7 * This program is free software; you can redistribute it and/or modify | |
8 * it under the terms of the GNU General Public License as published by | |
9 * the Free Software Foundation; either version 2 of the License, or | |
10 * (at your option) any later version. | |
11 * | |
12 * This program is distributed in the hope that it will be useful, | |
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 * GNU General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU General Public License | |
18 * along with this program; if not, write to the Free Software | |
1459 | 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
0 | 20 */ |
21 | |
22 #include "controlsocket.h" | |
23 | |
24 #include <glib.h> | |
25 #include <stdlib.h> | |
26 #include <string.h> | |
27 | |
28 #include <unistd.h> | |
29 #include <errno.h> | |
30 #include <sys/time.h> | |
31 #include <sys/types.h> | |
32 #include <sys/socket.h> | |
33 #include <sys/un.h> | |
1444
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
34 #include <arpa/inet.h> |
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
35 #include <netdb.h> |
1583 | 36 #include <netinet/in.h> |
37 #include <unistd.h> | |
38 #include <grp.h> | |
39 #include <sys/time.h> | |
40 #include <sys/wait.h> | |
41 #include <sys/resource.h> | |
42 #include <sys/socket.h> | |
43 #include <fcntl.h> | |
44 #include <arpa/inet.h> | |
0 | 45 |
46 #include "main.h" | |
1653 | 47 #include "equalizer.h" |
48 #include "mainwin.h" | |
0 | 49 #include "input.h" |
538
e4e897d20791
[svn] remove libaudcore, we never did anything with it
nenolod
parents:
383
diff
changeset
|
50 #include "playback.h" |
0 | 51 #include "playlist.h" |
1653 | 52 #include "ui_playlist.h" |
0 | 53 #include "prefswin.h" |
54 #include "libaudacious/beepctrl.h" | |
55 | |
56 #define CTRLSOCKET_BACKLOG 100 | |
57 #define CTRLSOCKET_TIMEOUT 100000 | |
58 | |
59 | |
60 static gint session_id = 0; | |
61 | |
62 static gint ctrl_fd = 0; | |
63 static gchar *socket_name = NULL; | |
64 | |
65 static gpointer ctrlsocket_func(gpointer); | |
66 static GThread *ctrlsocket_thread; | |
67 | |
68 static GList *packet_list = NULL; | |
69 static GMutex *packet_list_mutex = NULL; | |
70 | |
71 static gboolean started = FALSE; | |
72 static gboolean going = TRUE; | |
73 static GCond *start_cond = NULL; | |
74 static GMutex *status_mutex = NULL; | |
75 | |
76 | |
77 static void | |
78 ctrlsocket_start_thread(void) | |
79 { | |
80 start_cond = g_cond_new(); | |
81 status_mutex = g_mutex_new(); | |
82 packet_list_mutex = g_mutex_new(); | |
83 | |
84 ctrlsocket_thread = g_thread_create(ctrlsocket_func, NULL, TRUE, NULL); | |
85 } | |
86 | |
87 gboolean | |
88 ctrlsocket_setup(void) | |
89 { | |
1761
70caa62ead63
[svn] - fix for "bmp_rcfile_write_string: assertion `value != NULL' failed"
yaz
parents:
1653
diff
changeset
|
90 if (strcmp(cfg.session_uri_base, "")) |
70caa62ead63
[svn] - fix for "bmp_rcfile_write_string: assertion `value != NULL' failed"
yaz
parents:
1653
diff
changeset
|
91 audacious_set_session_uri(cfg.session_uri_base); |
70caa62ead63
[svn] - fix for "bmp_rcfile_write_string: assertion `value != NULL' failed"
yaz
parents:
1653
diff
changeset
|
92 else |
70caa62ead63
[svn] - fix for "bmp_rcfile_write_string: assertion `value != NULL' failed"
yaz
parents:
1653
diff
changeset
|
93 return ctrlsocket_setup_unix(); |
1453 | 94 |
95 if (!g_strncasecmp(cfg.session_uri_base, "tcp://", 6)) | |
1444
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
96 return ctrlsocket_setup_tcp(); |
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
97 |
1443 | 98 return ctrlsocket_setup_unix(); |
99 } | |
100 | |
101 gboolean | |
102 ctrlsocket_setup_unix(void) | |
103 { | |
0 | 104 struct sockaddr_un saddr; |
105 gint i; | |
106 gint fd; | |
107 | |
1456
6fe7ba6e5489
[svn] - Don't poll the config database if not using TCP sockets.
nhjm449
parents:
1454
diff
changeset
|
108 audacious_set_session_type((gint *) AUDACIOUS_TYPE_UNIX); |
6fe7ba6e5489
[svn] - Don't poll the config database if not using TCP sockets.
nhjm449
parents:
1454
diff
changeset
|
109 |
0 | 110 if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { |
111 g_critical("ctrlsocket_setup(): Failed to open socket: %s", | |
112 strerror(errno)); | |
113 return FALSE; | |
114 } | |
115 | |
116 for (i = 0;; i++) { | |
117 saddr.sun_family = AF_UNIX; | |
118 g_snprintf(saddr.sun_path, sizeof(saddr.sun_path), | |
119 "%s/%s_%s.%d", g_get_tmp_dir(), | |
120 CTRLSOCKET_NAME, g_get_user_name(), i); | |
121 | |
122 if (xmms_remote_is_running(i)) { | |
123 if (cfg.allow_multiple_instances) | |
124 continue; | |
125 break; | |
126 } | |
127 | |
128 if ((unlink(saddr.sun_path) == -1) && errno != ENOENT) { | |
129 g_critical | |
130 ("ctrlsocket_setup(): Failed to unlink %s (Error: %s)", | |
131 saddr.sun_path, strerror(errno)); | |
132 break; | |
133 } | |
134 | |
135 if (bind(fd, (struct sockaddr *) &saddr, sizeof(saddr)) == -1) { | |
136 g_critical | |
137 ("ctrlsocket_setup(): Failed to assign %s to a socket (Error: %s)", | |
138 saddr.sun_path, strerror(errno)); | |
139 break; | |
140 } | |
141 | |
142 listen(fd, CTRLSOCKET_BACKLOG); | |
143 | |
144 socket_name = g_strdup(saddr.sun_path); | |
145 ctrl_fd = fd; | |
146 session_id = i; | |
147 going = TRUE; | |
148 | |
149 ctrlsocket_start_thread(); | |
150 | |
151 return TRUE; | |
152 } | |
153 | |
154 close(fd); | |
155 | |
156 return FALSE; | |
157 } | |
158 | |
1444
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
159 gboolean |
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
160 ctrlsocket_setup_tcp(void) |
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
161 { |
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
162 struct sockaddr_in saddr; |
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
163 gint i; |
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
164 gint fd; |
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
165 |
1456
6fe7ba6e5489
[svn] - Don't poll the config database if not using TCP sockets.
nhjm449
parents:
1454
diff
changeset
|
166 audacious_set_session_type((gint *) AUDACIOUS_TYPE_TCP); |
6fe7ba6e5489
[svn] - Don't poll the config database if not using TCP sockets.
nhjm449
parents:
1454
diff
changeset
|
167 |
1444
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
168 if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { |
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
169 g_critical("ctrlsocket_setup(): Failed to open socket: %s", |
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
170 strerror(errno)); |
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
171 return FALSE; |
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
172 } |
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
173 |
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
174 for (i = 0;; i++) { |
1454 | 175 memset(&saddr, '\0', sizeof(saddr)); |
1444
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
176 saddr.sin_family = AF_INET; |
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
177 saddr.sin_port = htons(37370 + i); |
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
178 |
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
179 if (xmms_remote_is_running(i)) { |
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
180 if (cfg.allow_multiple_instances) |
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
181 continue; |
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
182 break; |
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
183 } |
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
184 |
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
185 if (bind(fd, (struct sockaddr *) &saddr, sizeof(saddr)) == -1) { |
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
186 g_critical |
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
187 ("ctrlsocket_setup(): Failed to bind the socket (Error: %s)", |
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
188 strerror(errno)); |
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
189 break; |
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
190 } |
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
191 |
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
192 listen(fd, CTRLSOCKET_BACKLOG); |
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
193 |
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
194 ctrl_fd = fd; |
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
195 session_id = i; |
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
196 going = TRUE; |
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
197 |
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
198 ctrlsocket_start_thread(); |
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
199 |
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
200 return TRUE; |
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
201 } |
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
202 |
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
203 close(fd); |
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
204 |
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
205 return FALSE; |
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
206 } |
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
207 |
0 | 208 gint |
209 ctrlsocket_get_session_id(void) | |
210 { | |
211 return session_id; | |
212 } | |
213 | |
214 void | |
215 ctrlsocket_cleanup(void) | |
216 { | |
217 if (ctrl_fd) { | |
218 g_mutex_lock(status_mutex); | |
219 going = FALSE; | |
220 g_cond_signal(start_cond); | |
221 g_mutex_unlock(status_mutex); | |
222 | |
223 /* wait for ctrlsocket_thread to terminate */ | |
224 g_thread_join(ctrlsocket_thread); | |
225 | |
226 /* close and remove socket */ | |
227 close(ctrl_fd); | |
228 ctrl_fd = 0; | |
1444
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
229 |
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
230 if (socket_name != NULL) |
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
231 { |
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
232 unlink(socket_name); |
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
233 g_free(socket_name); |
c04ce16b2b57
[svn] - libaudacious/beepctrl.c: optimise further and be more paranoid about leaks
nenolod
parents:
1443
diff
changeset
|
234 } |
0 | 235 |
236 g_cond_free(start_cond); | |
237 g_mutex_free(status_mutex); | |
238 g_mutex_free(packet_list_mutex); | |
239 } | |
240 } | |
241 | |
242 void | |
243 ctrlsocket_start(void) | |
244 { | |
245 /* tell control socket thread to go 'live' i.e. start handling | |
246 * packets */ | |
247 g_mutex_lock(status_mutex); | |
248 started = TRUE; | |
249 g_cond_signal(start_cond); | |
250 g_mutex_unlock(status_mutex); | |
251 } | |
252 | |
253 static void | |
254 ctrl_write_packet(gint fd, gpointer data, gint length) | |
255 { | |
256 ServerPktHeader pkthdr; | |
257 | |
1766
6cbb9360e8e2
[svn] - always zero-out stack variables, as stack memory may be dirty on x86 and friends
nenolod
parents:
1761
diff
changeset
|
258 memset(&pkthdr, '\0', sizeof(ServerPktHeader)); |
6cbb9360e8e2
[svn] - always zero-out stack variables, as stack memory may be dirty on x86 and friends
nenolod
parents:
1761
diff
changeset
|
259 |
0 | 260 pkthdr.version = XMMS_PROTOCOL_VERSION; |
261 pkthdr.data_length = length; | |
1582
d7af2755a397
[svn] - gcc 4.1.0, 4.1.1, 4.1.2 tree optimization workaround:
nenolod
parents:
1580
diff
changeset
|
262 if ((size_t)write(fd, &pkthdr, sizeof(ServerPktHeader)) < sizeof(pkthdr)) |
0 | 263 return; |
264 if (data && length > 0) | |
1582
d7af2755a397
[svn] - gcc 4.1.0, 4.1.1, 4.1.2 tree optimization workaround:
nenolod
parents:
1580
diff
changeset
|
265 write(fd, data, length); |
0 | 266 } |
267 | |
268 static void | |
269 ctrl_write_gint(gint fd, gint val) | |
270 { | |
271 ctrl_write_packet(fd, &val, sizeof(gint)); | |
272 } | |
273 | |
274 static void | |
275 ctrl_write_gfloat(gint fd, gfloat val) | |
276 { | |
277 ctrl_write_packet(fd, &val, sizeof(gfloat)); | |
278 } | |
279 | |
280 static void | |
281 ctrl_write_gboolean(gint fd, gboolean bool) | |
282 { | |
283 ctrl_write_packet(fd, &bool, sizeof(gboolean)); | |
284 } | |
285 | |
286 static void | |
287 ctrl_write_string(gint fd, gchar * string) | |
288 { | |
289 ctrl_write_packet(fd, string, string ? strlen(string) + 1 : 0); | |
290 } | |
291 | |
292 static void | |
293 ctrl_ack_packet(PacketNode * pkt) | |
294 { | |
295 ctrl_write_packet(pkt->fd, NULL, 0); | |
296 close(pkt->fd); | |
297 if (pkt->data) | |
298 g_free(pkt->data); | |
299 g_free(pkt); | |
300 } | |
301 | |
302 static gboolean | |
303 ctrlsocket_is_going(void) | |
304 { | |
305 gboolean result; | |
306 | |
307 g_mutex_lock(status_mutex); | |
308 result = going; | |
309 g_mutex_unlock(status_mutex); | |
310 | |
311 return result; | |
312 } | |
313 | |
314 static gpointer | |
315 ctrlsocket_func(gpointer arg) | |
316 { | |
317 fd_set set; | |
318 struct timeval tv; | |
319 struct sockaddr_un saddr; | |
320 gint fd, b, i; | |
377 | 321 gint info[3]; |
0 | 322 gint32 v[2]; |
323 PacketNode *pkt; | |
324 socklen_t len; | |
325 gfloat fval[11]; | |
326 | |
327 g_mutex_lock(status_mutex); | |
328 while (!started && going) | |
329 g_cond_wait(start_cond, status_mutex); | |
330 g_mutex_unlock(status_mutex); | |
331 | |
332 while (ctrlsocket_is_going()) { | |
333 FD_ZERO(&set); | |
334 FD_SET(ctrl_fd, &set); | |
335 tv.tv_sec = 0; | |
336 tv.tv_usec = CTRLSOCKET_TIMEOUT; | |
337 len = sizeof(saddr); | |
338 if (select(ctrl_fd + 1, &set, NULL, NULL, &tv) <= 0) | |
339 continue; | |
340 if ((fd = accept(ctrl_fd, (struct sockaddr *) &saddr, &len)) == -1) | |
341 continue; | |
342 | |
343 pkt = g_new0(PacketNode, 1); | |
1582
d7af2755a397
[svn] - gcc 4.1.0, 4.1.1, 4.1.2 tree optimization workaround:
nenolod
parents:
1580
diff
changeset
|
344 if ((size_t)read(fd, &pkt->hdr, sizeof(ClientPktHeader)) |
0 | 345 < sizeof(ClientPktHeader)) { |
346 g_free(pkt); | |
347 continue; | |
348 } | |
349 | |
350 if (pkt->hdr.data_length) { | |
351 size_t data_length = pkt->hdr.data_length; | |
352 pkt->data = g_malloc0(data_length); | |
1582
d7af2755a397
[svn] - gcc 4.1.0, 4.1.1, 4.1.2 tree optimization workaround:
nenolod
parents:
1580
diff
changeset
|
353 if ((size_t)read(fd, pkt->data, data_length) < data_length) { |
0 | 354 g_free(pkt->data); |
355 g_free(pkt); | |
356 g_warning("ctrlsocket_func(): Incomplete data packet dropped"); | |
357 continue; | |
358 } | |
359 } | |
360 | |
361 pkt->fd = fd; | |
362 switch (pkt->hdr.command) { | |
363 case CMD_GET_VERSION: | |
364 ctrl_write_gint(pkt->fd, 0x09a3); | |
365 ctrl_ack_packet(pkt); | |
366 break; | |
367 case CMD_IS_PLAYING: | |
368 ctrl_write_gboolean(pkt->fd, bmp_playback_get_playing()); | |
369 ctrl_ack_packet(pkt); | |
370 break; | |
371 case CMD_IS_PAUSED: | |
372 ctrl_write_gboolean(pkt->fd, bmp_playback_get_paused()); | |
373 ctrl_ack_packet(pkt); | |
374 break; | |
375 case CMD_GET_PLAYLIST_POS: | |
376 ctrl_write_gint(pkt->fd, playlist_get_position()); | |
377 ctrl_ack_packet(pkt); | |
378 break; | |
379 case CMD_GET_PLAYLIST_LENGTH: | |
380 ctrl_write_gint(pkt->fd, playlist_get_length()); | |
381 ctrl_ack_packet(pkt); | |
382 break; | |
383 case CMD_GET_PLAYQUEUE_LENGTH: | |
384 ctrl_write_gint(pkt->fd, playlist_queue_get_length()); | |
385 ctrl_ack_packet(pkt); | |
386 break; | |
984 | 387 case CMD_PLAYQUEUE_IS_QUEUED: |
388 ctrl_write_gboolean(pkt->fd, | |
389 playlist_is_position_queued(*((guint32 *) pkt->data))); | |
390 ctrl_ack_packet(pkt); | |
391 break; | |
392 case CMD_PLAYQUEUE_GET_POS: | |
393 if (pkt->data) | |
394 ctrl_write_gint(pkt->fd, | |
395 playlist_get_queue_position_number(* | |
396 ((guint32 *) pkt-> | |
397 data))); | |
398 else | |
399 ctrl_write_gint(pkt->fd, 0); | |
400 | |
401 ctrl_ack_packet(pkt); | |
402 break; | |
403 case CMD_PLAYQUEUE_GET_QPOS: | |
404 if (pkt->data) | |
405 ctrl_write_gint(pkt->fd, | |
406 playlist_get_queue_qposition_number(* | |
407 ((guint32 *) pkt-> | |
408 data))); | |
409 else | |
410 ctrl_write_gint(pkt->fd, 0); | |
411 | |
412 ctrl_ack_packet(pkt); | |
413 break; | |
0 | 414 case CMD_GET_OUTPUT_TIME: |
415 if (bmp_playback_get_playing()) | |
416 ctrl_write_gint(pkt->fd, bmp_playback_get_time()); | |
417 else | |
418 ctrl_write_gint(pkt->fd, 0); | |
419 ctrl_ack_packet(pkt); | |
420 break; | |
421 case CMD_GET_VOLUME: | |
422 input_get_volume(&v[0], &v[1]); | |
423 ctrl_write_packet(pkt->fd, v, sizeof(v)); | |
424 ctrl_ack_packet(pkt); | |
425 break; | |
426 case CMD_GET_BALANCE: | |
427 input_get_volume(&v[0], &v[1]); | |
428 if (v[0] < 0 || v[1] < 0) | |
429 b = 0; | |
430 else if (v[0] > v[1]) | |
431 b = -100 + ((v[1] * 100) / v[0]); | |
432 else if (v[1] > v[0]) | |
433 b = 100 - ((v[0] * 100) / v[1]); | |
434 else | |
435 b = 0; | |
436 ctrl_write_gint(pkt->fd, b); | |
437 ctrl_ack_packet(pkt); | |
438 break; | |
1653 | 439 case CMD_GET_SKIN: |
440 ctrl_write_string(pkt->fd, bmp_active_skin->path); | |
441 ctrl_ack_packet(pkt); | |
442 break; | |
0 | 443 case CMD_GET_PLAYLIST_FILE: |
444 if (pkt->data) { | |
445 gchar *filename; | |
446 filename = playlist_get_filename(*((guint32 *) pkt->data)); | |
447 ctrl_write_string(pkt->fd, filename); | |
448 g_free(filename); | |
449 } | |
450 else | |
451 ctrl_write_string(pkt->fd, NULL); | |
452 ctrl_ack_packet(pkt); | |
453 break; | |
454 case CMD_GET_PLAYLIST_TITLE: | |
455 if (pkt->data) { | |
456 gchar *title; | |
457 title = playlist_get_songtitle(*((guint32 *) pkt->data)); | |
458 ctrl_write_string(pkt->fd, title); | |
459 g_free(title); | |
460 } | |
461 else | |
462 ctrl_write_string(pkt->fd, NULL); | |
463 ctrl_ack_packet(pkt); | |
464 break; | |
465 case CMD_GET_PLAYLIST_TIME: | |
466 if (pkt->data) | |
467 ctrl_write_gint(pkt->fd, | |
468 playlist_get_songtime(* | |
469 ((guint32 *) pkt-> | |
470 data))); | |
471 else | |
472 ctrl_write_gint(pkt->fd, -1); | |
473 | |
474 ctrl_ack_packet(pkt); | |
475 break; | |
476 case CMD_GET_INFO: | |
477 playback_get_sample_params(&info[0], &info[1], &info[2]); | |
478 ctrl_write_packet(pkt->fd, info, 3 * sizeof(gint)); | |
479 ctrl_ack_packet(pkt); | |
480 break; | |
481 case CMD_GET_EQ_DATA: | |
482 case CMD_SET_EQ_DATA: | |
483 /* obsolete */ | |
484 ctrl_ack_packet(pkt); | |
485 break; | |
486 case CMD_PING: | |
487 ctrl_ack_packet(pkt); | |
488 break; | |
489 case CMD_PLAYLIST_ADD: | |
490 if (pkt->data) { | |
491 guint32 *dataptr = pkt->data; | |
492 while ((len = *dataptr) > 0) { | |
493 gchar *filename; | |
494 | |
495 dataptr++; | |
496 filename = g_malloc0(len); | |
497 memcpy(filename, dataptr, len); | |
498 | |
499 GDK_THREADS_ENTER(); | |
500 playlist_add_url(filename); | |
501 GDK_THREADS_LEAVE(); | |
502 | |
503 g_free(filename); | |
504 dataptr += (len + 3) / 4; | |
505 } | |
506 } | |
507 ctrl_ack_packet(pkt); | |
508 break; | |
509 case CMD_PLAYLIST_ADD_URL_STRING: | |
510 GDK_THREADS_ENTER(); | |
511 playlist_add_url(pkt->data); | |
512 GDK_THREADS_LEAVE(); | |
513 | |
514 ctrl_ack_packet(pkt); | |
515 break; | |
516 case CMD_PLAYLIST_INS_URL_STRING: | |
517 if (pkt->data) { | |
518 gint pos = *(gint *) pkt->data; | |
519 gchar *ptr = pkt->data; | |
520 ptr += sizeof(gint); | |
521 playlist_ins_url(ptr, pos); | |
522 } | |
523 ctrl_ack_packet(pkt); | |
524 break; | |
525 case CMD_PLAYLIST_DELETE: | |
526 GDK_THREADS_ENTER(); | |
527 playlist_delete_index(*((guint32 *) pkt->data)); | |
528 GDK_THREADS_LEAVE(); | |
529 ctrl_ack_packet(pkt); | |
530 break; | |
531 case CMD_PLAYLIST_CLEAR: | |
532 GDK_THREADS_ENTER(); | |
533 playlist_clear(); | |
534 mainwin_clear_song_info(); | |
535 mainwin_set_info_text(); | |
536 GDK_THREADS_LEAVE(); | |
537 ctrl_ack_packet(pkt); | |
538 break; | |
539 case CMD_IS_MAIN_WIN: | |
540 ctrl_write_gboolean(pkt->fd, cfg.player_visible); | |
541 ctrl_ack_packet(pkt); | |
542 break; | |
543 case CMD_IS_PL_WIN: | |
544 ctrl_write_gboolean(pkt->fd, cfg.playlist_visible); | |
545 ctrl_ack_packet(pkt); | |
546 break; | |
547 case CMD_IS_EQ_WIN: | |
548 ctrl_write_gboolean(pkt->fd, cfg.equalizer_visible); | |
549 ctrl_ack_packet(pkt); | |
550 break; | |
551 case CMD_IS_REPEAT: | |
552 ctrl_write_gboolean(pkt->fd, cfg.repeat); | |
553 ctrl_ack_packet(pkt); | |
554 break; | |
555 case CMD_IS_SHUFFLE: | |
556 ctrl_write_gboolean(pkt->fd, cfg.shuffle); | |
557 ctrl_ack_packet(pkt); | |
558 break; | |
559 case CMD_IS_ADVANCE: | |
560 ctrl_write_gboolean(pkt->fd, !cfg.no_playlist_advance); | |
561 ctrl_ack_packet(pkt); | |
562 break; | |
563 case CMD_GET_EQ: | |
564 fval[0] = equalizerwin_get_preamp(); | |
565 for (i = 0; i < 10; i++) | |
566 fval[i + 1] = equalizerwin_get_band(i); | |
567 ctrl_write_packet(pkt->fd, fval, 11 * sizeof(gfloat)); | |
568 ctrl_ack_packet(pkt); | |
569 break; | |
570 case CMD_GET_EQ_PREAMP: | |
571 ctrl_write_gfloat(pkt->fd, equalizerwin_get_preamp()); | |
572 ctrl_ack_packet(pkt); | |
573 break; | |
574 case CMD_GET_EQ_BAND: | |
575 i = *((guint32 *) pkt->data); | |
576 ctrl_write_gfloat(pkt->fd, equalizerwin_get_band(i)); | |
577 ctrl_ack_packet(pkt); | |
578 break; | |
579 default: | |
580 g_mutex_lock(packet_list_mutex); | |
581 packet_list = g_list_append(packet_list, pkt); | |
582 ctrl_write_packet(pkt->fd, NULL, 0); | |
583 close(pkt->fd); | |
584 g_mutex_unlock(packet_list_mutex); | |
585 break; | |
586 } | |
587 } | |
588 g_thread_exit(NULL); | |
589 | |
590 /* Used to suppress GCC warnings. Sometimes you'd wish C has | |
591 native threading support :p */ | |
592 return NULL; | |
593 } | |
594 | |
595 void | |
596 ctrlsocket_check(void) | |
597 { | |
598 GList *pkt_list, *next; | |
599 PacketNode *pkt; | |
600 gpointer data; | |
601 guint32 v[2], i, num; | |
602 gboolean tbool; | |
603 gfloat *fval, f; | |
604 | |
605 g_mutex_lock(packet_list_mutex); | |
606 for (pkt_list = packet_list; pkt_list; pkt_list = next) { | |
607 pkt = pkt_list->data; | |
608 data = pkt->data; | |
609 | |
610 switch (pkt->hdr.command) { | |
611 case CMD_PLAY: | |
612 if (bmp_playback_get_paused()) | |
613 bmp_playback_pause(); | |
614 else if (playlist_get_length()) | |
615 bmp_playback_initiate(); | |
616 else | |
617 mainwin_eject_pushed(); | |
618 break; | |
619 case CMD_PAUSE: | |
620 bmp_playback_pause(); | |
621 break; | |
622 case CMD_STOP: | |
906 | 623 ip_data.stop = TRUE; |
0 | 624 bmp_playback_stop(); |
906 | 625 ip_data.stop = FALSE; |
0 | 626 mainwin_clear_song_info(); |
627 break; | |
628 case CMD_PLAY_PAUSE: | |
629 if (bmp_playback_get_playing()) | |
630 bmp_playback_pause(); | |
631 else | |
632 bmp_playback_initiate(); | |
633 break; | |
634 case CMD_PLAYQUEUE_ADD: | |
635 num = *((guint32 *) data); | |
625
0a73d1faeb4e
[svn] GCC 4.1 warning fixes by Diego 'Flameeyes' Petteno from Gentoo.
chainsaw
parents:
538
diff
changeset
|
636 if (num < (guint)playlist_get_length()) |
0 | 637 playlist_queue_position(num); |
638 break; | |
639 case CMD_PLAYQUEUE_REMOVE: | |
640 num = *((guint32 *) data); | |
625
0a73d1faeb4e
[svn] GCC 4.1 warning fixes by Diego 'Flameeyes' Petteno from Gentoo.
chainsaw
parents:
538
diff
changeset
|
641 if (num < (guint)playlist_get_length()) |
0 | 642 playlist_queue_remove(num); |
643 break; | |
984 | 644 case CMD_PLAYQUEUE_CLEAR: |
645 playlist_clear_queue(); | |
646 break; | |
0 | 647 case CMD_SET_PLAYLIST_POS: |
648 num = *((guint32 *) data); | |
625
0a73d1faeb4e
[svn] GCC 4.1 warning fixes by Diego 'Flameeyes' Petteno from Gentoo.
chainsaw
parents:
538
diff
changeset
|
649 if (num < (guint)playlist_get_length()) |
0 | 650 playlist_set_position(num); |
651 break; | |
652 case CMD_JUMP_TO_TIME: | |
653 num = *((guint32 *) data); | |
654 if (playlist_get_current_length() > 0 && | |
625
0a73d1faeb4e
[svn] GCC 4.1 warning fixes by Diego 'Flameeyes' Petteno from Gentoo.
chainsaw
parents:
538
diff
changeset
|
655 num < (guint)playlist_get_current_length()) |
0 | 656 bmp_playback_seek(num / 1000); |
657 break; | |
658 case CMD_SET_VOLUME: | |
659 v[0] = ((guint32 *) data)[0]; | |
660 v[1] = ((guint32 *) data)[1]; | |
661 for (i = 0; i < 2; i++) { | |
662 if (v[i] > 100) | |
663 v[i] = 100; | |
664 } | |
665 input_set_volume(v[0], v[1]); | |
666 break; | |
667 case CMD_SET_SKIN: | |
680
8282b365f6cb
[svn] - Add some sanity checking to make sure we can't do X11 stuff when running headless.
nenolod
parents:
625
diff
changeset
|
668 if (has_x11_connection == TRUE) |
8282b365f6cb
[svn] - Add some sanity checking to make sure we can't do X11 stuff when running headless.
nenolod
parents:
625
diff
changeset
|
669 bmp_active_skin_load(data); |
0 | 670 break; |
671 case CMD_PL_WIN_TOGGLE: | |
680
8282b365f6cb
[svn] - Add some sanity checking to make sure we can't do X11 stuff when running headless.
nenolod
parents:
625
diff
changeset
|
672 if (has_x11_connection != TRUE) |
8282b365f6cb
[svn] - Add some sanity checking to make sure we can't do X11 stuff when running headless.
nenolod
parents:
625
diff
changeset
|
673 break; |
0 | 674 tbool = *((gboolean *) data); |
675 if (tbool) | |
676 playlistwin_show(); | |
677 else | |
678 playlistwin_hide(); | |
679 break; | |
680 case CMD_EQ_WIN_TOGGLE: | |
680
8282b365f6cb
[svn] - Add some sanity checking to make sure we can't do X11 stuff when running headless.
nenolod
parents:
625
diff
changeset
|
681 if (has_x11_connection != TRUE) |
8282b365f6cb
[svn] - Add some sanity checking to make sure we can't do X11 stuff when running headless.
nenolod
parents:
625
diff
changeset
|
682 break; |
0 | 683 tbool = *((gboolean *) data); |
684 equalizerwin_show(!!tbool); | |
685 break; | |
686 case CMD_SHOW_PREFS_BOX: | |
680
8282b365f6cb
[svn] - Add some sanity checking to make sure we can't do X11 stuff when running headless.
nenolod
parents:
625
diff
changeset
|
687 if (has_x11_connection != TRUE) |
8282b365f6cb
[svn] - Add some sanity checking to make sure we can't do X11 stuff when running headless.
nenolod
parents:
625
diff
changeset
|
688 break; |
0 | 689 show_prefs_window(); |
690 break; | |
984 | 691 case CMD_SHOW_JTF_BOX: |
692 if (has_x11_connection != TRUE) | |
693 break; | |
694 mainwin_jump_to_file(); | |
695 break; | |
0 | 696 case CMD_TOGGLE_AOT: |
680
8282b365f6cb
[svn] - Add some sanity checking to make sure we can't do X11 stuff when running headless.
nenolod
parents:
625
diff
changeset
|
697 if (has_x11_connection != TRUE) |
8282b365f6cb
[svn] - Add some sanity checking to make sure we can't do X11 stuff when running headless.
nenolod
parents:
625
diff
changeset
|
698 break; |
0 | 699 tbool = *((gboolean *) data); |
700 mainwin_set_always_on_top(tbool); | |
701 break; | |
702 case CMD_SHOW_ABOUT_BOX: | |
703 break; | |
704 case CMD_EJECT: | |
680
8282b365f6cb
[svn] - Add some sanity checking to make sure we can't do X11 stuff when running headless.
nenolod
parents:
625
diff
changeset
|
705 if (has_x11_connection != TRUE) |
8282b365f6cb
[svn] - Add some sanity checking to make sure we can't do X11 stuff when running headless.
nenolod
parents:
625
diff
changeset
|
706 break; |
0 | 707 mainwin_eject_pushed(); |
708 break; | |
709 case CMD_PLAYLIST_PREV: | |
710 playlist_prev(); | |
711 break; | |
712 case CMD_PLAYLIST_NEXT: | |
713 playlist_next(); | |
714 break; | |
715 case CMD_TOGGLE_REPEAT: | |
716 mainwin_repeat_pushed(!cfg.repeat); | |
717 break; | |
718 case CMD_TOGGLE_SHUFFLE: | |
719 mainwin_shuffle_pushed(!cfg.shuffle); | |
720 break; | |
721 case CMD_TOGGLE_ADVANCE: | |
722 /* FIXME: to be implemented */ | |
723 break; | |
724 case CMD_MAIN_WIN_TOGGLE: | |
680
8282b365f6cb
[svn] - Add some sanity checking to make sure we can't do X11 stuff when running headless.
nenolod
parents:
625
diff
changeset
|
725 if (has_x11_connection != TRUE) |
8282b365f6cb
[svn] - Add some sanity checking to make sure we can't do X11 stuff when running headless.
nenolod
parents:
625
diff
changeset
|
726 break; |
0 | 727 tbool = *((gboolean *) data); |
728 mainwin_show(!!tbool); | |
729 break; | |
730 case CMD_SET_EQ: | |
731 if (pkt->hdr.data_length >= 11 * sizeof(gfloat)) { | |
732 fval = (gfloat *) data; | |
733 equalizerwin_set_preamp(fval[0]); | |
734 for (i = 0; i < 10; i++) | |
735 equalizerwin_set_band(i, fval[i + 1]); | |
736 } | |
737 break; | |
738 case CMD_SET_EQ_PREAMP: | |
739 f = *((gfloat *) data); | |
740 equalizerwin_set_preamp(f); | |
741 break; | |
742 case CMD_SET_EQ_BAND: | |
743 if (pkt->hdr.data_length >= sizeof(gint) + sizeof(gfloat)) { | |
744 i = *((gint *) data); | |
745 f = *((gfloat *) ((gchar *) data + sizeof(gint))); | |
746 equalizerwin_set_band(i, f); | |
747 } | |
748 break; | |
749 case CMD_QUIT: | |
750 /* | |
751 * We unlock the packet_list_mutex to | |
752 * avoid that cleanup_ctrlsocket() can | |
753 * deadlock, mainwin_quit_cb() will | |
754 * never return anyway, so this will | |
755 * work ok. | |
756 */ | |
757 g_mutex_unlock(packet_list_mutex); | |
758 mainwin_quit_cb(); | |
759 break; | |
760 case CMD_ACTIVATE: | |
1653 | 761 gtk_window_present(GTK_WINDOW(mainwin)); |
0 | 762 break; |
763 default: | |
764 g_message("Unknown socket command received"); | |
765 break; | |
766 } | |
767 next = g_list_next(pkt_list); | |
768 packet_list = g_list_remove_link(packet_list, pkt_list); | |
769 g_list_free_1(pkt_list); | |
770 if (pkt->data) | |
771 g_free(pkt->data); | |
772 g_free(pkt); | |
773 } | |
774 g_mutex_unlock(packet_list_mutex); | |
775 } |