WebCore/plugins/qt/PluginViewQt.cpp
changeset 2 303757a437d3
parent 0 4f2f89ce4247
equal deleted inserted replaced
0:4f2f89ce4247 2:303757a437d3
   109 
   109 
   110     if (m_windowRect == oldWindowRect && m_clipRect == oldClipRect)
   110     if (m_windowRect == oldWindowRect && m_clipRect == oldClipRect)
   111         return;
   111         return;
   112 
   112 
   113     if (!m_isWindowed && m_windowRect.size() != oldWindowRect.size()) {
   113     if (!m_isWindowed && m_windowRect.size() != oldWindowRect.size()) {
   114         if (m_drawable)
   114 #if defined(MOZ_PLATFORM_MAEMO) && (MOZ_PLATFORM_MAEMO == 5)
   115             XFreePixmap(QX11Info::display(), m_drawable);
   115         // On Maemo5, Flash always renders to 16-bit buffer
   116 
   116         if (m_renderToImage)
   117         m_drawable = XCreatePixmap(QX11Info::display(), QX11Info::appRootWindow(), m_windowRect.width(), m_windowRect.height(), 
   117             m_image = QImage(m_windowRect.width(), m_windowRect.height(), QImage::Format_RGB16);
   118                                    ((NPSetWindowCallbackStruct*)m_npWindow.ws_info)->depth);
   118         else
   119         QApplication::syncX(); // make sure that the server knows about the Drawable
   119 #endif
       
   120         {
       
   121             if (m_drawable)
       
   122                 XFreePixmap(QX11Info::display(), m_drawable);
       
   123 
       
   124             m_drawable = XCreatePixmap(QX11Info::display(), QX11Info::appRootWindow(), m_windowRect.width(), m_windowRect.height(), 
       
   125                                        ((NPSetWindowCallbackStruct*)m_npWindow.ws_info)->depth);
       
   126             QApplication::syncX(); // make sure that the server knows about the Drawable
       
   127         }
   120     }
   128     }
   121 
   129 
   122     // do not call setNPWindowIfNeeded immediately, will be called on paint()
   130     // do not call setNPWindowIfNeeded immediately, will be called on paint()
   123     m_hasPendingGeometryChange = true;
   131     m_hasPendingGeometryChange = true;
   124 
   132 
   158 {
   166 {
   159     Q_ASSERT(platformPluginWidget() == platformWidget());
   167     Q_ASSERT(platformPluginWidget() == platformWidget());
   160     Widget::hide();
   168     Widget::hide();
   161 }
   169 }
   162 
   170 
       
   171 #if defined(MOZ_PLATFORM_MAEMO) && (MOZ_PLATFORM_MAEMO == 5)
       
   172 void PluginView::paintUsingImageSurfaceExtension(QPainter* painter, const IntRect& exposedRect)
       
   173 {
       
   174     NPImageExpose imageExpose;
       
   175     QPoint offset;
       
   176     QWebPageClient* client = m_parentFrame->view()->hostWindow()->platformPageClient();
       
   177     const bool surfaceHasUntransformedContents = client && qobject_cast<QWidget*>(client->pluginParent());
       
   178 
       
   179     QPaintDevice* surface =  QPainter::redirected(painter->device(), &offset);
       
   180 
       
   181     // If the surface is a QImage, we can render directly into it
       
   182     if (surfaceHasUntransformedContents && surface && surface->devType() == QInternal::Image) {
       
   183         QImage* image = static_cast<QImage*>(surface);
       
   184         offset = -offset; // negating the offset gives us the offset of the view within the surface
       
   185         imageExpose.data = reinterpret_cast<char*>(image->bits());
       
   186         imageExpose.dataSize.width = image->width();
       
   187         imageExpose.dataSize.height = image->height();
       
   188         imageExpose.stride = image->bytesPerLine();
       
   189         imageExpose.depth = image->depth(); // this is guaranteed to be 16 on Maemo5
       
   190         imageExpose.translateX = offset.x() + m_windowRect.x();
       
   191         imageExpose.translateY = offset.y() + m_windowRect.y();
       
   192         imageExpose.scaleX = 1;
       
   193         imageExpose.scaleY = 1;
       
   194     } else {
       
   195         if (m_isTransparent) {
       
   196             // On Maemo5, Flash expects the buffer to contain the contents that are below it.
       
   197             // We don't support transparency for non-raster graphicssystem, so clean the image 
       
   198             // before giving to Flash.
       
   199             QPainter imagePainter(&m_image);
       
   200             imagePainter.fillRect(exposedRect, Qt::white);
       
   201         }
       
   202 
       
   203         imageExpose.data = reinterpret_cast<char*>(m_image.bits());
       
   204         imageExpose.dataSize.width = m_image.width();
       
   205         imageExpose.dataSize.height = m_image.height();
       
   206         imageExpose.stride = m_image.bytesPerLine();
       
   207         imageExpose.depth = m_image.depth();
       
   208         imageExpose.translateX = 0;
       
   209         imageExpose.translateY = 0;
       
   210         imageExpose.scaleX = 1;
       
   211         imageExpose.scaleY = 1;
       
   212     }
       
   213     imageExpose.x = exposedRect.x();
       
   214     imageExpose.y = exposedRect.y();
       
   215     imageExpose.width = exposedRect.width();
       
   216     imageExpose.height = exposedRect.height();
       
   217 
       
   218     XEvent xevent;
       
   219     memset(&xevent, 0, sizeof(XEvent));
       
   220     XGraphicsExposeEvent& exposeEvent = xevent.xgraphicsexpose;
       
   221     exposeEvent.type = GraphicsExpose;
       
   222     exposeEvent.display = 0;
       
   223     exposeEvent.drawable = reinterpret_cast<XID>(&imageExpose);
       
   224     exposeEvent.x = exposedRect.x();
       
   225     exposeEvent.y = exposedRect.y();
       
   226     exposeEvent.width = exposedRect.width();
       
   227     exposeEvent.height = exposedRect.height();
       
   228 
       
   229     dispatchNPEvent(xevent);
       
   230 
       
   231     if (!surfaceHasUntransformedContents || !surface || surface->devType() != QInternal::Image)
       
   232         painter->drawImage(QPoint(frameRect().x() + exposedRect.x(), frameRect().y() + exposedRect.y()), m_image, exposedRect);
       
   233 }
       
   234 #endif
       
   235 
   163 void PluginView::paint(GraphicsContext* context, const IntRect& rect)
   236 void PluginView::paint(GraphicsContext* context, const IntRect& rect)
   164 {
   237 {
   165     if (!m_isStarted) {
   238     if (!m_isStarted) {
   166         paintMissingPluginIcon(context, rect);
   239         paintMissingPluginIcon(context, rect);
   167         return;
   240         return;
   170     if (context->paintingDisabled())
   243     if (context->paintingDisabled())
   171         return;
   244         return;
   172 
   245 
   173     setNPWindowIfNeeded();
   246     setNPWindowIfNeeded();
   174 
   247 
   175     if (m_isWindowed || !m_drawable)
   248     if (m_isWindowed)
   176         return;
   249         return;
   177 
   250 
   178     const bool syncX = m_pluginDisplay && m_pluginDisplay != QX11Info::display();
   251     if (!m_drawable
       
   252 #if defined(MOZ_PLATFORM_MAEMO) && (MOZ_PLATFORM_MAEMO == 5)
       
   253         && m_image.isNull()
       
   254 #endif
       
   255        )
       
   256         return;
   179 
   257 
   180     QPainter* painter = context->platformContext();
   258     QPainter* painter = context->platformContext();
   181     IntRect exposedRect(rect);
   259     IntRect exposedRect(rect);
   182     exposedRect.intersect(frameRect());
   260     exposedRect.intersect(frameRect());
   183     exposedRect.move(-frameRect().x(), -frameRect().y());
   261     exposedRect.move(-frameRect().x(), -frameRect().y());
   184 
   262 
       
   263 #if defined(MOZ_PLATFORM_MAEMO) && (MOZ_PLATFORM_MAEMO == 5)
       
   264     if (!m_image.isNull()) {
       
   265         paintUsingImageSurfaceExtension(painter, exposedRect);
       
   266         return;
       
   267     }
       
   268 #endif
       
   269 
   185     QPixmap qtDrawable = QPixmap::fromX11Pixmap(m_drawable, QPixmap::ExplicitlyShared);
   270     QPixmap qtDrawable = QPixmap::fromX11Pixmap(m_drawable, QPixmap::ExplicitlyShared);
   186     const int drawableDepth = ((NPSetWindowCallbackStruct*)m_npWindow.ws_info)->depth;
   271     const int drawableDepth = ((NPSetWindowCallbackStruct*)m_npWindow.ws_info)->depth;
   187     ASSERT(drawableDepth == qtDrawable.depth());
   272     ASSERT(drawableDepth == qtDrawable.depth());
       
   273     const bool syncX = m_pluginDisplay && m_pluginDisplay != QX11Info::display();
   188 
   274 
   189     // When printing, Qt uses a QPicture to capture the output in preview mode. The
   275     // When printing, Qt uses a QPicture to capture the output in preview mode. The
   190     // QPicture holds a reference to the X Pixmap. As a result, the print preview would
   276     // QPicture holds a reference to the X Pixmap. As a result, the print preview would
   191     // update itself when the X Pixmap changes. To prevent this, we create a copy.
   277     // update itself when the X Pixmap changes. To prevent this, we create a copy.
   192     if (m_element->document()->printing())
   278     if (m_element->document()->printing())
   490         platformPluginWidget()->setVisible(!m_clipRect.isEmpty());
   576         platformPluginWidget()->setVisible(!m_clipRect.isEmpty());
   491         platformPluginWidget()->setMask(QRegion(m_clipRect));
   577         platformPluginWidget()->setMask(QRegion(m_clipRect));
   492 
   578 
   493         m_npWindow.x = m_windowRect.x();
   579         m_npWindow.x = m_windowRect.x();
   494         m_npWindow.y = m_windowRect.y();
   580         m_npWindow.y = m_windowRect.y();
   495 
       
   496         m_npWindow.clipRect.left = max(0, m_clipRect.x());
       
   497         m_npWindow.clipRect.top = max(0, m_clipRect.y());
       
   498         m_npWindow.clipRect.right = m_clipRect.x() + m_clipRect.width();
       
   499         m_npWindow.clipRect.bottom = m_clipRect.y() + m_clipRect.height();
       
   500     } else {
   581     } else {
   501         m_npWindow.x = 0;
   582         m_npWindow.x = 0;
   502         m_npWindow.y = 0;
   583         m_npWindow.y = 0;
   503 
   584     }
       
   585 
       
   586     // If the width or height are null, set the clipRect to null, indicating that
       
   587     // the plugin is not visible/scrolled out.
       
   588     if (!m_clipRect.width() || !m_clipRect.height()) {
   504         m_npWindow.clipRect.left = 0;
   589         m_npWindow.clipRect.left = 0;
       
   590         m_npWindow.clipRect.right = 0;
   505         m_npWindow.clipRect.top = 0;
   591         m_npWindow.clipRect.top = 0;
   506         m_npWindow.clipRect.right = 0;
       
   507         m_npWindow.clipRect.bottom = 0;
   592         m_npWindow.clipRect.bottom = 0;
       
   593     } else {
       
   594         // Clipping rectangle of the plug-in; the origin is the top left corner of the drawable or window. 
       
   595         m_npWindow.clipRect.left = m_npWindow.x + m_clipRect.x();
       
   596         m_npWindow.clipRect.top = m_npWindow.y + m_clipRect.y();
       
   597         m_npWindow.clipRect.right = m_npWindow.x + m_clipRect.x() + m_clipRect.width();
       
   598         m_npWindow.clipRect.bottom = m_npWindow.y + m_clipRect.y() + m_clipRect.height();
   508     }
   599     }
   509 
   600 
   510     if (m_plugin->quirks().contains(PluginQuirkDontCallSetWindowMoreThanOnce)) {
   601     if (m_plugin->quirks().contains(PluginQuirkDontCallSetWindowMoreThanOnce)) {
   511         // FLASH WORKAROUND: Only set initially. Multiple calls to
   602         // FLASH WORKAROUND: Only set initially. Multiple calls to
   512         // setNPWindow() cause the plugin to crash in windowed mode.
   603         // setNPWindow() cause the plugin to crash in windowed mode.
   585     case NPNVSupportsWindowless:
   676     case NPNVSupportsWindowless:
   586         *static_cast<NPBool*>(value) = true;
   677         *static_cast<NPBool*>(value) = true;
   587         *result = NPERR_NO_ERROR;
   678         *result = NPERR_NO_ERROR;
   588         return true;
   679         return true;
   589 
   680 
       
   681 #if defined(MOZ_PLATFORM_MAEMO) && (MOZ_PLATFORM_MAEMO == 5)
       
   682     case NPNVSupportsWindowlessLocal:
       
   683         *static_cast<NPBool*>(value) = true;
       
   684         *result = NPERR_NO_ERROR;
       
   685         return true;
       
   686 #endif
       
   687 
   590     default:
   688     default:
   591         return false;
   689         return false;
   592     }
   690     }
   593 }
   691 }
   594 
   692 
   660 {
   758 {
   661     // The plugin toolkit might run using a different X connection. At the moment, we only
   759     // The plugin toolkit might run using a different X connection. At the moment, we only
   662     // support gdk based plugins (like flash) that use a different X connection.
   760     // support gdk based plugins (like flash) that use a different X connection.
   663     // The code below has the same effect as this one:
   761     // The code below has the same effect as this one:
   664     // Display *gdkDisplay = gdk_x11_display_get_xdisplay(gdk_display_get_default());
   762     // Display *gdkDisplay = gdk_x11_display_get_xdisplay(gdk_display_get_default());
   665     QLibrary library("libgdk-x11-2.0");
   763     QLibrary library("libgdk-x11-2.0.so.0");
   666     if (!library.load())
   764     if (!library.load())
   667         return 0;
   765         return 0;
   668 
   766 
   669     typedef void *(*gdk_display_get_default_ptr)();
   767     typedef void *(*gdk_display_get_default_ptr)();
   670     gdk_display_get_default_ptr gdk_display_get_default = (gdk_display_get_default_ptr)library.resolve("gdk_display_get_default");
   768     gdk_display_get_default_ptr gdk_display_get_default = (gdk_display_get_default_ptr)library.resolve("gdk_display_get_default");