diff options
Diffstat (limited to 'WebCore/plugins/qt')
-rw-r--r-- | WebCore/plugins/qt/PluginPackageQt.cpp | 63 | ||||
-rw-r--r-- | WebCore/plugins/qt/PluginViewQt.cpp | 57 |
2 files changed, 80 insertions, 40 deletions
diff --git a/WebCore/plugins/qt/PluginPackageQt.cpp b/WebCore/plugins/qt/PluginPackageQt.cpp index 07149f3..d92fffe 100644 --- a/WebCore/plugins/qt/PluginPackageQt.cpp +++ b/WebCore/plugins/qt/PluginPackageQt.cpp @@ -35,8 +35,6 @@ namespace WebCore { -typedef void gtkInitFunc(int *argc, char ***argv); - bool PluginPackage::fetchInfo() { if (!load()) @@ -92,6 +90,39 @@ static NPError staticPluginQuirkRequiresGtkToolKit_NPN_GetValue(NPP instance, NP return NPN_GetValue(instance, variable, value); } +static void initializeGtk(QLibrary* module = 0) +{ + // Ensures missing Gtk initialization in some versions of Adobe's flash player + // plugin do not cause crashes. See BR# 40567, 44324, and 44405 for details. + if (module) { + typedef void *(*gtk_init_ptr)(int*, char***); + gtk_init_ptr gtkInit = (gtk_init_ptr)module->resolve("gtk_init"); + if (gtkInit) { + // Prevent gtk_init() from replacing the X error handlers, since the Gtk + // handlers abort when they receive an X error, thus killing the viewer. +#ifdef Q_WS_X11 + int (*old_error_handler)(Display*, XErrorEvent*) = XSetErrorHandler(0); + int (*old_io_error_handler)(Display*) = XSetIOErrorHandler(0); +#endif + gtkInit(0, 0); +#ifdef Q_WS_X11 + XSetErrorHandler(old_error_handler); + XSetIOErrorHandler(old_io_error_handler); +#endif + return; + } + } + + QLibrary library("libgtk-x11-2.0.so.0"); + if (library.load()) { + typedef void *(*gtk_init_check_ptr)(int*, char***); + gtk_init_check_ptr gtkInitCheck = (gtk_init_check_ptr)library.resolve("gtk_init_check"); + // NOTE: We're using gtk_init_check() since gtk_init() calls exit() on failure. + if (gtkInitCheck) + (void) gtkInitCheck(0, 0); + } +} + bool PluginPackage::load() { if (m_isLoaded) { @@ -111,7 +142,6 @@ bool PluginPackage::load() NP_InitializeFuncPtr NP_Initialize; NPError npErr; - gtkInitFunc* gtkInit; NP_Initialize = (NP_InitializeFuncPtr)m_module->resolve("NP_Initialize"); m_NPP_Shutdown = (NPP_ShutdownProcPtr)m_module->resolve("NP_Shutdown"); @@ -128,26 +158,13 @@ bool PluginPackage::load() // 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; - } - - // WORKAROUND: Prevent gtk based plugin crashes such as BR# 40567 by - // explicitly forcing the initializing of Gtk, i.e. calling gtk_init, - // whenver the symbol is present in the plugin library loaded above. - // Note that this workaround is based on code from the NSPluginClass ctor - // in KDE's kdebase/apps/nsplugins/viewer/nsplugin.cpp file. - gtkInit = (gtkInitFunc*)m_module->resolve("gtk_init"); - if (gtkInit) { - // Prevent gtk_init() from replacing the X error handlers, since the Gtk - // handlers abort when they receive an X error, thus killing the viewer. -#ifdef Q_WS_X11 - int (*old_error_handler)(Display*, XErrorEvent*) = XSetErrorHandler(0); - int (*old_io_error_handler)(Display*) = XSetIOErrorHandler(0); -#endif - gtkInit(0, 0); -#ifdef Q_WS_X11 - XSetErrorHandler(old_error_handler); - XSetIOErrorHandler(old_io_error_handler); -#endif + // Workaround Adobe's failure to properly initialize Gtk in some versions + // of their flash player plugin. + initializeGtk(); + } else if (m_path.contains("flashplayer")) { + // Workaround Adobe's failure to properly initialize Gtk in some versions + // of their flash player plugin. + initializeGtk(m_module); } #if defined(XP_UNIX) diff --git a/WebCore/plugins/qt/PluginViewQt.cpp b/WebCore/plugins/qt/PluginViewQt.cpp index 3b41072..5c681b8 100644 --- a/WebCore/plugins/qt/PluginViewQt.cpp +++ b/WebCore/plugins/qt/PluginViewQt.cpp @@ -171,27 +171,49 @@ void PluginView::hide() #if defined(MOZ_PLATFORM_MAEMO) && (MOZ_PLATFORM_MAEMO == 5) void PluginView::paintUsingImageSurfaceExtension(QPainter* painter, const IntRect& exposedRect) { - if (m_isTransparent) { - // On Maemo5, Flash expects the buffer to contain the contents that are below it. - // We don't support transparency, so clean the image before giving to Flash. - QPainter imagePainter(&m_image); - imagePainter.fillRect(exposedRect, Qt::white); - } - NPImageExpose imageExpose; - imageExpose.data = reinterpret_cast<char*>(m_image.bits()); - imageExpose.stride = m_image.bytesPerLine(); - imageExpose.depth = m_image.depth(); + QPoint offset; + QWebPageClient* client = m_parentFrame->view()->hostWindow()->platformPageClient(); + const bool surfaceHasUntransformedContents = client && qobject_cast<QWidget*>(client->pluginParent()); + + QPaintDevice* surface = QPainter::redirected(painter->device(), &offset); + + // If the surface is a QImage, we can render directly into it + if (surfaceHasUntransformedContents && surface && surface->devType() == QInternal::Image) { + QImage* image = static_cast<QImage*>(surface); + offset = -offset; // negating the offset gives us the offset of the view within the surface + imageExpose.data = reinterpret_cast<char*>(image->bits()); + imageExpose.dataSize.width = image->width(); + imageExpose.dataSize.height = image->height(); + imageExpose.stride = image->bytesPerLine(); + imageExpose.depth = image->depth(); // this is guaranteed to be 16 on Maemo5 + imageExpose.translateX = offset.x() + m_windowRect.x(); + imageExpose.translateY = offset.y() + m_windowRect.y(); + imageExpose.scaleX = 1; + imageExpose.scaleY = 1; + } else { + if (m_isTransparent) { + // On Maemo5, Flash expects the buffer to contain the contents that are below it. + // We don't support transparency for non-raster graphicssystem, so clean the image + // before giving to Flash. + QPainter imagePainter(&m_image); + imagePainter.fillRect(exposedRect, Qt::white); + } + + imageExpose.data = reinterpret_cast<char*>(m_image.bits()); + imageExpose.dataSize.width = m_image.width(); + imageExpose.dataSize.height = m_image.height(); + imageExpose.stride = m_image.bytesPerLine(); + imageExpose.depth = m_image.depth(); + imageExpose.translateX = 0; + imageExpose.translateY = 0; + imageExpose.scaleX = 1; + imageExpose.scaleY = 1; + } imageExpose.x = exposedRect.x(); imageExpose.y = exposedRect.y(); imageExpose.width = exposedRect.width(); imageExpose.height = exposedRect.height(); - imageExpose.dataSize.width = m_image.width(); - imageExpose.dataSize.height = m_image.height(); - imageExpose.translateX = 0; - imageExpose.translateY = 0; - imageExpose.scaleX = 1; - imageExpose.scaleY = 1; XEvent xevent; memset(&xevent, 0, sizeof(XEvent)); @@ -206,7 +228,8 @@ void PluginView::paintUsingImageSurfaceExtension(QPainter* painter, const IntRec dispatchNPEvent(xevent); - painter->drawImage(QPoint(frameRect().x() + exposedRect.x(), frameRect().y() + exposedRect.y()), m_image, exposedRect); + if (!surfaceHasUntransformedContents || !surface || surface->devType() != QInternal::Image) + painter->drawImage(QPoint(frameRect().x() + exposedRect.x(), frameRect().y() + exposedRect.y()), m_image, exposedRect); } #endif |