1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * plugin.h: MoonLight browser plugin.
6 * Moonlight List (moonlight-list@lists.ximian.com)
8 * Copyright 2007 Novell, Inc. (http://www.novell.com)
10 * See the LICENSE file included with the distribution for details.
17 #include "moonlight.h"
19 class MoonlightScriptControlObject
;
20 class PluginXamlLoader
;
27 char *NPN_strdup (const char *val
);
34 void Recreate (const char *source
);
36 PluginInstance (NPP instance
, guint16 mode
);
41 void Initialize (int argc
, char * argn
[], char * argv
[]);
44 // Mozilla plugin related methods
45 NPError
GetValue (NPPVariable variable
, void *result
);
46 NPError
SetValue (NPNVariable variable
, void *value
);
47 NPError
SetWindow (NPWindow
*window
);
48 NPError
NewStream (NPMIMEType type
, NPStream
*stream
, NPBool seekable
, guint16
*stype
);
49 NPError
DestroyStream (NPStream
*stream
, NPError reason
);
50 void StreamAsFile (NPStream
*stream
, const char *fname
);
51 gint32
WriteReady (NPStream
*stream
);
52 gint32
Write (NPStream
*stream
, gint32 offset
, gint32 len
, void *buffer
);
53 void UrlNotify (const char *url
, NPReason reason
, void *notifyData
);
56 void Print (NPPrint
*platformPrint
);
57 int16_t EventHandle (void *event
);
58 /* @GenerateCBinding,GeneratePInvoke */
59 void ReportException (char *msg
, char *details
, /* @MarshalAs=string[] */ char **stack_trace
, int num_frames
);
60 /* @GenerateCBinding,GeneratePInvoke */
61 void *Evaluate (const char *code
);
65 /* @GenerateCBinding,GeneratePInvoke */
66 void *GetBrowserHost () { return GetHost (); } // same as GetHost, just without bleeding NPObjects into the cbindings
68 void AddWrappedObject (EventObject
*obj
, NPObject
*wrapper
);
69 void RemoveWrappedObject (EventObject
*obj
);
70 NPObject
*LookupWrappedObject (EventObject
*obj
);
72 void AddCleanupPointer (gpointer p
);
73 void RemoveCleanupPointer (gpointer p
);
77 // Property getters and setters
78 /* @GenerateCBinding,GeneratePInvoke */
79 const char *GetInitParams () { return this->initParams
; }
80 void SetInitParams (const char *value
);
81 /* @GenerateCBinding,GeneratePInvoke */
82 const char *GetSource () { return this->source
; }
83 /* @GenerateCBinding,GeneratePInvoke */
84 const char *GetSourceOriginal () { return this->source_original
; }
85 /* @GenerateCBinding,GeneratePInvoke */
86 const char *GetSourceLocation () { return this->source_location
; }
87 /* @GenerateCBinding,GeneratePInvoke */
88 const char *GetSourceLocationOriginal () { return this->source_location_original
; }
89 char *GetId () { return this->id
; }
91 void SetSource (const char *value
);
93 char *GetBackground ();
94 bool SetBackground (const char *value
);
95 bool GetEnableFramerateCounter ();
96 void SetEnableFramerateCounter (bool value
);
97 bool GetEnableRedrawRegions ();
98 void SetEnableRedrawRegions (bool value
);
99 /* @GenerateCBinding,GeneratePInvoke */
100 bool GetEnableHtmlAccess ();
101 /* @GenerateCBinding,GeneratePInvoke */
102 bool GetAllowHtmlPopupWindow ();
103 /* @GenerateCBinding,GeneratePInvoke */
104 bool GetWindowless ();
107 void SetMaxFrameRate (int value
);
108 int GetMaxFrameRate ();
109 Deployment
*GetDeployment ();
111 BrowserBridge
*GetBridge () { return bridge
; }
113 MoonlightScriptControlObject
*GetRootObject ();
115 NPWindow
*GetWindow ();
116 /* @GenerateCBinding,GeneratePInvoke */
117 Surface
*GetSurface () { return surface
; }
119 /* @GenerateCBinding,GeneratePInvoke */
120 gint32
GetActualHeight ();
121 /* @GenerateCBinding,GeneratePInvoke */
122 gint32
GetActualWidth ();
124 bool IsCrossDomainApplication () { return cross_domain_app
; }
125 static gint32
GetPluginCount ();
127 static gboolean
plugin_button_press_callback (GtkWidget
*widget
, GdkEventButton
*event
, gpointer user_data
);
129 static Downloader
*CreateDownloader (PluginInstance
*instance
);
132 struct moon_source
: List::Node
{
135 virtual ~moon_source ()
141 void AddSource (const char *uri
, const char *filename
);
145 bool CreatePluginDeployment ();
147 gpointer
ManagedCreateXamlLoaderForFile (XamlLoader
* loader
, const char *resourceBase
, const char *file
);
148 gpointer
ManagedCreateXamlLoaderForString (XamlLoader
* loader
, const char *resourceBase
, const char *str
);
156 bool connected_to_container
;
157 GtkWidget
*container
; // plugin container object
158 Surface
*surface
; // plugin surface object
159 MoonWindow
*moon_window
;
163 guint16 mode
; // NP_EMBED, NP_FULL, or NP_BACKGROUND
164 NPWindow
*window
; // Mozilla window object
165 NPP instance
; // Mozilla instance object
166 MoonlightScriptControlObject
*rootobject
; // Mozilla jscript object wrapper
167 guint32 xembed_supported
; // XEmbed Extension supported
169 GHashTable
*wrapped_objects
; // wrapped object cache
172 * Mozilla has a slightly different view on refcounting when dealing with
173 * NPObjects: normal refcounting until NPP_Destroy is called, after
174 * NPP_Destroy returns, all NPObjects are deleted no matter their refcount.
176 * See this link for some fun reading:
177 * - https://bugzilla.mozilla.org/show_bug.cgi?id=421217
179 * Apparently this behaviour is documented here: http://developer.mozilla.org/en/NPClass
180 * - The NPObjects' invalidate method is:
181 * "Called on live objects that belong to a plugin instance that is being destroyed."
182 * "This call is always followed by a call to the deallocate function called when"
183 * "the plugin is destroyed"
185 * However the documentation also says this about the deallocate method:
186 * "Called by NPN_ReleaseObject() when an object's reference count reaches zero."
188 * This contradicting documentation results in different behaviour between browsers,
189 * Safari and Opera comply 100% with refcounting laws, while firefox doesn't.
191 * This has a profound implication on for our shutdown code: it means that
192 * we can't access any NPObjects after returning from NPP_Destroy. Parts of
193 * our current shutdown is async (it wouldn't be completely impossible to
194 * make it sync, just dangerously difficult, we'd have to block the main thread
195 * until all other threads have shut down, while executing code we have little
196 * control over, exposing us to possible deadlocks).
198 * To protect against accessing NPObjects after returning from NPP_Destroy
199 * we keep a flag telling whether it's safe or not to access npobjects (which
200 * is set upon shutdown)
205 bool IsShuttingDown (); /* Not thread-safe */
206 bool HasShutdown (); /* It is not safe to access any NPObjects when this returns true. Not thread-safe. */
209 bool is_shutting_down
;
213 GSList
*cleanup_pointers
;
216 // If you add new property fields remember to handle them properly in Recreate too.
219 char *source_original
;
220 char *source_location
;
221 char *source_location_original
;
228 char *splashscreensource
;
229 char *onSourceDownloadProgressChanged
;
230 char *onSourceDownloadComplete
;
238 bool cross_domain_app
;
239 bool default_enable_html_access
;
240 bool enable_html_access
;
241 bool allow_html_popup_window
;
242 bool enable_framerate_counter
;
247 BrowserBridge
*bridge
;
249 GtkWidget
*properties_fps_label
;
250 GtkWidget
*properties_cache_label
;
253 // The XAML loader, contains a handle to a MonoObject *
255 PluginXamlLoader
*xaml_loader
;
256 Deployment
*deployment
;
258 bool LoadXAP (const char*url
, const char *fname
);
259 void DestroyApplication ();
263 void CreateWindow ();
264 void UpdateSource ();
265 void UpdateSourceByReference (const char *value
);
268 char* GetPageLocation ();
269 void CrossDomainApplicationCheck (const char *source
);
271 void TryLoadBridge (const char *prefix
);
273 static gboolean
IdleUpdateSourceByReference (gpointer data
);
275 static void ReportFPS (Surface
*surface
, int nframes
, float nsecs
, void *user_data
);
276 static void ReportCache (Surface
*surface
, long bytes
, void *user_data
);
277 static void properties_dialog_response (GtkWidget
*dialog
, int response
, PluginInstance
*plugin
);
279 static void network_error_tickcall (EventObject
*data
);
280 static void splashscreen_error_tickcall (EventObject
*data
);
282 EVENTHANDLER (PluginInstance
, AppDomainUnloadedEvent
, Deployment
, EventArgs
);
285 extern GSList
*plugin_instances
;
287 #define NPID(x) NPN_GetStringIdentifier (x)
289 #define STRDUP_FROM_VARIANT(v) (g_strndup ((char *) NPVARIANT_TO_STRING (v).utf8characters, NPVARIANT_TO_STRING (v).utf8length))
290 #define STRLEN_FROM_VARIANT(v) ((size_t) NPVARIANT_TO_STRING (v).utf8length)
292 #define STREAM_NOTIFY(x) ((StreamNotify*) x)
294 #define STREAM_NOTIFY_DATA(x) ((StreamNotify*) x)->pdata
296 #define IS_NOTIFY_SOURCE(x) \
297 (!x ? true : (((StreamNotify*) x)->type == StreamNotify::SOURCE))
299 #define IS_NOTIFY_SPLASHSOURCE(x) \
300 (!x ? true : (((StreamNotify*) x)->type == StreamNotify::SPLASHSOURCE))
302 #define IS_NOTIFY_DOWNLOADER(x) \
303 (!x ? StreamNotify::NONE : (((StreamNotify*) x)->type == StreamNotify::DOWNLOADER))
308 enum StreamNotifyFlags
{
315 StreamNotifyFlags type
;
318 StreamNotify () : type (NONE
), pdata (NULL
) {};
319 StreamNotify (void *data
) : type (NONE
), pdata (data
) {};
320 StreamNotify (StreamNotifyFlags type
) : type (type
), pdata (NULL
) {};
321 StreamNotify (StreamNotifyFlags type
, void *data
) : type (type
), pdata (data
) {};
322 StreamNotify (StreamNotifyFlags type
, DependencyObject
*dob
) : type (type
), pdata (dob
)
330 if (type
== DOWNLOADER
&& pdata
)
331 ((DependencyObject
*) pdata
)->unref ();
335 class PluginXamlLoader
: public XamlLoader
337 PluginXamlLoader (const char *resourceBase
, const char *filename
, const char *str
, PluginInstance
*plugin
, Surface
*surface
);
338 bool InitializeLoader ();
339 PluginInstance
*plugin
;
341 bool xaml_is_managed
;
344 gpointer managed_loader
;
348 virtual ~PluginXamlLoader ();
349 void TryLoad (int *error
);
351 bool SetProperty (void *parser
, Value
*top_level
, const char *xmlns
, Value
*target
, void *target_data
, Value
*target_parent
, const char *prop_xmlns
, const char *name
, Value
* value
, void* value_data
, int flags
= 0);
353 static PluginXamlLoader
*FromFilename (const char *resourceBase
, const char *filename
, PluginInstance
*plugin
, Surface
*surface
)
355 return new PluginXamlLoader (resourceBase
, filename
, NULL
, plugin
, surface
);
358 static PluginXamlLoader
*FromStr (const char *resourceBase
, const char *str
, PluginInstance
*plugin
, Surface
*surface
)
360 return new PluginXamlLoader (resourceBase
, NULL
, str
, plugin
, surface
);
363 bool IsManaged () { return xaml_is_managed
; }
365 virtual bool LoadVM ();
370 const char *get_plugin_dir (void);
372 char *plugin_instance_get_id (PluginInstance
*instance
);
374 void plugin_instance_get_browser_runtime_settings (bool *debug
, bool *html_access
,
375 bool *httpnet_access
, bool *script_access
);
377 void *plugin_instance_load_url (PluginInstance
*instance
, char *url
, gint32
*length
);
379 PluginXamlLoader
*plugin_xaml_loader_from_str (const char *str
, const char *resourceBase
, PluginInstance
*plugin
, Surface
*surface
);
383 #endif /* MOON_PLUGIN */