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 0 : if (mLibrary) {
150 0 : PR_UnloadLibrary(mLibrary);
151 : }
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 0 : NS_WARNING("Not yet implemented!");
1312 : }
1313 :
1314 : void NP_CALLBACK
1315 0 : _invalidaterect(NPP aNPP,
1316 : NPRect* aInvalidRect)
1317 : {
1318 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1319 0 : ENSURE_PLUGIN_THREAD_VOID();
1320 : // NULL check for nspluginwrapper (bug 548434)
1321 0 : if (aNPP) {
1322 0 : InstCast(aNPP)->InvalidateRect(aInvalidRect);
1323 : }
1324 : }
1325 :
1326 : void NP_CALLBACK
1327 0 : _invalidateregion(NPP aNPP,
1328 : NPRegion aInvalidRegion)
1329 : {
1330 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1331 0 : ENSURE_PLUGIN_THREAD_VOID();
1332 0 : NS_WARNING("Not yet implemented!");
1333 : }
1334 :
1335 : void NP_CALLBACK
1336 0 : _forceredraw(NPP aNPP)
1337 : {
1338 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1339 0 : ENSURE_PLUGIN_THREAD_VOID();
1340 :
1341 : // We ignore calls to NPN_ForceRedraw. Such calls should
1342 : // never be necessary.
1343 : }
1344 :
1345 : const char* NP_CALLBACK
1346 0 : _useragent(NPP aNPP)
1347 : {
1348 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1349 0 : ENSURE_PLUGIN_THREAD(nsnull);
1350 0 : return PluginModuleChild::current()->GetUserAgent();
1351 : }
1352 :
1353 : void* NP_CALLBACK
1354 0 : _memalloc(uint32_t aSize)
1355 : {
1356 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1357 : // Only assert plugin thread here for consistency with in-process plugins.
1358 0 : AssertPluginThread();
1359 0 : return NS_Alloc(aSize);
1360 : }
1361 :
1362 : // Deprecated entry points for the old Java plugin.
1363 : void* NP_CALLBACK /* OJI type: JRIEnv* */
1364 0 : _getjavaenv(void)
1365 : {
1366 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1367 0 : return 0;
1368 : }
1369 :
1370 : void* NP_CALLBACK /* OJI type: jref */
1371 0 : _getjavapeer(NPP aNPP)
1372 : {
1373 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1374 0 : return 0;
1375 : }
1376 :
1377 : bool NP_CALLBACK
1378 0 : _invoke(NPP aNPP,
1379 : NPObject* aNPObj,
1380 : NPIdentifier aMethod,
1381 : const NPVariant* aArgs,
1382 : uint32_t aArgCount,
1383 : NPVariant* aResult)
1384 : {
1385 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1386 0 : ENSURE_PLUGIN_THREAD(false);
1387 :
1388 0 : if (!aNPP || !aNPObj || !aNPObj->_class || !aNPObj->_class->invoke)
1389 0 : return false;
1390 :
1391 0 : return aNPObj->_class->invoke(aNPObj, aMethod, aArgs, aArgCount, aResult);
1392 : }
1393 :
1394 : bool NP_CALLBACK
1395 0 : _invokedefault(NPP aNPP,
1396 : NPObject* aNPObj,
1397 : const NPVariant* aArgs,
1398 : uint32_t aArgCount,
1399 : NPVariant* aResult)
1400 : {
1401 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1402 0 : ENSURE_PLUGIN_THREAD(false);
1403 :
1404 0 : if (!aNPP || !aNPObj || !aNPObj->_class || !aNPObj->_class->invokeDefault)
1405 0 : return false;
1406 :
1407 0 : return aNPObj->_class->invokeDefault(aNPObj, aArgs, aArgCount, aResult);
1408 : }
1409 :
1410 : bool NP_CALLBACK
1411 0 : _evaluate(NPP aNPP,
1412 : NPObject* aObject,
1413 : NPString* aScript,
1414 : NPVariant* aResult)
1415 : {
1416 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1417 0 : ENSURE_PLUGIN_THREAD(false);
1418 :
1419 0 : if (!(aNPP && aObject && aScript && aResult)) {
1420 0 : NS_ERROR("Bad arguments!");
1421 0 : return false;
1422 : }
1423 :
1424 : PluginScriptableObjectChild* actor =
1425 0 : InstCast(aNPP)->GetActorForNPObject(aObject);
1426 0 : if (!actor) {
1427 0 : NS_ERROR("Failed to create actor?!");
1428 0 : return false;
1429 : }
1430 :
1431 : #ifdef XP_WIN
1432 : if (gDelayFlashFocusReplyUntilEval) {
1433 : ReplyMessage(0);
1434 : gDelayFlashFocusReplyUntilEval = false;
1435 : }
1436 : #endif
1437 :
1438 0 : return actor->Evaluate(aScript, aResult);
1439 : }
1440 :
1441 : bool NP_CALLBACK
1442 0 : _getproperty(NPP aNPP,
1443 : NPObject* aNPObj,
1444 : NPIdentifier aPropertyName,
1445 : NPVariant* aResult)
1446 : {
1447 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1448 0 : ENSURE_PLUGIN_THREAD(false);
1449 :
1450 0 : if (!aNPP || !aNPObj || !aNPObj->_class || !aNPObj->_class->getProperty)
1451 0 : return false;
1452 :
1453 0 : return aNPObj->_class->getProperty(aNPObj, aPropertyName, aResult);
1454 : }
1455 :
1456 : bool NP_CALLBACK
1457 0 : _setproperty(NPP aNPP,
1458 : NPObject* aNPObj,
1459 : NPIdentifier aPropertyName,
1460 : const NPVariant* aValue)
1461 : {
1462 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1463 0 : ENSURE_PLUGIN_THREAD(false);
1464 :
1465 0 : if (!aNPP || !aNPObj || !aNPObj->_class || !aNPObj->_class->setProperty)
1466 0 : return false;
1467 :
1468 0 : return aNPObj->_class->setProperty(aNPObj, aPropertyName, aValue);
1469 : }
1470 :
1471 : bool NP_CALLBACK
1472 0 : _removeproperty(NPP aNPP,
1473 : NPObject* aNPObj,
1474 : NPIdentifier aPropertyName)
1475 : {
1476 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1477 0 : ENSURE_PLUGIN_THREAD(false);
1478 :
1479 0 : if (!aNPP || !aNPObj || !aNPObj->_class || !aNPObj->_class->removeProperty)
1480 0 : return false;
1481 :
1482 0 : return aNPObj->_class->removeProperty(aNPObj, aPropertyName);
1483 : }
1484 :
1485 : bool NP_CALLBACK
1486 0 : _hasproperty(NPP aNPP,
1487 : NPObject* aNPObj,
1488 : NPIdentifier aPropertyName)
1489 : {
1490 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1491 0 : ENSURE_PLUGIN_THREAD(false);
1492 :
1493 0 : if (!aNPP || !aNPObj || !aNPObj->_class || !aNPObj->_class->hasProperty)
1494 0 : return false;
1495 :
1496 0 : return aNPObj->_class->hasProperty(aNPObj, aPropertyName);
1497 : }
1498 :
1499 : bool NP_CALLBACK
1500 0 : _hasmethod(NPP aNPP,
1501 : NPObject* aNPObj,
1502 : NPIdentifier aMethodName)
1503 : {
1504 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1505 0 : ENSURE_PLUGIN_THREAD(false);
1506 :
1507 0 : if (!aNPP || !aNPObj || !aNPObj->_class || !aNPObj->_class->hasMethod)
1508 0 : return false;
1509 :
1510 0 : return aNPObj->_class->hasMethod(aNPObj, aMethodName);
1511 : }
1512 :
1513 : bool NP_CALLBACK
1514 0 : _enumerate(NPP aNPP,
1515 : NPObject* aNPObj,
1516 : NPIdentifier** aIdentifiers,
1517 : uint32_t* aCount)
1518 : {
1519 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1520 0 : ENSURE_PLUGIN_THREAD(false);
1521 :
1522 0 : if (!aNPP || !aNPObj || !aNPObj->_class)
1523 0 : return false;
1524 :
1525 0 : if (!NP_CLASS_STRUCT_VERSION_HAS_ENUM(aNPObj->_class) ||
1526 0 : !aNPObj->_class->enumerate) {
1527 0 : *aIdentifiers = 0;
1528 0 : *aCount = 0;
1529 0 : return true;
1530 : }
1531 :
1532 0 : return aNPObj->_class->enumerate(aNPObj, aIdentifiers, aCount);
1533 : }
1534 :
1535 : bool NP_CALLBACK
1536 0 : _construct(NPP aNPP,
1537 : NPObject* aNPObj,
1538 : const NPVariant* aArgs,
1539 : uint32_t aArgCount,
1540 : NPVariant* aResult)
1541 : {
1542 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1543 0 : ENSURE_PLUGIN_THREAD(false);
1544 :
1545 0 : if (!aNPP || !aNPObj || !aNPObj->_class ||
1546 0 : !NP_CLASS_STRUCT_VERSION_HAS_CTOR(aNPObj->_class) ||
1547 0 : !aNPObj->_class->construct) {
1548 0 : return false;
1549 : }
1550 :
1551 0 : return aNPObj->_class->construct(aNPObj, aArgs, aArgCount, aResult);
1552 : }
1553 :
1554 : void NP_CALLBACK
1555 0 : _releasevariantvalue(NPVariant* aVariant)
1556 : {
1557 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1558 : // Only assert plugin thread here for consistency with in-process plugins.
1559 0 : AssertPluginThread();
1560 :
1561 0 : if (NPVARIANT_IS_STRING(*aVariant)) {
1562 0 : NPString str = NPVARIANT_TO_STRING(*aVariant);
1563 0 : free(const_cast<NPUTF8*>(str.UTF8Characters));
1564 : }
1565 0 : else if (NPVARIANT_IS_OBJECT(*aVariant)) {
1566 0 : NPObject* object = NPVARIANT_TO_OBJECT(*aVariant);
1567 0 : if (object) {
1568 0 : PluginModuleChild::NPN_ReleaseObject(object);
1569 : }
1570 : }
1571 0 : VOID_TO_NPVARIANT(*aVariant);
1572 0 : }
1573 :
1574 : void NP_CALLBACK
1575 0 : _setexception(NPObject* aNPObj,
1576 : const NPUTF8* aMessage)
1577 : {
1578 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1579 0 : ENSURE_PLUGIN_THREAD_VOID();
1580 :
1581 0 : PluginModuleChild* self = PluginModuleChild::current();
1582 0 : PluginScriptableObjectChild* actor = NULL;
1583 0 : if (aNPObj) {
1584 0 : actor = self->GetActorForNPObject(aNPObj);
1585 0 : if (!actor) {
1586 0 : NS_ERROR("Failed to get actor!");
1587 0 : return;
1588 : }
1589 : }
1590 :
1591 : self->SendNPN_SetException(static_cast<PPluginScriptableObjectChild*>(actor),
1592 0 : NullableString(aMessage));
1593 : }
1594 :
1595 : void NP_CALLBACK
1596 0 : _pushpopupsenabledstate(NPP aNPP,
1597 : NPBool aEnabled)
1598 : {
1599 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1600 0 : ENSURE_PLUGIN_THREAD_VOID();
1601 :
1602 0 : InstCast(aNPP)->CallNPN_PushPopupsEnabledState(aEnabled ? true : false);
1603 : }
1604 :
1605 : void NP_CALLBACK
1606 0 : _poppopupsenabledstate(NPP aNPP)
1607 : {
1608 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1609 0 : ENSURE_PLUGIN_THREAD_VOID();
1610 :
1611 0 : InstCast(aNPP)->CallNPN_PopPopupsEnabledState();
1612 : }
1613 :
1614 : void NP_CALLBACK
1615 0 : _pluginthreadasynccall(NPP aNPP,
1616 : PluginThreadCallback aFunc,
1617 : void* aUserData)
1618 : {
1619 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1620 0 : if (!aFunc)
1621 0 : return;
1622 :
1623 0 : InstCast(aNPP)->AsyncCall(aFunc, aUserData);
1624 : }
1625 :
1626 : NPError NP_CALLBACK
1627 0 : _getvalueforurl(NPP npp, NPNURLVariable variable, const char *url,
1628 : char **value, uint32_t *len)
1629 : {
1630 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1631 0 : AssertPluginThread();
1632 :
1633 0 : if (!url)
1634 0 : return NPERR_INVALID_URL;
1635 :
1636 0 : if (!npp || !value || !len)
1637 0 : return NPERR_INVALID_PARAM;
1638 :
1639 0 : switch (variable) {
1640 : case NPNURLVCookie:
1641 : case NPNURLVProxy:
1642 0 : nsCString v;
1643 : NPError result;
1644 0 : InstCast(npp)->
1645 0 : CallNPN_GetValueForURL(variable, nsCString(url), &v, &result);
1646 0 : if (NPERR_NO_ERROR == result) {
1647 0 : *value = ToNewCString(v);
1648 0 : *len = v.Length();
1649 : }
1650 0 : return result;
1651 : }
1652 :
1653 0 : return NPERR_INVALID_PARAM;
1654 : }
1655 :
1656 : NPError NP_CALLBACK
1657 0 : _setvalueforurl(NPP npp, NPNURLVariable variable, const char *url,
1658 : const char *value, uint32_t len)
1659 : {
1660 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1661 0 : AssertPluginThread();
1662 :
1663 0 : if (!value)
1664 0 : return NPERR_INVALID_PARAM;
1665 :
1666 0 : if (!url)
1667 0 : return NPERR_INVALID_URL;
1668 :
1669 0 : switch (variable) {
1670 : case NPNURLVCookie:
1671 : case NPNURLVProxy:
1672 : NPError result;
1673 0 : InstCast(npp)->CallNPN_SetValueForURL(variable, nsCString(url),
1674 0 : nsDependentCString(value, len),
1675 0 : &result);
1676 0 : return result;
1677 : }
1678 :
1679 0 : return NPERR_INVALID_PARAM;
1680 : }
1681 :
1682 : NPError NP_CALLBACK
1683 0 : _getauthenticationinfo(NPP npp, const char *protocol,
1684 : const char *host, int32_t port,
1685 : const char *scheme, const char *realm,
1686 : char **username, uint32_t *ulen,
1687 : char **password, uint32_t *plen)
1688 : {
1689 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1690 0 : AssertPluginThread();
1691 :
1692 0 : if (!protocol || !host || !scheme || !realm || !username || !ulen ||
1693 : !password || !plen)
1694 0 : return NPERR_INVALID_PARAM;
1695 :
1696 0 : nsCString u;
1697 0 : nsCString p;
1698 : NPError result;
1699 0 : InstCast(npp)->
1700 0 : CallNPN_GetAuthenticationInfo(nsDependentCString(protocol),
1701 0 : nsDependentCString(host),
1702 : port,
1703 0 : nsDependentCString(scheme),
1704 0 : nsDependentCString(realm),
1705 0 : &u, &p, &result);
1706 0 : if (NPERR_NO_ERROR == result) {
1707 0 : *username = ToNewCString(u);
1708 0 : *ulen = u.Length();
1709 0 : *password = ToNewCString(p);
1710 0 : *plen = p.Length();
1711 : }
1712 0 : return result;
1713 : }
1714 :
1715 : uint32_t NP_CALLBACK
1716 0 : _scheduletimer(NPP npp, uint32_t interval, NPBool repeat,
1717 : void (*timerFunc)(NPP npp, uint32_t timerID))
1718 : {
1719 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1720 0 : AssertPluginThread();
1721 0 : return InstCast(npp)->ScheduleTimer(interval, repeat, timerFunc);
1722 : }
1723 :
1724 : void NP_CALLBACK
1725 0 : _unscheduletimer(NPP npp, uint32_t timerID)
1726 : {
1727 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1728 0 : AssertPluginThread();
1729 0 : InstCast(npp)->UnscheduleTimer(timerID);
1730 0 : }
1731 :
1732 :
1733 : #ifdef OS_MACOSX
1734 : static void ProcessBrowserEvents(void* pluginModule) {
1735 : PluginModuleChild* pmc = static_cast<PluginModuleChild*>(pluginModule);
1736 :
1737 : if (!pmc)
1738 : return;
1739 :
1740 : pmc->CallProcessSomeEvents();
1741 : }
1742 : #endif
1743 :
1744 : NPError NP_CALLBACK
1745 0 : _popupcontextmenu(NPP instance, NPMenu* menu)
1746 : {
1747 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1748 0 : AssertPluginThread();
1749 :
1750 : #ifdef MOZ_WIDGET_COCOA
1751 : double pluginX, pluginY;
1752 : double screenX, screenY;
1753 :
1754 : const NPCocoaEvent* currentEvent = InstCast(instance)->getCurrentEvent();
1755 : if (!currentEvent) {
1756 : return NPERR_GENERIC_ERROR;
1757 : }
1758 :
1759 : // Ensure that the events has an x/y value.
1760 : if (currentEvent->type != NPCocoaEventMouseDown &&
1761 : currentEvent->type != NPCocoaEventMouseUp &&
1762 : currentEvent->type != NPCocoaEventMouseMoved &&
1763 : currentEvent->type != NPCocoaEventMouseEntered &&
1764 : currentEvent->type != NPCocoaEventMouseExited &&
1765 : currentEvent->type != NPCocoaEventMouseDragged) {
1766 : return NPERR_GENERIC_ERROR;
1767 : }
1768 :
1769 : pluginX = currentEvent->data.mouse.pluginX;
1770 : pluginY = currentEvent->data.mouse.pluginY;
1771 :
1772 : if ((pluginX < 0.0) || (pluginY < 0.0))
1773 : return NPERR_GENERIC_ERROR;
1774 :
1775 : NPBool success = _convertpoint(instance,
1776 : pluginX, pluginY, NPCoordinateSpacePlugin,
1777 : &screenX, &screenY, NPCoordinateSpaceScreen);
1778 :
1779 : if (success) {
1780 : return mozilla::plugins::PluginUtilsOSX::ShowCocoaContextMenu(menu,
1781 : screenX, screenY,
1782 : PluginModuleChild::current(),
1783 : ProcessBrowserEvents);
1784 : } else {
1785 : NS_WARNING("Convertpoint failed, could not created contextmenu.");
1786 : return NPERR_GENERIC_ERROR;
1787 : }
1788 :
1789 : #else
1790 0 : NS_WARNING("Not supported on this platform!");
1791 0 : return NPERR_GENERIC_ERROR;
1792 : #endif
1793 : }
1794 :
1795 : NPBool NP_CALLBACK
1796 0 : _convertpoint(NPP instance,
1797 : double sourceX, double sourceY, NPCoordinateSpace sourceSpace,
1798 : double *destX, double *destY, NPCoordinateSpace destSpace)
1799 : {
1800 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1801 0 : AssertPluginThread();
1802 :
1803 0 : double rDestX = 0;
1804 0 : bool ignoreDestX = !destX;
1805 0 : double rDestY = 0;
1806 0 : bool ignoreDestY = !destY;
1807 0 : bool result = false;
1808 0 : InstCast(instance)->CallNPN_ConvertPoint(sourceX, ignoreDestX, sourceY, ignoreDestY, sourceSpace, destSpace,
1809 0 : &rDestX, &rDestY, &result);
1810 0 : if (result) {
1811 0 : if (destX)
1812 0 : *destX = rDestX;
1813 0 : if (destY)
1814 0 : *destY = rDestY;
1815 : }
1816 :
1817 0 : return result;
1818 : }
1819 :
1820 : void NP_CALLBACK
1821 0 : _urlredirectresponse(NPP instance, void* notifyData, NPBool allow)
1822 : {
1823 0 : InstCast(instance)->NPN_URLRedirectResponse(notifyData, allow);
1824 0 : }
1825 :
1826 : NPError NP_CALLBACK
1827 0 : _initasyncsurface(NPP instance, NPSize *size,
1828 : NPImageFormat format, void *initData,
1829 : NPAsyncSurface *surface)
1830 : {
1831 0 : return InstCast(instance)->NPN_InitAsyncSurface(size, format, initData, surface);
1832 : }
1833 :
1834 : NPError NP_CALLBACK
1835 0 : _finalizeasyncsurface(NPP instance, NPAsyncSurface *surface)
1836 : {
1837 0 : return InstCast(instance)->NPN_FinalizeAsyncSurface(surface);
1838 : }
1839 :
1840 : void NP_CALLBACK
1841 0 : _setcurrentasyncsurface(NPP instance, NPAsyncSurface *surface, NPRect *changed)
1842 : {
1843 0 : InstCast(instance)->NPN_SetCurrentAsyncSurface(surface, changed);
1844 0 : }
1845 :
1846 : } /* namespace child */
1847 : } /* namespace plugins */
1848 : } /* namespace mozilla */
1849 :
1850 : //-----------------------------------------------------------------------------
1851 :
1852 : bool
1853 0 : PluginModuleChild::AnswerNP_GetEntryPoints(NPError* _retval)
1854 : {
1855 0 : PLUGIN_LOG_DEBUG_METHOD;
1856 0 : AssertPluginThread();
1857 :
1858 : #if defined(OS_LINUX)
1859 0 : return true;
1860 : #elif defined(OS_WIN) || defined(OS_MACOSX)
1861 : *_retval = mGetEntryPointsFunc(&mFunctions);
1862 : return true;
1863 : #else
1864 : # error Please implement me for your platform
1865 : #endif
1866 : }
1867 :
1868 : bool
1869 0 : PluginModuleChild::AnswerNP_Initialize(const uint32_t& aFlags, NPError* _retval)
1870 : {
1871 0 : PLUGIN_LOG_DEBUG_METHOD;
1872 0 : AssertPluginThread();
1873 :
1874 0 : mAsyncDrawingAllowed = aFlags & kAllowAsyncDrawing;
1875 :
1876 : #ifdef OS_WIN
1877 : SetEventHooks();
1878 : #endif
1879 :
1880 : #ifdef MOZ_X11
1881 : // Send the parent a dup of our X socket, to act as a proxy
1882 : // reference for our X resources
1883 0 : int xSocketFd = ConnectionNumber(DefaultXDisplay());
1884 0 : SendBackUpXResources(FileDescriptor(xSocketFd, false/*don't close*/));
1885 : #endif
1886 :
1887 : #if defined(OS_LINUX)
1888 0 : *_retval = mInitializeFunc(&sBrowserFuncs, &mFunctions);
1889 0 : return true;
1890 : #elif defined(OS_WIN) || defined(OS_MACOSX)
1891 : *_retval = mInitializeFunc(&sBrowserFuncs);
1892 : return true;
1893 : #else
1894 : # error Please implement me for your platform
1895 : #endif
1896 : }
1897 :
1898 : PPluginIdentifierChild*
1899 0 : PluginModuleChild::AllocPPluginIdentifier(const nsCString& aString,
1900 : const int32_t& aInt,
1901 : const bool& aTemporary)
1902 : {
1903 : // We cannot call SetPermanent within this function because Manager() isn't
1904 : // set up yet.
1905 0 : if (aString.IsVoid()) {
1906 0 : return new PluginIdentifierChildInt(aInt);
1907 : }
1908 0 : return new PluginIdentifierChildString(aString);
1909 : }
1910 :
1911 : bool
1912 0 : PluginModuleChild::RecvPPluginIdentifierConstructor(PPluginIdentifierChild* actor,
1913 : const nsCString& aString,
1914 : const int32_t& aInt,
1915 : const bool& aTemporary)
1916 : {
1917 0 : if (!aTemporary) {
1918 0 : static_cast<PluginIdentifierChild*>(actor)->MakePermanent();
1919 : }
1920 0 : return true;
1921 : }
1922 :
1923 : bool
1924 0 : PluginModuleChild::DeallocPPluginIdentifier(PPluginIdentifierChild* aActor)
1925 : {
1926 0 : delete aActor;
1927 0 : return true;
1928 : }
1929 :
1930 : #if defined(XP_WIN)
1931 : BOOL WINAPI
1932 : PMCGetWindowInfoHook(HWND hWnd, PWINDOWINFO pwi)
1933 : {
1934 : if (!pwi)
1935 : return FALSE;
1936 :
1937 : if (!sGetWindowInfoPtrStub) {
1938 : NS_ASSERTION(FALSE, "Something is horribly wrong in PMCGetWindowInfoHook!");
1939 : return FALSE;
1940 : }
1941 :
1942 : if (!sBrowserHwnd) {
1943 : PRUnichar szClass[20];
1944 : if (GetClassNameW(hWnd, szClass, ArrayLength(szClass)) &&
1945 : !wcscmp(szClass, kMozillaWindowClass)) {
1946 : sBrowserHwnd = hWnd;
1947 : }
1948 : }
1949 : // Oddity: flash does strange rect comparisons for mouse input destined for
1950 : // it's internal settings window. Post removing sub widgets for tabs, touch
1951 : // this up so they get the rect they expect.
1952 : // XXX potentially tie this to a specific major version?
1953 : BOOL result = sGetWindowInfoPtrStub(hWnd, pwi);
1954 : if (sBrowserHwnd && sBrowserHwnd == hWnd)
1955 : pwi->rcWindow = pwi->rcClient;
1956 : return result;
1957 : }
1958 : #endif
1959 :
1960 : PPluginInstanceChild*
1961 0 : PluginModuleChild::AllocPPluginInstance(const nsCString& aMimeType,
1962 : const uint16_t& aMode,
1963 : const InfallibleTArray<nsCString>& aNames,
1964 : const InfallibleTArray<nsCString>& aValues,
1965 : NPError* rv)
1966 : {
1967 0 : PLUGIN_LOG_DEBUG_METHOD;
1968 0 : AssertPluginThread();
1969 :
1970 0 : InitQuirksModes(aMimeType);
1971 :
1972 : #ifdef XP_WIN
1973 : if ((mQuirks & QUIRK_FLASH_HOOK_GETWINDOWINFO) &&
1974 : !sGetWindowInfoPtrStub) {
1975 : sUser32Intercept.Init("user32.dll");
1976 : sUser32Intercept.AddHook("GetWindowInfo", reinterpret_cast<intptr_t>(PMCGetWindowInfoHook),
1977 : (void**) &sGetWindowInfoPtrStub);
1978 : }
1979 : #endif
1980 :
1981 : nsAutoPtr<PluginInstanceChild> childInstance(
1982 0 : new PluginInstanceChild(&mFunctions));
1983 0 : if (!childInstance->Initialize()) {
1984 0 : *rv = NPERR_GENERIC_ERROR;
1985 0 : return 0;
1986 : }
1987 0 : return childInstance.forget();
1988 : }
1989 :
1990 : void
1991 0 : PluginModuleChild::InitQuirksModes(const nsCString& aMimeType)
1992 : {
1993 0 : if (mQuirks != QUIRKS_NOT_INITIALIZED)
1994 0 : return;
1995 0 : mQuirks = 0;
1996 : // application/x-silverlight
1997 : // application/x-silverlight-2
1998 0 : NS_NAMED_LITERAL_CSTRING(silverlight, "application/x-silverlight");
1999 0 : if (FindInReadable(silverlight, aMimeType)) {
2000 0 : mQuirks |= QUIRK_SILVERLIGHT_DEFAULT_TRANSPARENT;
2001 : #ifdef OS_WIN
2002 : mQuirks |= QUIRK_WINLESS_TRACKPOPUP_HOOK;
2003 : mQuirks |= QUIRK_SILVERLIGHT_FOCUS_CHECK_PARENT;
2004 : #endif
2005 : }
2006 :
2007 : #ifdef OS_WIN
2008 : // application/x-shockwave-flash
2009 : NS_NAMED_LITERAL_CSTRING(flash, "application/x-shockwave-flash");
2010 : if (FindInReadable(flash, aMimeType)) {
2011 : mQuirks |= QUIRK_WINLESS_TRACKPOPUP_HOOK;
2012 : mQuirks |= QUIRK_FLASH_THROTTLE_WMUSER_EVENTS;
2013 : mQuirks |= QUIRK_FLASH_HOOK_SETLONGPTR;
2014 : mQuirks |= QUIRK_FLASH_HOOK_GETWINDOWINFO;
2015 : mQuirks |= QUIRK_FLASH_FIXUP_MOUSE_CAPTURE;
2016 : }
2017 :
2018 : // QuickTime plugin usually loaded with audio/mpeg mimetype
2019 : NS_NAMED_LITERAL_CSTRING(quicktime, "npqtplugin");
2020 : if (FindInReadable(quicktime, mPluginFilename)) {
2021 : mQuirks |= QUIRK_QUICKTIME_AVOID_SETWINDOW;
2022 : }
2023 : #endif
2024 :
2025 : #ifdef XP_MACOSX
2026 : // Whitelist Flash and Quicktime to support offline renderer
2027 : NS_NAMED_LITERAL_CSTRING(flash, "application/x-shockwave-flash");
2028 : NS_NAMED_LITERAL_CSTRING(quicktime, "QuickTime Plugin.plugin");
2029 : if (FindInReadable(flash, aMimeType) ||
2030 : FindInReadable(quicktime, mPluginFilename)) {
2031 : mQuirks |= QUIRK_ALLOW_OFFLINE_RENDERER;
2032 : }
2033 : #endif
2034 : }
2035 :
2036 : bool
2037 0 : PluginModuleChild::AnswerPPluginInstanceConstructor(PPluginInstanceChild* aActor,
2038 : const nsCString& aMimeType,
2039 : const uint16_t& aMode,
2040 : const InfallibleTArray<nsCString>& aNames,
2041 : const InfallibleTArray<nsCString>& aValues,
2042 : NPError* rv)
2043 : {
2044 0 : PLUGIN_LOG_DEBUG_METHOD;
2045 0 : AssertPluginThread();
2046 :
2047 : PluginInstanceChild* childInstance =
2048 0 : reinterpret_cast<PluginInstanceChild*>(aActor);
2049 0 : NS_ASSERTION(childInstance, "Null actor!");
2050 :
2051 : // unpack the arguments into a C format
2052 0 : int argc = aNames.Length();
2053 0 : NS_ASSERTION(argc == (int) aValues.Length(),
2054 : "argn.length != argv.length");
2055 :
2056 0 : nsAutoArrayPtr<char*> argn(new char*[1 + argc]);
2057 0 : nsAutoArrayPtr<char*> argv(new char*[1 + argc]);
2058 0 : argn[argc] = 0;
2059 0 : argv[argc] = 0;
2060 :
2061 0 : for (int i = 0; i < argc; ++i) {
2062 0 : argn[i] = const_cast<char*>(NullableStringGet(aNames[i]));
2063 0 : argv[i] = const_cast<char*>(NullableStringGet(aValues[i]));
2064 : }
2065 :
2066 0 : NPP npp = childInstance->GetNPP();
2067 :
2068 : // FIXME/cjones: use SAFE_CALL stuff
2069 0 : *rv = mFunctions.newp((char*)NullableStringGet(aMimeType),
2070 : npp,
2071 : aMode,
2072 : argc,
2073 : argn,
2074 : argv,
2075 0 : 0);
2076 0 : if (NPERR_NO_ERROR != *rv) {
2077 0 : return true;
2078 : }
2079 :
2080 : #if defined(XP_MACOSX) && defined(__i386__)
2081 : // If an i386 Mac OS X plugin has selected the Carbon event model then
2082 : // we have to fail. We do not support putting Carbon event model plugins
2083 : // out of process. Note that Carbon is the default model so out of process
2084 : // plugins need to actively negotiate something else in order to work
2085 : // out of process.
2086 : if (childInstance->EventModel() == NPEventModelCarbon) {
2087 : // Send notification that a plugin tried to negotiate Carbon NPAPI so that
2088 : // users can be notified that restarting the browser in i386 mode may allow
2089 : // them to use the plugin.
2090 : childInstance->SendNegotiatedCarbon();
2091 :
2092 : // Fail to instantiate.
2093 : *rv = NPERR_MODULE_LOAD_FAILED_ERROR;
2094 : }
2095 : #endif
2096 :
2097 0 : return true;
2098 : }
2099 :
2100 : bool
2101 0 : PluginModuleChild::DeallocPPluginInstance(PPluginInstanceChild* aActor)
2102 : {
2103 0 : PLUGIN_LOG_DEBUG_METHOD;
2104 0 : AssertPluginThread();
2105 :
2106 0 : delete aActor;
2107 :
2108 0 : return true;
2109 : }
2110 :
2111 : NPObject* NP_CALLBACK
2112 0 : PluginModuleChild::NPN_CreateObject(NPP aNPP, NPClass* aClass)
2113 : {
2114 0 : PLUGIN_LOG_DEBUG_FUNCTION;
2115 0 : ENSURE_PLUGIN_THREAD(nsnull);
2116 :
2117 0 : PluginInstanceChild* i = InstCast(aNPP);
2118 0 : if (i->mDeletingHash) {
2119 0 : NS_ERROR("Plugin used NPP after NPP_Destroy");
2120 0 : return NULL;
2121 : }
2122 :
2123 : NPObject* newObject;
2124 0 : if (aClass && aClass->allocate) {
2125 0 : newObject = aClass->allocate(aNPP, aClass);
2126 : }
2127 : else {
2128 0 : newObject = reinterpret_cast<NPObject*>(child::_memalloc(sizeof(NPObject)));
2129 : }
2130 :
2131 0 : if (newObject) {
2132 0 : newObject->_class = aClass;
2133 0 : newObject->referenceCount = 1;
2134 0 : NS_LOG_ADDREF(newObject, 1, "NPObject", sizeof(NPObject));
2135 : }
2136 :
2137 0 : NPObjectData* d = static_cast<PluginModuleChild*>(i->Manager())
2138 0 : ->mObjectMap.PutEntry(newObject);
2139 0 : NS_ASSERTION(!d->instance, "New NPObject already mapped?");
2140 0 : d->instance = i;
2141 :
2142 0 : return newObject;
2143 : }
2144 :
2145 : NPObject* NP_CALLBACK
2146 0 : PluginModuleChild::NPN_RetainObject(NPObject* aNPObj)
2147 : {
2148 0 : AssertPluginThread();
2149 :
2150 : #ifdef NS_BUILD_REFCNT_LOGGING
2151 : int32_t refCnt =
2152 : #endif
2153 0 : PR_ATOMIC_INCREMENT((int32_t*)&aNPObj->referenceCount);
2154 0 : NS_LOG_ADDREF(aNPObj, refCnt, "NPObject", sizeof(NPObject));
2155 :
2156 0 : return aNPObj;
2157 : }
2158 :
2159 : void NP_CALLBACK
2160 0 : PluginModuleChild::NPN_ReleaseObject(NPObject* aNPObj)
2161 : {
2162 0 : AssertPluginThread();
2163 :
2164 0 : NPObjectData* d = current()->mObjectMap.GetEntry(aNPObj);
2165 0 : if (!d) {
2166 0 : NS_ERROR("Releasing object not in mObjectMap?");
2167 0 : return;
2168 : }
2169 :
2170 0 : DeletingObjectEntry* doe = NULL;
2171 0 : if (d->instance->mDeletingHash) {
2172 0 : doe = d->instance->mDeletingHash->GetEntry(aNPObj);
2173 0 : if (!doe) {
2174 0 : NS_ERROR("An object for a destroyed instance isn't in the instance deletion hash");
2175 0 : return;
2176 : }
2177 0 : if (doe->mDeleted)
2178 0 : return;
2179 : }
2180 :
2181 0 : int32_t refCnt = PR_ATOMIC_DECREMENT((int32_t*)&aNPObj->referenceCount);
2182 0 : NS_LOG_RELEASE(aNPObj, refCnt, "NPObject");
2183 :
2184 0 : if (refCnt == 0) {
2185 0 : DeallocNPObject(aNPObj);
2186 0 : if (doe)
2187 0 : doe->mDeleted = true;
2188 : }
2189 0 : return;
2190 : }
2191 :
2192 : void
2193 0 : PluginModuleChild::DeallocNPObject(NPObject* aNPObj)
2194 : {
2195 0 : if (aNPObj->_class && aNPObj->_class->deallocate) {
2196 0 : aNPObj->_class->deallocate(aNPObj);
2197 : } else {
2198 0 : child::_memfree(aNPObj);
2199 : }
2200 :
2201 0 : NPObjectData* d = current()->mObjectMap.GetEntry(aNPObj);
2202 0 : if (d->actor)
2203 0 : d->actor->NPObjectDestroyed();
2204 :
2205 0 : current()->mObjectMap.RemoveEntry(aNPObj);
2206 0 : }
2207 :
2208 : void
2209 0 : PluginModuleChild::FindNPObjectsForInstance(PluginInstanceChild* instance)
2210 : {
2211 0 : NS_ASSERTION(instance->mDeletingHash, "filling null mDeletingHash?");
2212 0 : mObjectMap.EnumerateEntries(CollectForInstance, instance);
2213 0 : }
2214 :
2215 : PLDHashOperator
2216 0 : PluginModuleChild::CollectForInstance(NPObjectData* d, void* userArg)
2217 : {
2218 0 : PluginInstanceChild* instance = static_cast<PluginInstanceChild*>(userArg);
2219 0 : if (d->instance == instance) {
2220 0 : NPObject* o = d->GetKey();
2221 0 : instance->mDeletingHash->PutEntry(o);
2222 : }
2223 0 : return PL_DHASH_NEXT;
2224 : }
2225 :
2226 : NPIdentifier NP_CALLBACK
2227 0 : PluginModuleChild::NPN_GetStringIdentifier(const NPUTF8* aName)
2228 : {
2229 0 : PLUGIN_LOG_DEBUG_FUNCTION;
2230 0 : AssertPluginThread();
2231 :
2232 0 : if (!aName)
2233 0 : return 0;
2234 :
2235 0 : PluginModuleChild* self = PluginModuleChild::current();
2236 0 : nsDependentCString name(aName);
2237 :
2238 0 : PluginIdentifierChildString* ident = self->mStringIdentifiers.Get(name);
2239 0 : if (!ident) {
2240 0 : nsCString nameCopy(name);
2241 :
2242 0 : ident = new PluginIdentifierChildString(nameCopy);
2243 0 : self->SendPPluginIdentifierConstructor(ident, nameCopy, -1, false);
2244 : }
2245 0 : ident->MakePermanent();
2246 0 : return ident;
2247 : }
2248 :
2249 : void NP_CALLBACK
2250 0 : PluginModuleChild::NPN_GetStringIdentifiers(const NPUTF8** aNames,
2251 : int32_t aNameCount,
2252 : NPIdentifier* aIdentifiers)
2253 : {
2254 0 : PLUGIN_LOG_DEBUG_FUNCTION;
2255 0 : AssertPluginThread();
2256 :
2257 0 : if (!(aNames && aNameCount > 0 && aIdentifiers)) {
2258 0 : NS_RUNTIMEABORT("Bad input! Headed for a crash!");
2259 : }
2260 :
2261 0 : PluginModuleChild* self = PluginModuleChild::current();
2262 :
2263 0 : for (int32_t index = 0; index < aNameCount; ++index) {
2264 0 : if (!aNames[index]) {
2265 0 : aIdentifiers[index] = 0;
2266 0 : continue;
2267 : }
2268 0 : nsDependentCString name(aNames[index]);
2269 0 : PluginIdentifierChildString* ident = self->mStringIdentifiers.Get(name);
2270 0 : if (!ident) {
2271 0 : nsCString nameCopy(name);
2272 :
2273 0 : ident = new PluginIdentifierChildString(nameCopy);
2274 0 : self->SendPPluginIdentifierConstructor(ident, nameCopy, -1, false);
2275 : }
2276 0 : ident->MakePermanent();
2277 0 : aIdentifiers[index] = ident;
2278 : }
2279 0 : }
2280 :
2281 : bool NP_CALLBACK
2282 0 : PluginModuleChild::NPN_IdentifierIsString(NPIdentifier aIdentifier)
2283 : {
2284 0 : PLUGIN_LOG_DEBUG_FUNCTION;
2285 :
2286 : PluginIdentifierChild* ident =
2287 0 : static_cast<PluginIdentifierChild*>(aIdentifier);
2288 0 : return ident->IsString();
2289 : }
2290 :
2291 : NPIdentifier NP_CALLBACK
2292 0 : PluginModuleChild::NPN_GetIntIdentifier(int32_t aIntId)
2293 : {
2294 0 : PLUGIN_LOG_DEBUG_FUNCTION;
2295 0 : AssertPluginThread();
2296 :
2297 0 : PluginModuleChild* self = PluginModuleChild::current();
2298 :
2299 0 : PluginIdentifierChildInt* ident = self->mIntIdentifiers.Get(aIntId);
2300 0 : if (!ident) {
2301 0 : nsCString voidString;
2302 0 : voidString.SetIsVoid(true);
2303 :
2304 0 : ident = new PluginIdentifierChildInt(aIntId);
2305 0 : self->SendPPluginIdentifierConstructor(ident, voidString, aIntId, false);
2306 : }
2307 0 : ident->MakePermanent();
2308 0 : return ident;
2309 : }
2310 :
2311 : NPUTF8* NP_CALLBACK
2312 0 : PluginModuleChild::NPN_UTF8FromIdentifier(NPIdentifier aIdentifier)
2313 : {
2314 0 : PLUGIN_LOG_DEBUG_FUNCTION;
2315 :
2316 0 : if (static_cast<PluginIdentifierChild*>(aIdentifier)->IsString()) {
2317 0 : return static_cast<PluginIdentifierChildString*>(aIdentifier)->ToString();
2318 : }
2319 0 : return nsnull;
2320 : }
2321 :
2322 : int32_t NP_CALLBACK
2323 0 : PluginModuleChild::NPN_IntFromIdentifier(NPIdentifier aIdentifier)
2324 : {
2325 0 : PLUGIN_LOG_DEBUG_FUNCTION;
2326 :
2327 0 : if (!static_cast<PluginIdentifierChild*>(aIdentifier)->IsString()) {
2328 0 : return static_cast<PluginIdentifierChildInt*>(aIdentifier)->ToInt();
2329 : }
2330 0 : return PR_INT32_MIN;
2331 : }
2332 :
2333 : #ifdef OS_WIN
2334 : void
2335 : PluginModuleChild::EnteredCall()
2336 : {
2337 : mIncallPumpingStack.AppendElement();
2338 : }
2339 :
2340 : void
2341 : PluginModuleChild::ExitedCall()
2342 : {
2343 : NS_ASSERTION(mIncallPumpingStack.Length(), "mismatched entered/exited");
2344 : PRUint32 len = mIncallPumpingStack.Length();
2345 : const IncallFrame& f = mIncallPumpingStack[len - 1];
2346 : if (f._spinning)
2347 : MessageLoop::current()->SetNestableTasksAllowed(f._savedNestableTasksAllowed);
2348 :
2349 : mIncallPumpingStack.TruncateLength(len - 1);
2350 : }
2351 :
2352 : LRESULT CALLBACK
2353 : PluginModuleChild::CallWindowProcHook(int nCode, WPARAM wParam, LPARAM lParam)
2354 : {
2355 : // Trap and reply to anything we recognize as the source of a
2356 : // potential send message deadlock.
2357 : if (nCode >= 0 &&
2358 : (InSendMessageEx(NULL)&(ISMEX_REPLIED|ISMEX_SEND)) == ISMEX_SEND) {
2359 : CWPSTRUCT* pCwp = reinterpret_cast<CWPSTRUCT*>(lParam);
2360 : if (pCwp->message == WM_KILLFOCUS) {
2361 : // Fix for flash fullscreen window loosing focus. On single
2362 : // core systems, sync killfocus events need to be handled
2363 : // after the flash fullscreen window procedure processes this
2364 : // message, otherwise fullscreen focus will not work correctly.
2365 : PRUnichar szClass[26];
2366 : if (GetClassNameW(pCwp->hwnd, szClass,
2367 : sizeof(szClass)/sizeof(PRUnichar)) &&
2368 : !wcscmp(szClass, kFlashFullscreenClass)) {
2369 : gDelayFlashFocusReplyUntilEval = true;
2370 : }
2371 : }
2372 : }
2373 :
2374 : return CallNextHookEx(NULL, nCode, wParam, lParam);
2375 : }
2376 :
2377 : LRESULT CALLBACK
2378 : PluginModuleChild::NestedInputEventHook(int nCode, WPARAM wParam, LPARAM lParam)
2379 : {
2380 : PluginModuleChild* self = current();
2381 : PRUint32 len = self->mIncallPumpingStack.Length();
2382 : if (nCode >= 0 && len && !self->mIncallPumpingStack[len - 1]._spinning) {
2383 : MessageLoop* loop = MessageLoop::current();
2384 : self->SendProcessNativeEventsInRPCCall();
2385 : IncallFrame& f = self->mIncallPumpingStack[len - 1];
2386 : f._spinning = true;
2387 : f._savedNestableTasksAllowed = loop->NestableTasksAllowed();
2388 : loop->SetNestableTasksAllowed(true);
2389 : loop->set_os_modal_loop(true);
2390 : }
2391 :
2392 : return CallNextHookEx(NULL, nCode, wParam, lParam);
2393 : }
2394 :
2395 : void
2396 : PluginModuleChild::SetEventHooks()
2397 : {
2398 : NS_ASSERTION(!mNestedEventHook,
2399 : "mNestedEventHook already setup in call to SetNestedInputEventHook?");
2400 : NS_ASSERTION(!mGlobalCallWndProcHook,
2401 : "mGlobalCallWndProcHook already setup in call to CallWindowProcHook?");
2402 :
2403 : PLUGIN_LOG_DEBUG(("%s", FULLFUNCTION));
2404 :
2405 : // WH_MSGFILTER event hook for detecting modal loops in the child.
2406 : mNestedEventHook = SetWindowsHookEx(WH_MSGFILTER,
2407 : NestedInputEventHook,
2408 : NULL,
2409 : GetCurrentThreadId());
2410 :
2411 : // WH_CALLWNDPROC event hook for trapping sync messages sent from
2412 : // parent that can cause deadlocks.
2413 : mGlobalCallWndProcHook = SetWindowsHookEx(WH_CALLWNDPROC,
2414 : CallWindowProcHook,
2415 : NULL,
2416 : GetCurrentThreadId());
2417 : }
2418 :
2419 : void
2420 : PluginModuleChild::ResetEventHooks()
2421 : {
2422 : PLUGIN_LOG_DEBUG(("%s", FULLFUNCTION));
2423 : if (mNestedEventHook)
2424 : UnhookWindowsHookEx(mNestedEventHook);
2425 : mNestedEventHook = NULL;
2426 : if (mGlobalCallWndProcHook)
2427 : UnhookWindowsHookEx(mGlobalCallWndProcHook);
2428 : mGlobalCallWndProcHook = NULL;
2429 : }
2430 : #endif
2431 :
2432 : bool
2433 0 : PluginModuleChild::RecvProcessNativeEventsInRPCCall()
2434 : {
2435 0 : PLUGIN_LOG_DEBUG(("%s", FULLFUNCTION));
2436 : #if defined(OS_WIN)
2437 : ProcessNativeEventsInRPCCall();
2438 : return true;
2439 : #else
2440 : NS_RUNTIMEABORT(
2441 0 : "PluginModuleChild::RecvProcessNativeEventsInRPCCall not implemented!");
2442 0 : return false;
2443 : #endif
2444 : }
2445 :
2446 : #ifdef MOZ_WIDGET_COCOA
2447 : void
2448 : PluginModuleChild::ProcessNativeEvents() {
2449 : CallProcessSomeEvents();
2450 : }
2451 : #endif
|