added MouseWheel event support for Silverlight 3.0
[moon.git] / plugin / plugin.h
blob984c6b5ce3357ed9af2c012f9d3480f0e38a6325
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3 * plugin.h: MoonLight browser plugin.
5 * Contact:
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.
14 #ifndef MOON_PLUGIN
15 #define MOON_PLUGIN
17 #include "moonlight.h"
19 #if PLUGIN_SL_2_0
20 #include <mono/jit/jit.h>
21 #include <mono/metadata/appdomain.h>
22 #include <mono/metadata/assembly.h>
23 #include <mono/metadata/debug-helpers.h>
24 G_BEGIN_DECLS
25 /* because this header sucks */
26 #include <mono/metadata/mono-debug.h>
27 G_END_DECLS
28 #include <mono/metadata/mono-config.h>
29 #endif
31 class MoonlightScriptControlObject;
32 class PluginXamlLoader;
33 class PluginInstance;
34 class BrowserBridge;
35 #if PLUGIN_SL_2_0
36 class Xap;
37 #endif
39 char *NPN_strdup (const char *val);
41 class PluginInstance
43 private:
44 ~PluginInstance ();
46 public:
47 PluginInstance (NPMIMEType pluginType, NPP instance, guint16 mode);
49 void ref ();
50 void unref ();
52 void Initialize (int argc, char *const argn[], char *const argv[]);
53 void Shutdown ();
55 // Mozilla plugin related methods
56 NPError GetValue (NPPVariable variable, void *result);
57 NPError SetValue (NPNVariable variable, void *value);
58 NPError SetWindow (NPWindow *window);
59 NPError NewStream (NPMIMEType type, NPStream *stream, NPBool seekable, guint16 *stype);
60 NPError DestroyStream (NPStream *stream, NPError reason);
61 void StreamAsFile (NPStream *stream, const char *fname);
62 gint32 WriteReady (NPStream *stream);
63 gint32 Write (NPStream *stream, gint32 offset, gint32 len, void *buffer);
64 void UrlNotify (const char *url, NPReason reason, void *notifyData);
65 void LoadSplash ();
66 void FlushSplash ();
67 void Print (NPPrint *platformPrint);
68 int16_t EventHandle (void *event);
69 /* @GenerateCBinding,GeneratePInvoke */
70 void ReportException (char *msg, char *details, /* @MarshalAs=string[] */ char **stack_trace, int num_frames);
71 /* @GenerateCBinding,GeneratePInvoke */
72 void *Evaluate (const char *code);
74 NPObject *GetHost ();
76 /* @GenerateCBinding,GeneratePInvoke */
77 void *GetBrowserHost () { return GetHost (); } // same as GetHost, just without bleeding NPObjects into the cbindings
79 void AddWrappedObject (EventObject *obj, NPObject *wrapper);
80 void RemoveWrappedObject (EventObject *obj);
81 NPObject *LookupWrappedObject (EventObject *obj);
83 void AddCleanupPointer (gpointer p);
84 void RemoveCleanupPointer (gpointer p);
86 // [Obselete (this is obsolete in SL b2)]
87 guint32 TimeoutAdd (gint32 interval, GSourceFunc callback, gpointer data);
88 // [Obselete (this is obsolete in SL b2)]
89 void TimeoutStop (guint32 source_id);
91 void Properties ();
93 // Property getters and setters
94 /* @GenerateCBinding,GeneratePInvoke */
95 const char *GetInitParams () { return this->initParams; }
96 void SetInitParams (const char *value);
97 /* @GenerateCBinding,GeneratePInvoke */
98 const char *GetSource () { return this->source; }
99 /* @GenerateCBinding,GeneratePInvoke */
100 const char *GetSourceOriginal () { return this->source_original; }
101 /* @GenerateCBinding,GeneratePInvoke */
102 const char *GetSourceLocation () { return this->source_location; }
103 /* @GenerateCBinding,GeneratePInvoke */
104 const char *GetSourceLocationOriginal () { return this->source_location_original; }
105 char *GetId () { return this->id; }
107 void SetSource (const char *value);
109 char *GetBackground ();
110 bool SetBackground (const char *value);
111 bool GetEnableFramerateCounter ();
112 void SetEnableFramerateCounter (bool value);
113 bool GetEnableRedrawRegions ();
114 void SetEnableRedrawRegions (bool value);
115 /* @GenerateCBinding,GeneratePInvoke */
116 bool GetEnableHtmlAccess ();
117 /* @GenerateCBinding,GeneratePInvoke */
118 bool GetAllowHtmlPopupWindow ();
119 /* @GenerateCBinding,GeneratePInvoke */
120 bool GetWindowless ();
121 bool IsLoaded ();
123 void SetMaxFrameRate (int value);
124 int GetMaxFrameRate ();
125 Deployment *GetDeployment ();
127 BrowserBridge *GetBridge () { return bridge; }
129 MoonlightScriptControlObject *GetRootObject ();
130 NPP GetInstance ();
131 NPWindow *GetWindow ();
132 /* @GenerateCBinding,GeneratePInvoke */
133 Surface *GetSurface () { return surface; }
135 /* @GenerateCBinding,GeneratePInvoke */
136 gint32 GetActualHeight ();
137 /* @GenerateCBinding,GeneratePInvoke */
138 gint32 GetActualWidth ();
140 bool IsCrossDomainApplication () { return cross_domain_app; }
141 static gint32 GetPluginCount ();
143 static gboolean plugin_button_press_callback (GtkWidget *widget, GdkEventButton *event, gpointer user_data);
145 static Downloader *CreateDownloader (PluginInstance *instance);
147 #if DEBUG
148 struct moon_source : List::Node {
149 char *uri;
150 char *filename;
151 virtual ~moon_source ()
153 g_free (uri);
154 g_free (filename);
157 void AddSource (const char *uri, const char *filename);
158 List *GetSources ();
159 #endif
161 #if PLUGIN_SL_2_0
162 static bool MonoIsLoaded ();
163 static bool DeploymentInit ();
165 bool InitializePluginAppDomain ();
166 bool CreatePluginDeployment ();
168 gpointer ManagedCreateXamlLoaderForFile (XamlLoader* loader, const char *resourceBase, const char *file);
169 gpointer ManagedCreateXamlLoaderForString (XamlLoader* loader, const char *resourceBase, const char *str);
170 void ManagedLoaderDestroy (gpointer loader_object);
171 #endif
173 private:
174 #if DEBUG
175 List *moon_sources;
176 #endif
178 // Gtk controls
179 GtkWidget *container; // plugin container object
180 Surface *surface; // plugin surface object
181 MoonWindow *moon_window;
182 GdkDisplay *display;
184 GSList *timers;
186 guint16 mode; // NP_EMBED, NP_FULL, or NP_BACKGROUND
187 NPWindow *window; // Mozilla window object
188 NPP instance; // Mozilla instance object
189 NPObject *rootobject; // Mozilla jscript object wrapper
190 guint32 xembed_supported; // XEmbed Extension supported
192 GHashTable *wrapped_objects; // wrapped object cache
195 * Mozilla has a slightly different view on refcounting when dealing with
196 * NPObjects: normal refcounting until NPP_Destroy is called, after
197 * NPP_Destroy returns, all NPObjects are deleted no matter their refcount.
199 * See this link for some fun reading:
200 * - https://bugzilla.mozilla.org/show_bug.cgi?id=421217
202 * Apparently this behaviour is documented here: http://developer.mozilla.org/en/NPClass
203 * - The NPObjects' invalidate method is:
204 * "Called on live objects that belong to a plugin instance that is being destroyed."
205 * "This call is always followed by a call to the deallocate function called when"
206 * "the plugin is destroyed"
208 * However the documentation also says this about the deallocate method:
209 * "Called by NPN_ReleaseObject() when an object's reference count reaches zero."
211 * This contradicting documentation results in different behaviour between browsers,
212 * Safari and Opera comply 100% with refcounting laws, while firefox doesn't.
214 * This has a profound implication on for our shutdown code: it means that
215 * we can't access any NPObjects after returning from NPP_Destroy. Parts of
216 * our current shutdown is async (it wouldn't be completely impossible to
217 * make it sync, just dangerously difficult, we'd have to block the main thread
218 * until all other threads have shut down, while executing code we have little
219 * control over, exposing us to possible deadlocks).
221 * To protect against accessing NPObjects after returning from NPP_Destroy
222 * we keep a flag telling whether it's safe or not to access npobjects (which
223 * is set upon shutdown)
227 public:
228 bool IsShuttingDown (); /* Not thread-safe */
229 bool HasShutdown (); /* It is not safe to access any NPObjects when this returns true. Not thread-safe. */
231 private:
232 bool is_shutting_down;
233 bool has_shutdown;
234 gint32 refcount;
236 GSList *cleanup_pointers;
238 // Property fields
239 char *initParams;
240 char *source;
241 char *source_original;
242 char *source_location;
243 char *source_location_original;
244 guint source_idle;
245 char *onLoad;
246 char *background;
247 char *onError;
248 char *onResize;
249 char *id;
250 char *splashscreensource;
251 char *onSourceDownloadProgressChanged;
252 char *onSourceDownloadComplete;
254 char *culture;
255 char *uiCulture;
257 int source_size;
259 bool windowless;
260 bool cross_domain_app;
261 bool default_enable_html_access;
262 bool enable_html_access;
263 bool allow_html_popup_window;
264 bool enable_framerate_counter;
265 bool loading_splash;
266 bool is_splash;
267 int maxFrameRate;
269 BrowserBridge *bridge;
271 GtkWidget *properties_fps_label;
272 GtkWidget *properties_cache_label;
275 // The XAML loader, contains a handle to a MonoObject *
277 PluginXamlLoader *xaml_loader;
278 Deployment *deployment;
279 #if PLUGIN_SL_2_0
280 MonoAssembly *system_windows_assembly;
282 static bool mono_is_loaded;
284 // Methods
285 MonoMethod *moon_load_xaml;
286 MonoMethod *moon_initialize_deployment_xap;
287 MonoMethod *moon_initialize_deployment_xaml;
288 MonoMethod *moon_destroy_application;
290 MonoClass *moon_exception;
291 MonoProperty *moon_exception_message;
292 MonoProperty *moon_exception_error_code;
294 void LoadXAP (const char*url, const char *fname);
295 void DestroyApplication ();
297 MonoMethod *MonoGetMethodFromName (MonoClass *klass, const char *name, int narg);
298 MonoProperty *MonoGetPropertyFromName (MonoClass *klass, const char *name);
300 ErrorEventArgs* ManagedExceptionToErrorEventArgs (MonoObject *exc);
302 bool ManagedInitializeDeployment (const char *file);
303 void ManagedDestroyApplication ();
305 gpointer ManagedCreateXamlLoader (XamlLoader* native_loader, const char *resourceBase, const char *file, const char *str);
306 #endif
308 // The name of the file that we are missing, and we requested to be loaded
309 char *vm_missing_file;
311 // Private methods
312 void CreateWindow ();
313 void UpdateSource ();
314 void UpdateSourceByReference (const char *value);
315 void LoadXAML ();
316 void SetPageURL ();
317 char* GetPageLocation ();
318 void CrossDomainApplicationCheck (const char *source);
320 void TryLoadBridge (const char *prefix);
322 static gboolean IdleUpdateSourceByReference (gpointer data);
324 static void ReportFPS (Surface *surface, int nframes, float nsecs, void *user_data);
325 static void ReportCache (Surface *surface, long bytes, void *user_data);
326 static void properties_dialog_response (GtkWidget *dialog, int response, PluginInstance *plugin);
328 static void network_error_tickcall (EventObject *data);
329 static void splashscreen_error_tickcall (EventObject *data);
331 EVENTHANDLER (PluginInstance, AppDomainUnloadedEvent, Deployment, EventArgs);
334 extern GSList *plugin_instances;
336 #define NPID(x) NPN_GetStringIdentifier (x)
338 #define STRDUP_FROM_VARIANT(v) (g_strndup ((char *) NPVARIANT_TO_STRING (v).utf8characters, NPVARIANT_TO_STRING (v).utf8length))
339 #define STRLEN_FROM_VARIANT(v) ((size_t) NPVARIANT_TO_STRING (v).utf8length)
341 #define STREAM_NOTIFY(x) ((StreamNotify*) x)
343 #define STREAM_NOTIFY_DATA(x) ((StreamNotify*) x)->pdata
345 #define IS_NOTIFY_SOURCE(x) \
346 (!x ? true : (((StreamNotify*) x)->type == StreamNotify::SOURCE))
348 #define IS_NOTIFY_SPLASHSOURCE(x) \
349 (!x ? true : (((StreamNotify*) x)->type == StreamNotify::SPLASHSOURCE))
351 #define IS_NOTIFY_DOWNLOADER(x) \
352 (!x ? StreamNotify::NONE : (((StreamNotify*) x)->type == StreamNotify::DOWNLOADER))
354 #define IS_NOTIFY_REQUEST(x) \
355 (!x ? StreamNotify::NONE : (((StreamNotify*) x)->type == StreamNotify::REQUEST))
357 class StreamNotify
359 public:
360 enum StreamNotifyFlags {
361 NONE = 0,
362 SOURCE = 1,
363 SPLASHSOURCE = 2,
364 DOWNLOADER = 3,
365 REQUEST = 4
368 StreamNotifyFlags type;
369 void *pdata;
371 StreamNotify () : type (NONE), pdata (NULL) {};
372 StreamNotify (void *data) : type (NONE), pdata (data) {};
373 StreamNotify (StreamNotifyFlags type) : type (type), pdata (NULL) {};
374 StreamNotify (StreamNotifyFlags type, void *data) : type (type), pdata (data) {};
375 StreamNotify (StreamNotifyFlags type, DependencyObject *dob) : type (type), pdata (dob)
377 if (dob)
378 dob->ref ();
381 ~StreamNotify ()
383 if (type == DOWNLOADER && pdata)
384 ((DependencyObject *) pdata)->unref ();
388 class PluginXamlLoader : public XamlLoader
390 PluginXamlLoader (const char *resourceBase, const char *filename, const char *str, PluginInstance *plugin, Surface *surface);
391 bool InitializeLoader ();
392 PluginInstance *plugin;
393 bool initialized;
394 bool xaml_is_managed;
396 #if PLUGIN_SL_2_0
397 gpointer managed_loader;
398 Xap *xap;
399 #endif
400 public:
401 virtual ~PluginXamlLoader ();
402 const char *TryLoad (int *error);
404 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);
406 static PluginXamlLoader *FromFilename (const char *resourceBase, const char *filename, PluginInstance *plugin, Surface *surface)
408 return new PluginXamlLoader (resourceBase, filename, NULL, plugin, surface);
411 static PluginXamlLoader *FromStr (const char *resourceBase, const char *str, PluginInstance *plugin, Surface *surface)
413 return new PluginXamlLoader (resourceBase, NULL, str, plugin, surface);
416 bool IsManaged () { return xaml_is_managed; }
418 virtual bool LoadVM ();
421 G_BEGIN_DECLS
423 const char *get_plugin_dir (void);
425 char *plugin_instance_get_id (PluginInstance *instance);
427 void plugin_instance_get_browser_runtime_settings (bool *debug, bool *html_access,
428 bool *httpnet_access, bool *script_access);
430 void *plugin_instance_load_url (PluginInstance *instance, char *url, gint32 *length);
432 PluginXamlLoader *plugin_xaml_loader_from_str (const char *str, const char *resourceBase, PluginInstance *plugin, Surface *surface);
434 G_END_DECLS
436 #endif /* MOON_PLUGIN */