📄 pluginviewwin.cpp
字号:
setNPWindowRect(frameRect()); npEvent.event = WM_PAINT; npEvent.wParam = reinterpret_cast<uint32>(hdc); // This is supposed to be a pointer to the dirty rect, but it seems that the Flash plugin // ignores it so we just pass null. npEvent.lParam = 0; dispatchNPEvent(npEvent); context->releaseWindowsContext(hdc, frameRect(), m_isTransparent);}void PluginView::handleKeyboardEvent(KeyboardEvent* event){ NPEvent npEvent; npEvent.wParam = event->keyCode(); if (event->type() == eventNames().keydownEvent) { npEvent.event = WM_KEYDOWN; npEvent.lParam = 0; } else if (event->type() == eventNames().keyupEvent) { npEvent.event = WM_KEYUP; npEvent.lParam = 0x8000; } JSC::JSLock::DropAllLocks dropAllLocks(false); if (!dispatchNPEvent(npEvent)) event->setDefaultHandled();}extern HCURSOR lastSetCursor;extern bool ignoreNextSetCursor;void PluginView::handleMouseEvent(MouseEvent* event){ NPEvent npEvent; IntPoint p = static_cast<FrameView*>(parent())->contentsToWindow(IntPoint(event->pageX(), event->pageY())); npEvent.lParam = MAKELPARAM(p.x(), p.y()); npEvent.wParam = 0; if (event->ctrlKey()) npEvent.wParam |= MK_CONTROL; if (event->shiftKey()) npEvent.wParam |= MK_SHIFT; if (event->type() == eventNames().mousemoveEvent || event->type() == eventNames().mouseoutEvent || event->type() == eventNames().mouseoverEvent) { npEvent.event = WM_MOUSEMOVE; if (event->buttonDown()) switch (event->button()) { case LeftButton: npEvent.wParam |= MK_LBUTTON; break; case MiddleButton: npEvent.wParam |= MK_MBUTTON; break; case RightButton: npEvent.wParam |= MK_RBUTTON; break; } } else if (event->type() == eventNames().mousedownEvent) { // Focus the plugin if (Page* page = m_parentFrame->page()) page->focusController()->setFocusedFrame(m_parentFrame); m_parentFrame->document()->setFocusedNode(m_element); switch (event->button()) { case 0: npEvent.event = WM_LBUTTONDOWN; break; case 1: npEvent.event = WM_MBUTTONDOWN; break; case 2: npEvent.event = WM_RBUTTONDOWN; break; } } else if (event->type() == eventNames().mouseupEvent) { switch (event->button()) { case 0: npEvent.event = WM_LBUTTONUP; break; case 1: npEvent.event = WM_MBUTTONUP; break; case 2: npEvent.event = WM_RBUTTONUP; break; } } else return; HCURSOR currentCursor = ::GetCursor(); JSC::JSLock::DropAllLocks dropAllLocks(false); if (!dispatchNPEvent(npEvent)) event->setDefaultHandled();#if !PLATFORM(QT) // Currently, Widget::setCursor is always called after this function in EventHandler.cpp // and since we don't want that we set ignoreNextSetCursor to true here to prevent that. ignoreNextSetCursor = true; lastSetCursor = ::GetCursor();#endif}void PluginView::setParent(ScrollView* parent){ Widget::setParent(parent); if (parent) init(); else { if (!platformPluginWidget()) return; // If the plug-in window or one of its children have the focus, we need to // clear it to prevent the web view window from being focused because that can // trigger a layout while the plugin element is being detached. HWND focusedWindow = ::GetFocus(); if (platformPluginWidget() == focusedWindow || ::IsChild(platformPluginWidget(), focusedWindow)) ::SetFocus(0); }}void PluginView::setParentVisible(bool visible){ if (isParentVisible() == visible) return; Widget::setParentVisible(visible); if (isSelfVisible() && platformPluginWidget()) { if (visible) ShowWindow(platformPluginWidget(), SW_SHOWNA); else ShowWindow(platformPluginWidget(), SW_HIDE); }}void PluginView::setNPWindowRect(const IntRect& rect){ if (!m_isStarted) return; IntPoint p = static_cast<FrameView*>(parent())->contentsToWindow(rect.location()); m_npWindow.x = p.x(); m_npWindow.y = p.y(); m_npWindow.width = rect.width(); m_npWindow.height = rect.height(); m_npWindow.clipRect.left = 0; m_npWindow.clipRect.top = 0; m_npWindow.clipRect.right = rect.width(); m_npWindow.clipRect.bottom = rect.height(); if (m_plugin->pluginFuncs()->setwindow) { JSC::JSLock::DropAllLocks dropAllLocks(false); setCallingPlugin(true); m_plugin->pluginFuncs()->setwindow(m_instance, &m_npWindow); setCallingPlugin(false); if (!m_isWindowed) return; ASSERT(platformPluginWidget()); WNDPROC currentWndProc = (WNDPROC)GetWindowLongPtr(platformPluginWidget(), GWLP_WNDPROC); if (currentWndProc != PluginViewWndProc) m_pluginWndProc = (WNDPROC)SetWindowLongPtr(platformPluginWidget(), GWLP_WNDPROC, (LONG)PluginViewWndProc); }}void PluginView::stop(){ if (!m_isStarted) return; HashSet<RefPtr<PluginStream> > streams = m_streams; HashSet<RefPtr<PluginStream> >::iterator end = streams.end(); for (HashSet<RefPtr<PluginStream> >::iterator it = streams.begin(); it != end; ++it) { (*it)->stop(); disconnectStream((*it).get()); } ASSERT(m_streams.isEmpty()); m_isStarted = false; // Unsubclass the window if (m_isWindowed) { WNDPROC currentWndProc = (WNDPROC)GetWindowLongPtr(platformPluginWidget(), GWLP_WNDPROC); if (currentWndProc == PluginViewWndProc) SetWindowLongPtr(platformPluginWidget(), GWLP_WNDPROC, (LONG)m_pluginWndProc); } JSC::JSLock::DropAllLocks dropAllLocks(false); // Clear the window m_npWindow.window = 0; if (m_plugin->pluginFuncs()->setwindow && !m_plugin->quirks().contains(PluginQuirkDontSetNullWindowHandleOnDestroy)) { setCallingPlugin(true); m_plugin->pluginFuncs()->setwindow(m_instance, &m_npWindow); setCallingPlugin(false); } PluginMainThreadScheduler::scheduler().unregisterPlugin(m_instance); // Destroy the plugin NPSavedData* savedData = 0; setCallingPlugin(true); NPError npErr = m_plugin->pluginFuncs()->destroy(m_instance, &savedData); setCallingPlugin(false); LOG_NPERROR(npErr); if (savedData) { if (savedData->buf) NPN_MemFree(savedData->buf); NPN_MemFree(savedData); } m_instance->pdata = 0;}const char* PluginView::userAgentStatic(){ return 0;}const char* PluginView::userAgent(){ if (m_plugin->quirks().contains(PluginQuirkWantsMozillaUserAgent)) return MozillaUserAgent; if (m_userAgent.isNull()) m_userAgent = m_parentFrame->loader()->userAgent(m_url).utf8(); return m_userAgent.data();}NPError PluginView::handlePostReadFile(Vector<char>& buffer, uint32 len, const char* buf){ String filename(buf, len); if (filename.startsWith("file:///")) filename = filename.substring(8); // Get file info WIN32_FILE_ATTRIBUTE_DATA attrs; if (GetFileAttributesExW(filename.charactersWithNullTermination(), GetFileExInfoStandard, &attrs) == 0) return NPERR_FILE_NOT_FOUND; if (attrs.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) return NPERR_FILE_NOT_FOUND; HANDLE fileHandle = CreateFileW(filename.charactersWithNullTermination(), FILE_READ_DATA, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); if (fileHandle == INVALID_HANDLE_VALUE) return NPERR_FILE_NOT_FOUND; buffer.resize(attrs.nFileSizeLow); DWORD bytesRead; int retval = ReadFile(fileHandle, buffer.data(), attrs.nFileSizeLow, &bytesRead, 0); CloseHandle(fileHandle); if (retval == 0 || bytesRead != attrs.nFileSizeLow) return NPERR_FILE_NOT_FOUND; return NPERR_NO_ERROR;}NPError PluginView::getValueStatic(NPNVariable variable, void* value){ return NPERR_GENERIC_ERROR;}NPError PluginView::getValue(NPNVariable variable, void* value){ switch (variable) {#if ENABLE(NETSCAPE_PLUGIN_API) case NPNVWindowNPObject: { if (m_isJavaScriptPaused) return NPERR_GENERIC_ERROR; NPObject* windowScriptObject = m_parentFrame->script()->windowScriptNPObject(); // Return value is expected to be retained, as described here: <http://www.mozilla.org/projects/plugin/npruntime.html> if (windowScriptObject) _NPN_RetainObject(windowScriptObject); void** v = (void**)value; *v = windowScriptObject; return NPERR_NO_ERROR; } case NPNVPluginElementNPObject: { if (m_isJavaScriptPaused) return NPERR_GENERIC_ERROR; NPObject* pluginScriptObject = 0; if (m_element->hasTagName(appletTag) || m_element->hasTagName(embedTag) || m_element->hasTagName(objectTag)) pluginScriptObject = static_cast<HTMLPlugInElement*>(m_element)->getNPObject(); // Return value is expected to be retained, as described here: <http://www.mozilla.org/projects/plugin/npruntime.html> if (pluginScriptObject) _NPN_RetainObject(pluginScriptObject); void** v = (void**)value; *v = pluginScriptObject; return NPERR_NO_ERROR; }#endif case NPNVnetscapeWindow: { HWND* w = reinterpret_cast<HWND*>(value); *w = windowHandleForPlatformWidget(parent() ? parent()->hostWindow()->platformWindow() : 0); return NPERR_NO_ERROR; } case NPNVSupportsWindowless: { NPBool *result = reinterpret_cast<NPBool*>(value); *result = TRUE; return NPERR_NO_ERROR; } default: return NPERR_GENERIC_ERROR; }}void PluginView::invalidateRect(const IntRect& rect){ if (m_isWindowed) { RECT invalidRect = { rect.x(), rect.y(), rect.right(), rect.bottom() }; ::InvalidateRect(platformPluginWidget(), &invalidRect, false); return; } invalidateWindowlessPluginRect(rect);}void PluginView::invalidateRect(NPRect* rect){ if (!rect) { invalidate(); return; } IntRect r(rect->left, rect->top, rect->right - rect->left, rect->bottom - rect->top); if (m_isWindowed) { RECT invalidRect = { r.x(), r.y(), r.right(), r.bottom() }; InvalidateRect(platformPluginWidget(), &invalidRect, FALSE); } else { if (m_plugin->quirks().contains(PluginQuirkThrottleInvalidate)) { m_invalidRects.append(r); if (!m_invalidateTimer.isActive()) m_invalidateTimer.startOneShot(0.001); } else invalidateRect(r); }}void PluginView::invalidateRegion(NPRegion region){ if (m_isWindowed) return; RECT r; if (GetRgnBox(region, &r) == 0) { invalidate(); return; } IntRect rect(IntPoint(r.left, r.top), IntSize(r.right-r.left, r.bottom-r.top)); invalidateRect(rect);}void PluginView::forceRedraw(){ if (m_isWindowed) ::UpdateWindow(platformPluginWidget()); else ::UpdateWindow(windowHandleForPlatformWidget(parent() ? parent()->hostWindow()->platformWindow() : 0));}PluginView::~PluginView(){ stop(); deleteAllValues(m_requests); freeStringArray(m_paramNames, m_paramCount); freeStringArray(m_paramValues, m_paramCount); if (platformPluginWidget()) DestroyWindow(platformPluginWidget()); m_parentFrame->script()->cleanupScriptObjectsForPlugin(this); if (m_plugin && !m_plugin->quirks().contains(PluginQuirkDontUnloadPlugin)) m_plugin->unload();}void PluginView::init(){ if (m_haveInitialized) return; m_haveInitialized = true; if (!m_plugin) { ASSERT(m_status == PluginStatusCanNotFindPlugin); return; } if (!m_plugin->load()) { m_plugin = 0; m_status = PluginStatusCanNotLoadPlugin; return; } if (!start()) { m_status = PluginStatusCanNotLoadPlugin; return; } if (m_isWindowed) { registerPluginView(); setUpOffscreenPaintingHooks(hookedBeginPaint, hookedEndPaint); DWORD flags = WS_CHILD; if (isSelfVisible()) flags |= WS_VISIBLE; HWND parentWindowHandle = windowHandleForPlatformWidget(m_parentFrame->view()->hostWindow()->platformWindow()); HWND window = ::CreateWindowEx(0, kWebPluginViewdowClassName, 0, flags, 0, 0, 0, 0, parentWindowHandle, 0, Page::instanceHandle(), 0);#if PLATFORM(WIN_OS) && PLATFORM(QT) m_window = window;#else setPlatformWidget(window);#endif // Calling SetWindowLongPtrA here makes the window proc ASCII, which is required by at least // the Shockwave Director plug-in.#if PLATFORM(WIN_OS) && PLATFORM(X86_64) && COMPILER(MSVC) ::SetWindowLongPtrA(platformPluginWidget(), GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);#else ::SetWindowLongPtrA(platformPluginWidget(), GWL_WNDPROC, (LONG)DefWindowProcA);#endif SetProp(platformPluginWidget(), kWebPluginViewProperty, this); m_npWindow.type = NPWindowTypeWindow; m_npWindow.window = platformPluginWidget(); } else { m_npWindow.type = NPWindowTypeDrawable; m_npWindow.window = 0; } if (!m_plugin->quirks().contains(PluginQuirkDeferFirstSetWindowCall)) setNPWindowRect(frameRect()); m_status = PluginStatusLoadedSuccessfully;}} // namespace WebCore
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -