diff options
Diffstat (limited to 'WebKit/mac/Plugins/Hosted')
-rw-r--r-- | WebKit/mac/Plugins/Hosted/HostedNetscapePluginStream.mm | 18 | ||||
-rw-r--r-- | WebKit/mac/Plugins/Hosted/NetscapePluginHostManager.h | 4 | ||||
-rw-r--r-- | WebKit/mac/Plugins/Hosted/NetscapePluginHostManager.mm | 74 | ||||
-rw-r--r-- | WebKit/mac/Plugins/Hosted/NetscapePluginHostProxy.h | 16 | ||||
-rw-r--r-- | WebKit/mac/Plugins/Hosted/NetscapePluginHostProxy.mm | 468 | ||||
-rw-r--r-- | WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.h | 67 | ||||
-rw-r--r-- | WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.mm | 266 | ||||
-rw-r--r-- | WebKit/mac/Plugins/Hosted/ProxyInstance.h | 6 | ||||
-rw-r--r-- | WebKit/mac/Plugins/Hosted/ProxyInstance.mm | 93 | ||||
-rw-r--r-- | WebKit/mac/Plugins/Hosted/WebHostedNetscapePluginView.h | 2 | ||||
-rw-r--r-- | WebKit/mac/Plugins/Hosted/WebHostedNetscapePluginView.mm | 66 | ||||
-rw-r--r-- | WebKit/mac/Plugins/Hosted/WebKitPluginClient.defs | 108 | ||||
-rw-r--r-- | WebKit/mac/Plugins/Hosted/WebKitPluginHost.defs | 110 | ||||
-rw-r--r-- | WebKit/mac/Plugins/Hosted/WebTextInputWindowController.h | 46 | ||||
-rw-r--r-- | WebKit/mac/Plugins/Hosted/WebTextInputWindowController.m | 161 |
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) + |