1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/* ***** BEGIN LICENSE BLOCK *****
3
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
5
* The contents of this file are subject to the Mozilla Public License Version
6
* 1.1 (the "License"); you may not use this file except in compliance with
7
* the License. You may obtain a copy of the License at
8
* http://www.mozilla.org/MPL/
10
* Software distributed under the License is distributed on an "AS IS" basis,
11
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12
* for the specific language governing rights and limitations under the
15
* The Original Code is mozilla.org code.
17
* The Initial Developer of the Original Code is
18
* Netscape Communications Corporation.
19
* Portions created by the Initial Developer are Copyright (C) 1998
20
* the Initial Developer. All Rights Reserved.
24
* Alternatively, the contents of this file may be used under the terms of
25
* either the GNU General Public License Version 2 or later (the "GPL"), or
26
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27
* in which case the provisions of the GPL or the LGPL are applicable instead
28
* of those above. If you wish to allow use of your version of this file only
29
* under the terms of either the GPL or the LGPL, and not to allow others to
30
* use your version of this file under the terms of the MPL, indicate your
31
* decision by deleting the provisions above and replace them with the notice
32
* and other provisions required by the GPL or the LGPL. If you do not delete
33
* the provisions above, a recipient may use your version of this file under
34
* the terms of any one of the MPL, the GPL or the LGPL.
36
* ***** END LICENSE BLOCK ***** */
39
#include "plugin_setup.h"
40
#include "plugin_types.h"
42
static int32_t STREAMBUFSIZE = 0x0FFFFFFF;
44
NPError NS_PluginInitialize();
45
void NS_PluginShutdown();
46
NPError NS_PluginGetValue(NPPVariable aVariable, void *aValue);
48
//////////////////////////////////////
50
// general initialization and shutdown
52
NPError NS_PluginInitialize()
54
return NPERR_NO_ERROR;
57
void NS_PluginShutdown()
61
// get values per plugin
62
NPError NS_PluginGetValue(NPPVariable aVariable, void *aValue)
64
return PluginGetValue(aVariable, aValue);
68
//////////////////////
73
parole_plugin_ping (gpointer data)
75
CPlugin *plugin = (CPlugin*)data;
77
dbus_g_proxy_call_no_reply (plugin->proxy, "Ping",
84
parole_plugin_player_exiting_cb (DBusGProxy *proxy, gpointer data)
86
//g_debug ("Player exiting");
88
CPlugin *plugin = (CPlugin*)data;
90
plugin->player_exited = TRUE;
91
if ( plugin->ping_id != 0 )
92
g_source_remove (plugin->ping_id);
96
parole_plugin_player_ready_cb (DBusGProxy *proxy, gpointer data)
98
//g_debug ("Player ready");
100
CPlugin *plugin = (CPlugin*)data;
102
plugin->player_ready = TRUE;
104
if ( plugin->ping_id == 0 )
106
plugin->ping_id = g_timeout_add_seconds (10, (GSourceFunc) parole_plugin_ping, plugin);
112
////////////////////////////////////////
114
// CPlugin class implementation
116
CPlugin::CPlugin (NPP pNPInstance)
118
//g_debug ("Constructor");
120
mInstance = pNPInstance;
123
GError *error = NULL;
135
player_ready = FALSE;
136
player_started = FALSE;
137
player_spawned = FALSE;
138
player_exited = FALSE;
139
player_playing = FALSE;
142
bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
146
g_warning ("Failed to get session bus %s", error->message);
147
g_error_free (error);
154
g_source_remove (ping_id);
168
dbus_g_connection_unref (bus);
175
dbus_g_proxy_disconnect_signal (proxy, "Exiting",
176
G_CALLBACK (parole_plugin_player_exiting_cb), this);
178
dbus_g_proxy_disconnect_signal (proxy, "Ready",
179
G_CALLBACK (parole_plugin_player_ready_cb), this);
181
g_object_unref (proxy);
187
NPBool CPlugin::init(NPWindow * pNPWindow)
189
if (pNPWindow == NULL)
197
void CPlugin::SendPlay (const gchar *url)
199
GError *error = NULL;
200
g_return_if_fail (proxy);
202
//g_debug ("Sending play request of stream %s", url);
203
dbus_g_proxy_call (proxy, "PlayUrl", &error,
208
player_playing = TRUE;
212
g_critical ("Failed to play stream %s : %s", url, error->message);
213
g_error_free (error);
214
player_playing = FALSE;
219
CPlugin::SendList (const gchar *filename)
221
GError *error = NULL;
222
g_return_if_fail (proxy);
224
//g_debug ("Sending play request of playlist %s", filename);
226
dbus_g_proxy_call (proxy, "PlayList", &error,
227
G_TYPE_STRING, filename,
231
player_playing = TRUE;
235
g_critical ("Failed to play list %s : %s", filename, error->message);
236
g_error_free (error);
237
player_playing = FALSE;
241
NPError CPlugin::RunPlayer ()
246
GError *error = NULL;
248
socket = g_strdup_printf ("%ld", window);
250
app = g_build_filename (LIBEXECDIR, "parole-media-plugin", NULL);
253
command[1] = (gchar *)"--socket-id";
257
if ( !g_spawn_async (NULL,
265
g_critical ("Failed to spawn command : %s", error->message);
266
g_error_free (error);
267
return NPERR_GENERIC_ERROR;
270
player_spawned = TRUE;
277
return NPERR_NO_ERROR;
280
void CPlugin::GetProxy ()
284
g_return_if_fail (bus != NULL);
286
dbus_name = g_strdup_printf ("org.Parole.Media.Plugin%ld", window);
288
proxy = dbus_g_proxy_new_for_name (bus,
290
"/org/Parole/Media/Plugin",
291
"org.Parole.Media.Plugin");
294
g_critical ("Unable to create proxy for %s", dbus_name);
297
dbus_g_proxy_add_signal (proxy, "Error", G_TYPE_INVALID);
298
dbus_g_proxy_add_signal (proxy, "Finished", G_TYPE_INVALID);
299
dbus_g_proxy_add_signal (proxy, "Exiting", G_TYPE_INVALID);
300
dbus_g_proxy_add_signal (proxy, "Ready", G_TYPE_INVALID);
302
dbus_g_proxy_connect_signal (proxy, "Exiting",
303
G_CALLBACK (parole_plugin_player_exiting_cb), this, NULL);
305
dbus_g_proxy_connect_signal (proxy, "Ready",
306
G_CALLBACK (parole_plugin_player_ready_cb), this, NULL);
310
NPError CPlugin::SetWindow(NPWindow * aWindow)
312
//g_debug ("SetWindow");
314
if ( aWindow == NULL )
315
return NPERR_NO_ERROR;
317
if ( window_set == FALSE)
319
window = (Window) aWindow->window;
324
return NPERR_NO_ERROR;
333
//g_debug ("Sending Stop signal");
334
dbus_g_proxy_call_no_reply (proxy, "Stop",
341
NPBool CPlugin::isInitialized()
346
void CPlugin::StopPlayer ()
348
if ( player_spawned )
356
GError *error = NULL;
357
//g_debug ("Sending Quit message");
358
dbus_g_proxy_call (proxy, "Quit", &error,
363
* This might happen if the browser unload the plugin quickly
364
* while the process didn't get the dbus name.
369
//g_debug ("Failed to stop the backend via D-Bus %s", error->message);
371
if ( g_error_matches (error, DBUS_GERROR, DBUS_GERROR_NO_REPLY ) ||
372
g_error_matches (error, DBUS_GERROR, DBUS_GERROR_SERVICE_UNKNOWN) )
374
g_error_free (error);
375
g_main_context_iteration(NULL, FALSE);
378
//g_debug ("No reply, probably not ready, re-trying");
386
} while (num_tries < 4 && player_exited != TRUE);
391
g_snprintf (cmd, 128, "kill -9 %d", child_pid);
392
g_spawn_command_line_async (cmd, NULL);
397
NPError CPlugin::NewStream (NPMIMEType type, NPStream * stream, NPBool seekable, uint16_t * stype)
401
murl = g_strdup (stream->url);
402
//g_debug ("NewStream=%s", murl);
405
return NPERR_NO_ERROR;
408
NPError CPlugin::DestroyStream(NPStream * stream, NPError reason)
411
g_debug ("DestroyStream reason = %i for %s\n", reason, stream->url);
413
if ( reason == NPRES_DONE )
415
g_debug ("NPRES_DONE");
417
else if ( reason == NPRES_USER_BREAK )
419
g_debug ("NPRES_USER_BREAK");
422
else if ( reason == NPRES_NETWORK_ERR )
424
g_debug ("NPRES_NETWORK_ERR");
427
return NPERR_NO_ERROR;
430
void CPlugin::URLNotify (const char *url, NPReason reason, void *notifyData)
432
//g_debug ("Url notify %s reason %i", url, reason);
435
void CPlugin::StreamAsFile (NPStream * stream, const char *fname)
437
//g_debug ("StreamAsFile url=%s fname=%s", stream->url, fname);
440
int32_t CPlugin::WriteReady (NPStream * stream)
442
//g_debug ("WriteReady url=%s", stream->url);
444
if ( mode != NP_FULL && mode != NP_EMBED )
446
NPN_DestroyStream (mInstance, stream, NPRES_DONE);
450
return player_ready ? STREAMBUFSIZE : 0;
453
int32_t CPlugin::Write (NPStream * stream, int32_t offset, int32_t len, void *buffer)
455
static int32_t wrotebytes = -1;
457
if ( checked == FALSE )
461
/* Check if the url is a playlist */
462
//g_debug ("Checking if stream is a playlist");
464
char *data = (char *) buffer;
465
for ( int32_t i = 0; i < len; i++)
468
if ( g_ascii_iscntrl (c) && !g_ascii_isspace (c) )
479
tmp_file = g_strdup_printf ("/tmp/parole-plugin-player-%ld", window);
483
cache = fopen (tmp_file, "w");
484
g_warn_if_fail (cache != NULL);
489
fseek (cache, offset, SEEK_SET);
490
wrotebytes += fwrite (buffer, 1, MAX (len, STREAMBUFSIZE), cache);
491
//g_debug ("Wrotebytes=%d offset=%d data=%s", wrotebytes, offset, (gchar*)buffer);
494
if ( wrotebytes >= 0 )
502
else if ( player_ready && player_playing == FALSE )
504
SendPlay (stream->url);