bool NetscapePlugin::platformPostInitialize() { #if PLATFORM(GTK) if (moduleMixesGtkSymbols(m_pluginModule->module())) return false; #endif uint64_t windowID = 0; bool needsXEmbed = false; if (m_isWindowed) { NPP_GetValue(NPPVpluginNeedsXEmbed, &needsXEmbed); if (needsXEmbed) { windowID = controller()->createPluginContainer(); if (!windowID) return false; } else { notImplemented(); return false; } } if (!(m_pluginDisplay = getPluginDisplay())) return false; NPSetWindowCallbackStruct* callbackStruct = new NPSetWindowCallbackStruct; callbackStruct->type = 0; m_npWindow.ws_info = callbackStruct; if (m_isWindowed) return platformPostInitializeWindowed(needsXEmbed, windowID); return platformPostInitializeWindowless(); }
void PluginView::updatePluginWidget() { if (!parent()) return; ASSERT(parent()->isFrameView()); FrameView* frameView = toFrameView(parent()); IntRect oldWindowRect = m_windowRect; IntRect oldClipRect = m_clipRect; m_windowRect = IntRect(frameView->contentsToWindow(frameRect().location()), frameRect().size()); m_clipRect = windowClipRect(); m_clipRect.move(-m_windowRect.x(), -m_windowRect.y()); if (m_windowRect == oldWindowRect && m_clipRect == oldClipRect) return; if (m_status != PluginStatusLoadedSuccessfully) return; if (!m_isWindowed && !m_windowRect.isEmpty()) { Display* display = getPluginDisplay(nullptr); if (m_drawable) XFreePixmap(display, m_drawable); m_drawable = XCreatePixmap(display, getRootWindow(m_parentFrame.get()), m_windowRect.width(), m_windowRect.height(), ((NPSetWindowCallbackStruct*)m_npWindow.ws_info)->depth); XSync(display, false); // make sure that the server knows about the Drawable } setNPWindowIfNeeded(); }
bool NetscapePlugin::platformPostInitialize() { uint64_t windowID = 0; // NPPVpluginNeedsXEmbed is a boolean value, but at least the // Flash player plugin is using an 'int' instead. int needsXEmbed = 0; if (m_isWindowed) { NPP_GetValue(NPPVpluginNeedsXEmbed, &needsXEmbed); if (needsXEmbed) { windowID = controller()->createPluginContainer(); if (!windowID) return false; } else { notImplemented(); return false; } } if (!(m_pluginDisplay = getPluginDisplay())) return false; NPSetWindowCallbackStruct* callbackStruct = new NPSetWindowCallbackStruct; callbackStruct->type = 0; m_npWindow.ws_info = callbackStruct; if (m_isWindowed) return platformPostInitializeWindowed(needsXEmbed, windowID); return platformPostInitializeWindowless(); }
void PluginView::initXEvent(XEvent* xEvent) { memset(xEvent, 0, sizeof(XEvent)); xEvent->xany.serial = 0; // we are unaware of the last request processed by X Server xEvent->xany.send_event = false; xEvent->xany.display = getPluginDisplay(m_parentFrame.get()); // Mozilla also sends None here for windowless plugins. See nsObjectFrame.cpp in the Mozilla sources. // This method also sets up FocusIn and FocusOut events for windows plugins, but Mozilla doesn't // even send these types of events to windowed plugins. In the future, it may be good to only // send them to windowless plugins. xEvent->xany.window = None; }
std::unique_ptr<NetscapePluginX11> NetscapePluginX11::create(NetscapePlugin& plugin) { #if PLATFORM(GTK) uint64_t windowID = 0; #endif if (plugin.isWindowed()) { #if PLATFORM(GTK) // NPPVplugiNeedsXEmbed is a boolean value, but at least the // Flash player plugin is using an 'int' instead. int needsXEmbed = 0; plugin.NPP_GetValue(NPPVpluginNeedsXEmbed, &needsXEmbed); if (needsXEmbed) { windowID = plugin.controller()->createPluginContainer(); if (!windowID) return nullptr; } else { notImplemented(); return nullptr; } #else notImplemented(); return nullptr; #endif } Display* display = getPluginDisplay(); if (!display) return nullptr; #if PLATFORM(GTK) if (plugin.isWindowed()) return std::make_unique<NetscapePluginX11>(plugin, display, windowID); #endif return std::make_unique<NetscapePluginX11>(plugin, display); }
void PluginView::paint(GraphicsContext* context, const IntRect& rect) { if (!m_isStarted || m_status != PluginStatusLoadedSuccessfully) { paintMissingPluginIcon(context, rect); return; } if (context->paintingDisabled()) return; setNPWindowIfNeeded(); if (m_isWindowed) return; if (!m_drawable) return; Display* display = getPluginDisplay(nullptr); const bool syncX = m_pluginDisplay && m_pluginDisplay != display; IntRect exposedRect(rect); exposedRect.intersect(frameRect()); exposedRect.move(-frameRect().x(), -frameRect().y()); RefPtr<cairo_surface_t> drawableSurface = adoptRef(cairo_xlib_surface_create(display, m_drawable, m_visual, m_windowRect.width(), m_windowRect.height())); if (m_isTransparent) { // If we have a 32 bit drawable and the plugin wants transparency, // we'll clear the exposed area to transparent first. Otherwise, // we'd end up with junk in there from the last paint, or, worse, // uninitialized data. RefPtr<cairo_t> cr = adoptRef(cairo_create(drawableSurface.get())); if (!(cairo_surface_get_content(drawableSurface.get()) & CAIRO_CONTENT_ALPHA)) { // Attempt to fake it when we don't have an alpha channel on our // pixmap. If that's not possible, at least clear the window to // avoid drawing artifacts. // This Would not work without double buffering, but we always use it. cairo_set_source_surface(cr.get(), cairo_get_group_target(context->platformContext()->cr()), -m_windowRect.x(), -m_windowRect.y()); cairo_set_operator(cr.get(), CAIRO_OPERATOR_SOURCE); } else cairo_set_operator(cr.get(), CAIRO_OPERATOR_CLEAR); cairo_rectangle(cr.get(), exposedRect.x(), exposedRect.y(), exposedRect.width(), exposedRect.height()); cairo_fill(cr.get()); } XEvent xevent; memset(&xevent, 0, sizeof(XEvent)); XGraphicsExposeEvent& exposeEvent = xevent.xgraphicsexpose; exposeEvent.type = GraphicsExpose; exposeEvent.display = display; exposeEvent.drawable = m_drawable; exposeEvent.x = exposedRect.x(); exposeEvent.y = exposedRect.y(); exposeEvent.width = exposedRect.x() + exposedRect.width(); // flash bug? it thinks width is the right in transparent mode exposeEvent.height = exposedRect.y() + exposedRect.height(); // flash bug? it thinks height is the bottom in transparent mode dispatchNPEvent(xevent); if (syncX) XSync(m_pluginDisplay, false); // sync changes by plugin cairo_t* cr = context->platformContext()->cr(); cairo_save(cr); cairo_set_source_surface(cr, drawableSurface.get(), frameRect().x(), frameRect().y()); cairo_rectangle(cr, frameRect().x() + exposedRect.x(), frameRect().y() + exposedRect.y(), exposedRect.width(), exposedRect.height()); cairo_clip(cr); if (m_isTransparent) cairo_set_operator(cr, CAIRO_OPERATOR_OVER); else cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); cairo_paint(cr); cairo_restore(cr); }