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