abock / moonshine
- Source
- Commits
- Network (0)
- Issues (0)
- Downloads (1)
- Wiki (1)
- Graphs
-
Branch:
master
Aaron Bockover (committer)
Wed Sep 02 12:53:06 -0700 2009
| 558c6c6c » | Aaron Bockover | 2009-02-09 | 1 | // | |
| 2 | // This file is licensed under the MIT X11 open source license. | ||||
| 3 | // http://www.opensource.org/licenses/mit-license.php | ||||
| 4 | // | ||||
| 5 | // Authors: Aaron Bockover <abockover@novell.com> | ||||
| 6 | // | ||||
| 7 | // Copyright 2009 Novell, Inc. | ||||
| 8 | // | ||||
| 9 | |||||
| 1e6efed1 » | jstedfast | 2009-09-02 | 10 | #include <config.h> | |
| 11 | |||||
| d45d9491 » | Aaron Bockover | 2009-01-28 | 12 | #include <string.h> | |
| 13 | |||||
| dcb3f10f » | Aaron Bockover | 2009-01-28 | 14 | #include "mmp-binder.h" | |
| 3d136168 » | Aaron Bockover | 2009-01-28 | 15 | #include "mmp-script.h" | |
| dcb3f10f » | Aaron Bockover | 2009-01-28 | 16 | #include "mmp-resources.h" | |
| 17 | |||||
| bb7c4009 » | Aaron Bockover | 2009-02-09 | 18 | #define MLMP_XAML_LOAD_FUNCTION "__MoonshineWmpPluginBindInstance" | |
| b24b7d3d » | Aaron Bockover | 2009-02-09 | 19 | #define MLMP_XAML_DOM_ID "__MoonshineEmptyFakeXamlTrickery" | |
| dcb3f10f » | Aaron Bockover | 2009-01-28 | 20 | ||
| 3d136168 » | Aaron Bockover | 2009-01-28 | 21 | typedef enum { | |
| 22 | XAML_LOAD_ERROR = 0, | ||||
| 23 | XAML_LOAD_SUCCESS = 1, | ||||
| 24 | XAML_LOAD_ALREADY_LOADED = 2 | ||||
| 25 | } XamlLoadStatus; | ||||
| 26 | |||||
| 27 | static XamlLoadStatus | ||||
| 28 | mmp_binder_load_player_xaml (MoonlightPluginInstance *plugin) | ||||
| dcb3f10f » | Aaron Bockover | 2009-01-28 | 29 | { | |
| 3d136168 » | Aaron Bockover | 2009-01-28 | 30 | NPP npp = plugin->moz_instance; | |
| 31 | NPObject *window = mmp_script_get_window (npp); | ||||
| 32 | NPVariant document; | ||||
| 33 | NPVariant script_element; | ||||
| 34 | NPVariant xaml_node; | ||||
| 35 | NPVariant body; | ||||
| 36 | XamlLoadStatus xaml_loaded = XAML_LOAD_ERROR; | ||||
| 37 | |||||
| 38 | g_return_val_if_fail (npp != NULL, XAML_LOAD_ERROR); | ||||
| 39 | g_return_val_if_fail (window != NULL, XAML_LOAD_ERROR); | ||||
| 40 | |||||
| 41 | // Load the document object | ||||
| 42 | if (!mmp_script_get_document (npp, window, &document)) { | ||||
| 43 | mp_error ("Unable to get document object via npruntime"); | ||||
| 44 | return XAML_LOAD_ERROR; | ||||
| dcb3f10f » | Aaron Bockover | 2009-01-28 | 45 | } | |
| 46 | |||||
| 3d136168 » | Aaron Bockover | 2009-01-28 | 47 | // Check to see if the XAML was already loaded into the DOM | |
| 48 | if (mmp_script_document_get_element_by_id (npp, &document, MLMP_XAML_DOM_ID, &xaml_node)) { | ||||
| 49 | NPN_ReleaseVariantValue (&xaml_node); | ||||
| 50 | NPN_ReleaseVariantValue (&document); | ||||
| 51 | return XAML_LOAD_ALREADY_LOADED; | ||||
| 52 | } | ||||
| 53 | |||||
| 54 | // Create the XAML and add to the DOM (<script id='foo' type='text/xaml'>[xaml data]</script>) | ||||
| 55 | if (mmp_script_document_create_element (npp, &document, "script", &script_element)) { | ||||
| 56 | if (mmp_script_element_set_property_string (npp, &script_element, "id", MLMP_XAML_DOM_ID) && | ||||
| 57 | mmp_script_element_set_property_string (npp, &script_element, "type", "text/xaml") && | ||||
| 1e6efed1 » | jstedfast | 2009-09-02 | 58 | mmp_script_document_create_text_node (npp, &document, "<Canvas xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"/>", &xaml_node)) { | |
| 3d136168 » | Aaron Bockover | 2009-01-28 | 59 | ||
| 60 | if (mmp_script_element_append_child (npp, &script_element, &xaml_node)) { | ||||
| 61 | if (mmp_script_element_get_property_object (npp, &document, "body", &body)) { | ||||
| 62 | if (mmp_script_element_append_child (npp, &body, &script_element)) { | ||||
| 63 | xaml_loaded = XAML_LOAD_SUCCESS; | ||||
| 64 | } | ||||
| 65 | |||||
| 66 | NPN_ReleaseVariantValue (&body); | ||||
| 67 | } | ||||
| 68 | } | ||||
| 69 | |||||
| 70 | NPN_ReleaseVariantValue (&xaml_node); | ||||
| dcb3f10f » | Aaron Bockover | 2009-01-28 | 71 | } | |
| 3d136168 » | Aaron Bockover | 2009-01-28 | 72 | ||
| 73 | NPN_ReleaseVariantValue (&script_element); | ||||
| dcb3f10f » | Aaron Bockover | 2009-01-28 | 74 | } | |
| 75 | |||||
| 3d136168 » | Aaron Bockover | 2009-01-28 | 76 | NPN_ReleaseVariantValue (&document); | |
| 77 | return xaml_loaded; | ||||
| dcb3f10f » | Aaron Bockover | 2009-01-28 | 78 | } | |
| 79 | |||||
| 3d136168 » | Aaron Bockover | 2009-01-28 | 80 | static void | |
| 81 | mmp_binder_bind (MoonlightPluginInstance *plugin) | ||||
| dcb3f10f » | Aaron Bockover | 2009-01-28 | 82 | { | |
| 3d136168 » | Aaron Bockover | 2009-01-28 | 83 | XamlLoadStatus status; | |
| 84 | |||||
| 85 | status = mmp_binder_load_player_xaml (plugin); | ||||
| 86 | |||||
| 87 | if (status == XAML_LOAD_ERROR) { | ||||
| 88 | mp_error ("Unable to load player XAML into the DOM"); | ||||
| 89 | return; | ||||
| 90 | } else if (status == XAML_LOAD_SUCCESS) { | ||||
| 91 | // Only load the JS once, when the XAML is actually added to the DOM | ||||
| b24b7d3d » | Aaron Bockover | 2009-02-09 | 92 | gint i = 0; | |
| 93 | for (; MLMP_RESOURCES_ALL[i]; i++) { | ||||
| 94 | mmp_script_evaluate (plugin->moz_instance, MLMP_RESOURCES_ALL[i]); | ||||
| 95 | } | ||||
| 3d136168 » | Aaron Bockover | 2009-01-28 | 96 | } | |
| dcb3f10f » | Aaron Bockover | 2009-01-28 | 97 | } | |
| 98 | |||||
| 3d136168 » | Aaron Bockover | 2009-01-28 | 99 | NPError mmp_binder_npp_new (NPMIMEType pluginType, NPP instance, gushort mode, | |
| 100 | gshort argc, gchar **argn, gchar **argv, NPSavedData *saved) | ||||
| dcb3f10f » | Aaron Bockover | 2009-01-28 | 101 | { | |
| 3d136168 » | Aaron Bockover | 2009-01-28 | 102 | NPError result; | |
| 103 | gchar **param_names; | ||||
| 104 | gchar **param_values; | ||||
| 105 | gint param_count = 0, i; | ||||
| 106 | MoonlightPluginInstance *plugin; | ||||
| 107 | |||||
| 108 | mp_debug ("NPP_New"); | ||||
| 109 | |||||
| 1462a0e3 » | Aaron Bockover | 2009-01-30 | 110 | // +2 to ensure space for onload and source | |
| b49f550a » | Aaron Bockover | 2009-02-12 | 111 | param_names = g_new0 (gchar *, argc + 3); | |
| 112 | param_values = g_new0 (gchar *, argc + 3); | ||||
| 3d136168 » | Aaron Bockover | 2009-01-28 | 113 | ||
| 2d4ceb23 » | Aaron Bockover | 2009-01-29 | 114 | // We only preserve and proxy id, width, and height | |
| 3d136168 » | Aaron Bockover | 2009-01-28 | 115 | for (i = 0; i < argc; i++) { | |
| 2d4ceb23 » | Aaron Bockover | 2009-01-29 | 116 | if (g_ascii_strncasecmp (argn[i], "id", 2) == 0 || | |
| 117 | g_ascii_strncasecmp (argn[i], "width", 5) == 0 || | ||||
| 118 | g_ascii_strncasecmp (argn[i], "height", 6) == 0) { | ||||
| 119 | param_names[param_count] = g_strdup (argn[i]); | ||||
| 120 | param_values[param_count] = g_strdup (argv[i]); | ||||
| 121 | param_count++; | ||||
| 3d136168 » | Aaron Bockover | 2009-01-28 | 122 | } | |
| dcb3f10f » | Aaron Bockover | 2009-01-28 | 123 | } | |
| 124 | |||||
| 1462a0e3 » | Aaron Bockover | 2009-01-30 | 125 | param_names[param_count] = g_strdup ("source"); | |
| 126 | param_values[param_count++] = g_strdup ( "#" MLMP_XAML_DOM_ID ); | ||||
| 127 | |||||
| 3d136168 » | Aaron Bockover | 2009-01-28 | 128 | param_names[param_count] = g_strdup ("onload"); | |
| 129 | param_values[param_count++] = g_strdup (MLMP_XAML_LOAD_FUNCTION); | ||||
| b49f550a » | Aaron Bockover | 2009-02-12 | 130 | ||
| 7d8f3483 » | Aaron Bockover | 2009-02-23 | 131 | param_names[param_count] = g_strdup ("moonlight-relaxed-media-mode"); | |
| b49f550a » | Aaron Bockover | 2009-02-12 | 132 | param_values[param_count++] = g_strdup ("true"); | |
| 2d4ceb23 » | Aaron Bockover | 2009-01-29 | 133 | ||
| 134 | // Create an NPP wrapper and send the NPP_New to Moonlight | ||||
| 3d136168 » | Aaron Bockover | 2009-01-28 | 135 | plugin = mmp_plugin_new (instance); | |
| 136 | plugin->param_names = param_names; | ||||
| 137 | plugin->param_values = param_values; | ||||
| dcb3f10f » | Aaron Bockover | 2009-01-28 | 138 | ||
| 2d4ceb23 » | Aaron Bockover | 2009-01-29 | 139 | result = MMP_HANDLE ()->moon_npp_new ("application/x-silverlight", instance, mode, | |
| 140 | param_count, param_names, param_values, saved); | ||||
| 141 | |||||
| 3d136168 » | Aaron Bockover | 2009-01-28 | 142 | if (result == NPERR_NO_ERROR) { | |
| 2d4ceb23 » | Aaron Bockover | 2009-01-29 | 143 | // Everything was okay, so bind XAML and JS to the plugin instance | |
| 3d136168 » | Aaron Bockover | 2009-01-28 | 144 | mmp_binder_bind (plugin); | |
| 145 | return NPERR_NO_ERROR; | ||||
| dcb3f10f » | Aaron Bockover | 2009-01-28 | 146 | } | |
| 147 | |||||
| 3d136168 » | Aaron Bockover | 2009-01-28 | 148 | mmp_plugin_free (plugin); | |
| 149 | |||||
| 150 | return result; | ||||
| dcb3f10f » | Aaron Bockover | 2009-01-28 | 151 | } | |
| 3d136168 » | Aaron Bockover | 2009-01-28 | 152 | ||
| 153 | NPError | ||||
| 154 | mmp_binder_npp_destroy (NPP instance, NPSavedData **save) | ||||
| 155 | { | ||||
| 156 | MoonlightPluginInstance *plugin; | ||||
| 157 | |||||
| 158 | mp_debug ("NPP_Destroy"); | ||||
| 159 | |||||
| 160 | plugin = mmp_plugin_find_instance (instance); | ||||
| 161 | if (plugin != NULL) { | ||||
| 162 | mmp_plugin_free (plugin); | ||||
| 163 | } | ||||
| 164 | |||||
| 165 | return MMP_HANDLE ()->moon_npp_destroy (instance, save); | ||||
| 166 | } | ||||
| 167 | |||||
| dfbe809f » | Aaron Bockover | 2009-02-11 | 168 | // This is the NPStream::notifyData type that Moonlight uses internally! | |
| 169 | |||||
| 170 | typedef enum { | ||||
| 171 | STREAM_NOTIFY_NONE = 0, | ||||
| 172 | STREAM_NOTIFY_SOURCE = 1, | ||||
| 173 | STREAM_NOTIFY_DOWNLOADER = 2, | ||||
| 174 | STREAM_NOTIFY_REQUEST = 3 | ||||
| 175 | } StreamNotifyFlags; | ||||
| 176 | |||||
| 177 | typedef struct { | ||||
| 178 | StreamNotifyFlags type; | ||||
| 179 | gpointer pdata; | ||||
| 180 | } StreamNotify; | ||||
| 181 | |||||
| a2e11c52 » | Aaron Bockover | 2009-01-29 | 182 | void | |
| 183 | mmp_binder_npp_stream_as_file (NPP instance, NPStream *stream, const gchar *fname) | ||||
| 184 | { | ||||
| 1462a0e3 » | Aaron Bockover | 2009-01-30 | 185 | // Mozilla ends up calling this in some cases. It results in the file | |
| 186 | // being loaded as XAML inside of Moonlight, which is very bad since | ||||
| 187 | // it's going to be some kind of WM content. | ||||
| 188 | // | ||||
| 189 | // Observed cases where Mozilla does this: | ||||
| 190 | // | ||||
| 191 | // <embed src="..." /> | ||||
| 192 | // <object data="..." /> | ||||
| 193 | // | ||||
| dfbe809f » | Aaron Bockover | 2009-02-11 | 194 | ||
| 195 | if (stream && stream->notifyData && ((StreamNotify *)stream->notifyData)->type == STREAM_NOTIFY_DOWNLOADER) { | ||||
| fa4218d4 » | Aaron Bockover | 2009-02-12 | 196 | gchar *basename = g_path_get_basename (stream->url); | |
| 197 | |||||
| dfbe809f » | Aaron Bockover | 2009-02-11 | 198 | MMP_HANDLE ()->moon_npp_stream_as_file (instance, stream, fname); | |
| fa4218d4 » | Aaron Bockover | 2009-02-12 | 199 | ||
| 200 | if (g_str_has_prefix (basename, "silverlight-media-pack") && g_str_has_suffix (basename, ".so")) { | ||||
| 201 | NPObject *object = NULL; | ||||
| 202 | NPVariant result; | ||||
| 203 | NPIdentifier method = NPN_GetStringIdentifier ("ReloadMediaSource"); | ||||
| 204 | |||||
| 205 | if (NPN_GetValue (instance, NPNVPluginElementNPObject, &object) == NPERR_NO_ERROR && | ||||
| 206 | NPN_Invoke (instance, object, method, NULL, 0, &result) == NPERR_NO_ERROR) { | ||||
| 207 | mp_debug ("Silverlight Media Pack downloaded, reloading media"); | ||||
| 208 | } | ||||
| 209 | } | ||||
| 210 | |||||
| 211 | g_free (basename); | ||||
| dfbe809f » | Aaron Bockover | 2009-02-11 | 212 | } | |
| a2e11c52 » | Aaron Bockover | 2009-01-29 | 213 | } | |
| 214 | |||||
