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
4 *
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/
9 *
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
13 * License.
14 *
15 * The Original Code is mozilla.org code.
16 *
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.
21 *
22 * Contributor(s):
23 *
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.
35 *
36 * ***** END LICENSE BLOCK ***** */
37
38
39 #include "plugin.h"
40 //#include "npupp.h"
41 #include "plugin_list.h"
42 #include "plugin_setup.h"
43 #include "plugin_types.h"
44 #include "plugin_dbus.h"
45
46 #ifdef HAVE_NSPR
47 #include <nspr/nspr.h>
48 #else
49 #include <nsIPrefBranch.h>
50 #include <nsIPrefService.h>
51 #include <nsIServiceManager.h>
52 #include <nsISupportsPrimitives.h>
53 #endif
54
55 #include <dlfcn.h>
56
57 static NPObject *sWindowObj;
58
59 int32 STREAMBUFSIZE = 0X0FFFFFFF;
60
61 // methods
62 static NPIdentifier Play_id;
63 static NPIdentifier PlayAt_id;
64 static NPIdentifier Pause_id;
65 static NPIdentifier PlayPause_id;
66 static NPIdentifier Stop_id;
67 static NPIdentifier quit_id;
68 static NPIdentifier DoPlay_id;
69 static NPIdentifier DoPause_id;
70 static NPIdentifier FastForward_id;
71 static NPIdentifier FastReverse_id;
72 static NPIdentifier ff_id;
73 static NPIdentifier rew_id;
74 static NPIdentifier rewind_id;
75 static NPIdentifier Seek_id;
76 static NPIdentifier Open_id;
77 static NPIdentifier SetVolume_id;
78 static NPIdentifier GetVolume_id;
79 static NPIdentifier SetFileName_id;
80 static NPIdentifier GetFileName_id;
81 static NPIdentifier SetIsLooping_id;
82 static NPIdentifier GetIsLooping_id;
83 static NPIdentifier SetAutoPlay_id;
84 static NPIdentifier GetAutoPlay_id;
85 static NPIdentifier SetHREF_id;
86 static NPIdentifier GetHREF_id;
87 static NPIdentifier SetURL_id;
88 static NPIdentifier GetURL_id;
89 static NPIdentifier GetMIMEType_id;
90 static NPIdentifier getTime_id;
91 static NPIdentifier getDuration_id;
92 static NPIdentifier getPercent_id;
93 static NPIdentifier getBitrate_id;
94 static NPIdentifier isplaying_id;
95 static NPIdentifier playlistAppend_id;
96 static NPIdentifier playlistClear_id;
97 static NPIdentifier onClick_id;
98 static NPIdentifier onMediaComplete_id;
99 static NPIdentifier onMouseUp_id;
100 static NPIdentifier onMouseDown_id;
101 static NPIdentifier onMouseOut_id;
102 static NPIdentifier onMouseOver_id;
103 static NPIdentifier onDestroy_id;
104
105 static NPIdentifier controls_play_id;
106 static NPIdentifier controls_pause_id;
107 static NPIdentifier controls_stop_id;
108 static NPIdentifier controls_fastForward_id;
109 static NPIdentifier controls_fastReverse_id;
110 static NPIdentifier controls_step_id;
111
112 static NPIdentifier media_getItemInfo_id;
113
114
115 // properties
116 static NPIdentifier filename_id;
117 static NPIdentifier src_id;
118 static NPIdentifier ShowControls_id;
119 static NPIdentifier fullscreen_id;
120 static NPIdentifier showlogo_id;
121 static NPIdentifier playState_id;
122 static NPIdentifier controls_id;
123 static NPIdentifier media_id;
124 static NPIdentifier settings_id;
125 static NPIdentifier error_id;
126
127 static NPIdentifier status_id;
128 static NPIdentifier URL_id;
129 static NPIdentifier versionInfo_id;
130 static NPIdentifier enabled_id;
131 static NPIdentifier enableContextMenu_id;
132 static NPIdentifier controls_currentPosition_id;
133 static NPIdentifier controls_currentItem_id;
134 static NPIdentifier media_duration_id;
135 static NPIdentifier settings_volume_id;
136 static NPIdentifier error_errorCount_id;
137 //////////////////////////////////////
138 //
139 // general initialization and shutdown
140 //
NS_PluginInitialize()141 NPError NS_PluginInitialize()
142 {
143 return NPERR_NO_ERROR;
144 }
145
NS_PluginShutdown()146 void NS_PluginShutdown()
147 {
148 }
149
150 // get values per plugin
NS_PluginGetValue(NPPVariable aVariable,void * aValue)151 NPError NS_PluginGetValue(NPPVariable aVariable, void *aValue)
152 {
153 return PluginGetValue(aVariable, aValue);
154 }
155
postDOMEvent(NPP mInstance,const gchar * id,const gchar * event)156 void postDOMEvent(NPP mInstance, const gchar * id, const gchar * event)
157 {
158 gchar *jscript;
159
160 jscript = g_strdup_printf("javascript:obj_gmp=document.getElementById('%s');"
161 "e_gmp=document.createEvent('Events');"
162 "e_gmp.initEvent('%s',true,true);" "obj_gmp.dispatchEvent(e_gmp);",
163 id, event);
164 NPN_GetURL(mInstance, jscript, NULL);
165 g_free(jscript);
166 }
167
168 // disabled for now due to problems with certain sites
postPlayStateChange(NPP mInstance,const gint state)169 void postPlayStateChange(NPP mInstance, const gint state)
170 {
171 gchar *jscript;
172
173 jscript = g_strdup_printf("javascript:if (typeof OnDSPlayStateChangeEvt == 'function') {"
174 "OnDSPlayStateChangeEvt(%i);}", state);
175 //NPN_GetURL(mInstance, jscript, NULL);
176 g_free(jscript);
177 }
178
NPReasonToString(NPReason reason)179 const gchar *NPReasonToString(NPReason reason)
180 {
181
182 switch (reason) {
183 case NPRES_DONE:
184 return "Done";
185 break;
186 case NPRES_NETWORK_ERR:
187 return "Network Error";
188 break;
189 case NPRES_USER_BREAK:
190 return "User Break";
191 break;
192 default:
193 return "Unknown Reason";
194 }
195
196 }
197
198
NPErrorToString(NPError error)199 const gchar *NPErrorToString(NPError error)
200 {
201
202 switch (error) {
203 case NPERR_NO_ERROR:
204 return "No Error";
205 break;
206 case NPERR_GENERIC_ERROR:
207 return "Generic Error";
208 break;
209 case NPERR_INVALID_INSTANCE_ERROR:
210 return "Invalid Instance Error";
211 break;
212 case NPERR_INVALID_FUNCTABLE_ERROR:
213 return "Invalid Functable Error";
214 break;
215 case NPERR_MODULE_LOAD_FAILED_ERROR:
216 return "Module Load Failed Error";
217 break;
218 case NPERR_OUT_OF_MEMORY_ERROR:
219 return "Out Of Memory Error";
220 break;
221 case NPERR_INVALID_PLUGIN_ERROR:
222 return "Invalid Plugin Error";
223 break;
224 case NPERR_INVALID_PLUGIN_DIR_ERROR:
225 return "Invalid Plugin Dir Error";
226 break;
227 case NPERR_INCOMPATIBLE_VERSION_ERROR:
228 return "Incompatible Version Error";
229 break;
230 case NPERR_INVALID_PARAM:
231 return "Invalid Param";
232 break;
233 case NPERR_INVALID_URL:
234 return "Invalid URL";
235 break;
236 case NPERR_FILE_NOT_FOUND:
237 return "File Not Found";
238 break;
239 case NPERR_NO_DATA:
240 return "No Data";
241 break;
242 case NPERR_STREAM_NOT_SEEKABLE:
243 return "Stream Not Seekable";
244 break;
245 #ifdef NPERR_TIME_RANGE_NOT_SUPPORTED
246 case NPERR_TIME_RANGE_NOT_SUPPORTED:
247 return "Time Range Not Supported";
248 break;
249 #endif
250 #ifdef NPERR_MALFORMED_SITE
251 case NPERR_MALFORMED_SITE:
252 return "Malformed Site";
253 break;
254 #endif
255 default:
256 return "Unknown NPError Code";
257 break;
258 }
259 }
260
261 ////////////////////////////////////////
262 //
263 // CPlugin class implementation
264 //
CPlugin(NPP pNPInstance)265 CPlugin::CPlugin(NPP pNPInstance):
266 mInstance(pNPInstance),
267 m_pNPStream(NULL),
268 mInitialized(FALSE),
269 m_pScriptableObject(NULL),
270 m_pScriptableObjectControls(NULL),
271 m_pScriptableObjectMedia(NULL),
272 m_pScriptableObjectSettings(NULL),
273 m_pScriptableObjectError(NULL),
274 mWindow(0),
275 windowless(FALSE),
276 playlist(NULL),
277 player_launched(FALSE),
278 connection(NULL),
279 dbus_dispatch(NULL),
280 path(NULL),
281 acceptdata(TRUE),
282 playerready(FALSE),
283 nextid(1),
284 lastopened(NULL),
285 cache_size(2048),
286 hidden(FALSE),
287 autostart(1),
288 lastupdate(0),
289 show_controls(1),
290 name(NULL),
291 id(NULL),
292 console(NULL),
293 controls(NULL),
294 user_agent(NULL),
295 page_url(NULL),
296 player_backend(NULL),
297 quicktime_emulation(FALSE),
298 disable_context_menu(FALSE),
299 disable_fullscreen(FALSE),
300 post_dom_events(FALSE),
301 event_mediacomplete(NULL),
302 event_destroy(NULL),
303 event_mousedown(NULL),
304 event_mouseup(NULL),
305 event_mouseclicked(NULL), event_enterwindow(NULL), event_leavewindow(NULL), debug(FALSE),
306 tv_driver(NULL), tv_device(NULL), tv_input(NULL), tv_width(0), tv_height(0)
307 {
308 GRand *rand;
309 GmPrefStore *store;
310 gboolean b;
311
312 NPN_GetValue(mInstance, NPNVWindowNPObject, &sWindowObj);
313
314 // get the page plugin was called from
315 // found at https://developer.mozilla.org/en/Getting_the_page_URL_in_NPAPI_plugin
316 NPIdentifier identifier = NPN_GetStringIdentifier("location");
317 // Declare a local variant value.
318 NPVariant variantValue;
319 // Get the location property from the window object (which is another object).
320 b = NPN_GetProperty(mInstance, sWindowObj, identifier, &variantValue);
321 // Get a pointer to the "location" object.
322 NPObject *locationObj = variantValue.value.objectValue;
323 // Create a "href" identifier.
324 identifier = NPN_GetStringIdentifier("href");
325 // Get the location property from the location object.
326 b = NPN_GetProperty(mInstance, locationObj, identifier, &variantValue);
327 #ifdef NPAPI_USE_UPPERCASE_UTF8
328 page_url = g_strdup_printf("%s", NPVARIANT_TO_STRING(variantValue).UTF8Characters);
329 #else
330 page_url = g_strdup_printf("%s", NPVARIANT_TO_STRING(variantValue).utf8characters);
331 #endif
332
333 // register methods
334 Play_id = NPN_GetStringIdentifier("Play");
335 PlayAt_id = NPN_GetStringIdentifier("PlayAt");
336 Pause_id = NPN_GetStringIdentifier("Pause");
337 PlayPause_id = NPN_GetStringIdentifier("PlayPause");
338 Stop_id = NPN_GetStringIdentifier("Stop");
339 quit_id = NPN_GetStringIdentifier("quit");
340 DoPlay_id = NPN_GetStringIdentifier("DoPlay");
341 DoPause_id = NPN_GetStringIdentifier("DoPause");
342 FastForward_id = NPN_GetStringIdentifier("FastForward");
343 FastReverse_id = NPN_GetStringIdentifier("FastReverse");
344 ff_id = NPN_GetStringIdentifier("ff");
345 rew_id = NPN_GetStringIdentifier("rew");
346 rewind_id = NPN_GetStringIdentifier("rewind");
347 Seek_id = NPN_GetStringIdentifier("Seek");
348 Open_id = NPN_GetStringIdentifier("Open");
349 SetVolume_id = NPN_GetStringIdentifier("SetVolume");
350 GetVolume_id = NPN_GetStringIdentifier("GetVolume");
351 SetFileName_id = NPN_GetStringIdentifier("SetFileName");
352 GetFileName_id = NPN_GetStringIdentifier("GetFileName");
353 SetIsLooping_id = NPN_GetStringIdentifier("SetIsLooping");
354 GetIsLooping_id = NPN_GetStringIdentifier("GetIsLooping");
355 SetAutoPlay_id = NPN_GetStringIdentifier("SetAutoPlay");
356 GetAutoPlay_id = NPN_GetStringIdentifier("GetAutoPlay");
357 SetHREF_id = NPN_GetStringIdentifier("SetHREF");
358 GetHREF_id = NPN_GetStringIdentifier("GetHREF");
359 SetURL_id = NPN_GetStringIdentifier("SetURL");
360 GetURL_id = NPN_GetStringIdentifier("GetURL");
361 GetMIMEType_id = NPN_GetStringIdentifier("GetMIMEType");
362 getTime_id = NPN_GetStringIdentifier("getTime");
363 getDuration_id = NPN_GetStringIdentifier("getDuration");
364 getPercent_id = NPN_GetStringIdentifier("getPercent");
365 getBitrate_id = NPN_GetStringIdentifier("getBitrate");
366 isplaying_id = NPN_GetStringIdentifier("isplaying");
367 playlistAppend_id = NPN_GetStringIdentifier("playlistAppend");
368 playlistClear_id = NPN_GetStringIdentifier("playlistClear");
369 onClick_id = NPN_GetStringIdentifier("onClick");
370 onMediaComplete_id = NPN_GetStringIdentifier("onMediaComplete");
371 onMouseUp_id = NPN_GetStringIdentifier("onMouseUp");
372 onMouseDown_id = NPN_GetStringIdentifier("onMouseDown");
373 onMouseOut_id = NPN_GetStringIdentifier("onMouseOut");
374 onMouseOver_id = NPN_GetStringIdentifier("onMouseOver");
375 onDestroy_id = NPN_GetStringIdentifier("onDestroy");
376
377 controls_play_id = NPN_GetStringIdentifier("play");
378 controls_pause_id = NPN_GetStringIdentifier("pause");
379 controls_stop_id = NPN_GetStringIdentifier("stop");
380 controls_fastForward_id = NPN_GetStringIdentifier("fastForward");
381 controls_fastReverse_id = NPN_GetStringIdentifier("fastReverse");
382 controls_step_id = NPN_GetStringIdentifier("step");
383
384 media_getItemInfo_id = NPN_GetStringIdentifier("getItemInfo");
385
386 // register properties
387 filename_id = NPN_GetStringIdentifier("filename");
388 src_id = NPN_GetStringIdentifier("src");
389 ShowControls_id = NPN_GetStringIdentifier("ShowControls");
390 fullscreen_id = NPN_GetStringIdentifier("fullscreen");
391 showlogo_id = NPN_GetStringIdentifier("showlogo");
392 playState_id = NPN_GetStringIdentifier("playState");
393 controls_id = NPN_GetStringIdentifier("controls");
394 controls_currentItem_id = NPN_GetStringIdentifier("currentItem");
395 media_id = NPN_GetStringIdentifier("media");
396 settings_id = NPN_GetStringIdentifier("settings");
397 error_id = NPN_GetStringIdentifier("error");
398
399 status_id = NPN_GetStringIdentifier("status");
400 URL_id = NPN_GetStringIdentifier("URL");
401 versionInfo_id = NPN_GetStringIdentifier("versionInfo");
402 enabled_id = NPN_GetStringIdentifier("enabled");
403 enableContextMenu_id = NPN_GetStringIdentifier("enableContextMenu");
404 controls_currentPosition_id = NPN_GetStringIdentifier("currentPosition");
405 media_duration_id = NPN_GetStringIdentifier("duration");
406 settings_volume_id = NPN_GetStringIdentifier("volume");
407 error_errorCount_id = NPN_GetStringIdentifier("errorCount");
408
409 // generate a random controlid
410 rand = g_rand_new();
411 controlid = g_rand_int_range(rand, 0, 65535);
412 g_rand_free(rand);
413
414 if (path == NULL) {
415 path = g_strdup_printf("/control/%i", controlid);
416 // printf("using path %s\n",path);
417 }
418 #ifdef ENABLE_NLS
419 bindtextdomain(GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
420 bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
421 textdomain(GETTEXT_PACKAGE);
422 #endif
423 printf(_("gecko mediaplayer v%s\n"), VERSION);
424
425 g_type_init();
426 store = gm_pref_store_new("gecko-mediaplayer");
427 if (store != NULL) {
428 debug_level = gm_pref_store_get_int(store, DEBUG_LEVEL);
429 gm_log(debug_level, G_LOG_LEVEL_INFO, "debug_level = %i", debug_level);
430 player_backend = gm_pref_store_get_string(store, PLAYER_BACKEND);
431 gm_log(debug_level, G_LOG_LEVEL_INFO, "Using player backend of '%s'\n",
432 (player_backend == NULL
433 || strlen(player_backend) == 0) ? "gnome-mplayer" : player_backend);
434 gm_pref_store_free(store);
435 } else {
436 gm_log(TRUE, G_LOG_LEVEL_INFO, "Unable to find preference store, setting debug_level to 1");
437 debug_level = 1;
438 }
439
440
441 if (connection == NULL) {
442 connection = dbus_hookup(this);
443 }
444 pluginSpecific(this);
445
446 mInitialized = TRUE;
447 }
448
~CPlugin()449 CPlugin::~CPlugin()
450 {
451 // mScriptablePeer may be also held by the browser
452 // so releasing it here does not guarantee that it is over
453 // we should take precaution in case it will be called later
454 // and zero its mPlugin member
455 // mScriptablePeer->SetInstance(NULL);
456 // NS_IF_RELEASE(mScriptablePeer);
457
458 if (mInitialized)
459 shut();
460 if (sWindowObj)
461 NPN_ReleaseObject(sWindowObj);
462
463 mInstance = NULL;
464 /*
465 if (mControlsScriptablePeer != NULL) {
466 mControlsScriptablePeer->SetInstance(NULL);
467 mControlsScriptablePeer->Release();
468 NS_IF_RELEASE(mControlsScriptablePeer);
469 }
470 */
471 // clearPreference(this, "general.useragent.override");
472
473 if (m_pScriptableObjectControls) {
474 NPN_ReleaseObject(m_pScriptableObjectControls);
475 }
476
477 if (m_pScriptableObject) {
478 NPN_ReleaseObject(m_pScriptableObject);
479 }
480 }
481
482
483
init(NPWindow * pNPWindow)484 NPBool CPlugin::init(NPWindow * pNPWindow)
485 {
486 if (pNPWindow == NULL)
487 return FALSE;
488
489 m_Window = pNPWindow;
490 mInitialized = TRUE;
491
492 return mInitialized;
493 }
494
handleEvent(void * event)495 int16 CPlugin::handleEvent(void *event)
496 {
497 #ifdef XP_MAC
498 NPEvent *ev = (NPEvent *) event;
499 if (m_Window) {
500 Rect box = { m_Window->y, m_Window->x,
501 m_Window->y + m_Window->height, m_Window->x + m_Window->width
502 };
503 if (ev->what == updateEvt) {
504 ::TETextBox(m_String, strlen(m_String), &box, teJustCenter);
505 }
506 }
507 #endif
508 return 0;
509 }
510
SetWindow(NPWindow * aWindow)511 NPError CPlugin::SetWindow(NPWindow * aWindow)
512 {
513 GError *error = NULL;
514 gchar *argvn[255];
515 gint arg = 0;
516 gint ok;
517 ListItem *item;
518 gchar *app_name;
519
520 if (!acceptdata)
521 return NPERR_NO_ERROR;
522
523 if (aWindow == NULL)
524 return NPERR_NO_ERROR;
525
526 mX = aWindow->x;
527 mY = aWindow->y;
528 mWidth = aWindow->width;
529 mHeight = aWindow->height;
530 if (mWindow != (Window) aWindow->window) {
531 mWindow = (Window) aWindow->window;
532 NPSetWindowCallbackStruct *ws_info = (NPSetWindowCallbackStruct *) aWindow->ws_info;
533 }
534
535
536 if (player_launched && mWidth > 0 && mHeight > 0) {
537 resize_window(this, NULL, mWidth, mHeight);
538 }
539
540 if (!player_launched && mWidth > 0 && mHeight > 0) {
541 app_name = NULL;
542 if (player_backend != NULL) {
543 app_name = g_find_program_in_path(player_backend);
544 }
545 if (app_name == NULL) {
546 app_name = g_find_program_in_path("gnome-mplayer");
547 if (app_name == NULL)
548 app_name = g_find_program_in_path("gnome-mplayer-minimal");
549 }
550
551 argvn[arg++] = g_strdup_printf("%s", app_name);
552 argvn[arg++] = g_strdup_printf("--window=%i", (gint) mWindow);
553 argvn[arg++] = g_strdup_printf("--controlid=%i", controlid);
554 argvn[arg++] = g_strdup_printf("--width=%i", mWidth);
555 argvn[arg++] = g_strdup_printf("--height=%i", mHeight);
556 argvn[arg++] = g_strdup_printf("--autostart=%i", autostart);
557 argvn[arg++] = g_strdup_printf("--showcontrols=%i", show_controls);
558 if (disable_context_menu == TRUE)
559 argvn[arg++] = g_strdup_printf("--disablecontextmenu");
560 if (disable_fullscreen == TRUE)
561 argvn[arg++] = g_strdup_printf("--disablefullscreen");
562 if (debug == TRUE)
563 argvn[arg++] = g_strdup_printf("--verbose");
564 if (name != NULL)
565 argvn[arg++] = g_strdup_printf("--rpname=%s", name);
566 if (console != NULL)
567 argvn[arg++] = g_strdup_printf("--rpconsole=%s", console);
568 if (controls != NULL) {
569 argvn[arg++] = g_strdup_printf("--rpcontrols=%s", controls);
570 }
571 if (tv_device != NULL) {
572 argvn[arg++] = g_strdup_printf("--tvdevice=%s", tv_device);
573 }
574 if (tv_driver != NULL) {
575 argvn[arg++] = g_strdup_printf("--tvdriver=%s", tv_driver);
576 }
577 if (tv_input != NULL) {
578 argvn[arg++] = g_strdup_printf("--tvinput=%s", tv_input);
579 }
580 if (tv_width > 0) {
581 argvn[arg++] = g_strdup_printf("--tvwidth=%i", tv_width);
582 }
583 if (tv_height > 0) {
584 argvn[arg++] = g_strdup_printf("--tvheight=%i", tv_height);
585 }
586
587 argvn[arg] = NULL;
588 playerready = FALSE;
589 ok = g_spawn_async(NULL, argvn, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, &error);
590
591 if (ok) {
592 player_launched = TRUE;
593 } else {
594 gm_log(debug_level, G_LOG_LEVEL_INFO, "Unable to launch %s: %s\n", app_name,
595 error->message);
596 g_error_free(error);
597 error = NULL;
598 }
599
600 g_free(app_name);
601
602 if (post_dom_events && id != NULL) {
603 postDOMEvent(mInstance, id, "qt_begin");
604 }
605 //postPlayStateChange(mInstance, STATE_READY);
606 }
607
608 if (playlist != NULL) {
609 item = (ListItem *) playlist->data;
610 if (item && !item->play)
611 item = list_find_next_playable(playlist);
612 if (item && !item->requested) {
613 item->cancelled = FALSE;
614 if (item->streaming) {
615 gm_log(debug_level, G_LOG_LEVEL_INFO,
616 "Calling open_location with item = %p src = %s\n", item, item->src);
617 open_location(this, item, FALSE);
618 item->requested = 1;
619 } else {
620 item->requested = 1;
621 gm_log(debug_level, G_LOG_LEVEL_INFO,
622 "Calling GetURLNotify with item = %p src = %s\n", item, item->src);
623 this->GetURLNotify(mInstance, item->src, NULL, item);
624 }
625 }
626 }
627 return NPERR_NO_ERROR;
628 }
629
630
shut()631 void CPlugin::shut()
632 {
633 ListItem *item;
634 GList *iter;
635
636 acceptdata = FALSE;
637 mInitialized = FALSE;
638
639 if (playlist != NULL) {
640 for (iter = playlist; iter != NULL; iter = g_list_next(iter)) {
641 item = (ListItem *) iter->data;
642 if (item != NULL) {
643 item->cancelled = TRUE;
644 if (item->controlid != 0) {
645 send_signal_when_ready(this, item, "Terminate");
646 }
647 }
648 }
649 }
650 send_signal_when_ready(this, NULL, "Terminate");
651 playerready = FALSE;
652 playlist = list_clear(playlist);
653
654 if (event_destroy != NULL) {
655 NPN_GetURL(mInstance, event_destroy, NULL);
656 }
657
658 if (connection != NULL) {
659 connection = dbus_unhook(connection, this);
660 }
661 }
662
isInitialized()663 NPBool CPlugin::isInitialized()
664 {
665 return mInitialized;
666 }
667
NewStream(NPMIMEType type,NPStream * stream,NPBool seekable,uint16 * stype)668 NPError CPlugin::NewStream(NPMIMEType type, NPStream * stream, NPBool seekable, uint16 * stype)
669 {
670 if (g_strrstr(stream->url, "javascript") == NULL) {
671 gm_log(debug_level, G_LOG_LEVEL_DEBUG, "New Stream Requested - %s\n", stream->url);
672 }
673
674 if (g_strrstr(stream->url, "javascript") == NULL && stream->notifyData == NULL) {
675 gm_log(debug_level, G_LOG_LEVEL_DEBUG, "item is NULL for %s\n", stream->url);
676 }
677
678 return NPERR_NO_ERROR;
679 }
680
DestroyStream(NPStream * stream,NPError reason)681 NPError CPlugin::DestroyStream(NPStream * stream, NPError reason)
682 {
683 ListItem *item;
684 ListItem *fetch_item;
685 gchar *text;
686 gboolean fetch_next = TRUE;
687
688 if (g_strrstr(stream->url, "javascript") == NULL)
689 gm_log(debug_level, G_LOG_LEVEL_MESSAGE, "Entering destroy stream reason = %i - %s for %s",
690 reason, NPErrorToString(reason), stream->url);
691
692 if (reason == NPERR_NO_ERROR) {
693 item = (ListItem *) stream->notifyData;
694 // item = list_find(playlist, (gchar*)stream->url);
695
696 if (item == NULL) {
697 gm_log(debug_level, G_LOG_LEVEL_DEBUG, "Leaving destroy stream - item not found");
698 return NPERR_NO_ERROR;
699 }
700
701 if (item->localfp) {
702 fclose(item->localfp);
703 item->retrieved = TRUE;
704 item->localfp = 0;
705 send_signal_with_double(this, item, "SetCachePercent", 1.0);
706 text = g_strdup_printf(_("Cache fill: %2.2f%%"), 100.0);
707 send_signal_with_string(this, item, "SetProgressText", text);
708 g_free(text);
709 }
710
711
712 if (!item->opened && item->play) {
713 gm_log(debug_level, G_LOG_LEVEL_MESSAGE, "item '%s' is not opened and is playable",
714 item->src);
715 if (!item->streaming)
716 item->streaming = streaming(item->src);
717 if (!item->streaming) {
718 gm_log(debug_level, G_LOG_LEVEL_DEBUG, "in Destroy Stream");
719 playlist = list_parse_qt(playlist, item, FALSE);
720 playlist = list_parse_qt2(playlist, item, FALSE);
721 playlist = list_parse_asx(playlist, item, FALSE);
722 playlist = list_parse_qml(playlist, item, FALSE);
723 playlist = list_parse_ram(playlist, item, FALSE);
724 }
725
726 if (item->playlist == FALSE) {
727 if (item != NULL && item->queuedtoplay == FALSE) {
728 if (!list_item_opened(playlist)) {
729 item = list_find_first_playable(playlist);
730 }
731 }
732 if (item != NULL) {
733 if (item->play == TRUE && item->opened == FALSE) {
734
735 open_location(this, item, TRUE);
736 if (post_dom_events && this->id != NULL) {
737 postDOMEvent(mInstance, this->id, "qt_play");
738 }
739 }
740 }
741 } else {
742 item = list_find_first_playable(playlist);
743 if (item != NULL) {
744 if (!item->streaming) {
745 if (item->requested == FALSE) {
746 gm_log(debug_level, G_LOG_LEVEL_INFO, "Getting URL '%s'", item->src);
747 item->requested = TRUE;
748 this->GetURLNotify(mInstance, item->src, NULL, item);
749 fetch_next = FALSE;
750 }
751 } else {
752 if (!list_item_opened(playlist))
753 open_location(this, item, FALSE);
754 }
755 }
756 }
757
758 // fetch the next item on the playlist
759 if (fetch_next) {
760 fetch_item = list_find_next_playable_after_listitem(playlist, item);
761 if (fetch_item != NULL) {
762 if (!fetch_item->streaming) {
763 gm_log(debug_level, G_LOG_LEVEL_INFO, "Prefetching URL '%s'",
764 fetch_item->src);
765 fetch_item->requested = TRUE;
766 this->GetURLNotify(mInstance, fetch_item->src, NULL, fetch_item);
767 }
768 }
769 }
770 }
771
772 } else if (reason == NPERR_INVALID_URL) {
773 item = (ListItem *) stream->notifyData;
774 if (item) {
775 gm_log(debug_level, G_LOG_LEVEL_INFO, "Destroy Stream, invalid url, item is %s\n",
776 item->src);
777 } else {
778 if (g_strrstr(stream->url, "javascript") == NULL) {
779 gm_log(debug_level, G_LOG_LEVEL_INFO,
780 "Destroy Stream, network error, item is NULL\n");
781 }
782 }
783 } else {
784 item = (ListItem *) stream->notifyData;
785 // item = list_find(playlist, (gchar*)stream->url);
786 if (g_strrstr(stream->url, "javascript") == NULL)
787 gm_log(debug_level, G_LOG_LEVEL_DEBUG, "Exiting destroy stream reason = %i for %s\n",
788 reason, stream->url);
789 if (item == NULL) {
790 return NPERR_NO_ERROR;
791 } else {
792 if (post_dom_events && this->id != NULL) {
793 postDOMEvent(mInstance, this->id, "qt_load");
794 }
795 postPlayStateChange(mInstance, STATE_TRANSITIONING);
796 }
797
798 if (item->localfp) {
799 fclose(item->localfp);
800 item->retrieved = FALSE;
801 item->localfp = 0;
802 }
803 }
804
805 gm_log(debug_level, G_LOG_LEVEL_INFO,
806 "Leaving DestroyStream for %s and the playlist looks like this", stream->url);
807 list_dump(playlist);
808 return NPERR_NO_ERROR;
809 }
810
URLNotify(const char * url,NPReason reason,void * notifyData)811 void CPlugin::URLNotify(const char *url, NPReason reason, void *notifyData)
812 {
813 ListItem *item = (ListItem *) notifyData;
814
815 gm_log(debug_level, G_LOG_LEVEL_MESSAGE, "URL Notify url = '%s'\nreason = %i - %s\n%s\n%s\n%s",
816 url, reason, NPReasonToString(reason), item->src, item->local, path);
817 if (reason == NPRES_DONE) {
818 // done
819 } else if (reason == NPRES_NETWORK_ERR) {
820 // error
821 } else if (reason == NPRES_USER_BREAK) {
822 // user cancelled
823 } else {
824 // something else
825 }
826 }
827
WriteReady(NPStream * stream)828 int32 CPlugin::WriteReady(NPStream * stream)
829 {
830 ListItem *item;
831 gchar *path;
832 gchar *tmp;
833
834 // printf("WriteReady called\n");
835 if (!acceptdata) {
836 gm_log(debug_level, G_LOG_LEVEL_INFO, "Not accepting data\n");
837 NPN_DestroyStream(mInstance, stream, NPERR_GENERIC_ERROR);
838 return -1;
839 }
840
841
842 item = (ListItem *) stream->notifyData;
843 // item = list_find(playlist, (gchar*)stream->url);
844 if (item == NULL) {
845
846 if (mode == NP_FULL) {
847 return -1;
848 } else {
849 gm_log(debug_level, G_LOG_LEVEL_INFO, "item is null\nstream url %s\n", stream->url);
850 NPN_DestroyStream(mInstance, stream, NPERR_NO_ERROR);
851 return -1;
852 }
853 } else {
854 if (g_ascii_strcasecmp(item->src, stream->url) != 0) {
855 g_strlcpy(item->src, stream->url, 4096);
856 }
857 }
858
859 // printf("Write Ready item url = %s\n%s\n",item->src,stream->url);
860
861 if (item->cancelled) {
862 gm_log(debug_level, G_LOG_LEVEL_INFO, "cancelling WriteReady\n");
863 NPN_DestroyStream(mInstance, stream, NPERR_NO_ERROR);
864 return -1;
865 }
866
867 if (strlen(item->local) == 0) {
868 path = g_strdup_printf("%s/gnome-mplayer/plugin", g_get_user_cache_dir());
869 if (!g_file_test(path, G_FILE_TEST_IS_DIR)) {
870 g_mkdir_with_parents(path, 0775);
871 }
872 tmp = gm_tempname(path, "gecko-mediaplayerXXXXXX");
873 g_snprintf(item->local, 1024, "%s", tmp);
874 g_free(tmp);
875 g_free(path);
876 if (strstr(mimetype, "midi") != NULL) {
877 g_strlcat(item->local, ".mid", 1024);
878 }
879 if (strstr(mimetype, "mp3") != NULL) {
880 g_strlcat(item->local, ".mp3", 1024);
881 }
882 if (strstr(mimetype, "audio/mpeg") != NULL) {
883 g_strlcat(item->local, ".mp3", 1024);
884 }
885 if (strstr(mimetype, "audio/x-mod") != NULL) {
886 g_strlcat(item->local, ".mod", 1024);
887 }
888 if (strstr(mimetype, "flac") != NULL) {
889 g_strlcat(item->local, ".flac", 1024);
890 }
891 }
892
893 if (item->retrieved) {
894 gm_log(debug_level, G_LOG_LEVEL_INFO, "Duplicate request, item already retrieved\n");
895 NPN_DestroyStream(mInstance, stream, NPERR_NO_ERROR);
896 return -1;
897 }
898
899 return STREAMBUFSIZE;
900 }
901
Write(NPStream * stream,int32 offset,int32 len,void * buffer)902 int32 CPlugin::Write(NPStream * stream, int32 offset, int32 len, void *buffer)
903 {
904 ListItem *item;
905 int32 wrotebytes = -1;
906 gchar *text;
907 gdouble percent = 0.0;
908 gdouble rate = 0.0;
909 gchar *upper = NULL;
910
911 gm_log(debug_level, G_LOG_LEVEL_DEBUG, "Write Called\n");
912 if (!acceptdata) {
913 gm_log(debug_level, G_LOG_LEVEL_INFO, "not accepting data\n");
914 NPN_DestroyStream(mInstance, stream, NPERR_NO_ERROR);
915 return -1;
916 }
917
918 item = (ListItem *) stream->notifyData;
919
920 if (item == NULL) {
921 gm_log(debug_level, G_LOG_LEVEL_DEBUG, "item is NULL\n");
922 gm_log(debug_level, G_LOG_LEVEL_INFO, _("Write unable to write because item is NULL\n"));
923 NPN_DestroyStream(mInstance, stream, NPERR_GENERIC_ERROR);
924 return -1;
925 }
926
927 if (item->cancelled || item->retrieved) {
928 gm_log(debug_level, G_LOG_LEVEL_DEBUG, "cancelled\n");
929 NPN_DestroyStream(mInstance, stream, NPERR_NO_ERROR);
930 return -1;
931 }
932
933 upper = g_ascii_strup((char *) buffer, len);
934 if (strstr((char *) buffer, "ICY 200 OK") != NULL
935 || strstr((char *) buffer, "Content-length:") != NULL
936 || (upper != NULL && strstr(upper, "<HTML>") != NULL) || item->streaming == TRUE
937 || strstr(item->src, "file://") != NULL) {
938
939 item->streaming = TRUE;
940 open_location(this, item, FALSE);
941 if (post_dom_events && this->id != NULL) {
942 postDOMEvent(mInstance, this->id, "qt_play");
943 }
944 item->requested = TRUE;
945 if (item->localfp) {
946 fclose(item->localfp);
947 }
948 gm_log(debug_level, G_LOG_LEVEL_INFO, "Got IceCast Stream, let mplayer stream it\n");
949 NPN_DestroyStream(mInstance, stream, NPERR_NO_ERROR);
950 return -1;
951 }
952 if (upper != NULL) {
953 g_free(upper);
954 upper = NULL;
955 }
956
957 if ((!item->localfp) && (!item->retrieved)) {
958 gm_log(debug_level, G_LOG_LEVEL_DEBUG, "opening %s for localcache\n", item->local);
959 item->localfp = fopen(item->local, "w+");
960 }
961 gm_log(debug_level, G_LOG_LEVEL_DEBUG, "Write item url = %s\n", item->src);
962
963 if (item->localfp == NULL) {
964 gm_log(debug_level, G_LOG_LEVEL_INFO, "Local cache file is not open, cannot write data\n");
965 NPN_DestroyStream(mInstance, stream, NPERR_GENERIC_ERROR);
966 return -1;
967 }
968 fseek(item->localfp, offset, SEEK_SET);
969 wrotebytes = fwrite(buffer, 1, len, item->localfp);
970 item->localsize += wrotebytes;
971
972 if (item->mediasize != stream->end)
973 item->mediasize = stream->end;
974
975 if (playerready) {
976 percent = 0.0;
977 if (item->mediasize > 0) {
978
979 percent = (gdouble) item->localsize / (gdouble) item->mediasize;
980 if (difftime(time(NULL), lastupdate) > 0.5) {
981 send_signal_with_double(this, item, "SetCachePercent", percent);
982 rate =
983 (gdouble) ((item->localsize -
984 item->lastsize) / 1024.0) / (gdouble) difftime(time(NULL),
985 lastupdate);
986 if (percent > 0.99) {
987 text =
988 g_strdup_printf(_("Caching %iK (%0.1f K/s)"), item->mediasize / 1024, rate);
989 } else {
990 text =
991 g_strdup_printf(_("Cache fill: %2.2f%% (%0.1f K/s)"), percent * 100.0,
992 rate);
993 }
994 send_signal_with_string(this, item, "SetProgressText", text);
995 if (!item->opened)
996 send_signal_with_string(this, item, "SetURL", item->src);
997 if (post_dom_events && this->id != NULL) {
998 postDOMEvent(mInstance, this->id, "qt_progress");
999 postDOMEvent(mInstance, this->id, "qt_durationchange");
1000 }
1001 postPlayStateChange(mInstance, STATE_BUFFERING);
1002
1003 time(&lastupdate);
1004 item->lastsize = item->localsize;
1005 }
1006 }
1007 if (!item->opened) {
1008 if ((item->localsize >= (cache_size * 1024)) && (percent >= 0.2)) {
1009 gm_log(debug_level, G_LOG_LEVEL_DEBUG, "Setting to play because %i > %i\n",
1010 item->localsize, cache_size * 1024);
1011 item->oktoplay = TRUE;
1012 }
1013 if (item->oktoplay == FALSE && (item->localsize > (cache_size * 2 * 1024))
1014 && (cache_size >= 512)) {
1015 // printf("Setting to play because %i > %i (double cache)\n", item->localsize,
1016 // cache_size * 2 * 1024);
1017 item->oktoplay = TRUE;
1018 }
1019 if (item->oktoplay == FALSE) {
1020 if (item->bitrate == 0 && item->bitrate_requests < 5
1021 && ((gint) (percent * 100) > item->bitrate_requests)) {
1022 item->bitrate = request_bitrate(this, item, item->local);
1023 item->bitrate_requests++;
1024 }
1025 if (item->bitrate > 0) {
1026 if (item->localsize / item->bitrate >= 10 && (percent >= 0.2)) {
1027 // printf("Setting to play because %i >= 10\n",
1028 // item->localsize / item->bitrate);
1029 item->oktoplay = TRUE;
1030 if (post_dom_events && this->id != NULL) {
1031 postDOMEvent(mInstance, this->id, "qt_canplay");
1032 }
1033 }
1034 }
1035 }
1036
1037 }
1038 // item->playlist may have been set on an earlier pass, so do not bother
1039 // checking for playlist again, if it is true.
1040
1041 if (!item->opened && item->play && item->oktoplay && !item->playlist) {
1042 gm_log(debug_level, G_LOG_LEVEL_MESSAGE, "item '%s' is not opened and is playable",
1043 item->src);
1044 if (!item->streaming)
1045 item->streaming = streaming(item->src);
1046 if (!item->streaming) {
1047 gm_log(debug_level, G_LOG_LEVEL_DEBUG, "in Write");
1048 // we want to detect a playlist, but not add any items to the actual playlist
1049 // if we find them
1050 playlist = list_parse_qt(playlist, item, TRUE);
1051 playlist = list_parse_qt2(playlist, item, TRUE);
1052 playlist = list_parse_asx(playlist, item, TRUE);
1053 playlist = list_parse_qml(playlist, item, TRUE);
1054 playlist = list_parse_ram(playlist, item, TRUE);
1055 }
1056
1057 gm_log(debug_level, G_LOG_LEVEL_MESSAGE, "Write item (%s) playlist = %i", item->src,
1058 item->playlist);
1059
1060 if (item->playlist == FALSE) {
1061
1062 // queuedtoplay is only true on a item when the player has requested the
1063 // next item to play. So the rule is this
1064 /*
1065 1. Automatically play only the first playable item on the playlist
1066 2. Play queuedtoplay items when they are playable and not opened
1067
1068 */
1069 if (item->queuedtoplay == FALSE) {
1070 if (!list_item_opened(playlist)) {
1071 item = list_find_first_playable(playlist);
1072 }
1073 if (item->play == TRUE && item->opened == FALSE) {
1074
1075 open_location(this, item, TRUE);
1076 if (post_dom_events && this->id != NULL) {
1077 postDOMEvent(mInstance, this->id, "qt_play");
1078 }
1079 }
1080 }
1081 }
1082 }
1083
1084 }
1085
1086 return wrotebytes;
1087 }
1088
1089
Play()1090 void CPlugin::Play()
1091 {
1092 send_signal(this, this->lastopened, "Play");
1093 if (post_dom_events && this->id != NULL) {
1094 postDOMEvent(mInstance, this->id, "qt_play");
1095 }
1096 }
1097
Pause()1098 void CPlugin::Pause()
1099 {
1100 send_signal(this, this->lastopened, "Pause");
1101 if (post_dom_events && this->id != NULL) {
1102 postDOMEvent(mInstance, this->id, "qt_pause");
1103 }
1104 }
1105
Stop()1106 void CPlugin::Stop()
1107 {
1108 send_signal(this, this->lastopened, "Stop");
1109 }
1110
FastForward()1111 void CPlugin::FastForward()
1112 {
1113 send_signal(this, this->lastopened, "FastForward");
1114 postPlayStateChange(mInstance, STATE_SCANFORWARD);
1115 }
1116
FastReverse()1117 void CPlugin::FastReverse()
1118 {
1119 send_signal(this, this->lastopened, "FastReverse");
1120 postPlayStateChange(mInstance, STATE_SCANREVERSE);
1121 }
1122
Seek(double counter)1123 void CPlugin::Seek(double counter)
1124 {
1125 send_signal_with_double(this, this->lastopened, "Seek", counter);
1126 }
1127
SetShowControls(bool value)1128 void CPlugin::SetShowControls(bool value)
1129 {
1130 send_signal_with_boolean(this, this->lastopened, "SetShowControls", value);
1131 }
1132
SetFullScreen(bool value)1133 void CPlugin::SetFullScreen(bool value)
1134 {
1135 send_signal_with_boolean(this, this->lastopened, "SetFullScreen", value);
1136 }
1137
SetVolume(double value)1138 void CPlugin::SetVolume(double value)
1139 {
1140 send_signal_with_double(this, this->lastopened, "Volume", value);
1141 if (post_dom_events && this->id != NULL) {
1142 postDOMEvent(mInstance, this->id, "qt_volumechange");
1143 }
1144 }
1145
GetVolume(double * _retval)1146 void CPlugin::GetVolume(double *_retval)
1147 {
1148 *_retval = request_double_value(this, this->lastopened, "GetVolume");
1149 }
1150
GetFullScreen(bool * _retval)1151 void CPlugin::GetFullScreen(bool * _retval)
1152 {
1153 *_retval = request_boolean_value(this, this->lastopened, "GetFullScreen");
1154 }
1155
GetShowControls(bool * _retval)1156 void CPlugin::GetShowControls(bool * _retval)
1157 {
1158 *_retval = request_boolean_value(this, this->lastopened, "GetShowControls");
1159 }
1160
GetTime(double * _retval)1161 void CPlugin::GetTime(double *_retval)
1162 {
1163 *_retval = request_double_value(this, this->lastopened, "GetTime");
1164 }
1165
GetDuration(double * _retval)1166 void CPlugin::GetDuration(double *_retval)
1167 {
1168 *_retval = request_double_value(this, this->lastopened, "GetDuration");
1169 }
1170
GetPercent(double * _retval)1171 void CPlugin::GetPercent(double *_retval)
1172 {
1173 *_retval = request_double_value(this, this->lastopened, "GetPercent");
1174 }
1175
GetBitrate(int * _retval)1176 void CPlugin::GetBitrate(int *_retval)
1177 {
1178 *_retval = request_int_value(this, this->lastopened, "GetBitrate");
1179 }
1180
1181
SetFilename(const char * filename)1182 void CPlugin::SetFilename(const char *filename)
1183 {
1184 ListItem *item;
1185
1186 if (filename == NULL)
1187 return;
1188
1189 item = g_new0(ListItem, 1);
1190 g_strlcpy(item->src, filename, 1024);
1191 item->streaming = streaming(item->src);
1192 item->play = TRUE;
1193 item->id = nextid++;
1194 playlist = g_list_append(playlist, item);
1195
1196 send_signal(this, this->lastopened, "Quit");
1197
1198 if (item->streaming) {
1199 open_location(this, item, FALSE);
1200 item->requested = 1;
1201 } else {
1202 item->requested = 1;
1203 this->GetURLNotify(mInstance, item->src, NULL, item);
1204 }
1205 }
1206
GetFilename(char ** filename)1207 void CPlugin::GetFilename(char **filename)
1208 {
1209 ListItem *item = NULL;
1210
1211 if (this->lastopened != NULL) {
1212 *filename = g_strdup(this->lastopened->src);
1213 } else {
1214 if (playlist != NULL)
1215 item = (ListItem *) playlist->data;
1216 if (item != NULL) {
1217 *filename = g_strdup(item->src);
1218 } else {
1219 *filename = NULL;
1220 }
1221 }
1222 }
1223
GetMIMEType(char ** _retval)1224 void CPlugin::GetMIMEType(char **_retval)
1225 {
1226 *_retval = g_strdup(mimetype);
1227 }
1228
GetPlayState(PRInt32 * playstate)1229 void CPlugin::GetPlayState(PRInt32 * playstate)
1230 {
1231 *playstate = request_int_value(this, this->lastopened, "GetPlayState");
1232 }
1233
GetLoop(bool * _retval)1234 void CPlugin::GetLoop(bool * _retval)
1235 {
1236 if (lastopened != NULL) {
1237 *_retval = (bool) lastopened->loop;
1238 } else {
1239 *_retval = FALSE;
1240 }
1241
1242 }
1243
SetLoop(bool value)1244 void CPlugin::SetLoop(bool value)
1245 {
1246 if (lastopened != NULL) {
1247 lastopened->loop = (int) value;
1248 lastopened->loopcount = -1;
1249 }
1250 }
1251
PlayPause()1252 void CPlugin::PlayPause()
1253 {
1254 gint state;
1255
1256 state = request_int_value(this, this->lastopened, "GetPlayState");
1257 if (state == STATE_PAUSED) {
1258 send_signal(this, this->lastopened, "Play");
1259 }
1260
1261 if (state == STATE_PLAYING) {
1262 send_signal(this, this->lastopened, "Pause");
1263 }
1264 }
1265
1266
SetOnClick(const char * event)1267 void CPlugin::SetOnClick(const char *event)
1268 {
1269 if (event_mouseclicked != NULL) {
1270 g_free(event_mouseclicked);
1271 }
1272
1273 if (g_ascii_strncasecmp(event, "javascript:", 11) == 0) {
1274 event_mouseclicked = g_strdup_printf("%s", event);
1275 } else {
1276 event_mouseclicked = g_strdup_printf("javascript:%s", event);
1277 }
1278 }
1279
SetOnMediaComplete(const char * event)1280 void CPlugin::SetOnMediaComplete(const char *event)
1281 {
1282 if (event_mediacomplete != NULL) {
1283 g_free(event_mediacomplete);
1284 }
1285
1286 if (g_ascii_strncasecmp(event, "javascript:", 11) == 0) {
1287 event_mediacomplete = g_strdup_printf("%s", event);
1288 } else {
1289 event_mediacomplete = g_strdup_printf("javascript:%s", event);
1290 }
1291
1292 }
1293
SetOnMouseUp(const char * event)1294 void CPlugin::SetOnMouseUp(const char *event)
1295 {
1296 if (event_mouseup != NULL) {
1297 g_free(event_mouseup);
1298 }
1299
1300 if (g_ascii_strncasecmp(event, "javascript:", 11) == 0) {
1301 event_mouseup = g_strdup_printf("%s", event);
1302 } else {
1303 event_mouseup = g_strdup_printf("javascript:%s", event);
1304 }
1305 }
1306
SetOnMouseDown(const char * event)1307 void CPlugin::SetOnMouseDown(const char *event)
1308 {
1309 if (event_mousedown != NULL) {
1310 g_free(event_mousedown);
1311 }
1312
1313 if (g_ascii_strncasecmp(event, "javascript:", 11) == 0) {
1314 event_mousedown = g_strdup_printf("%s", event);
1315 } else {
1316 event_mousedown = g_strdup_printf("javascript:%s", event);
1317 }
1318 }
1319
SetOnMouseOut(const char * event)1320 void CPlugin::SetOnMouseOut(const char *event)
1321 {
1322 if (event_leavewindow != NULL) {
1323 g_free(event_leavewindow);
1324 }
1325
1326 if (g_ascii_strncasecmp(event, "javascript:", 11) == 0) {
1327 event_leavewindow = g_strdup_printf("%s", event);
1328 } else {
1329 event_leavewindow = g_strdup_printf("javascript:%s", event);
1330 }
1331 }
1332
SetOnMouseOver(const char * event)1333 void CPlugin::SetOnMouseOver(const char *event)
1334 {
1335 if (event_enterwindow != NULL) {
1336 g_free(event_enterwindow);
1337 }
1338
1339 if (g_ascii_strncasecmp(event, "javascript:", 11) == 0) {
1340 event_enterwindow = g_strdup_printf("%s", event);
1341 } else {
1342 event_enterwindow = g_strdup_printf("javascript:%s", event);
1343 }
1344 }
1345
SetOnDestroy(const char * event)1346 void CPlugin::SetOnDestroy(const char *event)
1347 {
1348 if (event_destroy != NULL) {
1349 g_free(event_destroy);
1350 }
1351
1352 if (g_ascii_strncasecmp(event, "javascript:", 11) == 0) {
1353 event_destroy = g_strdup_printf("%s", event);
1354 } else {
1355 event_destroy = g_strdup_printf("javascript:%s", event);
1356 }
1357 }
1358
1359 #ifdef HAVE_CURL
1360
progress_callback(void * clientp,double dltotal,double dlnow,double ultotal,double ulnow)1361 int progress_callback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow)
1362 {
1363 ListItem *item = (ListItem *) clientp;
1364 gdouble percent, rate;
1365 gchar *text;
1366 gboolean ok_to_play = FALSE;
1367 gint id;
1368 gboolean ready;
1369 gboolean newwindow;
1370 CPlugin *plugin = (CPlugin *) item->plugin;
1371 gchar *path;
1372
1373 // skip divide by zero issues
1374 if (dltotal == 0)
1375 return 0; // keeps downloading
1376
1377 if (item->cancelled) {
1378 gm_log(plugin->debug_level, G_LOG_LEVEL_DEBUG, "cancelling download at %f for %s\n", dlnow,
1379 item->src);
1380 return -1; // cancels download
1381 }
1382 //printf("item ready = %i,player ready = %i,%f,%f,%f\n", item->playerready, plugin->playerready,
1383 // dlnow, dltotal, dlnow / dltotal);
1384
1385 item->localsize = dlnow;
1386
1387 if (item->mediasize != dltotal)
1388 item->mediasize = dltotal;
1389
1390 if (plugin->playerready) {
1391 percent = 0.0;
1392 if (item->mediasize > 0) {
1393
1394 percent = (gdouble) item->localsize / (gdouble) item->mediasize;
1395 if (difftime(time(NULL), plugin->lastupdate) > 0.5) {
1396 gm_log(plugin->debug_level, G_LOG_LEVEL_INFO, "updating display id = %i\n",
1397 item->id);
1398 send_signal_with_double(plugin, item, "SetCachePercent", percent);
1399 rate =
1400 (gdouble) ((item->localsize -
1401 item->lastsize) / 1024.0) / (gdouble) difftime(time(NULL),
1402 plugin->lastupdate);
1403 if (percent > 0.99) {
1404 text =
1405 g_strdup_printf(_("Caching %iK (%0.1f K/s)"), item->mediasize / 1024, rate);
1406 } else {
1407 text =
1408 g_strdup_printf(_("Cache fill: %2.2f%% (%0.1f K/s)"), percent * 100.0,
1409 rate);
1410 }
1411 send_signal_with_string(plugin, item, "SetProgressText", text);
1412 if (!item->opened) {
1413 //open_location (plugin, item, TRUE);
1414 //item->opened = TRUE;
1415 //send_signal_with_string(plugin, item, "SetURL", item->src);
1416 }
1417 if (plugin->post_dom_events && plugin->id != NULL) {
1418 postDOMEvent(plugin->mInstance, plugin->id, "qt_progress");
1419 postDOMEvent(plugin->mInstance, plugin->id, "qt_durationchange");
1420 }
1421 postPlayStateChange(plugin->mInstance, STATE_BUFFERING);
1422
1423 time(&(plugin->lastupdate));
1424 item->lastsize = item->localsize;
1425 }
1426 }
1427 }
1428
1429 return 0;
1430 }
1431
CURLGetURLNotify(gpointer data)1432 gpointer CURLGetURLNotify(gpointer data)
1433 {
1434 ListItem *item = (ListItem *) data;
1435 ListItem *fetch_item = NULL;
1436 CPlugin *plugin = (CPlugin *) item->plugin;
1437 FILE *local;
1438 CURL *curl;
1439
1440 if (item) {
1441 local = fopen(item->local, "wb");
1442 if (local) {
1443 curl = curl_easy_init();
1444 if (curl) {
1445
1446 curl_easy_setopt(curl, CURLOPT_URL, item->src);
1447 curl_easy_setopt(curl, CURLOPT_WRITEDATA, local);
1448 curl_easy_setopt(curl, CURLOPT_USERAGENT, "QuickTime/7.6.9");
1449 curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, progress_callback);
1450 curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, item);
1451 curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
1452
1453 curl_easy_perform(curl);
1454 curl_easy_cleanup(curl);
1455 gm_log(plugin->debug_level, G_LOG_LEVEL_INFO, "item retrieved using CURL\n");
1456 //plugin->URLNotify(item->src, NPRES_DONE, item);
1457
1458 }
1459 fclose(local);
1460 gm_log(plugin->debug_level, G_LOG_LEVEL_DEBUG, "fetched %s to %s opened = %i\n",
1461 item->src, item->local, item->opened);
1462 send_signal_with_double(plugin, item, "SetCachePercent", 1.0);
1463 send_signal_with_double(plugin, item, "SetCachePercent", 0.0);
1464 item->retrieved = TRUE;
1465 }
1466
1467 if (!item->opened) {
1468 if (!item->streaming)
1469 item->streaming = streaming(item->src);
1470 if (!item->streaming) {
1471 gm_log(plugin->debug_level, G_LOG_LEVEL_DEBUG, "in CURLGetURLNotify\n");
1472 plugin->playlist = list_parse_qt(plugin->playlist, item, FALSE);
1473 plugin->playlist = list_parse_qt2(plugin->playlist, item, FALSE);
1474 plugin->playlist = list_parse_asx(plugin->playlist, item, FALSE);
1475 plugin->playlist = list_parse_qml(plugin->playlist, item, FALSE);
1476 plugin->playlist = list_parse_ram(plugin->playlist, item, FALSE);
1477 }
1478 // printf("item->play = %i\n", item->play);
1479 // printf("item->src = %i\n", item->src);
1480 // printf("calling open_location from CURLGetURLNotify\n");
1481
1482 if (item->playlist == FALSE) {
1483 if (item != NULL && item->queuedtoplay == FALSE) {
1484 if (!list_item_opened(plugin->playlist)) {
1485 item = list_find_first_playable(plugin->playlist);
1486 }
1487 }
1488 if (item != NULL) {
1489 if (item->play == TRUE && item->opened == FALSE) {
1490
1491 open_location(plugin, item, TRUE);
1492 if (plugin->post_dom_events && plugin->id != NULL) {
1493 postDOMEvent(plugin->mInstance, plugin->id, "qt_loadedfirstframe");
1494 postDOMEvent(plugin->mInstance, plugin->id, "qt_canplay");
1495 postDOMEvent(plugin->mInstance, plugin->id, "qt_play");
1496 }
1497 }
1498 }
1499 } else {
1500 item = list_find_first_playable(plugin->playlist);
1501 if (item != NULL) {
1502 if (!item->streaming) {
1503 if (item->requested == FALSE) {
1504 gm_log(plugin->debug_level, G_LOG_LEVEL_INFO, "Getting URL '%s'",
1505 item->src);
1506 item->requested = TRUE;
1507 plugin->GetURLNotify(plugin->mInstance, item->src, NULL, item);
1508 }
1509 } else {
1510 if (!list_item_opened(plugin->playlist))
1511 open_location(plugin, item, FALSE);
1512 }
1513 }
1514 }
1515
1516 // fetch the next item on the playlist
1517 fetch_item = list_find_next_playable_after_listitem(plugin->playlist, item);
1518 if (fetch_item != NULL) {
1519 if (!fetch_item->streaming) {
1520 gm_log(plugin->debug_level, G_LOG_LEVEL_INFO, "Getting URL '%s'",
1521 fetch_item->src);
1522 fetch_item->requested = TRUE;
1523 CURLGetURLNotify(fetch_item);
1524 }
1525 }
1526
1527 }
1528 }
1529 return NULL;
1530 }
1531
1532
1533 #endif
1534
1535
GetURLNotify(NPP instance,const char * url,const char * target,void * notifyData)1536 NPError CPlugin::GetURLNotify(NPP instance, const char *url, const char *target, void *notifyData)
1537 {
1538 #ifdef HAVE_CURL
1539 ListItem *item;
1540 gchar *path;
1541 gchar *tmp;
1542 #endif
1543
1544 if (g_strrstr(url, "apple.com") == NULL /* && this->quicktime_emulation == 0 */ ) {
1545 return NPN_GetURLNotify(instance, url, target, notifyData);
1546 } else {
1547 #ifdef HAVE_CURL
1548 gm_log(debug_level, G_LOG_LEVEL_DEBUG, "using curl to retrieve data from apple.com site\n");
1549 gm_log(debug_level, G_LOG_LEVEL_DEBUG, "quicktime_emulation = %i\n", quicktime_emulation);
1550
1551 item = (ListItem *) notifyData;
1552 // item = list_find(playlist, (gchar*)stream->url);
1553 if (item == NULL) {
1554
1555 if (this->mode == NP_FULL) {
1556 // printf("adding new item %s\n",stream->url);
1557 item = g_new0(ListItem, 1);
1558 g_strlcpy(item->src, url, 1024);
1559 item->requested = TRUE;
1560 item->play = TRUE;
1561 if (!item->streaming)
1562 item->streaming = streaming(item->src);
1563 playlist = g_list_append(playlist, item);
1564 notifyData = item;
1565 } else {
1566 gm_log(debug_level, G_LOG_LEVEL_DEBUG, "item is null\nstream url %s\n", url);
1567 return -1;
1568 }
1569 } else {
1570 if (g_ascii_strcasecmp(item->src, url) != 0) {
1571 g_strlcpy(item->src, url, 4096);
1572 }
1573 }
1574
1575 if (item->cancelled) {
1576 gm_log(debug_level, G_LOG_LEVEL_DEBUG, "item has been cancelled\n");
1577 return -1;
1578 }
1579
1580 if (strlen(item->local) == 0) {
1581 path = g_strdup_printf("%s/gnome-mplayer/plugin", g_get_user_cache_dir());
1582 if (!g_file_test(path, G_FILE_TEST_IS_DIR)) {
1583 g_mkdir_with_parents(path, 0775);
1584 }
1585 tmp = gm_tempname(path, "gecko-mediaplayerXXXXXX");
1586 g_snprintf(item->local, 1024, "%s", tmp);
1587 g_free(tmp);
1588 g_free(path);
1589 }
1590
1591 if (item->retrieved) {
1592 gm_log(debug_level, G_LOG_LEVEL_DEBUG, "item is already retrieved\n");
1593 return -1;
1594 }
1595
1596 item->plugin = (void *) this;
1597
1598 g_thread_create(CURLGetURLNotify, item, FALSE, NULL);
1599
1600 return NPERR_NO_ERROR;
1601 #else
1602 printf
1603 ("Unable to set user agent for pulling data from apple.com, request will probably fail\n");
1604 return NPN_GetURLNotify(instance, url, target, notifyData);
1605 #endif
1606 }
1607 }
1608
1609
1610 // ==============================
1611 // ! Scriptability related code !
1612 // ==============================
1613 //
1614 // here the plugin is asked by Mozilla to tell if it is scriptable
1615 // we should return a valid interface id and a pointer to
1616 // nsScriptablePeer interface which we should have implemented
1617 // and which should be defined in the corressponding *.xpt file
1618 // in the bin/components folder
1619 class ScriptablePluginObjectBase:public NPObject {
1620 public:
ScriptablePluginObjectBase(NPP npp)1621 ScriptablePluginObjectBase(NPP npp):mNpp(npp) {
1622 };
~ScriptablePluginObjectBase()1623 virtual ~ ScriptablePluginObjectBase() {
1624 };
1625
1626 // Virtual NPObject hooks called through this base class. Override
1627 // as you see fit.
1628
1629 virtual void Invalidate();
1630 virtual bool HasMethod(NPIdentifier name);
1631 virtual bool Invoke(NPIdentifier name, const NPVariant * args,
1632 uint32_t argCount, NPVariant * result);
1633 virtual bool InvokeDefault(const NPVariant * args, uint32_t argCount, NPVariant * result);
1634 virtual bool HasProperty(NPIdentifier name);
1635 virtual bool GetProperty(NPIdentifier name, NPVariant * result);
1636 virtual bool SetProperty(NPIdentifier name, const NPVariant * value);
1637 virtual bool RemoveProperty(NPIdentifier name);
1638
1639 public:
1640
1641 static void _Deallocate(NPObject * npobj);
1642 static void _Invalidate(NPObject * npobj);
1643 static bool _HasMethod(NPObject * npobj, NPIdentifier name);
1644 static bool _Invoke(NPObject * npobj, NPIdentifier name,
1645 const NPVariant * args, uint32_t argCount, NPVariant * result);
1646 static bool _InvokeDefault(NPObject * npobj, const NPVariant * args,
1647 uint32_t argCount, NPVariant * result);
1648 static bool _HasProperty(NPObject * npobj, NPIdentifier name);
1649 static bool _GetProperty(NPObject * npobj, NPIdentifier name, NPVariant * result);
1650 static bool _SetProperty(NPObject * npobj, NPIdentifier name, const NPVariant * value);
1651 static bool _RemoveProperty(NPObject * npobj, NPIdentifier name);
1652
1653 protected:
1654 NPP mNpp;
1655 };
1656
1657 #define DECLARE_NPOBJECT_CLASS_WITH_BASE(_class, ctor) \
1658 static NPClass s##_class##_NPClass = { \
1659 NP_CLASS_STRUCT_VERSION, \
1660 ctor, \
1661 ScriptablePluginObjectBase::_Deallocate, \
1662 ScriptablePluginObjectBase::_Invalidate, \
1663 ScriptablePluginObjectBase::_HasMethod, \
1664 ScriptablePluginObjectBase::_Invoke, \
1665 ScriptablePluginObjectBase::_InvokeDefault, \
1666 ScriptablePluginObjectBase::_HasProperty, \
1667 ScriptablePluginObjectBase::_GetProperty, \
1668 ScriptablePluginObjectBase::_SetProperty, \
1669 ScriptablePluginObjectBase::_RemoveProperty \
1670 }
1671
1672 #define GET_NPOBJECT_CLASS(_class) &s##_class##_NPClass
1673
Invalidate()1674 void ScriptablePluginObjectBase::Invalidate()
1675 {
1676 }
1677
HasMethod(NPIdentifier name)1678 bool ScriptablePluginObjectBase::HasMethod(NPIdentifier name)
1679 {
1680 return false;
1681 }
1682
Invoke(NPIdentifier name,const NPVariant * args,uint32_t argCount,NPVariant * result)1683 bool ScriptablePluginObjectBase::Invoke(NPIdentifier name, const NPVariant * args,
1684 uint32_t argCount, NPVariant * result)
1685 {
1686 return false;
1687 }
1688
InvokeDefault(const NPVariant * args,uint32_t argCount,NPVariant * result)1689 bool ScriptablePluginObjectBase::InvokeDefault(const NPVariant * args,
1690 uint32_t argCount, NPVariant * result)
1691 {
1692 return false;
1693 }
1694
HasProperty(NPIdentifier name)1695 bool ScriptablePluginObjectBase::HasProperty(NPIdentifier name)
1696 {
1697 return false;
1698 }
1699
GetProperty(NPIdentifier name,NPVariant * result)1700 bool ScriptablePluginObjectBase::GetProperty(NPIdentifier name, NPVariant * result)
1701 {
1702
1703 VOID_TO_NPVARIANT(*result);
1704
1705 return false;
1706 }
1707
SetProperty(NPIdentifier name,const NPVariant * value)1708 bool ScriptablePluginObjectBase::SetProperty(NPIdentifier name, const NPVariant * value)
1709 {
1710 return false;
1711 }
1712
RemoveProperty(NPIdentifier name)1713 bool ScriptablePluginObjectBase::RemoveProperty(NPIdentifier name)
1714 {
1715 return false;
1716 }
1717
1718 // static
_Deallocate(NPObject * npobj)1719 void ScriptablePluginObjectBase::_Deallocate(NPObject * npobj)
1720 {
1721 // Call the virtual destructor.
1722 delete(ScriptablePluginObjectBase *) npobj;
1723 }
1724
1725 // static
_Invalidate(NPObject * npobj)1726 void ScriptablePluginObjectBase::_Invalidate(NPObject * npobj)
1727 {
1728 ((ScriptablePluginObjectBase *) npobj)->Invalidate();
1729 }
1730
1731 // static
_HasMethod(NPObject * npobj,NPIdentifier name)1732 bool ScriptablePluginObjectBase::_HasMethod(NPObject * npobj, NPIdentifier name)
1733 {
1734 return ((ScriptablePluginObjectBase *) npobj)->HasMethod(name);
1735 }
1736
1737 // static
_Invoke(NPObject * npobj,NPIdentifier name,const NPVariant * args,uint32_t argCount,NPVariant * result)1738 bool ScriptablePluginObjectBase::_Invoke(NPObject * npobj, NPIdentifier name,
1739 const NPVariant * args, uint32_t argCount,
1740 NPVariant * result)
1741 {
1742 return ((ScriptablePluginObjectBase *) npobj)->Invoke(name, args, argCount, result);
1743 }
1744
1745 // static
_InvokeDefault(NPObject * npobj,const NPVariant * args,uint32_t argCount,NPVariant * result)1746 bool ScriptablePluginObjectBase::_InvokeDefault(NPObject * npobj,
1747 const NPVariant * args,
1748 uint32_t argCount, NPVariant * result)
1749 {
1750 return ((ScriptablePluginObjectBase *) npobj)->InvokeDefault(args, argCount, result);
1751 }
1752
1753 // static
_HasProperty(NPObject * npobj,NPIdentifier name)1754 bool ScriptablePluginObjectBase::_HasProperty(NPObject * npobj, NPIdentifier name)
1755 {
1756 return ((ScriptablePluginObjectBase *) npobj)->HasProperty(name);
1757 }
1758
1759 // static
_GetProperty(NPObject * npobj,NPIdentifier name,NPVariant * result)1760 bool ScriptablePluginObjectBase::_GetProperty(NPObject * npobj, NPIdentifier name,
1761 NPVariant * result)
1762 {
1763 return ((ScriptablePluginObjectBase *) npobj)->GetProperty(name, result);
1764 }
1765
1766 // static
_SetProperty(NPObject * npobj,NPIdentifier name,const NPVariant * value)1767 bool ScriptablePluginObjectBase::_SetProperty(NPObject * npobj, NPIdentifier name,
1768 const NPVariant * value)
1769 {
1770 return ((ScriptablePluginObjectBase *) npobj)->SetProperty(name, value);
1771 }
1772
1773 // static
_RemoveProperty(NPObject * npobj,NPIdentifier name)1774 bool ScriptablePluginObjectBase::_RemoveProperty(NPObject * npobj, NPIdentifier name)
1775 {
1776 return ((ScriptablePluginObjectBase *) npobj)->RemoveProperty(name);
1777 }
1778
1779 class ScriptablePluginObjectControls:public ScriptablePluginObjectBase {
1780 public:
ScriptablePluginObjectControls(NPP npp)1781 ScriptablePluginObjectControls(NPP npp):ScriptablePluginObjectBase(npp) {
1782 };
1783 virtual bool HasMethod(NPIdentifier name);
1784 virtual bool Invoke(NPIdentifier name, const NPVariant * args,
1785 uint32_t argCount, NPVariant * result);
1786 virtual bool InvokeDefault(const NPVariant * args, uint32_t argCount, NPVariant * result);
1787 virtual bool HasProperty(NPIdentifier name);
1788 virtual bool GetProperty(NPIdentifier name, NPVariant * result);
1789 virtual bool SetProperty(NPIdentifier name, const NPVariant * value);
1790
1791 };
1792
AllocateScriptablePluginObjectControls(NPP npp,NPClass * aClass)1793 static NPObject *AllocateScriptablePluginObjectControls(NPP npp, NPClass * aClass)
1794 {
1795 return new ScriptablePluginObjectControls(npp);
1796 }
1797
1798 DECLARE_NPOBJECT_CLASS_WITH_BASE(ScriptablePluginObjectControls,
1799 AllocateScriptablePluginObjectControls);
1800
HasMethod(NPIdentifier name)1801 bool ScriptablePluginObjectControls::HasMethod(NPIdentifier name)
1802 {
1803 if (name == controls_play_id ||
1804 name == controls_pause_id ||
1805 name == controls_stop_id ||
1806 name == controls_fastForward_id ||
1807 name == controls_fastReverse_id || name == controls_step_id) {
1808 return true;
1809 } else {
1810 return false;
1811 }
1812 }
1813
Invoke(NPIdentifier name,const NPVariant * args,uint32_t argCount,NPVariant * result)1814 bool ScriptablePluginObjectControls::Invoke(NPIdentifier name, const NPVariant * args,
1815 uint32_t argCount, NPVariant * result)
1816 {
1817 CPlugin *pPlugin = (CPlugin *) mNpp->pdata;
1818 if (pPlugin == NULL) {
1819 gm_log(pPlugin->debug_level, G_LOG_LEVEL_DEBUG, "Can't find plugin pointer\n");
1820 return PR_FALSE;
1821 }
1822
1823 if (name == controls_play_id) {
1824 pPlugin->Play();
1825 return PR_TRUE;
1826 }
1827
1828 if (name == controls_pause_id) {
1829 pPlugin->Pause();
1830 return PR_TRUE;
1831 }
1832
1833 if (name == controls_stop_id) {
1834 pPlugin->Stop();
1835 return PR_TRUE;
1836 }
1837
1838 return false;
1839 }
1840
InvokeDefault(const NPVariant * args,uint32_t argCount,NPVariant * result)1841 bool ScriptablePluginObjectControls::InvokeDefault(const NPVariant * args, uint32_t argCount,
1842 NPVariant * result)
1843 {
1844 CPlugin *pPlugin = (CPlugin *) mNpp->pdata;
1845 if (pPlugin == NULL) {
1846 gm_log(pPlugin->debug_level, G_LOG_LEVEL_DEBUG,
1847 "ScriptablePluginObjectControls default method called!\n");
1848 }
1849
1850 STRINGZ_TO_NPVARIANT(strdup("default method return val"), *result);
1851
1852 return PR_TRUE;
1853 }
1854
HasProperty(NPIdentifier name)1855 bool ScriptablePluginObjectControls::HasProperty(NPIdentifier name)
1856 {
1857 if (name == controls_currentPosition_id || name == controls_currentItem_id) {
1858 return true;
1859 } else {
1860 return false;
1861 }
1862 }
1863
GetProperty(NPIdentifier name,NPVariant * result)1864 bool ScriptablePluginObjectControls::GetProperty(NPIdentifier name, NPVariant * result)
1865 {
1866 double position;
1867
1868 CPlugin *pPlugin = (CPlugin *) mNpp->pdata;
1869 if (pPlugin == NULL) {
1870 gm_log(pPlugin->debug_level, G_LOG_LEVEL_DEBUG, "Can't find plugin pointer\n");
1871 VOID_TO_NPVARIANT(*result);
1872 return false;
1873 }
1874
1875 if (name == controls_currentPosition_id) {
1876 pPlugin->GetTime(&position);
1877 DOUBLE_TO_NPVARIANT(position, *result);
1878 return true;
1879 }
1880
1881 if (name == controls_currentItem_id) {
1882 OBJECT_TO_NPVARIANT(pPlugin->GetScriptableObjectMedia(), *result);
1883 return true;
1884 }
1885
1886 VOID_TO_NPVARIANT(*result);
1887 return false;
1888 }
1889
SetProperty(NPIdentifier name,const NPVariant * value)1890 bool ScriptablePluginObjectControls::SetProperty(NPIdentifier name, const NPVariant * value)
1891 {
1892 CPlugin *pPlugin = (CPlugin *) mNpp->pdata;
1893 if (pPlugin == NULL) {
1894 gm_log(pPlugin->debug_level, G_LOG_LEVEL_DEBUG, "Can't find plugin pointer\n");
1895 return false;
1896 }
1897
1898 if (name == controls_currentPosition_id) {
1899 pPlugin->Seek(NPVARIANT_TO_DOUBLE(*value));
1900 return true;
1901 }
1902
1903 return false;
1904 }
1905
1906 class ScriptablePluginObjectMedia:public ScriptablePluginObjectBase {
1907 public:
ScriptablePluginObjectMedia(NPP npp)1908 ScriptablePluginObjectMedia(NPP npp):ScriptablePluginObjectBase(npp) {
1909 };
1910 virtual bool HasMethod(NPIdentifier name);
1911 virtual bool Invoke(NPIdentifier name, const NPVariant * args,
1912 uint32_t argCount, NPVariant * result);
1913 virtual bool InvokeDefault(const NPVariant * args, uint32_t argCount, NPVariant * result);
1914 virtual bool HasProperty(NPIdentifier name);
1915 virtual bool GetProperty(NPIdentifier name, NPVariant * result);
1916 virtual bool SetProperty(NPIdentifier name, const NPVariant * value);
1917
1918 };
1919
AllocateScriptablePluginObjectMedia(NPP npp,NPClass * aClass)1920 static NPObject *AllocateScriptablePluginObjectMedia(NPP npp, NPClass * aClass)
1921 {
1922 return new ScriptablePluginObjectMedia(npp);
1923 }
1924
1925 DECLARE_NPOBJECT_CLASS_WITH_BASE(ScriptablePluginObjectMedia, AllocateScriptablePluginObjectMedia);
1926
HasMethod(NPIdentifier name)1927 bool ScriptablePluginObjectMedia::HasMethod(NPIdentifier name)
1928 {
1929 if (name == media_getItemInfo_id) {
1930 return true;
1931 } else {
1932 return false;
1933 }
1934 }
1935
Invoke(NPIdentifier name,const NPVariant * args,uint32_t argCount,NPVariant * result)1936 bool ScriptablePluginObjectMedia::Invoke(NPIdentifier name, const NPVariant * args,
1937 uint32_t argCount, NPVariant * result)
1938 {
1939 CPlugin *pPlugin = (CPlugin *) mNpp->pdata;
1940 gchar *arg;
1941 int i;
1942
1943 if (pPlugin == NULL) {
1944 gm_log(pPlugin->debug_level, G_LOG_LEVEL_DEBUG, "Can't find plugin pointer\n");
1945 return PR_FALSE;
1946 }
1947
1948 if (name == media_getItemInfo_id) {
1949 #ifdef NPAPI_USE_UPPERCASE_UTF8
1950 arg = g_strdup(NPVARIANT_TO_STRING(args[0]).UTF8Characters);
1951 #else
1952 arg = g_strdup(NPVARIANT_TO_STRING(args[0]).utf8characters);
1953 #endif
1954
1955 if (g_ascii_strcasecmp(arg, "title") == 0) {
1956 STRINGZ_TO_NPVARIANT(strdup
1957 (request_string_value(pPlugin, pPlugin->lastopened, "GetTitle")),
1958 *result);
1959 } else if (g_ascii_strcasecmp(arg, "uri") == 0) {
1960 STRINGZ_TO_NPVARIANT(strdup
1961 (request_string_value(pPlugin, pPlugin->lastopened, "GetURI")),
1962 *result);
1963 } else if (g_ascii_strcasecmp(arg, "bitrate") == 0) {
1964 pPlugin->GetBitrate(&i);
1965 INT32_TO_NPVARIANT(i, *result);
1966 } else {
1967 STRINGZ_TO_NPVARIANT(strdup("Unknown"), *result);
1968 }
1969
1970 return true;
1971 }
1972
1973 return false;
1974 }
1975
InvokeDefault(const NPVariant * args,uint32_t argCount,NPVariant * result)1976 bool ScriptablePluginObjectMedia::InvokeDefault(const NPVariant * args, uint32_t argCount,
1977 NPVariant * result)
1978 {
1979 CPlugin *pPlugin = (CPlugin *) mNpp->pdata;
1980 if (pPlugin == NULL) {
1981 gm_log(pPlugin->debug_level, G_LOG_LEVEL_DEBUG,
1982 "ScriptablePluginObjectMedia default method called!\n");
1983 }
1984 STRINGZ_TO_NPVARIANT(strdup("default method return val"), *result);
1985
1986 return PR_TRUE;
1987 }
1988
HasProperty(NPIdentifier name)1989 bool ScriptablePluginObjectMedia::HasProperty(NPIdentifier name)
1990 {
1991 if (name == media_duration_id) {
1992 return true;
1993 } else {
1994 return false;
1995 }
1996 }
1997
GetProperty(NPIdentifier name,NPVariant * result)1998 bool ScriptablePluginObjectMedia::GetProperty(NPIdentifier name, NPVariant * result)
1999 {
2000 double d;
2001
2002 CPlugin *pPlugin = (CPlugin *) mNpp->pdata;
2003 if (pPlugin == NULL) {
2004 gm_log(pPlugin->debug_level, G_LOG_LEVEL_DEBUG, "Can't find plugin pointer\n");
2005 VOID_TO_NPVARIANT(*result);
2006 return false;
2007 }
2008
2009 if (name == media_duration_id) {
2010 pPlugin->GetDuration(&d);
2011 DOUBLE_TO_NPVARIANT(d, *result);
2012 return true;
2013 }
2014
2015 VOID_TO_NPVARIANT(*result);
2016 return false;
2017 }
2018
SetProperty(NPIdentifier name,const NPVariant * value)2019 bool ScriptablePluginObjectMedia::SetProperty(NPIdentifier name, const NPVariant * value)
2020 {
2021 CPlugin *pPlugin = (CPlugin *) mNpp->pdata;
2022 if (pPlugin == NULL) {
2023 gm_log(pPlugin->debug_level, G_LOG_LEVEL_DEBUG, "Can't find plugin pointer\n");
2024 return false;
2025 }
2026
2027 if (name == media_duration_id) {
2028 return true;
2029 }
2030
2031 return false;
2032 }
2033
2034 class ScriptablePluginObjectSettings:public ScriptablePluginObjectBase {
2035 public:
ScriptablePluginObjectSettings(NPP npp)2036 ScriptablePluginObjectSettings(NPP npp):ScriptablePluginObjectBase(npp) {
2037 };
2038 virtual bool HasMethod(NPIdentifier name);
2039 virtual bool Invoke(NPIdentifier name, const NPVariant * args,
2040 uint32_t argCount, NPVariant * result);
2041 virtual bool InvokeDefault(const NPVariant * args, uint32_t argCount, NPVariant * result);
2042 virtual bool HasProperty(NPIdentifier name);
2043 virtual bool GetProperty(NPIdentifier name, NPVariant * result);
2044 virtual bool SetProperty(NPIdentifier name, const NPVariant * value);
2045
2046 };
2047
AllocateScriptablePluginObjectSettings(NPP npp,NPClass * aClass)2048 static NPObject *AllocateScriptablePluginObjectSettings(NPP npp, NPClass * aClass)
2049 {
2050 return new ScriptablePluginObjectSettings(npp);
2051 }
2052
2053 DECLARE_NPOBJECT_CLASS_WITH_BASE(ScriptablePluginObjectSettings,
2054 AllocateScriptablePluginObjectSettings);
2055
HasMethod(NPIdentifier name)2056 bool ScriptablePluginObjectSettings::HasMethod(NPIdentifier name)
2057 {
2058 return false;
2059 }
2060
Invoke(NPIdentifier name,const NPVariant * args,uint32_t argCount,NPVariant * result)2061 bool ScriptablePluginObjectSettings::Invoke(NPIdentifier name, const NPVariant * args,
2062 uint32_t argCount, NPVariant * result)
2063 {
2064 CPlugin *pPlugin = (CPlugin *) mNpp->pdata;
2065 if (pPlugin == NULL) {
2066 gm_log(pPlugin->debug_level, G_LOG_LEVEL_DEBUG, "Can't find plugin pointer\n");
2067 return PR_FALSE;
2068 }
2069
2070 return false;
2071 }
2072
InvokeDefault(const NPVariant * args,uint32_t argCount,NPVariant * result)2073 bool ScriptablePluginObjectSettings::InvokeDefault(const NPVariant * args, uint32_t argCount,
2074 NPVariant * result)
2075 {
2076 CPlugin *pPlugin = (CPlugin *) mNpp->pdata;
2077 if (pPlugin == NULL) {
2078 gm_log(pPlugin->debug_level, G_LOG_LEVEL_DEBUG,
2079 "ScriptablePluginObjectSettings default method called!\n");
2080 }
2081 STRINGZ_TO_NPVARIANT(strdup("default method return val"), *result);
2082
2083 return PR_TRUE;
2084 }
2085
HasProperty(NPIdentifier name)2086 bool ScriptablePluginObjectSettings::HasProperty(NPIdentifier name)
2087 {
2088 if (name == settings_volume_id) {
2089 return true;
2090 } else {
2091 return false;
2092 }
2093 }
2094
GetProperty(NPIdentifier name,NPVariant * result)2095 bool ScriptablePluginObjectSettings::GetProperty(NPIdentifier name, NPVariant * result)
2096 {
2097 double d;
2098
2099 CPlugin *pPlugin = (CPlugin *) mNpp->pdata;
2100 if (pPlugin == NULL) {
2101 gm_log(pPlugin->debug_level, G_LOG_LEVEL_DEBUG, "Can't find plugin pointer\n");
2102 VOID_TO_NPVARIANT(*result);
2103 return false;
2104 }
2105
2106 if (name == settings_volume_id) {
2107 pPlugin->GetVolume(&d);
2108 DOUBLE_TO_NPVARIANT(d, *result);
2109 return true;
2110 }
2111
2112 VOID_TO_NPVARIANT(*result);
2113 return false;
2114 }
2115
SetProperty(NPIdentifier name,const NPVariant * value)2116 bool ScriptablePluginObjectSettings::SetProperty(NPIdentifier name, const NPVariant * value)
2117 {
2118 CPlugin *pPlugin = (CPlugin *) mNpp->pdata;
2119 if (pPlugin == NULL) {
2120 gm_log(pPlugin->debug_level, G_LOG_LEVEL_DEBUG, "Can't find plugin pointer\n");
2121 return false;
2122 }
2123
2124 if (name == settings_volume_id) {
2125 if ((int) NPVARIANT_TO_DOUBLE(*value) == 0 && NPVARIANT_TO_INT32(*value) > 0) {
2126 pPlugin->SetVolume((double) NPVARIANT_TO_INT32(*value));
2127 } else {
2128 pPlugin->SetVolume(NPVARIANT_TO_DOUBLE(*value));
2129 }
2130 return true;
2131 }
2132
2133 return false;
2134 }
2135
2136 class ScriptablePluginObjectError:public ScriptablePluginObjectBase {
2137 public:
ScriptablePluginObjectError(NPP npp)2138 ScriptablePluginObjectError(NPP npp):ScriptablePluginObjectBase(npp) {
2139 };
2140 virtual bool HasMethod(NPIdentifier name);
2141 virtual bool Invoke(NPIdentifier name, const NPVariant * args,
2142 uint32_t argCount, NPVariant * result);
2143 virtual bool InvokeDefault(const NPVariant * args, uint32_t argCount, NPVariant * result);
2144 virtual bool HasProperty(NPIdentifier name);
2145 virtual bool GetProperty(NPIdentifier name, NPVariant * result);
2146 virtual bool SetProperty(NPIdentifier name, const NPVariant * value);
2147
2148 };
2149
AllocateScriptablePluginObjectError(NPP npp,NPClass * aClass)2150 static NPObject *AllocateScriptablePluginObjectError(NPP npp, NPClass * aClass)
2151 {
2152 return new ScriptablePluginObjectError(npp);
2153 }
2154
2155 DECLARE_NPOBJECT_CLASS_WITH_BASE(ScriptablePluginObjectError, AllocateScriptablePluginObjectError);
2156
HasMethod(NPIdentifier name)2157 bool ScriptablePluginObjectError::HasMethod(NPIdentifier name)
2158 {
2159 return false;
2160 }
2161
Invoke(NPIdentifier name,const NPVariant * args,uint32_t argCount,NPVariant * result)2162 bool ScriptablePluginObjectError::Invoke(NPIdentifier name, const NPVariant * args,
2163 uint32_t argCount, NPVariant * result)
2164 {
2165 CPlugin *pPlugin = (CPlugin *) mNpp->pdata;
2166 if (pPlugin == NULL) {
2167 gm_log(pPlugin->debug_level, G_LOG_LEVEL_DEBUG, "Can't find plugin pointer\n");
2168 return PR_FALSE;
2169 }
2170
2171 return false;
2172 }
2173
InvokeDefault(const NPVariant * args,uint32_t argCount,NPVariant * result)2174 bool ScriptablePluginObjectError::InvokeDefault(const NPVariant * args, uint32_t argCount,
2175 NPVariant * result)
2176 {
2177 CPlugin *pPlugin = (CPlugin *) mNpp->pdata;
2178 if (pPlugin == NULL) {
2179 gm_log(pPlugin->debug_level, G_LOG_LEVEL_DEBUG,
2180 "ScriptablePluginObjectError default method called!\n");
2181 }
2182 STRINGZ_TO_NPVARIANT(strdup("default method return val"), *result);
2183
2184 return PR_TRUE;
2185 }
2186
HasProperty(NPIdentifier name)2187 bool ScriptablePluginObjectError::HasProperty(NPIdentifier name)
2188 {
2189 if (name == error_errorCount_id) {
2190 return true;
2191 } else {
2192 return false;
2193 }
2194 }
2195
GetProperty(NPIdentifier name,NPVariant * result)2196 bool ScriptablePluginObjectError::GetProperty(NPIdentifier name, NPVariant * result)
2197 {
2198 CPlugin *pPlugin = (CPlugin *) mNpp->pdata;
2199 if (pPlugin == NULL) {
2200 gm_log(pPlugin->debug_level, G_LOG_LEVEL_DEBUG, "Can't find plugin pointer\n");
2201 VOID_TO_NPVARIANT(*result);
2202 return false;
2203 }
2204
2205 if (name == error_errorCount_id) {
2206 INT32_TO_NPVARIANT(0, *result);
2207 return true;
2208 }
2209
2210 VOID_TO_NPVARIANT(*result);
2211 return false;
2212 }
2213
SetProperty(NPIdentifier name,const NPVariant * value)2214 bool ScriptablePluginObjectError::SetProperty(NPIdentifier name, const NPVariant * value)
2215 {
2216 CPlugin *pPlugin = (CPlugin *) mNpp->pdata;
2217 if (pPlugin == NULL) {
2218 gm_log(pPlugin->debug_level, G_LOG_LEVEL_DEBUG, "Can't find plugin pointer\n");
2219 return false;
2220 }
2221
2222 if (name == settings_volume_id) {
2223 if ((int) NPVARIANT_TO_DOUBLE(*value) == 0 && NPVARIANT_TO_INT32(*value) > 0) {
2224 pPlugin->SetVolume((double) NPVARIANT_TO_INT32(*value));
2225 } else {
2226 pPlugin->SetVolume(NPVARIANT_TO_DOUBLE(*value));
2227 }
2228 return true;
2229 }
2230
2231 return false;
2232 }
2233
2234
2235 class ScriptablePluginObject:public ScriptablePluginObjectBase {
2236 public:
ScriptablePluginObject(NPP npp)2237 ScriptablePluginObject(NPP npp):ScriptablePluginObjectBase(npp) {
2238 };
2239 virtual bool HasMethod(NPIdentifier name);
2240 virtual bool Invoke(NPIdentifier name, const NPVariant * args,
2241 uint32_t argCount, NPVariant * result);
2242 virtual bool InvokeDefault(const NPVariant * args, uint32_t argCount, NPVariant * result);
2243 virtual bool HasProperty(NPIdentifier name);
2244 virtual bool GetProperty(NPIdentifier name, NPVariant * result);
2245 virtual bool SetProperty(NPIdentifier name, const NPVariant * value);
2246
2247 };
2248
AllocateScriptablePluginObject(NPP npp,NPClass * aClass)2249 static NPObject *AllocateScriptablePluginObject(NPP npp, NPClass * aClass)
2250 {
2251 return new ScriptablePluginObject(npp);
2252 }
2253
2254 DECLARE_NPOBJECT_CLASS_WITH_BASE(ScriptablePluginObject, AllocateScriptablePluginObject);
2255
2256
HasMethod(NPIdentifier name)2257 bool ScriptablePluginObject::HasMethod(NPIdentifier name)
2258 {
2259 if (name == Play_id ||
2260 name == PlayAt_id ||
2261 name == Pause_id ||
2262 name == PlayPause_id ||
2263 name == Stop_id ||
2264 name == quit_id ||
2265 name == DoPlay_id ||
2266 name == DoPause_id ||
2267 name == FastForward_id ||
2268 name == FastReverse_id ||
2269 name == ff_id ||
2270 name == rew_id ||
2271 name == rewind_id ||
2272 name == Seek_id ||
2273 name == Open_id ||
2274 name == SetVolume_id ||
2275 name == GetVolume_id ||
2276 name == SetFileName_id ||
2277 name == GetFileName_id ||
2278 name == SetIsLooping_id ||
2279 name == GetIsLooping_id ||
2280 name == SetAutoPlay_id ||
2281 name == GetAutoPlay_id ||
2282 name == SetHREF_id ||
2283 name == GetHREF_id ||
2284 name == SetURL_id ||
2285 name == GetURL_id ||
2286 name == GetMIMEType_id ||
2287 name == getTime_id ||
2288 name == getDuration_id ||
2289 name == getPercent_id ||
2290 name == getBitrate_id ||
2291 name == isplaying_id ||
2292 name == playlistAppend_id ||
2293 name == playlistClear_id ||
2294 name == onClick_id ||
2295 name == onMediaComplete_id ||
2296 name == onMouseUp_id ||
2297 name == onMouseDown_id ||
2298 name == onMouseOut_id || name == onMouseOver_id || name == onDestroy_id) {
2299 return true;
2300 } else {
2301 return false;
2302 }
2303 }
2304
Invoke(NPIdentifier name,const NPVariant * args,uint32_t argCount,NPVariant * result)2305 bool ScriptablePluginObject::Invoke(NPIdentifier name, const NPVariant * args,
2306 uint32_t argCount, NPVariant * result)
2307 {
2308 double d;
2309 char *s;
2310 bool b;
2311 int i;
2312
2313 CPlugin *pPlugin = (CPlugin *) mNpp->pdata;
2314 if (pPlugin == NULL) {
2315 gm_log(pPlugin->debug_level, G_LOG_LEVEL_DEBUG, "Can't find plugin pointer\n");
2316 return PR_FALSE;
2317 }
2318
2319 if (name == Play_id || name == DoPlay_id) {
2320 pPlugin->Play();
2321 return PR_TRUE;
2322 }
2323
2324 if (name == PlayAt_id) {
2325 pPlugin->Play();
2326 if ((int) NPVARIANT_TO_DOUBLE(args[0]) == 0 && NPVARIANT_TO_INT32(args[0]) > 0) {
2327 pPlugin->Seek((double) NPVARIANT_TO_INT32(args[0]));
2328 } else {
2329 pPlugin->Seek(NPVARIANT_TO_DOUBLE(args[0]));
2330 }
2331 return PR_TRUE;
2332 }
2333
2334 if (name == Pause_id || name == DoPause_id) {
2335 pPlugin->Pause();
2336 return PR_TRUE;
2337 }
2338
2339 if (name == PlayPause_id) {
2340 pPlugin->PlayPause();
2341 return PR_TRUE;
2342 }
2343
2344 if (name == Stop_id) {
2345 pPlugin->Stop();
2346 return PR_TRUE;
2347 }
2348
2349 if (name == FastForward_id || name == ff_id) {
2350 pPlugin->FastForward();
2351 return PR_TRUE;
2352 }
2353
2354 if (name == FastReverse_id || name == rew_id || name == rewind_id) {
2355 pPlugin->FastReverse();
2356 return PR_TRUE;
2357 }
2358
2359 if (name == Seek_id) {
2360
2361 if ((int) NPVARIANT_TO_DOUBLE(args[0]) == 0 && NPVARIANT_TO_INT32(args[0]) > 0) {
2362 pPlugin->Seek((double) NPVARIANT_TO_INT32(args[0]));
2363 } else {
2364 pPlugin->Seek(NPVARIANT_TO_DOUBLE(args[0]));
2365 }
2366 return PR_TRUE;
2367 }
2368
2369 if (name == Open_id || name == SetFileName_id || name == SetHREF_id || name == SetURL_id) {
2370 #ifdef NPAPI_USE_UPPERCASE_UTF8
2371 pPlugin->SetFilename(NPVARIANT_TO_STRING(args[0]).UTF8Characters);
2372 #else
2373 pPlugin->SetFilename(NPVARIANT_TO_STRING(args[0]).utf8characters);
2374 #endif
2375 return PR_TRUE;
2376 }
2377
2378 if (name == GetFileName_id || name == GetHREF_id || name == GetURL_id) {
2379 pPlugin->GetFilename(&s);
2380 STRINGZ_TO_NPVARIANT(s, *result);
2381 g_free(s);
2382 return PR_TRUE;
2383 }
2384
2385 if (name == SetVolume_id) {
2386 if ((int) NPVARIANT_TO_DOUBLE(args[0]) == 0 && NPVARIANT_TO_INT32(args[0]) > 0) {
2387 pPlugin->SetVolume((double) NPVARIANT_TO_INT32(args[0]));
2388 } else {
2389 pPlugin->SetVolume(NPVARIANT_TO_DOUBLE(args[0]));
2390 }
2391 return PR_TRUE;
2392 }
2393
2394 if (name == GetVolume_id) {
2395 pPlugin->GetVolume(&d);
2396 DOUBLE_TO_NPVARIANT(d, *result);
2397 return PR_TRUE;
2398 }
2399
2400 if (name == SetIsLooping_id) {
2401 pPlugin->SetLoop(NPVARIANT_TO_BOOLEAN(args[0]));
2402 return PR_TRUE;
2403 }
2404
2405 if (name == GetIsLooping_id) {
2406 pPlugin->GetLoop(&b);
2407 BOOLEAN_TO_NPVARIANT(b, *result);
2408 return PR_TRUE;
2409 }
2410
2411 if (name == SetAutoPlay_id) {
2412 pPlugin->autostart = NPVARIANT_TO_BOOLEAN(args[0]);
2413 return PR_TRUE;
2414 }
2415
2416 if (name == GetAutoPlay_id) {
2417 BOOLEAN_TO_NPVARIANT(pPlugin->autostart, *result);
2418 return PR_TRUE;
2419 }
2420
2421 if (name == GetMIMEType_id) {
2422 pPlugin->GetMIMEType(&s);
2423 STRINGZ_TO_NPVARIANT(s, *result);
2424 g_free(s);
2425 return PR_TRUE;
2426 }
2427
2428 if (name == getTime_id) {
2429 pPlugin->GetTime(&d);
2430 DOUBLE_TO_NPVARIANT(d, *result);
2431 return PR_TRUE;
2432 }
2433
2434 if (name == getDuration_id) {
2435 pPlugin->GetDuration(&d);
2436 DOUBLE_TO_NPVARIANT(d, *result);
2437 return PR_TRUE;
2438 }
2439
2440 if (name == getPercent_id) {
2441 pPlugin->GetPercent(&d);
2442 DOUBLE_TO_NPVARIANT(d, *result);
2443 return PR_TRUE;
2444 }
2445
2446 if (name == getBitrate_id) {
2447 pPlugin->GetBitrate(&i);
2448 INT32_TO_NPVARIANT(i, *result);
2449 return PR_TRUE;
2450 }
2451
2452 if (name == isplaying_id || name == playlistAppend_id || name == playlistClear_id) {
2453 return PR_TRUE;
2454 }
2455
2456 if (name == onClick_id) {
2457 #ifdef NPAPI_USE_UPPERCASE_UTF8
2458 pPlugin->SetOnClick(NPVARIANT_TO_STRING(args[0]).UTF8Characters);
2459 #else
2460 pPlugin->SetOnClick(NPVARIANT_TO_STRING(args[0]).utf8characters);
2461 #endif
2462 return PR_TRUE;
2463 }
2464
2465 if (name == onMediaComplete_id) {
2466 #ifdef NPAPI_USE_UPPERCASE_UTF8
2467 pPlugin->SetOnMediaComplete(NPVARIANT_TO_STRING(args[0]).UTF8Characters);
2468 #else
2469 pPlugin->SetOnMediaComplete(NPVARIANT_TO_STRING(args[0]).utf8characters);
2470 #endif
2471 return PR_TRUE;
2472 }
2473
2474 if (name == onMouseUp_id) {
2475 #ifdef NPAPI_USE_UPPERCASE_UTF8
2476 pPlugin->SetOnMouseUp(NPVARIANT_TO_STRING(args[0]).UTF8Characters);
2477 #else
2478 pPlugin->SetOnMouseUp(NPVARIANT_TO_STRING(args[0]).utf8characters);
2479 #endif
2480 return PR_TRUE;
2481 }
2482
2483 if (name == onMouseDown_id) {
2484 #ifdef NPAPI_USE_UPPERCASE_UTF8
2485 pPlugin->SetOnMouseDown(NPVARIANT_TO_STRING(args[0]).UTF8Characters);
2486 #else
2487 pPlugin->SetOnMouseDown(NPVARIANT_TO_STRING(args[0]).utf8characters);
2488 #endif
2489 return PR_TRUE;
2490 }
2491
2492 if (name == onMouseOut_id) {
2493 #ifdef NPAPI_USE_UPPERCASE_UTF8
2494 pPlugin->SetOnMouseOut(NPVARIANT_TO_STRING(args[0]).UTF8Characters);
2495 #else
2496 pPlugin->SetOnMouseOut(NPVARIANT_TO_STRING(args[0]).utf8characters);
2497 #endif
2498 return PR_TRUE;
2499 }
2500
2501 if (name == onMouseOver_id) {
2502 #ifdef NPAPI_USE_UPPERCASE_UTF8
2503 pPlugin->SetOnMouseOver(NPVARIANT_TO_STRING(args[0]).UTF8Characters);
2504 #else
2505 pPlugin->SetOnMouseOver(NPVARIANT_TO_STRING(args[0]).utf8characters);
2506 #endif
2507 return PR_TRUE;
2508 }
2509
2510 if (name == onDestroy_id) {
2511 #ifdef NPAPI_USE_UPPERCASE_UTF8
2512 pPlugin->SetOnDestroy(NPVARIANT_TO_STRING(args[0]).UTF8Characters);
2513 #else
2514 pPlugin->SetOnDestroy(NPVARIANT_TO_STRING(args[0]).utf8characters);
2515 #endif
2516 return PR_TRUE;
2517 }
2518
2519 return PR_FALSE;
2520 }
2521
InvokeDefault(const NPVariant * args,uint32_t argCount,NPVariant * result)2522 bool ScriptablePluginObject::InvokeDefault(const NPVariant * args, uint32_t argCount,
2523 NPVariant * result)
2524 {
2525 CPlugin *pPlugin = (CPlugin *) mNpp->pdata;
2526 if (pPlugin == NULL) {
2527 gm_log(pPlugin->debug_level, G_LOG_LEVEL_DEBUG,
2528 "ScriptablePluginObject default method called!\n");
2529 }
2530
2531 STRINGZ_TO_NPVARIANT(strdup("default method return val"), *result);
2532
2533 return PR_TRUE;
2534 }
2535
HasProperty(NPIdentifier name)2536 bool ScriptablePluginObject::HasProperty(NPIdentifier name)
2537 {
2538 if (name == filename_id
2539 || name == src_id
2540 || name == ShowControls_id
2541 || name == fullscreen_id
2542 || name == showlogo_id
2543 || name == playState_id
2544 || name == URL_id
2545 || name == versionInfo_id
2546 || name == status_id
2547 || name == controls_id
2548 || name == media_id
2549 || name == settings_id
2550 || name == error_id || name == enabled_id || name == enableContextMenu_id) {
2551 return true;
2552 } else {
2553 return false;
2554 }
2555 }
2556
GetProperty(NPIdentifier name,NPVariant * result)2557 bool ScriptablePluginObject::GetProperty(NPIdentifier name, NPVariant * result)
2558 {
2559 char *filename;
2560 char *version;
2561 char *status;
2562 bool setting;
2563 PRInt32 state;
2564
2565 CPlugin *pPlugin = (CPlugin *) mNpp->pdata;
2566 if (pPlugin == NULL) {
2567 gm_log(pPlugin->debug_level, G_LOG_LEVEL_DEBUG, "Can't find plugin pointer\n");
2568 VOID_TO_NPVARIANT(*result);
2569 return false;
2570 }
2571
2572 if (name == filename_id || name == src_id || name == URL_id) {
2573 pPlugin->GetFilename(&filename);
2574 if (filename != NULL) {
2575 STRINGZ_TO_NPVARIANT(filename, *result);
2576 } else {
2577 STRINGZ_TO_NPVARIANT(strdup(""), *result);
2578 }
2579 return true;
2580 }
2581
2582 if (name == versionInfo_id) {
2583 version = g_strdup("7.0.0.7777");
2584 STRINGZ_TO_NPVARIANT(version, *result);
2585 return true;
2586 }
2587
2588 if (name == ShowControls_id) {
2589 pPlugin->GetShowControls(&setting);
2590 BOOLEAN_TO_NPVARIANT(setting, *result);
2591 return true;
2592 }
2593
2594 if (name == fullscreen_id) {
2595 pPlugin->GetFullScreen(&setting);
2596 BOOLEAN_TO_NPVARIANT(setting, *result);
2597 return true;
2598 }
2599
2600 if (name == showlogo_id) {
2601 setting = true;
2602 BOOLEAN_TO_NPVARIANT(setting, *result);
2603 return true;
2604 }
2605
2606 if (name == playState_id) {
2607 pPlugin->GetPlayState(&state);
2608 INT32_TO_NPVARIANT(state, *result);
2609 return true;
2610 }
2611
2612 if (name == status_id) {
2613 pPlugin->GetPlayState(&state);
2614 switch (state) {
2615 case STATE_PLAYING:
2616 status = g_strdup(_("Playing"));
2617 break;
2618 case STATE_PAUSED:
2619 status = g_strdup(_("Paused"));
2620 break;
2621 case STATE_STOPPED:
2622 status = g_strdup(_("Stopped"));
2623 break;
2624 case STATE_BUFFERING:
2625 status =
2626 g_strdup_printf(_("Buffering %2.1lf%%"),
2627 request_double_value(pPlugin, pPlugin->lastopened,
2628 "GetCachePercent") * 100.0);
2629 break;
2630 default:
2631 status = g_strdup(_("Unknown Status"));
2632 }
2633 // printf("Status = %s\n", status);
2634 STRINGZ_TO_NPVARIANT(status, *result);
2635 return true;
2636 }
2637
2638 if (name == enabled_id) {
2639 BOOLEAN_TO_NPVARIANT(true, *result);
2640 return true;
2641 }
2642
2643 if (name == enableContextMenu_id) {
2644 BOOLEAN_TO_NPVARIANT(!(pPlugin->disable_context_menu), *result);
2645 return true;
2646 }
2647
2648 if (name == controls_id) {
2649 OBJECT_TO_NPVARIANT(pPlugin->GetScriptableObjectControls(), *result);
2650 return true;
2651 }
2652
2653 if (name == media_id) {
2654 OBJECT_TO_NPVARIANT(pPlugin->GetScriptableObjectMedia(), *result);
2655 return true;
2656 }
2657
2658 if (name == settings_id) {
2659 OBJECT_TO_NPVARIANT(pPlugin->GetScriptableObjectSettings(), *result);
2660 return true;
2661 }
2662
2663 if (name == error_id) {
2664 OBJECT_TO_NPVARIANT(pPlugin->GetScriptableObjectError(), *result);
2665 return true;
2666 }
2667
2668 VOID_TO_NPVARIANT(*result);
2669 return false;
2670 }
2671
SetProperty(NPIdentifier name,const NPVariant * value)2672 bool ScriptablePluginObject::SetProperty(NPIdentifier name, const NPVariant * value)
2673 {
2674 CPlugin *pPlugin = (CPlugin *) mNpp->pdata;
2675 if (pPlugin == NULL) {
2676 gm_log(pPlugin->debug_level, G_LOG_LEVEL_DEBUG, "Can't find plugin pointer\n");
2677 return false;
2678 }
2679
2680 if (name == filename_id || name == src_id || name == URL_id) {
2681 #ifdef NPAPI_USE_UPPERCASE_UTF8
2682 pPlugin->SetFilename(NPVARIANT_TO_STRING(*value).UTF8Characters);
2683 #else
2684 pPlugin->SetFilename(NPVARIANT_TO_STRING(*value).utf8characters);
2685 #endif
2686 return true;
2687 }
2688
2689 if (name == ShowControls_id) {
2690 pPlugin->SetShowControls(NPVARIANT_TO_BOOLEAN(*value));
2691 return true;
2692 }
2693
2694 if (name == fullscreen_id) {
2695 pPlugin->SetFullScreen(NPVARIANT_TO_BOOLEAN(*value));
2696 return true;
2697 }
2698
2699 if (name == showlogo_id) {
2700 return true;
2701 }
2702
2703 if (name == playState_id) {
2704 // readonly property
2705 return true;
2706 }
2707
2708 if (name == enabled_id) {
2709 return true;
2710 }
2711
2712 if (name == enableContextMenu_id) {
2713 pPlugin->disable_context_menu = !(NPVARIANT_TO_BOOLEAN(*value));
2714 return true;
2715 }
2716
2717 return false;
2718 }
2719
GetScriptableObject()2720 NPObject *CPlugin::GetScriptableObject()
2721 {
2722 if (!m_pScriptableObject) {
2723 m_pScriptableObject =
2724 NPN_CreateObject(mInstance, GET_NPOBJECT_CLASS(ScriptablePluginObject));
2725 }
2726
2727 if (m_pScriptableObject) {
2728 NPN_RetainObject(m_pScriptableObject);
2729 }
2730
2731 return m_pScriptableObject;
2732 }
2733
GetScriptableObjectControls()2734 NPObject *CPlugin::GetScriptableObjectControls()
2735 {
2736 if (!m_pScriptableObjectControls) {
2737 m_pScriptableObjectControls =
2738 NPN_CreateObject(mInstance, GET_NPOBJECT_CLASS(ScriptablePluginObjectControls));
2739 }
2740
2741 if (m_pScriptableObjectControls) {
2742 NPN_RetainObject(m_pScriptableObjectControls);
2743 }
2744
2745 return m_pScriptableObjectControls;
2746 }
2747
GetScriptableObjectMedia()2748 NPObject *CPlugin::GetScriptableObjectMedia()
2749 {
2750 if (!m_pScriptableObjectMedia) {
2751 m_pScriptableObjectMedia =
2752 NPN_CreateObject(mInstance, GET_NPOBJECT_CLASS(ScriptablePluginObjectMedia));
2753 }
2754
2755 if (m_pScriptableObjectMedia) {
2756 NPN_RetainObject(m_pScriptableObjectMedia);
2757 }
2758
2759 return m_pScriptableObjectMedia;
2760 }
2761
GetScriptableObjectSettings()2762 NPObject *CPlugin::GetScriptableObjectSettings()
2763 {
2764 if (!m_pScriptableObjectSettings) {
2765 m_pScriptableObjectSettings =
2766 NPN_CreateObject(mInstance, GET_NPOBJECT_CLASS(ScriptablePluginObjectSettings));
2767 }
2768
2769 if (m_pScriptableObjectSettings) {
2770 NPN_RetainObject(m_pScriptableObjectSettings);
2771 }
2772
2773 return m_pScriptableObjectSettings;
2774 }
2775
GetScriptableObjectError()2776 NPObject *CPlugin::GetScriptableObjectError()
2777 {
2778 if (!m_pScriptableObjectError) {
2779 m_pScriptableObjectError =
2780 NPN_CreateObject(mInstance, GET_NPOBJECT_CLASS(ScriptablePluginObjectError));
2781 }
2782
2783 if (m_pScriptableObjectError) {
2784 NPN_RetainObject(m_pScriptableObjectError);
2785 }
2786
2787 return m_pScriptableObjectError;
2788 }
2789