diff options
author | Steve Block <steveblock@google.com> | 2009-10-08 17:19:54 +0100 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2009-10-20 00:41:58 +0100 |
commit | 231d4e3152a9c27a73b6ac7badbe6be673aa3ddf (patch) | |
tree | a6c7e2d6cd7bfa7011cc39abbb436142d7a4a7c8 /WebCore/plugins/qt | |
parent | e196732677050bd463301566a68a643b6d14b907 (diff) | |
download | external_webkit-231d4e3152a9c27a73b6ac7badbe6be673aa3ddf.zip external_webkit-231d4e3152a9c27a73b6ac7badbe6be673aa3ddf.tar.gz external_webkit-231d4e3152a9c27a73b6ac7badbe6be673aa3ddf.tar.bz2 |
Merge webkit.org at R49305 : Automatic merge by git.
Change-Id: I8968561bc1bfd72b8923b7118d3728579c6dbcc7
Diffstat (limited to 'WebCore/plugins/qt')
-rw-r--r-- | WebCore/plugins/qt/PluginPackageQt.cpp | 18 | ||||
-rw-r--r-- | WebCore/plugins/qt/PluginViewQt.cpp | 516 |
2 files changed, 434 insertions, 100 deletions
diff --git a/WebCore/plugins/qt/PluginPackageQt.cpp b/WebCore/plugins/qt/PluginPackageQt.cpp index b9c1656..8119924 100644 --- a/WebCore/plugins/qt/PluginPackageQt.cpp +++ b/WebCore/plugins/qt/PluginPackageQt.cpp @@ -63,7 +63,7 @@ bool PluginPackage::fetchInfo() String s = gm(); Vector<String> types; s.split(UChar(';'), false, types); - for (int i = 0; i < types.size(); ++i) { + for (unsigned i = 0; i < types.size(); ++i) { Vector<String> mime; types[i].split(UChar(':'), true, mime); if (mime.size() > 0) { @@ -80,6 +80,16 @@ bool PluginPackage::fetchInfo() return true; } +static NPError staticPluginQuirkRequiresGtkToolKit_NPN_GetValue(NPP instance, NPNVariable variable, void* value) +{ + if (variable == NPNVToolkit) { + *static_cast<uint32*>(value) = 2; + return NPERR_NO_ERROR; + } + + return NPN_GetValue(instance, variable, value); +} + bool PluginPackage::load() { if (m_isLoaded) { @@ -111,6 +121,12 @@ bool PluginPackage::load() initializeBrowserFuncs(); + if (m_path.contains("npwrapper.")) { + // nspluginwrapper relies on the toolkit value to know if glib is available + // It does so in NP_Initialize with a null instance, therefore it is done this way: + m_browserFuncs.getvalue = staticPluginQuirkRequiresGtkToolKit_NPN_GetValue; + } + #if defined(XP_UNIX) npErr = NP_Initialize(&m_browserFuncs, &m_pluginFuncs); #else diff --git a/WebCore/plugins/qt/PluginViewQt.cpp b/WebCore/plugins/qt/PluginViewQt.cpp index a02a8fd..27639e1 100644 --- a/WebCore/plugins/qt/PluginViewQt.cpp +++ b/WebCore/plugins/qt/PluginViewQt.cpp @@ -1,6 +1,7 @@ /* * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. * Copyright (C) 2008 Collabora Ltd. All rights reserved. + * Copyright (C) 2009 Girish Ramakrishnan <girish@forwardbias.in> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -30,6 +31,8 @@ #include "Document.h" #include "DocumentLoader.h" #include "Element.h" +#include "FloatPoint.h" +#include "FocusController.h" #include "Frame.h" #include "FrameLoadRequest.h" #include "FrameLoader.h" @@ -56,12 +59,21 @@ #include "npruntime_impl.h" #include "runtime.h" #include "runtime_root.h" +#include "QWebPageClient.h" +#include <QApplication> +#include <QDesktopWidget> #include <QKeyEvent> +#include <QPainter> #include <QWidget> #include <QX11Info> #include <runtime/JSLock.h> #include <runtime/JSValue.h> #include <X11/X.h> +#ifndef QT_NO_XRENDER +#define Bool int +#define Status int +#include <X11/extensions/Xrender.h> +#endif using JSC::ExecState; using JSC::Interpreter; @@ -79,7 +91,7 @@ using namespace HTMLNames; void PluginView::updatePluginWidget() { - if (!parent() || !m_isWindowed || !platformPluginWidget()) + if (!parent()) return; ASSERT(parent()->isFrameView()); @@ -95,6 +107,15 @@ void PluginView::updatePluginWidget() if (m_windowRect == oldWindowRect && m_clipRect == oldClipRect) return; + if (m_drawable) + XFreePixmap(QX11Info::display(), m_drawable); + + if (!m_isWindowed) { + m_drawable = XCreatePixmap(QX11Info::display(), QX11Info::appRootWindow(), m_windowRect.width(), m_windowRect.height(), + ((NPSetWindowCallbackStruct*)m_npWindow.ws_info)->depth); + QApplication::syncX(); // make sure that the server knows about the Drawable + } + // do not call setNPWindowIfNeeded immediately, will be called on paint() m_hasPendingGeometryChange = true; @@ -149,8 +170,67 @@ void PluginView::paint(GraphicsContext* context, const IntRect& rect) if (context->paintingDisabled()) return; - if (m_isWindowed && platformPluginWidget()) - setNPWindowIfNeeded(); + setNPWindowIfNeeded(); + + if (m_isWindowed || !m_drawable) + return; + + const bool syncX = m_pluginDisplay && m_pluginDisplay != QX11Info::display(); + + QPainter* painter = context->platformContext(); + + QPixmap qtDrawable = QPixmap::fromX11Pixmap(m_drawable, QPixmap::ExplicitlyShared); + const int drawableDepth = ((NPSetWindowCallbackStruct*)m_npWindow.ws_info)->depth; + ASSERT(drawableDepth == qtDrawable.depth()); + + if (m_isTransparent && drawableDepth != 32) { + // Attempt content propagation for drawable with no alpha by copying over from the backing store + QPoint offset; + QPaintDevice* backingStoreDevice = QPainter::redirected(painter->device(), &offset); + offset = -offset; // negating the offset gives us the offset of the view within the backing store pixmap + + const bool hasValidBackingStore = backingStoreDevice && backingStoreDevice->devType() == QInternal::Pixmap; + QPixmap* backingStorePixmap = static_cast<QPixmap*>(backingStoreDevice); + + // We cannot grab contents from the backing store when painting on QGraphicsView items + // (because backing store contents are already transformed). What we really mean to do + // here is to check if we are painting on QWebView, but let's be a little permissive :) + QWebPageClient* client = m_parentFrame->view()->hostWindow()->platformPageClient(); + const bool backingStoreHasUntransformedContents = qobject_cast<QWidget*>(client->pluginParent()); + + if (hasValidBackingStore && backingStorePixmap->depth() == drawableDepth + && backingStoreHasUntransformedContents) { + GC gc = XDefaultGC(QX11Info::display(), QX11Info::appScreen()); + XCopyArea(QX11Info::display(), backingStorePixmap->handle(), m_drawable, gc, + offset.x() + m_windowRect.x() + m_clipRect.x(), offset.y() + m_windowRect.y() + m_clipRect.y(), + m_clipRect.width(), m_clipRect.height(), m_clipRect.x(), m_clipRect.y()); + } else { // no backing store, clean the pixmap because the plugin thinks its transparent + QPainter painter(&qtDrawable); + painter.fillRect(m_clipRect, Qt::white); + } + + if (syncX) + QApplication::syncX(); + } + + XEvent xevent; + memset(&xevent, 0, sizeof(XEvent)); + XGraphicsExposeEvent& exposeEvent = xevent.xgraphicsexpose; + exposeEvent.type = GraphicsExpose; + exposeEvent.display = QX11Info::display(); + exposeEvent.drawable = m_drawable; + exposeEvent.x = m_clipRect.x(); + exposeEvent.y = m_clipRect.y(); + exposeEvent.width = m_clipRect.x() + m_clipRect.width(); // flash bug? it thinks width is the right + exposeEvent.height = m_clipRect.y() + m_clipRect.height(); // flash bug? it thinks height is the bottom + + dispatchNPEvent(xevent); + + if (syncX) + XSync(m_pluginDisplay, False); // sync changes by plugin + + painter->drawPixmap(frameRect().x() + m_clipRect.x(), frameRect().y() + m_clipRect.y(), qtDrawable, + m_clipRect.x(), m_clipRect.y(), m_clipRect.width(), m_clipRect.height()); } // TODO: Unify across ports. @@ -163,42 +243,52 @@ bool PluginView::dispatchNPEvent(NPEvent& event) JSC::JSLock::DropAllLocks dropAllLocks(false); setCallingPlugin(true); - bool accepted = m_plugin->pluginFuncs(); + bool accepted = m_plugin->pluginFuncs()->event(m_instance, &event); setCallingPlugin(false); return accepted; } -void setSharedXEventFields(XEvent& xEvent, QWidget* hostWindow) +void setSharedXEventFields(XEvent* xEvent, QWidget* hostWindow) { - xEvent.xany.serial = 0; // we are unaware of the last request processed by X Server - xEvent.xany.send_event = false; - xEvent.xany.display = hostWindow->x11Info().display(); - // NOTE: event.xany.window doesn't always respond to the .window property of other XEvent's + xEvent->xany.serial = 0; // we are unaware of the last request processed by X Server + xEvent->xany.send_event = false; + xEvent->xany.display = hostWindow->x11Info().display(); + // NOTE: event->xany.window doesn't always respond to the .window property of other XEvent's // but does in the case of KeyPress, KeyRelease, ButtonPress, ButtonRelease, and MotionNotify // events; thus, this is right: - xEvent.xany.window = hostWindow->window()->handle(); + xEvent->xany.window = hostWindow->window()->handle(); } -void setXKeyEventSpecificFields(XEvent& xEvent, KeyboardEvent* event) +void PluginView::initXEvent(XEvent* xEvent) +{ + memset(xEvent, 0, sizeof(XEvent)); + + QWebPageClient* client = m_parentFrame->view()->hostWindow()->platformPageClient(); + QWidget* window = QWidget::find(client->winId()); + setSharedXEventFields(xEvent, window); +} + +void setXKeyEventSpecificFields(XEvent* xEvent, KeyboardEvent* event) { QKeyEvent* qKeyEvent = event->keyEvent()->qtEvent(); - xEvent.xkey.root = QX11Info::appRootWindow(); - xEvent.xkey.subwindow = 0; // we have no child window - xEvent.xkey.time = event->timeStamp(); - xEvent.xkey.state = qKeyEvent->nativeModifiers(); - xEvent.xkey.keycode = qKeyEvent->nativeScanCode(); - xEvent.xkey.same_screen = true; + xEvent->type = (event->type() == eventNames().keydownEvent) ? 2 : 3; // ints as Qt unsets KeyPress and KeyRelease + xEvent->xkey.root = QX11Info::appRootWindow(); + xEvent->xkey.subwindow = 0; // we have no child window + xEvent->xkey.time = event->timeStamp(); + xEvent->xkey.state = qKeyEvent->nativeModifiers(); + xEvent->xkey.keycode = qKeyEvent->nativeScanCode(); + xEvent->xkey.same_screen = true; // NOTE: As the XEvents sent to the plug-in are synthesized and there is not a native window // corresponding to the plug-in rectangle, some of the members of the XEvent structures are not // set to their normal Xserver values. e.g. Key events don't have a position. // source: https://developer.mozilla.org/en/NPEvent - xEvent.xkey.x = 0; - xEvent.xkey.y = 0; - xEvent.xkey.x_root = 0; - xEvent.xkey.y_root = 0; + xEvent->xkey.x = 0; + xEvent->xkey.y = 0; + xEvent->xkey.x_root = 0; + xEvent->xkey.y_root = 0; } void PluginView::handleKeyboardEvent(KeyboardEvent* event) @@ -206,23 +296,147 @@ void PluginView::handleKeyboardEvent(KeyboardEvent* event) if (m_isWindowed) return; - if (event->type() != "keydown" && event->type() != "keyup") + if (event->type() != eventNames().keydownEvent && event->type() != eventNames().keyupEvent) return; - XEvent npEvent; // On UNIX NPEvent is a typedef for XEvent. - - npEvent.type = (event->type() == "keydown") ? 2 : 3; // ints as Qt unsets KeyPress and KeyRelease - setSharedXEventFields(npEvent, m_parentFrame->view()->hostWindow()->platformWindow()); - setXKeyEventSpecificFields(npEvent, event); + XEvent npEvent; + initXEvent(&npEvent); + setXKeyEventSpecificFields(&npEvent, event); if (!dispatchNPEvent(npEvent)) event->setDefaultHandled(); } +static unsigned int inputEventState(MouseEvent* event) +{ + unsigned int state = 0; + if (event->ctrlKey()) + state |= ControlMask; + if (event->shiftKey()) + state |= ShiftMask; + if (event->altKey()) + state |= Mod1Mask; + if (event->metaKey()) + state |= Mod4Mask; + return state; +} + +static void setXButtonEventSpecificFields(XEvent* xEvent, MouseEvent* event, const IntPoint& postZoomPos) +{ + XButtonEvent& xbutton = xEvent->xbutton; + xbutton.type = event->type() == eventNames().mousedownEvent ? ButtonPress : ButtonRelease; + xbutton.root = QX11Info::appRootWindow(); + xbutton.subwindow = 0; + xbutton.time = event->timeStamp(); + xbutton.x = postZoomPos.x(); + xbutton.y = postZoomPos.y(); + xbutton.x_root = event->screenX(); + xbutton.y_root = event->screenY(); + xbutton.state = inputEventState(event); + switch (event->button()) { + case MiddleButton: + xbutton.button = Button2; + break; + case RightButton: + xbutton.button = Button3; + break; + case LeftButton: + default: + xbutton.button = Button1; + break; + } + xbutton.same_screen = true; +} + +static void setXMotionEventSpecificFields(XEvent* xEvent, MouseEvent* event, const IntPoint& postZoomPos) +{ + XMotionEvent& xmotion = xEvent->xmotion; + xmotion.type = MotionNotify; + xmotion.root = QX11Info::appRootWindow(); + xmotion.subwindow = 0; + xmotion.time = event->timeStamp(); + xmotion.x = postZoomPos.x(); + xmotion.y = postZoomPos.y(); + xmotion.x_root = event->screenX(); + xmotion.y_root = event->screenY(); + xmotion.state = inputEventState(event); + xmotion.is_hint = NotifyNormal; + xmotion.same_screen = true; +} + +static void setXCrossingEventSpecificFields(XEvent* xEvent, MouseEvent* event, const IntPoint& postZoomPos) +{ + XCrossingEvent& xcrossing = xEvent->xcrossing; + xcrossing.type = event->type() == eventNames().mouseoverEvent ? EnterNotify : LeaveNotify; + xcrossing.root = QX11Info::appRootWindow(); + xcrossing.subwindow = 0; + xcrossing.time = event->timeStamp(); + xcrossing.x = postZoomPos.y(); + xcrossing.y = postZoomPos.x(); + xcrossing.x_root = event->screenX(); + xcrossing.y_root = event->screenY(); + xcrossing.state = inputEventState(event); + xcrossing.mode = NotifyNormal; + xcrossing.detail = NotifyDetailNone; + xcrossing.same_screen = true; + xcrossing.focus = false; +} + void PluginView::handleMouseEvent(MouseEvent* event) { if (m_isWindowed) return; + + if (event->type() == eventNames().mousedownEvent) { + // Give focus to the plugin on click + if (Page* page = m_parentFrame->page()) + page->focusController()->setActive(true); + + focusPluginElement(); + } + + XEvent npEvent; + initXEvent(&npEvent); + + IntPoint postZoomPos = roundedIntPoint(m_element->renderer()->absoluteToLocal(event->absoluteLocation())); + + if (event->type() == eventNames().mousedownEvent || event->type() == eventNames().mouseupEvent) + setXButtonEventSpecificFields(&npEvent, event, postZoomPos); + else if (event->type() == eventNames().mousemoveEvent) + setXMotionEventSpecificFields(&npEvent, event, postZoomPos); + else if (event->type() == eventNames().mouseoutEvent || event->type() == eventNames().mouseoverEvent) + setXCrossingEventSpecificFields(&npEvent, event, postZoomPos); + else + return; + + if (!dispatchNPEvent(npEvent)) + event->setDefaultHandled(); +} + +void PluginView::handleFocusInEvent() +{ + XEvent npEvent; + initXEvent(&npEvent); + + XFocusChangeEvent& event = npEvent.xfocus; + event.type = 9; /* int as Qt unsets FocusIn */ + event.mode = NotifyNormal; + event.detail = NotifyDetailNone; + + dispatchNPEvent(npEvent); +} + +void PluginView::handleFocusOutEvent() +{ + XEvent npEvent; + initXEvent(&npEvent); + + XFocusChangeEvent& event = npEvent.xfocus; + event.type = 10; /* int as Qt unsets FocusOut */ + event.mode = NotifyNormal; + event.detail = NotifyDetailNone; + + dispatchNPEvent(npEvent); } void PluginView::setParent(ScrollView* parent) @@ -235,7 +449,8 @@ void PluginView::setParent(ScrollView* parent) void PluginView::setNPWindowRect(const IntRect&) { - // Ignored as we don't want to move immediately. + if (!m_isWindowed) + setNPWindowIfNeeded(); } void PluginView::setNPWindowIfNeeded() @@ -251,28 +466,38 @@ void PluginView::setNPWindowIfNeeded() return; m_hasPendingGeometryChange = false; - ASSERT(platformPluginWidget()); - platformPluginWidget()->setGeometry(m_windowRect); - // if setMask is set with an empty QRegion, no clipping will - // be performed, so in that case we hide the plugin view - platformPluginWidget()->setVisible(!m_clipRect.isEmpty()); - platformPluginWidget()->setMask(QRegion(m_clipRect)); + if (m_isWindowed) { + ASSERT(platformPluginWidget()); + platformPluginWidget()->setGeometry(m_windowRect); + // if setMask is set with an empty QRegion, no clipping will + // be performed, so in that case we hide the plugin view + platformPluginWidget()->setVisible(!m_clipRect.isEmpty()); + platformPluginWidget()->setMask(QRegion(m_clipRect)); + + m_npWindow.x = m_windowRect.x(); + m_npWindow.y = m_windowRect.y(); + + m_npWindow.clipRect.left = m_clipRect.x(); + m_npWindow.clipRect.top = m_clipRect.y(); + m_npWindow.clipRect.right = m_clipRect.width(); + m_npWindow.clipRect.bottom = m_clipRect.height(); + } else { + m_npWindow.x = 0; + m_npWindow.y = 0; + + m_npWindow.clipRect.left = 0; + m_npWindow.clipRect.top = 0; + m_npWindow.clipRect.right = 0; + m_npWindow.clipRect.bottom = 0; + } // FLASH WORKAROUND: Only set initially. Multiple calls to - // setNPWindow() cause the plugin to crash. - if (m_npWindow.width == -1 || m_npWindow.height == -1) { + // setNPWindow() cause the plugin to crash in windowed mode. + if (!m_isWindowed || m_npWindow.width == -1 || m_npWindow.height == -1) { m_npWindow.width = m_windowRect.width(); m_npWindow.height = m_windowRect.height(); } - m_npWindow.x = m_windowRect.x(); - m_npWindow.y = m_windowRect.y(); - - m_npWindow.clipRect.left = m_clipRect.x(); - m_npWindow.clipRect.top = m_clipRect.y(); - m_npWindow.clipRect.right = m_clipRect.width(); - m_npWindow.clipRect.bottom = m_clipRect.height(); - PluginView::setCurrentPluginView(this); JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly); setCallingPlugin(true); @@ -337,6 +562,10 @@ NPError PluginView::getValueStatic(NPNVariable variable, void* value) *static_cast<NPBool*>(value) = true; return NPERR_NO_ERROR; + case NPNVSupportsWindowless: + *static_cast<NPBool*>(value) = true; + return NPERR_NO_ERROR; + default: return NPERR_GENERIC_ERROR; } @@ -350,8 +579,11 @@ NPError PluginView::getValue(NPNVariable variable, void* value) case NPNVxDisplay: if (platformPluginWidget()) *(void **)value = platformPluginWidget()->x11Info().display(); - else - *(void **)value = m_parentFrame->view()->hostWindow()->platformWindow()->x11Info().display(); + else { + QWebPageClient* client = m_parentFrame->view()->hostWindow()->platformPageClient(); + QWidget* window = QWidget::find(client->winId()); + *(void **)value = window->x11Info().display(); + } return NPERR_NO_ERROR; case NPNVxtAppContext: @@ -396,7 +628,7 @@ NPError PluginView::getValue(NPNVariable variable, void* value) case NPNVnetscapeWindow: { void* w = reinterpret_cast<void*>(value); - *((XID *)w) = m_parentFrame->view()->hostWindow()->platformWindow()->winId(); + *((XID *)w) = m_parentFrame->view()->hostWindow()->platformPageClient()->winId(); return NPERR_NO_ERROR; } @@ -413,7 +645,7 @@ NPError PluginView::getValue(NPNVariable variable, void* value) void PluginView::invalidateRect(const IntRect& rect) { - if (platformWidget()) { + if (m_isWindowed) { platformWidget()->update(rect); return; } @@ -423,59 +655,94 @@ void PluginView::invalidateRect(const IntRect& rect) void PluginView::invalidateRect(NPRect* rect) { - notImplemented(); + if (!rect) { + invalidate(); + return; + } + IntRect r(rect->left, rect->top, rect->right + rect->left, rect->bottom + rect->top); + invalidateWindowlessPluginRect(r); } void PluginView::invalidateRegion(NPRegion region) { - notImplemented(); + invalidate(); } void PluginView::forceRedraw() { - notImplemented(); + invalidate(); } -PluginView::~PluginView() +static Display *getPluginDisplay() { - stop(); - - deleteAllValues(m_requests); - - freeStringArray(m_paramNames, m_paramCount); - freeStringArray(m_paramValues, m_paramCount); - - m_parentFrame->script()->cleanupScriptObjectsForPlugin(this); - - if (m_plugin && !(m_plugin->quirks().contains(PluginQuirkDontUnloadPlugin))) - m_plugin->unload(); - - delete platformPluginWidget(); + // The plugin toolkit might run using a different X connection. At the moment, we only + // support gdk based plugins (like flash) that use a different X connection. + // The code below has the same effect as this one: + // Display *gdkDisplay = gdk_x11_display_get_xdisplay(gdk_display_get_default()); + QLibrary library("libgdk-x11-2.0"); + if (!library.load()) + return 0; + + typedef void *(*gdk_display_get_default_ptr)(); + gdk_display_get_default_ptr gdk_display_get_default = (gdk_display_get_default_ptr)library.resolve("gdk_display_get_default"); + if (!gdk_display_get_default) + return 0; + + typedef void *(*gdk_x11_display_get_xdisplay_ptr)(void *); + gdk_x11_display_get_xdisplay_ptr gdk_x11_display_get_xdisplay = (gdk_x11_display_get_xdisplay_ptr)library.resolve("gdk_x11_display_get_xdisplay"); + if (!gdk_x11_display_get_xdisplay) + return 0; + + return (Display*)gdk_x11_display_get_xdisplay(gdk_display_get_default()); } -void PluginView::init() +static void getVisualAndColormap(int depth, Visual **visual, Colormap *colormap) { - if (m_haveInitialized) - return; - m_haveInitialized = true; + *visual = 0; + *colormap = 0; - m_hasPendingGeometryChange = false; +#ifndef QT_NO_XRENDER + static const bool useXRender = qgetenv("QT_X11_NO_XRENDER").isNull(); // Should also check for XRender >= 0.5 +#else + static const bool useXRender = false; +#endif - if (!m_plugin) { - ASSERT(m_status == PluginStatusCanNotFindPlugin); + if (!useXRender && depth == 32) return; - } - if (!m_plugin->load()) { - m_plugin = 0; - m_status = PluginStatusCanNotLoadPlugin; - return; - } + int nvi; + XVisualInfo templ; + templ.screen = QX11Info::appScreen(); + templ.depth = depth; + templ.c_class = TrueColor; + XVisualInfo* xvi = XGetVisualInfo(QX11Info::display(), VisualScreenMask | VisualDepthMask | VisualClassMask, &templ, &nvi); - if (!start()) { - m_status = PluginStatusCanNotLoadPlugin; + if (!xvi) return; - } + +#ifndef QT_NO_XRENDER + if (depth == 32) { + for (int idx = 0; idx < nvi; ++idx) { + XRenderPictFormat* format = XRenderFindVisualFormat(QX11Info::display(), xvi[idx].visual); + if (format->type == PictTypeDirect && format->direct.alphaMask) { + *visual = xvi[idx].visual; + break; + } + } + } else +#endif // QT_NO_XRENDER + *visual = xvi[0].visual; + + XFree(xvi); + + if (*visual) + *colormap = XCreateColormap(QX11Info::display(), QX11Info::appRootWindow(), *visual, AllocNone); +} + +bool PluginView::platformStart() +{ + ASSERT(m_isStarted); + ASSERT(m_status == PluginStatusLoadedSuccessfully); if (m_plugin->pluginFuncs()->getvalue) { PluginView::setCurrentPluginView(this); @@ -486,41 +753,92 @@ void PluginView::init() PluginView::setCurrentPluginView(0); } - if (m_needsXEmbed) { - setPlatformWidget(new PluginContainerQt(this, m_parentFrame->view()->hostWindow()->platformWindow())); + if (m_isWindowed) { + if (m_needsXEmbed) { + QWebPageClient* client = m_parentFrame->view()->hostWindow()->platformPageClient(); + setPlatformWidget(new PluginContainerQt(this, QWidget::find(client->winId()))); + // sync our XEmbed container window creation before sending the xid to plugins. + QApplication::syncX(); + } else { + notImplemented(); + m_status = PluginStatusCanNotLoadPlugin; + return false; + } } else { - notImplemented(); - m_status = PluginStatusCanNotLoadPlugin; - return; + setPlatformWidget(0); + m_pluginDisplay = getPluginDisplay(); } - show(); - NPSetWindowCallbackStruct *wsi = new NPSetWindowCallbackStruct(); + show(); + NPSetWindowCallbackStruct* wsi = new NPSetWindowCallbackStruct(); wsi->type = 0; - wsi->display = platformPluginWidget()->x11Info().display(); - wsi->visual = (Visual*)platformPluginWidget()->x11Info().visual(); - wsi->depth = platformPluginWidget()->x11Info().depth(); - wsi->colormap = platformPluginWidget()->x11Info().colormap(); - m_npWindow.ws_info = wsi; + if (m_isWindowed) { + const QX11Info* x11Info = &platformPluginWidget()->x11Info(); + + wsi->display = x11Info->display(); + wsi->visual = (Visual*)x11Info->visual(); + wsi->depth = x11Info->depth(); + wsi->colormap = x11Info->colormap(); + + m_npWindow.type = NPWindowTypeWindow; + m_npWindow.window = (void*)platformPluginWidget()->winId(); + m_npWindow.width = -1; + m_npWindow.height = -1; + } else { + const QX11Info* x11Info = &QApplication::desktop()->x11Info(); + + if (x11Info->depth() == 32 || !m_plugin->quirks().contains(PluginQuirkRequiresDefaultScreenDepth)) { + getVisualAndColormap(32, &m_visual, &m_colormap); + wsi->depth = 32; + } + + if (!m_visual) { + getVisualAndColormap(x11Info->depth(), &m_visual, &m_colormap); + wsi->depth = x11Info->depth(); + } + + wsi->display = x11Info->display(); + wsi->visual = m_visual; + wsi->colormap = m_colormap; - m_npWindow.type = NPWindowTypeWindow; - m_npWindow.window = (void*)platformPluginWidget()->winId(); - m_npWindow.width = -1; - m_npWindow.height = -1; + m_npWindow.type = NPWindowTypeDrawable; + m_npWindow.window = 0; // Not used? + m_npWindow.x = 0; + m_npWindow.y = 0; + m_npWindow.width = -1; + m_npWindow.height = -1; + } + + m_npWindow.ws_info = wsi; if (!(m_plugin->quirks().contains(PluginQuirkDeferFirstSetWindowCall))) { updatePluginWidget(); setNPWindowIfNeeded(); } - m_status = PluginStatusLoadedSuccessfully; + return true; } -void PluginView::platformStart() +void PluginView::platformDestroy() +{ + if (platformPluginWidget()) + delete platformPluginWidget(); + + if (m_drawable) + XFreePixmap(QX11Info::display(), m_drawable); + + if (m_colormap) + XFreeColormap(QX11Info::display(), m_colormap); +} + +void PluginView::halt() { } +void PluginView::restart() +{ +} } // namespace WebCore |