diff options
Diffstat (limited to 'WebKit/mac/Plugins')
33 files changed, 1551 insertions, 832 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) + diff --git a/WebKit/mac/Plugins/WebBaseNetscapePluginStream.mm b/WebKit/mac/Plugins/WebBaseNetscapePluginStream.mm index a29be2d..96f7644 100644 --- a/WebKit/mac/Plugins/WebBaseNetscapePluginStream.mm +++ b/WebKit/mac/Plugins/WebBaseNetscapePluginStream.mm @@ -43,6 +43,7 @@ #import <WebCore/Frame.h> #import <WebCore/FrameLoader.h> #import <WebCore/WebCoreObjCExtras.h> +#import <WebCore/WebCoreURLResponse.h> #import <WebKitSystemInterface.h> #import <wtf/HashMap.h> #import <wtf/StdLibExtras.h> @@ -53,6 +54,26 @@ using namespace WebCore; static NSString *CarbonPathFromPOSIXPath(NSString *posixPath); +class PluginStopDeferrer { +public: + PluginStopDeferrer(WebNetscapePluginView* pluginView) + : m_pluginView(pluginView) + { + ASSERT(m_pluginView); + + [m_pluginView.get() willCallPlugInFunction]; + } + + ~PluginStopDeferrer() + { + ASSERT(m_pluginView); + [m_pluginView.get() didCallPlugInFunction]; + } + +private: + RetainPtr<WebNetscapePluginView> m_pluginView; +}; + typedef HashMap<NPStream*, NPP> StreamMap; static StreamMap& streams() { @@ -217,9 +238,12 @@ void WebNetscapePluginStream::startStream(NSURL *url, long long expectedContentL // FIXME: Need a way to check if stream is seekable - [m_pluginView.get() willCallPlugInFunction]; - NPError npErr = m_pluginFuncs->newstream(m_plugin, (char *)[m_mimeType.get() UTF8String], &m_stream, NO, &m_transferMode); - [m_pluginView.get() didCallPlugInFunction]; + NPError npErr; + { + PluginStopDeferrer deferrer(m_pluginView.get()); + npErr = m_pluginFuncs->newstream(m_plugin, (char *)[m_mimeType.get() UTF8String], &m_stream, NO, &m_transferMode); + } + LOG(Plugins, "NPP_NewStream URL=%@ MIME=%@ error=%d", m_responseURL.get(), m_mimeType.get(), npErr); if (npErr != NPERR_NO_ERROR) { @@ -324,7 +348,7 @@ void WebNetscapePluginStream::didReceiveResponse(NetscapePlugInStreamLoader*, co // startStreamResponseURL:... will null-terminate. } - startStream([r URL], expectedContentLength, WKGetNSURLResponseLastModifiedDate(r), [r MIMEType], theHeaders); + startStream([r URL], expectedContentLength, WKGetNSURLResponseLastModifiedDate(r), [r _webcore_MIMEType], theHeaders); } void WebNetscapePluginStream::startStreamWithResponse(NSURLResponse *response) @@ -339,12 +363,11 @@ bool WebNetscapePluginStream::wantsAllStreams() const void *value = 0; NPError error; - [m_pluginView.get() willCallPlugInFunction]; { + PluginStopDeferrer deferrer(m_pluginView.get()); JSC::JSLock::DropAllLocks dropAllLocks(false); error = m_pluginFuncs->getvalue(m_plugin, NPPVpluginWantsAllNetworkStreams, &value); } - [m_pluginView.get() didCallPlugInFunction]; if (error != NPERR_NO_ERROR) return false; @@ -369,9 +392,9 @@ void WebNetscapePluginStream::destroyStream() ASSERT(m_path); NSString *carbonPath = CarbonPathFromPOSIXPath(m_path.get()); ASSERT(carbonPath != NULL); - [m_pluginView.get() willCallPlugInFunction]; + + PluginStopDeferrer deferrer(m_pluginView.get()); m_pluginFuncs->asfile(m_plugin, &m_stream, [carbonPath fileSystemRepresentation]); - [m_pluginView.get() didCallPlugInFunction]; LOG(Plugins, "NPP_StreamAsFile responseURL=%@ path=%s", m_responseURL.get(), carbonPath); } @@ -394,12 +417,11 @@ void WebNetscapePluginStream::destroyStream() } if (m_newStreamSuccessful) { - [m_pluginView.get() willCallPlugInFunction]; + PluginStopDeferrer deferrer(m_pluginView.get()); #if !LOG_DISABLED NPError npErr = #endif m_pluginFuncs->destroystream(m_plugin, &m_stream, m_reason); - [m_pluginView.get() didCallPlugInFunction]; LOG(Plugins, "NPP_DestroyStream responseURL=%@ error=%d", m_responseURL.get(), npErr); } @@ -415,9 +437,8 @@ void WebNetscapePluginStream::destroyStream() if (m_sendNotification) { // NPP_URLNotify expects the request URL, not the response URL. - [m_pluginView.get() willCallPlugInFunction]; + PluginStopDeferrer deferrer(m_pluginView.get()); m_pluginFuncs->urlnotify(m_plugin, [m_requestURL.get() _web_URLCString], m_reason, m_notifyData); - [m_pluginView.get() didCallPlugInFunction]; LOG(Plugins, "NPP_URLNotify requestURL=%@ reason=%d", m_requestURL.get(), m_reason); } @@ -488,9 +509,8 @@ void WebNetscapePluginStream::deliverData() int32 totalBytesDelivered = 0; while (totalBytesDelivered < totalBytes) { - [m_pluginView.get() willCallPlugInFunction]; + PluginStopDeferrer deferrer(m_pluginView.get()); int32 deliveryBytes = m_pluginFuncs->writeready(m_plugin, &m_stream); - [m_pluginView.get() didCallPlugInFunction]; LOG(Plugins, "NPP_WriteReady responseURL=%@ bytes=%d", m_responseURL.get(), deliveryBytes); if (m_isTerminated) @@ -504,9 +524,8 @@ void WebNetscapePluginStream::deliverData() } else { deliveryBytes = MIN(deliveryBytes, totalBytes - totalBytesDelivered); NSData *subdata = [m_deliveryData.get() subdataWithRange:NSMakeRange(totalBytesDelivered, deliveryBytes)]; - [m_pluginView.get() willCallPlugInFunction]; + PluginStopDeferrer deferrer(m_pluginView.get()); deliveryBytes = m_pluginFuncs->write(m_plugin, &m_stream, m_offset, [subdata length], (void *)[subdata bytes]); - [m_pluginView.get() didCallPlugInFunction]; if (deliveryBytes < 0) { // Netscape documentation says that a negative result from NPP_Write means cancel the load. cancelLoadAndDestroyStreamWithError(pluginCancelledConnectionError()); @@ -523,9 +542,8 @@ void WebNetscapePluginStream::deliverData() if (totalBytesDelivered < totalBytes) { NSMutableData *newDeliveryData = [[NSMutableData alloc] initWithCapacity:totalBytes - totalBytesDelivered]; [newDeliveryData appendBytes:(char *)[m_deliveryData.get() bytes] + totalBytesDelivered length:totalBytes - totalBytesDelivered]; - [m_deliveryData.get() release]; - m_deliveryData = newDeliveryData; - [newDeliveryData release]; + + m_deliveryData.adoptNS(newDeliveryData); } else { [m_deliveryData.get() setLength:0]; if (m_reason != WEB_REASON_NONE) diff --git a/WebKit/mac/Plugins/WebBaseNetscapePluginView.h b/WebKit/mac/Plugins/WebBaseNetscapePluginView.h index b2ea2b1..ec0a3df 100644 --- a/WebKit/mac/Plugins/WebBaseNetscapePluginView.h +++ b/WebKit/mac/Plugins/WebBaseNetscapePluginView.h @@ -31,6 +31,8 @@ #import "WebNetscapePluginPackage.h" +#import <wtf/PassRefPtr.h> +#import <wtf/RefPtr.h> #import <wtf/RetainPtr.h> @class DOMElement; @@ -38,6 +40,10 @@ @class WebFrame; @class WebView; +namespace WebCore { + class HTMLPlugInElement; +} + @interface WebBaseNetscapePluginView : NSView { RetainPtr<WebNetscapePluginPackage> _pluginPackage; @@ -52,7 +58,7 @@ BOOL _hasFocus; BOOL _isCompletelyObscured; - RetainPtr<DOMElement> _element; + RefPtr<WebCore::HTMLPlugInElement> _element; RetainPtr<NSString> _MIMEType; RetainPtr<NSURL> _baseURL; RetainPtr<NSURL> _sourceURL; @@ -68,7 +74,7 @@ attributeKeys:(NSArray *)keys attributeValues:(NSArray *)values loadManually:(BOOL)loadManually - DOMElement:(DOMElement *)anElement; + element:(PassRefPtr<WebCore::HTMLPlugInElement>)element; - (WebNetscapePluginPackage *)pluginPackage; @@ -83,6 +89,7 @@ - (WebDataSource *)dataSource; - (WebView *)webView; - (NSWindow *)currentWindow; +- (WebCore::HTMLPlugInElement*)element; - (void)removeTrackingRect; - (void)resetTrackingRect; diff --git a/WebKit/mac/Plugins/WebBaseNetscapePluginView.mm b/WebKit/mac/Plugins/WebBaseNetscapePluginView.mm index a2a8b50..26057fa 100644 --- a/WebKit/mac/Plugins/WebBaseNetscapePluginView.mm +++ b/WebKit/mac/Plugins/WebBaseNetscapePluginView.mm @@ -44,7 +44,9 @@ #import <WebCore/Element.h> #import <WebCore/Frame.h> #import <WebCore/FrameLoader.h> +#import <WebCore/HTMLPlugInElement.h> #import <WebCore/Page.h> +#import <WebCore/RenderView.h> #import <WebKit/DOMPrivate.h> #import <runtime/InitializeThreading.h> #import <wtf/Assertions.h> @@ -73,14 +75,14 @@ using namespace WebCore; attributeKeys:(NSArray *)keys attributeValues:(NSArray *)values loadManually:(BOOL)loadManually - DOMElement:(DOMElement *)anElement + element:(PassRefPtr<WebCore::HTMLPlugInElement>)element { self = [super initWithFrame:frame]; if (!self) return nil; _pluginPackage = pluginPackage; - _element = anElement; + _element = element; _sourceURL.adoptNS([URL copy]); _baseURL.adoptNS([baseURL copy]); _MIMEType.adoptNS([MIME copy]); @@ -237,11 +239,23 @@ using namespace WebCore; [self startTimers]; } +- (NSRect)_windowClipRect +{ + RenderObject* renderer = _element->renderer(); + + if (renderer && renderer->view()) { + if (FrameView* frameView = renderer->view()->frameView()) + return frameView->windowClipRectForLayer(renderer->enclosingLayer(), true); + } + + return NSZeroRect; +} + - (NSRect)visibleRect { // WebCore may impose an additional clip (via CSS overflow or clip properties). Fetch // that clip now. - return NSIntersectionRect([self convertRect:[_element.get() _windowClipRect] fromView:nil], [super visibleRect]); + return NSIntersectionRect([self convertRect:[self _windowClipRect] fromView:nil], [super visibleRect]); } - (BOOL)acceptsFirstResponder @@ -558,7 +572,7 @@ using namespace WebCore; - (WebDataSource *)dataSource { - WebFrame *webFrame = kit(core(_element.get())->document()->frame()); + WebFrame *webFrame = kit(_element->document()->frame()); return [webFrame _dataSource]; } @@ -577,6 +591,11 @@ using namespace WebCore; return [self window] ? [self window] : [[self webView] hostWindow]; } +- (WebCore::HTMLPlugInElement*)element +{ + return _element.get(); +} + // We want to treat these as regular keyboard events. - (void)cut:(id)sender diff --git a/WebKit/mac/Plugins/WebBasePluginPackage.mm b/WebKit/mac/Plugins/WebBasePluginPackage.mm index 7b5ef8e..1bddbcf 100644 --- a/WebKit/mac/Plugins/WebBasePluginPackage.mm +++ b/WebKit/mac/Plugins/WebBasePluginPackage.mm @@ -198,12 +198,18 @@ { } -- (NSDictionary *)pListForPath:(NSString *)pListPath createFile:(BOOL)createFile +- (void)createPropertyListFile { - if (createFile && [self load] && BP_CreatePluginMIMETypesPreferences) { + if ([self load] && BP_CreatePluginMIMETypesPreferences) { BP_CreatePluginMIMETypesPreferences(); [self unload]; } +} + +- (NSDictionary *)pListForPath:(NSString *)pListPath createFile:(BOOL)createFile +{ + if (createFile) + [self createPropertyListFile]; NSDictionary *pList = nil; NSData *data = [NSData dataWithContentsOfFile:pListPath]; diff --git a/WebKit/mac/Plugins/WebKitPluginContainerView.h b/WebKit/mac/Plugins/WebKitPluginContainerView.h deleted file mode 100644 index a67c105..0000000 --- a/WebKit/mac/Plugins/WebKitPluginContainerView.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2007 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. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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. - */ - -#import <Cocoa/Cocoa.h> - -@class DOMElement; - -@interface WebKitPluginContainerView : NSView -{ - DOMElement *_element; -} - -- (id)initWithFrame:(NSRect)r - DOMElement:(DOMElement *)anElement; - -- (id)objectForWebScript; - -@end diff --git a/WebKit/mac/Plugins/WebKitPluginContainerView.mm b/WebKit/mac/Plugins/WebKitPluginContainerView.mm deleted file mode 100644 index fb61644..0000000 --- a/WebKit/mac/Plugins/WebKitPluginContainerView.mm +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2007 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. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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. - */ - -#import "WebKitPluginContainerView.h" -#import <WebKit/DOMPrivate.h> - -@implementation WebKitPluginContainerView - -- (id)initWithFrame:(NSRect)frame - DOMElement:(DOMElement *)anElement -{ - [super initWithFrame:frame]; - - _element = [anElement retain]; - - return self; -} - -- (void)dealloc -{ - [_element release]; - - [super dealloc]; -} - -- (NSRect)visibleRect -{ - if (![self window]) - return [super visibleRect]; - - // WebCore may impose an additional clip (via CSS overflow or clip properties). Fetch - // that clip now. - return NSIntersectionRect([self convertRect:[_element _windowClipRect] fromView:nil], [super visibleRect]); -} - -- (BOOL)respondsToSelector:(SEL)selector -{ - if (selector == @selector(objectForWebScript)) - return [[[self subviews] objectAtIndex: 0] respondsToSelector:selector]; - return [super respondsToSelector:selector]; -} - -- (id)objectForWebScript -{ - return [[[self subviews] objectAtIndex: 0] objectForWebScript]; -} - -@end - diff --git a/WebKit/mac/Plugins/WebNetscapeDeprecatedFunctions.h b/WebKit/mac/Plugins/WebNetscapeDeprecatedFunctions.h index 93c3194..dc8bf4d 100644 --- a/WebKit/mac/Plugins/WebNetscapeDeprecatedFunctions.h +++ b/WebKit/mac/Plugins/WebNetscapeDeprecatedFunctions.h @@ -27,9 +27,17 @@ #import <CoreServices/CoreServices.h> +#ifdef __cplusplus +extern "C" { +#endif + extern OSErr WebGetDiskFragment(const FSSpec *fileSpec, UInt32 offset, UInt32 length, ConstStr63Param fragName, CFragLoadOptions options, CFragConnectionID *connID, Ptr *mainAddr, Str255 errMessage); extern OSErr WebCloseConnection(CFragConnectionID *connID); extern SInt16 WebLMGetCurApRefNum(void); extern void WebLMSetCurApRefNum(SInt16 value); +#ifdef __cplusplus +} +#endif + #endif /* ENABLE(NETSCAPE_PLUGIN_API) && !defined(__LP64__) */ diff --git a/WebKit/mac/Plugins/WebNetscapePluginEventHandlerCocoa.h b/WebKit/mac/Plugins/WebNetscapePluginEventHandlerCocoa.h index 8b6f6e7..4613fcd 100644 --- a/WebKit/mac/Plugins/WebNetscapePluginEventHandlerCocoa.h +++ b/WebKit/mac/Plugins/WebNetscapePluginEventHandlerCocoa.h @@ -53,10 +53,24 @@ public: virtual void focusChanged(bool hasFocus); virtual void* platformWindow(NSWindow*); + private: bool sendMouseEvent(NSEvent*, NPCocoaEventType); bool sendKeyEvent(NSEvent*, NPCocoaEventType); bool sendEvent(NPCocoaEvent*); + +#ifndef __LP64__ + void installKeyEventHandler(); + void removeKeyEventHandler(); + + static OSStatus TSMEventHandler(EventHandlerCallRef, EventRef, void *eventHandler); + OSStatus handleTSMEvent(EventRef); + + EventHandlerRef m_keyEventHandler; +#else + inline void installKeyEventHandler() { } + void removeKeyEventHandler() { } +#endif }; #endif //WebNetscapePluginEventHandlerCocoa_h diff --git a/WebKit/mac/Plugins/WebNetscapePluginEventHandlerCocoa.mm b/WebKit/mac/Plugins/WebNetscapePluginEventHandlerCocoa.mm index 288a356..e3fb362 100644 --- a/WebKit/mac/Plugins/WebNetscapePluginEventHandlerCocoa.mm +++ b/WebKit/mac/Plugins/WebNetscapePluginEventHandlerCocoa.mm @@ -27,10 +27,16 @@ #import "WebNetscapePluginEventHandlerCocoa.h" +#import "WebKitSystemInterface.h" #import "WebNetscapePluginView.h" +#import <wtf/UnusedParam.h> +#import <wtf/Vector.h> WebNetscapePluginEventHandlerCocoa::WebNetscapePluginEventHandlerCocoa(WebNetscapePluginView* pluginView) : WebNetscapePluginEventHandler(pluginView) +#ifndef __LP64__ + , m_keyEventHandler(0) +#endif { } @@ -117,9 +123,13 @@ void WebNetscapePluginEventHandlerCocoa::keyDown(NSEvent *event) { bool retval = sendKeyEvent(event, NPCocoaEventKeyDown); +#ifndef __LP64__ // If the plug-in did not handle the event, pass it on to the Input Manager. - if (!retval) - [m_pluginView interpretKeyEvents:[NSArray arrayWithObject:event]]; + if (retval) + WKSendKeyEventToTSM(event); +#else + UNUSED_PARAM(retval); +#endif } void WebNetscapePluginEventHandlerCocoa::keyUp(NSEvent *event) @@ -173,6 +183,11 @@ void WebNetscapePluginEventHandlerCocoa::focusChanged(bool hasFocus) event.data.focus.hasFocus = hasFocus; sendEvent(&event); + + if (hasFocus) + installKeyEventHandler(); + else + removeKeyEventHandler(); } void* WebNetscapePluginEventHandlerCocoa::platformWindow(NSWindow* window) @@ -202,4 +217,67 @@ bool WebNetscapePluginEventHandlerCocoa::sendEvent(NPCocoaEvent* event) return result; } +#ifndef __LP64__ + +void WebNetscapePluginEventHandlerCocoa::installKeyEventHandler() +{ + static const EventTypeSpec TSMEvents[] = + { + { kEventClassTextInput, kEventTextInputUnicodeForKeyEvent } + }; + + if (!m_keyEventHandler) + InstallEventHandler(GetWindowEventTarget((WindowRef)[[m_pluginView window] windowRef]), + NewEventHandlerUPP(TSMEventHandler), + GetEventTypeCount(TSMEvents), + TSMEvents, + this, + &m_keyEventHandler); +} + +void WebNetscapePluginEventHandlerCocoa::removeKeyEventHandler() +{ + if (m_keyEventHandler) { + RemoveEventHandler(m_keyEventHandler); + m_keyEventHandler = 0; + } +} + +OSStatus WebNetscapePluginEventHandlerCocoa::TSMEventHandler(EventHandlerCallRef inHandlerRef, EventRef event, void* eventHandler) +{ + return static_cast<WebNetscapePluginEventHandlerCocoa*>(eventHandler)->handleTSMEvent(event); +} + +OSStatus WebNetscapePluginEventHandlerCocoa::handleTSMEvent(EventRef eventRef) +{ + ASSERT(GetEventKind(eventRef) == kEventTextInputUnicodeForKeyEvent); + + // Get the text buffer size. + ByteCount size; + OSStatus result = GetEventParameter(eventRef, kEventParamTextInputSendText, typeUnicodeText, 0, 0, &size, 0); + if (result != noErr) + return result; + + unsigned length = size / sizeof(UniChar); + Vector<UniChar, 16> characters(length); + + // Now get the actual text. + result = GetEventParameter(eventRef, kEventParamTextInputSendText, typeUnicodeText, 0, size, 0, characters.data()); + if (result != noErr) + return result; + + RetainPtr<CFStringRef> text(AdoptCF, CFStringCreateWithCharacters(0, characters.data(), length)); + + NPCocoaEvent event; + + initializeEvent(&event, NPCocoaEventTextInput); + event.data.text.text = (NPNSString*)text.get(); + + sendEvent(&event); + + return noErr; +} + +#endif // __LP64__ + #endif // ENABLE(NETSCAPE_PLUGIN_API) diff --git a/WebKit/mac/Plugins/WebNetscapePluginPackage.m b/WebKit/mac/Plugins/WebNetscapePluginPackage.mm index b3ad0bd..38ddddc 100644 --- a/WebKit/mac/Plugins/WebNetscapePluginPackage.m +++ b/WebKit/mac/Plugins/WebNetscapePluginPackage.mm @@ -35,6 +35,12 @@ #import "WebNetscapeDeprecatedFunctions.h" #import <WebCore/npruntime_impl.h> +#if USE(PLUGIN_HOST_PROCESS) +#import "NetscapePluginHostManager.h" + +using namespace WebKit; +#endif + #ifdef SUPPORT_CFM typedef void (* FunctionPointer)(void); typedef void (* TransitionVector)(void); @@ -288,6 +294,12 @@ static TransitionVector tVectorForFunctionPointer(FunctionPointer); { return pluginHostArchitecture; } + +- (void)createPropertyListFile +{ + NetscapePluginHostManager::createPropertyListFile(self); +} + #endif - (void)launchRealPlayer @@ -323,8 +335,8 @@ static TransitionVector tVectorForFunctionPointer(FunctionPointer); [self _unloadWithShutdown:YES]; } -- (BOOL)load -{ +- (BOOL)_tryLoad +{ NP_GetEntryPointsFuncPtr NP_GetEntryPoints = NULL; NP_InitializeFuncPtr NP_Initialize = NULL; NPError npErr; @@ -347,7 +359,7 @@ static TransitionVector tVectorForFunctionPointer(FunctionPointer); if (isBundle) { #endif if (!CFBundleLoadExecutable(cfBundle)) - goto abort; + return NO; #if !LOG_DISABLED currentTime = CFAbsoluteTimeGetCurrent(); duration = currentTime - start; @@ -359,14 +371,14 @@ static TransitionVector tVectorForFunctionPointer(FunctionPointer); if (isCFM) { pluginMainFunc = (MainFuncPtr)CFBundleGetFunctionPointerForName(cfBundle, CFSTR("main") ); if (!pluginMainFunc) - goto abort; + return NO; } else { #endif NP_Initialize = (NP_InitializeFuncPtr)CFBundleGetFunctionPointerForName(cfBundle, CFSTR("NP_Initialize")); NP_GetEntryPoints = (NP_GetEntryPointsFuncPtr)CFBundleGetFunctionPointerForName(cfBundle, CFSTR("NP_GetEntryPoints")); NP_Shutdown = (NPP_ShutdownProcPtr)CFBundleGetFunctionPointerForName(cfBundle, CFSTR("NP_Shutdown")); if (!NP_Initialize || !NP_GetEntryPoints || !NP_Shutdown) - goto abort; + return NO; #ifdef SUPPORT_CFM } } else { @@ -378,17 +390,17 @@ static TransitionVector tVectorForFunctionPointer(FunctionPointer); err = FSPathMakeRef((UInt8 *)[path fileSystemRepresentation], &fref, NULL); if (err != noErr) { LOG_ERROR("FSPathMakeRef failed. Error=%d", err); - goto abort; + return NO; } err = FSGetCatalogInfo(&fref, kFSCatInfoNone, NULL, NULL, &spec, NULL); if (err != noErr) { LOG_ERROR("FSGetCatalogInfo failed. Error=%d", err); - goto abort; + return NO; } err = WebGetDiskFragment(&spec, 0, kCFragGoesToEOF, nil, kPrivateCFragCopy, &connID, (Ptr *)&pluginMainFunc, nil); if (err != noErr) { LOG_ERROR("WebGetDiskFragment failed. Error=%d", err); - goto abort; + return NO; } #if !LOG_DISABLED currentTime = CFAbsoluteTimeGetCurrent(); @@ -399,7 +411,7 @@ static TransitionVector tVectorForFunctionPointer(FunctionPointer); pluginMainFunc = (MainFuncPtr)functionPointerForTVector((TransitionVector)pluginMainFunc); if (!pluginMainFunc) { - goto abort; + return NO; } // NOTE: pluginMainFunc is freed after it is called. Be sure not to return before that. @@ -480,14 +492,14 @@ static TransitionVector tVectorForFunctionPointer(FunctionPointer); NP_Shutdown = (NPP_ShutdownProcPtr)functionPointerForTVector((TransitionVector)shutdownFunction); if (!isBundle) // Don't free pluginMainFunc if we got it from a bundle because it is owned by CFBundle in that case. - free(pluginMainFunc); + free(reinterpret_cast<void*>(pluginMainFunc)); // Workaround for 3270576. The RealPlayer plug-in fails to load if its preference file is out of date. // Launch the RealPlayer application to refresh the file. if (npErr != NPERR_NO_ERROR) { if (npErr == NPERR_MODULE_LOAD_FAILED_ERROR && [[self filename] isEqualToString:RealPlayerPluginFilename]) [self launchRealPlayer]; - goto abort; + return NO; } #if !LOG_DISABLED currentTime = CFAbsoluteTimeGetCurrent(); @@ -514,7 +526,7 @@ static TransitionVector tVectorForFunctionPointer(FunctionPointer); pluginFuncs.setvalue = (NPP_SetValueProcPtr)functionPointerForTVector((TransitionVector)pluginFuncs.setvalue); // LiveConnect support - pluginFuncs.javaClass = (NPP_GetJavaClassProcPtr)functionPointerForTVector((TransitionVector)pluginFuncs.javaClass); + pluginFuncs.javaClass = (JRIGlobalRef)functionPointerForTVector((TransitionVector)pluginFuncs.javaClass); if (pluginFuncs.javaClass) { LOG(LiveConnect, "%@: CFM entry point for NPP_GetJavaClass = %p", [self name], pluginFuncs.javaClass); } else { @@ -586,7 +598,7 @@ static TransitionVector tVectorForFunctionPointer(FunctionPointer); LOG(Plugins, "%f NP_Initialize timing started", initializeStart); npErr = NP_Initialize(&browserFuncs); if (npErr != NPERR_NO_ERROR) - goto abort; + return NO; #if !LOG_DISABLED currentTime = CFAbsoluteTimeGetCurrent(); duration = currentTime - initializeStart; @@ -597,7 +609,7 @@ static TransitionVector tVectorForFunctionPointer(FunctionPointer); npErr = NP_GetEntryPoints(&pluginFuncs); if (npErr != NPERR_NO_ERROR) - goto abort; + return NO; pluginSize = pluginFuncs.size; pluginVersion = pluginFuncs.version; @@ -617,9 +629,14 @@ static TransitionVector tVectorForFunctionPointer(FunctionPointer); #endif LOG(Plugins, "%f Total load time: %f seconds", currentTime, duration); - return [super load]; + return YES; +} + +- (BOOL)load +{ + if ([self _tryLoad]) + return [super load]; -abort: [self _unloadWithShutdown:NO]; return NO; } @@ -724,11 +741,7 @@ TransitionVector tVectorForFunctionPointer(FunctionPointer fp) [self closeResourceFile:resourceRef]; #ifdef SUPPORT_CFM - if (isBundle) -#endif - CFBundleUnloadExecutable(cfBundle); -#ifdef SUPPORT_CFM - else + if (!isBundle) WebCloseConnection(&connID); #endif diff --git a/WebKit/mac/Plugins/WebNetscapePluginView.h b/WebKit/mac/Plugins/WebNetscapePluginView.h index 9d2555b..783b7fb 100644 --- a/WebKit/mac/Plugins/WebNetscapePluginView.h +++ b/WebKit/mac/Plugins/WebNetscapePluginView.h @@ -52,14 +52,12 @@ typedef union PluginPort { NP_CGContext cgPort; } PluginPort; -typedef struct _NPPluginTextInputFuncs NPPluginTextInputFuncs; - // Because the Adobe 7.x Acrobat plug-in has a hard coded check for a view named // "WebNetscapePluginDocumentView", this class must retain the old name in order // for the plug-in to function correctly. (rdar://problem/4699455) #define WebNetscapePluginView WebNetscapePluginDocumentView -@interface WebNetscapePluginView : WebBaseNetscapePluginView<WebPluginManualLoader, NSTextInput> +@interface WebNetscapePluginView : WebBaseNetscapePluginView<WebPluginManualLoader> { RefPtr<WebNetscapePluginStream> _manualStream; #ifndef BUILDING_ON_TIGER @@ -101,9 +99,8 @@ typedef struct _NPPluginTextInputFuncs NPPluginTextInputFuncs; HashSet<RefPtr<WebNetscapePluginStream> > streams; RetainPtr<NSMutableDictionary> _pendingFrameLoads; + BOOL _isFlash; BOOL _isSilverlight; - - NPPluginTextInputFuncs *textInputFuncs; } + (WebNetscapePluginView *)currentPluginView; @@ -117,7 +114,7 @@ typedef struct _NPPluginTextInputFuncs NPPluginTextInputFuncs; attributeKeys:(NSArray *)keys attributeValues:(NSArray *)values loadManually:(BOOL)loadManually - DOMElement:(DOMElement *)anElement; + element:(PassRefPtr<WebCore::HTMLPlugInElement>)element; - (NPP)plugin; diff --git a/WebKit/mac/Plugins/WebNetscapePluginView.mm b/WebKit/mac/Plugins/WebNetscapePluginView.mm index a792e21..cef33a4 100644 --- a/WebKit/mac/Plugins/WebNetscapePluginView.mm +++ b/WebKit/mac/Plugins/WebNetscapePluginView.mm @@ -35,6 +35,7 @@ #import "WebFrameInternal.h" #import "WebFrameView.h" #import "WebGraphicsExtras.h" +#import "WebKitErrorsPrivate.h" #import "WebKitLogging.h" #import "WebKitNSStringExtras.h" #import "WebKitSystemInterface.h" @@ -59,19 +60,22 @@ #import <WebCore/Element.h> #import <WebCore/Frame.h> #import <WebCore/FrameLoader.h> -#import <WebCore/FrameTree.h> +#import <WebCore/FrameTree.h> +#import <WebCore/HTMLPlugInElement.h> #import <WebCore/Page.h> #import <WebCore/PluginMainThreadScheduler.h> #import <WebCore/ScriptController.h> #import <WebCore/SoftLinking.h> #import <WebCore/WebCoreObjCExtras.h> -#import <WebKit/nptextinput.h> +#import <WebCore/WebCoreURLResponse.h> #import <WebKit/DOMPrivate.h> #import <WebKit/WebUIDelegate.h> #import <runtime/InitializeThreading.h> #import <wtf/Assertions.h> #import <objc/objc-runtime.h> +using std::max; + #define LoginWindowDidSwitchFromUserNotification @"WebLoginWindowDidSwitchFromUserNotification" #define LoginWindowDidSwitchToUserNotification @"WebLoginWindowDidSwitchToUserNotification" @@ -91,6 +95,7 @@ static inline bool isDrawingModelQuickDraw(NPDrawingModel drawingModel) - (void)_destroyPlugin; - (NSBitmapImageRep *)_printedPluginBitmap; - (void)_redeliverStream; +- (BOOL)_shouldCancelSrcStream; @end static WebNetscapePluginView *currentPluginView = nil; @@ -489,6 +494,11 @@ static inline void getNPRect(const NSRect& nr, NPRect& npr) #endif /* NP_NO_QUICKDRAW */ case NPDrawingModelCoreGraphics: { + if (![self canDraw]) { + portState = NULL; + break; + } + ASSERT([NSView focusView] == self); CGContextRef context = static_cast<CGContextRef>([[NSGraphicsContext currentContext] graphicsPort]); @@ -620,10 +630,6 @@ static inline void getNPRect(const NSRect& nr, NPRect& npr) if (!page) return NO; - bool wasDeferring = page->defersLoading(); - if (!wasDeferring) - page->setDefersLoading(true); - // Can only send drawRect (updateEvt) to CoreGraphics plugins when actually drawing ASSERT((drawingModel != NPDrawingModelCoreGraphics) || !eventIsDrawRect || [NSView focusView] == self); @@ -667,9 +673,6 @@ static inline void getNPRect(const NSRect& nr, NPRect& npr) free(portState); } - if (!wasDeferring) - page->setDefersLoading(false); - return acceptedEvent; } @@ -894,10 +897,18 @@ static inline void getNPRect(const NSRect& nr, NPRect& npr) { // A plug-in can only update if it's (1) already been started (2) isn't stopped // and (3) is able to draw on-screen. To meet condition (3) the plug-in must not - // be hidden and be attached to a window. QuickDraw plug-ins are an important - // excpetion to rule (3) because they manually must be told when to stop writing + // be hidden and be attached to a window. There are two exceptions to this rule: + // + // Exception 1: QuickDraw plug-ins must be manually told when to stop writing // bits to the window backing store, thus to do so requires a new call to // NPP_SetWindow() with an empty NPWindow struct. + // + // Exception 2: CoreGraphics plug-ins expect to have their drawable area updated + // when they are moved to a background tab, via a NPP_SetWindow call. This is + // accomplished by allowing -saveAndSetNewPortStateForUpdate to "clip-out" the window's + // clipRect. Flash is curently an exception to this. See 6453738. + // + if (!_isStarted) return; @@ -907,9 +918,11 @@ static inline void getNPRect(const NSRect& nr, NPRect& npr) #else if (drawingModel == NPDrawingModelQuickDraw) [self tellQuickTimeToChill]; - else if (drawingModel == NPDrawingModelCoreGraphics && ![self canDraw]) + else if (drawingModel == NPDrawingModelCoreGraphics && ![self canDraw] && _isFlash) { + // The Flash plug-in does not expect an NPP_SetWindow call from WebKit in this case. + // See Exception 2 above. return; - + } #endif // NP_NO_QUICKDRAW BOOL didLockFocus = [NSView focusView] != self && [self lockFocusIfCanDraw]; @@ -920,7 +933,9 @@ static inline void getNPRect(const NSRect& nr, NPRect& npr) [self restorePortState:portState]; if (portState != (PortState)1) free(portState); - } + } else if (drawingModel == NPDrawingModelCoreGraphics) + [self setWindowIfNecessary]; + if (didLockFocus) [self unlockFocus]; } @@ -938,11 +953,7 @@ static inline void getNPRect(const NSRect& nr, NPRect& npr) NPError npErr; ASSERT(!inSetWindow); - inSetWindow = YES; - - // A CoreGraphics plugin's window may only be set while the plugin is being updated - ASSERT((drawingModel != NPDrawingModelCoreGraphics) || [NSView focusView] == self); - + inSetWindow = YES; [self willCallPlugInFunction]; { JSC::JSLock::DropAllLocks dropAllLocks(false); @@ -961,8 +972,9 @@ static inline void getNPRect(const NSRect& nr, NPRect& npr) #endif /* NP_NO_QUICKDRAW */ case NPDrawingModelCoreGraphics: - LOG(Plugins, "NPP_SetWindow (CoreGraphics): %d, window=%p, context=%p, window.x:%d window.y:%d window.width:%d window.height:%d", - npErr, nPort.cgPort.window, nPort.cgPort.context, (int)window.x, (int)window.y, (int)window.width, (int)window.height); + LOG(Plugins, "NPP_SetWindow (CoreGraphics): %d, window=%p, context=%p, window.x:%d window.y:%d window.width:%d window.height:%d window.clipRect size:%dx%d", + npErr, nPort.cgPort.window, nPort.cgPort.context, (int)window.x, (int)window.y, (int)window.width, (int)window.height, + window.clipRect.right - window.clipRect.left, window.clipRect.bottom - window.clipRect.top); break; case NPDrawingModelCoreAnimation: @@ -1056,19 +1068,7 @@ static inline void getNPRect(const NSRect& nr, NPRect& npr) // Create the event handler _eventHandler.set(WebNetscapePluginEventHandler::create(self)); - - // Get the text input vtable - if (eventModel == NPEventModelCocoa) { - [self willCallPlugInFunction]; - { - JSC::JSLock::DropAllLocks dropAllLocks(false); - NPPluginTextInputFuncs *value = 0; - if (![_pluginPackage.get() pluginFuncs]->getvalue(plugin, NPPVpluginTextInputFuncs, &value) == NPERR_NO_ERROR && value) - textInputFuncs = value; - } - [self didCallPlugInFunction]; - } - + return YES; } @@ -1076,14 +1076,19 @@ static inline void getNPRect(const NSRect& nr, NPRect& npr) - (void)setLayer:(CALayer *)newLayer { [super setLayer:newLayer]; - - if (_pluginLayer) + + if (_pluginLayer) { + _pluginLayer.get().autoresizingMask = kCALayerWidthSizable | kCALayerHeightSizable; [newLayer addSublayer:_pluginLayer.get()]; + } } #endif - (void)loadStream { + if ([self _shouldCancelSrcStream]) + return; + if (_loadManually) { [self _redeliverStream]; return; @@ -1136,8 +1141,6 @@ static inline void getNPRect(const NSRect& nr, NPRect& npr) [_pluginPackage.get() close]; _eventHandler.clear(); - - textInputFuncs = 0; } - (NPEventModel)eventModel @@ -1150,7 +1153,7 @@ static inline void getNPRect(const NSRect& nr, NPRect& npr) return plugin; } -- (void)setAttributeKeys:(NSArray *)keys andValues:(NSArray *)values; +- (void)setAttributeKeys:(NSArray *)keys andValues:(NSArray *)values { ASSERT([keys count] == [values count]); @@ -1203,9 +1206,9 @@ static inline void getNPRect(const NSRect& nr, NPRect& npr) 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; @@ -1358,7 +1361,20 @@ static inline void getNPRect(const NSRect& nr, NPRect& npr) return; if (!_manualStream->plugin()) { - + // Check if the load should be cancelled + if ([self _shouldCancelSrcStream]) { + NSURLResponse *response = [[self dataSource] response]; + + NSError *error = [[NSError alloc] _initWithPluginErrorCode:WebKitErrorPlugInWillHandleLoad + contentURL:[response URL] + pluginPageURL:nil + pluginName:nil // FIXME: Get this from somewhere + MIMEType:[response _webcore_MIMEType]]; + [[self dataSource] _documentLoader]->cancelMainResourceLoad(error); + [error release]; + return; + } + _manualStream->setRequestURL([[[self dataSource] request] URL]); _manualStream->setPlugin([self plugin]); ASSERT(_manualStream->plugin()); @@ -1392,160 +1408,11 @@ static inline void getNPRect(const NSRect& nr, NPRect& npr) _manualStream->didFinishLoading(0); } -#pragma mark NSTextInput implementation - - (NSTextInputContext *)inputContext { -#ifndef NP_NO_CARBON - if (!_isStarted || eventModel == NPEventModelCarbon) - return nil; -#endif - - return [super inputContext]; -} - -- (BOOL)hasMarkedText -{ - ASSERT(eventModel == NPEventModelCocoa); - ASSERT(_isStarted); - - if (textInputFuncs && textInputFuncs->hasMarkedText) - return textInputFuncs->hasMarkedText(plugin); - - return NO; -} - -- (void)insertText:(id)aString -{ - ASSERT(eventModel == NPEventModelCocoa); - ASSERT(_isStarted); - - if (textInputFuncs && textInputFuncs->insertText) - textInputFuncs->insertText(plugin, aString); -} - -- (NSRange)markedRange -{ - ASSERT(eventModel == NPEventModelCocoa); - ASSERT(_isStarted); - - if (textInputFuncs && textInputFuncs->markedRange) - return textInputFuncs->markedRange(plugin); - - return NSMakeRange(NSNotFound, 0); -} - -- (NSRange)selectedRange -{ - ASSERT(eventModel == NPEventModelCocoa); - ASSERT(_isStarted); - - if (textInputFuncs && textInputFuncs->selectedRange) - return textInputFuncs->selectedRange(plugin); - - return NSMakeRange(NSNotFound, 0); -} - -- (void)setMarkedText:(id)aString selectedRange:(NSRange)selRange -{ - ASSERT(eventModel == NPEventModelCocoa); - ASSERT(_isStarted); - - if (textInputFuncs && textInputFuncs->setMarkedText) - textInputFuncs->setMarkedText(plugin, aString, selRange); -} - -- (void)unmarkText -{ - ASSERT(eventModel == NPEventModelCocoa); - ASSERT(_isStarted); - - if (textInputFuncs && textInputFuncs->unmarkText) - textInputFuncs->unmarkText(plugin); -} - -- (NSArray *)validAttributesForMarkedText -{ - ASSERT(eventModel == NPEventModelCocoa); - ASSERT(_isStarted); - - if (textInputFuncs && textInputFuncs->validAttributesForMarkedText) - return textInputFuncs->validAttributesForMarkedText(plugin); - - return [NSArray array]; -} - -- (NSAttributedString *)attributedSubstringFromRange:(NSRange)theRange -{ - ASSERT(eventModel == NPEventModelCocoa); - ASSERT(_isStarted); - - if (textInputFuncs && textInputFuncs->attributedSubstringFromRange) - return textInputFuncs->attributedSubstringFromRange(plugin, theRange); - return nil; } -- (NSUInteger)characterIndexForPoint:(NSPoint)thePoint -{ - ASSERT(eventModel == NPEventModelCocoa); - ASSERT(_isStarted); - - if (textInputFuncs && textInputFuncs->characterIndexForPoint) { - // Convert the point to window coordinates - NSPoint point = [[self window] convertScreenToBase:thePoint]; - - // And view coordinates - point = [self convertPoint:point fromView:nil]; - - return textInputFuncs->characterIndexForPoint(plugin, point); - } - - return NSNotFound; -} - -- (void)doCommandBySelector:(SEL)aSelector -{ - ASSERT(eventModel == NPEventModelCocoa); - ASSERT(_isStarted); - - if (textInputFuncs && textInputFuncs->doCommandBySelector) - textInputFuncs->doCommandBySelector(plugin, aSelector); -} - -- (NSRect)firstRectForCharacterRange:(NSRange)theRange -{ - ASSERT(eventModel == NPEventModelCocoa); - ASSERT(_isStarted); - - if (textInputFuncs && textInputFuncs->firstRectForCharacterRange) { - NSRect rect = textInputFuncs->firstRectForCharacterRange(plugin, theRange); - - // Convert the rect to window coordinates - rect = [self convertRect:rect toView:nil]; - - // Convert the rect location to screen coordinates - rect.origin = [[self window] convertBaseToScreen:rect.origin]; - - return rect; - } - - return NSZeroRect; -} - -// test for 10.4 because of <rdar://problem/4243463> -#ifdef BUILDING_ON_TIGER -- (long)conversationIdentifier -{ - return (long)self; -} -#else -- (NSInteger)conversationIdentifier -{ - return (NSInteger)self; -} -#endif - @end @implementation WebNetscapePluginView (WebNPPCallbacks) @@ -1945,11 +1812,6 @@ static inline void getNPRect(const NSRect& nr, NPRect& npr) (float)invalidRect->right - invalidRect->left, (float)invalidRect->bottom - invalidRect->top)]; } --(BOOL)isOpaque -{ - return YES; -} - - (void)invalidateRegion:(NPRegion)invalidRegion { LOG(Plugins, "NPN_InvalidateRegion"); @@ -1986,18 +1848,6 @@ static inline void getNPRect(const NSRect& nr, NPRect& npr) [[self window] displayIfNeeded]; } -static NPBrowserTextInputFuncs *browserTextInputFuncs() -{ - static NPBrowserTextInputFuncs inputFuncs = { - 0, - sizeof(NPBrowserTextInputFuncs), - NPN_MarkedTextAbandoned, - NPN_MarkedTextSelectionChanged - }; - - return &inputFuncs; -} - - (NPError)getVariable:(NPNVariable)variable value:(void *)value { switch (variable) { @@ -2021,7 +1871,7 @@ static NPBrowserTextInputFuncs *browserTextInputFuncs() if (!_element) return NPERR_GENERIC_ERROR; - NPObject *plugInScriptObject = (NPObject *)[_element.get() _NPObject]; + NPObject *plugInScriptObject = _element->getNPObject(); // Return value is expected to be retained, as described here: <http://www.mozilla.org/projects/plugins/npruntime.html#browseraccess> if (plugInScriptObject) @@ -2082,14 +1932,7 @@ static NPBrowserTextInputFuncs *browserTextInputFuncs() *(NPBool *)value = TRUE; return NPERR_NO_ERROR; } - - case NPNVbrowserTextInputFuncs: - { - if (eventModel == NPEventModelCocoa) { - *(NPBrowserTextInputFuncs **)value = browserTextInputFuncs(); - return NPERR_NO_ERROR; - } - } + default: break; } @@ -2205,6 +2048,19 @@ static NPBrowserTextInputFuncs *browserTextInputFuncs() @implementation WebNetscapePluginView (Internal) +- (BOOL)_shouldCancelSrcStream +{ + ASSERT(_isStarted); + + // Check if we should cancel the load + NPBool cancelSrcStream = 0; + if ([_pluginPackage.get() pluginFuncs]->getvalue && + [_pluginPackage.get() pluginFuncs]->getvalue(plugin, NPPVpluginCancelSrcStream, &cancelSrcStream) == NPERR_NO_ERROR && cancelSrcStream) + return YES; + + return NO; +} + - (NPError)_createPlugin { plugin = (NPP)calloc(1, sizeof(NPP_t)); @@ -2217,6 +2073,7 @@ static NPBrowserTextInputFuncs *browserTextInputFuncs() PluginMainThreadScheduler::scheduler().registerPlugin(plugin); + _isFlash = [[[_pluginPackage.get() bundle] bundleIdentifier] isEqualToString:@"com.macromedia.Flash Player.plugin"]; _isSilverlight = [[[_pluginPackage.get() bundle] bundleIdentifier] isEqualToString:@"com.microsoft.SilverlightPlugin"]; [[self class] setCurrentPluginView:self]; diff --git a/WebKit/mac/Plugins/WebPlugin.h b/WebKit/mac/Plugins/WebPlugin.h index bd0600e..797634f 100644 --- a/WebKit/mac/Plugins/WebPlugin.h +++ b/WebKit/mac/Plugins/WebPlugin.h @@ -100,7 +100,7 @@ @discussion This method is only sent to the plug-in if the WebPlugInShouldLoadMainResourceKey argument passed to the plug-in was NO. */ -- (void)webPlugInMainResourceDidReceiveResponse:(NSURLResponse *)response WEBKIT_OBJC_METHOD_ANNOTATION(AVAILABLE_AFTER_WEBKIT_VERSION_3_1); +- (void)webPlugInMainResourceDidReceiveResponse:(NSURLResponse *)response WEBKIT_OBJC_METHOD_ANNOTATION(AVAILABLE_IN_WEBKIT_VERSION_4_0); /*! @method webPlugInMainResourceDidReceiveData: @@ -109,7 +109,7 @@ @discussion This method is only sent to the plug-in if the WebPlugInShouldLoadMainResourceKey argument passed to the plug-in was NO. */ -- (void)webPlugInMainResourceDidReceiveData:(NSData *)data WEBKIT_OBJC_METHOD_ANNOTATION(AVAILABLE_AFTER_WEBKIT_VERSION_3_1); +- (void)webPlugInMainResourceDidReceiveData:(NSData *)data WEBKIT_OBJC_METHOD_ANNOTATION(AVAILABLE_IN_WEBKIT_VERSION_4_0); /*! @method webPlugInMainResourceDidFailWithError: @@ -118,7 +118,7 @@ @discussion This method is only sent to the plug-in if the WebPlugInShouldLoadMainResourceKey argument passed to the plug-in was NO. */ -- (void)webPlugInMainResourceDidFailWithError:(NSError *)error WEBKIT_OBJC_METHOD_ANNOTATION(AVAILABLE_AFTER_WEBKIT_VERSION_3_1); +- (void)webPlugInMainResourceDidFailWithError:(NSError *)error WEBKIT_OBJC_METHOD_ANNOTATION(AVAILABLE_IN_WEBKIT_VERSION_4_0); /*! @method webPlugInMainResourceDidFinishLoading @@ -127,6 +127,6 @@ @discussion This method is only sent to the plug-in if the WebPlugInShouldLoadMainResourceKey argument passed to the plug-in was NO. */ -- (void)webPlugInMainResourceDidFinishLoading WEBKIT_OBJC_METHOD_ANNOTATION(AVAILABLE_AFTER_WEBKIT_VERSION_3_1); +- (void)webPlugInMainResourceDidFinishLoading WEBKIT_OBJC_METHOD_ANNOTATION(AVAILABLE_IN_WEBKIT_VERSION_4_0); @end diff --git a/WebKit/mac/Plugins/WebPluginContainerPrivate.h b/WebKit/mac/Plugins/WebPluginContainerPrivate.h index c9d64d5..af7251d 100644 --- a/WebKit/mac/Plugins/WebPluginContainerPrivate.h +++ b/WebKit/mac/Plugins/WebPluginContainerPrivate.h @@ -28,10 +28,24 @@ #import <Cocoa/Cocoa.h> +#if !defined(ENABLE_PLUGIN_PROXY_FOR_VIDEO) +#define ENABLE_PLUGIN_PROXY_FOR_VIDEO 1 +#endif + +#if ENABLE_PLUGIN_PROXY_FOR_VIDEO +@class WebMediaPlayerProxy; +#endif + @interface NSObject (WebPlugInContainerPrivate) - (id)_webPluginContainerCheckIfAllowedToLoadRequest:(NSURLRequest *)Request inFrame:(NSString *)target resultObject:(id)obj selector:(SEL)selector; - (void)_webPluginContainerCancelCheckIfAllowedToLoadRequest:(id)checkIdentifier; +#if ENABLE_PLUGIN_PROXY_FOR_VIDEO +- (void)_webPluginContainerSetMediaPlayerProxy:(WebMediaPlayerProxy *)proxy forElement:(DOMElement *)element; + +- (void)_webPluginContainerPostMediaPlayerNotification:(int)notification forElement:(DOMElement *)element; +#endif + @end diff --git a/WebKit/mac/Plugins/WebPluginController.mm b/WebKit/mac/Plugins/WebPluginController.mm index b618bd6..54d9615 100644 --- a/WebKit/mac/Plugins/WebPluginController.mm +++ b/WebKit/mac/Plugins/WebPluginController.mm @@ -31,12 +31,17 @@ #import <Foundation/NSURLRequest.h> #import <runtime/JSLock.h> +#import <WebCore/DocumentLoader.h> +#import <WebCore/DOMNodeInternal.h> #import <WebCore/Frame.h> #import <WebCore/FrameLoader.h> -#import <WebCore/ResourceRequest.h> +#import <WebCore/HTMLMediaElement.h> +#import <WebCore/HTMLNames.h> +#import <WebCore/MediaPlayerProxy.h> #import <WebCore/PlatformString.h> -#import <WebCore/DocumentLoader.h> +#import <WebCore/ResourceRequest.h> #import <WebCore/ScriptController.h> +#import <WebCore/WebCoreURLResponse.h> #import <WebKit/WebDataSourceInternal.h> #import <WebKit/WebFrameInternal.h> #import <WebKit/WebFrameView.h> @@ -55,6 +60,7 @@ #import <WebKit/WebViewInternal.h> using namespace WebCore; +using namespace HTMLNames; @interface NSView (PluginSecrets) - (void)setContainingWindow:(NSWindow *)w; @@ -185,6 +191,10 @@ static NSMutableSet *pluginViews = nil; [_views addObject:view]; [[_documentView _webView] addPluginInstanceView:view]; + BOOL oldDefersCallbacks = [[self webView] defersCallbacks]; + if (!oldDefersCallbacks) + [[self webView] setDefersCallbacks:YES]; + LOG(Plugins, "initializing plug-in %@", view); if ([view respondsToSelector:@selector(webPlugInInitialize)]) { JSC::JSLock::DropAllLocks dropAllLocks(false); @@ -194,6 +204,9 @@ static NSMutableSet *pluginViews = nil; [view pluginInitialize]; } + if (!oldDefersCallbacks) + [[self webView] setDefersCallbacks:NO]; + if (_started) { LOG(Plugins, "starting plug-in %@", view); if ([view respondsToSelector:@selector(webPlugInStart)]) { @@ -406,7 +419,7 @@ static void cancelOutstandingCheck(const void *item, void *context) contentURL:[response URL] pluginPageURL:nil pluginName:nil // FIXME: Get this from somewhere - MIMEType:[response MIMEType]]; + MIMEType:[response _webcore_MIMEType]]; [_dataSource _documentLoader]->cancelMainResourceLoad(error); [error release]; } @@ -430,4 +443,36 @@ static void cancelOutstandingCheck(const void *item, void *context) [pluginView webPlugInMainResourceDidFinishLoading]; } +#if ENABLE(PLUGIN_PROXY_FOR_VIDEO) +static WebCore::HTMLMediaElement* mediaProxyClient(DOMElement* element) +{ + if (!element) { + LOG_ERROR("nil element passed"); + return nil; + } + + Node* node = [element _node]; + if (!node || (!node->hasTagName(HTMLNames::videoTag) && !node->hasTagName(HTMLNames::audioTag))) { + LOG_ERROR("invalid media element passed"); + return nil; + } + + return static_cast<WebCore::HTMLMediaElement*>(node); +} + +- (void)_webPluginContainerSetMediaPlayerProxy:(WebMediaPlayerProxy *)proxy forElement:(DOMElement *)element +{ + WebCore::HTMLMediaElement* client = mediaProxyClient(element); + if (client) + client->setMediaPlayerProxy(proxy); +} + +- (void)_webPluginContainerPostMediaPlayerNotification:(int)notification forElement:(DOMElement *)element +{ + WebCore::HTMLMediaElement* client = mediaProxyClient(element); + if (client) + client->deliverNotification((MediaPlayerProxyNotificationType)notification); +} +#endif + @end diff --git a/WebKit/mac/Plugins/WebPluginViewFactory.h b/WebKit/mac/Plugins/WebPluginViewFactory.h index 583a73d..a215906 100644 --- a/WebKit/mac/Plugins/WebPluginViewFactory.h +++ b/WebKit/mac/Plugins/WebPluginViewFactory.h @@ -66,7 +66,7 @@ extern NSString *WebPlugInContainingElementKey; For compatibility with older versions of WebKit, the plug-in should assume that the value for WebPlugInShouldLoadMainResourceKey is NO if it is absent from the arguments dictionary. */ -extern NSString *WebPlugInShouldLoadMainResourceKey AVAILABLE_AFTER_WEBKIT_VERSION_3_1; +extern NSString *WebPlugInShouldLoadMainResourceKey AVAILABLE_IN_WEBKIT_VERSION_4_0; /*! @protocol WebPlugInViewFactory diff --git a/WebKit/mac/Plugins/npapi.mm b/WebKit/mac/Plugins/npapi.mm index eb32c2b..79eff2a 100644 --- a/WebKit/mac/Plugins/npapi.mm +++ b/WebKit/mac/Plugins/npapi.mm @@ -28,7 +28,6 @@ #if ENABLE(NETSCAPE_PLUGIN_API) #import <WebKit/npapi.h> -#import <WebKit/nptextinput.h> #import "WebNetscapePluginView.h" #import "WebKitLogging.h" @@ -192,18 +191,4 @@ NPError NPN_PopUpContextMenu(NPP instance, NPMenu *menu) return [pluginViewForInstance(instance) popUpContextMenu:menu]; } -void NPN_MarkedTextAbandoned(NPP instance) -{ - WebNetscapePluginView *pluginView = pluginViewForInstance(instance); - - [[NSInputManager currentInputManager] markedTextAbandoned:pluginView]; -} - -void NPN_MarkedTextSelectionChanged(NPP instance, NSRange newSel) -{ - WebNetscapePluginView *pluginView = pluginViewForInstance(instance); - - [[NSInputManager currentInputManager] markedTextSelectionChanged:newSel client:pluginView]; -} - #endif diff --git a/WebKit/mac/Plugins/nptextinput.h b/WebKit/mac/Plugins/nptextinput.h deleted file mode 100644 index 2ed3146..0000000 --- a/WebKit/mac/Plugins/nptextinput.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (C) 2008, Apple Inc. and The Mozilla Foundation. - * 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. - * 3. Neither the names of Apple Inc. ("Apple") or The Mozilla - * Foundation ("Mozilla") nor the names of their contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE, MOZILLA AND THEIR CONTRIBUTORS "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, MOZILLA OR - * THEIR 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. - * - */ - - -#ifndef __OBJC__ -#error "npinput.h can only be included from Objective-C code." -#endif - -#ifndef _NP_TEXTINPUT_H_ -#define _NP_TEXTINPUT_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include <WebKit/npapi.h> - -#import <Cocoa/Cocoa.h> - -typedef void (*NPP_InsertTextFunc)(NPP npp, id aString); -typedef void (*NPP_DoCommandBySelectorFunc)(NPP npp, SEL aSelector); -typedef void (*NPP_SetMarkedTextFunc)(NPP npp, id aString, NSRange selRange); -typedef void (*NPP_UnmarkTextFunc)(NPP npp); -typedef BOOL (*NPP_HasMarkedTextFunc)(NPP npp); -typedef NSAttributedString * (*NPP_AttributedSubstringFromRangeFunc)(NPP npp, NSRange theRange); -typedef NSRange (*NPP_MarkedRangeFunc)(NPP npp); -typedef NSRange (*NPP_SelectedRangeFunc)(NPP npp); -typedef NSRect (*NPP_FirstRectForCharacterRangeFunc)(NPP npp, NSRange theRange); -typedef unsigned long long (*NPP_CharacterIndexForPointFunc)(NPP npp, NSPoint thePoint); -typedef NSArray *(*NPP_ValidAttributesForMarkedTextFunc)(NPP npp); - -typedef struct _NPPluginTextInputFuncs { - uint16 size; - uint16 version; - - NPP_InsertTextFunc insertText; - NPP_DoCommandBySelectorFunc doCommandBySelector; - NPP_SetMarkedTextFunc setMarkedText; - NPP_UnmarkTextFunc unmarkText; - NPP_HasMarkedTextFunc hasMarkedText; - NPP_AttributedSubstringFromRangeFunc attributedSubstringFromRange; - NPP_MarkedRangeFunc markedRange; - NPP_SelectedRangeFunc selectedRange; - NPP_FirstRectForCharacterRangeFunc firstRectForCharacterRange; - NPP_CharacterIndexForPointFunc characterIndexForPoint; - NPP_ValidAttributesForMarkedTextFunc validAttributesForMarkedText; -} NPPluginTextInputFuncs; - -void NPP_InsertText(NPP npp, id aString); -void NPP_DoCommandBySelector(NPP npp, SEL aSelector); -void NPP_SetMarkedText(NPP npp, id aString, NSRange selRange); -void NPP_UnmarkText(NPP npp); -BOOL NPP_HasMarkedText(NPP npp); -NSAttributedString *NPP_AttributedSubstringFromRange(NPP npp, NSRange theRange); -NSRange NPP_MarkedRange(NPP npp); -NSRange NPP_SelectedRange(NPP npp); -NSRect NPP_FirstRectForCharacterRange(NPP npp, NSRange theRange); -unsigned long long NPP_CharacterIndexForPoint(NPP npp, NSPoint thePoint); -NSArray *NPP_ValidAttributesForMarkedText(NPP npp); - -typedef void (*NPN_MarkedTextAbandonedFunc)(NPP npp); -typedef void (*NPN_MarkedTextSelectionChangedFunc)(NPP npp, NSRange newSel); - -typedef struct _NPBrowserTextInputFuncs { - uint16 size; - uint16 version; - - NPN_MarkedTextAbandonedFunc markedTextAbandoned; - NPN_MarkedTextSelectionChangedFunc markedTextSelectionChanged; -} NPBrowserTextInputFuncs; - -void NPN_MarkedTextAbandoned(NPP npp); -void NPN_MarkedTextSelectionChanged(NPP npp, NSRange newSel); - -#ifdef __cplusplus -} -#endif - -#endif |