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 ***** */
38
#include "plugin_dbus.h"
40
static DBusHandlerResult filter_func(DBusConnection * connection,
41
DBusMessage * message, void *user_data)
45
const gchar *destination;
49
DBusMessage *reply_message;
51
nsPluginInstance *instance;
58
message_type = dbus_message_get_type(message);
59
sender = dbus_message_get_sender(message);
60
destination = dbus_message_get_destination(message);
63
printf("path=%s; interface=%s; member=%s; data=%s\n",
64
dbus_message_get_path(message),
65
dbus_message_get_interface(message), dbus_message_get_member(message), s);
68
instance = (nsPluginInstance *) user_data;
69
path = instance->path;
71
if (dbus_message_get_path(message) != NULL
72
&& is_valid_path(instance, dbus_message_get_path(message))) {
74
//printf("Path matched %s\n", dbus_message_get_path(message));
75
if (message_type == DBUS_MESSAGE_TYPE_SIGNAL) {
76
if (g_ascii_strcasecmp(dbus_message_get_member(message), "Ready") == 0) {
77
dbus_error_init(&error);
78
if (dbus_message_get_args(message, &error, DBUS_TYPE_INT32, &i, DBUS_TYPE_INVALID)) {
79
item = list_find_by_controlid(instance->playlist, i);
81
list_mark_controlid_ready(instance->playlist, i);
83
// printf("Control id not found\n");
86
dbus_error_free(&error);
89
instance->playerready = TRUE;
90
instance->cache_size = request_int_value(instance, item, "GetCacheSize");
91
//printf("cache size = %i\n",instance->cache_size);
92
if (instance->cache_size == 0) {
95
return DBUS_HANDLER_RESULT_HANDLED;
97
if (g_ascii_strcasecmp(dbus_message_get_member(message), "Cancel") == 0) {
98
dbus_error_init(&error);
99
if (dbus_message_get_args(message, &error, DBUS_TYPE_INT32, &i, DBUS_TYPE_INVALID)) {
100
list_mark_controlid_cancelled(instance->playlist, i, TRUE);
102
dbus_error_free(&error);
104
return DBUS_HANDLER_RESULT_HANDLED;
106
if (g_ascii_strcasecmp(dbus_message_get_member(message), "ReloadPlugins") == 0) {
107
NPN_ReloadPlugins(FALSE);
108
return DBUS_HANDLER_RESULT_HANDLED;
111
if (g_ascii_strcasecmp(dbus_message_get_member(message), "RequestById") == 0) {
112
dbus_error_init(&error);
113
if (dbus_message_get_args(message, &error, DBUS_TYPE_STRING, &s, DBUS_TYPE_INVALID)) {
114
printf("Got id %s\n", s);
115
item = list_find_by_id(instance->playlist, (gint) g_strtod(s, NULL));
118
item->cancelled = FALSE;
119
item->retrieved = FALSE;
120
printf("id %s has url of %s\n", s, item->src);
121
printf("id %s has newwindow = %i\n", s, item->newwindow);
122
if (item->newwindow == 0) {
123
send_signal_with_boolean(instance, item, "SetShowControls", TRUE);
124
if (item->streaming) {
125
send_signal_with_string(instance, item, "Open", item->src);
127
NPN_GetURLNotify(instance->mInstance, item->src, NULL, item);
131
// generate a random controlid
133
item->controlid = g_rand_int_range(rand, 0, 65535);
135
tmp = g_strdup_printf("/control/%i", item->controlid);
136
g_strlcpy(item->path, tmp, 1024);
139
// list_dump(instance->playlist);
141
arg[i++] = g_strdup("gnome-mplayer");
142
arg[i++] = g_strdup_printf("--controlid=%i", item->controlid);
144
g_spawn_async(NULL, arg, NULL,
145
G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, NULL);
146
printf("requesting %s \n",item->src);
147
NPN_GetURLNotify(instance->mInstance, item->src, NULL, item);
149
instance->lastopened->played = TRUE;
150
item->requested = TRUE;
151
instance->lastopened = item;
154
dbus_error_free(&error);
156
//list_dump(instance->playlist);
157
return DBUS_HANDLER_RESULT_HANDLED;
160
if (g_ascii_strcasecmp(dbus_message_get_member(message), "Next") == 0) {
162
if (instance->lastopened != NULL && instance->lastopened->loop == FALSE) {
163
list_mark_id_played(instance->playlist, instance->lastopened->id);
164
instance->lastopened->played = TRUE;
165
item = list_find_next_playable(instance->playlist);
167
if (instance->lastopened != NULL && instance->lastopened->loop == TRUE) {
168
if (instance->lastopened->loopcount < 0) {
169
item = instance->lastopened;
170
item->played = FALSE;
171
item->opened = FALSE;
172
} else if (instance->lastopened->loopcount > 0) {
173
instance->lastopened->loopcount--;
174
item = instance->lastopened;
175
item->played = FALSE;
176
item->opened = FALSE;
179
instance->lastopened->loop = FALSE;
180
item = list_find_next_playable(instance->playlist);
185
//printf("next item src = %s\n", item->src);
186
//printf("next item local = %s\n", item->local);
187
//printf("next item streaming = %i\n", item->streaming);
191
if (item->newwindow == 0) {
192
open_location(instance, item, TRUE);
195
arg[i++] = g_strdup("gnome-mplayer");
197
g_strdup_printf("--controlid=%i",
198
instance->controlid);
199
arg[i++] = g_strdup(item->src);
201
g_spawn_async(NULL, arg, NULL,
203
NULL, NULL, NULL, NULL);
205
instance->lastopened = item;
208
if (!item->streaming) {
209
item->controlid = instance->lastopened->controlid;
210
g_strlcpy(item->path, instance->lastopened->path, 1024);
211
item->playerready = instance->lastopened->playerready;
212
item->newwindow = instance->lastopened->newwindow;
213
item->cancelled = FALSE;
214
if (item->retrieved) {
215
open_location(instance, item, TRUE);
217
NPN_GetURLNotify(instance->mInstance, item->src, NULL, item);
220
open_location(instance, item, FALSE);
223
return DBUS_HANDLER_RESULT_HANDLED;
225
if (g_ascii_strcasecmp(dbus_message_get_member(message), "Event") == 0) {
226
dbus_error_init(&error);
227
if (dbus_message_get_args
228
(message, &error, DBUS_TYPE_STRING, &s, DBUS_TYPE_INT32, &i,
229
DBUS_TYPE_INVALID)) {
230
// uncomment for event debugging
231
// printf("Event: %s button %i\n",s,i);
233
if (g_ascii_strcasecmp(s, "MediaComplete") == 0) {
234
if (instance->event_mediacomplete != NULL) {
235
NPN_GetURL(instance->mInstance, instance->event_mediacomplete, NULL);
238
if (g_ascii_strcasecmp(s, "MouseClicked") == 0) {
239
if (instance->event_mouseclicked != NULL) {
240
NPN_GetURL(instance->mInstance, instance->event_mouseclicked, NULL);
243
if (g_ascii_strcasecmp(s, "EnterWindow") == 0) {
244
if (instance->event_enterwindow != NULL) {
245
NPN_GetURL(instance->mInstance, instance->event_enterwindow, NULL);
248
if (g_ascii_strcasecmp(s, "LeaveWindow") == 0) {
249
if (instance->event_leavewindow != NULL) {
250
NPN_GetURL(instance->mInstance, instance->event_leavewindow, NULL);
253
if (g_ascii_strcasecmp(s, "MouseDown") == 0) {
254
if (instance->event_mousedown != NULL) {
255
tmp = g_strdup_printf("%s(%i);", instance->event_mousedown, i);
256
NPN_GetURL(instance->mInstance, tmp, NULL);
260
if (g_ascii_strcasecmp(s, "MouseUp") == 0) {
261
if (instance->event_mouseup != NULL) {
262
tmp = g_strdup_printf("%s(%i);", instance->event_mouseup, i);
263
NPN_GetURL(instance->mInstance, tmp, NULL);
271
// printf("path didn't match path = %s\n", path);
273
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
276
DBusConnection *dbus_hookup(nsPluginInstance * instance)
278
DBusConnection *connection;
280
DBusBusType type = DBUS_BUS_SESSION;
283
dbus_error_init(&dberror);
284
connection = dbus_bus_get_private(type, &dberror);
286
dbus_connection_setup_with_g_main(connection, NULL);
288
dbus_bus_add_match(connection, "type='signal',interface='com.gecko.mediaplayer'", NULL);
289
dbus_connection_add_filter(connection, filter_func, instance, NULL);
291
printf("DBUS connection created\nListening to path %s\n", instance->path);
296
DBusConnection *dbus_unhook(DBusConnection * connection, nsPluginInstance * instance)
299
dbus_connection_flush(connection);
300
dbus_connection_remove_filter(connection, filter_func, instance);
301
dbus_connection_close(connection);
302
dbus_connection_unref(connection);
307
void open_location(nsPluginInstance * instance, ListItem * item, gboolean uselocal)
309
DBusMessage *message;
313
GError *error = NULL;
318
//list_dump(instance->playlist);
319
//printf("Opening %s to connection %p\n",file, instance->connection);
321
if (!(instance->player_launched)) {
323
if (uselocal && strlen(item->local) > 0) {
324
file = g_strdup(item->local);
326
file = g_strdup(item->src);
329
//printf("launching gnome-mplayer from Open with id = %i\n",instance->controlid);
330
argvn[arg++] = g_strdup_printf("gnome-mplayer");
331
argvn[arg++] = g_strdup_printf("--window=-1");
332
argvn[arg++] = g_strdup_printf("--controlid=%i", instance->controlid);
333
if (instance->disable_context_menu == TRUE)
334
argvn[arg++] = g_strdup_printf("--disablecontextmenu");
335
if (instance->debug == TRUE)
336
argvn[arg++] = g_strdup_printf("--verbose");
338
argvn[arg++] = g_strdup_printf("%s", file);
339
argvn[arg] = g_strdup("");
340
argvn[arg + 1] = NULL;
341
instance->playerready = FALSE;
342
ok = g_spawn_async(NULL, argvn, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, &error);
345
instance->player_launched = TRUE;
347
instance->lastopened = item;
354
while (!(instance->playerready)) {
355
g_main_context_iteration(NULL, FALSE);
358
if (item->controlid != 0) {
359
while (!(item->playerready)) {
360
g_main_context_iteration(NULL, FALSE);
366
if (uselocal && strlen(item->local) > 0) {
367
file = g_strdup(item->local);
369
file = g_strdup(item->src);
372
if (strlen(item->path) > 0) {
375
path = instance->path;
378
//printf("Sending Open %s to connection %p\n",file, instance->connection);
379
if (item->hrefid == 0) {
380
message = dbus_message_new_signal(path, "com.gnome.mplayer", "Open");
381
dbus_message_append_args(message, DBUS_TYPE_STRING, &file, DBUS_TYPE_INVALID);
382
dbus_connection_send(instance->connection, message, NULL);
383
dbus_message_unref(message);
385
// ok, not done here yet, may need a new window for Apple HD video
386
id = g_strdup_printf("%i", item->hrefid);
387
message = dbus_message_new_signal(path, "com.gnome.mplayer", "OpenButton");
388
dbus_message_append_args(message, DBUS_TYPE_STRING, &file,
389
DBUS_TYPE_STRING, &id, DBUS_TYPE_INVALID);
390
dbus_connection_send(instance->connection, message, NULL);
391
dbus_message_unref(message);
393
send_signal_with_string(instance,item,"SetURL",item->src);
395
instance->lastopened = item;
399
void resize_window(nsPluginInstance * instance, ListItem * item, gint x, gint y)
401
DBusMessage *message;
404
if (instance == NULL)
409
if (item != NULL && strlen(item->path) > 0) {
412
path = instance->path;
415
if (instance->playerready) {
416
if (instance->connection != NULL && path != NULL) {
417
message = dbus_message_new_signal(path, "com.gnome.mplayer", "ResizeWindow");
418
dbus_message_append_args(message, DBUS_TYPE_INT32, &x,
419
DBUS_TYPE_INT32, &y, DBUS_TYPE_INVALID);
420
dbus_connection_send(instance->connection, message, NULL);
421
dbus_message_unref(message);
427
void send_signal(nsPluginInstance * instance, ListItem * item, gchar * signal)
429
DBusMessage *message;
430
const char *localsignal;
433
// printf("Sending %s to connection %p\n", signal, instance->connection);
434
if (instance == NULL)
437
if (instance->console != NULL) {
438
path = g_strdup_printf("/console/%s",instance->console);
440
if (item != NULL && strlen(item->path) > 0) {
441
path = g_strdup(item->path);
443
path = g_strdup(instance->path);
447
if (instance->playerready && instance->connection != NULL) {
448
localsignal = g_strdup(signal);
449
message = dbus_message_new_signal(path, "com.gnome.mplayer", localsignal);
450
dbus_connection_send(instance->connection, message, NULL);
451
dbus_message_unref(message);
458
void send_signal_when_ready(nsPluginInstance * instance, ListItem * item, gchar * signal)
460
DBusMessage *message;
461
const char *localsignal;
464
if (instance == NULL)
467
if (item != NULL && strlen(item->path) > 0) {
470
path = instance->path;
473
if (instance->player_launched) {
474
while (!(instance->playerready)) {
475
g_main_context_iteration(NULL,FALSE);
478
if (instance->playerready && (instance->connection != NULL)) {
479
//printf("Sending %s to connection %p\n", signal, instance->connection);
480
localsignal = g_strdup(signal);
481
message = dbus_message_new_signal(path, "com.gnome.mplayer", localsignal);
482
dbus_connection_send(instance->connection, message, NULL);
483
dbus_message_unref(message);
484
//printf("Sent %s to connection %p\n", signal, instance->connection);
489
void send_signal_with_string(nsPluginInstance * instance, ListItem * item,
490
gchar * signal, gchar * str)
492
DBusMessage *message;
493
const char *localsignal;
494
const char *localstr;
497
//printf("Sending %s to connection %p\n", signal, instance->connection);
498
if (instance == NULL)
501
if (instance->console != NULL) {
502
path = g_strdup_printf("/console/%s",instance->console);
504
if (item != NULL && strlen(item->path) > 0) {
505
path = g_strdup(item->path);
507
path = g_strdup(instance->path);
511
if (instance->playerready && instance->connection != NULL) {
512
localsignal = g_strdup(signal);
513
localstr = g_strdup(str);
514
message = dbus_message_new_signal(path, "com.gnome.mplayer", localsignal);
515
dbus_message_append_args(message, DBUS_TYPE_STRING, &localstr, DBUS_TYPE_INVALID);
516
dbus_connection_send(instance->connection, message, NULL);
517
dbus_message_unref(message);
523
void send_signal_with_double(nsPluginInstance * instance, ListItem * item,
524
gchar * signal, gdouble dbl)
526
DBusMessage *message;
527
const char *localsignal;
530
//printf("Sending %s to connection %p\n", signal, instance->connection);
531
if (instance == NULL)
534
if (instance->console != NULL) {
535
path = g_strdup_printf("/console/%s",instance->console);
537
if (item != NULL && strlen(item->path) > 0) {
538
path = g_strdup(item->path);
540
path = g_strdup(instance->path);
544
if (instance->playerready && instance->connection != NULL) {
545
localsignal = g_strdup(signal);
546
message = dbus_message_new_signal(path, "com.gnome.mplayer", localsignal);
547
dbus_message_append_args(message, DBUS_TYPE_DOUBLE, &dbl, DBUS_TYPE_INVALID);
548
dbus_connection_send(instance->connection, message, NULL);
549
dbus_message_unref(message);
555
void send_signal_with_boolean(nsPluginInstance * instance, ListItem * item,
556
gchar * signal, gboolean boolean)
558
DBusMessage *message;
559
const char *localsignal;
562
//printf("Sending %s to connection %p\n", signal, instance->connection);
563
if (instance == NULL)
566
if (instance->console != NULL) {
567
path = g_strdup_printf("/console/%s",instance->console);
569
if (item != NULL && strlen(item->path) > 0) {
570
path = g_strdup(item->path);
572
path = g_strdup(instance->path);
576
if (instance->playerready && instance->connection != NULL) {
577
localsignal = g_strdup(signal);
578
message = dbus_message_new_signal(path, "com.gnome.mplayer", localsignal);
579
dbus_message_append_args(message, DBUS_TYPE_BOOLEAN, &boolean, DBUS_TYPE_INVALID);
580
dbus_connection_send(instance->connection, message, NULL);
581
dbus_message_unref(message);
587
gboolean request_boolean_value(nsPluginInstance * instance, ListItem * item, gchar * member)
589
DBusMessage *message;
590
DBusMessage *replymessage;
591
const gchar *localmember;
593
gboolean result = FALSE;
598
//printf("Requesting %s to connection %p\n", member, instance->connection);
599
if (instance == NULL)
602
if (item != NULL && strlen(item->path) > 0) {
604
controlid = item->controlid;
606
path = instance->path;
607
controlid = instance->controlid;
610
dest = g_strdup_printf("com.gnome.mplayer.cid%i", controlid);
612
if (instance->playerready && instance->connection != NULL) {
613
localmember = g_strdup(member);
614
message = dbus_message_new_method_call(dest, path, "com.gnome.mplayer", localmember);
615
dbus_error_init(&error);
617
dbus_connection_send_with_reply_and_block(instance->connection, message, -1, &error);
618
if (dbus_error_is_set(&error)) {
619
printf("Error message = %s\n", error.message);
621
dbus_message_get_args(replymessage, &error, DBUS_TYPE_BOOLEAN, &result, DBUS_TYPE_INVALID);
622
dbus_message_unref(message);
623
dbus_message_unref(replymessage);
630
gdouble request_double_value(nsPluginInstance * instance, ListItem * item, gchar * member)
632
DBusMessage *message;
633
DBusMessage *replymessage;
634
const gchar *localmember;
636
gdouble result = 0.0;
641
//printf("Requesting %s to connection %p\n", member, instance->connection);
642
if (instance == NULL)
645
if (item != NULL && strlen(item->path) > 0) {
647
controlid = item->controlid;
649
path = instance->path;
650
controlid = instance->controlid;
653
dest = g_strdup_printf("com.gnome.mplayer.cid%i", controlid);
655
if (instance->playerready && instance->connection != NULL) {
656
localmember = g_strdup(member);
657
message = dbus_message_new_method_call(dest, path, "com.gnome.mplayer", localmember);
658
dbus_error_init(&error);
660
dbus_connection_send_with_reply_and_block(instance->connection, message, -1, &error);
661
if (dbus_error_is_set(&error)) {
662
printf("Error message = %s\n", error.message);
664
dbus_message_get_args(replymessage, &error, DBUS_TYPE_DOUBLE, &result, DBUS_TYPE_INVALID);
665
dbus_message_unref(message);
666
dbus_message_unref(replymessage);
674
gint request_int_value(nsPluginInstance * instance, ListItem * item, gchar * member)
676
DBusMessage *message;
677
DBusMessage *replymessage;
678
const gchar *localmember;
685
//printf("Requesting %s to connection %p\n", member, instance->connection);
686
if (instance == NULL)
689
if (item != NULL && strlen(item->path) > 0) {
691
controlid = item->controlid;
693
path = instance->path;
694
controlid = instance->controlid;
697
dest = g_strdup_printf("com.gnome.mplayer.cid%i", controlid);
699
if (instance->playerready && instance->connection != NULL) {
700
localmember = g_strdup(member);
701
message = dbus_message_new_method_call(dest, path, "com.gnome.mplayer", localmember);
702
dbus_error_init(&error);
704
dbus_connection_send_with_reply_and_block(instance->connection, message, -1, &error);
705
if (dbus_error_is_set(&error)) {
706
printf("Error message = %s\n", error.message);
708
dbus_message_get_args(replymessage, &error, DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID);
709
dbus_message_unref(message);
710
dbus_message_unref(replymessage);
717
gboolean is_valid_path(nsPluginInstance * instance, const char *message)
719
gboolean result = FALSE;
723
if (instance == NULL)
726
if (g_ascii_strcasecmp(message, instance->path) == 0) {
732
if (instance->playlist != NULL) {
733
for (iter = instance->playlist; iter != NULL; iter = g_list_next(iter)) {
734
item = (ListItem *) iter->data;
736
if (g_ascii_strcasecmp(message, item->path) == 0) {