1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /* vim: set sw=4 ts=4 et : */
3 : /* ***** BEGIN LICENSE BLOCK *****
4 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 : *
6 : * The contents of this file are subject to the Mozilla Public License Version
7 : * 1.1 (the "License"); you may not use this file except in compliance with
8 : * the License. You may obtain a copy of the License at
9 : * http://www.mozilla.org/MPL/
10 : *
11 : * Software distributed under the License is distributed on an "AS IS" basis,
12 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 : * for the specific language governing rights and limitations under the
14 : * License.
15 : *
16 : * The Original Code is Mozilla Plugin App.
17 : *
18 : * The Initial Developer of the Original Code is
19 : * Ben Turner <bent.mozilla@gmail.com>.
20 : * Portions created by the Initial Developer are Copyright (C) 2009
21 : * the Initial Developer. All Rights Reserved.
22 : *
23 : * Contributor(s):
24 : * Chris Jones <jones.chris.g@gmail.com>
25 : *
26 : * Alternatively, the contents of this file may be used under the terms of
27 : * either the GNU General Public License Version 2 or later (the "GPL"), or
28 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 : * in which case the provisions of the GPL or the LGPL are applicable instead
30 : * of those above. If you wish to allow use of your version of this file only
31 : * under the terms of either the GPL or the LGPL, and not to allow others to
32 : * use your version of this file under the terms of the MPL, indicate your
33 : * decision by deleting the provisions above and replace them with the notice
34 : * and other provisions required by the GPL or the LGPL. If you do not delete
35 : * the provisions above, a recipient may use your version of this file under
36 : * the terms of any one of the MPL, the GPL or the LGPL.
37 : *
38 : * ***** END LICENSE BLOCK ***** */
39 :
40 : #ifdef MOZ_WIDGET_QT
41 : #include <QtCore/QTimer>
42 : #include "nsQAppInstance.h"
43 : #include "NestedLoopTimer.h"
44 : #endif
45 :
46 : #include "mozilla/plugins/PluginModuleChild.h"
47 :
48 : /* This must occur *after* plugins/PluginModuleChild.h to avoid typedefs conflicts. */
49 : #include "mozilla/Util.h"
50 :
51 : #include "mozilla/ipc/SyncChannel.h"
52 :
53 : #ifdef MOZ_WIDGET_GTK2
54 : #include <gtk/gtk.h>
55 : #endif
56 :
57 : #include "nsILocalFile.h"
58 :
59 : #include "pratom.h"
60 : #include "nsDebug.h"
61 : #include "nsCOMPtr.h"
62 : #include "nsPluginsDir.h"
63 : #include "nsXULAppAPI.h"
64 :
65 : #ifdef MOZ_X11
66 : # include "mozilla/X11Util.h"
67 : #endif
68 : #include "mozilla/plugins/PluginInstanceChild.h"
69 : #include "mozilla/plugins/StreamNotifyChild.h"
70 : #include "mozilla/plugins/BrowserStreamChild.h"
71 : #include "mozilla/plugins/PluginStreamChild.h"
72 : #include "PluginIdentifierChild.h"
73 : #include "mozilla/dom/CrashReporterChild.h"
74 :
75 : #include "nsNPAPIPlugin.h"
76 :
77 : #ifdef XP_WIN
78 : #include "COMMessageFilter.h"
79 : #include "nsWindowsDllInterceptor.h"
80 : #include "mozilla/widget/AudioSession.h"
81 : #endif
82 :
83 : #ifdef MOZ_WIDGET_COCOA
84 : #include "PluginInterposeOSX.h"
85 : #include "PluginUtilsOSX.h"
86 : #endif
87 :
88 : using namespace mozilla;
89 : using namespace mozilla::plugins;
90 : using mozilla::dom::CrashReporterChild;
91 : using mozilla::dom::PCrashReporterChild;
92 :
93 : #if defined(XP_WIN)
94 : const PRUnichar * kFlashFullscreenClass = L"ShockwaveFlashFullScreen";
95 : const PRUnichar * kMozillaWindowClass = L"MozillaWindowClass";
96 : #endif
97 :
98 : namespace {
99 : PluginModuleChild* gInstance = nsnull;
100 : }
101 :
102 : #ifdef MOZ_WIDGET_QT
103 : typedef void (*_gtk_init_fn)(int argc, char **argv);
104 : static _gtk_init_fn s_gtk_init = nsnull;
105 : static PRLibrary *sGtkLib = nsnull;
106 : #endif
107 :
108 : #ifdef XP_WIN
109 : // Used with fix for flash fullscreen window loosing focus.
110 : static bool gDelayFlashFocusReplyUntilEval = false;
111 : // Used to fix GetWindowInfo problems with internal flash settings dialogs
112 : static WindowsDllInterceptor sUser32Intercept;
113 : typedef BOOL (WINAPI *GetWindowInfoPtr)(HWND hwnd, PWINDOWINFO pwi);
114 : static GetWindowInfoPtr sGetWindowInfoPtrStub = NULL;
115 : static HWND sBrowserHwnd = NULL;
116 : #endif
117 :
118 0 : PluginModuleChild::PluginModuleChild()
119 : : mLibrary(0)
120 : , mPluginFilename("")
121 : , mQuirks(QUIRKS_NOT_INITIALIZED)
122 : , mShutdownFunc(0)
123 : , mInitializeFunc(0)
124 : #if defined(OS_WIN) || defined(OS_MACOSX)
125 : , mGetEntryPointsFunc(0)
126 : #elif defined(MOZ_WIDGET_GTK2)
127 0 : , mNestedLoopTimerId(0)
128 : #elif defined(MOZ_WIDGET_QT)
129 : , mNestedLoopTimerObject(0)
130 : #endif
131 : #ifdef OS_WIN
132 : , mNestedEventHook(NULL)
133 : , mGlobalCallWndProcHook(NULL)
134 : #endif
135 : {
136 0 : NS_ASSERTION(!gInstance, "Something terribly wrong here!");
137 0 : memset(&mFunctions, 0, sizeof(mFunctions));
138 0 : memset(&mSavedData, 0, sizeof(mSavedData));
139 0 : gInstance = this;
140 0 : mUserAgent.SetIsVoid(true);
141 : #ifdef XP_MACOSX
142 : mac_plugin_interposing::child::SetUpCocoaInterposing();
143 : #endif
144 0 : }
145 :
146 0 : PluginModuleChild::~PluginModuleChild()
147 : {
148 0 : NS_ASSERTION(gInstance == this, "Something terribly wrong here!");
149 :
150 : // We don't unload the plugin library in case it uses atexit handlers or
151 : // other similar hooks.
152 :
153 0 : DeinitGraphics();
154 :
155 0 : gInstance = nsnull;
156 0 : }
157 :
158 : // static
159 : PluginModuleChild*
160 0 : PluginModuleChild::current()
161 : {
162 0 : NS_ASSERTION(gInstance, "Null instance!");
163 0 : return gInstance;
164 : }
165 :
166 : bool
167 0 : PluginModuleChild::Init(const std::string& aPluginFilename,
168 : base::ProcessHandle aParentProcessHandle,
169 : MessageLoop* aIOLoop,
170 : IPC::Channel* aChannel)
171 : {
172 0 : PLUGIN_LOG_DEBUG_METHOD;
173 :
174 : #ifdef XP_WIN
175 : COMMessageFilter::Initialize(this);
176 : #endif
177 :
178 0 : NS_ASSERTION(aChannel, "need a channel");
179 :
180 0 : if (!mObjectMap.Init()) {
181 0 : NS_WARNING("Failed to initialize object hashtable!");
182 0 : return false;
183 : }
184 :
185 0 : if (!mStringIdentifiers.Init()) {
186 0 : NS_ERROR("Failed to initialize string identifier hashtable!");
187 0 : return false;
188 : }
189 :
190 0 : if (!mIntIdentifiers.Init()) {
191 0 : NS_ERROR("Failed to initialize int identifier hashtable!");
192 0 : return false;
193 : }
194 :
195 0 : if (!InitGraphics())
196 0 : return false;
197 :
198 0 : mPluginFilename = aPluginFilename.c_str();
199 0 : nsCOMPtr<nsILocalFile> localFile;
200 0 : NS_NewLocalFile(NS_ConvertUTF8toUTF16(mPluginFilename),
201 : true,
202 0 : getter_AddRefs(localFile));
203 :
204 : bool exists;
205 0 : localFile->Exists(&exists);
206 0 : NS_ASSERTION(exists, "plugin file ain't there");
207 :
208 0 : nsPluginFile pluginFile(localFile);
209 :
210 : // Maemo flash can render with any provided rectangle and so does not
211 : // require this quirk.
212 : #if defined(MOZ_X11) && !defined(MOZ_PLATFORM_MAEMO)
213 0 : nsPluginInfo info = nsPluginInfo();
214 0 : if (NS_FAILED(pluginFile.GetPluginInfo(info, &mLibrary)))
215 0 : return false;
216 :
217 0 : NS_NAMED_LITERAL_CSTRING(flash10Head, "Shockwave Flash 10.");
218 0 : if (StringBeginsWith(nsDependentCString(info.fDescription), flash10Head)) {
219 0 : AddQuirk(QUIRK_FLASH_EXPOSE_COORD_TRANSLATION);
220 : }
221 :
222 0 : if (!mLibrary)
223 : #endif
224 : {
225 0 : DebugOnly<nsresult> rv = pluginFile.LoadPlugin(&mLibrary);
226 0 : NS_ASSERTION(NS_OK == rv, "trouble with mPluginFile");
227 : }
228 0 : NS_ASSERTION(mLibrary, "couldn't open shared object");
229 :
230 0 : if (!Open(aChannel, aParentProcessHandle, aIOLoop))
231 0 : return false;
232 :
233 0 : memset((void*) &mFunctions, 0, sizeof(mFunctions));
234 0 : mFunctions.size = sizeof(mFunctions);
235 0 : mFunctions.version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR;
236 :
237 : // TODO: use PluginPRLibrary here
238 :
239 : #if defined(OS_LINUX)
240 : mShutdownFunc =
241 0 : (NP_PLUGINSHUTDOWN) PR_FindFunctionSymbol(mLibrary, "NP_Shutdown");
242 :
243 : // create the new plugin handler
244 :
245 : mInitializeFunc =
246 0 : (NP_PLUGINUNIXINIT) PR_FindFunctionSymbol(mLibrary, "NP_Initialize");
247 0 : NS_ASSERTION(mInitializeFunc, "couldn't find NP_Initialize()");
248 :
249 : #elif defined(OS_WIN) || defined(OS_MACOSX)
250 : mShutdownFunc =
251 : (NP_PLUGINSHUTDOWN)PR_FindFunctionSymbol(mLibrary, "NP_Shutdown");
252 :
253 : mGetEntryPointsFunc =
254 : (NP_GETENTRYPOINTS)PR_FindSymbol(mLibrary, "NP_GetEntryPoints");
255 : NS_ENSURE_TRUE(mGetEntryPointsFunc, false);
256 :
257 : mInitializeFunc =
258 : (NP_PLUGININIT)PR_FindFunctionSymbol(mLibrary, "NP_Initialize");
259 : NS_ENSURE_TRUE(mInitializeFunc, false);
260 : #else
261 :
262 : # error Please copy the initialization code from nsNPAPIPlugin.cpp
263 :
264 : #endif
265 :
266 : #ifdef XP_MACOSX
267 : nsPluginInfo info = nsPluginInfo();
268 : if (pluginFile.GetPluginInfo(info, &mLibrary) == NS_OK) {
269 : mozilla::plugins::PluginUtilsOSX::SetProcessName(info.fName);
270 : }
271 : #endif
272 :
273 0 : return true;
274 : }
275 :
276 : #if defined(MOZ_WIDGET_GTK2)
277 : typedef void (*GObjectDisposeFn)(GObject*);
278 : typedef gboolean (*GtkWidgetScrollEventFn)(GtkWidget*, GdkEventScroll*);
279 : typedef void (*GtkPlugEmbeddedFn)(GtkPlug*);
280 :
281 : static GObjectDisposeFn real_gtk_plug_dispose;
282 : static GtkPlugEmbeddedFn real_gtk_plug_embedded;
283 :
284 : static void
285 0 : undo_bogus_unref(gpointer data, GObject* object, gboolean is_last_ref) {
286 0 : if (!is_last_ref) // recursion in g_object_ref
287 0 : return;
288 :
289 0 : g_object_ref(object);
290 : }
291 :
292 : static void
293 0 : wrap_gtk_plug_dispose(GObject* object) {
294 : // Work around Flash Player bug described in bug 538914.
295 : //
296 : // This function is called during gtk_widget_destroy and/or before
297 : // the object's last reference is removed. A reference to the
298 : // object is held during the call so the ref count should not drop
299 : // to zero. However, Flash Player tries to destroy the GtkPlug
300 : // using g_object_unref instead of gtk_widget_destroy. The
301 : // reference that Flash is removing actually belongs to the
302 : // GtkPlug. During real_gtk_plug_dispose, the GtkPlug removes its
303 : // reference.
304 : //
305 : // A toggle ref is added to prevent premature deletion of the object
306 : // caused by Flash Player's extra unref, and to detect when there are
307 : // unexpectedly no other references.
308 0 : g_object_add_toggle_ref(object, undo_bogus_unref, NULL);
309 0 : (*real_gtk_plug_dispose)(object);
310 0 : g_object_remove_toggle_ref(object, undo_bogus_unref, NULL);
311 0 : }
312 :
313 : static gboolean
314 0 : gtk_plug_scroll_event(GtkWidget *widget, GdkEventScroll *gdk_event)
315 : {
316 0 : if (!GTK_WIDGET_TOPLEVEL(widget)) // in same process as its GtkSocket
317 0 : return FALSE; // event not handled; propagate to GtkSocket
318 :
319 0 : GdkWindow* socket_window = GTK_PLUG(widget)->socket_window;
320 0 : if (!socket_window)
321 0 : return FALSE;
322 :
323 : // Propagate the event to the embedder.
324 0 : GdkScreen* screen = gdk_drawable_get_screen(socket_window);
325 0 : GdkWindow* plug_window = widget->window;
326 0 : GdkWindow* event_window = gdk_event->window;
327 0 : gint x = gdk_event->x;
328 0 : gint y = gdk_event->y;
329 : unsigned int button;
330 0 : unsigned int button_mask = 0;
331 : XEvent xevent;
332 0 : Display* dpy = GDK_WINDOW_XDISPLAY(socket_window);
333 :
334 : /* Translate the event coordinates to the plug window,
335 : * which should be aligned with the socket window.
336 : */
337 0 : while (event_window != plug_window)
338 : {
339 : gint dx, dy;
340 :
341 0 : gdk_window_get_position(event_window, &dx, &dy);
342 0 : x += dx;
343 0 : y += dy;
344 :
345 0 : event_window = gdk_window_get_parent(event_window);
346 0 : if (!event_window)
347 0 : return FALSE;
348 : }
349 :
350 0 : switch (gdk_event->direction) {
351 : case GDK_SCROLL_UP:
352 0 : button = 4;
353 0 : button_mask = Button4Mask;
354 0 : break;
355 : case GDK_SCROLL_DOWN:
356 0 : button = 5;
357 0 : button_mask = Button5Mask;
358 0 : break;
359 : case GDK_SCROLL_LEFT:
360 0 : button = 6;
361 0 : break;
362 : case GDK_SCROLL_RIGHT:
363 0 : button = 7;
364 0 : break;
365 : default:
366 0 : return FALSE; // unknown GdkScrollDirection
367 : }
368 :
369 0 : memset(&xevent, 0, sizeof(xevent));
370 0 : xevent.xbutton.type = ButtonPress;
371 0 : xevent.xbutton.window = GDK_WINDOW_XWINDOW(socket_window);
372 0 : xevent.xbutton.root = GDK_WINDOW_XWINDOW(gdk_screen_get_root_window(screen));
373 0 : xevent.xbutton.subwindow = GDK_WINDOW_XWINDOW(plug_window);
374 0 : xevent.xbutton.time = gdk_event->time;
375 0 : xevent.xbutton.x = x;
376 0 : xevent.xbutton.y = y;
377 0 : xevent.xbutton.x_root = gdk_event->x_root;
378 0 : xevent.xbutton.y_root = gdk_event->y_root;
379 0 : xevent.xbutton.state = gdk_event->state;
380 0 : xevent.xbutton.button = button;
381 0 : xevent.xbutton.same_screen = True;
382 :
383 0 : gdk_error_trap_push();
384 :
385 : XSendEvent(dpy, xevent.xbutton.window,
386 0 : True, ButtonPressMask, &xevent);
387 :
388 0 : xevent.xbutton.type = ButtonRelease;
389 0 : xevent.xbutton.state |= button_mask;
390 : XSendEvent(dpy, xevent.xbutton.window,
391 0 : True, ButtonReleaseMask, &xevent);
392 :
393 0 : gdk_display_sync(gdk_screen_get_display(screen));
394 0 : gdk_error_trap_pop();
395 :
396 0 : return TRUE; // event handled
397 : }
398 :
399 : static void
400 0 : wrap_gtk_plug_embedded(GtkPlug* plug) {
401 0 : GdkWindow* socket_window = plug->socket_window;
402 0 : if (socket_window) {
403 0 : if (gtk_check_version(2,18,7) != NULL // older
404 0 : && g_object_get_data(G_OBJECT(socket_window),
405 0 : "moz-existed-before-set-window")) {
406 : // Add missing reference for
407 : // https://bugzilla.gnome.org/show_bug.cgi?id=607061
408 0 : g_object_ref(socket_window);
409 : }
410 :
411 : // Ensure the window exists to make this GtkPlug behave like an
412 : // in-process GtkPlug for Flash Player. (Bugs 561308 and 539138).
413 0 : gtk_widget_realize(GTK_WIDGET(plug));
414 : }
415 :
416 0 : if (*real_gtk_plug_embedded) {
417 0 : (*real_gtk_plug_embedded)(plug);
418 : }
419 0 : }
420 :
421 : //
422 : // The next four constants are knobs that can be tuned. They trade
423 : // off potential UI lag from delayed event processing with CPU time.
424 : //
425 : static const gint kNestedLoopDetectorPriority = G_PRIORITY_HIGH_IDLE;
426 : // 90ms so that we can hopefully break livelocks before the user
427 : // notices UI lag (100ms)
428 : static const guint kNestedLoopDetectorIntervalMs = 90;
429 :
430 : static const gint kBrowserEventPriority = G_PRIORITY_HIGH_IDLE;
431 : static const guint kBrowserEventIntervalMs = 10;
432 :
433 : // static
434 : gboolean
435 0 : PluginModuleChild::DetectNestedEventLoop(gpointer data)
436 : {
437 0 : PluginModuleChild* pmc = static_cast<PluginModuleChild*>(data);
438 :
439 0 : NS_ABORT_IF_FALSE(0 != pmc->mNestedLoopTimerId,
440 : "callback after descheduling");
441 0 : NS_ABORT_IF_FALSE(pmc->mTopLoopDepth < g_main_depth(),
442 : "not canceled before returning to main event loop!");
443 :
444 0 : PLUGIN_LOG_DEBUG(("Detected nested glib event loop"));
445 :
446 : // just detected a nested loop; start a timer that will
447 : // periodically rpc-call back into the browser and process some
448 : // events
449 : pmc->mNestedLoopTimerId =
450 : g_timeout_add_full(kBrowserEventPriority,
451 : kBrowserEventIntervalMs,
452 : PluginModuleChild::ProcessBrowserEvents,
453 : data,
454 0 : NULL);
455 : // cancel the nested-loop detection timer
456 0 : return FALSE;
457 : }
458 :
459 : // static
460 : gboolean
461 0 : PluginModuleChild::ProcessBrowserEvents(gpointer data)
462 : {
463 0 : PluginModuleChild* pmc = static_cast<PluginModuleChild*>(data);
464 :
465 0 : NS_ABORT_IF_FALSE(pmc->mTopLoopDepth < g_main_depth(),
466 : "not canceled before returning to main event loop!");
467 :
468 0 : pmc->CallProcessSomeEvents();
469 :
470 0 : return TRUE;
471 : }
472 :
473 : void
474 0 : PluginModuleChild::EnteredCxxStack()
475 : {
476 0 : NS_ABORT_IF_FALSE(0 == mNestedLoopTimerId,
477 : "previous timer not descheduled");
478 :
479 : mNestedLoopTimerId =
480 : g_timeout_add_full(kNestedLoopDetectorPriority,
481 : kNestedLoopDetectorIntervalMs,
482 : PluginModuleChild::DetectNestedEventLoop,
483 : this,
484 0 : NULL);
485 :
486 : #ifdef DEBUG
487 0 : mTopLoopDepth = g_main_depth();
488 : #endif
489 0 : }
490 :
491 : void
492 0 : PluginModuleChild::ExitedCxxStack()
493 : {
494 0 : NS_ABORT_IF_FALSE(0 < mNestedLoopTimerId,
495 : "nested loop timeout not scheduled");
496 :
497 0 : g_source_remove(mNestedLoopTimerId);
498 0 : mNestedLoopTimerId = 0;
499 0 : }
500 : #elif defined (MOZ_WIDGET_QT)
501 :
502 : void
503 : PluginModuleChild::EnteredCxxStack()
504 : {
505 : NS_ABORT_IF_FALSE(mNestedLoopTimerObject == NULL,
506 : "previous timer not descheduled");
507 : mNestedLoopTimerObject = new NestedLoopTimer(this);
508 : QTimer::singleShot(kNestedLoopDetectorIntervalMs,
509 : mNestedLoopTimerObject, SLOT(timeOut()));
510 : }
511 :
512 : void
513 : PluginModuleChild::ExitedCxxStack()
514 : {
515 : NS_ABORT_IF_FALSE(mNestedLoopTimerObject != NULL,
516 : "nested loop timeout not scheduled");
517 : delete mNestedLoopTimerObject;
518 : mNestedLoopTimerObject = NULL;
519 : }
520 :
521 : #endif
522 :
523 : bool
524 0 : PluginModuleChild::RecvSetParentHangTimeout(const uint32_t& aSeconds)
525 : {
526 : #ifdef XP_WIN
527 : SetReplyTimeoutMs(((aSeconds > 0) ? (1000 * aSeconds) : 0));
528 : #endif
529 0 : return true;
530 : }
531 :
532 : bool
533 0 : PluginModuleChild::ShouldContinueFromReplyTimeout()
534 : {
535 : #ifdef XP_WIN
536 : NS_RUNTIMEABORT("terminating child process");
537 : #endif
538 0 : return true;
539 : }
540 :
541 : bool
542 0 : PluginModuleChild::InitGraphics()
543 : {
544 : #if defined(MOZ_WIDGET_GTK2)
545 : // Work around plugins that don't interact well with GDK
546 : // client-side windows.
547 0 : PR_SetEnv("GDK_NATIVE_WINDOWS=1");
548 :
549 0 : gtk_init(0, 0);
550 :
551 : // GtkPlug is a static class so will leak anyway but this ref makes sure.
552 0 : gpointer gtk_plug_class = g_type_class_ref(GTK_TYPE_PLUG);
553 :
554 : // The dispose method is a good place to hook into the destruction process
555 : // because the reference count should be 1 the last time dispose is
556 : // called. (Toggle references wouldn't detect if the reference count
557 : // might be higher.)
558 0 : GObjectDisposeFn* dispose = &G_OBJECT_CLASS(gtk_plug_class)->dispose;
559 0 : NS_ABORT_IF_FALSE(*dispose != wrap_gtk_plug_dispose,
560 : "InitGraphics called twice");
561 0 : real_gtk_plug_dispose = *dispose;
562 0 : *dispose = wrap_gtk_plug_dispose;
563 :
564 : // If we ever stop setting GDK_NATIVE_WINDOWS, we'll also need to
565 : // gtk_widget_add_events GDK_SCROLL_MASK or GDK client-side windows will
566 : // not tell us about the scroll events that it intercepts. With native
567 : // windows, this is called when GDK intercepts the events; if GDK doesn't
568 : // intercept the events, then the X server will instead send them directly
569 : // to an ancestor (embedder) window.
570 : GtkWidgetScrollEventFn* scroll_event =
571 0 : >K_WIDGET_CLASS(gtk_plug_class)->scroll_event;
572 0 : if (!*scroll_event) {
573 0 : *scroll_event = gtk_plug_scroll_event;
574 : }
575 :
576 0 : GtkPlugEmbeddedFn* embedded = >K_PLUG_CLASS(gtk_plug_class)->embedded;
577 0 : real_gtk_plug_embedded = *embedded;
578 0 : *embedded = wrap_gtk_plug_embedded;
579 :
580 : #elif defined(MOZ_WIDGET_QT)
581 : nsQAppInstance::AddRef();
582 : // Work around plugins that don't interact well without gtk initialized
583 : // see bug 566845
584 : #if defined(MOZ_X11)
585 : if (!sGtkLib)
586 : sGtkLib = PR_LoadLibrary("libgtk-x11-2.0.so.0");
587 : #endif
588 : if (sGtkLib) {
589 : s_gtk_init = (_gtk_init_fn)PR_FindFunctionSymbol(sGtkLib, "gtk_init");
590 : if (s_gtk_init)
591 : s_gtk_init(0, 0);
592 : }
593 : #else
594 : // may not be necessary on all platforms
595 : #endif
596 : #ifdef MOZ_X11
597 : // Do this after initializing GDK, or GDK will install its own handler.
598 0 : XRE_InstallX11ErrorHandler();
599 : #endif
600 0 : return true;
601 : }
602 :
603 : void
604 0 : PluginModuleChild::DeinitGraphics()
605 : {
606 : #ifdef MOZ_WIDGET_QT
607 : nsQAppInstance::Release();
608 : if (sGtkLib) {
609 : PR_UnloadLibrary(sGtkLib);
610 : sGtkLib = nsnull;
611 : s_gtk_init = nsnull;
612 : }
613 : #endif
614 :
615 : #if defined(MOZ_X11) && defined(NS_FREE_PERMANENT_DATA)
616 : // We free some data off of XDisplay close hooks, ensure they're
617 : // run. Closing the display is pretty scary, so we only do it to
618 : // silence leak checkers.
619 0 : XCloseDisplay(DefaultXDisplay());
620 : #endif
621 0 : }
622 :
623 : bool
624 0 : PluginModuleChild::AnswerNP_Shutdown(NPError *rv)
625 : {
626 0 : AssertPluginThread();
627 :
628 : #if defined XP_WIN
629 : mozilla::widget::StopAudioSession();
630 : #endif
631 :
632 : // the PluginModuleParent shuts down this process after this RPC
633 : // call pops off its stack
634 :
635 0 : *rv = mShutdownFunc ? mShutdownFunc() : NPERR_NO_ERROR;
636 :
637 : // weakly guard against re-entry after NP_Shutdown
638 0 : memset(&mFunctions, 0, sizeof(mFunctions));
639 :
640 : #ifdef OS_WIN
641 : ResetEventHooks();
642 : #endif
643 :
644 0 : return true;
645 : }
646 :
647 : bool
648 0 : PluginModuleChild::AnswerOptionalFunctionsSupported(bool *aURLRedirectNotify,
649 : bool *aClearSiteData,
650 : bool *aGetSitesWithData)
651 : {
652 0 : *aURLRedirectNotify = !!mFunctions.urlredirectnotify;
653 0 : *aClearSiteData = !!mFunctions.clearsitedata;
654 0 : *aGetSitesWithData = !!mFunctions.getsiteswithdata;
655 0 : return true;
656 : }
657 :
658 : bool
659 0 : PluginModuleChild::AnswerNPP_ClearSiteData(const nsCString& aSite,
660 : const uint64_t& aFlags,
661 : const uint64_t& aMaxAge,
662 : NPError* aResult)
663 : {
664 : *aResult =
665 0 : mFunctions.clearsitedata(NullableStringGet(aSite), aFlags, aMaxAge);
666 0 : return true;
667 : }
668 :
669 : bool
670 0 : PluginModuleChild::AnswerNPP_GetSitesWithData(InfallibleTArray<nsCString>* aResult)
671 : {
672 0 : char** result = mFunctions.getsiteswithdata();
673 0 : if (!result)
674 0 : return true;
675 :
676 0 : char** iterator = result;
677 0 : while (*iterator) {
678 0 : aResult->AppendElement(*iterator);
679 0 : NS_Free(*iterator);
680 0 : ++iterator;
681 : }
682 0 : NS_Free(result);
683 :
684 0 : return true;
685 : }
686 :
687 : bool
688 0 : PluginModuleChild::RecvSetAudioSessionData(const nsID& aId,
689 : const nsString& aDisplayName,
690 : const nsString& aIconPath)
691 : {
692 : #if !defined XP_WIN
693 0 : NS_RUNTIMEABORT("Not Reached!");
694 0 : return false;
695 : #else
696 : nsresult rv = mozilla::widget::RecvAudioSessionData(aId, aDisplayName, aIconPath);
697 : NS_ENSURE_SUCCESS(rv, true); // Bail early if this fails
698 :
699 : // Ignore failures here; we can't really do anything about them
700 : mozilla::widget::StartAudioSession();
701 : return true;
702 : #endif
703 : }
704 :
705 : void
706 0 : PluginModuleChild::QuickExit()
707 : {
708 0 : NS_WARNING("plugin process _exit()ing");
709 0 : _exit(0);
710 : }
711 :
712 : PCrashReporterChild*
713 0 : PluginModuleChild::AllocPCrashReporter(mozilla::dom::NativeThreadId* id,
714 : PRUint32* processType)
715 : {
716 0 : return new CrashReporterChild();
717 : }
718 :
719 : bool
720 0 : PluginModuleChild::DeallocPCrashReporter(PCrashReporterChild* actor)
721 : {
722 0 : delete actor;
723 0 : return true;
724 : }
725 :
726 : bool
727 0 : PluginModuleChild::AnswerPCrashReporterConstructor(
728 : PCrashReporterChild* actor,
729 : mozilla::dom::NativeThreadId* id,
730 : PRUint32* processType)
731 : {
732 : #ifdef MOZ_CRASHREPORTER
733 0 : *id = CrashReporter::CurrentThreadId();
734 0 : *processType = XRE_GetProcessType();
735 : #endif
736 0 : return true;
737 : }
738 :
739 : void
740 0 : PluginModuleChild::ActorDestroy(ActorDestroyReason why)
741 : {
742 0 : if (AbnormalShutdown == why) {
743 0 : NS_WARNING("shutting down early because of crash!");
744 0 : QuickExit();
745 : }
746 :
747 : // doesn't matter why we're being destroyed; it's up to us to
748 : // initiate (clean) shutdown
749 0 : XRE_ShutdownChildProcess();
750 0 : }
751 :
752 : void
753 0 : PluginModuleChild::CleanUp()
754 : {
755 0 : }
756 :
757 : const char*
758 0 : PluginModuleChild::GetUserAgent()
759 : {
760 0 : if (mUserAgent.IsVoid() && !CallNPN_UserAgent(&mUserAgent))
761 0 : return NULL;
762 :
763 0 : return NullableStringGet(mUserAgent);
764 : }
765 :
766 : bool
767 0 : PluginModuleChild::RegisterActorForNPObject(NPObject* aObject,
768 : PluginScriptableObjectChild* aActor)
769 : {
770 0 : AssertPluginThread();
771 0 : NS_ASSERTION(mObjectMap.IsInitialized(), "Not initialized!");
772 0 : NS_ASSERTION(aObject && aActor, "Null pointer!");
773 :
774 0 : NPObjectData* d = mObjectMap.GetEntry(aObject);
775 0 : if (!d) {
776 0 : NS_ERROR("NPObject not in object table");
777 0 : return false;
778 : }
779 :
780 0 : d->actor = aActor;
781 0 : return true;
782 : }
783 :
784 : void
785 0 : PluginModuleChild::UnregisterActorForNPObject(NPObject* aObject)
786 : {
787 0 : AssertPluginThread();
788 0 : NS_ASSERTION(mObjectMap.IsInitialized(), "Not initialized!");
789 0 : NS_ASSERTION(aObject, "Null pointer!");
790 :
791 0 : mObjectMap.GetEntry(aObject)->actor = NULL;
792 0 : }
793 :
794 : PluginScriptableObjectChild*
795 0 : PluginModuleChild::GetActorForNPObject(NPObject* aObject)
796 : {
797 0 : AssertPluginThread();
798 0 : NS_ASSERTION(mObjectMap.IsInitialized(), "Not initialized!");
799 0 : NS_ASSERTION(aObject, "Null pointer!");
800 :
801 0 : NPObjectData* d = mObjectMap.GetEntry(aObject);
802 0 : if (!d) {
803 0 : NS_ERROR("Plugin using object not created with NPN_CreateObject?");
804 0 : return NULL;
805 : }
806 :
807 0 : return d->actor;
808 : }
809 :
810 : #ifdef DEBUG
811 : bool
812 0 : PluginModuleChild::NPObjectIsRegistered(NPObject* aObject)
813 : {
814 0 : return !!mObjectMap.GetEntry(aObject);
815 : }
816 : #endif
817 :
818 : //-----------------------------------------------------------------------------
819 : // FIXME/cjones: just getting this out of the way for the moment ...
820 :
821 : namespace mozilla {
822 : namespace plugins {
823 : namespace child {
824 :
825 : static NPError NP_CALLBACK
826 : _requestread(NPStream *pstream, NPByteRange *rangeList);
827 :
828 : static NPError NP_CALLBACK
829 : _geturlnotify(NPP aNPP, const char* relativeURL, const char* target,
830 : void* notifyData);
831 :
832 : static NPError NP_CALLBACK
833 : _getvalue(NPP aNPP, NPNVariable variable, void *r_value);
834 :
835 : static NPError NP_CALLBACK
836 : _setvalue(NPP aNPP, NPPVariable variable, void *r_value);
837 :
838 : static NPError NP_CALLBACK
839 : _geturl(NPP aNPP, const char* relativeURL, const char* target);
840 :
841 : static NPError NP_CALLBACK
842 : _posturlnotify(NPP aNPP, const char* relativeURL, const char *target,
843 : uint32_t len, const char *buf, NPBool file, void* notifyData);
844 :
845 : static NPError NP_CALLBACK
846 : _posturl(NPP aNPP, const char* relativeURL, const char *target, uint32_t len,
847 : const char *buf, NPBool file);
848 :
849 : static NPError NP_CALLBACK
850 : _newstream(NPP aNPP, NPMIMEType type, const char* window, NPStream** pstream);
851 :
852 : static int32_t NP_CALLBACK
853 : _write(NPP aNPP, NPStream *pstream, int32_t len, void *buffer);
854 :
855 : static NPError NP_CALLBACK
856 : _destroystream(NPP aNPP, NPStream *pstream, NPError reason);
857 :
858 : static void NP_CALLBACK
859 : _status(NPP aNPP, const char *message);
860 :
861 : static void NP_CALLBACK
862 : _memfree (void *ptr);
863 :
864 : static uint32_t NP_CALLBACK
865 : _memflush(uint32_t size);
866 :
867 : static void NP_CALLBACK
868 : _reloadplugins(NPBool reloadPages);
869 :
870 : static void NP_CALLBACK
871 : _invalidaterect(NPP aNPP, NPRect *invalidRect);
872 :
873 : static void NP_CALLBACK
874 : _invalidateregion(NPP aNPP, NPRegion invalidRegion);
875 :
876 : static void NP_CALLBACK
877 : _forceredraw(NPP aNPP);
878 :
879 : static const char* NP_CALLBACK
880 : _useragent(NPP aNPP);
881 :
882 : static void* NP_CALLBACK
883 : _memalloc (uint32_t size);
884 :
885 : // Deprecated entry points for the old Java plugin.
886 : static void* NP_CALLBACK /* OJI type: JRIEnv* */
887 : _getjavaenv(void);
888 :
889 : // Deprecated entry points for the old Java plugin.
890 : static void* NP_CALLBACK /* OJI type: jref */
891 : _getjavapeer(NPP aNPP);
892 :
893 : static bool NP_CALLBACK
894 : _invoke(NPP aNPP, NPObject* npobj, NPIdentifier method, const NPVariant *args,
895 : uint32_t argCount, NPVariant *result);
896 :
897 : static bool NP_CALLBACK
898 : _invokedefault(NPP aNPP, NPObject* npobj, const NPVariant *args,
899 : uint32_t argCount, NPVariant *result);
900 :
901 : static bool NP_CALLBACK
902 : _evaluate(NPP aNPP, NPObject* npobj, NPString *script, NPVariant *result);
903 :
904 : static bool NP_CALLBACK
905 : _getproperty(NPP aNPP, NPObject* npobj, NPIdentifier property,
906 : NPVariant *result);
907 :
908 : static bool NP_CALLBACK
909 : _setproperty(NPP aNPP, NPObject* npobj, NPIdentifier property,
910 : const NPVariant *value);
911 :
912 : static bool NP_CALLBACK
913 : _removeproperty(NPP aNPP, NPObject* npobj, NPIdentifier property);
914 :
915 : static bool NP_CALLBACK
916 : _hasproperty(NPP aNPP, NPObject* npobj, NPIdentifier propertyName);
917 :
918 : static bool NP_CALLBACK
919 : _hasmethod(NPP aNPP, NPObject* npobj, NPIdentifier methodName);
920 :
921 : static bool NP_CALLBACK
922 : _enumerate(NPP aNPP, NPObject *npobj, NPIdentifier **identifier,
923 : uint32_t *count);
924 :
925 : static bool NP_CALLBACK
926 : _construct(NPP aNPP, NPObject* npobj, const NPVariant *args,
927 : uint32_t argCount, NPVariant *result);
928 :
929 : static void NP_CALLBACK
930 : _releasevariantvalue(NPVariant *variant);
931 :
932 : static void NP_CALLBACK
933 : _setexception(NPObject* npobj, const NPUTF8 *message);
934 :
935 : static void NP_CALLBACK
936 : _pushpopupsenabledstate(NPP aNPP, NPBool enabled);
937 :
938 : static void NP_CALLBACK
939 : _poppopupsenabledstate(NPP aNPP);
940 :
941 : static void NP_CALLBACK
942 : _pluginthreadasynccall(NPP instance, PluginThreadCallback func,
943 : void *userData);
944 :
945 : static NPError NP_CALLBACK
946 : _getvalueforurl(NPP npp, NPNURLVariable variable, const char *url,
947 : char **value, uint32_t *len);
948 :
949 : static NPError NP_CALLBACK
950 : _setvalueforurl(NPP npp, NPNURLVariable variable, const char *url,
951 : const char *value, uint32_t len);
952 :
953 : static NPError NP_CALLBACK
954 : _getauthenticationinfo(NPP npp, const char *protocol,
955 : const char *host, int32_t port,
956 : const char *scheme, const char *realm,
957 : char **username, uint32_t *ulen,
958 : char **password, uint32_t *plen);
959 :
960 : static uint32_t NP_CALLBACK
961 : _scheduletimer(NPP instance, uint32_t interval, NPBool repeat,
962 : void (*timerFunc)(NPP npp, uint32_t timerID));
963 :
964 : static void NP_CALLBACK
965 : _unscheduletimer(NPP instance, uint32_t timerID);
966 :
967 : static NPError NP_CALLBACK
968 : _popupcontextmenu(NPP instance, NPMenu* menu);
969 :
970 : static NPBool NP_CALLBACK
971 : _convertpoint(NPP instance,
972 : double sourceX, double sourceY, NPCoordinateSpace sourceSpace,
973 : double *destX, double *destY, NPCoordinateSpace destSpace);
974 :
975 : static void NP_CALLBACK
976 : _urlredirectresponse(NPP instance, void* notifyData, NPBool allow);
977 :
978 : static NPError NP_CALLBACK
979 : _initasyncsurface(NPP instance, NPSize *size,
980 : NPImageFormat format, void *initData,
981 : NPAsyncSurface *surface);
982 :
983 : static NPError NP_CALLBACK
984 : _finalizeasyncsurface(NPP instance, NPAsyncSurface *surface);
985 :
986 : static void NP_CALLBACK
987 : _setcurrentasyncsurface(NPP instance, NPAsyncSurface *surface, NPRect *changed);
988 :
989 : } /* namespace child */
990 : } /* namespace plugins */
991 : } /* namespace mozilla */
992 :
993 : const NPNetscapeFuncs PluginModuleChild::sBrowserFuncs = {
994 : sizeof(sBrowserFuncs),
995 : (NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR,
996 : mozilla::plugins::child::_geturl,
997 : mozilla::plugins::child::_posturl,
998 : mozilla::plugins::child::_requestread,
999 : mozilla::plugins::child::_newstream,
1000 : mozilla::plugins::child::_write,
1001 : mozilla::plugins::child::_destroystream,
1002 : mozilla::plugins::child::_status,
1003 : mozilla::plugins::child::_useragent,
1004 : mozilla::plugins::child::_memalloc,
1005 : mozilla::plugins::child::_memfree,
1006 : mozilla::plugins::child::_memflush,
1007 : mozilla::plugins::child::_reloadplugins,
1008 : mozilla::plugins::child::_getjavaenv,
1009 : mozilla::plugins::child::_getjavapeer,
1010 : mozilla::plugins::child::_geturlnotify,
1011 : mozilla::plugins::child::_posturlnotify,
1012 : mozilla::plugins::child::_getvalue,
1013 : mozilla::plugins::child::_setvalue,
1014 : mozilla::plugins::child::_invalidaterect,
1015 : mozilla::plugins::child::_invalidateregion,
1016 : mozilla::plugins::child::_forceredraw,
1017 : PluginModuleChild::NPN_GetStringIdentifier,
1018 : PluginModuleChild::NPN_GetStringIdentifiers,
1019 : PluginModuleChild::NPN_GetIntIdentifier,
1020 : PluginModuleChild::NPN_IdentifierIsString,
1021 : PluginModuleChild::NPN_UTF8FromIdentifier,
1022 : PluginModuleChild::NPN_IntFromIdentifier,
1023 : PluginModuleChild::NPN_CreateObject,
1024 : PluginModuleChild::NPN_RetainObject,
1025 : PluginModuleChild::NPN_ReleaseObject,
1026 : mozilla::plugins::child::_invoke,
1027 : mozilla::plugins::child::_invokedefault,
1028 : mozilla::plugins::child::_evaluate,
1029 : mozilla::plugins::child::_getproperty,
1030 : mozilla::plugins::child::_setproperty,
1031 : mozilla::plugins::child::_removeproperty,
1032 : mozilla::plugins::child::_hasproperty,
1033 : mozilla::plugins::child::_hasmethod,
1034 : mozilla::plugins::child::_releasevariantvalue,
1035 : mozilla::plugins::child::_setexception,
1036 : mozilla::plugins::child::_pushpopupsenabledstate,
1037 : mozilla::plugins::child::_poppopupsenabledstate,
1038 : mozilla::plugins::child::_enumerate,
1039 : mozilla::plugins::child::_pluginthreadasynccall,
1040 : mozilla::plugins::child::_construct,
1041 : mozilla::plugins::child::_getvalueforurl,
1042 : mozilla::plugins::child::_setvalueforurl,
1043 : mozilla::plugins::child::_getauthenticationinfo,
1044 : mozilla::plugins::child::_scheduletimer,
1045 : mozilla::plugins::child::_unscheduletimer,
1046 : mozilla::plugins::child::_popupcontextmenu,
1047 : mozilla::plugins::child::_convertpoint,
1048 : NULL, // handleevent, unimplemented
1049 : NULL, // unfocusinstance, unimplemented
1050 : mozilla::plugins::child::_urlredirectresponse,
1051 : mozilla::plugins::child::_initasyncsurface,
1052 : mozilla::plugins::child::_finalizeasyncsurface,
1053 : mozilla::plugins::child::_setcurrentasyncsurface
1054 : };
1055 :
1056 : PluginInstanceChild*
1057 0 : InstCast(NPP aNPP)
1058 : {
1059 0 : NS_ABORT_IF_FALSE(!!(aNPP->ndata), "nil instance");
1060 0 : return static_cast<PluginInstanceChild*>(aNPP->ndata);
1061 : }
1062 :
1063 : namespace mozilla {
1064 : namespace plugins {
1065 : namespace child {
1066 :
1067 : NPError NP_CALLBACK
1068 0 : _requestread(NPStream* aStream,
1069 : NPByteRange* aRangeList)
1070 : {
1071 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1072 0 : ENSURE_PLUGIN_THREAD(NPERR_INVALID_PARAM);
1073 :
1074 : BrowserStreamChild* bs =
1075 0 : static_cast<BrowserStreamChild*>(static_cast<AStream*>(aStream->ndata));
1076 0 : bs->EnsureCorrectStream(aStream);
1077 0 : return bs->NPN_RequestRead(aRangeList);
1078 : }
1079 :
1080 : NPError NP_CALLBACK
1081 0 : _geturlnotify(NPP aNPP,
1082 : const char* aRelativeURL,
1083 : const char* aTarget,
1084 : void* aNotifyData)
1085 : {
1086 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1087 0 : ENSURE_PLUGIN_THREAD(NPERR_INVALID_PARAM);
1088 :
1089 0 : if (!aNPP) // NULL check for nspluginwrapper (bug 561690)
1090 0 : return NPERR_INVALID_INSTANCE_ERROR;
1091 :
1092 0 : nsCString url = NullableString(aRelativeURL);
1093 0 : StreamNotifyChild* sn = new StreamNotifyChild(url);
1094 :
1095 : NPError err;
1096 0 : InstCast(aNPP)->CallPStreamNotifyConstructor(
1097 0 : sn, url, NullableString(aTarget), false, nsCString(), false, &err);
1098 :
1099 0 : if (NPERR_NO_ERROR == err) {
1100 : // If NPN_PostURLNotify fails, the parent will immediately send us
1101 : // a PStreamNotifyDestructor, which should not call NPP_URLNotify.
1102 0 : sn->SetValid(aNotifyData);
1103 : }
1104 :
1105 0 : return err;
1106 : }
1107 :
1108 : NPError NP_CALLBACK
1109 0 : _getvalue(NPP aNPP,
1110 : NPNVariable aVariable,
1111 : void* aValue)
1112 : {
1113 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1114 0 : ENSURE_PLUGIN_THREAD(NPERR_INVALID_PARAM);
1115 :
1116 0 : switch (aVariable) {
1117 : // Copied from nsNPAPIPlugin.cpp
1118 : case NPNVToolkit:
1119 : #if defined(MOZ_WIDGET_GTK2) || defined(MOZ_WIDGET_QT)
1120 0 : *static_cast<NPNToolkitType*>(aValue) = NPNVGtk2;
1121 0 : return NPERR_NO_ERROR;
1122 : #endif
1123 : return NPERR_GENERIC_ERROR;
1124 :
1125 : case NPNVjavascriptEnabledBool: // Intentional fall-through
1126 : case NPNVasdEnabledBool: // Intentional fall-through
1127 : case NPNVisOfflineBool: // Intentional fall-through
1128 : case NPNVSupportsXEmbedBool: // Intentional fall-through
1129 : case NPNVSupportsWindowless: // Intentional fall-through
1130 : case NPNVprivateModeBool: {
1131 : NPError result;
1132 : bool value;
1133 0 : PluginModuleChild::current()->
1134 0 : CallNPN_GetValue_WithBoolReturn(aVariable, &result, &value);
1135 0 : *(NPBool*)aValue = value ? true : false;
1136 0 : return result;
1137 : }
1138 :
1139 : default: {
1140 0 : if (aNPP) {
1141 0 : return InstCast(aNPP)->NPN_GetValue(aVariable, aValue);
1142 : }
1143 :
1144 0 : NS_WARNING("Null NPP!");
1145 0 : return NPERR_INVALID_INSTANCE_ERROR;
1146 : }
1147 : }
1148 :
1149 : NS_NOTREACHED("Shouldn't get here!");
1150 : return NPERR_GENERIC_ERROR;
1151 : }
1152 :
1153 : NPError NP_CALLBACK
1154 0 : _setvalue(NPP aNPP,
1155 : NPPVariable aVariable,
1156 : void* aValue)
1157 : {
1158 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1159 0 : ENSURE_PLUGIN_THREAD(NPERR_INVALID_PARAM);
1160 0 : return InstCast(aNPP)->NPN_SetValue(aVariable, aValue);
1161 : }
1162 :
1163 : NPError NP_CALLBACK
1164 0 : _geturl(NPP aNPP,
1165 : const char* aRelativeURL,
1166 : const char* aTarget)
1167 : {
1168 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1169 0 : ENSURE_PLUGIN_THREAD(NPERR_INVALID_PARAM);
1170 :
1171 : NPError err;
1172 0 : InstCast(aNPP)->CallNPN_GetURL(NullableString(aRelativeURL),
1173 0 : NullableString(aTarget), &err);
1174 0 : return err;
1175 : }
1176 :
1177 : NPError NP_CALLBACK
1178 0 : _posturlnotify(NPP aNPP,
1179 : const char* aRelativeURL,
1180 : const char* aTarget,
1181 : uint32_t aLength,
1182 : const char* aBuffer,
1183 : NPBool aIsFile,
1184 : void* aNotifyData)
1185 : {
1186 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1187 0 : ENSURE_PLUGIN_THREAD(NPERR_INVALID_PARAM);
1188 :
1189 0 : if (!aBuffer)
1190 0 : return NPERR_INVALID_PARAM;
1191 :
1192 0 : nsCString url = NullableString(aRelativeURL);
1193 0 : StreamNotifyChild* sn = new StreamNotifyChild(url);
1194 :
1195 : NPError err;
1196 0 : InstCast(aNPP)->CallPStreamNotifyConstructor(
1197 0 : sn, url, NullableString(aTarget), true,
1198 0 : nsCString(aBuffer, aLength), aIsFile, &err);
1199 :
1200 0 : if (NPERR_NO_ERROR == err) {
1201 : // If NPN_PostURLNotify fails, the parent will immediately send us
1202 : // a PStreamNotifyDestructor, which should not call NPP_URLNotify.
1203 0 : sn->SetValid(aNotifyData);
1204 : }
1205 :
1206 0 : return err;
1207 : }
1208 :
1209 : NPError NP_CALLBACK
1210 0 : _posturl(NPP aNPP,
1211 : const char* aRelativeURL,
1212 : const char* aTarget,
1213 : uint32_t aLength,
1214 : const char* aBuffer,
1215 : NPBool aIsFile)
1216 : {
1217 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1218 0 : ENSURE_PLUGIN_THREAD(NPERR_INVALID_PARAM);
1219 :
1220 : NPError err;
1221 : // FIXME what should happen when |aBuffer| is null?
1222 0 : InstCast(aNPP)->CallNPN_PostURL(NullableString(aRelativeURL),
1223 0 : NullableString(aTarget),
1224 0 : nsDependentCString(aBuffer, aLength),
1225 0 : aIsFile, &err);
1226 0 : return err;
1227 : }
1228 :
1229 : NPError NP_CALLBACK
1230 0 : _newstream(NPP aNPP,
1231 : NPMIMEType aMIMEType,
1232 : const char* aWindow,
1233 : NPStream** aStream)
1234 : {
1235 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1236 0 : ENSURE_PLUGIN_THREAD(NPERR_INVALID_PARAM);
1237 0 : return InstCast(aNPP)->NPN_NewStream(aMIMEType, aWindow, aStream);
1238 : }
1239 :
1240 : int32_t NP_CALLBACK
1241 0 : _write(NPP aNPP,
1242 : NPStream* aStream,
1243 : int32_t aLength,
1244 : void* aBuffer)
1245 : {
1246 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1247 0 : ENSURE_PLUGIN_THREAD(0);
1248 :
1249 : PluginStreamChild* ps =
1250 0 : static_cast<PluginStreamChild*>(static_cast<AStream*>(aStream->ndata));
1251 0 : ps->EnsureCorrectInstance(InstCast(aNPP));
1252 0 : ps->EnsureCorrectStream(aStream);
1253 0 : return ps->NPN_Write(aLength, aBuffer);
1254 : }
1255 :
1256 : NPError NP_CALLBACK
1257 0 : _destroystream(NPP aNPP,
1258 : NPStream* aStream,
1259 : NPError aReason)
1260 : {
1261 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1262 0 : ENSURE_PLUGIN_THREAD(NPERR_INVALID_PARAM);
1263 :
1264 0 : PluginInstanceChild* p = InstCast(aNPP);
1265 0 : AStream* s = static_cast<AStream*>(aStream->ndata);
1266 0 : if (s->IsBrowserStream()) {
1267 0 : BrowserStreamChild* bs = static_cast<BrowserStreamChild*>(s);
1268 0 : bs->EnsureCorrectInstance(p);
1269 0 : bs->NPN_DestroyStream(aReason);
1270 : }
1271 : else {
1272 0 : PluginStreamChild* ps = static_cast<PluginStreamChild*>(s);
1273 0 : ps->EnsureCorrectInstance(p);
1274 0 : PPluginStreamChild::Call__delete__(ps, aReason, false);
1275 : }
1276 0 : return NPERR_NO_ERROR;
1277 : }
1278 :
1279 : void NP_CALLBACK
1280 0 : _status(NPP aNPP,
1281 : const char* aMessage)
1282 : {
1283 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1284 0 : ENSURE_PLUGIN_THREAD_VOID();
1285 0 : NS_WARNING("Not yet implemented!");
1286 : }
1287 :
1288 : void NP_CALLBACK
1289 0 : _memfree(void* aPtr)
1290 : {
1291 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1292 : // Only assert plugin thread here for consistency with in-process plugins.
1293 0 : AssertPluginThread();
1294 0 : NS_Free(aPtr);
1295 0 : }
1296 :
1297 : uint32_t NP_CALLBACK
1298 0 : _memflush(uint32_t aSize)
1299 : {
1300 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1301 : // Only assert plugin thread here for consistency with in-process plugins.
1302 0 : AssertPluginThread();
1303 0 : return 0;
1304 : }
1305 :
1306 : void NP_CALLBACK
1307 0 : _reloadplugins(NPBool aReloadPages)
1308 : {
1309 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1310 0 : ENSURE_PLUGIN_THREAD_VOID();
1311 :
1312 0 : PluginModuleChild::current()->SendNPN_ReloadPlugins(!!aReloadPages);
1313 : }
1314 :
1315 : void NP_CALLBACK
1316 0 : _invalidaterect(NPP aNPP,
1317 : NPRect* aInvalidRect)
1318 : {
1319 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1320 0 : ENSURE_PLUGIN_THREAD_VOID();
1321 : // NULL check for nspluginwrapper (bug 548434)
1322 0 : if (aNPP) {
1323 0 : InstCast(aNPP)->InvalidateRect(aInvalidRect);
1324 : }
1325 : }
1326 :
1327 : void NP_CALLBACK
1328 0 : _invalidateregion(NPP aNPP,
1329 : NPRegion aInvalidRegion)
1330 : {
1331 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1332 0 : ENSURE_PLUGIN_THREAD_VOID();
1333 0 : NS_WARNING("Not yet implemented!");
1334 : }
1335 :
1336 : void NP_CALLBACK
1337 0 : _forceredraw(NPP aNPP)
1338 : {
1339 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1340 0 : ENSURE_PLUGIN_THREAD_VOID();
1341 :
1342 : // We ignore calls to NPN_ForceRedraw. Such calls should
1343 : // never be necessary.
1344 : }
1345 :
1346 : const char* NP_CALLBACK
1347 0 : _useragent(NPP aNPP)
1348 : {
1349 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1350 0 : ENSURE_PLUGIN_THREAD(nsnull);
1351 0 : return PluginModuleChild::current()->GetUserAgent();
1352 : }
1353 :
1354 : void* NP_CALLBACK
1355 0 : _memalloc(uint32_t aSize)
1356 : {
1357 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1358 : // Only assert plugin thread here for consistency with in-process plugins.
1359 0 : AssertPluginThread();
1360 0 : return NS_Alloc(aSize);
1361 : }
1362 :
1363 : // Deprecated entry points for the old Java plugin.
1364 : void* NP_CALLBACK /* OJI type: JRIEnv* */
1365 0 : _getjavaenv(void)
1366 : {
1367 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1368 0 : return 0;
1369 : }
1370 :
1371 : void* NP_CALLBACK /* OJI type: jref */
1372 0 : _getjavapeer(NPP aNPP)
1373 : {
1374 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1375 0 : return 0;
1376 : }
1377 :
1378 : bool NP_CALLBACK
1379 0 : _invoke(NPP aNPP,
1380 : NPObject* aNPObj,
1381 : NPIdentifier aMethod,
1382 : const NPVariant* aArgs,
1383 : uint32_t aArgCount,
1384 : NPVariant* aResult)
1385 : {
1386 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1387 0 : ENSURE_PLUGIN_THREAD(false);
1388 :
1389 0 : if (!aNPP || !aNPObj || !aNPObj->_class || !aNPObj->_class->invoke)
1390 0 : return false;
1391 :
1392 0 : return aNPObj->_class->invoke(aNPObj, aMethod, aArgs, aArgCount, aResult);
1393 : }
1394 :
1395 : bool NP_CALLBACK
1396 0 : _invokedefault(NPP aNPP,
1397 : NPObject* aNPObj,
1398 : const NPVariant* aArgs,
1399 : uint32_t aArgCount,
1400 : NPVariant* aResult)
1401 : {
1402 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1403 0 : ENSURE_PLUGIN_THREAD(false);
1404 :
1405 0 : if (!aNPP || !aNPObj || !aNPObj->_class || !aNPObj->_class->invokeDefault)
1406 0 : return false;
1407 :
1408 0 : return aNPObj->_class->invokeDefault(aNPObj, aArgs, aArgCount, aResult);
1409 : }
1410 :
1411 : bool NP_CALLBACK
1412 0 : _evaluate(NPP aNPP,
1413 : NPObject* aObject,
1414 : NPString* aScript,
1415 : NPVariant* aResult)
1416 : {
1417 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1418 0 : ENSURE_PLUGIN_THREAD(false);
1419 :
1420 0 : if (!(aNPP && aObject && aScript && aResult)) {
1421 0 : NS_ERROR("Bad arguments!");
1422 0 : return false;
1423 : }
1424 :
1425 : PluginScriptableObjectChild* actor =
1426 0 : InstCast(aNPP)->GetActorForNPObject(aObject);
1427 0 : if (!actor) {
1428 0 : NS_ERROR("Failed to create actor?!");
1429 0 : return false;
1430 : }
1431 :
1432 : #ifdef XP_WIN
1433 : if (gDelayFlashFocusReplyUntilEval) {
1434 : ReplyMessage(0);
1435 : gDelayFlashFocusReplyUntilEval = false;
1436 : }
1437 : #endif
1438 :
1439 0 : return actor->Evaluate(aScript, aResult);
1440 : }
1441 :
1442 : bool NP_CALLBACK
1443 0 : _getproperty(NPP aNPP,
1444 : NPObject* aNPObj,
1445 : NPIdentifier aPropertyName,
1446 : NPVariant* aResult)
1447 : {
1448 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1449 0 : ENSURE_PLUGIN_THREAD(false);
1450 :
1451 0 : if (!aNPP || !aNPObj || !aNPObj->_class || !aNPObj->_class->getProperty)
1452 0 : return false;
1453 :
1454 0 : return aNPObj->_class->getProperty(aNPObj, aPropertyName, aResult);
1455 : }
1456 :
1457 : bool NP_CALLBACK
1458 0 : _setproperty(NPP aNPP,
1459 : NPObject* aNPObj,
1460 : NPIdentifier aPropertyName,
1461 : const NPVariant* aValue)
1462 : {
1463 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1464 0 : ENSURE_PLUGIN_THREAD(false);
1465 :
1466 0 : if (!aNPP || !aNPObj || !aNPObj->_class || !aNPObj->_class->setProperty)
1467 0 : return false;
1468 :
1469 0 : return aNPObj->_class->setProperty(aNPObj, aPropertyName, aValue);
1470 : }
1471 :
1472 : bool NP_CALLBACK
1473 0 : _removeproperty(NPP aNPP,
1474 : NPObject* aNPObj,
1475 : NPIdentifier aPropertyName)
1476 : {
1477 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1478 0 : ENSURE_PLUGIN_THREAD(false);
1479 :
1480 0 : if (!aNPP || !aNPObj || !aNPObj->_class || !aNPObj->_class->removeProperty)
1481 0 : return false;
1482 :
1483 0 : return aNPObj->_class->removeProperty(aNPObj, aPropertyName);
1484 : }
1485 :
1486 : bool NP_CALLBACK
1487 0 : _hasproperty(NPP aNPP,
1488 : NPObject* aNPObj,
1489 : NPIdentifier aPropertyName)
1490 : {
1491 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1492 0 : ENSURE_PLUGIN_THREAD(false);
1493 :
1494 0 : if (!aNPP || !aNPObj || !aNPObj->_class || !aNPObj->_class->hasProperty)
1495 0 : return false;
1496 :
1497 0 : return aNPObj->_class->hasProperty(aNPObj, aPropertyName);
1498 : }
1499 :
1500 : bool NP_CALLBACK
1501 0 : _hasmethod(NPP aNPP,
1502 : NPObject* aNPObj,
1503 : NPIdentifier aMethodName)
1504 : {
1505 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1506 0 : ENSURE_PLUGIN_THREAD(false);
1507 :
1508 0 : if (!aNPP || !aNPObj || !aNPObj->_class || !aNPObj->_class->hasMethod)
1509 0 : return false;
1510 :
1511 0 : return aNPObj->_class->hasMethod(aNPObj, aMethodName);
1512 : }
1513 :
1514 : bool NP_CALLBACK
1515 0 : _enumerate(NPP aNPP,
1516 : NPObject* aNPObj,
1517 : NPIdentifier** aIdentifiers,
1518 : uint32_t* aCount)
1519 : {
1520 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1521 0 : ENSURE_PLUGIN_THREAD(false);
1522 :
1523 0 : if (!aNPP || !aNPObj || !aNPObj->_class)
1524 0 : return false;
1525 :
1526 0 : if (!NP_CLASS_STRUCT_VERSION_HAS_ENUM(aNPObj->_class) ||
1527 0 : !aNPObj->_class->enumerate) {
1528 0 : *aIdentifiers = 0;
1529 0 : *aCount = 0;
1530 0 : return true;
1531 : }
1532 :
1533 0 : return aNPObj->_class->enumerate(aNPObj, aIdentifiers, aCount);
1534 : }
1535 :
1536 : bool NP_CALLBACK
1537 0 : _construct(NPP aNPP,
1538 : NPObject* aNPObj,
1539 : const NPVariant* aArgs,
1540 : uint32_t aArgCount,
1541 : NPVariant* aResult)
1542 : {
1543 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1544 0 : ENSURE_PLUGIN_THREAD(false);
1545 :
1546 0 : if (!aNPP || !aNPObj || !aNPObj->_class ||
1547 0 : !NP_CLASS_STRUCT_VERSION_HAS_CTOR(aNPObj->_class) ||
1548 0 : !aNPObj->_class->construct) {
1549 0 : return false;
1550 : }
1551 :
1552 0 : return aNPObj->_class->construct(aNPObj, aArgs, aArgCount, aResult);
1553 : }
1554 :
1555 : void NP_CALLBACK
1556 0 : _releasevariantvalue(NPVariant* aVariant)
1557 : {
1558 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1559 : // Only assert plugin thread here for consistency with in-process plugins.
1560 0 : AssertPluginThread();
1561 :
1562 0 : if (NPVARIANT_IS_STRING(*aVariant)) {
1563 0 : NPString str = NPVARIANT_TO_STRING(*aVariant);
1564 0 : free(const_cast<NPUTF8*>(str.UTF8Characters));
1565 : }
1566 0 : else if (NPVARIANT_IS_OBJECT(*aVariant)) {
1567 0 : NPObject* object = NPVARIANT_TO_OBJECT(*aVariant);
1568 0 : if (object) {
1569 0 : PluginModuleChild::NPN_ReleaseObject(object);
1570 : }
1571 : }
1572 0 : VOID_TO_NPVARIANT(*aVariant);
1573 0 : }
1574 :
1575 : void NP_CALLBACK
1576 0 : _setexception(NPObject* aNPObj,
1577 : const NPUTF8* aMessage)
1578 : {
1579 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1580 0 : ENSURE_PLUGIN_THREAD_VOID();
1581 :
1582 0 : PluginModuleChild* self = PluginModuleChild::current();
1583 0 : PluginScriptableObjectChild* actor = NULL;
1584 0 : if (aNPObj) {
1585 0 : actor = self->GetActorForNPObject(aNPObj);
1586 0 : if (!actor) {
1587 0 : NS_ERROR("Failed to get actor!");
1588 0 : return;
1589 : }
1590 : }
1591 :
1592 : self->SendNPN_SetException(static_cast<PPluginScriptableObjectChild*>(actor),
1593 0 : NullableString(aMessage));
1594 : }
1595 :
1596 : void NP_CALLBACK
1597 0 : _pushpopupsenabledstate(NPP aNPP,
1598 : NPBool aEnabled)
1599 : {
1600 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1601 0 : ENSURE_PLUGIN_THREAD_VOID();
1602 :
1603 0 : InstCast(aNPP)->CallNPN_PushPopupsEnabledState(aEnabled ? true : false);
1604 : }
1605 :
1606 : void NP_CALLBACK
1607 0 : _poppopupsenabledstate(NPP aNPP)
1608 : {
1609 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1610 0 : ENSURE_PLUGIN_THREAD_VOID();
1611 :
1612 0 : InstCast(aNPP)->CallNPN_PopPopupsEnabledState();
1613 : }
1614 :
1615 : void NP_CALLBACK
1616 0 : _pluginthreadasynccall(NPP aNPP,
1617 : PluginThreadCallback aFunc,
1618 : void* aUserData)
1619 : {
1620 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1621 0 : if (!aFunc)
1622 0 : return;
1623 :
1624 0 : InstCast(aNPP)->AsyncCall(aFunc, aUserData);
1625 : }
1626 :
1627 : NPError NP_CALLBACK
1628 0 : _getvalueforurl(NPP npp, NPNURLVariable variable, const char *url,
1629 : char **value, uint32_t *len)
1630 : {
1631 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1632 0 : AssertPluginThread();
1633 :
1634 0 : if (!url)
1635 0 : return NPERR_INVALID_URL;
1636 :
1637 0 : if (!npp || !value || !len)
1638 0 : return NPERR_INVALID_PARAM;
1639 :
1640 0 : switch (variable) {
1641 : case NPNURLVCookie:
1642 : case NPNURLVProxy:
1643 0 : nsCString v;
1644 : NPError result;
1645 0 : InstCast(npp)->
1646 0 : CallNPN_GetValueForURL(variable, nsCString(url), &v, &result);
1647 0 : if (NPERR_NO_ERROR == result) {
1648 0 : *value = ToNewCString(v);
1649 0 : *len = v.Length();
1650 : }
1651 0 : return result;
1652 : }
1653 :
1654 0 : return NPERR_INVALID_PARAM;
1655 : }
1656 :
1657 : NPError NP_CALLBACK
1658 0 : _setvalueforurl(NPP npp, NPNURLVariable variable, const char *url,
1659 : const char *value, uint32_t len)
1660 : {
1661 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1662 0 : AssertPluginThread();
1663 :
1664 0 : if (!value)
1665 0 : return NPERR_INVALID_PARAM;
1666 :
1667 0 : if (!url)
1668 0 : return NPERR_INVALID_URL;
1669 :
1670 0 : switch (variable) {
1671 : case NPNURLVCookie:
1672 : case NPNURLVProxy:
1673 : NPError result;
1674 0 : InstCast(npp)->CallNPN_SetValueForURL(variable, nsCString(url),
1675 0 : nsDependentCString(value, len),
1676 0 : &result);
1677 0 : return result;
1678 : }
1679 :
1680 0 : return NPERR_INVALID_PARAM;
1681 : }
1682 :
1683 : NPError NP_CALLBACK
1684 0 : _getauthenticationinfo(NPP npp, const char *protocol,
1685 : const char *host, int32_t port,
1686 : const char *scheme, const char *realm,
1687 : char **username, uint32_t *ulen,
1688 : char **password, uint32_t *plen)
1689 : {
1690 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1691 0 : AssertPluginThread();
1692 :
1693 0 : if (!protocol || !host || !scheme || !realm || !username || !ulen ||
1694 : !password || !plen)
1695 0 : return NPERR_INVALID_PARAM;
1696 :
1697 0 : nsCString u;
1698 0 : nsCString p;
1699 : NPError result;
1700 0 : InstCast(npp)->
1701 0 : CallNPN_GetAuthenticationInfo(nsDependentCString(protocol),
1702 0 : nsDependentCString(host),
1703 : port,
1704 0 : nsDependentCString(scheme),
1705 0 : nsDependentCString(realm),
1706 0 : &u, &p, &result);
1707 0 : if (NPERR_NO_ERROR == result) {
1708 0 : *username = ToNewCString(u);
1709 0 : *ulen = u.Length();
1710 0 : *password = ToNewCString(p);
1711 0 : *plen = p.Length();
1712 : }
1713 0 : return result;
1714 : }
1715 :
1716 : uint32_t NP_CALLBACK
1717 0 : _scheduletimer(NPP npp, uint32_t interval, NPBool repeat,
1718 : void (*timerFunc)(NPP npp, uint32_t timerID))
1719 : {
1720 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1721 0 : AssertPluginThread();
1722 0 : return InstCast(npp)->ScheduleTimer(interval, repeat, timerFunc);
1723 : }
1724 :
1725 : void NP_CALLBACK
1726 0 : _unscheduletimer(NPP npp, uint32_t timerID)
1727 : {
1728 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1729 0 : AssertPluginThread();
1730 0 : InstCast(npp)->UnscheduleTimer(timerID);
1731 0 : }
1732 :
1733 :
1734 : #ifdef OS_MACOSX
1735 : static void ProcessBrowserEvents(void* pluginModule) {
1736 : PluginModuleChild* pmc = static_cast<PluginModuleChild*>(pluginModule);
1737 :
1738 : if (!pmc)
1739 : return;
1740 :
1741 : pmc->CallProcessSomeEvents();
1742 : }
1743 : #endif
1744 :
1745 : NPError NP_CALLBACK
1746 0 : _popupcontextmenu(NPP instance, NPMenu* menu)
1747 : {
1748 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1749 0 : AssertPluginThread();
1750 :
1751 : #ifdef MOZ_WIDGET_COCOA
1752 : double pluginX, pluginY;
1753 : double screenX, screenY;
1754 :
1755 : const NPCocoaEvent* currentEvent = InstCast(instance)->getCurrentEvent();
1756 : if (!currentEvent) {
1757 : return NPERR_GENERIC_ERROR;
1758 : }
1759 :
1760 : // Ensure that the events has an x/y value.
1761 : if (currentEvent->type != NPCocoaEventMouseDown &&
1762 : currentEvent->type != NPCocoaEventMouseUp &&
1763 : currentEvent->type != NPCocoaEventMouseMoved &&
1764 : currentEvent->type != NPCocoaEventMouseEntered &&
1765 : currentEvent->type != NPCocoaEventMouseExited &&
1766 : currentEvent->type != NPCocoaEventMouseDragged) {
1767 : return NPERR_GENERIC_ERROR;
1768 : }
1769 :
1770 : pluginX = currentEvent->data.mouse.pluginX;
1771 : pluginY = currentEvent->data.mouse.pluginY;
1772 :
1773 : if ((pluginX < 0.0) || (pluginY < 0.0))
1774 : return NPERR_GENERIC_ERROR;
1775 :
1776 : NPBool success = _convertpoint(instance,
1777 : pluginX, pluginY, NPCoordinateSpacePlugin,
1778 : &screenX, &screenY, NPCoordinateSpaceScreen);
1779 :
1780 : if (success) {
1781 : return mozilla::plugins::PluginUtilsOSX::ShowCocoaContextMenu(menu,
1782 : screenX, screenY,
1783 : PluginModuleChild::current(),
1784 : ProcessBrowserEvents);
1785 : } else {
1786 : NS_WARNING("Convertpoint failed, could not created contextmenu.");
1787 : return NPERR_GENERIC_ERROR;
1788 : }
1789 :
1790 : #else
1791 0 : NS_WARNING("Not supported on this platform!");
1792 0 : return NPERR_GENERIC_ERROR;
1793 : #endif
1794 : }
1795 :
1796 : NPBool NP_CALLBACK
1797 0 : _convertpoint(NPP instance,
1798 : double sourceX, double sourceY, NPCoordinateSpace sourceSpace,
1799 : double *destX, double *destY, NPCoordinateSpace destSpace)
1800 : {
1801 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1802 0 : AssertPluginThread();
1803 :
1804 0 : double rDestX = 0;
1805 0 : bool ignoreDestX = !destX;
1806 0 : double rDestY = 0;
1807 0 : bool ignoreDestY = !destY;
1808 0 : bool result = false;
1809 0 : InstCast(instance)->CallNPN_ConvertPoint(sourceX, ignoreDestX, sourceY, ignoreDestY, sourceSpace, destSpace,
1810 0 : &rDestX, &rDestY, &result);
1811 0 : if (result) {
1812 0 : if (destX)
1813 0 : *destX = rDestX;
1814 0 : if (destY)
1815 0 : *destY = rDestY;
1816 : }
1817 :
1818 0 : return result;
1819 : }
1820 :
1821 : void NP_CALLBACK
1822 0 : _urlredirectresponse(NPP instance, void* notifyData, NPBool allow)
1823 : {
1824 0 : InstCast(instance)->NPN_URLRedirectResponse(notifyData, allow);
1825 0 : }
1826 :
1827 : NPError NP_CALLBACK
1828 0 : _initasyncsurface(NPP instance, NPSize *size,
1829 : NPImageFormat format, void *initData,
1830 : NPAsyncSurface *surface)
1831 : {
1832 0 : return InstCast(instance)->NPN_InitAsyncSurface(size, format, initData, surface);
1833 : }
1834 :
1835 : NPError NP_CALLBACK
1836 0 : _finalizeasyncsurface(NPP instance, NPAsyncSurface *surface)
1837 : {
1838 0 : return InstCast(instance)->NPN_FinalizeAsyncSurface(surface);
1839 : }
1840 :
1841 : void NP_CALLBACK
1842 0 : _setcurrentasyncsurface(NPP instance, NPAsyncSurface *surface, NPRect *changed)
1843 : {
1844 0 : InstCast(instance)->NPN_SetCurrentAsyncSurface(surface, changed);
1845 0 : }
1846 :
1847 : } /* namespace child */
1848 : } /* namespace plugins */
1849 : } /* namespace mozilla */
1850 :
1851 : //-----------------------------------------------------------------------------
1852 :
1853 : bool
1854 0 : PluginModuleChild::AnswerNP_GetEntryPoints(NPError* _retval)
1855 : {
1856 0 : PLUGIN_LOG_DEBUG_METHOD;
1857 0 : AssertPluginThread();
1858 :
1859 : #if defined(OS_LINUX)
1860 0 : return true;
1861 : #elif defined(OS_WIN) || defined(OS_MACOSX)
1862 : *_retval = mGetEntryPointsFunc(&mFunctions);
1863 : return true;
1864 : #else
1865 : # error Please implement me for your platform
1866 : #endif
1867 : }
1868 :
1869 : bool
1870 0 : PluginModuleChild::AnswerNP_Initialize(const uint32_t& aFlags, NPError* _retval)
1871 : {
1872 0 : PLUGIN_LOG_DEBUG_METHOD;
1873 0 : AssertPluginThread();
1874 :
1875 0 : mAsyncDrawingAllowed = aFlags & kAllowAsyncDrawing;
1876 :
1877 : #ifdef OS_WIN
1878 : SetEventHooks();
1879 : #endif
1880 :
1881 : #ifdef MOZ_X11
1882 : // Send the parent a dup of our X socket, to act as a proxy
1883 : // reference for our X resources
1884 0 : int xSocketFd = ConnectionNumber(DefaultXDisplay());
1885 0 : SendBackUpXResources(FileDescriptor(xSocketFd, false/*don't close*/));
1886 : #endif
1887 :
1888 : #if defined(OS_LINUX)
1889 0 : *_retval = mInitializeFunc(&sBrowserFuncs, &mFunctions);
1890 0 : return true;
1891 : #elif defined(OS_WIN) || defined(OS_MACOSX)
1892 : *_retval = mInitializeFunc(&sBrowserFuncs);
1893 : return true;
1894 : #else
1895 : # error Please implement me for your platform
1896 : #endif
1897 : }
1898 :
1899 : PPluginIdentifierChild*
1900 0 : PluginModuleChild::AllocPPluginIdentifier(const nsCString& aString,
1901 : const int32_t& aInt,
1902 : const bool& aTemporary)
1903 : {
1904 : // We cannot call SetPermanent within this function because Manager() isn't
1905 : // set up yet.
1906 0 : if (aString.IsVoid()) {
1907 0 : return new PluginIdentifierChildInt(aInt);
1908 : }
1909 0 : return new PluginIdentifierChildString(aString);
1910 : }
1911 :
1912 : bool
1913 0 : PluginModuleChild::RecvPPluginIdentifierConstructor(PPluginIdentifierChild* actor,
1914 : const nsCString& aString,
1915 : const int32_t& aInt,
1916 : const bool& aTemporary)
1917 : {
1918 0 : if (!aTemporary) {
1919 0 : static_cast<PluginIdentifierChild*>(actor)->MakePermanent();
1920 : }
1921 0 : return true;
1922 : }
1923 :
1924 : bool
1925 0 : PluginModuleChild::DeallocPPluginIdentifier(PPluginIdentifierChild* aActor)
1926 : {
1927 0 : delete aActor;
1928 0 : return true;
1929 : }
1930 :
1931 : #if defined(XP_WIN)
1932 : BOOL WINAPI
1933 : PMCGetWindowInfoHook(HWND hWnd, PWINDOWINFO pwi)
1934 : {
1935 : if (!pwi)
1936 : return FALSE;
1937 :
1938 : if (!sGetWindowInfoPtrStub) {
1939 : NS_ASSERTION(FALSE, "Something is horribly wrong in PMCGetWindowInfoHook!");
1940 : return FALSE;
1941 : }
1942 :
1943 : if (!sBrowserHwnd) {
1944 : PRUnichar szClass[20];
1945 : if (GetClassNameW(hWnd, szClass, ArrayLength(szClass)) &&
1946 : !wcscmp(szClass, kMozillaWindowClass)) {
1947 : sBrowserHwnd = hWnd;
1948 : }
1949 : }
1950 : // Oddity: flash does strange rect comparisons for mouse input destined for
1951 : // it's internal settings window. Post removing sub widgets for tabs, touch
1952 : // this up so they get the rect they expect.
1953 : // XXX potentially tie this to a specific major version?
1954 : BOOL result = sGetWindowInfoPtrStub(hWnd, pwi);
1955 : if (sBrowserHwnd && sBrowserHwnd == hWnd)
1956 : pwi->rcWindow = pwi->rcClient;
1957 : return result;
1958 : }
1959 : #endif
1960 :
1961 : PPluginInstanceChild*
1962 0 : PluginModuleChild::AllocPPluginInstance(const nsCString& aMimeType,
1963 : const uint16_t& aMode,
1964 : const InfallibleTArray<nsCString>& aNames,
1965 : const InfallibleTArray<nsCString>& aValues,
1966 : NPError* rv)
1967 : {
1968 0 : PLUGIN_LOG_DEBUG_METHOD;
1969 0 : AssertPluginThread();
1970 :
1971 0 : InitQuirksModes(aMimeType);
1972 :
1973 : #ifdef XP_WIN
1974 : if ((mQuirks & QUIRK_FLASH_HOOK_GETWINDOWINFO) &&
1975 : !sGetWindowInfoPtrStub) {
1976 : sUser32Intercept.Init("user32.dll");
1977 : sUser32Intercept.AddHook("GetWindowInfo", reinterpret_cast<intptr_t>(PMCGetWindowInfoHook),
1978 : (void**) &sGetWindowInfoPtrStub);
1979 : }
1980 : #endif
1981 :
1982 : nsAutoPtr<PluginInstanceChild> childInstance(
1983 0 : new PluginInstanceChild(&mFunctions));
1984 0 : if (!childInstance->Initialize()) {
1985 0 : *rv = NPERR_GENERIC_ERROR;
1986 0 : return 0;
1987 : }
1988 0 : return childInstance.forget();
1989 : }
1990 :
1991 : void
1992 0 : PluginModuleChild::InitQuirksModes(const nsCString& aMimeType)
1993 : {
1994 0 : if (mQuirks != QUIRKS_NOT_INITIALIZED)
1995 0 : return;
1996 0 : mQuirks = 0;
1997 : // application/x-silverlight
1998 : // application/x-silverlight-2
1999 0 : NS_NAMED_LITERAL_CSTRING(silverlight, "application/x-silverlight");
2000 0 : if (FindInReadable(silverlight, aMimeType)) {
2001 0 : mQuirks |= QUIRK_SILVERLIGHT_DEFAULT_TRANSPARENT;
2002 : #ifdef OS_WIN
2003 : mQuirks |= QUIRK_WINLESS_TRACKPOPUP_HOOK;
2004 : mQuirks |= QUIRK_SILVERLIGHT_FOCUS_CHECK_PARENT;
2005 : #endif
2006 : }
2007 :
2008 : #ifdef OS_WIN
2009 : // application/x-shockwave-flash
2010 : NS_NAMED_LITERAL_CSTRING(flash, "application/x-shockwave-flash");
2011 : if (FindInReadable(flash, aMimeType)) {
2012 : mQuirks |= QUIRK_WINLESS_TRACKPOPUP_HOOK;
2013 : mQuirks |= QUIRK_FLASH_THROTTLE_WMUSER_EVENTS;
2014 : mQuirks |= QUIRK_FLASH_HOOK_SETLONGPTR;
2015 : mQuirks |= QUIRK_FLASH_HOOK_GETWINDOWINFO;
2016 : mQuirks |= QUIRK_FLASH_FIXUP_MOUSE_CAPTURE;
2017 : }
2018 :
2019 : // QuickTime plugin usually loaded with audio/mpeg mimetype
2020 : NS_NAMED_LITERAL_CSTRING(quicktime, "npqtplugin");
2021 : if (FindInReadable(quicktime, mPluginFilename)) {
2022 : mQuirks |= QUIRK_QUICKTIME_AVOID_SETWINDOW;
2023 : }
2024 : #endif
2025 :
2026 : #ifdef XP_MACOSX
2027 : // Whitelist Flash and Quicktime to support offline renderer
2028 : NS_NAMED_LITERAL_CSTRING(flash, "application/x-shockwave-flash");
2029 : NS_NAMED_LITERAL_CSTRING(quicktime, "QuickTime Plugin.plugin");
2030 : if (FindInReadable(flash, aMimeType) ||
2031 : FindInReadable(quicktime, mPluginFilename)) {
2032 : mQuirks |= QUIRK_ALLOW_OFFLINE_RENDERER;
2033 : }
2034 : #endif
2035 : }
2036 :
2037 : bool
2038 0 : PluginModuleChild::AnswerPPluginInstanceConstructor(PPluginInstanceChild* aActor,
2039 : const nsCString& aMimeType,
2040 : const uint16_t& aMode,
2041 : const InfallibleTArray<nsCString>& aNames,
2042 : const InfallibleTArray<nsCString>& aValues,
2043 : NPError* rv)
2044 : {
2045 0 : PLUGIN_LOG_DEBUG_METHOD;
2046 0 : AssertPluginThread();
2047 :
2048 : PluginInstanceChild* childInstance =
2049 0 : reinterpret_cast<PluginInstanceChild*>(aActor);
2050 0 : NS_ASSERTION(childInstance, "Null actor!");
2051 :
2052 : // unpack the arguments into a C format
2053 0 : int argc = aNames.Length();
2054 0 : NS_ASSERTION(argc == (int) aValues.Length(),
2055 : "argn.length != argv.length");
2056 :
2057 0 : nsAutoArrayPtr<char*> argn(new char*[1 + argc]);
2058 0 : nsAutoArrayPtr<char*> argv(new char*[1 + argc]);
2059 0 : argn[argc] = 0;
2060 0 : argv[argc] = 0;
2061 :
2062 0 : for (int i = 0; i < argc; ++i) {
2063 0 : argn[i] = const_cast<char*>(NullableStringGet(aNames[i]));
2064 0 : argv[i] = const_cast<char*>(NullableStringGet(aValues[i]));
2065 : }
2066 :
2067 0 : NPP npp = childInstance->GetNPP();
2068 :
2069 : // FIXME/cjones: use SAFE_CALL stuff
2070 0 : *rv = mFunctions.newp((char*)NullableStringGet(aMimeType),
2071 : npp,
2072 : aMode,
2073 : argc,
2074 : argn,
2075 : argv,
2076 0 : 0);
2077 0 : if (NPERR_NO_ERROR != *rv) {
2078 0 : return true;
2079 : }
2080 :
2081 : #if defined(XP_MACOSX) && defined(__i386__)
2082 : // If an i386 Mac OS X plugin has selected the Carbon event model then
2083 : // we have to fail. We do not support putting Carbon event model plugins
2084 : // out of process. Note that Carbon is the default model so out of process
2085 : // plugins need to actively negotiate something else in order to work
2086 : // out of process.
2087 : if (childInstance->EventModel() == NPEventModelCarbon) {
2088 : // Send notification that a plugin tried to negotiate Carbon NPAPI so that
2089 : // users can be notified that restarting the browser in i386 mode may allow
2090 : // them to use the plugin.
2091 : childInstance->SendNegotiatedCarbon();
2092 :
2093 : // Fail to instantiate.
2094 : *rv = NPERR_MODULE_LOAD_FAILED_ERROR;
2095 : }
2096 : #endif
2097 :
2098 0 : return true;
2099 : }
2100 :
2101 : bool
2102 0 : PluginModuleChild::DeallocPPluginInstance(PPluginInstanceChild* aActor)
2103 : {
2104 0 : PLUGIN_LOG_DEBUG_METHOD;
2105 0 : AssertPluginThread();
2106 :
2107 0 : delete aActor;
2108 :
2109 0 : return true;
2110 : }
2111 :
2112 : NPObject* NP_CALLBACK
2113 0 : PluginModuleChild::NPN_CreateObject(NPP aNPP, NPClass* aClass)
2114 : {
2115 0 : PLUGIN_LOG_DEBUG_FUNCTION;
2116 0 : ENSURE_PLUGIN_THREAD(nsnull);
2117 :
2118 0 : PluginInstanceChild* i = InstCast(aNPP);
2119 0 : if (i->mDeletingHash) {
2120 0 : NS_ERROR("Plugin used NPP after NPP_Destroy");
2121 0 : return NULL;
2122 : }
2123 :
2124 : NPObject* newObject;
2125 0 : if (aClass && aClass->allocate) {
2126 0 : newObject = aClass->allocate(aNPP, aClass);
2127 : }
2128 : else {
2129 0 : newObject = reinterpret_cast<NPObject*>(child::_memalloc(sizeof(NPObject)));
2130 : }
2131 :
2132 0 : if (newObject) {
2133 0 : newObject->_class = aClass;
2134 0 : newObject->referenceCount = 1;
2135 0 : NS_LOG_ADDREF(newObject, 1, "NPObject", sizeof(NPObject));
2136 : }
2137 :
2138 0 : NPObjectData* d = static_cast<PluginModuleChild*>(i->Manager())
2139 0 : ->mObjectMap.PutEntry(newObject);
2140 0 : NS_ASSERTION(!d->instance, "New NPObject already mapped?");
2141 0 : d->instance = i;
2142 :
2143 0 : return newObject;
2144 : }
2145 :
2146 : NPObject* NP_CALLBACK
2147 0 : PluginModuleChild::NPN_RetainObject(NPObject* aNPObj)
2148 : {
2149 0 : AssertPluginThread();
2150 :
2151 : #ifdef NS_BUILD_REFCNT_LOGGING
2152 : int32_t refCnt =
2153 : #endif
2154 0 : PR_ATOMIC_INCREMENT((int32_t*)&aNPObj->referenceCount);
2155 0 : NS_LOG_ADDREF(aNPObj, refCnt, "NPObject", sizeof(NPObject));
2156 :
2157 0 : return aNPObj;
2158 : }
2159 :
2160 : void NP_CALLBACK
2161 0 : PluginModuleChild::NPN_ReleaseObject(NPObject* aNPObj)
2162 : {
2163 0 : AssertPluginThread();
2164 :
2165 0 : NPObjectData* d = current()->mObjectMap.GetEntry(aNPObj);
2166 0 : if (!d) {
2167 0 : NS_ERROR("Releasing object not in mObjectMap?");
2168 0 : return;
2169 : }
2170 :
2171 0 : DeletingObjectEntry* doe = NULL;
2172 0 : if (d->instance->mDeletingHash) {
2173 0 : doe = d->instance->mDeletingHash->GetEntry(aNPObj);
2174 0 : if (!doe) {
2175 0 : NS_ERROR("An object for a destroyed instance isn't in the instance deletion hash");
2176 0 : return;
2177 : }
2178 0 : if (doe->mDeleted)
2179 0 : return;
2180 : }
2181 :
2182 0 : int32_t refCnt = PR_ATOMIC_DECREMENT((int32_t*)&aNPObj->referenceCount);
2183 0 : NS_LOG_RELEASE(aNPObj, refCnt, "NPObject");
2184 :
2185 0 : if (refCnt == 0) {
2186 0 : DeallocNPObject(aNPObj);
2187 0 : if (doe)
2188 0 : doe->mDeleted = true;
2189 : }
2190 0 : return;
2191 : }
2192 :
2193 : void
2194 0 : PluginModuleChild::DeallocNPObject(NPObject* aNPObj)
2195 : {
2196 0 : if (aNPObj->_class && aNPObj->_class->deallocate) {
2197 0 : aNPObj->_class->deallocate(aNPObj);
2198 : } else {
2199 0 : child::_memfree(aNPObj);
2200 : }
2201 :
2202 0 : NPObjectData* d = current()->mObjectMap.GetEntry(aNPObj);
2203 0 : if (d->actor)
2204 0 : d->actor->NPObjectDestroyed();
2205 :
2206 0 : current()->mObjectMap.RemoveEntry(aNPObj);
2207 0 : }
2208 :
2209 : void
2210 0 : PluginModuleChild::FindNPObjectsForInstance(PluginInstanceChild* instance)
2211 : {
2212 0 : NS_ASSERTION(instance->mDeletingHash, "filling null mDeletingHash?");
2213 0 : mObjectMap.EnumerateEntries(CollectForInstance, instance);
2214 0 : }
2215 :
2216 : PLDHashOperator
2217 0 : PluginModuleChild::CollectForInstance(NPObjectData* d, void* userArg)
2218 : {
2219 0 : PluginInstanceChild* instance = static_cast<PluginInstanceChild*>(userArg);
2220 0 : if (d->instance == instance) {
2221 0 : NPObject* o = d->GetKey();
2222 0 : instance->mDeletingHash->PutEntry(o);
2223 : }
2224 0 : return PL_DHASH_NEXT;
2225 : }
2226 :
2227 : NPIdentifier NP_CALLBACK
2228 0 : PluginModuleChild::NPN_GetStringIdentifier(const NPUTF8* aName)
2229 : {
2230 0 : PLUGIN_LOG_DEBUG_FUNCTION;
2231 0 : AssertPluginThread();
2232 :
2233 0 : if (!aName)
2234 0 : return 0;
2235 :
2236 0 : PluginModuleChild* self = PluginModuleChild::current();
2237 0 : nsDependentCString name(aName);
2238 :
2239 0 : PluginIdentifierChildString* ident = self->mStringIdentifiers.Get(name);
2240 0 : if (!ident) {
2241 0 : nsCString nameCopy(name);
2242 :
2243 0 : ident = new PluginIdentifierChildString(nameCopy);
2244 0 : self->SendPPluginIdentifierConstructor(ident, nameCopy, -1, false);
2245 : }
2246 0 : ident->MakePermanent();
2247 0 : return ident;
2248 : }
2249 :
2250 : void NP_CALLBACK
2251 0 : PluginModuleChild::NPN_GetStringIdentifiers(const NPUTF8** aNames,
2252 : int32_t aNameCount,
2253 : NPIdentifier* aIdentifiers)
2254 : {
2255 0 : PLUGIN_LOG_DEBUG_FUNCTION;
2256 0 : AssertPluginThread();
2257 :
2258 0 : if (!(aNames && aNameCount > 0 && aIdentifiers)) {
2259 0 : NS_RUNTIMEABORT("Bad input! Headed for a crash!");
2260 : }
2261 :
2262 0 : PluginModuleChild* self = PluginModuleChild::current();
2263 :
2264 0 : for (int32_t index = 0; index < aNameCount; ++index) {
2265 0 : if (!aNames[index]) {
2266 0 : aIdentifiers[index] = 0;
2267 0 : continue;
2268 : }
2269 0 : nsDependentCString name(aNames[index]);
2270 0 : PluginIdentifierChildString* ident = self->mStringIdentifiers.Get(name);
2271 0 : if (!ident) {
2272 0 : nsCString nameCopy(name);
2273 :
2274 0 : ident = new PluginIdentifierChildString(nameCopy);
2275 0 : self->SendPPluginIdentifierConstructor(ident, nameCopy, -1, false);
2276 : }
2277 0 : ident->MakePermanent();
2278 0 : aIdentifiers[index] = ident;
2279 : }
2280 0 : }
2281 :
2282 : bool NP_CALLBACK
2283 0 : PluginModuleChild::NPN_IdentifierIsString(NPIdentifier aIdentifier)
2284 : {
2285 0 : PLUGIN_LOG_DEBUG_FUNCTION;
2286 :
2287 : PluginIdentifierChild* ident =
2288 0 : static_cast<PluginIdentifierChild*>(aIdentifier);
2289 0 : return ident->IsString();
2290 : }
2291 :
2292 : NPIdentifier NP_CALLBACK
2293 0 : PluginModuleChild::NPN_GetIntIdentifier(int32_t aIntId)
2294 : {
2295 0 : PLUGIN_LOG_DEBUG_FUNCTION;
2296 0 : AssertPluginThread();
2297 :
2298 0 : PluginModuleChild* self = PluginModuleChild::current();
2299 :
2300 0 : PluginIdentifierChildInt* ident = self->mIntIdentifiers.Get(aIntId);
2301 0 : if (!ident) {
2302 0 : nsCString voidString;
2303 0 : voidString.SetIsVoid(true);
2304 :
2305 0 : ident = new PluginIdentifierChildInt(aIntId);
2306 0 : self->SendPPluginIdentifierConstructor(ident, voidString, aIntId, false);
2307 : }
2308 0 : ident->MakePermanent();
2309 0 : return ident;
2310 : }
2311 :
2312 : NPUTF8* NP_CALLBACK
2313 0 : PluginModuleChild::NPN_UTF8FromIdentifier(NPIdentifier aIdentifier)
2314 : {
2315 0 : PLUGIN_LOG_DEBUG_FUNCTION;
2316 :
2317 0 : if (static_cast<PluginIdentifierChild*>(aIdentifier)->IsString()) {
2318 0 : return static_cast<PluginIdentifierChildString*>(aIdentifier)->ToString();
2319 : }
2320 0 : return nsnull;
2321 : }
2322 :
2323 : int32_t NP_CALLBACK
2324 0 : PluginModuleChild::NPN_IntFromIdentifier(NPIdentifier aIdentifier)
2325 : {
2326 0 : PLUGIN_LOG_DEBUG_FUNCTION;
2327 :
2328 0 : if (!static_cast<PluginIdentifierChild*>(aIdentifier)->IsString()) {
2329 0 : return static_cast<PluginIdentifierChildInt*>(aIdentifier)->ToInt();
2330 : }
2331 0 : return PR_INT32_MIN;
2332 : }
2333 :
2334 : #ifdef OS_WIN
2335 : void
2336 : PluginModuleChild::EnteredCall()
2337 : {
2338 : mIncallPumpingStack.AppendElement();
2339 : }
2340 :
2341 : void
2342 : PluginModuleChild::ExitedCall()
2343 : {
2344 : NS_ASSERTION(mIncallPumpingStack.Length(), "mismatched entered/exited");
2345 : PRUint32 len = mIncallPumpingStack.Length();
2346 : const IncallFrame& f = mIncallPumpingStack[len - 1];
2347 : if (f._spinning)
2348 : MessageLoop::current()->SetNestableTasksAllowed(f._savedNestableTasksAllowed);
2349 :
2350 : mIncallPumpingStack.TruncateLength(len - 1);
2351 : }
2352 :
2353 : LRESULT CALLBACK
2354 : PluginModuleChild::CallWindowProcHook(int nCode, WPARAM wParam, LPARAM lParam)
2355 : {
2356 : // Trap and reply to anything we recognize as the source of a
2357 : // potential send message deadlock.
2358 : if (nCode >= 0 &&
2359 : (InSendMessageEx(NULL)&(ISMEX_REPLIED|ISMEX_SEND)) == ISMEX_SEND) {
2360 : CWPSTRUCT* pCwp = reinterpret_cast<CWPSTRUCT*>(lParam);
2361 : if (pCwp->message == WM_KILLFOCUS) {
2362 : // Fix for flash fullscreen window loosing focus. On single
2363 : // core systems, sync killfocus events need to be handled
2364 : // after the flash fullscreen window procedure processes this
2365 : // message, otherwise fullscreen focus will not work correctly.
2366 : PRUnichar szClass[26];
2367 : if (GetClassNameW(pCwp->hwnd, szClass,
2368 : sizeof(szClass)/sizeof(PRUnichar)) &&
2369 : !wcscmp(szClass, kFlashFullscreenClass)) {
2370 : gDelayFlashFocusReplyUntilEval = true;
2371 : }
2372 : }
2373 : }
2374 :
2375 : return CallNextHookEx(NULL, nCode, wParam, lParam);
2376 : }
2377 :
2378 : LRESULT CALLBACK
2379 : PluginModuleChild::NestedInputEventHook(int nCode, WPARAM wParam, LPARAM lParam)
2380 : {
2381 : PluginModuleChild* self = current();
2382 : PRUint32 len = self->mIncallPumpingStack.Length();
2383 : if (nCode >= 0 && len && !self->mIncallPumpingStack[len - 1]._spinning) {
2384 : MessageLoop* loop = MessageLoop::current();
2385 : self->SendProcessNativeEventsInRPCCall();
2386 : IncallFrame& f = self->mIncallPumpingStack[len - 1];
2387 : f._spinning = true;
2388 : f._savedNestableTasksAllowed = loop->NestableTasksAllowed();
2389 : loop->SetNestableTasksAllowed(true);
2390 : loop->set_os_modal_loop(true);
2391 : }
2392 :
2393 : return CallNextHookEx(NULL, nCode, wParam, lParam);
2394 : }
2395 :
2396 : void
2397 : PluginModuleChild::SetEventHooks()
2398 : {
2399 : NS_ASSERTION(!mNestedEventHook,
2400 : "mNestedEventHook already setup in call to SetNestedInputEventHook?");
2401 : NS_ASSERTION(!mGlobalCallWndProcHook,
2402 : "mGlobalCallWndProcHook already setup in call to CallWindowProcHook?");
2403 :
2404 : PLUGIN_LOG_DEBUG(("%s", FULLFUNCTION));
2405 :
2406 : // WH_MSGFILTER event hook for detecting modal loops in the child.
2407 : mNestedEventHook = SetWindowsHookEx(WH_MSGFILTER,
2408 : NestedInputEventHook,
2409 : NULL,
2410 : GetCurrentThreadId());
2411 :
2412 : // WH_CALLWNDPROC event hook for trapping sync messages sent from
2413 : // parent that can cause deadlocks.
2414 : mGlobalCallWndProcHook = SetWindowsHookEx(WH_CALLWNDPROC,
2415 : CallWindowProcHook,
2416 : NULL,
2417 : GetCurrentThreadId());
2418 : }
2419 :
2420 : void
2421 : PluginModuleChild::ResetEventHooks()
2422 : {
2423 : PLUGIN_LOG_DEBUG(("%s", FULLFUNCTION));
2424 : if (mNestedEventHook)
2425 : UnhookWindowsHookEx(mNestedEventHook);
2426 : mNestedEventHook = NULL;
2427 : if (mGlobalCallWndProcHook)
2428 : UnhookWindowsHookEx(mGlobalCallWndProcHook);
2429 : mGlobalCallWndProcHook = NULL;
2430 : }
2431 : #endif
2432 :
2433 : bool
2434 0 : PluginModuleChild::RecvProcessNativeEventsInRPCCall()
2435 : {
2436 0 : PLUGIN_LOG_DEBUG(("%s", FULLFUNCTION));
2437 : #if defined(OS_WIN)
2438 : ProcessNativeEventsInRPCCall();
2439 : return true;
2440 : #else
2441 : NS_RUNTIMEABORT(
2442 0 : "PluginModuleChild::RecvProcessNativeEventsInRPCCall not implemented!");
2443 0 : return false;
2444 : #endif
2445 : }
2446 :
2447 : #ifdef MOZ_WIDGET_COCOA
2448 : void
2449 : PluginModuleChild::ProcessNativeEvents() {
2450 : CallProcessSomeEvents();
2451 : }
2452 : #endif
|