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. |
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"); |