summaryrefslogtreecommitdiffstats
path: root/WebKit/mac/Plugins/Hosted
diff options
context:
space:
mode:
Diffstat (limited to 'WebKit/mac/Plugins/Hosted')
-rw-r--r--WebKit/mac/Plugins/Hosted/HostedNetscapePluginStream.mm18
-rw-r--r--WebKit/mac/Plugins/Hosted/NetscapePluginHostManager.h4
-rw-r--r--WebKit/mac/Plugins/Hosted/NetscapePluginHostManager.mm74
-rw-r--r--WebKit/mac/Plugins/Hosted/NetscapePluginHostProxy.h16
-rw-r--r--WebKit/mac/Plugins/Hosted/NetscapePluginHostProxy.mm468
-rw-r--r--WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.h67
-rw-r--r--WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.mm266
-rw-r--r--WebKit/mac/Plugins/Hosted/ProxyInstance.h6
-rw-r--r--WebKit/mac/Plugins/Hosted/ProxyInstance.mm93
-rw-r--r--WebKit/mac/Plugins/Hosted/WebHostedNetscapePluginView.h2
-rw-r--r--WebKit/mac/Plugins/Hosted/WebHostedNetscapePluginView.mm66
-rw-r--r--WebKit/mac/Plugins/Hosted/WebKitPluginClient.defs108
-rw-r--r--WebKit/mac/Plugins/Hosted/WebKitPluginHost.defs110
-rw-r--r--WebKit/mac/Plugins/Hosted/WebTextInputWindowController.h46
-rw-r--r--WebKit/mac/Plugins/Hosted/WebTextInputWindowController.m161
15 files changed, 1194 insertions, 311 deletions
diff --git a/WebKit/mac/Plugins/Hosted/HostedNetscapePluginStream.mm b/WebKit/mac/Plugins/Hosted/HostedNetscapePluginStream.mm
index 68e25ab..c2abc92 100644
--- a/WebKit/mac/Plugins/Hosted/HostedNetscapePluginStream.mm
+++ b/WebKit/mac/Plugins/Hosted/HostedNetscapePluginStream.mm
@@ -29,16 +29,17 @@
#import "NetscapePluginHostProxy.h"
#import "NetscapePluginInstanceProxy.h"
-#import <WebCore/DocumentLoader.h>
-#import <WebCore/Frame.h>
-#import <WebCore/FrameLoader.h>
-#import "WebHostedNetscapePluginView.h"
#import "WebFrameInternal.h"
+#import "WebHostedNetscapePluginView.h"
#import "WebKitErrorsPrivate.h"
-#import "WebNSURLExtras.h"
-#import "WebNSURLRequestExtras.h"
#import "WebKitPluginHost.h"
#import "WebKitSystemInterface.h"
+#import "WebNSURLExtras.h"
+#import "WebNSURLRequestExtras.h"
+#import <WebCore/DocumentLoader.h>
+#import <WebCore/Frame.h>
+#import <WebCore/FrameLoader.h>
+#import <WebCore/WebCoreURLResponse.h>
using namespace WebCore;
@@ -151,7 +152,7 @@ void HostedNetscapePluginStream::didReceiveResponse(NetscapePlugInStreamLoader*,
[theHeaders appendBytes:"\0" length:1];
}
- startStream([r URL], expectedContentLength, WKGetNSURLResponseLastModifiedDate(r), [r MIMEType], theHeaders);
+ startStream([r URL], expectedContentLength, WKGetNSURLResponseLastModifiedDate(r), [r _webcore_MIMEType], theHeaders);
}
static NPReason reasonForError(NSError *error)
@@ -167,7 +168,8 @@ static NPReason reasonForError(NSError *error)
void HostedNetscapePluginStream::didFail(WebCore::NetscapePlugInStreamLoader*, const WebCore::ResourceError& error)
{
- _WKPHStreamDidFail(m_instance->hostProxy()->port(), m_instance->pluginID(), m_streamID, reasonForError(error));
+ if (NetscapePluginHostProxy* hostProxy = m_instance->hostProxy())
+ _WKPHStreamDidFail(hostProxy->port(), m_instance->pluginID(), m_streamID, reasonForError(error));
}
bool HostedNetscapePluginStream::wantsAllStreams() const
diff --git a/WebKit/mac/Plugins/Hosted/NetscapePluginHostManager.h b/WebKit/mac/Plugins/Hosted/NetscapePluginHostManager.h
index 8e539f3..d550dac 100644
--- a/WebKit/mac/Plugins/Hosted/NetscapePluginHostManager.h
+++ b/WebKit/mac/Plugins/Hosted/NetscapePluginHostManager.h
@@ -47,13 +47,15 @@ public:
void pluginHostDied(NetscapePluginHostProxy*);
+ static void createPropertyListFile(WebNetscapePluginPackage *);
+
private:
NetscapePluginHostProxy* hostForPackage(WebNetscapePluginPackage *);
NetscapePluginHostManager();
~NetscapePluginHostManager();
- bool spawnPluginHost(WebNetscapePluginPackage *, mach_port_t clientPort, mach_port_t& pluginHostPort);
+ bool spawnPluginHost(WebNetscapePluginPackage *, mach_port_t clientPort, mach_port_t& pluginHostPort, ProcessSerialNumber& pluginHostPSN);
bool initializeVendorPort();
diff --git a/WebKit/mac/Plugins/Hosted/NetscapePluginHostManager.mm b/WebKit/mac/Plugins/Hosted/NetscapePluginHostManager.mm
index 9cedc42..08a6d6a 100644
--- a/WebKit/mac/Plugins/Hosted/NetscapePluginHostManager.mm
+++ b/WebKit/mac/Plugins/Hosted/NetscapePluginHostManager.mm
@@ -33,6 +33,7 @@
#import "WebNetscapePluginPackage.h"
#import <mach/mach_port.h>
#import <servers/bootstrap.h>
+#import <spawn.h>
#import <wtf/Assertions.h>
#import <wtf/RetainPtr.h>
#import <wtf/StdLibExtras.h>
@@ -77,12 +78,13 @@ NetscapePluginHostProxy* NetscapePluginHostManager::hostForPackage(WebNetscapePl
return 0;
mach_port_t pluginHostPort;
- if (!spawnPluginHost(package, clientPort, pluginHostPort)) {
+ ProcessSerialNumber pluginHostPSN;
+ if (!spawnPluginHost(package, clientPort, pluginHostPort, pluginHostPSN)) {
mach_port_destroy(mach_task_self(), clientPort);
return 0;
}
- NetscapePluginHostProxy* hostProxy = new NetscapePluginHostProxy(clientPort, pluginHostPort);
+ NetscapePluginHostProxy* hostProxy = new NetscapePluginHostProxy(clientPort, pluginHostPort, pluginHostPSN);
CFRetain(package);
result.first->second = hostProxy;
@@ -90,7 +92,7 @@ NetscapePluginHostProxy* NetscapePluginHostManager::hostForPackage(WebNetscapePl
return hostProxy;
}
-bool NetscapePluginHostManager::spawnPluginHost(WebNetscapePluginPackage *package, mach_port_t clientPort, mach_port_t& pluginHostPort)
+bool NetscapePluginHostManager::spawnPluginHost(WebNetscapePluginPackage *package, mach_port_t clientPort, mach_port_t& pluginHostPort, ProcessSerialNumber& pluginHostPSN)
{
if (m_pluginVendorPort == MACH_PORT_NULL) {
if (!initializeVendorPort())
@@ -116,13 +118,26 @@ bool NetscapePluginHostManager::spawnPluginHost(WebNetscapePluginPackage *packag
kern_return_t kr = _WKPASpawnPluginHost(m_pluginVendorPort, reinterpret_cast<uint8_t*>(const_cast<void*>([data bytes])), [data length], &pluginHostPort);
+ if (kr == MACH_SEND_INVALID_DEST) {
+ // The plug-in vendor port has gone away for some reason. Try to reinitialize it.
+ m_pluginVendorPort = MACH_PORT_NULL;
+ if (!initializeVendorPort())
+ return false;
+
+ // And spawn the plug-in host again.
+ kr = _WKPASpawnPluginHost(m_pluginVendorPort, reinterpret_cast<uint8_t*>(const_cast<void*>([data bytes])), [data length], &pluginHostPort);
+ }
+
if (kr != KERN_SUCCESS) {
// FIXME: Check for invalid dest and try to re-spawn the plug-in agent.
LOG_ERROR("Failed to spawn plug-in host, error %x", kr);
return false;
}
+ NSString *visibleName = [NSString stringWithFormat:@"%@ Plug-in Host - %@", [[NSProcessInfo processInfo] processName], [package filename]];
+
NSDictionary *hostProperties = [[NSDictionary alloc] initWithObjectsAndKeys:
+ visibleName, @"visibleName",
[package path], @"bundlePath",
nil];
@@ -130,8 +145,12 @@ bool NetscapePluginHostManager::spawnPluginHost(WebNetscapePluginPackage *packag
ASSERT(data);
[hostProperties release];
-
- kr = _WKPHCheckInWithPluginHost(pluginHostPort, (uint8_t*)[data bytes], [data length], clientPort, renderServerPort);
+
+ ProcessSerialNumber psn;
+ GetCurrentProcess(&psn);
+
+ kr = _WKPHCheckInWithPluginHost(pluginHostPort, (uint8_t*)[data bytes], [data length], clientPort, psn.highLongOfPSN, psn.lowLongOfPSN, renderServerPort,
+ &pluginHostPSN.highLongOfPSN, &pluginHostPSN.lowLongOfPSN);
if (kr != KERN_SUCCESS) {
mach_port_deallocate(mach_task_self(), pluginHostPort);
@@ -205,7 +224,8 @@ PassRefPtr<NetscapePluginInstanceProxy> NetscapePluginHostManager::instantiatePl
ASSERT(data);
RefPtr<NetscapePluginInstanceProxy> instance = NetscapePluginInstanceProxy::create(hostProxy, pluginView);
- kern_return_t kr = _WKPHInstantiatePlugin(hostProxy->port(), (uint8_t*)[data bytes], [data length], instance->pluginID());
+ uint32_t requestID = instance->nextRequestID();
+ kern_return_t kr = _WKPHInstantiatePlugin(hostProxy->port(), requestID, (uint8_t*)[data bytes], [data length], instance->pluginID());
if (kr == MACH_SEND_INVALID_DEST) {
// The plug-in host must have died, but we haven't received the death notification yet.
pluginHostDied(hostProxy);
@@ -213,22 +233,52 @@ PassRefPtr<NetscapePluginInstanceProxy> NetscapePluginHostManager::instantiatePl
// Try to spawn it again.
hostProxy = hostForPackage(pluginPackage);
- kr = _WKPHInstantiatePlugin(hostProxy->port(), (uint8_t*)[data bytes], [data length], instance->pluginID());
+ // Create a new instance.
+ instance = NetscapePluginInstanceProxy::create(hostProxy, pluginView);
+ requestID = instance->nextRequestID();
+ kr = _WKPHInstantiatePlugin(hostProxy->port(), requestID, (uint8_t*)[data bytes], [data length], instance->pluginID());
}
- auto_ptr<NetscapePluginInstanceProxy::InstantiatePluginReply> reply = instance->waitForReply<NetscapePluginInstanceProxy::InstantiatePluginReply>();
- if (!reply.get())
- return 0;
-
- if (reply->m_resultCode != KERN_SUCCESS)
+ auto_ptr<NetscapePluginInstanceProxy::InstantiatePluginReply> reply = instance->waitForReply<NetscapePluginInstanceProxy::InstantiatePluginReply>(requestID);
+ if (!reply.get() || reply->m_resultCode != KERN_SUCCESS) {
+ instance->invalidate();
return 0;
+ }
instance->setRenderContextID(reply->m_renderContextID);
instance->setUseSoftwareRenderer(reply->m_useSoftwareRenderer);
return instance.release();
}
+
+void NetscapePluginHostManager::createPropertyListFile(WebNetscapePluginPackage *package)
+{
+ NSString *pluginHostAppPath = [[NSBundle bundleWithIdentifier:@"com.apple.WebKit"] pathForAuxiliaryExecutable:pluginHostAppName];
+ NSString *pluginHostAppExecutablePath = [[NSBundle bundleWithPath:pluginHostAppPath] executablePath];
+ NSString *bundlePath = [package path];
+
+ pid_t pid;
+ posix_spawnattr_t attr;
+ posix_spawnattr_init(&attr);
+
+ // Set the architecture.
+ size_t ocount = 0;
+ int cpuTypes[1] = { [package pluginHostArchitecture] };
+ posix_spawnattr_setbinpref_np(&attr, 1, cpuTypes, &ocount);
+
+ // Spawn the plug-in host and tell it to call the registration function.
+ const char* args[] = { [pluginHostAppExecutablePath fileSystemRepresentation], "-createPluginMIMETypesPreferences", [bundlePath fileSystemRepresentation], 0 };
+
+ int result = posix_spawn(&pid, args[0], 0, &attr, const_cast<char* const*>(args), 0);
+ posix_spawnattr_destroy(&attr);
+
+ if (!result && pid > 0) {
+ // Wait for the process to finish.
+ while (waitpid(pid, 0, 0) == -1) { }
+ }
+}
+
} // namespace WebKit
#endif // USE(PLUGIN_HOST_PROCESS)
diff --git a/WebKit/mac/Plugins/Hosted/NetscapePluginHostProxy.h b/WebKit/mac/Plugins/Hosted/NetscapePluginHostProxy.h
index c597eec..4676f47 100644
--- a/WebKit/mac/Plugins/Hosted/NetscapePluginHostProxy.h
+++ b/WebKit/mac/Plugins/Hosted/NetscapePluginHostProxy.h
@@ -39,7 +39,7 @@ class NetscapePluginInstanceProxy;
class NetscapePluginHostProxy {
public:
- NetscapePluginHostProxy(mach_port_t clientPort, mach_port_t pluginHostPort);
+ NetscapePluginHostProxy(mach_port_t clientPort, mach_port_t pluginHostPort, const ProcessSerialNumber& pluginHostPSN);
mach_port_t port() const { return m_pluginHostPort; }
mach_port_t clientPort() const { return m_clientPort; }
@@ -52,9 +52,16 @@ public:
void setMenuBarVisible(bool);
void setModal(bool);
+ void applicationDidBecomeActive();
+
+ bool processRequests();
+
private:
~NetscapePluginHostProxy();
void pluginHostDied();
+
+ void beginModal();
+ void endModal();
static void deadNameNotificationCallback(CFMachPortRef port, void *msg, CFIndex size, void *info);
@@ -62,6 +69,8 @@ private:
PluginInstanceMap m_instances;
mach_port_t m_clientPort;
+ mach_port_t m_portSet;
+
#ifdef USE_LIBDISPATCH
dispatch_source_t m_clientPortSource;
#else
@@ -70,10 +79,11 @@ private:
mach_port_t m_pluginHostPort;
RetainPtr<CFMachPortRef> m_deadNameNotificationPort;
+ RetainPtr<id> m_activationObserver;
RetainPtr<NSWindow *> m_placeholderWindow;
- unsigned m_modalCount;
-
+ unsigned m_isModal;
bool m_menuBarIsVisible;
+ const ProcessSerialNumber m_pluginHostPSN;
};
} // namespace WebKit
diff --git a/WebKit/mac/Plugins/Hosted/NetscapePluginHostProxy.mm b/WebKit/mac/Plugins/Hosted/NetscapePluginHostProxy.mm
index 14af429..c0beb2f 100644
--- a/WebKit/mac/Plugins/Hosted/NetscapePluginHostProxy.mm
+++ b/WebKit/mac/Plugins/Hosted/NetscapePluginHostProxy.mm
@@ -37,8 +37,8 @@
#import "WebHostedNetscapePluginView.h"
#import "WebKitSystemInterface.h"
#import <WebCore/Frame.h>
+#import <WebCore/IdentifierRep.h>
#import <WebCore/ScriptController.h>
-#import <WebCore/npruntime_impl.h>
extern "C" {
#import "WebKitPluginHost.h"
@@ -51,19 +51,23 @@ using namespace WebCore;
namespace WebKit {
-static String fromUTF8WithLatin1Fallback(const char* data, int length = -1)
-{
- if (length == -1)
- length = strlen(data);
-
- String result = String::fromUTF8(data, length);
-
- if (result.isNull())
- result = String(data, length);
-
- return result;
-}
+class PluginDestroyDeferrer {
+public:
+ PluginDestroyDeferrer(NetscapePluginInstanceProxy* proxy)
+ : m_proxy(proxy)
+ {
+ m_proxy->willCallPluginFunction();
+ }
+ ~PluginDestroyDeferrer()
+ {
+ m_proxy->didCallPluginFunction();
+ }
+
+private:
+ RefPtr<NetscapePluginInstanceProxy> m_proxy;
+};
+
typedef HashMap<mach_port_t, NetscapePluginHostProxy*> PluginProxyMap;
static PluginProxyMap& pluginProxyMap()
{
@@ -72,11 +76,13 @@ static PluginProxyMap& pluginProxyMap()
return pluginProxyMap;
}
-NetscapePluginHostProxy::NetscapePluginHostProxy(mach_port_t clientPort, mach_port_t pluginHostPort)
+NetscapePluginHostProxy::NetscapePluginHostProxy(mach_port_t clientPort, mach_port_t pluginHostPort, const ProcessSerialNumber& pluginHostPSN)
: m_clientPort(clientPort)
+ , m_portSet(MACH_PORT_NULL)
, m_pluginHostPort(pluginHostPort)
- , m_modalCount(0)
+ , m_isModal(false)
, m_menuBarIsVisible(true)
+ , m_pluginHostPSN(pluginHostPSN)
{
pluginProxyMap().add(m_clientPort, this);
@@ -95,17 +101,25 @@ NetscapePluginHostProxy::NetscapePluginHostProxy(mach_port_t clientPort, mach_po
#ifdef USE_LIBDISPATCH
// FIXME: Unfortunately we can't use a dispatch source here until <rdar://problem/6393180> has been resolved.
- m_clientPortSource = dispatch_source_mig_create(m_clientPort, WKPCWebKitPluginClient_subsystem.maxsize, 0,
+ m_clientPortSource = dispatch_source_mig_create(m_clientPort, WKWebKitPluginClient_subsystem.maxsize, 0,
dispatch_get_main_queue(), WebKitPluginClient_server);
#else
- m_clientPortSource.adoptCF(WKCreateMIGServerSource((mig_subsystem_t)&WKPCWebKitPluginClient_subsystem, m_clientPort));
+ m_clientPortSource.adoptCF(WKCreateMIGServerSource((mig_subsystem_t)&WKWebKitPluginClient_subsystem, m_clientPort));
CFRunLoopAddSource(CFRunLoopGetCurrent(), m_clientPortSource.get(), kCFRunLoopDefaultMode);
+ CFRunLoopAddSource(CFRunLoopGetCurrent(), m_clientPortSource.get(), (CFStringRef)NSEventTrackingRunLoopMode);
#endif
}
NetscapePluginHostProxy::~NetscapePluginHostProxy()
{
pluginProxyMap().remove(m_clientPort);
+
+ // Free the port set
+ if (m_portSet) {
+ mach_port_extract_member(mach_task_self(), m_clientPort, m_portSet);
+ mach_port_extract_member(mach_task_self(), CFMachPortGetPort(m_deadNameNotificationPort.get()), m_portSet);
+ mach_port_destroy(mach_task_self(), m_portSet);
+ }
ASSERT(m_clientPortSource);
#ifdef USE_LIBDISPATCH
@@ -128,15 +142,12 @@ void NetscapePluginHostProxy::pluginHostDied()
NetscapePluginHostManager::shared().pluginHostDied(this);
// The plug-in crashed while its menu bar was hidden. Make sure to show it.
- if (m_menuBarIsVisible)
+ if (!m_menuBarIsVisible)
setMenuBarVisible(true);
// The plug-in crashed while it had a modal dialog up.
- if (m_modalCount) {
- m_modalCount = 1;
-
- setModal(false);
- }
+ if (m_isModal)
+ endModal();
delete this;
}
@@ -180,44 +191,137 @@ void NetscapePluginHostProxy::setMenuBarVisible(bool visible)
}
}
-void NetscapePluginHostProxy::setModal(bool modal)
+void NetscapePluginHostProxy::applicationDidBecomeActive()
{
- if (modal) {
- if (!m_modalCount++) {
- ASSERT(!m_placeholderWindow);
-
- m_placeholderWindow.adoptNS([[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 1, 1) styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:YES]);
-
- // We need to be able to get the setModal(false) call from the plug-in host.
- CFRunLoopAddSource(CFRunLoopGetCurrent(), m_clientPortSource.get(), (CFStringRef)NSModalPanelRunLoopMode);
+ SetFrontProcess(&m_pluginHostPSN);
+}
- [NSApp runModalForWindow:m_placeholderWindow.get()];
- }
- } else {
- if (!--m_modalCount) {
- ASSERT(m_placeholderWindow);
-
- CFRunLoopRemoveSource(CFRunLoopGetCurrent(), m_clientPortSource.get(), (CFStringRef)NSModalPanelRunLoopMode);
+void NetscapePluginHostProxy::beginModal()
+{
+ ASSERT(!m_placeholderWindow);
+ ASSERT(!m_activationObserver);
+
+ m_placeholderWindow.adoptNS([[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 1, 1) styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:YES]);
+
+ m_activationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:NSApplicationWillBecomeActiveNotification object:NSApp queue:nil
+ usingBlock:^(NSNotification *){ applicationDidBecomeActive(); }];
+
+ // We need to be able to get the setModal(false) call from the plug-in host.
+ CFRunLoopAddSource(CFRunLoopGetCurrent(), m_clientPortSource.get(), (CFStringRef)NSModalPanelRunLoopMode);
+
+ [NSApp runModalForWindow:m_placeholderWindow.get()];
+}
+
+void NetscapePluginHostProxy::endModal()
+{
+ ASSERT(m_placeholderWindow);
+ ASSERT(m_activationObserver);
+
+ [[NSNotificationCenter defaultCenter] removeObserver:m_activationObserver.get()];
+ m_activationObserver = nil;
+
+ CFRunLoopRemoveSource(CFRunLoopGetCurrent(), m_clientPortSource.get(), (CFStringRef)NSModalPanelRunLoopMode);
+
+ [NSApp stopModal];
+ [m_placeholderWindow.get() orderOut:nil];
+ m_placeholderWindow = 0;
+
+ // Make ourselves the front process.
+ ProcessSerialNumber psn;
+ GetCurrentProcess(&psn);
+ SetFrontProcess(&psn);
+}
+
- [NSApp stopModal];
- [m_placeholderWindow.get() orderOut:nil];
- m_placeholderWindow = 0;
+void NetscapePluginHostProxy::setModal(bool modal)
+{
+ if (modal == m_isModal)
+ return;
+
+ m_isModal = modal;
+
+ if (m_isModal)
+ beginModal();
+ else
+ endModal();
+}
+
+bool NetscapePluginHostProxy::processRequests()
+{
+ if (!m_portSet) {
+ mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_PORT_SET, &m_portSet);
+ mach_port_insert_member(mach_task_self(), m_clientPort, m_portSet);
+ mach_port_insert_member(mach_task_self(), CFMachPortGetPort(m_deadNameNotificationPort.get()), m_portSet);
+ }
+
+ char buffer[4096];
+
+ mach_msg_header_t* msg = reinterpret_cast<mach_msg_header_t*>(buffer);
+
+ kern_return_t kr = mach_msg(msg, MACH_RCV_MSG, 0, sizeof(buffer), m_portSet, 0, MACH_PORT_NULL);
+
+ if (kr != KERN_SUCCESS) {
+ LOG_ERROR("Could not receive mach message, error %x", kr);
+ return false;
+ }
+
+ if (msg->msgh_local_port == m_clientPort) {
+ __ReplyUnion__WKWebKitPluginClient_subsystem reply;
+ mach_msg_header_t* replyHeader = reinterpret_cast<mach_msg_header_t*>(&reply);
+
+ if (WebKitPluginClient_server(msg, replyHeader) && replyHeader->msgh_remote_port != MACH_PORT_NULL) {
+ kr = mach_msg(replyHeader, MACH_SEND_MSG, replyHeader->msgh_size, 0, MACH_PORT_NULL, 0, MACH_PORT_NULL);
- // Make ourselves the front process.
- ProcessSerialNumber psn;
- GetCurrentProcess(&psn);
- SetFrontProcess(&psn);
+ if (kr != KERN_SUCCESS) {
+ LOG_ERROR("Could not send mach message, error %x", kr);
+ return false;
+ }
}
- }
-}
+
+ return true;
+ }
+ if (msg->msgh_local_port == CFMachPortGetPort(m_deadNameNotificationPort.get())) {
+ ASSERT(msg->msgh_id == MACH_NOTIFY_DEAD_NAME);
+ pluginHostDied();
+ return false;
+ }
+
+ ASSERT_NOT_REACHED();
+ return false;
+}
+
} // namespace WebKit
using namespace WebKit;
+// Helper class for deallocating data
+class DataDeallocator {
+public:
+ DataDeallocator(data_t data, mach_msg_type_number_t dataLength)
+ : m_data(reinterpret_cast<vm_address_t>(data))
+ , m_dataLength(dataLength)
+ {
+ }
+
+ ~DataDeallocator()
+ {
+ if (!m_data)
+ return;
+
+ vm_deallocate(mach_task_self(), m_data, m_dataLength);
+ }
+
+private:
+ vm_address_t m_data;
+ vm_size_t m_dataLength;
+};
+
// MiG callbacks
kern_return_t WKPCStatusText(mach_port_t clientPort, uint32_t pluginID, data_t text, mach_msg_type_number_t textCnt)
{
+ DataDeallocator deallocator(text, textCnt);
+
NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
if (!hostProxy)
return KERN_FAILURE;
@@ -234,6 +338,10 @@ kern_return_t WKPCLoadURL(mach_port_t clientPort, uint32_t pluginID, data_t url,
data_t postData, mach_msg_type_number_t postDataLength, uint32_t flags,
uint16_t* outResult, uint32_t* outStreamID)
{
+ DataDeallocator urlDeallocator(url, urlLength);
+ DataDeallocator targetDeallocator(target, targetLength);
+ DataDeallocator postDataDeallocator(postData, postDataLength);
+
NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
if (!hostProxy)
return KERN_FAILURE;
@@ -278,12 +386,11 @@ kern_return_t WKPCInvalidateRect(mach_port_t clientPort, uint32_t pluginID, doub
if (!instanceProxy)
return KERN_FAILURE;
- [instanceProxy->pluginView() setNeedsDisplayInRect:NSMakeRect(x, y, width, height)];
-
+ instanceProxy->invalidateRect(x, y, width, height);
return KERN_SUCCESS;
}
-kern_return_t WKPCGetScriptableNPObjectReply(mach_port_t clientPort, uint32_t pluginID, uint32_t objectID)
+kern_return_t WKPCGetScriptableNPObjectReply(mach_port_t clientPort, uint32_t pluginID, uint32_t requestID, uint32_t objectID)
{
NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
if (!hostProxy)
@@ -293,11 +400,11 @@ kern_return_t WKPCGetScriptableNPObjectReply(mach_port_t clientPort, uint32_t pl
if (!instanceProxy)
return KERN_FAILURE;
- instanceProxy->setCurrentReply(new NetscapePluginInstanceProxy::GetScriptableNPObjectReply(objectID));
+ instanceProxy->setCurrentReply(requestID, new NetscapePluginInstanceProxy::GetScriptableNPObjectReply(objectID));
return KERN_SUCCESS;
}
-kern_return_t WKPCBooleanReply(mach_port_t clientPort, uint32_t pluginID, boolean_t result)
+kern_return_t WKPCBooleanReply(mach_port_t clientPort, uint32_t pluginID, uint32_t requestID, boolean_t result)
{
NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
if (!hostProxy)
@@ -307,12 +414,14 @@ kern_return_t WKPCBooleanReply(mach_port_t clientPort, uint32_t pluginID, boolea
if (!instanceProxy)
return KERN_FAILURE;
- instanceProxy->setCurrentReply(new NetscapePluginInstanceProxy::BooleanReply(result));
+ instanceProxy->setCurrentReply(requestID, new NetscapePluginInstanceProxy::BooleanReply(result));
return KERN_SUCCESS;
}
-kern_return_t WKPCBooleanAndDataReply(mach_port_t clientPort, uint32_t pluginID, boolean_t returnValue, data_t resultData, mach_msg_type_number_t resultLength)
+kern_return_t WKPCBooleanAndDataReply(mach_port_t clientPort, uint32_t pluginID, uint32_t requestID, boolean_t returnValue, data_t resultData, mach_msg_type_number_t resultLength)
{
+ DataDeallocator deallocator(resultData, resultLength);
+
NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
if (!hostProxy)
return KERN_FAILURE;
@@ -321,13 +430,13 @@ kern_return_t WKPCBooleanAndDataReply(mach_port_t clientPort, uint32_t pluginID,
if (!instanceProxy)
return KERN_FAILURE;
- RetainPtr<CFDataRef> result = CFDataCreate(0, reinterpret_cast<UInt8*>(resultData), resultLength);
- instanceProxy->setCurrentReply(new NetscapePluginInstanceProxy::BooleanAndDataReply(returnValue, result));
+ RetainPtr<CFDataRef> result(AdoptCF, CFDataCreate(0, reinterpret_cast<UInt8*>(resultData), resultLength));
+ instanceProxy->setCurrentReply(requestID, new NetscapePluginInstanceProxy::BooleanAndDataReply(returnValue, result));
return KERN_SUCCESS;
}
-kern_return_t WKPCInstantiatePluginReply(mach_port_t clientPort, uint32_t pluginID, kern_return_t result, uint32_t renderContextID, boolean_t useSoftwareRenderer)
+kern_return_t WKPCInstantiatePluginReply(mach_port_t clientPort, uint32_t pluginID, uint32_t requestID, kern_return_t result, uint32_t renderContextID, boolean_t useSoftwareRenderer)
{
NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
if (!hostProxy)
@@ -337,7 +446,7 @@ kern_return_t WKPCInstantiatePluginReply(mach_port_t clientPort, uint32_t plugin
if (!instanceProxy)
return KERN_FAILURE;
- instanceProxy->setCurrentReply(new NetscapePluginInstanceProxy::InstantiatePluginReply(result, renderContextID, useSoftwareRenderer));
+ instanceProxy->setCurrentReply(requestID, new NetscapePluginInstanceProxy::InstantiatePluginReply(result, renderContextID, useSoftwareRenderer));
return KERN_SUCCESS;
}
@@ -359,6 +468,24 @@ kern_return_t WKPCGetWindowNPObject(mach_port_t clientPort, uint32_t pluginID, u
return KERN_SUCCESS;
}
+kern_return_t WKPCGetPluginElementNPObject(mach_port_t clientPort, uint32_t pluginID, uint32_t* outObjectID)
+{
+ NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
+ if (!hostProxy)
+ return KERN_FAILURE;
+
+ NetscapePluginInstanceProxy* instanceProxy = hostProxy->pluginInstance(pluginID);
+ if (!instanceProxy)
+ return KERN_FAILURE;
+
+ uint32_t objectID;
+ if (!instanceProxy->getPluginElementNPObject(objectID))
+ return KERN_FAILURE;
+
+ *outObjectID = objectID;
+ return KERN_SUCCESS;
+}
+
kern_return_t WKPCReleaseObject(mach_port_t clientPort, uint32_t pluginID, uint32_t objectID)
{
NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
@@ -373,8 +500,10 @@ kern_return_t WKPCReleaseObject(mach_port_t clientPort, uint32_t pluginID, uint3
return KERN_SUCCESS;
}
-kern_return_t WKPCEvaluate(mach_port_t clientPort, uint32_t pluginID, uint32_t objectID, data_t scriptData, mach_msg_type_number_t scriptLength)
+kern_return_t WKPCEvaluate(mach_port_t clientPort, uint32_t pluginID, uint32_t requestID, uint32_t objectID, data_t scriptData, mach_msg_type_number_t scriptLength)
{
+ DataDeallocator deallocator(scriptData, scriptLength);
+
NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
if (!hostProxy)
return KERN_FAILURE;
@@ -383,24 +512,28 @@ kern_return_t WKPCEvaluate(mach_port_t clientPort, uint32_t pluginID, uint32_t o
if (!instanceProxy)
return KERN_FAILURE;
- String script = fromUTF8WithLatin1Fallback(scriptData, scriptLength);
+ PluginDestroyDeferrer deferrer(instanceProxy);
- data_t resultData;
- mach_msg_type_number_t resultLength;
+ String script = String::fromUTF8WithLatin1Fallback(scriptData, scriptLength);
+ data_t resultData = 0;
+ mach_msg_type_number_t resultLength = 0;
boolean_t returnValue = instanceProxy->evaluate(objectID, script, resultData, resultLength);
- _WKPHEvaluateReply(hostProxy->port(), instanceProxy->pluginID(), returnValue, resultData, resultLength);
- mig_deallocate(reinterpret_cast<vm_address_t>(resultData), resultLength);
+ _WKPHBooleanAndDataReply(hostProxy->port(), instanceProxy->pluginID(), requestID, returnValue, resultData, resultLength);
+ if (resultData)
+ mig_deallocate(reinterpret_cast<vm_address_t>(resultData), resultLength);
return KERN_SUCCESS;
}
kern_return_t WKPCGetStringIdentifier(mach_port_t clientPort, data_t name, mach_msg_type_number_t nameCnt, uint64_t* identifier)
{
- COMPILE_ASSERT(sizeof(*identifier) == sizeof(NPIdentifier), identifier_sizes);
+ DataDeallocator deallocator(name, nameCnt);
+
+ COMPILE_ASSERT(sizeof(*identifier) == sizeof(IdentifierRep*), identifier_sizes);
- *identifier = reinterpret_cast<uint64_t>(_NPN_GetStringIdentifier(name));
+ *identifier = reinterpret_cast<uint64_t>(IdentifierRep::get(name));
return KERN_SUCCESS;
}
@@ -408,23 +541,24 @@ kern_return_t WKPCGetIntIdentifier(mach_port_t clientPort, int32_t value, uint64
{
COMPILE_ASSERT(sizeof(*identifier) == sizeof(NPIdentifier), identifier_sizes);
- *identifier = reinterpret_cast<uint64_t>(_NPN_GetIntIdentifier(value));
+ *identifier = reinterpret_cast<uint64_t>(IdentifierRep::get(value));
return KERN_SUCCESS;
}
-static Identifier identifierFromServerIdentifier(uint64_t serverIdentifier)
+static Identifier identifierFromIdentifierRep(IdentifierRep* identifier)
{
- NPIdentifier identifier = reinterpret_cast<NPIdentifier>(serverIdentifier);
- ASSERT(_NPN_IdentifierIsString(identifier));
-
- String s = fromUTF8WithLatin1Fallback(_NPN_UTF8FromIdentifier(identifier));
-
- return Identifier(JSDOMWindow::commonJSGlobalData(), s);
+ ASSERT(IdentifierRep::isValid(identifier));
+ ASSERT(identifier->isString());
+
+ const char* str = identifier->string();
+ return Identifier(JSDOMWindow::commonJSGlobalData(), String::fromUTF8WithLatin1Fallback(str, strlen(str)));
}
-kern_return_t WKPCInvoke(mach_port_t clientPort, uint32_t pluginID, uint32_t objectID, uint64_t identifier,
+kern_return_t WKPCInvoke(mach_port_t clientPort, uint32_t pluginID, uint32_t requestID, uint32_t objectID, uint64_t serverIdentifier,
data_t argumentsData, mach_msg_type_number_t argumentsLength)
{
+ DataDeallocator deallocator(argumentsData, argumentsLength);
+
NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
if (!hostProxy)
return KERN_FAILURE;
@@ -433,23 +567,32 @@ kern_return_t WKPCInvoke(mach_port_t clientPort, uint32_t pluginID, uint32_t obj
if (!instanceProxy)
return KERN_FAILURE;
- Identifier methodNameIdentifier = identifierFromServerIdentifier(identifier);
-
- data_t resultData;
- mach_msg_type_number_t resultLength;
+ PluginDestroyDeferrer deferrer(instanceProxy);
+ IdentifierRep* identifier = reinterpret_cast<IdentifierRep*>(serverIdentifier);
+ if (!IdentifierRep::isValid(identifier)) {
+ _WKPHBooleanAndDataReply(hostProxy->port(), instanceProxy->pluginID(), requestID, false, 0, 0);
+ return KERN_SUCCESS;
+ }
+
+ Identifier methodNameIdentifier = identifierFromIdentifierRep(identifier);
+
+ data_t resultData = 0;
+ mach_msg_type_number_t resultLength = 0;
boolean_t returnValue = instanceProxy->invoke(objectID, methodNameIdentifier, argumentsData, argumentsLength, resultData, resultLength);
- _WKPHEvaluateReply(hostProxy->port(), instanceProxy->pluginID(), returnValue, resultData, resultLength);
- mig_deallocate(reinterpret_cast<vm_address_t>(resultData), resultLength);
+ _WKPHBooleanAndDataReply(hostProxy->port(), instanceProxy->pluginID(), requestID, returnValue, resultData, resultLength);
+ if (resultData)
+ mig_deallocate(reinterpret_cast<vm_address_t>(resultData), resultLength);
return KERN_SUCCESS;
}
-kern_return_t WKPCInvokeDefault(mach_port_t clientPort, uint32_t pluginID, uint32_t objectID,
- data_t argumentsData, mach_msg_type_number_t argumentsLength,
- boolean_t*returnValue, data_t* resultData, mach_msg_type_number_t* resultLength)
+kern_return_t WKPCInvokeDefault(mach_port_t clientPort, uint32_t pluginID, uint32_t requestID, uint32_t objectID,
+ data_t argumentsData, mach_msg_type_number_t argumentsLength)
{
+ DataDeallocator deallocator(argumentsData, argumentsLength);
+
NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
if (!hostProxy)
return KERN_FAILURE;
@@ -458,15 +601,25 @@ kern_return_t WKPCInvokeDefault(mach_port_t clientPort, uint32_t pluginID, uint3
if (!instanceProxy)
return KERN_FAILURE;
- *returnValue = instanceProxy->invokeDefault(objectID, argumentsData, argumentsLength, *resultData, *resultLength);
+ PluginDestroyDeferrer deferrer(instanceProxy);
+
+ data_t resultData = 0;
+ mach_msg_type_number_t resultLength = 0;
+ boolean_t returnValue = instanceProxy->invokeDefault(objectID, argumentsData, argumentsLength, resultData, resultLength);
+
+ _WKPHBooleanAndDataReply(hostProxy->port(), instanceProxy->pluginID(), requestID, returnValue, resultData, resultLength);
+ if (resultData)
+ mig_deallocate(reinterpret_cast<vm_address_t>(resultData), resultLength);
return KERN_SUCCESS;
}
kern_return_t WKPCConstruct(mach_port_t clientPort, uint32_t pluginID, uint32_t objectID,
data_t argumentsData, mach_msg_type_number_t argumentsLength,
- boolean_t*returnValue, data_t* resultData, mach_msg_type_number_t* resultLength)
+ boolean_t* returnValue, data_t* resultData, mach_msg_type_number_t* resultLength)
{
+ DataDeallocator deallocator(argumentsData, argumentsLength);
+
NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
if (!hostProxy)
return KERN_FAILURE;
@@ -475,12 +628,14 @@ kern_return_t WKPCConstruct(mach_port_t clientPort, uint32_t pluginID, uint32_t
if (!instanceProxy)
return KERN_FAILURE;
+ PluginDestroyDeferrer deferrer(instanceProxy);
+
*returnValue = instanceProxy->construct(objectID, argumentsData, argumentsLength, *resultData, *resultLength);
return KERN_SUCCESS;
}
-kern_return_t WKPCGetProperty(mach_port_t clientPort, uint32_t pluginID, uint32_t objectID, uint64_t identifier, boolean_t*returnValue, data_t* resultData, mach_msg_type_number_t* resultLength)
+kern_return_t WKPCGetProperty(mach_port_t clientPort, uint32_t pluginID, uint32_t requestID, uint32_t objectID, uint64_t serverIdentifier)
{
NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
if (!hostProxy)
@@ -490,21 +645,33 @@ kern_return_t WKPCGetProperty(mach_port_t clientPort, uint32_t pluginID, uint32_
if (!instanceProxy)
return KERN_FAILURE;
- NPIdentifier npIdentifier = reinterpret_cast<NPIdentifier>(identifier);
- if (_NPN_IdentifierIsString(npIdentifier)) {
- const NPUTF8* propertyName = _NPN_UTF8FromIdentifier(npIdentifier);
- String propertyNameString = fromUTF8WithLatin1Fallback(propertyName);
-
- Identifier propertyNameIdentifier = identifierFromServerIdentifier(identifier);
- *returnValue = instanceProxy->getProperty(objectID, propertyNameIdentifier, *resultData, *resultLength);
+ IdentifierRep* identifier = reinterpret_cast<IdentifierRep*>(serverIdentifier);
+ if (!IdentifierRep::isValid(identifier))
+ return KERN_FAILURE;
+
+ PluginDestroyDeferrer deferrer(instanceProxy);
+
+ data_t resultData = 0;
+ mach_msg_type_number_t resultLength = 0;
+ boolean_t returnValue;
+
+ if (identifier->isString()) {
+ Identifier propertyNameIdentifier = identifierFromIdentifierRep(identifier);
+ returnValue = instanceProxy->getProperty(objectID, propertyNameIdentifier, resultData, resultLength);
} else
- *returnValue = instanceProxy->setProperty(objectID, _NPN_IntFromIdentifier(npIdentifier), *resultData, *resultLength);
+ returnValue = instanceProxy->setProperty(objectID, identifier->number(), resultData, resultLength);
+
+ _WKPHBooleanAndDataReply(hostProxy->port(), instanceProxy->pluginID(), requestID, returnValue, resultData, resultLength);
+ if (resultData)
+ mig_deallocate(reinterpret_cast<vm_address_t>(resultData), resultLength);
return KERN_SUCCESS;
}
-kern_return_t WKPCSetProperty(mach_port_t clientPort, uint32_t pluginID, uint32_t objectID, uint64_t identifier, data_t valueData, mach_msg_type_number_t valueLength, boolean_t*returnValue)
+kern_return_t WKPCSetProperty(mach_port_t clientPort, uint32_t pluginID, uint32_t objectID, uint64_t serverIdentifier, data_t valueData, mach_msg_type_number_t valueLength, boolean_t* returnValue)
{
+ DataDeallocator deallocator(valueData, valueLength);
+
NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
if (!hostProxy)
return KERN_FAILURE;
@@ -512,21 +679,23 @@ kern_return_t WKPCSetProperty(mach_port_t clientPort, uint32_t pluginID, uint32_
NetscapePluginInstanceProxy* instanceProxy = hostProxy->pluginInstance(pluginID);
if (!instanceProxy)
return KERN_FAILURE;
+
+ PluginDestroyDeferrer deferrer(instanceProxy);
+
+ IdentifierRep* identifier = reinterpret_cast<IdentifierRep*>(serverIdentifier);
+ if (!IdentifierRep::isValid(identifier))
+ *returnValue = false;
- NPIdentifier npIdentifier = reinterpret_cast<NPIdentifier>(identifier);
- if (_NPN_IdentifierIsString(npIdentifier)) {
- const NPUTF8* propertyName = _NPN_UTF8FromIdentifier(npIdentifier);
- String propertyNameString = fromUTF8WithLatin1Fallback(propertyName);
-
- Identifier propertyNameIdentifier = identifierFromServerIdentifier(identifier);
+ if (identifier->isString()) {
+ Identifier propertyNameIdentifier = identifierFromIdentifierRep(identifier);
*returnValue = instanceProxy->setProperty(objectID, propertyNameIdentifier, valueData, valueLength);
} else
- *returnValue = instanceProxy->setProperty(objectID, _NPN_IntFromIdentifier(npIdentifier), valueData, valueLength);
+ *returnValue = instanceProxy->setProperty(objectID, identifier->number(), valueData, valueLength);
return KERN_SUCCESS;
}
-kern_return_t WKPCRemoveProperty(mach_port_t clientPort, uint32_t pluginID, uint32_t objectID, uint64_t identifier, boolean_t*returnValue)
+kern_return_t WKPCRemoveProperty(mach_port_t clientPort, uint32_t pluginID, uint32_t objectID, uint64_t serverIdentifier, boolean_t* returnValue)
{
NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
if (!hostProxy)
@@ -536,20 +705,22 @@ kern_return_t WKPCRemoveProperty(mach_port_t clientPort, uint32_t pluginID, uint
if (!instanceProxy)
return KERN_FAILURE;
- NPIdentifier npIdentifier = reinterpret_cast<NPIdentifier>(identifier);
- if (_NPN_IdentifierIsString(npIdentifier)) {
- const NPUTF8* propertyName = _NPN_UTF8FromIdentifier(npIdentifier);
- String propertyNameString = fromUTF8WithLatin1Fallback(propertyName);
+ PluginDestroyDeferrer deferrer(instanceProxy);
+
+ IdentifierRep* identifier = reinterpret_cast<IdentifierRep*>(serverIdentifier);
+ if (!IdentifierRep::isValid(identifier))
+ return KERN_FAILURE;
- Identifier propertyNameIdentifier = identifierFromServerIdentifier(identifier);
+ if (identifier->isString()) {
+ Identifier propertyNameIdentifier = identifierFromIdentifierRep(identifier);
*returnValue = instanceProxy->removeProperty(objectID, propertyNameIdentifier);
} else
- *returnValue = instanceProxy->removeProperty(objectID, _NPN_IntFromIdentifier(npIdentifier));
+ *returnValue = instanceProxy->removeProperty(objectID, identifier->number());
return KERN_SUCCESS;
}
-kern_return_t WKPCHasProperty(mach_port_t clientPort, uint32_t pluginID, uint32_t objectID, uint64_t identifier, boolean_t*returnValue)
+kern_return_t WKPCHasProperty(mach_port_t clientPort, uint32_t pluginID, uint32_t requestID, uint32_t objectID, uint64_t serverIdentifier)
{
NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
if (!hostProxy)
@@ -559,20 +730,27 @@ kern_return_t WKPCHasProperty(mach_port_t clientPort, uint32_t pluginID, uint32_
if (!instanceProxy)
return KERN_FAILURE;
- NPIdentifier npIdentifier = reinterpret_cast<NPIdentifier>(identifier);
- if (_NPN_IdentifierIsString(npIdentifier)) {
- const NPUTF8* propertyName = _NPN_UTF8FromIdentifier(npIdentifier);
- String propertyNameString = fromUTF8WithLatin1Fallback(propertyName);
-
- Identifier propertyNameIdentifier = identifierFromServerIdentifier(identifier);
- *returnValue = instanceProxy->hasProperty(objectID, propertyNameIdentifier);
+ PluginDestroyDeferrer deferrer(instanceProxy);
+
+ IdentifierRep* identifier = reinterpret_cast<IdentifierRep*>(serverIdentifier);
+ if (!IdentifierRep::isValid(identifier)) {
+ _WKPHBooleanReply(hostProxy->port(), instanceProxy->pluginID(), requestID, false);
+ return KERN_SUCCESS;
+ }
+
+ boolean_t returnValue;
+ if (identifier->isString()) {
+ Identifier propertyNameIdentifier = identifierFromIdentifierRep(identifier);
+ returnValue = instanceProxy->hasProperty(objectID, propertyNameIdentifier);
} else
- *returnValue = instanceProxy->hasProperty(objectID, _NPN_IntFromIdentifier(npIdentifier));
+ returnValue = instanceProxy->hasProperty(objectID, identifier->number());
+
+ _WKPHBooleanReply(hostProxy->port(), instanceProxy->pluginID(), requestID, returnValue);
return KERN_SUCCESS;
}
-kern_return_t WKPCHasMethod(mach_port_t clientPort, uint32_t pluginID, uint32_t objectID, uint64_t identifier, boolean_t*returnValue)
+kern_return_t WKPCHasMethod(mach_port_t clientPort, uint32_t pluginID, uint32_t requestID, uint32_t objectID, uint64_t serverIdentifier)
{
NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
if (!hostProxy)
@@ -582,22 +760,34 @@ kern_return_t WKPCHasMethod(mach_port_t clientPort, uint32_t pluginID, uint32_t
if (!instanceProxy)
return KERN_FAILURE;
- Identifier methodNameIdentifier = identifierFromServerIdentifier(identifier);
- *returnValue = instanceProxy->hasMethod(objectID, methodNameIdentifier);
+ PluginDestroyDeferrer deferrer(instanceProxy);
+
+ IdentifierRep* identifier = reinterpret_cast<IdentifierRep*>(serverIdentifier);
+ if (!IdentifierRep::isValid(identifier)) {
+ _WKPHBooleanReply(hostProxy->port(), instanceProxy->pluginID(), requestID, false);
+ return KERN_SUCCESS;
+ }
+
+ Identifier methodNameIdentifier = identifierFromIdentifierRep(identifier);
+ boolean_t returnValue = instanceProxy->hasMethod(objectID, methodNameIdentifier);
+
+ _WKPHBooleanReply(hostProxy->port(), instanceProxy->pluginID(), requestID, returnValue);
return KERN_SUCCESS;
}
kern_return_t WKPCIdentifierInfo(mach_port_t clientPort, uint64_t serverIdentifier, data_t* infoData, mach_msg_type_number_t* infoLength)
{
- NPIdentifier identifier = reinterpret_cast<NPIdentifier>(serverIdentifier);
+ IdentifierRep* identifier = reinterpret_cast<IdentifierRep*>(serverIdentifier);
+ if (!IdentifierRep::isValid(identifier))
+ return KERN_FAILURE;
id info;
- if (_NPN_IdentifierIsString(identifier)) {
- char* s = _NPN_UTF8FromIdentifier(identifier);
- info = [NSData dataWithBytesNoCopy:s length:strlen(s) freeWhenDone:NO];
+ if (identifier->isString()) {
+ const char* str = identifier->string();
+ info = [NSData dataWithBytesNoCopy:(void*)str length:strlen(str) freeWhenDone:NO];
} else
- info = [NSNumber numberWithInt:_NPN_IntFromIdentifier(identifier)];
+ info = [NSNumber numberWithInt:identifier->number()];
RetainPtr<NSData*> data = [NSPropertyListSerialization dataFromPropertyList:info format:NSPropertyListBinaryFormat_v1_0 errorDescription:0];
ASSERT(data);
@@ -610,6 +800,28 @@ kern_return_t WKPCIdentifierInfo(mach_port_t clientPort, uint64_t serverIdentifi
return KERN_SUCCESS;
}
+kern_return_t WKPCEnumerate(mach_port_t clientPort, uint32_t pluginID, uint32_t requestID, uint32_t objectID)
+{
+ NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
+ if (!hostProxy)
+ return KERN_FAILURE;
+
+ NetscapePluginInstanceProxy* instanceProxy = hostProxy->pluginInstance(pluginID);
+ if (!instanceProxy)
+ return KERN_FAILURE;
+
+ data_t resultData = 0;
+ mach_msg_type_number_t resultLength = 0;
+ boolean_t returnValue = instanceProxy->enumerate(objectID, resultData, resultLength);
+
+ _WKPHBooleanAndDataReply(hostProxy->port(), instanceProxy->pluginID(), requestID, returnValue, resultData, resultLength);
+
+ if (resultData)
+ mig_deallocate(reinterpret_cast<vm_address_t>(resultData), resultLength);
+
+ return KERN_SUCCESS;
+}
+
kern_return_t WKPCSetMenuBarVisible(mach_port_t clientPort, boolean_t menuBarVisible)
{
NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
diff --git a/WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.h b/WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.h
index 343aa41..3f9132d 100644
--- a/WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.h
+++ b/WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.h
@@ -54,6 +54,7 @@ namespace WebKit {
class HostedNetscapePluginStream;
class NetscapePluginHostProxy;
+class ProxyInstance;
class NetscapePluginInstanceProxy : public RefCounted<NetscapePluginInstanceProxy> {
public:
@@ -63,7 +64,12 @@ public:
}
~NetscapePluginInstanceProxy();
- uint32_t pluginID() const { return m_pluginID; }
+ uint32_t pluginID() const
+ {
+ ASSERT(m_pluginID);
+
+ return m_pluginID;
+ }
uint32_t renderContextID() const { return m_renderContextID; }
void setRenderContextID(uint32_t renderContextID) { m_renderContextID = renderContextID; }
@@ -86,17 +92,25 @@ public:
void mouseEvent(NSView *pluginView, NSEvent *, NPCocoaEventType);
void keyEvent(NSView *pluginView, NSEvent *, NPCocoaEventType);
+ void insertText(NSString *);
+
+ void print(CGContextRef, unsigned width, unsigned height);
+
void startTimers(bool throttleTimers);
void stopTimers();
+ void invalidateRect(double x, double y, double width, double height);
+
// NPRuntime
bool getWindowNPObject(uint32_t& objectID);
+ bool getPluginElementNPObject(uint32_t& objectID);
void releaseObject(uint32_t objectID);
bool evaluate(uint32_t objectID, const WebCore::String& script, data_t& resultData, mach_msg_type_number_t& resultLength);
bool invoke(uint32_t objectID, const JSC::Identifier& methodName, data_t argumentsData, mach_msg_type_number_t argumentsLength, data_t& resultData, mach_msg_type_number_t& resultLength);
bool invokeDefault(uint32_t objectID, data_t argumentsData, mach_msg_type_number_t argumentsLength, data_t& resultData, mach_msg_type_number_t& resultLength);
bool construct(uint32_t objectID, data_t argumentsData, mach_msg_type_number_t argumentsLength, data_t& resultData, mach_msg_type_number_t& resultLength);
+ bool enumerate(uint32_t objectID, data_t& resultData, mach_msg_type_number_t& resultLength);
bool getProperty(uint32_t objectID, const JSC::Identifier& propertyName, data_t &resultData, mach_msg_type_number_t& resultLength);
bool getProperty(uint32_t objectID, unsigned propertyName, data_t &resultData, mach_msg_type_number_t& resultLength);
@@ -116,6 +130,17 @@ public:
void marshalValue(JSC::ExecState*, JSC::JSValuePtr value, data_t& resultData, mach_msg_type_number_t& resultLength);
JSC::JSValuePtr demarshalValue(JSC::ExecState*, const char* valueData, mach_msg_type_number_t valueLength);
+ void addInstance(ProxyInstance*);
+ void removeInstance(ProxyInstance*);
+
+ void invalidate();
+
+ void willCallPluginFunction();
+ void didCallPluginFunction();
+ bool shouldStop();
+
+ uint32_t nextRequestID();
+
// Reply structs
struct Reply {
enum Type {
@@ -125,7 +150,11 @@ public:
Boolean
};
- Reply(Type type) : m_type(type) { }
+ Reply(Type type)
+ : m_type(type)
+ {
+ }
+
virtual ~Reply() { }
Type m_type;
@@ -185,24 +214,23 @@ public:
RetainPtr<CFDataRef> m_result;
};
- void setCurrentReply(Reply* reply)
+ void setCurrentReply(uint32_t requestID, Reply* reply)
{
- ASSERT(!m_currentReply.get());
- m_currentReply = std::auto_ptr<Reply>(reply);
+ ASSERT(!m_replies.contains(requestID));
+ m_replies.set(requestID, reply);
}
template <typename T>
- std::auto_ptr<T> waitForReply()
+ std::auto_ptr<T> waitForReply(uint32_t requestID)
{
m_waitingForReply = true;
-
- processRequestsAndWaitForReply();
-
- if (m_currentReply.get())
- ASSERT(m_currentReply->m_type == T::ReplyType);
+
+ Reply* reply = processRequestsAndWaitForReply(requestID);
+ if (reply)
+ ASSERT(reply->m_type == T::ReplyType);
m_waitingForReply = false;
- return std::auto_ptr<T>(static_cast<T*>(m_currentReply.release()));
+ return std::auto_ptr<T>(static_cast<T*>(reply));
}
private:
@@ -215,7 +243,9 @@ private:
void evaluateJavaScript(PluginRequest*);
void stopAllStreams();
- void processRequestsAndWaitForReply();
+ Reply* processRequestsAndWaitForReply(uint32_t requestID);
+
+ void cleanup();
NetscapePluginHostProxy* m_pluginHostProxy;
WebHostedNetscapePluginView *m_pluginView;
@@ -226,14 +256,14 @@ private:
HashMap<uint32_t, RefPtr<HostedNetscapePluginStream> > m_streams;
- uint32_t m_currentRequestID;
+ uint32_t m_currentURLRequestID;
uint32_t m_pluginID;
uint32_t m_renderContextID;
boolean_t m_useSoftwareRenderer;
bool m_waitingForReply;
- std::auto_ptr<Reply> m_currentReply;
+ HashMap<uint32_t, Reply*> m_replies;
// NPRuntime
uint32_t idForObject(JSC::JSObject*);
@@ -246,6 +276,13 @@ private:
uint32_t m_objectIDCounter;
typedef HashMap<uint32_t, JSC::ProtectedPtr<JSC::JSObject> > ObjectMap;
ObjectMap m_objects;
+
+ typedef HashSet<ProxyInstance*> ProxyInstanceSet;
+ ProxyInstanceSet m_instances;
+
+ unsigned m_pluginFunctionCallDepth;
+ bool m_shouldStopSoon;
+ uint32_t m_currentRequestID;
};
} // namespace WebKit
diff --git a/WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.mm b/WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.mm
index 6d0df52..2ef921a 100644
--- a/WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.mm
+++ b/WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.mm
@@ -46,10 +46,12 @@
#import <WebCore/Frame.h>
#import <WebCore/FrameLoader.h>
#import <WebCore/FrameTree.h>
+#import <WebCore/npruntime_impl.h>
#import <WebCore/runtime_object.h>
#import <WebCore/ScriptController.h>
#import <WebCore/ScriptValue.h>
#include <runtime/JSLock.h>
+#include <runtime/PropertyNameArray.h>
#import <utility>
extern "C" {
@@ -92,11 +94,14 @@ NetscapePluginInstanceProxy::NetscapePluginInstanceProxy(NetscapePluginHostProxy
: m_pluginHostProxy(pluginHostProxy)
, m_pluginView(pluginView)
, m_requestTimer(this, &NetscapePluginInstanceProxy::requestTimerFired)
- , m_currentRequestID(0)
+ , m_currentURLRequestID(0)
, m_renderContextID(0)
, m_useSoftwareRenderer(false)
, m_waitingForReply(false)
, m_objectIDCounter(0)
+ , m_pluginFunctionCallDepth(0)
+ , m_shouldStopSoon(false)
+ , m_currentRequestID(0)
{
ASSERT(m_pluginView);
@@ -111,6 +116,9 @@ NetscapePluginInstanceProxy::NetscapePluginInstanceProxy(NetscapePluginHostProxy
NetscapePluginInstanceProxy::~NetscapePluginInstanceProxy()
{
ASSERT(!m_pluginHostProxy);
+
+ m_pluginID = 0;
+ deleteAllValues(m_replies);
}
void NetscapePluginInstanceProxy::resize(NSRect size, NSRect clipRect)
@@ -126,20 +134,53 @@ void NetscapePluginInstanceProxy::stopAllStreams()
streamsCopy[i]->stop();
}
-void NetscapePluginInstanceProxy::destroy()
+void NetscapePluginInstanceProxy::cleanup()
{
stopAllStreams();
- _WKPHDestroyPluginInstance(m_pluginHostProxy->port(), m_pluginID);
+ m_requestTimer.stop();
// Clear the object map, this will cause any outstanding JS objects that the plug-in had a reference to
// to go away when the next garbage collection takes place.
m_objects.clear();
+ if (Frame* frame = core([m_pluginView webFrame]))
+ frame->script()->cleanupScriptObjectsForPlugin(m_pluginView);
+
+ ProxyInstanceSet instances;
+ instances.swap(m_instances);
+
+ // Invalidate all proxy instances.
+ ProxyInstanceSet::const_iterator end = instances.end();
+ for (ProxyInstanceSet::const_iterator it = instances.begin(); it != end; ++it)
+ (*it)->invalidate();
+
+ m_pluginView = nil;
+}
+
+void NetscapePluginInstanceProxy::invalidate()
+{
+ // If the plug-in host has died, the proxy will be null.
+ if (!m_pluginHostProxy)
+ return;
+
m_pluginHostProxy->removePluginInstance(this);
m_pluginHostProxy = 0;
}
+void NetscapePluginInstanceProxy::destroy()
+{
+ uint32_t requestID = nextRequestID();
+
+ _WKPHDestroyPluginInstance(m_pluginHostProxy->port(), m_pluginID, requestID);
+
+ // We don't care about the reply here - we just want to block until the plug-in instance has been torn down.
+ waitForReply<NetscapePluginInstanceProxy::BooleanReply>(requestID);
+
+ cleanup();
+ invalidate();
+}
+
HostedNetscapePluginStream *NetscapePluginInstanceProxy::pluginStream(uint32_t streamID)
{
return m_streams.get(streamID).get();
@@ -152,12 +193,11 @@ void NetscapePluginInstanceProxy::disconnectStream(HostedNetscapePluginStream* s
void NetscapePluginInstanceProxy::pluginHostDied()
{
- stopAllStreams();
-
m_pluginHostProxy = 0;
-
+
[m_pluginView pluginHostDied];
- m_pluginView = nil;
+
+ cleanup();
}
void NetscapePluginInstanceProxy::focusChanged(bool hasFocus)
@@ -218,6 +258,37 @@ void NetscapePluginInstanceProxy::keyEvent(NSView *pluginView, NSEvent *event, N
[event isARepeat], [event keyCode]);
}
+void NetscapePluginInstanceProxy::insertText(NSString *text)
+{
+ NSData *textData = [text dataUsingEncoding:NSUTF8StringEncoding];
+
+ _WKPHPluginInstanceInsertText(m_pluginHostProxy->port(), m_pluginID,
+ const_cast<char*>(reinterpret_cast<const char*>([textData bytes])), [textData length]);
+}
+
+void NetscapePluginInstanceProxy::print(CGContextRef context, unsigned width, unsigned height)
+{
+ uint32_t requestID = nextRequestID();
+ _WKPHPluginInstancePrint(m_pluginHostProxy->port(), m_pluginID, requestID, width, height);
+
+ auto_ptr<NetscapePluginInstanceProxy::BooleanAndDataReply> reply = waitForReply<NetscapePluginInstanceProxy::BooleanAndDataReply>(requestID);
+ if (!reply.get() || !reply->m_returnValue)
+ return;
+
+ RetainPtr<CGDataProvider> dataProvider(AdoptCF, CGDataProviderCreateWithCFData(reply->m_result.get()));
+ RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB());
+ RetainPtr<CGImageRef> image(AdoptCF, CGImageCreate(width, height, 8, 32, width * 4, colorSpace.get(), kCGImageAlphaFirst, dataProvider.get(), 0, false, kCGRenderingIntentDefault));
+
+ // Flip the context and draw the image.
+ CGContextSaveGState(context);
+ CGContextTranslateCTM(context, 0.0, height);
+ CGContextScaleCTM(context, 1.0, -1.0);
+
+ CGContextDrawImage(context, CGRectMake(0, 0, width, height), image.get());
+
+ CGContextRestoreGState(context);
+}
+
void NetscapePluginInstanceProxy::stopTimers()
{
_WKPHPluginInstanceStopTimers(m_pluginHostProxy->port(), m_pluginID);
@@ -309,6 +380,8 @@ NPError NetscapePluginInstanceProxy::loadURL(const char* url, const char* target
void NetscapePluginInstanceProxy::performRequest(PluginRequest* pluginRequest)
{
+ ASSERT(m_pluginView);
+
NSURLRequest *request = pluginRequest->request();
NSString *frameName = pluginRequest->frameName();
WebFrame *frame = nil;
@@ -329,8 +402,10 @@ void NetscapePluginInstanceProxy::performRequest(PluginRequest* pluginRequest)
windowFeatures:features];
[features release];
- if (!newWebView)
+ if (!newWebView) {
+ _WKPHLoadURLNotify(m_pluginHostProxy->port(), m_pluginID, pluginRequest->requestID(), NPERR_GENERIC_ERROR);
return;
+ }
frame = [newWebView mainFrame];
core(frame)->tree()->setName(frameName);
@@ -379,6 +454,7 @@ void NetscapePluginInstanceProxy::evaluateJavaScript(PluginRequest* pluginReques
void NetscapePluginInstanceProxy::requestTimerFired(Timer<NetscapePluginInstanceProxy>*)
{
ASSERT(!m_pluginRequests.isEmpty());
+ ASSERT(m_pluginView);
PluginRequest* request = m_pluginRequests.first();
m_pluginRequests.removeFirst();
@@ -427,7 +503,7 @@ NPError NetscapePluginInstanceProxy::loadRequest(NSURLRequest *request, const ch
}
// FIXME: Handle wraparound
- requestID = ++m_currentRequestID;
+ requestID = ++m_currentURLRequestID;
if (cTarget || JSString) {
// Make when targetting a frame or evaluating a JS string, perform the request after a delay because we don't
@@ -451,15 +527,17 @@ NPError NetscapePluginInstanceProxy::loadRequest(NSURLRequest *request, const ch
return NPERR_NO_ERROR;
}
-void NetscapePluginInstanceProxy::processRequestsAndWaitForReply()
+NetscapePluginInstanceProxy::Reply* NetscapePluginInstanceProxy::processRequestsAndWaitForReply(uint32_t requestID)
{
- while (!m_currentReply.get()) {
- kern_return_t kr = mach_msg_server_once(WebKitPluginClient_server, WKPCWebKitPluginClient_subsystem.maxsize + MAX_TRAILER_SIZE, m_pluginHostProxy->clientPort(), 0);
- if (kr != KERN_SUCCESS) {
- m_currentReply.reset();
- break;
- }
+ Reply* reply = 0;
+
+ while (!(reply = m_replies.take(requestID))) {
+ if (!m_pluginHostProxy->processRequests())
+ return 0;
}
+
+ ASSERT(reply);
+ return reply;
}
uint32_t NetscapePluginInstanceProxy::idForObject(JSObject* object)
@@ -490,7 +568,21 @@ bool NetscapePluginInstanceProxy::getWindowNPObject(uint32_t& objectID)
return true;
}
+
+bool NetscapePluginInstanceProxy::getPluginElementNPObject(uint32_t& objectID)
+{
+ Frame* frame = core([m_pluginView webFrame]);
+ if (!frame)
+ return false;
+ if (JSObject* object = frame->script()->jsObjectForPluginElement([m_pluginView element]))
+ objectID = idForObject(object);
+ else
+ objectID = 0;
+
+ return true;
+}
+
void NetscapePluginInstanceProxy::releaseObject(uint32_t objectID)
{
m_objects.remove(objectID);
@@ -507,11 +599,25 @@ bool NetscapePluginInstanceProxy::evaluate(uint32_t objectID, const String& scri
Frame* frame = core([m_pluginView webFrame]);
if (!frame)
return false;
+
+ JSLock lock(false);
- ExecState* exec = frame->script()->globalObject()->globalExec();
- JSValuePtr value = frame->loader()->executeScript(script).jsValue();
+ ProtectedPtr<JSGlobalObject> globalObject = frame->script()->globalObject();
+ ExecState* exec = globalObject->globalExec();
+
+ globalObject->globalData()->timeoutChecker.start();
+ Completion completion = JSC::evaluate(exec, globalObject->globalScopeChain(), makeSource(script));
+ globalObject->globalData()->timeoutChecker.stop();
+ ComplType type = completion.complType();
- marshalValue(exec, value, resultData, resultLength);
+ JSValuePtr result;
+ if (type == Normal)
+ result = completion.value();
+
+ if (!result)
+ result = jsUndefined();
+
+ marshalValue(exec, result, resultData, resultLength);
exec->clearException();
return true;
}
@@ -541,9 +647,9 @@ bool NetscapePluginInstanceProxy::invoke(uint32_t objectID, const Identifier& me
demarshalValues(exec, argumentsData, argumentsLength, argList);
ProtectedPtr<JSGlobalObject> globalObject = frame->script()->globalObject();
- globalObject->startTimeoutCheck();
+ globalObject->globalData()->timeoutChecker.start();
JSValuePtr value = call(exec, function, callType, callData, object, argList);
- globalObject->stopTimeoutCheck();
+ globalObject->globalData()->timeoutChecker.stop();
marshalValue(exec, value, resultData, resultLength);
exec->clearException();
@@ -571,9 +677,9 @@ bool NetscapePluginInstanceProxy::invokeDefault(uint32_t objectID, data_t argume
demarshalValues(exec, argumentsData, argumentsLength, argList);
ProtectedPtr<JSGlobalObject> globalObject = frame->script()->globalObject();
- globalObject->startTimeoutCheck();
+ globalObject->globalData()->timeoutChecker.start();
JSValuePtr value = call(exec, object, callType, callData, object, argList);
- globalObject->stopTimeoutCheck();
+ globalObject->globalData()->timeoutChecker.stop();
marshalValue(exec, value, resultData, resultLength);
exec->clearException();
@@ -602,9 +708,9 @@ bool NetscapePluginInstanceProxy::construct(uint32_t objectID, data_t argumentsD
demarshalValues(exec, argumentsData, argumentsLength, argList);
ProtectedPtr<JSGlobalObject> globalObject = frame->script()->globalObject();
- globalObject->startTimeoutCheck();
+ globalObject->globalData()->timeoutChecker.start();
JSValuePtr value = JSC::construct(exec, object, constructType, constructData, argList);
- globalObject->stopTimeoutCheck();
+ globalObject->globalData()->timeoutChecker.stop();
marshalValue(exec, value, resultData, resultLength);
exec->clearException();
@@ -785,6 +891,42 @@ bool NetscapePluginInstanceProxy::hasMethod(uint32_t objectID, const Identifier&
return !func.isUndefined();
}
+bool NetscapePluginInstanceProxy::enumerate(uint32_t objectID, data_t& resultData, mach_msg_type_number_t& resultLength)
+{
+ JSObject* object = m_objects.get(objectID);
+ if (!object)
+ return false;
+
+ Frame* frame = core([m_pluginView webFrame]);
+ if (!frame)
+ return false;
+
+ ExecState* exec = frame->script()->globalObject()->globalExec();
+ JSLock lock(false);
+
+ PropertyNameArray propertyNames(exec);
+ object->getPropertyNames(exec, propertyNames);
+
+ NSMutableArray *array = [[NSMutableArray alloc] init];
+ for (unsigned i = 0; i < propertyNames.size(); i++) {
+ uint64_t methodName = reinterpret_cast<uint64_t>(_NPN_GetStringIdentifier(propertyNames[i].ustring().UTF8String().c_str()));
+
+ [array addObject:[NSNumber numberWithLongLong:methodName]];
+ }
+
+ NSData *data = [NSPropertyListSerialization dataFromPropertyList:array format:NSPropertyListBinaryFormat_v1_0 errorDescription:0];
+ ASSERT(data);
+
+ resultLength = [data length];
+ mig_allocate(reinterpret_cast<vm_address_t*>(&resultData), resultLength);
+
+ memcpy(resultData, [data bytes], resultLength);
+
+ exec->clearException();
+
+ return true;
+}
+
void NetscapePluginInstanceProxy::addValueToArray(NSMutableArray *array, ExecState* exec, JSValuePtr value)
{
JSLock lock(false);
@@ -803,8 +945,11 @@ void NetscapePluginInstanceProxy::addValueToArray(NSMutableArray *array, ExecSta
else if (value.isObject()) {
JSObject* object = asObject(value);
if (object->classInfo() == &RuntimeObjectImp::s_info) {
- // FIXME: Handle ProxyInstance objects.
- ASSERT_NOT_REACHED();
+ RuntimeObjectImp* imp = static_cast<RuntimeObjectImp*>(object);
+ if (ProxyInstance* instance = static_cast<ProxyInstance*>(imp->getInternalInstance())) {
+ [array addObject:[NSNumber numberWithInt:NPObjectValueType]];
+ [array addObject:[NSNumber numberWithInt:instance->objectID()]];
+ }
} else {
[array addObject:[NSNumber numberWithInt:JSObjectValueType]];
[array addObject:[NSNumber numberWithInt:idForObject(object)]];
@@ -928,10 +1073,12 @@ void NetscapePluginInstanceProxy::demarshalValues(ExecState* exec, data_t values
PassRefPtr<Instance> NetscapePluginInstanceProxy::createBindingsInstance(PassRefPtr<RootObject> rootObject)
{
- if (_WKPHGetScriptableNPObject(m_pluginHostProxy->port(), m_pluginID) != KERN_SUCCESS)
+ uint32_t requestID = nextRequestID();
+
+ if (_WKPHGetScriptableNPObject(m_pluginHostProxy->port(), m_pluginID, requestID) != KERN_SUCCESS)
return 0;
- auto_ptr<GetScriptableNPObjectReply> reply = waitForReply<GetScriptableNPObjectReply>();
+ auto_ptr<GetScriptableNPObjectReply> reply = waitForReply<GetScriptableNPObjectReply>(requestID);
if (!reply.get())
return 0;
@@ -941,6 +1088,67 @@ PassRefPtr<Instance> NetscapePluginInstanceProxy::createBindingsInstance(PassRef
return ProxyInstance::create(rootObject, this, reply->m_objectID);
}
+void NetscapePluginInstanceProxy::addInstance(ProxyInstance* instance)
+{
+ ASSERT(!m_instances.contains(instance));
+
+ m_instances.add(instance);
+}
+
+void NetscapePluginInstanceProxy::removeInstance(ProxyInstance* instance)
+{
+ ASSERT(m_instances.contains(instance));
+
+ m_instances.remove(instance);
+}
+
+void NetscapePluginInstanceProxy::willCallPluginFunction()
+{
+ m_pluginFunctionCallDepth++;
+}
+
+void NetscapePluginInstanceProxy::didCallPluginFunction()
+{
+ ASSERT(m_pluginFunctionCallDepth > 0);
+ m_pluginFunctionCallDepth--;
+
+ // If -stop was called while we were calling into a plug-in function, and we're no longer
+ // inside a plug-in function, stop now.
+ if (!m_pluginFunctionCallDepth && m_shouldStopSoon) {
+ m_shouldStopSoon = false;
+ [m_pluginView stop];
+ }
+}
+
+bool NetscapePluginInstanceProxy::shouldStop()
+{
+ if (m_pluginFunctionCallDepth) {
+ m_shouldStopSoon = true;
+ return false;
+ }
+
+ return true;
+}
+
+uint32_t NetscapePluginInstanceProxy::nextRequestID()
+{
+ uint32_t requestID = ++m_currentRequestID;
+
+ // We don't want to return the HashMap empty/deleted "special keys"
+ if (requestID == 0 || requestID == static_cast<uint32_t>(-1))
+ return nextRequestID();
+
+ return requestID;
+}
+
+void NetscapePluginInstanceProxy::invalidateRect(double x, double y, double width, double height)
+{
+ ASSERT(m_pluginView);
+
+ [m_pluginView setNeedsDisplayInRect:NSMakeRect(x, y, width, height)];
+}
+
+
} // namespace WebKit
#endif // USE(PLUGIN_HOST_PROCESS)
diff --git a/WebKit/mac/Plugins/Hosted/ProxyInstance.h b/WebKit/mac/Plugins/Hosted/ProxyInstance.h
index 014e388..1e2e2dc 100644
--- a/WebKit/mac/Plugins/Hosted/ProxyInstance.h
+++ b/WebKit/mac/Plugins/Hosted/ProxyInstance.h
@@ -52,6 +52,10 @@ public:
JSC::JSValuePtr fieldValue(JSC::ExecState*, const JSC::Bindings::Field*) const;
void setFieldValue(JSC::ExecState*, const JSC::Bindings::Field*, JSC::JSValuePtr) const;
+ void invalidate();
+
+ uint32_t objectID() const { return m_objectID; }
+
private:
ProxyInstance(PassRefPtr<JSC::Bindings::RootObject>, NetscapePluginInstanceProxy*, uint32_t objectID);
@@ -68,6 +72,8 @@ private:
virtual JSC::JSValuePtr defaultValue(JSC::ExecState*, JSC::PreferredPrimitiveType) const;
virtual JSC::JSValuePtr valueOf(JSC::ExecState*) const;
+ virtual void getPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&);
+
JSC::JSValuePtr stringValue(JSC::ExecState*) const;
JSC::JSValuePtr numberValue(JSC::ExecState*) const;
JSC::JSValuePtr booleanValue() const;
diff --git a/WebKit/mac/Plugins/Hosted/ProxyInstance.mm b/WebKit/mac/Plugins/Hosted/ProxyInstance.mm
index 8d6aaee..01e64ba 100644
--- a/WebKit/mac/Plugins/Hosted/ProxyInstance.mm
+++ b/WebKit/mac/Plugins/Hosted/ProxyInstance.mm
@@ -29,6 +29,9 @@
#import "NetscapePluginHostProxy.h"
#import "NetscapePluginInstanceProxy.h"
+#import <runtime/PropertyNameArray.h>
+#import <WebCore/IdentifierRep.h>
+#import <WebCore/JSDOMWindow.h>
#import <WebCore/npruntime_impl.h>
extern "C" {
@@ -38,6 +41,7 @@ extern "C" {
using namespace JSC;
using namespace JSC::Bindings;
using namespace std;
+using namespace WebCore;
namespace WebKit {
@@ -109,15 +113,20 @@ ProxyInstance::ProxyInstance(PassRefPtr<RootObject> rootObject, NetscapePluginIn
, m_instanceProxy(instanceProxy)
, m_objectID(objectID)
{
+ m_instanceProxy->addInstance(this);
}
ProxyInstance::~ProxyInstance()
{
deleteAllValues(m_fields);
deleteAllValues(m_methods);
+
+ if (!m_instanceProxy)
+ return;
- _WKPHNPObjectRelease(m_instanceProxy->hostProxy()->port(),
- m_instanceProxy->pluginID(), m_objectID);
+ m_instanceProxy->removeInstance(this);
+
+ invalidate();
}
JSC::Bindings::Class *ProxyInstance::getClass() const
@@ -128,12 +137,14 @@ JSC::Bindings::Class *ProxyInstance::getClass() const
JSValuePtr ProxyInstance::invoke(JSC::ExecState* exec, InvokeType type, uint64_t identifier, const JSC::ArgList& args)
{
RetainPtr<NSData*> arguments(m_instanceProxy->marshalValues(exec, args));
-
- if (_WKPHNPObjectInvoke(m_instanceProxy->hostProxy()->port(), m_instanceProxy->pluginID(), m_objectID,
+
+ uint32_t requestID = m_instanceProxy->nextRequestID();
+
+ if (_WKPHNPObjectInvoke(m_instanceProxy->hostProxy()->port(), m_instanceProxy->pluginID(), requestID, m_objectID,
type, identifier, (char*)[arguments.get() bytes], [arguments.get() length]) != KERN_SUCCESS)
return jsUndefined();
- auto_ptr<NetscapePluginInstanceProxy::BooleanAndDataReply> reply = m_instanceProxy->waitForReply<NetscapePluginInstanceProxy::BooleanAndDataReply>();
+ auto_ptr<NetscapePluginInstanceProxy::BooleanAndDataReply> reply = m_instanceProxy->waitForReply<NetscapePluginInstanceProxy::BooleanAndDataReply>(requestID);
if (!reply.get() || !reply->m_returnValue)
return jsUndefined();
@@ -151,12 +162,14 @@ JSValuePtr ProxyInstance::invokeMethod(ExecState* exec, const MethodList& method
bool ProxyInstance::supportsInvokeDefaultMethod() const
{
+ uint32_t requestID = m_instanceProxy->nextRequestID();
+
if (_WKPHNPObjectHasInvokeDefaultMethod(m_instanceProxy->hostProxy()->port(),
- m_instanceProxy->pluginID(),
+ m_instanceProxy->pluginID(), requestID,
m_objectID) != KERN_SUCCESS)
return false;
- auto_ptr<NetscapePluginInstanceProxy::BooleanReply> reply = m_instanceProxy->waitForReply<NetscapePluginInstanceProxy::BooleanReply>();
+ auto_ptr<NetscapePluginInstanceProxy::BooleanReply> reply = m_instanceProxy->waitForReply<NetscapePluginInstanceProxy::BooleanReply>(requestID);
if (reply.get() && reply->m_result)
return true;
@@ -170,12 +183,14 @@ JSValuePtr ProxyInstance::invokeDefaultMethod(ExecState* exec, const ArgList& ar
bool ProxyInstance::supportsConstruct() const
{
+ uint32_t requestID = m_instanceProxy->nextRequestID();
+
if (_WKPHNPObjectHasConstructMethod(m_instanceProxy->hostProxy()->port(),
- m_instanceProxy->pluginID(),
+ m_instanceProxy->pluginID(), requestID,
m_objectID) != KERN_SUCCESS)
return false;
- auto_ptr<NetscapePluginInstanceProxy::BooleanReply> reply = m_instanceProxy->waitForReply<NetscapePluginInstanceProxy::BooleanReply>();
+ auto_ptr<NetscapePluginInstanceProxy::BooleanReply> reply = m_instanceProxy->waitForReply<NetscapePluginInstanceProxy::BooleanReply>(requestID);
if (reply.get() && reply->m_result)
return true;
@@ -219,6 +234,36 @@ JSValuePtr ProxyInstance::valueOf(ExecState* exec) const
return stringValue(exec);
}
+void ProxyInstance::getPropertyNames(ExecState* exec, PropertyNameArray& nameArray)
+{
+ uint32_t requestID = m_instanceProxy->nextRequestID();
+
+ if (_WKPHNPObjectEnumerate(m_instanceProxy->hostProxy()->port(), m_instanceProxy->pluginID(), requestID, m_objectID) != KERN_SUCCESS)
+ return;
+
+ auto_ptr<NetscapePluginInstanceProxy::BooleanAndDataReply> reply = m_instanceProxy->waitForReply<NetscapePluginInstanceProxy::BooleanAndDataReply>(requestID);
+
+ if (!reply.get() || !reply->m_returnValue)
+ return;
+
+ RetainPtr<NSArray*> array = [NSPropertyListSerialization propertyListFromData:(NSData *)reply->m_result.get()
+ mutabilityOption:NSPropertyListImmutable
+ format:0
+ errorDescription:0];
+
+ for (NSNumber *number in array.get()) {
+ IdentifierRep* identifier = reinterpret_cast<IdentifierRep*>([number longLongValue]);
+ if (!IdentifierRep::isValid(identifier))
+ continue;
+
+ if (identifier->isString()) {
+ const char* str = identifier->string();
+ nameArray.add(Identifier(JSDOMWindow::commonJSGlobalData(), String::fromUTF8WithLatin1Fallback(str, strlen(str))));
+ } else
+ nameArray.add(Identifier::from(exec, identifier->number()));
+ }
+}
+
MethodList ProxyInstance::methodsNamed(const Identifier& identifier)
{
if (Method* method = m_methods.get(identifier.ustring().rep())) {
@@ -228,12 +273,14 @@ MethodList ProxyInstance::methodsNamed(const Identifier& identifier)
}
uint64_t methodName = reinterpret_cast<uint64_t>(_NPN_GetStringIdentifier(identifier.ascii()));
+ uint32_t requestID = m_instanceProxy->nextRequestID();
+
if (_WKPHNPObjectHasMethod(m_instanceProxy->hostProxy()->port(),
- m_instanceProxy->pluginID(),
+ m_instanceProxy->pluginID(), requestID,
m_objectID, methodName) != KERN_SUCCESS)
return MethodList();
- auto_ptr<NetscapePluginInstanceProxy::BooleanReply> reply = m_instanceProxy->waitForReply<NetscapePluginInstanceProxy::BooleanReply>();
+ auto_ptr<NetscapePluginInstanceProxy::BooleanReply> reply = m_instanceProxy->waitForReply<NetscapePluginInstanceProxy::BooleanReply>(requestID);
if (reply.get() && reply->m_result) {
Method* method = new ProxyMethod(methodName);
@@ -253,12 +300,14 @@ Field* ProxyInstance::fieldNamed(const Identifier& identifier)
return field;
uint64_t propertyName = reinterpret_cast<uint64_t>(_NPN_GetStringIdentifier(identifier.ascii()));
+ uint32_t requestID = m_instanceProxy->nextRequestID();
+
if (_WKPHNPObjectHasProperty(m_instanceProxy->hostProxy()->port(),
- m_instanceProxy->pluginID(),
+ m_instanceProxy->pluginID(), requestID,
m_objectID, propertyName) != KERN_SUCCESS)
return 0;
- auto_ptr<NetscapePluginInstanceProxy::BooleanReply> reply = m_instanceProxy->waitForReply<NetscapePluginInstanceProxy::BooleanReply>();
+ auto_ptr<NetscapePluginInstanceProxy::BooleanReply> reply = m_instanceProxy->waitForReply<NetscapePluginInstanceProxy::BooleanReply>(requestID);
if (reply.get() && reply->m_result) {
Field* field = new ProxyField(propertyName);
@@ -273,13 +322,14 @@ Field* ProxyInstance::fieldNamed(const Identifier& identifier)
JSC::JSValuePtr ProxyInstance::fieldValue(ExecState* exec, const Field* field) const
{
uint64_t serverIdentifier = static_cast<const ProxyField*>(field)->serverIdentifier();
+ uint32_t requestID = m_instanceProxy->nextRequestID();
if (_WKPHNPObjectGetProperty(m_instanceProxy->hostProxy()->port(),
- m_instanceProxy->pluginID(),
+ m_instanceProxy->pluginID(), requestID,
m_objectID, serverIdentifier) != KERN_SUCCESS)
return jsUndefined();
- auto_ptr<NetscapePluginInstanceProxy::BooleanAndDataReply> reply = m_instanceProxy->waitForReply<NetscapePluginInstanceProxy::BooleanAndDataReply>();
+ auto_ptr<NetscapePluginInstanceProxy::BooleanAndDataReply> reply = m_instanceProxy->waitForReply<NetscapePluginInstanceProxy::BooleanAndDataReply>(requestID);
if (!reply.get() || !reply->m_returnValue)
return jsUndefined();
@@ -289,19 +339,28 @@ JSC::JSValuePtr ProxyInstance::fieldValue(ExecState* exec, const Field* field) c
void ProxyInstance::setFieldValue(ExecState* exec, const Field* field, JSValuePtr value) const
{
uint64_t serverIdentifier = static_cast<const ProxyField*>(field)->serverIdentifier();
+ uint32_t requestID = m_instanceProxy->nextRequestID();
data_t valueData;
mach_msg_type_number_t valueLength;
m_instanceProxy->marshalValue(exec, value, valueData, valueLength);
kern_return_t kr = _WKPHNPObjectSetProperty(m_instanceProxy->hostProxy()->port(),
- m_instanceProxy->pluginID(),
+ m_instanceProxy->pluginID(), requestID,
m_objectID, serverIdentifier, valueData, valueLength);
mig_deallocate(reinterpret_cast<vm_address_t>(valueData), valueLength);
if (kr != KERN_SUCCESS)
return;
- auto_ptr<NetscapePluginInstanceProxy::BooleanReply> reply = m_instanceProxy->waitForReply<NetscapePluginInstanceProxy::BooleanReply>();
+ auto_ptr<NetscapePluginInstanceProxy::BooleanReply> reply = m_instanceProxy->waitForReply<NetscapePluginInstanceProxy::BooleanReply>(requestID);
+}
+
+void ProxyInstance::invalidate()
+{
+ if (NetscapePluginHostProxy* hostProxy = m_instanceProxy->hostProxy())
+ _WKPHNPObjectRelease(hostProxy->port(),
+ m_instanceProxy->pluginID(), m_objectID);
+ m_instanceProxy = 0;
}
} // namespace WebKit
diff --git a/WebKit/mac/Plugins/Hosted/WebHostedNetscapePluginView.h b/WebKit/mac/Plugins/Hosted/WebHostedNetscapePluginView.h
index 14b0dc1..8b68b7b 100644
--- a/WebKit/mac/Plugins/Hosted/WebHostedNetscapePluginView.h
+++ b/WebKit/mac/Plugins/Hosted/WebHostedNetscapePluginView.h
@@ -54,7 +54,7 @@ namespace WebKit {
attributeKeys:(NSArray *)keys
attributeValues:(NSArray *)values
loadManually:(BOOL)loadManually
- DOMElement:(DOMElement *)anElement;
+ element:(PassRefPtr<WebCore::HTMLPlugInElement>)element;
- (void)pluginHostDied;
@end
diff --git a/WebKit/mac/Plugins/Hosted/WebHostedNetscapePluginView.mm b/WebKit/mac/Plugins/Hosted/WebHostedNetscapePluginView.mm
index f30c2cb..c17d249 100644
--- a/WebKit/mac/Plugins/Hosted/WebHostedNetscapePluginView.mm
+++ b/WebKit/mac/Plugins/Hosted/WebHostedNetscapePluginView.mm
@@ -29,11 +29,13 @@
#import "NetscapePluginInstanceProxy.h"
#import "NetscapePluginHostManager.h"
#import "NetscapePluginHostProxy.h"
+#import "WebTextInputWindowController.h"
#import "WebView.h"
#import "WebViewInternal.h"
#import "WebUIDelegate.h"
#import <CoreFoundation/CoreFoundation.h>
+#import <WebCore/HTMLPlugInElement.h>
#import <WebCore/runtime.h>
#import <WebCore/runtime_root.h>
#import <WebCore/WebCoreObjCExtras.h>
@@ -66,9 +68,9 @@ extern "C" {
attributeKeys:(NSArray *)keys
attributeValues:(NSArray *)values
loadManually:(BOOL)loadManually
- DOMElement:(DOMElement *)element
+ element:(PassRefPtr<WebCore::HTMLPlugInElement>)element
{
- self = [super initWithFrame:frame pluginPackage:pluginPackage URL:URL baseURL:baseURL MIMEType:MIME attributeKeys:keys attributeValues:values loadManually:loadManually DOMElement:element];
+ self = [super initWithFrame:frame pluginPackage:pluginPackage URL:URL baseURL:baseURL MIMEType:MIME attributeKeys:keys attributeValues:values loadManually:loadManually element:element];
if (!self)
return nil;
@@ -149,7 +151,10 @@ extern "C" {
- (BOOL)shouldStop
{
- return YES;
+ if (!_proxy)
+ return YES;
+
+ return _proxy->shouldStop();
}
- (void)destroyPlugin
@@ -197,13 +202,17 @@ extern "C" {
ASSERT([self window]);
- NSWindow *theWindow = [self window];
+ NSWindow *window = [self window];
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter addObserver:self selector:@selector(windowFrameDidChange:)
- name:NSWindowDidMoveNotification object:theWindow];
+ name:NSWindowDidMoveNotification object:window];
[notificationCenter addObserver:self selector:@selector(windowFrameDidChange:)
- name:NSWindowDidResizeNotification object:theWindow];
+ name:NSWindowDidResizeNotification object:window];
+
+ if (_proxy)
+ _proxy->windowFrameChanged([window frame]);
+ [self updateAndSetWindow];
}
- (void)removeWindowObservers
@@ -245,10 +254,24 @@ extern "C" {
_proxy->mouseEvent(self, event, NPCocoaEventMouseExited);
}
+- (NSTextInputContext *)inputContext
+{
+ return [[WebTextInputWindowController sharedTextInputWindowController] inputContext];
+}
+
- (void)keyDown:(NSEvent *)event
{
- if (_isStarted && _proxy)
- _proxy->keyEvent(self, event, NPCocoaEventKeyDown);
+ if (!_isStarted || !_proxy)
+ return;
+
+ NSString *string = nil;
+ if ([[WebTextInputWindowController sharedTextInputWindowController] interpretKeyEvent:event string:&string]) {
+ if (string)
+ _proxy->insertText(string);
+ return;
+ }
+
+ _proxy->keyEvent(self, event, NPCocoaEventKeyDown);
}
- (void)keyUp:(NSEvent *)event
@@ -274,15 +297,32 @@ extern "C" {
- (void)drawRect:(NSRect)rect
{
if (_proxy) {
- if (_softwareRenderer)
- WKSoftwareCARendererRender(_softwareRenderer, (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort], NSRectToCGRect(rect));
+ if (_softwareRenderer) {
+ if ([NSGraphicsContext currentContextDrawingToScreen])
+ WKSoftwareCARendererRender(_softwareRenderer, (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort], NSRectToCGRect(rect));
+ else
+ _proxy->print(reinterpret_cast<CGContextRef>([[NSGraphicsContext currentContext] graphicsPort]), [self bounds].size.width, [self bounds].size.height);
+ }
+
return;
}
if (_pluginHostDied) {
- // Fill the area with a nice red color for now.
- [[NSColor redColor] set];
- NSRectFill(rect);
+ static NSImage *nullPlugInImage;
+ if (!nullPlugInImage) {
+ NSBundle *bundle = [NSBundle bundleForClass:[WebHostedNetscapePluginView class]];
+ nullPlugInImage = [[NSImage alloc] initWithContentsOfFile:[bundle pathForResource:@"nullplugin" ofType:@"tiff"]];
+ [nullPlugInImage setFlipped:YES];
+ }
+
+ if (!nullPlugInImage)
+ return;
+
+ NSSize imageSize = [nullPlugInImage size];
+ NSSize viewSize = [self bounds].size;
+
+ NSPoint point = NSMakePoint((viewSize.width - imageSize.width) / 2.0, (viewSize.height - imageSize.height) / 2.0);
+ [nullPlugInImage drawAtPoint:point fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];
}
}
diff --git a/WebKit/mac/Plugins/Hosted/WebKitPluginClient.defs b/WebKit/mac/Plugins/Hosted/WebKitPluginClient.defs
index 1aab38d..6128517 100644
--- a/WebKit/mac/Plugins/Hosted/WebKitPluginClient.defs
+++ b/WebKit/mac/Plugins/Hosted/WebKitPluginClient.defs
@@ -28,14 +28,14 @@
// FIXME: Come up with a better name.
subsystem WebKitPluginClient 300;
-serverprefix WKPC;
-userprefix _WKPC;
+serverprefix WK;
+userprefix _WK;
-simpleroutine StatusText(clientPort :mach_port_t;
+simpleroutine PCStatusText(clientPort :mach_port_t;
pluginID :uint32_t;
text :data_t);
-routine LoadURL(clientPort :mach_port_t;
+routine PCLoadURL(clientPort :mach_port_t;
pluginID :uint32_t;
url :data_t;
target :data_t;
@@ -44,12 +44,12 @@ routine LoadURL(clientPort :mach_port_t;
out resultCode :uint16_t;
out requestID :uint32_t);
-simpleroutine CancelLoadURL(clientPort :mach_port_t;
+simpleroutine PCCancelLoadURL(clientPort :mach_port_t;
pluginID :uint32_t;
streamID :uint32_t;
reason :int16_t);
-simpleroutine InvalidateRect(clientPort :mach_port_t;
+simpleroutine PCInvalidateRect(clientPort :mach_port_t;
pluginID :uint32_t;
x :double;
y :double;
@@ -58,109 +58,119 @@ simpleroutine InvalidateRect(clientPort :mach_port_t;
// NPRuntime
-routine GetStringIdentifier(clientPort :mach_port_t;
+routine PCGetStringIdentifier(clientPort :mach_port_t;
name :data_t;
out identifier :uint64_t);
-routine GetIntIdentifier(clientPort :mach_port_t;
+routine PCGetIntIdentifier(clientPort :mach_port_t;
value :int32_t;
out identifier: uint64_t);
-routine GetWindowNPObject(clientPort :mach_port_t;
+routine PCGetWindowNPObject(clientPort :mach_port_t;
pluginID :uint32_t;
out objectID :uint32_t);
+routine PCGetPluginElementNPObject(clientPort :mach_port_t;
+ pluginID :uint32_t;
+ out objectID :uint32_t);
-routine ReleaseObject(clientPort :mach_port_t;
+routine PCReleaseObject(clientPort :mach_port_t;
pluginID :uint32_t;
objectID :uint32_t);
-simpleroutine Evaluate(clientPort :mach_port_t;
+simpleroutine PCEvaluate(clientPort :mach_port_t;
pluginID :uint32_t;
+ requestID :uint32_t;
objectID :uint32_t;
script :data_t);
-simpleroutine Invoke(clientPort :mach_port_t;
+simpleroutine PCInvoke(clientPort :mach_port_t;
pluginID :uint32_t;
+ requestID :uint32_t;
objectID :uint32_t;
methodNameIdentifier :uint64_t;
arguments :data_t);
-routine InvokeDefault(clientPort :mach_port_t;
+simpleroutine PCInvokeDefault(clientPort :mach_port_t;
pluginID :uint32_t;
+ requestID :uint32_t;
objectID :uint32_t;
- arguments :data_t;
- out returnValue :boolean_t;
- out result :data_t, dealloc);
+ arguments :data_t);
-routine Construct(clientPort :mach_port_t;
+routine PCConstruct(clientPort :mach_port_t;
pluginID :uint32_t;
objectID :uint32_t;
arguments :data_t;
out returnValue :boolean_t;
out result :data_t, dealloc);
-routine GetProperty(clientPort :mach_port_t;
- pluginID :uint32_t;
- objectID :uint32_t;
- propertyNameIdentifier :uint64_t;
- out returnValue :boolean_t;
- out result :data_t, dealloc);
+simpleroutine PCGetProperty(clientPort :mach_port_t;
+ pluginID :uint32_t;
+ requestID :uint32_t;
+ objectID :uint32_t;
+ propertyNameIdentifier :uint64_t);
-routine SetProperty(clientPort :mach_port_t;
+routine PCSetProperty(clientPort :mach_port_t;
pluginID :uint32_t;
objectID :uint32_t;
propertyNameIdentifier :uint64_t;
value :data_t;
out returnValue :boolean_t);
-routine RemoveProperty(clientPort :mach_port_t;
+routine PCRemoveProperty(clientPort :mach_port_t;
pluginID :uint32_t;
objectID :uint32_t;
propertyNameIdentifier :uint64_t;
out returnValue :boolean_t);
-routine HasProperty(clientPort :mach_port_t;
- pluginID :uint32_t;
- objectID :uint32_t;
- propertyNameIdentifier :uint64_t;
- out returnValue :boolean_t);
+simpleroutine PCHasProperty(clientPort :mach_port_t;
+ pluginID :uint32_t;
+ requestID :uint32_t;
+ objectID :uint32_t;
+ propertyNameIdentifier :uint64_t);
-routine HasMethod(clientPort :mach_port_t;
- pluginID :uint32_t;
- objectID :uint32_t;
- methodNameIdentifier :uint64_t;
- out returnValue :boolean_t);
+simpleroutine PCHasMethod(clientPort :mach_port_t;
+ pluginID :uint32_t;
+ requestID :uint32_t;
+ objectID :uint32_t;
+ methodNameIdentifier :uint64_t);
-routine IdentifierInfo(clientPort :mach_port_t;
+routine PCIdentifierInfo(clientPort :mach_port_t;
identifier :uint64_t;
out info :data_t, dealloc);
+simpleroutine PCEnumerate(clientPort :mach_port_t;
+ pluginID :uint32_t;
+ requestID :uint32_t;
+ objectID :uint32_t);
+
// Misc
-simpleroutine SetMenuBarVisible(clientPort :mach_port_t;
+simpleroutine PCSetMenuBarVisible(clientPort :mach_port_t;
visible :boolean_t);
-simpleroutine SetModal(clientPort :mach_port_t;
+simpleroutine PCSetModal(clientPort :mach_port_t;
modal :boolean_t);
// Replies
-simpleroutine InstantiatePluginReply(clientPort :mach_port_t;
+simpleroutine PCInstantiatePluginReply(clientPort :mach_port_t;
pluginID :uint32_t;
+ requestID :uint32_t;
result :kern_return_t;
renderContextID :uint32_t;
useSoftwareRenderer :boolean_t);
-simpleroutine GetScriptableNPObjectReply(clientPort :mach_port_t;
+simpleroutine PCGetScriptableNPObjectReply(clientPort :mach_port_t;
pluginID :uint32_t;
+ requestID :uint32_t;
objectID :uint32_t);
-simpleroutine BooleanReply(clientPort :mach_port_t;
- pluginID :uint32_t;
- result :boolean_t);
+simpleroutine PCBooleanReply(clientPort :mach_port_t;
+ pluginID :uint32_t;
+ requestID :uint32_t;
+ result :boolean_t);
-simpleroutine BooleanAndDataReply(clientPort :mach_port_t;
- pluginID :uint32_t;
- returnValue :boolean_t;
- result :data_t);
-
-
+simpleroutine PCBooleanAndDataReply(clientPort :mach_port_t;
+ pluginID :uint32_t;
+ requestID :uint32_t;
+ returnValue :boolean_t;
+ result :data_t);
diff --git a/WebKit/mac/Plugins/Hosted/WebKitPluginHost.defs b/WebKit/mac/Plugins/Hosted/WebKitPluginHost.defs
index 4fe96f9..c6c38aa 100644
--- a/WebKit/mac/Plugins/Hosted/WebKitPluginHost.defs
+++ b/WebKit/mac/Plugins/Hosted/WebKitPluginHost.defs
@@ -27,31 +27,36 @@
subsystem WebKitPluginHost 300;
-serverprefix WKPH;
-userprefix _WKPH;
+serverprefix WK;
+userprefix _WK;
-routine CheckInWithPluginHost(pluginHostPort :mach_port_t;
+routine PHCheckInWithPluginHost(pluginHostPort :mach_port_t;
options :plist_bytes_t;
clientPort :mach_port_make_send_t;
- renderPort :mach_port_copy_send_t);
-
-simpleroutine InstantiatePlugin(pluginHostPort :mach_port_t;
+ clientPSNHigh :uint32_t;
+ clientPSNLow :uint32_t;
+ renderPort :mach_port_copy_send_t;
+ out pluginHostPSNHigh :uint32_t;
+ out pluginHostPSNLow :uint32_t);
+
+simpleroutine PHInstantiatePlugin(pluginHostPort :mach_port_t;
+ requestID :uint32_t;
options :plist_bytes_t;
pluginID :uint32_t);
-simpleroutine ResizePluginInstance(pluginHostPort :mach_port_t;
+simpleroutine PHResizePluginInstance(pluginHostPort :mach_port_t;
pluginID :uint32_t;
x :double;
y :double;
width :double;
height :double);
-simpleroutine PluginInstanceFocusChanged(pluginHostPort :mach_port_t;
+simpleroutine PHPluginInstanceFocusChanged(pluginHostPort :mach_port_t;
pluginID :uint32_t;
hasFocus :boolean_t);
-simpleroutine PluginInstanceWindowFocusChanged(pluginHostPort :mach_port_t;
+simpleroutine PHPluginInstanceWindowFocusChanged(pluginHostPort :mach_port_t;
pluginID :uint32_t;
hasFocus :boolean_t);
-simpleroutine PluginInstanceWindowFrameChanged(pluginHostPort :mach_port_t;
+simpleroutine PHPluginInstanceWindowFrameChanged(pluginHostPort :mach_port_t;
pluginID :uint32_t;
x :double;
y :double;
@@ -59,7 +64,7 @@ simpleroutine PluginInstanceWindowFrameChanged(pluginHostPort :mach_port_t;
height :double;
maxScreenY :double);
-simpleroutine PluginInstanceMouseEvent(pluginHostPort :mach_port_t;
+simpleroutine PHPluginInstanceMouseEvent(pluginHostPort :mach_port_t;
pluginID :uint32_t;
timestamp :double;
eventType :uint32_t;
@@ -75,7 +80,7 @@ simpleroutine PluginInstanceMouseEvent(pluginHostPort :mach_port_t;
deltaY :double;
deltaZ: double);
-simpleroutine PluginInstanceKeyboardEvent(pluginHostPort :mach_port_t;
+simpleroutine PHPluginInstanceKeyboardEvent(pluginHostPort :mach_port_t;
pluginID :uint32_t;
timestamp :double;
eventType :uint32_t;
@@ -84,19 +89,30 @@ simpleroutine PluginInstanceKeyboardEvent(pluginHostPort :mach_port_t;
charactersIgnoringModifiers :data_t;
isARepeat :boolean_t;
keyCode :uint16_t);
-
-simpleroutine PluginInstanceStartTimers(pluginHostPort :mach_port_t;
+
+simpleroutine PHPluginInstanceInsertText(pluginHostPort :mach_port_t;
+ pluginID :uint32_t;
+ text :data_t);
+
+simpleroutine PHPluginInstanceStartTimers(pluginHostPort :mach_port_t;
pluginID :uint32_t;
throttleTimers :boolean_t);
-simpleroutine PluginInstanceStopTimers(pluginHostPort :mach_port_t;
+simpleroutine PHPluginInstanceStopTimers(pluginHostPort :mach_port_t;
pluginID :uint32_t);
-simpleroutine DestroyPluginInstance(pluginHostPort :mach_port_t;
- pluginID :uint32_t);
+simpleroutine PHPluginInstancePrint(pluginHostPort :mach_port_t;
+ pluginID :uint32_t;
+ requestID :uint32_t;
+ width :uint32_t;
+ height :uint32_t);
+
+simpleroutine PHDestroyPluginInstance(pluginHostPort :mach_port_t;
+ pluginID :uint32_t;
+ requestID :uint32_t);
// Streams
-simpleroutine StartStream(pluginHostPort :mach_port_t;
+simpleroutine PHStartStream(pluginHostPort :mach_port_t;
pluginID :uint32_t;
streamID :uint32_t;
responseURL :data_t;
@@ -105,68 +121,92 @@ simpleroutine StartStream(pluginHostPort :mach_port_t;
mimeType :data_t;
headers :data_t);
-simpleroutine StreamDidReceiveData(pluginHostPort :mach_port_t;
+simpleroutine PHStreamDidReceiveData(pluginHostPort :mach_port_t;
pluginID :uint32_t;
streamID :uint32_t;
data :data_t);
-simpleroutine StreamDidFinishLoading(pluginHostPort :mach_port_t;
+simpleroutine PHStreamDidFinishLoading(pluginHostPort :mach_port_t;
pluginID :uint32_t;
streamID :uint32_t);
-simpleroutine StreamDidFail(pluginHostPort :mach_port_t;
+simpleroutine PHStreamDidFail(pluginHostPort :mach_port_t;
pluginID :uint32_t;
streamID :uint32_t;
reason :int16_t);
+simpleroutine PHLoadURLNotify(pluginHostPort :mach_port_t;
+ pluginID :uint32_t;
+ requestID :uint32_t;
+ reason :int16_t);
+
// NPRuntime
-simpleroutine GetScriptableNPObject(pluginHostPort :mach_port_t;
- pluginID :uint32_t);
+simpleroutine PHGetScriptableNPObject(pluginHostPort :mach_port_t;
+ pluginID :uint32_t;
+ requestID :uint32_t);
-simpleroutine NPObjectHasProperty(pluginHostPort :mach_port_t;
+simpleroutine PHNPObjectHasProperty(pluginHostPort :mach_port_t;
pluginID :uint32_t;
+ requestID :uint32_t;
objectID :uint32_t;
propertyName :uint64_t);
-simpleroutine NPObjectHasMethod(pluginHostPort :mach_port_t;
+simpleroutine PHNPObjectHasMethod(pluginHostPort :mach_port_t;
pluginID :uint32_t;
+ requestID :uint32_t;
objectID :uint32_t;
methodName :uint64_t);
-simpleroutine NPObjectInvoke(pluginHostPort :mach_port_t;
+simpleroutine PHNPObjectInvoke(pluginHostPort :mach_port_t;
pluginID :uint32_t;
+ requestID :uint32_t;
objectID :uint32_t;
invokeType :uint32_t;
methodName :uint64_t;
arguments :data_t);
-simpleroutine NPObjectHasInvokeDefaultMethod(pluginHostPort :mach_port_t;
+simpleroutine PHNPObjectHasInvokeDefaultMethod(pluginHostPort :mach_port_t;
pluginID :uint32_t;
+ requestID :uint32_t;
objectID :uint32_t);
-simpleroutine NPObjectHasConstructMethod(pluginHostPort :mach_port_t;
+simpleroutine PHNPObjectHasConstructMethod(pluginHostPort :mach_port_t;
pluginID :uint32_t;
+ requestID :uint32_t;
objectID :uint32_t);
-simpleroutine NPObjectGetProperty(pluginHostPort :mach_port_t;
+simpleroutine PHNPObjectGetProperty(pluginHostPort :mach_port_t;
pluginID :uint32_t;
+ requestID :uint32_t;
objectID :uint32_t;
propertyName :uint64_t);
-simpleroutine NPObjectSetProperty(pluginHostPort :mach_port_t;
+simpleroutine PHNPObjectSetProperty(pluginHostPort :mach_port_t;
pluginID :uint32_t;
+ requestID :uint32_t;
objectID :uint32_t;
propertyName :uint64_t;
value :data_t);
-simpleroutine NPObjectRelease(pluginHostPort :mach_port_t;
+simpleroutine PHNPObjectRelease(pluginHostPort :mach_port_t;
pluginID :uint32_t;
objectID :uint32_t);
+simpleroutine PHNPObjectEnumerate(pluginHostPort :mach_port_t;
+ pluginID :uint32_t;
+ requestID :uint32_t;
+ objectID :uint32_t);
+
// Replies
-simpleroutine EvaluateReply(pluginHostPort :mach_port_t;
- pluginID :uint32_t;
- returnValue :boolean_t;
- result :data_t);
+simpleroutine PHBooleanReply(clientPort :mach_port_t;
+ pluginID :uint32_t;
+ requestID :uint32_t;
+ result :boolean_t);
+
+simpleroutine PHBooleanAndDataReply(pluginHostPort :mach_port_t;
+ pluginID :uint32_t;
+ requestID :uint32_t;
+ returnValue :boolean_t;
+ result :data_t);
diff --git a/WebKit/mac/Plugins/Hosted/WebTextInputWindowController.h b/WebKit/mac/Plugins/Hosted/WebTextInputWindowController.h
new file mode 100644
index 0000000..9f036ee
--- /dev/null
+++ b/WebKit/mac/Plugins/Hosted/WebTextInputWindowController.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if USE(PLUGIN_HOST_PROCESS)
+
+#ifndef WebTextInputWindowController_h
+#define WebTextInputWindowController_h
+
+@class WebTextInputPanel;
+
+@interface WebTextInputWindowController : NSObject {
+ WebTextInputPanel *_panel;
+}
+
++ (WebTextInputWindowController *)sharedTextInputWindowController;
+
+- (NSTextInputContext *)inputContext;
+- (BOOL)interpretKeyEvent:(NSEvent *)event string:(NSString **)string;
+
+@end
+
+#endif // WebTextInputWindowController_h
+
+#endif // USE(PLUGIN_HOST_PROCESS)
diff --git a/WebKit/mac/Plugins/Hosted/WebTextInputWindowController.m b/WebKit/mac/Plugins/Hosted/WebTextInputWindowController.m
new file mode 100644
index 0000000..c168e6e
--- /dev/null
+++ b/WebKit/mac/Plugins/Hosted/WebTextInputWindowController.m
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if USE(PLUGIN_HOST_PROCESS)
+
+#import "WebTextInputWindowController.h"
+
+#import <WebKitSystemInterface.h>
+
+@interface WebTextInputPanel : NSPanel {
+ NSTextView *_inputTextView;
+}
+
+- (NSTextInputContext *)_inputContext;
+- (BOOL)_interpretKeyEvent:(NSEvent *)event string:(NSString **)string;
+
+@end
+
+#define inputWindowHeight 20
+
+@implementation WebTextInputPanel
+
+- (void)dealloc
+{
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
+
+ [_inputTextView release];
+
+ [super dealloc];
+}
+
+- (id)init
+{
+ self = [super initWithContentRect:NSZeroRect styleMask:WKGetInputPanelWindowStyle() backing:NSBackingStoreBuffered defer:YES];
+ if (!self)
+ return nil;
+
+ // Set the frame size.
+ NSRect visibleFrame = [[NSScreen mainScreen] visibleFrame];
+ NSRect frame = NSMakeRect(visibleFrame.origin.x, visibleFrame.origin.y, visibleFrame.size.width, inputWindowHeight);
+
+ [self setFrame:frame display:NO];
+
+ _inputTextView = [[NSTextView alloc] initWithFrame:[self.contentView frame]];
+ _inputTextView.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable | NSViewMaxXMargin | NSViewMinXMargin | NSViewMaxYMargin | NSViewMinYMargin;
+
+ NSScrollView* scrollView = [[NSScrollView alloc] initWithFrame:[self.contentView frame]];
+ scrollView.documentView = _inputTextView;
+ self.contentView = scrollView;
+ [scrollView release];
+
+ [self setFloatingPanel:YES];
+
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(_keyboardInputSourceChanged:)
+ name:NSTextInputContextKeyboardSelectionDidChangeNotification
+ object:nil];
+
+ return self;
+}
+
+- (void)_keyboardInputSourceChanged:(NSNotification *)notification
+{
+ [_inputTextView setString:@""];
+ [self orderOut:nil];
+}
+
+- (BOOL)_interpretKeyEvent:(NSEvent *)event string:(NSString **)string
+{
+ BOOL hadMarkedText = [_inputTextView hasMarkedText];
+
+ *string = nil;
+
+ if (![[_inputTextView inputContext] handleEvent:event])
+ return NO;
+
+ if ([_inputTextView hasMarkedText]) {
+ // Don't show the input method window for dead keys
+ if ([[event characters] length] > 0)
+ [self orderFront:nil];
+
+ return YES;
+ }
+
+ if (hadMarkedText) {
+ [self orderOut:nil];
+
+ NSString *text = [[_inputTextView textStorage] string];
+ if ([text length] > 0)
+ *string = [[text copy] autorelease];
+ }
+
+ [_inputTextView setString:@""];
+ return hadMarkedText;
+}
+
+- (NSTextInputContext *)_inputContext
+{
+ return [_inputTextView inputContext];
+}
+
+@end
+
+@implementation WebTextInputWindowController
+
++ (WebTextInputWindowController *)sharedTextInputWindowController
+{
+ static WebTextInputWindowController *textInputWindowController;
+ if (!textInputWindowController)
+ textInputWindowController = [[WebTextInputWindowController alloc] init];
+
+ return textInputWindowController;
+}
+
+- (id)init
+{
+ self = [super init];
+ if (!self)
+ return nil;
+
+ _panel = [[WebTextInputPanel alloc] init];
+
+ return self;
+}
+
+- (NSTextInputContext *)inputContext
+{
+ return [_panel _inputContext];
+}
+
+- (BOOL)interpretKeyEvent:(NSEvent *)event string:(NSString **)string
+{
+ return [_panel _interpretKeyEvent:event string:string];
+}
+
+@end
+
+#endif // USE(PLUGIN_HOST_PROCESS)
+