1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/plugins/ipc/PluginModuleChild.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,2445 @@ 1.4 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 1.5 +/* vim: set sw=4 ts=4 et : */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#ifdef MOZ_WIDGET_QT 1.11 +#include <unistd.h> // for _exit() 1.12 +#include <QtCore/QTimer> 1.13 +#include "nsQAppInstance.h" 1.14 +#include "NestedLoopTimer.h" 1.15 +#endif 1.16 + 1.17 +#include "mozilla/plugins/PluginModuleChild.h" 1.18 + 1.19 +/* This must occur *after* plugins/PluginModuleChild.h to avoid typedefs conflicts. */ 1.20 +#include "mozilla/ArrayUtils.h" 1.21 + 1.22 +#include "mozilla/ipc/MessageChannel.h" 1.23 + 1.24 +#ifdef MOZ_WIDGET_GTK 1.25 +#include <gtk/gtk.h> 1.26 +#if (MOZ_WIDGET_GTK == 3) 1.27 +#include <gtk/gtkx.h> 1.28 +#endif 1.29 +#endif 1.30 + 1.31 +#include "nsIFile.h" 1.32 + 1.33 +#include "pratom.h" 1.34 +#include "nsDebug.h" 1.35 +#include "nsCOMPtr.h" 1.36 +#include "nsPluginsDir.h" 1.37 +#include "nsXULAppAPI.h" 1.38 + 1.39 +#ifdef MOZ_X11 1.40 +# include "mozilla/X11Util.h" 1.41 +#endif 1.42 +#include "mozilla/plugins/PluginInstanceChild.h" 1.43 +#include "mozilla/plugins/StreamNotifyChild.h" 1.44 +#include "mozilla/plugins/BrowserStreamChild.h" 1.45 +#include "mozilla/plugins/PluginStreamChild.h" 1.46 +#include "PluginIdentifierChild.h" 1.47 +#include "mozilla/dom/CrashReporterChild.h" 1.48 + 1.49 +#include "nsNPAPIPlugin.h" 1.50 + 1.51 +#ifdef XP_WIN 1.52 +#include "COMMessageFilter.h" 1.53 +#include "nsWindowsDllInterceptor.h" 1.54 +#include "mozilla/widget/AudioSession.h" 1.55 +#endif 1.56 + 1.57 +#ifdef MOZ_WIDGET_COCOA 1.58 +#include "PluginInterposeOSX.h" 1.59 +#include "PluginUtilsOSX.h" 1.60 +#endif 1.61 + 1.62 +#include "GeckoProfiler.h" 1.63 + 1.64 +using namespace mozilla; 1.65 +using namespace mozilla::plugins; 1.66 +using mozilla::dom::CrashReporterChild; 1.67 +using mozilla::dom::PCrashReporterChild; 1.68 + 1.69 +#if defined(XP_WIN) 1.70 +const wchar_t * kFlashFullscreenClass = L"ShockwaveFlashFullScreen"; 1.71 +const wchar_t * kMozillaWindowClass = L"MozillaWindowClass"; 1.72 +#endif 1.73 + 1.74 +namespace { 1.75 +PluginModuleChild* gInstance = nullptr; 1.76 +} 1.77 + 1.78 +#ifdef MOZ_WIDGET_QT 1.79 +typedef void (*_gtk_init_fn)(int argc, char **argv); 1.80 +static _gtk_init_fn s_gtk_init = nullptr; 1.81 +static PRLibrary *sGtkLib = nullptr; 1.82 +#endif 1.83 + 1.84 +#ifdef XP_WIN 1.85 +// Used with fix for flash fullscreen window loosing focus. 1.86 +static bool gDelayFlashFocusReplyUntilEval = false; 1.87 +// Used to fix GetWindowInfo problems with internal flash settings dialogs 1.88 +static WindowsDllInterceptor sUser32Intercept; 1.89 +typedef BOOL (WINAPI *GetWindowInfoPtr)(HWND hwnd, PWINDOWINFO pwi); 1.90 +static GetWindowInfoPtr sGetWindowInfoPtrStub = nullptr; 1.91 +static HWND sBrowserHwnd = nullptr; 1.92 +#endif 1.93 + 1.94 +PluginModuleChild::PluginModuleChild() 1.95 + : mLibrary(0) 1.96 + , mPluginFilename("") 1.97 + , mQuirks(QUIRKS_NOT_INITIALIZED) 1.98 + , mShutdownFunc(0) 1.99 + , mInitializeFunc(0) 1.100 +#if defined(OS_WIN) || defined(OS_MACOSX) 1.101 + , mGetEntryPointsFunc(0) 1.102 +#elif defined(MOZ_WIDGET_GTK) 1.103 + , mNestedLoopTimerId(0) 1.104 +#elif defined(MOZ_WIDGET_QT) 1.105 + , mNestedLoopTimerObject(0) 1.106 +#endif 1.107 +#ifdef OS_WIN 1.108 + , mNestedEventHook(nullptr) 1.109 + , mGlobalCallWndProcHook(nullptr) 1.110 +#endif 1.111 +{ 1.112 + NS_ASSERTION(!gInstance, "Something terribly wrong here!"); 1.113 + memset(&mFunctions, 0, sizeof(mFunctions)); 1.114 + memset(&mSavedData, 0, sizeof(mSavedData)); 1.115 + gInstance = this; 1.116 + mUserAgent.SetIsVoid(true); 1.117 +#ifdef XP_MACOSX 1.118 + mac_plugin_interposing::child::SetUpCocoaInterposing(); 1.119 +#endif 1.120 +} 1.121 + 1.122 +PluginModuleChild::~PluginModuleChild() 1.123 +{ 1.124 + NS_ASSERTION(gInstance == this, "Something terribly wrong here!"); 1.125 + 1.126 + // We don't unload the plugin library in case it uses atexit handlers or 1.127 + // other similar hooks. 1.128 + 1.129 + DeinitGraphics(); 1.130 + 1.131 + gInstance = nullptr; 1.132 +} 1.133 + 1.134 +// static 1.135 +PluginModuleChild* 1.136 +PluginModuleChild::current() 1.137 +{ 1.138 + NS_ASSERTION(gInstance, "Null instance!"); 1.139 + return gInstance; 1.140 +} 1.141 + 1.142 +bool 1.143 +PluginModuleChild::Init(const std::string& aPluginFilename, 1.144 + base::ProcessHandle aParentProcessHandle, 1.145 + MessageLoop* aIOLoop, 1.146 + IPC::Channel* aChannel) 1.147 +{ 1.148 + PLUGIN_LOG_DEBUG_METHOD; 1.149 + 1.150 + GetIPCChannel()->SetAbortOnError(true); 1.151 + 1.152 + // Request Windows message deferral behavior on our channel. This 1.153 + // applies to the top level and all sub plugin protocols since they 1.154 + // all share the same channel. 1.155 + GetIPCChannel()->SetChannelFlags(MessageChannel::REQUIRE_DEFERRED_MESSAGE_PROTECTION); 1.156 + 1.157 +#ifdef XP_WIN 1.158 + COMMessageFilter::Initialize(this); 1.159 +#endif 1.160 + 1.161 + NS_ASSERTION(aChannel, "need a channel"); 1.162 + 1.163 + if (!InitGraphics()) 1.164 + return false; 1.165 + 1.166 + mPluginFilename = aPluginFilename.c_str(); 1.167 + nsCOMPtr<nsIFile> localFile; 1.168 + NS_NewLocalFile(NS_ConvertUTF8toUTF16(mPluginFilename), 1.169 + true, 1.170 + getter_AddRefs(localFile)); 1.171 + 1.172 + bool exists; 1.173 + localFile->Exists(&exists); 1.174 + NS_ASSERTION(exists, "plugin file ain't there"); 1.175 + 1.176 + nsPluginFile pluginFile(localFile); 1.177 + 1.178 +#if defined(MOZ_X11) || defined(OS_MACOSX) 1.179 + nsPluginInfo info = nsPluginInfo(); 1.180 + if (NS_FAILED(pluginFile.GetPluginInfo(info, &mLibrary))) { 1.181 + return false; 1.182 + } 1.183 + 1.184 +#if defined(MOZ_X11) 1.185 + NS_NAMED_LITERAL_CSTRING(flash10Head, "Shockwave Flash 10."); 1.186 + if (StringBeginsWith(nsDependentCString(info.fDescription), flash10Head)) { 1.187 + AddQuirk(QUIRK_FLASH_EXPOSE_COORD_TRANSLATION); 1.188 + } 1.189 +#else // defined(OS_MACOSX) 1.190 + mozilla::plugins::PluginUtilsOSX::SetProcessName(info.fName); 1.191 +#endif 1.192 + 1.193 + pluginFile.FreePluginInfo(info); 1.194 + 1.195 + if (!mLibrary) 1.196 +#endif 1.197 + { 1.198 + nsresult rv = pluginFile.LoadPlugin(&mLibrary); 1.199 + if (NS_FAILED(rv)) 1.200 + return false; 1.201 + } 1.202 + NS_ASSERTION(mLibrary, "couldn't open shared object"); 1.203 + 1.204 + if (!Open(aChannel, aParentProcessHandle, aIOLoop)) 1.205 + return false; 1.206 + 1.207 + memset((void*) &mFunctions, 0, sizeof(mFunctions)); 1.208 + mFunctions.size = sizeof(mFunctions); 1.209 + mFunctions.version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR; 1.210 + 1.211 + // TODO: use PluginPRLibrary here 1.212 + 1.213 +#if defined(OS_LINUX) || defined(OS_BSD) 1.214 + mShutdownFunc = 1.215 + (NP_PLUGINSHUTDOWN) PR_FindFunctionSymbol(mLibrary, "NP_Shutdown"); 1.216 + 1.217 + // create the new plugin handler 1.218 + 1.219 + mInitializeFunc = 1.220 + (NP_PLUGINUNIXINIT) PR_FindFunctionSymbol(mLibrary, "NP_Initialize"); 1.221 + NS_ASSERTION(mInitializeFunc, "couldn't find NP_Initialize()"); 1.222 + 1.223 +#elif defined(OS_WIN) || defined(OS_MACOSX) 1.224 + mShutdownFunc = 1.225 + (NP_PLUGINSHUTDOWN)PR_FindFunctionSymbol(mLibrary, "NP_Shutdown"); 1.226 + 1.227 + mGetEntryPointsFunc = 1.228 + (NP_GETENTRYPOINTS)PR_FindSymbol(mLibrary, "NP_GetEntryPoints"); 1.229 + NS_ENSURE_TRUE(mGetEntryPointsFunc, false); 1.230 + 1.231 + mInitializeFunc = 1.232 + (NP_PLUGININIT)PR_FindFunctionSymbol(mLibrary, "NP_Initialize"); 1.233 + NS_ENSURE_TRUE(mInitializeFunc, false); 1.234 +#else 1.235 + 1.236 +# error Please copy the initialization code from nsNPAPIPlugin.cpp 1.237 + 1.238 +#endif 1.239 + 1.240 + return true; 1.241 +} 1.242 + 1.243 +#if defined(MOZ_WIDGET_GTK) 1.244 +typedef void (*GObjectDisposeFn)(GObject*); 1.245 +typedef gboolean (*GtkWidgetScrollEventFn)(GtkWidget*, GdkEventScroll*); 1.246 +typedef void (*GtkPlugEmbeddedFn)(GtkPlug*); 1.247 + 1.248 +static GObjectDisposeFn real_gtk_plug_dispose; 1.249 +static GtkPlugEmbeddedFn real_gtk_plug_embedded; 1.250 + 1.251 +static void 1.252 +undo_bogus_unref(gpointer data, GObject* object, gboolean is_last_ref) { 1.253 + if (!is_last_ref) // recursion in g_object_ref 1.254 + return; 1.255 + 1.256 + g_object_ref(object); 1.257 +} 1.258 + 1.259 +static void 1.260 +wrap_gtk_plug_dispose(GObject* object) { 1.261 + // Work around Flash Player bug described in bug 538914. 1.262 + // 1.263 + // This function is called during gtk_widget_destroy and/or before 1.264 + // the object's last reference is removed. A reference to the 1.265 + // object is held during the call so the ref count should not drop 1.266 + // to zero. However, Flash Player tries to destroy the GtkPlug 1.267 + // using g_object_unref instead of gtk_widget_destroy. The 1.268 + // reference that Flash is removing actually belongs to the 1.269 + // GtkPlug. During real_gtk_plug_dispose, the GtkPlug removes its 1.270 + // reference. 1.271 + // 1.272 + // A toggle ref is added to prevent premature deletion of the object 1.273 + // caused by Flash Player's extra unref, and to detect when there are 1.274 + // unexpectedly no other references. 1.275 + g_object_add_toggle_ref(object, undo_bogus_unref, nullptr); 1.276 + (*real_gtk_plug_dispose)(object); 1.277 + g_object_remove_toggle_ref(object, undo_bogus_unref, nullptr); 1.278 +} 1.279 + 1.280 +static gboolean 1.281 +gtk_plug_scroll_event(GtkWidget *widget, GdkEventScroll *gdk_event) 1.282 +{ 1.283 + if (!gtk_widget_is_toplevel(widget)) // in same process as its GtkSocket 1.284 + return FALSE; // event not handled; propagate to GtkSocket 1.285 + 1.286 + GdkWindow* socket_window = gtk_plug_get_socket_window(GTK_PLUG(widget)); 1.287 + if (!socket_window) 1.288 + return FALSE; 1.289 + 1.290 + // Propagate the event to the embedder. 1.291 + GdkScreen* screen = gdk_window_get_screen(socket_window); 1.292 + GdkWindow* plug_window = gtk_widget_get_window(widget); 1.293 + GdkWindow* event_window = gdk_event->window; 1.294 + gint x = gdk_event->x; 1.295 + gint y = gdk_event->y; 1.296 + unsigned int button; 1.297 + unsigned int button_mask = 0; 1.298 + XEvent xevent; 1.299 + Display* dpy = GDK_WINDOW_XDISPLAY(socket_window); 1.300 + 1.301 + /* Translate the event coordinates to the plug window, 1.302 + * which should be aligned with the socket window. 1.303 + */ 1.304 + while (event_window != plug_window) 1.305 + { 1.306 + gint dx, dy; 1.307 + 1.308 + gdk_window_get_position(event_window, &dx, &dy); 1.309 + x += dx; 1.310 + y += dy; 1.311 + 1.312 + event_window = gdk_window_get_parent(event_window); 1.313 + if (!event_window) 1.314 + return FALSE; 1.315 + } 1.316 + 1.317 + switch (gdk_event->direction) { 1.318 + case GDK_SCROLL_UP: 1.319 + button = 4; 1.320 + button_mask = Button4Mask; 1.321 + break; 1.322 + case GDK_SCROLL_DOWN: 1.323 + button = 5; 1.324 + button_mask = Button5Mask; 1.325 + break; 1.326 + case GDK_SCROLL_LEFT: 1.327 + button = 6; 1.328 + break; 1.329 + case GDK_SCROLL_RIGHT: 1.330 + button = 7; 1.331 + break; 1.332 + default: 1.333 + return FALSE; // unknown GdkScrollDirection 1.334 + } 1.335 + 1.336 + memset(&xevent, 0, sizeof(xevent)); 1.337 + xevent.xbutton.type = ButtonPress; 1.338 + xevent.xbutton.window = gdk_x11_window_get_xid(socket_window); 1.339 + xevent.xbutton.root = gdk_x11_window_get_xid(gdk_screen_get_root_window(screen)); 1.340 + xevent.xbutton.subwindow = gdk_x11_window_get_xid(plug_window); 1.341 + xevent.xbutton.time = gdk_event->time; 1.342 + xevent.xbutton.x = x; 1.343 + xevent.xbutton.y = y; 1.344 + xevent.xbutton.x_root = gdk_event->x_root; 1.345 + xevent.xbutton.y_root = gdk_event->y_root; 1.346 + xevent.xbutton.state = gdk_event->state; 1.347 + xevent.xbutton.button = button; 1.348 + xevent.xbutton.same_screen = True; 1.349 + 1.350 + gdk_error_trap_push(); 1.351 + 1.352 + XSendEvent(dpy, xevent.xbutton.window, 1.353 + True, ButtonPressMask, &xevent); 1.354 + 1.355 + xevent.xbutton.type = ButtonRelease; 1.356 + xevent.xbutton.state |= button_mask; 1.357 + XSendEvent(dpy, xevent.xbutton.window, 1.358 + True, ButtonReleaseMask, &xevent); 1.359 + 1.360 + gdk_display_sync(gdk_screen_get_display(screen)); 1.361 + gdk_error_trap_pop(); 1.362 + 1.363 + return TRUE; // event handled 1.364 +} 1.365 + 1.366 +static void 1.367 +wrap_gtk_plug_embedded(GtkPlug* plug) { 1.368 + GdkWindow* socket_window = gtk_plug_get_socket_window(plug); 1.369 + if (socket_window) { 1.370 + if (gtk_check_version(2,18,7) != nullptr // older 1.371 + && g_object_get_data(G_OBJECT(socket_window), 1.372 + "moz-existed-before-set-window")) { 1.373 + // Add missing reference for 1.374 + // https://bugzilla.gnome.org/show_bug.cgi?id=607061 1.375 + g_object_ref(socket_window); 1.376 + } 1.377 + 1.378 + // Ensure the window exists to make this GtkPlug behave like an 1.379 + // in-process GtkPlug for Flash Player. (Bugs 561308 and 539138). 1.380 + gtk_widget_realize(GTK_WIDGET(plug)); 1.381 + } 1.382 + 1.383 + if (*real_gtk_plug_embedded) { 1.384 + (*real_gtk_plug_embedded)(plug); 1.385 + } 1.386 +} 1.387 + 1.388 +// 1.389 +// The next four constants are knobs that can be tuned. They trade 1.390 +// off potential UI lag from delayed event processing with CPU time. 1.391 +// 1.392 +static const gint kNestedLoopDetectorPriority = G_PRIORITY_HIGH_IDLE; 1.393 +// 90ms so that we can hopefully break livelocks before the user 1.394 +// notices UI lag (100ms) 1.395 +static const guint kNestedLoopDetectorIntervalMs = 90; 1.396 + 1.397 +static const gint kBrowserEventPriority = G_PRIORITY_HIGH_IDLE; 1.398 +static const guint kBrowserEventIntervalMs = 10; 1.399 + 1.400 +// static 1.401 +gboolean 1.402 +PluginModuleChild::DetectNestedEventLoop(gpointer data) 1.403 +{ 1.404 + PluginModuleChild* pmc = static_cast<PluginModuleChild*>(data); 1.405 + 1.406 + NS_ABORT_IF_FALSE(0 != pmc->mNestedLoopTimerId, 1.407 + "callback after descheduling"); 1.408 + NS_ABORT_IF_FALSE(pmc->mTopLoopDepth < g_main_depth(), 1.409 + "not canceled before returning to main event loop!"); 1.410 + 1.411 + PLUGIN_LOG_DEBUG(("Detected nested glib event loop")); 1.412 + 1.413 + // just detected a nested loop; start a timer that will 1.414 + // periodically rpc-call back into the browser and process some 1.415 + // events 1.416 + pmc->mNestedLoopTimerId = 1.417 + g_timeout_add_full(kBrowserEventPriority, 1.418 + kBrowserEventIntervalMs, 1.419 + PluginModuleChild::ProcessBrowserEvents, 1.420 + data, 1.421 + nullptr); 1.422 + // cancel the nested-loop detection timer 1.423 + return FALSE; 1.424 +} 1.425 + 1.426 +// static 1.427 +gboolean 1.428 +PluginModuleChild::ProcessBrowserEvents(gpointer data) 1.429 +{ 1.430 + PluginModuleChild* pmc = static_cast<PluginModuleChild*>(data); 1.431 + 1.432 + NS_ABORT_IF_FALSE(pmc->mTopLoopDepth < g_main_depth(), 1.433 + "not canceled before returning to main event loop!"); 1.434 + 1.435 + pmc->CallProcessSomeEvents(); 1.436 + 1.437 + return TRUE; 1.438 +} 1.439 + 1.440 +void 1.441 +PluginModuleChild::EnteredCxxStack() 1.442 +{ 1.443 + NS_ABORT_IF_FALSE(0 == mNestedLoopTimerId, 1.444 + "previous timer not descheduled"); 1.445 + 1.446 + mNestedLoopTimerId = 1.447 + g_timeout_add_full(kNestedLoopDetectorPriority, 1.448 + kNestedLoopDetectorIntervalMs, 1.449 + PluginModuleChild::DetectNestedEventLoop, 1.450 + this, 1.451 + nullptr); 1.452 + 1.453 +#ifdef DEBUG 1.454 + mTopLoopDepth = g_main_depth(); 1.455 +#endif 1.456 +} 1.457 + 1.458 +void 1.459 +PluginModuleChild::ExitedCxxStack() 1.460 +{ 1.461 + NS_ABORT_IF_FALSE(0 < mNestedLoopTimerId, 1.462 + "nested loop timeout not scheduled"); 1.463 + 1.464 + g_source_remove(mNestedLoopTimerId); 1.465 + mNestedLoopTimerId = 0; 1.466 +} 1.467 +#elif defined (MOZ_WIDGET_QT) 1.468 + 1.469 +void 1.470 +PluginModuleChild::EnteredCxxStack() 1.471 +{ 1.472 + NS_ABORT_IF_FALSE(mNestedLoopTimerObject == nullptr, 1.473 + "previous timer not descheduled"); 1.474 + mNestedLoopTimerObject = new NestedLoopTimer(this); 1.475 + QTimer::singleShot(kNestedLoopDetectorIntervalMs, 1.476 + mNestedLoopTimerObject, SLOT(timeOut())); 1.477 +} 1.478 + 1.479 +void 1.480 +PluginModuleChild::ExitedCxxStack() 1.481 +{ 1.482 + NS_ABORT_IF_FALSE(mNestedLoopTimerObject != nullptr, 1.483 + "nested loop timeout not scheduled"); 1.484 + delete mNestedLoopTimerObject; 1.485 + mNestedLoopTimerObject = nullptr; 1.486 +} 1.487 + 1.488 +#endif 1.489 + 1.490 +bool 1.491 +PluginModuleChild::RecvSetParentHangTimeout(const uint32_t& aSeconds) 1.492 +{ 1.493 +#ifdef XP_WIN 1.494 + SetReplyTimeoutMs(((aSeconds > 0) ? (1000 * aSeconds) : 0)); 1.495 +#endif 1.496 + return true; 1.497 +} 1.498 + 1.499 +bool 1.500 +PluginModuleChild::ShouldContinueFromReplyTimeout() 1.501 +{ 1.502 +#ifdef XP_WIN 1.503 + NS_RUNTIMEABORT("terminating child process"); 1.504 +#endif 1.505 + return true; 1.506 +} 1.507 + 1.508 +bool 1.509 +PluginModuleChild::InitGraphics() 1.510 +{ 1.511 +#if defined(MOZ_WIDGET_GTK) 1.512 + // Work around plugins that don't interact well with GDK 1.513 + // client-side windows. 1.514 + PR_SetEnv("GDK_NATIVE_WINDOWS=1"); 1.515 + 1.516 + gtk_init(0, 0); 1.517 + 1.518 + // GtkPlug is a static class so will leak anyway but this ref makes sure. 1.519 + gpointer gtk_plug_class = g_type_class_ref(GTK_TYPE_PLUG); 1.520 + 1.521 + // The dispose method is a good place to hook into the destruction process 1.522 + // because the reference count should be 1 the last time dispose is 1.523 + // called. (Toggle references wouldn't detect if the reference count 1.524 + // might be higher.) 1.525 + GObjectDisposeFn* dispose = &G_OBJECT_CLASS(gtk_plug_class)->dispose; 1.526 + NS_ABORT_IF_FALSE(*dispose != wrap_gtk_plug_dispose, 1.527 + "InitGraphics called twice"); 1.528 + real_gtk_plug_dispose = *dispose; 1.529 + *dispose = wrap_gtk_plug_dispose; 1.530 + 1.531 + // If we ever stop setting GDK_NATIVE_WINDOWS, we'll also need to 1.532 + // gtk_widget_add_events GDK_SCROLL_MASK or GDK client-side windows will 1.533 + // not tell us about the scroll events that it intercepts. With native 1.534 + // windows, this is called when GDK intercepts the events; if GDK doesn't 1.535 + // intercept the events, then the X server will instead send them directly 1.536 + // to an ancestor (embedder) window. 1.537 + GtkWidgetScrollEventFn* scroll_event = 1.538 + >K_WIDGET_CLASS(gtk_plug_class)->scroll_event; 1.539 + if (!*scroll_event) { 1.540 + *scroll_event = gtk_plug_scroll_event; 1.541 + } 1.542 + 1.543 + GtkPlugEmbeddedFn* embedded = >K_PLUG_CLASS(gtk_plug_class)->embedded; 1.544 + real_gtk_plug_embedded = *embedded; 1.545 + *embedded = wrap_gtk_plug_embedded; 1.546 + 1.547 +#elif defined(MOZ_WIDGET_QT) 1.548 + nsQAppInstance::AddRef(); 1.549 + // Work around plugins that don't interact well without gtk initialized 1.550 + // see bug 566845 1.551 +#if defined(MOZ_X11) 1.552 + if (!sGtkLib) 1.553 + sGtkLib = PR_LoadLibrary("libgtk-x11-2.0.so.0"); 1.554 +#endif 1.555 + if (sGtkLib) { 1.556 + s_gtk_init = (_gtk_init_fn)PR_FindFunctionSymbol(sGtkLib, "gtk_init"); 1.557 + if (s_gtk_init) 1.558 + s_gtk_init(0, 0); 1.559 + } 1.560 +#else 1.561 + // may not be necessary on all platforms 1.562 +#endif 1.563 +#ifdef MOZ_X11 1.564 + // Do this after initializing GDK, or GDK will install its own handler. 1.565 + XRE_InstallX11ErrorHandler(); 1.566 +#endif 1.567 + return true; 1.568 +} 1.569 + 1.570 +void 1.571 +PluginModuleChild::DeinitGraphics() 1.572 +{ 1.573 +#ifdef MOZ_WIDGET_QT 1.574 + nsQAppInstance::Release(); 1.575 + if (sGtkLib) { 1.576 + PR_UnloadLibrary(sGtkLib); 1.577 + sGtkLib = nullptr; 1.578 + s_gtk_init = nullptr; 1.579 + } 1.580 +#endif 1.581 + 1.582 +#if defined(MOZ_X11) && defined(NS_FREE_PERMANENT_DATA) 1.583 + // We free some data off of XDisplay close hooks, ensure they're 1.584 + // run. Closing the display is pretty scary, so we only do it to 1.585 + // silence leak checkers. 1.586 + XCloseDisplay(DefaultXDisplay()); 1.587 +#endif 1.588 +} 1.589 + 1.590 +bool 1.591 +PluginModuleChild::AnswerNP_Shutdown(NPError *rv) 1.592 +{ 1.593 + AssertPluginThread(); 1.594 + 1.595 +#if defined XP_WIN 1.596 + mozilla::widget::StopAudioSession(); 1.597 +#endif 1.598 + 1.599 + // the PluginModuleParent shuts down this process after this interrupt 1.600 + // call pops off its stack 1.601 + 1.602 + *rv = mShutdownFunc ? mShutdownFunc() : NPERR_NO_ERROR; 1.603 + 1.604 + // weakly guard against re-entry after NP_Shutdown 1.605 + memset(&mFunctions, 0, sizeof(mFunctions)); 1.606 + 1.607 +#ifdef OS_WIN 1.608 + ResetEventHooks(); 1.609 +#endif 1.610 + 1.611 + GetIPCChannel()->SetAbortOnError(false); 1.612 + 1.613 + return true; 1.614 +} 1.615 + 1.616 +bool 1.617 +PluginModuleChild::AnswerOptionalFunctionsSupported(bool *aURLRedirectNotify, 1.618 + bool *aClearSiteData, 1.619 + bool *aGetSitesWithData) 1.620 +{ 1.621 + *aURLRedirectNotify = !!mFunctions.urlredirectnotify; 1.622 + *aClearSiteData = !!mFunctions.clearsitedata; 1.623 + *aGetSitesWithData = !!mFunctions.getsiteswithdata; 1.624 + return true; 1.625 +} 1.626 + 1.627 +bool 1.628 +PluginModuleChild::AnswerNPP_ClearSiteData(const nsCString& aSite, 1.629 + const uint64_t& aFlags, 1.630 + const uint64_t& aMaxAge, 1.631 + NPError* aResult) 1.632 +{ 1.633 + *aResult = 1.634 + mFunctions.clearsitedata(NullableStringGet(aSite), aFlags, aMaxAge); 1.635 + return true; 1.636 +} 1.637 + 1.638 +bool 1.639 +PluginModuleChild::AnswerNPP_GetSitesWithData(InfallibleTArray<nsCString>* aResult) 1.640 +{ 1.641 + char** result = mFunctions.getsiteswithdata(); 1.642 + if (!result) 1.643 + return true; 1.644 + 1.645 + char** iterator = result; 1.646 + while (*iterator) { 1.647 + aResult->AppendElement(*iterator); 1.648 + NS_Free(*iterator); 1.649 + ++iterator; 1.650 + } 1.651 + NS_Free(result); 1.652 + 1.653 + return true; 1.654 +} 1.655 + 1.656 +bool 1.657 +PluginModuleChild::RecvSetAudioSessionData(const nsID& aId, 1.658 + const nsString& aDisplayName, 1.659 + const nsString& aIconPath) 1.660 +{ 1.661 +#if !defined XP_WIN 1.662 + NS_RUNTIMEABORT("Not Reached!"); 1.663 + return false; 1.664 +#else 1.665 + nsresult rv = mozilla::widget::RecvAudioSessionData(aId, aDisplayName, aIconPath); 1.666 + NS_ENSURE_SUCCESS(rv, true); // Bail early if this fails 1.667 + 1.668 + // Ignore failures here; we can't really do anything about them 1.669 + mozilla::widget::StartAudioSession(); 1.670 + return true; 1.671 +#endif 1.672 +} 1.673 + 1.674 +void 1.675 +PluginModuleChild::QuickExit() 1.676 +{ 1.677 + NS_WARNING("plugin process _exit()ing"); 1.678 + _exit(0); 1.679 +} 1.680 + 1.681 +PCrashReporterChild* 1.682 +PluginModuleChild::AllocPCrashReporterChild(mozilla::dom::NativeThreadId* id, 1.683 + uint32_t* processType) 1.684 +{ 1.685 + return new CrashReporterChild(); 1.686 +} 1.687 + 1.688 +bool 1.689 +PluginModuleChild::DeallocPCrashReporterChild(PCrashReporterChild* actor) 1.690 +{ 1.691 + delete actor; 1.692 + return true; 1.693 +} 1.694 + 1.695 +bool 1.696 +PluginModuleChild::AnswerPCrashReporterConstructor( 1.697 + PCrashReporterChild* actor, 1.698 + mozilla::dom::NativeThreadId* id, 1.699 + uint32_t* processType) 1.700 +{ 1.701 +#ifdef MOZ_CRASHREPORTER 1.702 + *id = CrashReporter::CurrentThreadId(); 1.703 + *processType = XRE_GetProcessType(); 1.704 +#endif 1.705 + return true; 1.706 +} 1.707 + 1.708 +void 1.709 +PluginModuleChild::ActorDestroy(ActorDestroyReason why) 1.710 +{ 1.711 + if (AbnormalShutdown == why) { 1.712 + NS_WARNING("shutting down early because of crash!"); 1.713 + QuickExit(); 1.714 + } 1.715 + 1.716 + // doesn't matter why we're being destroyed; it's up to us to 1.717 + // initiate (clean) shutdown 1.718 + XRE_ShutdownChildProcess(); 1.719 +} 1.720 + 1.721 +void 1.722 +PluginModuleChild::CleanUp() 1.723 +{ 1.724 +} 1.725 + 1.726 +const char* 1.727 +PluginModuleChild::GetUserAgent() 1.728 +{ 1.729 + if (mUserAgent.IsVoid() && !CallNPN_UserAgent(&mUserAgent)) 1.730 + return nullptr; 1.731 + 1.732 + return NullableStringGet(mUserAgent); 1.733 +} 1.734 + 1.735 +bool 1.736 +PluginModuleChild::RegisterActorForNPObject(NPObject* aObject, 1.737 + PluginScriptableObjectChild* aActor) 1.738 +{ 1.739 + AssertPluginThread(); 1.740 + NS_ASSERTION(aObject && aActor, "Null pointer!"); 1.741 + 1.742 + NPObjectData* d = mObjectMap.GetEntry(aObject); 1.743 + if (!d) { 1.744 + NS_ERROR("NPObject not in object table"); 1.745 + return false; 1.746 + } 1.747 + 1.748 + d->actor = aActor; 1.749 + return true; 1.750 +} 1.751 + 1.752 +void 1.753 +PluginModuleChild::UnregisterActorForNPObject(NPObject* aObject) 1.754 +{ 1.755 + AssertPluginThread(); 1.756 + NS_ASSERTION(aObject, "Null pointer!"); 1.757 + 1.758 + NPObjectData* d = mObjectMap.GetEntry(aObject); 1.759 + NS_ASSERTION(d, "NPObject not in object table"); 1.760 + if (d) { 1.761 + d->actor = nullptr; 1.762 + } 1.763 +} 1.764 + 1.765 +PluginScriptableObjectChild* 1.766 +PluginModuleChild::GetActorForNPObject(NPObject* aObject) 1.767 +{ 1.768 + AssertPluginThread(); 1.769 + NS_ASSERTION(aObject, "Null pointer!"); 1.770 + 1.771 + NPObjectData* d = mObjectMap.GetEntry(aObject); 1.772 + if (!d) { 1.773 + NS_ERROR("Plugin using object not created with NPN_CreateObject?"); 1.774 + return nullptr; 1.775 + } 1.776 + 1.777 + return d->actor; 1.778 +} 1.779 + 1.780 +#ifdef DEBUG 1.781 +bool 1.782 +PluginModuleChild::NPObjectIsRegistered(NPObject* aObject) 1.783 +{ 1.784 + return !!mObjectMap.GetEntry(aObject); 1.785 +} 1.786 +#endif 1.787 + 1.788 +//----------------------------------------------------------------------------- 1.789 +// FIXME/cjones: just getting this out of the way for the moment ... 1.790 + 1.791 +namespace mozilla { 1.792 +namespace plugins { 1.793 +namespace child { 1.794 + 1.795 +static NPError 1.796 +_requestread(NPStream *pstream, NPByteRange *rangeList); 1.797 + 1.798 +static NPError 1.799 +_geturlnotify(NPP aNPP, const char* relativeURL, const char* target, 1.800 + void* notifyData); 1.801 + 1.802 +static NPError 1.803 +_getvalue(NPP aNPP, NPNVariable variable, void *r_value); 1.804 + 1.805 +static NPError 1.806 +_setvalue(NPP aNPP, NPPVariable variable, void *r_value); 1.807 + 1.808 +static NPError 1.809 +_geturl(NPP aNPP, const char* relativeURL, const char* target); 1.810 + 1.811 +static NPError 1.812 +_posturlnotify(NPP aNPP, const char* relativeURL, const char *target, 1.813 + uint32_t len, const char *buf, NPBool file, void* notifyData); 1.814 + 1.815 +static NPError 1.816 +_posturl(NPP aNPP, const char* relativeURL, const char *target, uint32_t len, 1.817 + const char *buf, NPBool file); 1.818 + 1.819 +static NPError 1.820 +_newstream(NPP aNPP, NPMIMEType type, const char* window, NPStream** pstream); 1.821 + 1.822 +static int32_t 1.823 +_write(NPP aNPP, NPStream *pstream, int32_t len, void *buffer); 1.824 + 1.825 +static NPError 1.826 +_destroystream(NPP aNPP, NPStream *pstream, NPError reason); 1.827 + 1.828 +static void 1.829 +_status(NPP aNPP, const char *message); 1.830 + 1.831 +static void 1.832 +_memfree (void *ptr); 1.833 + 1.834 +static uint32_t 1.835 +_memflush(uint32_t size); 1.836 + 1.837 +static void 1.838 +_reloadplugins(NPBool reloadPages); 1.839 + 1.840 +static void 1.841 +_invalidaterect(NPP aNPP, NPRect *invalidRect); 1.842 + 1.843 +static void 1.844 +_invalidateregion(NPP aNPP, NPRegion invalidRegion); 1.845 + 1.846 +static void 1.847 +_forceredraw(NPP aNPP); 1.848 + 1.849 +static const char* 1.850 +_useragent(NPP aNPP); 1.851 + 1.852 +static void* 1.853 +_memalloc (uint32_t size); 1.854 + 1.855 +// Deprecated entry points for the old Java plugin. 1.856 +static void* /* OJI type: JRIEnv* */ 1.857 +_getjavaenv(void); 1.858 + 1.859 +// Deprecated entry points for the old Java plugin. 1.860 +static void* /* OJI type: jref */ 1.861 +_getjavapeer(NPP aNPP); 1.862 + 1.863 +static bool 1.864 +_invoke(NPP aNPP, NPObject* npobj, NPIdentifier method, const NPVariant *args, 1.865 + uint32_t argCount, NPVariant *result); 1.866 + 1.867 +static bool 1.868 +_invokedefault(NPP aNPP, NPObject* npobj, const NPVariant *args, 1.869 + uint32_t argCount, NPVariant *result); 1.870 + 1.871 +static bool 1.872 +_evaluate(NPP aNPP, NPObject* npobj, NPString *script, NPVariant *result); 1.873 + 1.874 +static bool 1.875 +_getproperty(NPP aNPP, NPObject* npobj, NPIdentifier property, 1.876 + NPVariant *result); 1.877 + 1.878 +static bool 1.879 +_setproperty(NPP aNPP, NPObject* npobj, NPIdentifier property, 1.880 + const NPVariant *value); 1.881 + 1.882 +static bool 1.883 +_removeproperty(NPP aNPP, NPObject* npobj, NPIdentifier property); 1.884 + 1.885 +static bool 1.886 +_hasproperty(NPP aNPP, NPObject* npobj, NPIdentifier propertyName); 1.887 + 1.888 +static bool 1.889 +_hasmethod(NPP aNPP, NPObject* npobj, NPIdentifier methodName); 1.890 + 1.891 +static bool 1.892 +_enumerate(NPP aNPP, NPObject *npobj, NPIdentifier **identifier, 1.893 + uint32_t *count); 1.894 + 1.895 +static bool 1.896 +_construct(NPP aNPP, NPObject* npobj, const NPVariant *args, 1.897 + uint32_t argCount, NPVariant *result); 1.898 + 1.899 +static void 1.900 +_releasevariantvalue(NPVariant *variant); 1.901 + 1.902 +static void 1.903 +_setexception(NPObject* npobj, const NPUTF8 *message); 1.904 + 1.905 +static void 1.906 +_pushpopupsenabledstate(NPP aNPP, NPBool enabled); 1.907 + 1.908 +static void 1.909 +_poppopupsenabledstate(NPP aNPP); 1.910 + 1.911 +static void 1.912 +_pluginthreadasynccall(NPP instance, PluginThreadCallback func, 1.913 + void *userData); 1.914 + 1.915 +static NPError 1.916 +_getvalueforurl(NPP npp, NPNURLVariable variable, const char *url, 1.917 + char **value, uint32_t *len); 1.918 + 1.919 +static NPError 1.920 +_setvalueforurl(NPP npp, NPNURLVariable variable, const char *url, 1.921 + const char *value, uint32_t len); 1.922 + 1.923 +static NPError 1.924 +_getauthenticationinfo(NPP npp, const char *protocol, 1.925 + const char *host, int32_t port, 1.926 + const char *scheme, const char *realm, 1.927 + char **username, uint32_t *ulen, 1.928 + char **password, uint32_t *plen); 1.929 + 1.930 +static uint32_t 1.931 +_scheduletimer(NPP instance, uint32_t interval, NPBool repeat, 1.932 + void (*timerFunc)(NPP npp, uint32_t timerID)); 1.933 + 1.934 +static void 1.935 +_unscheduletimer(NPP instance, uint32_t timerID); 1.936 + 1.937 +static NPError 1.938 +_popupcontextmenu(NPP instance, NPMenu* menu); 1.939 + 1.940 +static NPBool 1.941 +_convertpoint(NPP instance, 1.942 + double sourceX, double sourceY, NPCoordinateSpace sourceSpace, 1.943 + double *destX, double *destY, NPCoordinateSpace destSpace); 1.944 + 1.945 +static void 1.946 +_urlredirectresponse(NPP instance, void* notifyData, NPBool allow); 1.947 + 1.948 +static NPError 1.949 +_initasyncsurface(NPP instance, NPSize *size, 1.950 + NPImageFormat format, void *initData, 1.951 + NPAsyncSurface *surface); 1.952 + 1.953 +static NPError 1.954 +_finalizeasyncsurface(NPP instance, NPAsyncSurface *surface); 1.955 + 1.956 +static void 1.957 +_setcurrentasyncsurface(NPP instance, NPAsyncSurface *surface, NPRect *changed); 1.958 + 1.959 +} /* namespace child */ 1.960 +} /* namespace plugins */ 1.961 +} /* namespace mozilla */ 1.962 + 1.963 +const NPNetscapeFuncs PluginModuleChild::sBrowserFuncs = { 1.964 + sizeof(sBrowserFuncs), 1.965 + (NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR, 1.966 + mozilla::plugins::child::_geturl, 1.967 + mozilla::plugins::child::_posturl, 1.968 + mozilla::plugins::child::_requestread, 1.969 + mozilla::plugins::child::_newstream, 1.970 + mozilla::plugins::child::_write, 1.971 + mozilla::plugins::child::_destroystream, 1.972 + mozilla::plugins::child::_status, 1.973 + mozilla::plugins::child::_useragent, 1.974 + mozilla::plugins::child::_memalloc, 1.975 + mozilla::plugins::child::_memfree, 1.976 + mozilla::plugins::child::_memflush, 1.977 + mozilla::plugins::child::_reloadplugins, 1.978 + mozilla::plugins::child::_getjavaenv, 1.979 + mozilla::plugins::child::_getjavapeer, 1.980 + mozilla::plugins::child::_geturlnotify, 1.981 + mozilla::plugins::child::_posturlnotify, 1.982 + mozilla::plugins::child::_getvalue, 1.983 + mozilla::plugins::child::_setvalue, 1.984 + mozilla::plugins::child::_invalidaterect, 1.985 + mozilla::plugins::child::_invalidateregion, 1.986 + mozilla::plugins::child::_forceredraw, 1.987 + PluginModuleChild::NPN_GetStringIdentifier, 1.988 + PluginModuleChild::NPN_GetStringIdentifiers, 1.989 + PluginModuleChild::NPN_GetIntIdentifier, 1.990 + PluginModuleChild::NPN_IdentifierIsString, 1.991 + PluginModuleChild::NPN_UTF8FromIdentifier, 1.992 + PluginModuleChild::NPN_IntFromIdentifier, 1.993 + PluginModuleChild::NPN_CreateObject, 1.994 + PluginModuleChild::NPN_RetainObject, 1.995 + PluginModuleChild::NPN_ReleaseObject, 1.996 + mozilla::plugins::child::_invoke, 1.997 + mozilla::plugins::child::_invokedefault, 1.998 + mozilla::plugins::child::_evaluate, 1.999 + mozilla::plugins::child::_getproperty, 1.1000 + mozilla::plugins::child::_setproperty, 1.1001 + mozilla::plugins::child::_removeproperty, 1.1002 + mozilla::plugins::child::_hasproperty, 1.1003 + mozilla::plugins::child::_hasmethod, 1.1004 + mozilla::plugins::child::_releasevariantvalue, 1.1005 + mozilla::plugins::child::_setexception, 1.1006 + mozilla::plugins::child::_pushpopupsenabledstate, 1.1007 + mozilla::plugins::child::_poppopupsenabledstate, 1.1008 + mozilla::plugins::child::_enumerate, 1.1009 + mozilla::plugins::child::_pluginthreadasynccall, 1.1010 + mozilla::plugins::child::_construct, 1.1011 + mozilla::plugins::child::_getvalueforurl, 1.1012 + mozilla::plugins::child::_setvalueforurl, 1.1013 + mozilla::plugins::child::_getauthenticationinfo, 1.1014 + mozilla::plugins::child::_scheduletimer, 1.1015 + mozilla::plugins::child::_unscheduletimer, 1.1016 + mozilla::plugins::child::_popupcontextmenu, 1.1017 + mozilla::plugins::child::_convertpoint, 1.1018 + nullptr, // handleevent, unimplemented 1.1019 + nullptr, // unfocusinstance, unimplemented 1.1020 + mozilla::plugins::child::_urlredirectresponse, 1.1021 + mozilla::plugins::child::_initasyncsurface, 1.1022 + mozilla::plugins::child::_finalizeasyncsurface, 1.1023 + mozilla::plugins::child::_setcurrentasyncsurface 1.1024 +}; 1.1025 + 1.1026 +PluginInstanceChild* 1.1027 +InstCast(NPP aNPP) 1.1028 +{ 1.1029 + NS_ABORT_IF_FALSE(!!(aNPP->ndata), "nil instance"); 1.1030 + return static_cast<PluginInstanceChild*>(aNPP->ndata); 1.1031 +} 1.1032 + 1.1033 +namespace mozilla { 1.1034 +namespace plugins { 1.1035 +namespace child { 1.1036 + 1.1037 +NPError 1.1038 +_requestread(NPStream* aStream, 1.1039 + NPByteRange* aRangeList) 1.1040 +{ 1.1041 + PLUGIN_LOG_DEBUG_FUNCTION; 1.1042 + ENSURE_PLUGIN_THREAD(NPERR_INVALID_PARAM); 1.1043 + 1.1044 + BrowserStreamChild* bs = 1.1045 + static_cast<BrowserStreamChild*>(static_cast<AStream*>(aStream->ndata)); 1.1046 + bs->EnsureCorrectStream(aStream); 1.1047 + return bs->NPN_RequestRead(aRangeList); 1.1048 +} 1.1049 + 1.1050 +NPError 1.1051 +_geturlnotify(NPP aNPP, 1.1052 + const char* aRelativeURL, 1.1053 + const char* aTarget, 1.1054 + void* aNotifyData) 1.1055 +{ 1.1056 + PLUGIN_LOG_DEBUG_FUNCTION; 1.1057 + ENSURE_PLUGIN_THREAD(NPERR_INVALID_PARAM); 1.1058 + 1.1059 + if (!aNPP) // nullptr check for nspluginwrapper (bug 561690) 1.1060 + return NPERR_INVALID_INSTANCE_ERROR; 1.1061 + 1.1062 + nsCString url = NullableString(aRelativeURL); 1.1063 + StreamNotifyChild* sn = new StreamNotifyChild(url); 1.1064 + 1.1065 + NPError err; 1.1066 + InstCast(aNPP)->CallPStreamNotifyConstructor( 1.1067 + sn, url, NullableString(aTarget), false, nsCString(), false, &err); 1.1068 + 1.1069 + if (NPERR_NO_ERROR == err) { 1.1070 + // If NPN_PostURLNotify fails, the parent will immediately send us 1.1071 + // a PStreamNotifyDestructor, which should not call NPP_URLNotify. 1.1072 + sn->SetValid(aNotifyData); 1.1073 + } 1.1074 + 1.1075 + return err; 1.1076 +} 1.1077 + 1.1078 +NPError 1.1079 +_getvalue(NPP aNPP, 1.1080 + NPNVariable aVariable, 1.1081 + void* aValue) 1.1082 +{ 1.1083 + PLUGIN_LOG_DEBUG_FUNCTION; 1.1084 + ENSURE_PLUGIN_THREAD(NPERR_INVALID_PARAM); 1.1085 + 1.1086 + switch (aVariable) { 1.1087 + // Copied from nsNPAPIPlugin.cpp 1.1088 + case NPNVToolkit: 1.1089 +#if defined(MOZ_WIDGET_GTK) || defined(MOZ_WIDGET_QT) 1.1090 + *static_cast<NPNToolkitType*>(aValue) = NPNVGtk2; 1.1091 + return NPERR_NO_ERROR; 1.1092 +#endif 1.1093 + return NPERR_GENERIC_ERROR; 1.1094 + 1.1095 + case NPNVjavascriptEnabledBool: // Intentional fall-through 1.1096 + case NPNVasdEnabledBool: // Intentional fall-through 1.1097 + case NPNVisOfflineBool: // Intentional fall-through 1.1098 + case NPNVSupportsXEmbedBool: // Intentional fall-through 1.1099 + case NPNVSupportsWindowless: { // Intentional fall-through 1.1100 + NPError result; 1.1101 + bool value; 1.1102 + PluginModuleChild::current()-> 1.1103 + CallNPN_GetValue_WithBoolReturn(aVariable, &result, &value); 1.1104 + *(NPBool*)aValue = value ? true : false; 1.1105 + return result; 1.1106 + } 1.1107 +#if (MOZ_WIDGET_GTK == 2) 1.1108 + case NPNVxDisplay: { 1.1109 + if (aNPP) { 1.1110 + return InstCast(aNPP)->NPN_GetValue(aVariable, aValue); 1.1111 + } 1.1112 + else { 1.1113 + *(void **)aValue = xt_client_get_display(); 1.1114 + } 1.1115 + return NPERR_NO_ERROR; 1.1116 + } 1.1117 + case NPNVxtAppContext: 1.1118 + return NPERR_GENERIC_ERROR; 1.1119 +#endif 1.1120 + default: { 1.1121 + if (aNPP) { 1.1122 + return InstCast(aNPP)->NPN_GetValue(aVariable, aValue); 1.1123 + } 1.1124 + 1.1125 + NS_WARNING("Null NPP!"); 1.1126 + return NPERR_INVALID_INSTANCE_ERROR; 1.1127 + } 1.1128 + } 1.1129 + 1.1130 + NS_NOTREACHED("Shouldn't get here!"); 1.1131 + return NPERR_GENERIC_ERROR; 1.1132 +} 1.1133 + 1.1134 +NPError 1.1135 +_setvalue(NPP aNPP, 1.1136 + NPPVariable aVariable, 1.1137 + void* aValue) 1.1138 +{ 1.1139 + PLUGIN_LOG_DEBUG_FUNCTION; 1.1140 + ENSURE_PLUGIN_THREAD(NPERR_INVALID_PARAM); 1.1141 + return InstCast(aNPP)->NPN_SetValue(aVariable, aValue); 1.1142 +} 1.1143 + 1.1144 +NPError 1.1145 +_geturl(NPP aNPP, 1.1146 + const char* aRelativeURL, 1.1147 + const char* aTarget) 1.1148 +{ 1.1149 + PLUGIN_LOG_DEBUG_FUNCTION; 1.1150 + ENSURE_PLUGIN_THREAD(NPERR_INVALID_PARAM); 1.1151 + 1.1152 + NPError err; 1.1153 + InstCast(aNPP)->CallNPN_GetURL(NullableString(aRelativeURL), 1.1154 + NullableString(aTarget), &err); 1.1155 + return err; 1.1156 +} 1.1157 + 1.1158 +NPError 1.1159 +_posturlnotify(NPP aNPP, 1.1160 + const char* aRelativeURL, 1.1161 + const char* aTarget, 1.1162 + uint32_t aLength, 1.1163 + const char* aBuffer, 1.1164 + NPBool aIsFile, 1.1165 + void* aNotifyData) 1.1166 +{ 1.1167 + PLUGIN_LOG_DEBUG_FUNCTION; 1.1168 + ENSURE_PLUGIN_THREAD(NPERR_INVALID_PARAM); 1.1169 + 1.1170 + if (!aBuffer) 1.1171 + return NPERR_INVALID_PARAM; 1.1172 + 1.1173 + nsCString url = NullableString(aRelativeURL); 1.1174 + StreamNotifyChild* sn = new StreamNotifyChild(url); 1.1175 + 1.1176 + NPError err; 1.1177 + InstCast(aNPP)->CallPStreamNotifyConstructor( 1.1178 + sn, url, NullableString(aTarget), true, 1.1179 + nsCString(aBuffer, aLength), aIsFile, &err); 1.1180 + 1.1181 + if (NPERR_NO_ERROR == err) { 1.1182 + // If NPN_PostURLNotify fails, the parent will immediately send us 1.1183 + // a PStreamNotifyDestructor, which should not call NPP_URLNotify. 1.1184 + sn->SetValid(aNotifyData); 1.1185 + } 1.1186 + 1.1187 + return err; 1.1188 +} 1.1189 + 1.1190 +NPError 1.1191 +_posturl(NPP aNPP, 1.1192 + const char* aRelativeURL, 1.1193 + const char* aTarget, 1.1194 + uint32_t aLength, 1.1195 + const char* aBuffer, 1.1196 + NPBool aIsFile) 1.1197 +{ 1.1198 + PLUGIN_LOG_DEBUG_FUNCTION; 1.1199 + ENSURE_PLUGIN_THREAD(NPERR_INVALID_PARAM); 1.1200 + 1.1201 + NPError err; 1.1202 + // FIXME what should happen when |aBuffer| is null? 1.1203 + InstCast(aNPP)->CallNPN_PostURL(NullableString(aRelativeURL), 1.1204 + NullableString(aTarget), 1.1205 + nsDependentCString(aBuffer, aLength), 1.1206 + aIsFile, &err); 1.1207 + return err; 1.1208 +} 1.1209 + 1.1210 +NPError 1.1211 +_newstream(NPP aNPP, 1.1212 + NPMIMEType aMIMEType, 1.1213 + const char* aWindow, 1.1214 + NPStream** aStream) 1.1215 +{ 1.1216 + PLUGIN_LOG_DEBUG_FUNCTION; 1.1217 + ENSURE_PLUGIN_THREAD(NPERR_INVALID_PARAM); 1.1218 + return InstCast(aNPP)->NPN_NewStream(aMIMEType, aWindow, aStream); 1.1219 +} 1.1220 + 1.1221 +int32_t 1.1222 +_write(NPP aNPP, 1.1223 + NPStream* aStream, 1.1224 + int32_t aLength, 1.1225 + void* aBuffer) 1.1226 +{ 1.1227 + PLUGIN_LOG_DEBUG_FUNCTION; 1.1228 + ENSURE_PLUGIN_THREAD(0); 1.1229 + 1.1230 + PluginStreamChild* ps = 1.1231 + static_cast<PluginStreamChild*>(static_cast<AStream*>(aStream->ndata)); 1.1232 + ps->EnsureCorrectInstance(InstCast(aNPP)); 1.1233 + ps->EnsureCorrectStream(aStream); 1.1234 + return ps->NPN_Write(aLength, aBuffer); 1.1235 +} 1.1236 + 1.1237 +NPError 1.1238 +_destroystream(NPP aNPP, 1.1239 + NPStream* aStream, 1.1240 + NPError aReason) 1.1241 +{ 1.1242 + PLUGIN_LOG_DEBUG_FUNCTION; 1.1243 + ENSURE_PLUGIN_THREAD(NPERR_INVALID_PARAM); 1.1244 + 1.1245 + PluginInstanceChild* p = InstCast(aNPP); 1.1246 + AStream* s = static_cast<AStream*>(aStream->ndata); 1.1247 + if (s->IsBrowserStream()) { 1.1248 + BrowserStreamChild* bs = static_cast<BrowserStreamChild*>(s); 1.1249 + bs->EnsureCorrectInstance(p); 1.1250 + bs->NPN_DestroyStream(aReason); 1.1251 + } 1.1252 + else { 1.1253 + PluginStreamChild* ps = static_cast<PluginStreamChild*>(s); 1.1254 + ps->EnsureCorrectInstance(p); 1.1255 + PPluginStreamChild::Call__delete__(ps, aReason, false); 1.1256 + } 1.1257 + return NPERR_NO_ERROR; 1.1258 +} 1.1259 + 1.1260 +void 1.1261 +_status(NPP aNPP, 1.1262 + const char* aMessage) 1.1263 +{ 1.1264 + PLUGIN_LOG_DEBUG_FUNCTION; 1.1265 + ENSURE_PLUGIN_THREAD_VOID(); 1.1266 + NS_WARNING("Not yet implemented!"); 1.1267 +} 1.1268 + 1.1269 +void 1.1270 +_memfree(void* aPtr) 1.1271 +{ 1.1272 + PLUGIN_LOG_DEBUG_FUNCTION; 1.1273 + // Only assert plugin thread here for consistency with in-process plugins. 1.1274 + AssertPluginThread(); 1.1275 + NS_Free(aPtr); 1.1276 +} 1.1277 + 1.1278 +uint32_t 1.1279 +_memflush(uint32_t aSize) 1.1280 +{ 1.1281 + PLUGIN_LOG_DEBUG_FUNCTION; 1.1282 + // Only assert plugin thread here for consistency with in-process plugins. 1.1283 + AssertPluginThread(); 1.1284 + return 0; 1.1285 +} 1.1286 + 1.1287 +void 1.1288 +_reloadplugins(NPBool aReloadPages) 1.1289 +{ 1.1290 + PLUGIN_LOG_DEBUG_FUNCTION; 1.1291 + ENSURE_PLUGIN_THREAD_VOID(); 1.1292 + 1.1293 + PluginModuleChild::current()->SendNPN_ReloadPlugins(!!aReloadPages); 1.1294 +} 1.1295 + 1.1296 +void 1.1297 +_invalidaterect(NPP aNPP, 1.1298 + NPRect* aInvalidRect) 1.1299 +{ 1.1300 + PLUGIN_LOG_DEBUG_FUNCTION; 1.1301 + ENSURE_PLUGIN_THREAD_VOID(); 1.1302 + // nullptr check for nspluginwrapper (bug 548434) 1.1303 + if (aNPP) { 1.1304 + InstCast(aNPP)->InvalidateRect(aInvalidRect); 1.1305 + } 1.1306 +} 1.1307 + 1.1308 +void 1.1309 +_invalidateregion(NPP aNPP, 1.1310 + NPRegion aInvalidRegion) 1.1311 +{ 1.1312 + PLUGIN_LOG_DEBUG_FUNCTION; 1.1313 + ENSURE_PLUGIN_THREAD_VOID(); 1.1314 + NS_WARNING("Not yet implemented!"); 1.1315 +} 1.1316 + 1.1317 +void 1.1318 +_forceredraw(NPP aNPP) 1.1319 +{ 1.1320 + PLUGIN_LOG_DEBUG_FUNCTION; 1.1321 + ENSURE_PLUGIN_THREAD_VOID(); 1.1322 + 1.1323 + // We ignore calls to NPN_ForceRedraw. Such calls should 1.1324 + // never be necessary. 1.1325 +} 1.1326 + 1.1327 +const char* 1.1328 +_useragent(NPP aNPP) 1.1329 +{ 1.1330 + PLUGIN_LOG_DEBUG_FUNCTION; 1.1331 + ENSURE_PLUGIN_THREAD(nullptr); 1.1332 + return PluginModuleChild::current()->GetUserAgent(); 1.1333 +} 1.1334 + 1.1335 +void* 1.1336 +_memalloc(uint32_t aSize) 1.1337 +{ 1.1338 + PLUGIN_LOG_DEBUG_FUNCTION; 1.1339 + // Only assert plugin thread here for consistency with in-process plugins. 1.1340 + AssertPluginThread(); 1.1341 + return NS_Alloc(aSize); 1.1342 +} 1.1343 + 1.1344 +// Deprecated entry points for the old Java plugin. 1.1345 +void* /* OJI type: JRIEnv* */ 1.1346 +_getjavaenv(void) 1.1347 +{ 1.1348 + PLUGIN_LOG_DEBUG_FUNCTION; 1.1349 + return 0; 1.1350 +} 1.1351 + 1.1352 +void* /* OJI type: jref */ 1.1353 +_getjavapeer(NPP aNPP) 1.1354 +{ 1.1355 + PLUGIN_LOG_DEBUG_FUNCTION; 1.1356 + return 0; 1.1357 +} 1.1358 + 1.1359 +bool 1.1360 +_invoke(NPP aNPP, 1.1361 + NPObject* aNPObj, 1.1362 + NPIdentifier aMethod, 1.1363 + const NPVariant* aArgs, 1.1364 + uint32_t aArgCount, 1.1365 + NPVariant* aResult) 1.1366 +{ 1.1367 + PLUGIN_LOG_DEBUG_FUNCTION; 1.1368 + ENSURE_PLUGIN_THREAD(false); 1.1369 + 1.1370 + if (!aNPP || !aNPObj || !aNPObj->_class || !aNPObj->_class->invoke) 1.1371 + return false; 1.1372 + 1.1373 + return aNPObj->_class->invoke(aNPObj, aMethod, aArgs, aArgCount, aResult); 1.1374 +} 1.1375 + 1.1376 +bool 1.1377 +_invokedefault(NPP aNPP, 1.1378 + NPObject* aNPObj, 1.1379 + const NPVariant* aArgs, 1.1380 + uint32_t aArgCount, 1.1381 + NPVariant* aResult) 1.1382 +{ 1.1383 + PLUGIN_LOG_DEBUG_FUNCTION; 1.1384 + ENSURE_PLUGIN_THREAD(false); 1.1385 + 1.1386 + if (!aNPP || !aNPObj || !aNPObj->_class || !aNPObj->_class->invokeDefault) 1.1387 + return false; 1.1388 + 1.1389 + return aNPObj->_class->invokeDefault(aNPObj, aArgs, aArgCount, aResult); 1.1390 +} 1.1391 + 1.1392 +bool 1.1393 +_evaluate(NPP aNPP, 1.1394 + NPObject* aObject, 1.1395 + NPString* aScript, 1.1396 + NPVariant* aResult) 1.1397 +{ 1.1398 + PLUGIN_LOG_DEBUG_FUNCTION; 1.1399 + ENSURE_PLUGIN_THREAD(false); 1.1400 + 1.1401 + if (!(aNPP && aObject && aScript && aResult)) { 1.1402 + NS_ERROR("Bad arguments!"); 1.1403 + return false; 1.1404 + } 1.1405 + 1.1406 + PluginScriptableObjectChild* actor = 1.1407 + InstCast(aNPP)->GetActorForNPObject(aObject); 1.1408 + if (!actor) { 1.1409 + NS_ERROR("Failed to create actor?!"); 1.1410 + return false; 1.1411 + } 1.1412 + 1.1413 +#ifdef XP_WIN 1.1414 + if (gDelayFlashFocusReplyUntilEval) { 1.1415 + ReplyMessage(0); 1.1416 + gDelayFlashFocusReplyUntilEval = false; 1.1417 + } 1.1418 +#endif 1.1419 + 1.1420 + return actor->Evaluate(aScript, aResult); 1.1421 +} 1.1422 + 1.1423 +bool 1.1424 +_getproperty(NPP aNPP, 1.1425 + NPObject* aNPObj, 1.1426 + NPIdentifier aPropertyName, 1.1427 + NPVariant* aResult) 1.1428 +{ 1.1429 + PLUGIN_LOG_DEBUG_FUNCTION; 1.1430 + ENSURE_PLUGIN_THREAD(false); 1.1431 + 1.1432 + if (!aNPP || !aNPObj || !aNPObj->_class || !aNPObj->_class->getProperty) 1.1433 + return false; 1.1434 + 1.1435 + return aNPObj->_class->getProperty(aNPObj, aPropertyName, aResult); 1.1436 +} 1.1437 + 1.1438 +bool 1.1439 +_setproperty(NPP aNPP, 1.1440 + NPObject* aNPObj, 1.1441 + NPIdentifier aPropertyName, 1.1442 + const NPVariant* aValue) 1.1443 +{ 1.1444 + PLUGIN_LOG_DEBUG_FUNCTION; 1.1445 + ENSURE_PLUGIN_THREAD(false); 1.1446 + 1.1447 + if (!aNPP || !aNPObj || !aNPObj->_class || !aNPObj->_class->setProperty) 1.1448 + return false; 1.1449 + 1.1450 + return aNPObj->_class->setProperty(aNPObj, aPropertyName, aValue); 1.1451 +} 1.1452 + 1.1453 +bool 1.1454 +_removeproperty(NPP aNPP, 1.1455 + NPObject* aNPObj, 1.1456 + NPIdentifier aPropertyName) 1.1457 +{ 1.1458 + PLUGIN_LOG_DEBUG_FUNCTION; 1.1459 + ENSURE_PLUGIN_THREAD(false); 1.1460 + 1.1461 + if (!aNPP || !aNPObj || !aNPObj->_class || !aNPObj->_class->removeProperty) 1.1462 + return false; 1.1463 + 1.1464 + return aNPObj->_class->removeProperty(aNPObj, aPropertyName); 1.1465 +} 1.1466 + 1.1467 +bool 1.1468 +_hasproperty(NPP aNPP, 1.1469 + NPObject* aNPObj, 1.1470 + NPIdentifier aPropertyName) 1.1471 +{ 1.1472 + PLUGIN_LOG_DEBUG_FUNCTION; 1.1473 + ENSURE_PLUGIN_THREAD(false); 1.1474 + 1.1475 + if (!aNPP || !aNPObj || !aNPObj->_class || !aNPObj->_class->hasProperty) 1.1476 + return false; 1.1477 + 1.1478 + return aNPObj->_class->hasProperty(aNPObj, aPropertyName); 1.1479 +} 1.1480 + 1.1481 +bool 1.1482 +_hasmethod(NPP aNPP, 1.1483 + NPObject* aNPObj, 1.1484 + NPIdentifier aMethodName) 1.1485 +{ 1.1486 + PLUGIN_LOG_DEBUG_FUNCTION; 1.1487 + ENSURE_PLUGIN_THREAD(false); 1.1488 + 1.1489 + if (!aNPP || !aNPObj || !aNPObj->_class || !aNPObj->_class->hasMethod) 1.1490 + return false; 1.1491 + 1.1492 + return aNPObj->_class->hasMethod(aNPObj, aMethodName); 1.1493 +} 1.1494 + 1.1495 +bool 1.1496 +_enumerate(NPP aNPP, 1.1497 + NPObject* aNPObj, 1.1498 + NPIdentifier** aIdentifiers, 1.1499 + uint32_t* aCount) 1.1500 +{ 1.1501 + PLUGIN_LOG_DEBUG_FUNCTION; 1.1502 + ENSURE_PLUGIN_THREAD(false); 1.1503 + 1.1504 + if (!aNPP || !aNPObj || !aNPObj->_class) 1.1505 + return false; 1.1506 + 1.1507 + if (!NP_CLASS_STRUCT_VERSION_HAS_ENUM(aNPObj->_class) || 1.1508 + !aNPObj->_class->enumerate) { 1.1509 + *aIdentifiers = 0; 1.1510 + *aCount = 0; 1.1511 + return true; 1.1512 + } 1.1513 + 1.1514 + return aNPObj->_class->enumerate(aNPObj, aIdentifiers, aCount); 1.1515 +} 1.1516 + 1.1517 +bool 1.1518 +_construct(NPP aNPP, 1.1519 + NPObject* aNPObj, 1.1520 + const NPVariant* aArgs, 1.1521 + uint32_t aArgCount, 1.1522 + NPVariant* aResult) 1.1523 +{ 1.1524 + PLUGIN_LOG_DEBUG_FUNCTION; 1.1525 + ENSURE_PLUGIN_THREAD(false); 1.1526 + 1.1527 + if (!aNPP || !aNPObj || !aNPObj->_class || 1.1528 + !NP_CLASS_STRUCT_VERSION_HAS_CTOR(aNPObj->_class) || 1.1529 + !aNPObj->_class->construct) { 1.1530 + return false; 1.1531 + } 1.1532 + 1.1533 + return aNPObj->_class->construct(aNPObj, aArgs, aArgCount, aResult); 1.1534 +} 1.1535 + 1.1536 +void 1.1537 +_releasevariantvalue(NPVariant* aVariant) 1.1538 +{ 1.1539 + PLUGIN_LOG_DEBUG_FUNCTION; 1.1540 + // Only assert plugin thread here for consistency with in-process plugins. 1.1541 + AssertPluginThread(); 1.1542 + 1.1543 + if (NPVARIANT_IS_STRING(*aVariant)) { 1.1544 + NPString str = NPVARIANT_TO_STRING(*aVariant); 1.1545 + free(const_cast<NPUTF8*>(str.UTF8Characters)); 1.1546 + } 1.1547 + else if (NPVARIANT_IS_OBJECT(*aVariant)) { 1.1548 + NPObject* object = NPVARIANT_TO_OBJECT(*aVariant); 1.1549 + if (object) { 1.1550 + PluginModuleChild::NPN_ReleaseObject(object); 1.1551 + } 1.1552 + } 1.1553 + VOID_TO_NPVARIANT(*aVariant); 1.1554 +} 1.1555 + 1.1556 +void 1.1557 +_setexception(NPObject* aNPObj, 1.1558 + const NPUTF8* aMessage) 1.1559 +{ 1.1560 + PLUGIN_LOG_DEBUG_FUNCTION; 1.1561 + ENSURE_PLUGIN_THREAD_VOID(); 1.1562 + 1.1563 + PluginModuleChild* self = PluginModuleChild::current(); 1.1564 + PluginScriptableObjectChild* actor = nullptr; 1.1565 + if (aNPObj) { 1.1566 + actor = self->GetActorForNPObject(aNPObj); 1.1567 + if (!actor) { 1.1568 + NS_ERROR("Failed to get actor!"); 1.1569 + return; 1.1570 + } 1.1571 + } 1.1572 + 1.1573 + self->SendNPN_SetException(static_cast<PPluginScriptableObjectChild*>(actor), 1.1574 + NullableString(aMessage)); 1.1575 +} 1.1576 + 1.1577 +void 1.1578 +_pushpopupsenabledstate(NPP aNPP, 1.1579 + NPBool aEnabled) 1.1580 +{ 1.1581 + PLUGIN_LOG_DEBUG_FUNCTION; 1.1582 + ENSURE_PLUGIN_THREAD_VOID(); 1.1583 + 1.1584 + InstCast(aNPP)->CallNPN_PushPopupsEnabledState(aEnabled ? true : false); 1.1585 +} 1.1586 + 1.1587 +void 1.1588 +_poppopupsenabledstate(NPP aNPP) 1.1589 +{ 1.1590 + PLUGIN_LOG_DEBUG_FUNCTION; 1.1591 + ENSURE_PLUGIN_THREAD_VOID(); 1.1592 + 1.1593 + InstCast(aNPP)->CallNPN_PopPopupsEnabledState(); 1.1594 +} 1.1595 + 1.1596 +void 1.1597 +_pluginthreadasynccall(NPP aNPP, 1.1598 + PluginThreadCallback aFunc, 1.1599 + void* aUserData) 1.1600 +{ 1.1601 + PLUGIN_LOG_DEBUG_FUNCTION; 1.1602 + if (!aFunc) 1.1603 + return; 1.1604 + 1.1605 + InstCast(aNPP)->AsyncCall(aFunc, aUserData); 1.1606 +} 1.1607 + 1.1608 +NPError 1.1609 +_getvalueforurl(NPP npp, NPNURLVariable variable, const char *url, 1.1610 + char **value, uint32_t *len) 1.1611 +{ 1.1612 + PLUGIN_LOG_DEBUG_FUNCTION; 1.1613 + AssertPluginThread(); 1.1614 + 1.1615 + if (!url) 1.1616 + return NPERR_INVALID_URL; 1.1617 + 1.1618 + if (!npp || !value || !len) 1.1619 + return NPERR_INVALID_PARAM; 1.1620 + 1.1621 + switch (variable) { 1.1622 + case NPNURLVCookie: 1.1623 + case NPNURLVProxy: 1.1624 + nsCString v; 1.1625 + NPError result; 1.1626 + InstCast(npp)-> 1.1627 + CallNPN_GetValueForURL(variable, nsCString(url), &v, &result); 1.1628 + if (NPERR_NO_ERROR == result) { 1.1629 + *value = ToNewCString(v); 1.1630 + *len = v.Length(); 1.1631 + } 1.1632 + return result; 1.1633 + } 1.1634 + 1.1635 + return NPERR_INVALID_PARAM; 1.1636 +} 1.1637 + 1.1638 +NPError 1.1639 +_setvalueforurl(NPP npp, NPNURLVariable variable, const char *url, 1.1640 + const char *value, uint32_t len) 1.1641 +{ 1.1642 + PLUGIN_LOG_DEBUG_FUNCTION; 1.1643 + AssertPluginThread(); 1.1644 + 1.1645 + if (!value) 1.1646 + return NPERR_INVALID_PARAM; 1.1647 + 1.1648 + if (!url) 1.1649 + return NPERR_INVALID_URL; 1.1650 + 1.1651 + switch (variable) { 1.1652 + case NPNURLVCookie: 1.1653 + case NPNURLVProxy: 1.1654 + NPError result; 1.1655 + InstCast(npp)->CallNPN_SetValueForURL(variable, nsCString(url), 1.1656 + nsDependentCString(value, len), 1.1657 + &result); 1.1658 + return result; 1.1659 + } 1.1660 + 1.1661 + return NPERR_INVALID_PARAM; 1.1662 +} 1.1663 + 1.1664 +NPError 1.1665 +_getauthenticationinfo(NPP npp, const char *protocol, 1.1666 + const char *host, int32_t port, 1.1667 + const char *scheme, const char *realm, 1.1668 + char **username, uint32_t *ulen, 1.1669 + char **password, uint32_t *plen) 1.1670 +{ 1.1671 + PLUGIN_LOG_DEBUG_FUNCTION; 1.1672 + AssertPluginThread(); 1.1673 + 1.1674 + if (!protocol || !host || !scheme || !realm || !username || !ulen || 1.1675 + !password || !plen) 1.1676 + return NPERR_INVALID_PARAM; 1.1677 + 1.1678 + nsCString u; 1.1679 + nsCString p; 1.1680 + NPError result; 1.1681 + InstCast(npp)-> 1.1682 + CallNPN_GetAuthenticationInfo(nsDependentCString(protocol), 1.1683 + nsDependentCString(host), 1.1684 + port, 1.1685 + nsDependentCString(scheme), 1.1686 + nsDependentCString(realm), 1.1687 + &u, &p, &result); 1.1688 + if (NPERR_NO_ERROR == result) { 1.1689 + *username = ToNewCString(u); 1.1690 + *ulen = u.Length(); 1.1691 + *password = ToNewCString(p); 1.1692 + *plen = p.Length(); 1.1693 + } 1.1694 + return result; 1.1695 +} 1.1696 + 1.1697 +uint32_t 1.1698 +_scheduletimer(NPP npp, uint32_t interval, NPBool repeat, 1.1699 + void (*timerFunc)(NPP npp, uint32_t timerID)) 1.1700 +{ 1.1701 + PLUGIN_LOG_DEBUG_FUNCTION; 1.1702 + AssertPluginThread(); 1.1703 + return InstCast(npp)->ScheduleTimer(interval, repeat, timerFunc); 1.1704 +} 1.1705 + 1.1706 +void 1.1707 +_unscheduletimer(NPP npp, uint32_t timerID) 1.1708 +{ 1.1709 + PLUGIN_LOG_DEBUG_FUNCTION; 1.1710 + AssertPluginThread(); 1.1711 + InstCast(npp)->UnscheduleTimer(timerID); 1.1712 +} 1.1713 + 1.1714 + 1.1715 +#ifdef OS_MACOSX 1.1716 +static void ProcessBrowserEvents(void* pluginModule) { 1.1717 + PluginModuleChild* pmc = static_cast<PluginModuleChild*>(pluginModule); 1.1718 + 1.1719 + if (!pmc) 1.1720 + return; 1.1721 + 1.1722 + pmc->CallProcessSomeEvents(); 1.1723 +} 1.1724 +#endif 1.1725 + 1.1726 +NPError 1.1727 +_popupcontextmenu(NPP instance, NPMenu* menu) 1.1728 +{ 1.1729 + PLUGIN_LOG_DEBUG_FUNCTION; 1.1730 + AssertPluginThread(); 1.1731 + 1.1732 +#ifdef MOZ_WIDGET_COCOA 1.1733 + double pluginX, pluginY; 1.1734 + double screenX, screenY; 1.1735 + 1.1736 + const NPCocoaEvent* currentEvent = InstCast(instance)->getCurrentEvent(); 1.1737 + if (!currentEvent) { 1.1738 + return NPERR_GENERIC_ERROR; 1.1739 + } 1.1740 + 1.1741 + // Ensure that the events has an x/y value. 1.1742 + if (currentEvent->type != NPCocoaEventMouseDown && 1.1743 + currentEvent->type != NPCocoaEventMouseUp && 1.1744 + currentEvent->type != NPCocoaEventMouseMoved && 1.1745 + currentEvent->type != NPCocoaEventMouseEntered && 1.1746 + currentEvent->type != NPCocoaEventMouseExited && 1.1747 + currentEvent->type != NPCocoaEventMouseDragged) { 1.1748 + return NPERR_GENERIC_ERROR; 1.1749 + } 1.1750 + 1.1751 + pluginX = currentEvent->data.mouse.pluginX; 1.1752 + pluginY = currentEvent->data.mouse.pluginY; 1.1753 + 1.1754 + if ((pluginX < 0.0) || (pluginY < 0.0)) 1.1755 + return NPERR_GENERIC_ERROR; 1.1756 + 1.1757 + NPBool success = _convertpoint(instance, 1.1758 + pluginX, pluginY, NPCoordinateSpacePlugin, 1.1759 + &screenX, &screenY, NPCoordinateSpaceScreen); 1.1760 + 1.1761 + if (success) { 1.1762 + return mozilla::plugins::PluginUtilsOSX::ShowCocoaContextMenu(menu, 1.1763 + screenX, screenY, 1.1764 + PluginModuleChild::current(), 1.1765 + ProcessBrowserEvents); 1.1766 + } else { 1.1767 + NS_WARNING("Convertpoint failed, could not created contextmenu."); 1.1768 + return NPERR_GENERIC_ERROR; 1.1769 + } 1.1770 + 1.1771 +#else 1.1772 + NS_WARNING("Not supported on this platform!"); 1.1773 + return NPERR_GENERIC_ERROR; 1.1774 +#endif 1.1775 +} 1.1776 + 1.1777 +NPBool 1.1778 +_convertpoint(NPP instance, 1.1779 + double sourceX, double sourceY, NPCoordinateSpace sourceSpace, 1.1780 + double *destX, double *destY, NPCoordinateSpace destSpace) 1.1781 +{ 1.1782 + PLUGIN_LOG_DEBUG_FUNCTION; 1.1783 + if (!IsPluginThread()) { 1.1784 + NS_WARNING("Not running on the plugin's main thread!"); 1.1785 + return false; 1.1786 + } 1.1787 + 1.1788 + double rDestX = 0; 1.1789 + bool ignoreDestX = !destX; 1.1790 + double rDestY = 0; 1.1791 + bool ignoreDestY = !destY; 1.1792 + bool result = false; 1.1793 + InstCast(instance)->CallNPN_ConvertPoint(sourceX, ignoreDestX, sourceY, ignoreDestY, sourceSpace, destSpace, 1.1794 + &rDestX, &rDestY, &result); 1.1795 + if (result) { 1.1796 + if (destX) 1.1797 + *destX = rDestX; 1.1798 + if (destY) 1.1799 + *destY = rDestY; 1.1800 + } 1.1801 + 1.1802 + return result; 1.1803 +} 1.1804 + 1.1805 +void 1.1806 +_urlredirectresponse(NPP instance, void* notifyData, NPBool allow) 1.1807 +{ 1.1808 + InstCast(instance)->NPN_URLRedirectResponse(notifyData, allow); 1.1809 +} 1.1810 + 1.1811 +NPError 1.1812 +_initasyncsurface(NPP instance, NPSize *size, 1.1813 + NPImageFormat format, void *initData, 1.1814 + NPAsyncSurface *surface) 1.1815 +{ 1.1816 + return InstCast(instance)->NPN_InitAsyncSurface(size, format, initData, surface); 1.1817 +} 1.1818 + 1.1819 +NPError 1.1820 +_finalizeasyncsurface(NPP instance, NPAsyncSurface *surface) 1.1821 +{ 1.1822 + return InstCast(instance)->NPN_FinalizeAsyncSurface(surface); 1.1823 +} 1.1824 + 1.1825 +void 1.1826 +_setcurrentasyncsurface(NPP instance, NPAsyncSurface *surface, NPRect *changed) 1.1827 +{ 1.1828 + InstCast(instance)->NPN_SetCurrentAsyncSurface(surface, changed); 1.1829 +} 1.1830 + 1.1831 +} /* namespace child */ 1.1832 +} /* namespace plugins */ 1.1833 +} /* namespace mozilla */ 1.1834 + 1.1835 +//----------------------------------------------------------------------------- 1.1836 + 1.1837 +bool 1.1838 +PluginModuleChild::AnswerNP_GetEntryPoints(NPError* _retval) 1.1839 +{ 1.1840 + PLUGIN_LOG_DEBUG_METHOD; 1.1841 + AssertPluginThread(); 1.1842 + 1.1843 +#if defined(OS_LINUX) || defined(OS_BSD) 1.1844 + return true; 1.1845 +#elif defined(OS_WIN) || defined(OS_MACOSX) 1.1846 + *_retval = mGetEntryPointsFunc(&mFunctions); 1.1847 + return true; 1.1848 +#else 1.1849 +# error Please implement me for your platform 1.1850 +#endif 1.1851 +} 1.1852 + 1.1853 +bool 1.1854 +PluginModuleChild::AnswerNP_Initialize(const uint32_t& aFlags, NPError* _retval) 1.1855 +{ 1.1856 + PLUGIN_LOG_DEBUG_METHOD; 1.1857 + AssertPluginThread(); 1.1858 + 1.1859 + mAsyncDrawingAllowed = aFlags & kAllowAsyncDrawing; 1.1860 + 1.1861 +#ifdef OS_WIN 1.1862 + SetEventHooks(); 1.1863 +#endif 1.1864 + 1.1865 +#ifdef MOZ_X11 1.1866 + // Send the parent our X socket to act as a proxy reference for our X 1.1867 + // resources. 1.1868 + int xSocketFd = ConnectionNumber(DefaultXDisplay()); 1.1869 + SendBackUpXResources(FileDescriptor(xSocketFd)); 1.1870 +#endif 1.1871 + 1.1872 +#if defined(OS_LINUX) || defined(OS_BSD) 1.1873 + *_retval = mInitializeFunc(&sBrowserFuncs, &mFunctions); 1.1874 + return true; 1.1875 +#elif defined(OS_WIN) || defined(OS_MACOSX) 1.1876 + *_retval = mInitializeFunc(&sBrowserFuncs); 1.1877 + return true; 1.1878 +#else 1.1879 +# error Please implement me for your platform 1.1880 +#endif 1.1881 +} 1.1882 + 1.1883 +PPluginIdentifierChild* 1.1884 +PluginModuleChild::AllocPPluginIdentifierChild(const nsCString& aString, 1.1885 + const int32_t& aInt, 1.1886 + const bool& aTemporary) 1.1887 +{ 1.1888 + // We cannot call SetPermanent within this function because Manager() isn't 1.1889 + // set up yet. 1.1890 + if (aString.IsVoid()) { 1.1891 + return new PluginIdentifierChildInt(aInt); 1.1892 + } 1.1893 + return new PluginIdentifierChildString(aString); 1.1894 +} 1.1895 + 1.1896 +bool 1.1897 +PluginModuleChild::RecvPPluginIdentifierConstructor(PPluginIdentifierChild* actor, 1.1898 + const nsCString& aString, 1.1899 + const int32_t& aInt, 1.1900 + const bool& aTemporary) 1.1901 +{ 1.1902 + if (!aTemporary) { 1.1903 + static_cast<PluginIdentifierChild*>(actor)->MakePermanent(); 1.1904 + } 1.1905 + return true; 1.1906 +} 1.1907 + 1.1908 +bool 1.1909 +PluginModuleChild::DeallocPPluginIdentifierChild(PPluginIdentifierChild* aActor) 1.1910 +{ 1.1911 + delete aActor; 1.1912 + return true; 1.1913 +} 1.1914 + 1.1915 +#if defined(XP_WIN) 1.1916 +BOOL WINAPI 1.1917 +PMCGetWindowInfoHook(HWND hWnd, PWINDOWINFO pwi) 1.1918 +{ 1.1919 + if (!pwi) 1.1920 + return FALSE; 1.1921 + 1.1922 + if (!sGetWindowInfoPtrStub) { 1.1923 + NS_ASSERTION(FALSE, "Something is horribly wrong in PMCGetWindowInfoHook!"); 1.1924 + return FALSE; 1.1925 + } 1.1926 + 1.1927 + if (!sBrowserHwnd) { 1.1928 + wchar_t szClass[20]; 1.1929 + if (GetClassNameW(hWnd, szClass, ArrayLength(szClass)) && 1.1930 + !wcscmp(szClass, kMozillaWindowClass)) { 1.1931 + sBrowserHwnd = hWnd; 1.1932 + } 1.1933 + } 1.1934 + // Oddity: flash does strange rect comparisons for mouse input destined for 1.1935 + // it's internal settings window. Post removing sub widgets for tabs, touch 1.1936 + // this up so they get the rect they expect. 1.1937 + // XXX potentially tie this to a specific major version? 1.1938 + BOOL result = sGetWindowInfoPtrStub(hWnd, pwi); 1.1939 + if (sBrowserHwnd && sBrowserHwnd == hWnd) 1.1940 + pwi->rcWindow = pwi->rcClient; 1.1941 + return result; 1.1942 +} 1.1943 +#endif 1.1944 + 1.1945 +PPluginInstanceChild* 1.1946 +PluginModuleChild::AllocPPluginInstanceChild(const nsCString& aMimeType, 1.1947 + const uint16_t& aMode, 1.1948 + const InfallibleTArray<nsCString>& aNames, 1.1949 + const InfallibleTArray<nsCString>& aValues, 1.1950 + NPError* rv) 1.1951 +{ 1.1952 + PLUGIN_LOG_DEBUG_METHOD; 1.1953 + AssertPluginThread(); 1.1954 + 1.1955 + InitQuirksModes(aMimeType); 1.1956 + 1.1957 +#ifdef XP_WIN 1.1958 + if ((mQuirks & QUIRK_FLASH_HOOK_GETWINDOWINFO) && 1.1959 + !sGetWindowInfoPtrStub) { 1.1960 + sUser32Intercept.Init("user32.dll"); 1.1961 + sUser32Intercept.AddHook("GetWindowInfo", reinterpret_cast<intptr_t>(PMCGetWindowInfoHook), 1.1962 + (void**) &sGetWindowInfoPtrStub); 1.1963 + } 1.1964 +#endif 1.1965 + 1.1966 + return new PluginInstanceChild(&mFunctions); 1.1967 +} 1.1968 + 1.1969 +void 1.1970 +PluginModuleChild::InitQuirksModes(const nsCString& aMimeType) 1.1971 +{ 1.1972 + if (mQuirks != QUIRKS_NOT_INITIALIZED) 1.1973 + return; 1.1974 + mQuirks = 0; 1.1975 + // application/x-silverlight 1.1976 + // application/x-silverlight-2 1.1977 + NS_NAMED_LITERAL_CSTRING(silverlight, "application/x-silverlight"); 1.1978 + if (FindInReadable(silverlight, aMimeType)) { 1.1979 + mQuirks |= QUIRK_SILVERLIGHT_DEFAULT_TRANSPARENT; 1.1980 +#ifdef OS_WIN 1.1981 + mQuirks |= QUIRK_WINLESS_TRACKPOPUP_HOOK; 1.1982 + mQuirks |= QUIRK_SILVERLIGHT_FOCUS_CHECK_PARENT; 1.1983 +#endif 1.1984 + } 1.1985 + 1.1986 +#ifdef OS_WIN 1.1987 + // application/x-shockwave-flash 1.1988 + NS_NAMED_LITERAL_CSTRING(flash, "application/x-shockwave-flash"); 1.1989 + if (FindInReadable(flash, aMimeType)) { 1.1990 + mQuirks |= QUIRK_WINLESS_TRACKPOPUP_HOOK; 1.1991 + mQuirks |= QUIRK_FLASH_THROTTLE_WMUSER_EVENTS; 1.1992 + mQuirks |= QUIRK_FLASH_HOOK_SETLONGPTR; 1.1993 + mQuirks |= QUIRK_FLASH_HOOK_GETWINDOWINFO; 1.1994 + mQuirks |= QUIRK_FLASH_FIXUP_MOUSE_CAPTURE; 1.1995 + } 1.1996 + 1.1997 + // QuickTime plugin usually loaded with audio/mpeg mimetype 1.1998 + NS_NAMED_LITERAL_CSTRING(quicktime, "npqtplugin"); 1.1999 + if (FindInReadable(quicktime, mPluginFilename)) { 1.2000 + mQuirks |= QUIRK_QUICKTIME_AVOID_SETWINDOW; 1.2001 + } 1.2002 +#endif 1.2003 + 1.2004 +#ifdef XP_MACOSX 1.2005 + // Whitelist Flash and Quicktime to support offline renderer 1.2006 + NS_NAMED_LITERAL_CSTRING(flash, "application/x-shockwave-flash"); 1.2007 + NS_NAMED_LITERAL_CSTRING(quicktime, "QuickTime Plugin.plugin"); 1.2008 + if (FindInReadable(flash, aMimeType)) { 1.2009 + mQuirks |= QUIRK_FLASH_AVOID_CGMODE_CRASHES; 1.2010 + } 1.2011 + if (FindInReadable(flash, aMimeType) || 1.2012 + FindInReadable(quicktime, mPluginFilename)) { 1.2013 + mQuirks |= QUIRK_ALLOW_OFFLINE_RENDERER; 1.2014 + } 1.2015 +#endif 1.2016 +} 1.2017 + 1.2018 +bool 1.2019 +PluginModuleChild::AnswerPPluginInstanceConstructor(PPluginInstanceChild* aActor, 1.2020 + const nsCString& aMimeType, 1.2021 + const uint16_t& aMode, 1.2022 + const InfallibleTArray<nsCString>& aNames, 1.2023 + const InfallibleTArray<nsCString>& aValues, 1.2024 + NPError* rv) 1.2025 +{ 1.2026 + PLUGIN_LOG_DEBUG_METHOD; 1.2027 + AssertPluginThread(); 1.2028 + 1.2029 + PluginInstanceChild* childInstance = 1.2030 + reinterpret_cast<PluginInstanceChild*>(aActor); 1.2031 + NS_ASSERTION(childInstance, "Null actor!"); 1.2032 + 1.2033 + // unpack the arguments into a C format 1.2034 + int argc = aNames.Length(); 1.2035 + NS_ASSERTION(argc == (int) aValues.Length(), 1.2036 + "argn.length != argv.length"); 1.2037 + 1.2038 + nsAutoArrayPtr<char*> argn(new char*[1 + argc]); 1.2039 + nsAutoArrayPtr<char*> argv(new char*[1 + argc]); 1.2040 + argn[argc] = 0; 1.2041 + argv[argc] = 0; 1.2042 + 1.2043 + for (int i = 0; i < argc; ++i) { 1.2044 + argn[i] = const_cast<char*>(NullableStringGet(aNames[i])); 1.2045 + argv[i] = const_cast<char*>(NullableStringGet(aValues[i])); 1.2046 + } 1.2047 + 1.2048 + NPP npp = childInstance->GetNPP(); 1.2049 + 1.2050 + // FIXME/cjones: use SAFE_CALL stuff 1.2051 + *rv = mFunctions.newp((char*)NullableStringGet(aMimeType), 1.2052 + npp, 1.2053 + aMode, 1.2054 + argc, 1.2055 + argn, 1.2056 + argv, 1.2057 + 0); 1.2058 + if (NPERR_NO_ERROR != *rv) { 1.2059 + return true; 1.2060 + } 1.2061 + 1.2062 + childInstance->Initialize(); 1.2063 + 1.2064 +#if defined(XP_MACOSX) && defined(__i386__) 1.2065 + // If an i386 Mac OS X plugin has selected the Carbon event model then 1.2066 + // we have to fail. We do not support putting Carbon event model plugins 1.2067 + // out of process. Note that Carbon is the default model so out of process 1.2068 + // plugins need to actively negotiate something else in order to work 1.2069 + // out of process. 1.2070 + if (childInstance->EventModel() == NPEventModelCarbon) { 1.2071 + // Send notification that a plugin tried to negotiate Carbon NPAPI so that 1.2072 + // users can be notified that restarting the browser in i386 mode may allow 1.2073 + // them to use the plugin. 1.2074 + childInstance->SendNegotiatedCarbon(); 1.2075 + 1.2076 + // Fail to instantiate. 1.2077 + *rv = NPERR_MODULE_LOAD_FAILED_ERROR; 1.2078 + } 1.2079 +#endif 1.2080 + 1.2081 + return true; 1.2082 +} 1.2083 + 1.2084 +bool 1.2085 +PluginModuleChild::DeallocPPluginInstanceChild(PPluginInstanceChild* aActor) 1.2086 +{ 1.2087 + PLUGIN_LOG_DEBUG_METHOD; 1.2088 + AssertPluginThread(); 1.2089 + 1.2090 + delete aActor; 1.2091 + 1.2092 + return true; 1.2093 +} 1.2094 + 1.2095 +NPObject* 1.2096 +PluginModuleChild::NPN_CreateObject(NPP aNPP, NPClass* aClass) 1.2097 +{ 1.2098 + PLUGIN_LOG_DEBUG_FUNCTION; 1.2099 + ENSURE_PLUGIN_THREAD(nullptr); 1.2100 + 1.2101 + PluginInstanceChild* i = InstCast(aNPP); 1.2102 + if (i->mDeletingHash) { 1.2103 + NS_ERROR("Plugin used NPP after NPP_Destroy"); 1.2104 + return nullptr; 1.2105 + } 1.2106 + 1.2107 + NPObject* newObject; 1.2108 + if (aClass && aClass->allocate) { 1.2109 + newObject = aClass->allocate(aNPP, aClass); 1.2110 + } 1.2111 + else { 1.2112 + newObject = reinterpret_cast<NPObject*>(child::_memalloc(sizeof(NPObject))); 1.2113 + } 1.2114 + 1.2115 + if (newObject) { 1.2116 + newObject->_class = aClass; 1.2117 + newObject->referenceCount = 1; 1.2118 + NS_LOG_ADDREF(newObject, 1, "NPObject", sizeof(NPObject)); 1.2119 + } 1.2120 + 1.2121 + NPObjectData* d = static_cast<PluginModuleChild*>(i->Manager()) 1.2122 + ->mObjectMap.PutEntry(newObject); 1.2123 + NS_ASSERTION(!d->instance, "New NPObject already mapped?"); 1.2124 + d->instance = i; 1.2125 + 1.2126 + return newObject; 1.2127 +} 1.2128 + 1.2129 +NPObject* 1.2130 +PluginModuleChild::NPN_RetainObject(NPObject* aNPObj) 1.2131 +{ 1.2132 + AssertPluginThread(); 1.2133 + 1.2134 +#ifdef NS_BUILD_REFCNT_LOGGING 1.2135 + int32_t refCnt = 1.2136 +#endif 1.2137 + PR_ATOMIC_INCREMENT((int32_t*)&aNPObj->referenceCount); 1.2138 + NS_LOG_ADDREF(aNPObj, refCnt, "NPObject", sizeof(NPObject)); 1.2139 + 1.2140 + return aNPObj; 1.2141 +} 1.2142 + 1.2143 +void 1.2144 +PluginModuleChild::NPN_ReleaseObject(NPObject* aNPObj) 1.2145 +{ 1.2146 + AssertPluginThread(); 1.2147 + 1.2148 + NPObjectData* d = current()->mObjectMap.GetEntry(aNPObj); 1.2149 + if (!d) { 1.2150 + NS_ERROR("Releasing object not in mObjectMap?"); 1.2151 + return; 1.2152 + } 1.2153 + 1.2154 + DeletingObjectEntry* doe = nullptr; 1.2155 + if (d->instance->mDeletingHash) { 1.2156 + doe = d->instance->mDeletingHash->GetEntry(aNPObj); 1.2157 + if (!doe) { 1.2158 + NS_ERROR("An object for a destroyed instance isn't in the instance deletion hash"); 1.2159 + return; 1.2160 + } 1.2161 + if (doe->mDeleted) 1.2162 + return; 1.2163 + } 1.2164 + 1.2165 + int32_t refCnt = PR_ATOMIC_DECREMENT((int32_t*)&aNPObj->referenceCount); 1.2166 + NS_LOG_RELEASE(aNPObj, refCnt, "NPObject"); 1.2167 + 1.2168 + if (refCnt == 0) { 1.2169 + DeallocNPObject(aNPObj); 1.2170 + if (doe) 1.2171 + doe->mDeleted = true; 1.2172 + } 1.2173 + return; 1.2174 +} 1.2175 + 1.2176 +void 1.2177 +PluginModuleChild::DeallocNPObject(NPObject* aNPObj) 1.2178 +{ 1.2179 + if (aNPObj->_class && aNPObj->_class->deallocate) { 1.2180 + aNPObj->_class->deallocate(aNPObj); 1.2181 + } else { 1.2182 + child::_memfree(aNPObj); 1.2183 + } 1.2184 + 1.2185 + NPObjectData* d = current()->mObjectMap.GetEntry(aNPObj); 1.2186 + if (d->actor) 1.2187 + d->actor->NPObjectDestroyed(); 1.2188 + 1.2189 + current()->mObjectMap.RemoveEntry(aNPObj); 1.2190 +} 1.2191 + 1.2192 +void 1.2193 +PluginModuleChild::FindNPObjectsForInstance(PluginInstanceChild* instance) 1.2194 +{ 1.2195 + NS_ASSERTION(instance->mDeletingHash, "filling null mDeletingHash?"); 1.2196 + mObjectMap.EnumerateEntries(CollectForInstance, instance); 1.2197 +} 1.2198 + 1.2199 +PLDHashOperator 1.2200 +PluginModuleChild::CollectForInstance(NPObjectData* d, void* userArg) 1.2201 +{ 1.2202 + PluginInstanceChild* instance = static_cast<PluginInstanceChild*>(userArg); 1.2203 + if (d->instance == instance) { 1.2204 + NPObject* o = d->GetKey(); 1.2205 + instance->mDeletingHash->PutEntry(o); 1.2206 + } 1.2207 + return PL_DHASH_NEXT; 1.2208 +} 1.2209 + 1.2210 +NPIdentifier 1.2211 +PluginModuleChild::NPN_GetStringIdentifier(const NPUTF8* aName) 1.2212 +{ 1.2213 + PLUGIN_LOG_DEBUG_FUNCTION; 1.2214 + AssertPluginThread(); 1.2215 + 1.2216 + if (!aName) 1.2217 + return 0; 1.2218 + 1.2219 + PluginModuleChild* self = PluginModuleChild::current(); 1.2220 + nsDependentCString name(aName); 1.2221 + 1.2222 + PluginIdentifierChildString* ident = self->mStringIdentifiers.Get(name); 1.2223 + if (!ident) { 1.2224 + nsCString nameCopy(name); 1.2225 + 1.2226 + ident = new PluginIdentifierChildString(nameCopy); 1.2227 + self->SendPPluginIdentifierConstructor(ident, nameCopy, -1, false); 1.2228 + } 1.2229 + ident->MakePermanent(); 1.2230 + return ident; 1.2231 +} 1.2232 + 1.2233 +void 1.2234 +PluginModuleChild::NPN_GetStringIdentifiers(const NPUTF8** aNames, 1.2235 + int32_t aNameCount, 1.2236 + NPIdentifier* aIdentifiers) 1.2237 +{ 1.2238 + PLUGIN_LOG_DEBUG_FUNCTION; 1.2239 + AssertPluginThread(); 1.2240 + 1.2241 + if (!(aNames && aNameCount > 0 && aIdentifiers)) { 1.2242 + NS_RUNTIMEABORT("Bad input! Headed for a crash!"); 1.2243 + } 1.2244 + 1.2245 + PluginModuleChild* self = PluginModuleChild::current(); 1.2246 + 1.2247 + for (int32_t index = 0; index < aNameCount; ++index) { 1.2248 + if (!aNames[index]) { 1.2249 + aIdentifiers[index] = 0; 1.2250 + continue; 1.2251 + } 1.2252 + nsDependentCString name(aNames[index]); 1.2253 + PluginIdentifierChildString* ident = self->mStringIdentifiers.Get(name); 1.2254 + if (!ident) { 1.2255 + nsCString nameCopy(name); 1.2256 + 1.2257 + ident = new PluginIdentifierChildString(nameCopy); 1.2258 + self->SendPPluginIdentifierConstructor(ident, nameCopy, -1, false); 1.2259 + } 1.2260 + ident->MakePermanent(); 1.2261 + aIdentifiers[index] = ident; 1.2262 + } 1.2263 +} 1.2264 + 1.2265 +bool 1.2266 +PluginModuleChild::NPN_IdentifierIsString(NPIdentifier aIdentifier) 1.2267 +{ 1.2268 + PLUGIN_LOG_DEBUG_FUNCTION; 1.2269 + 1.2270 + PluginIdentifierChild* ident = 1.2271 + static_cast<PluginIdentifierChild*>(aIdentifier); 1.2272 + return ident->IsString(); 1.2273 +} 1.2274 + 1.2275 +NPIdentifier 1.2276 +PluginModuleChild::NPN_GetIntIdentifier(int32_t aIntId) 1.2277 +{ 1.2278 + PLUGIN_LOG_DEBUG_FUNCTION; 1.2279 + AssertPluginThread(); 1.2280 + 1.2281 + PluginModuleChild* self = PluginModuleChild::current(); 1.2282 + 1.2283 + PluginIdentifierChildInt* ident = self->mIntIdentifiers.Get(aIntId); 1.2284 + if (!ident) { 1.2285 + nsCString voidString; 1.2286 + voidString.SetIsVoid(true); 1.2287 + 1.2288 + ident = new PluginIdentifierChildInt(aIntId); 1.2289 + self->SendPPluginIdentifierConstructor(ident, voidString, aIntId, false); 1.2290 + } 1.2291 + ident->MakePermanent(); 1.2292 + return ident; 1.2293 +} 1.2294 + 1.2295 +NPUTF8* 1.2296 +PluginModuleChild::NPN_UTF8FromIdentifier(NPIdentifier aIdentifier) 1.2297 +{ 1.2298 + PLUGIN_LOG_DEBUG_FUNCTION; 1.2299 + 1.2300 + if (static_cast<PluginIdentifierChild*>(aIdentifier)->IsString()) { 1.2301 + return static_cast<PluginIdentifierChildString*>(aIdentifier)->ToString(); 1.2302 + } 1.2303 + return nullptr; 1.2304 +} 1.2305 + 1.2306 +int32_t 1.2307 +PluginModuleChild::NPN_IntFromIdentifier(NPIdentifier aIdentifier) 1.2308 +{ 1.2309 + PLUGIN_LOG_DEBUG_FUNCTION; 1.2310 + 1.2311 + if (!static_cast<PluginIdentifierChild*>(aIdentifier)->IsString()) { 1.2312 + return static_cast<PluginIdentifierChildInt*>(aIdentifier)->ToInt(); 1.2313 + } 1.2314 + return INT32_MIN; 1.2315 +} 1.2316 + 1.2317 +#ifdef OS_WIN 1.2318 +void 1.2319 +PluginModuleChild::EnteredCall() 1.2320 +{ 1.2321 + mIncallPumpingStack.AppendElement(); 1.2322 +} 1.2323 + 1.2324 +void 1.2325 +PluginModuleChild::ExitedCall() 1.2326 +{ 1.2327 + NS_ASSERTION(mIncallPumpingStack.Length(), "mismatched entered/exited"); 1.2328 + uint32_t len = mIncallPumpingStack.Length(); 1.2329 + const IncallFrame& f = mIncallPumpingStack[len - 1]; 1.2330 + if (f._spinning) 1.2331 + MessageLoop::current()->SetNestableTasksAllowed(f._savedNestableTasksAllowed); 1.2332 + 1.2333 + mIncallPumpingStack.TruncateLength(len - 1); 1.2334 +} 1.2335 + 1.2336 +LRESULT CALLBACK 1.2337 +PluginModuleChild::CallWindowProcHook(int nCode, WPARAM wParam, LPARAM lParam) 1.2338 +{ 1.2339 + // Trap and reply to anything we recognize as the source of a 1.2340 + // potential send message deadlock. 1.2341 + if (nCode >= 0 && 1.2342 + (InSendMessageEx(nullptr)&(ISMEX_REPLIED|ISMEX_SEND)) == ISMEX_SEND) { 1.2343 + CWPSTRUCT* pCwp = reinterpret_cast<CWPSTRUCT*>(lParam); 1.2344 + if (pCwp->message == WM_KILLFOCUS) { 1.2345 + // Fix for flash fullscreen window loosing focus. On single 1.2346 + // core systems, sync killfocus events need to be handled 1.2347 + // after the flash fullscreen window procedure processes this 1.2348 + // message, otherwise fullscreen focus will not work correctly. 1.2349 + wchar_t szClass[26]; 1.2350 + if (GetClassNameW(pCwp->hwnd, szClass, 1.2351 + sizeof(szClass)/sizeof(char16_t)) && 1.2352 + !wcscmp(szClass, kFlashFullscreenClass)) { 1.2353 + gDelayFlashFocusReplyUntilEval = true; 1.2354 + } 1.2355 + } 1.2356 + } 1.2357 + 1.2358 + return CallNextHookEx(nullptr, nCode, wParam, lParam); 1.2359 +} 1.2360 + 1.2361 +LRESULT CALLBACK 1.2362 +PluginModuleChild::NestedInputEventHook(int nCode, WPARAM wParam, LPARAM lParam) 1.2363 +{ 1.2364 + PluginModuleChild* self = current(); 1.2365 + uint32_t len = self->mIncallPumpingStack.Length(); 1.2366 + if (nCode >= 0 && len && !self->mIncallPumpingStack[len - 1]._spinning) { 1.2367 + MessageLoop* loop = MessageLoop::current(); 1.2368 + self->SendProcessNativeEventsInInterruptCall(); 1.2369 + IncallFrame& f = self->mIncallPumpingStack[len - 1]; 1.2370 + f._spinning = true; 1.2371 + f._savedNestableTasksAllowed = loop->NestableTasksAllowed(); 1.2372 + loop->SetNestableTasksAllowed(true); 1.2373 + loop->set_os_modal_loop(true); 1.2374 + } 1.2375 + 1.2376 + return CallNextHookEx(nullptr, nCode, wParam, lParam); 1.2377 +} 1.2378 + 1.2379 +void 1.2380 +PluginModuleChild::SetEventHooks() 1.2381 +{ 1.2382 + NS_ASSERTION(!mNestedEventHook, 1.2383 + "mNestedEventHook already setup in call to SetNestedInputEventHook?"); 1.2384 + NS_ASSERTION(!mGlobalCallWndProcHook, 1.2385 + "mGlobalCallWndProcHook already setup in call to CallWindowProcHook?"); 1.2386 + 1.2387 + PLUGIN_LOG_DEBUG(("%s", FULLFUNCTION)); 1.2388 + 1.2389 + // WH_MSGFILTER event hook for detecting modal loops in the child. 1.2390 + mNestedEventHook = SetWindowsHookEx(WH_MSGFILTER, 1.2391 + NestedInputEventHook, 1.2392 + nullptr, 1.2393 + GetCurrentThreadId()); 1.2394 + 1.2395 + // WH_CALLWNDPROC event hook for trapping sync messages sent from 1.2396 + // parent that can cause deadlocks. 1.2397 + mGlobalCallWndProcHook = SetWindowsHookEx(WH_CALLWNDPROC, 1.2398 + CallWindowProcHook, 1.2399 + nullptr, 1.2400 + GetCurrentThreadId()); 1.2401 +} 1.2402 + 1.2403 +void 1.2404 +PluginModuleChild::ResetEventHooks() 1.2405 +{ 1.2406 + PLUGIN_LOG_DEBUG(("%s", FULLFUNCTION)); 1.2407 + if (mNestedEventHook) 1.2408 + UnhookWindowsHookEx(mNestedEventHook); 1.2409 + mNestedEventHook = nullptr; 1.2410 + if (mGlobalCallWndProcHook) 1.2411 + UnhookWindowsHookEx(mGlobalCallWndProcHook); 1.2412 + mGlobalCallWndProcHook = nullptr; 1.2413 +} 1.2414 +#endif 1.2415 + 1.2416 +bool 1.2417 +PluginModuleChild::RecvProcessNativeEventsInInterruptCall() 1.2418 +{ 1.2419 + PLUGIN_LOG_DEBUG(("%s", FULLFUNCTION)); 1.2420 +#if defined(OS_WIN) 1.2421 + ProcessNativeEventsInInterruptCall(); 1.2422 + return true; 1.2423 +#else 1.2424 + NS_RUNTIMEABORT( 1.2425 + "PluginModuleChild::RecvProcessNativeEventsInInterruptCall not implemented!"); 1.2426 + return false; 1.2427 +#endif 1.2428 +} 1.2429 + 1.2430 +#ifdef MOZ_WIDGET_COCOA 1.2431 +void 1.2432 +PluginModuleChild::ProcessNativeEvents() { 1.2433 + CallProcessSomeEvents(); 1.2434 +} 1.2435 +#endif 1.2436 + 1.2437 +bool 1.2438 +PluginModuleChild::AnswerGeckoGetProfile(nsCString* aProfile) { 1.2439 + char* profile = profiler_get_profile(); 1.2440 + if (profile != nullptr) { 1.2441 + *aProfile = nsCString(profile, strlen(profile)); 1.2442 + free(profile); 1.2443 + } else { 1.2444 + *aProfile = nsCString("", 0); 1.2445 + } 1.2446 + return true; 1.2447 +} 1.2448 +