[Qt] Simplify QT_VERSION_CHECKS for Qt5 by introducing HAVE(QT5)
[WebKit-https.git] / Source / WebKit / qt / WebCoreSupport / PageClientQt.cpp
1 /*
2  * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public License
15  * along with this library; see the file COPYING.LIB.  If not, write to
16  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  *
19  */
20
21 #include "config.h"
22 #include "PageClientQt.h"
23
24 #include <QGraphicsScene>
25 #include <QGraphicsView>
26 #if defined(Q_WS_X11)
27 #include <QX11Info>
28 #endif
29
30 #if ENABLE(WEBGL)
31 #include <QGLWidget>
32
33 #if HAVE(QT5)
34 #include <QWindow>
35 #endif
36
37 static void createPlatformGraphicsContext3DFromWidget(QWidget* widget, PlatformGraphicsContext3D* context,
38                                                       PlatformGraphicsSurface3D* surface)
39 {
40     *context = 0;
41     *surface = 0;
42     QAbstractScrollArea* scrollArea = qobject_cast<QAbstractScrollArea*>(widget);
43     if (!scrollArea)
44         return;
45
46     QGLWidget* glViewport = qobject_cast<QGLWidget*>(scrollArea->viewport());
47     if (!glViewport)
48         return;
49     QGLWidget* glWidget = new QGLWidget(0, glViewport);
50     if (glWidget->isValid()) {
51         // Geometry can be set to zero because m_glWidget is used only for its QGLContext.
52         glWidget->setGeometry(0, 0, 0, 0);
53 #if HAVE(QT5)
54         *surface = glWidget->windowHandle();
55         *context = glWidget->context()->contextHandle();
56 #else
57         *surface = glWidget;
58         *context = const_cast<QGLContext*>(glWidget->context());
59 #endif
60     } else {
61         delete glWidget;
62         glWidget = 0;
63     }
64 }
65 #endif
66
67 #if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER)
68 #include "TextureMapper.h"
69 #include "texmap/TextureMapperLayer.h"
70 #endif
71
72 #if HAVE(QT5)
73 QWindow* QWebPageClient::ownerWindow() const
74 {
75     QWidget* widget = ownerWidget();
76     if (!widget)
77         return 0;
78     if (QWindow *window = widget->windowHandle())
79         return window;
80     if (const QWidget *nativeParent = widget->nativeParentWidget())
81         return nativeParent->windowHandle();
82     return 0;
83 }
84 #endif
85
86 namespace WebCore {
87
88 #if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER)
89 TextureMapperLayerClientQt::TextureMapperLayerClientQt(QWebFrame* frame, GraphicsLayer* layer)
90     : m_frame(frame)
91     , m_rootGraphicsLayer(GraphicsLayer::create(0))
92 {
93     m_frame->d->rootTextureMapperLayer = rootLayer();
94     m_rootGraphicsLayer->addChild(layer);
95     m_rootGraphicsLayer->setDrawsContent(false);
96     m_rootGraphicsLayer->setMasksToBounds(false);
97     m_rootGraphicsLayer->setSize(IntSize(1, 1));
98 }
99
100 void TextureMapperLayerClientQt::setTextureMapper(const PassOwnPtr<TextureMapper>& textureMapper)
101 {
102     m_frame->d->textureMapper = textureMapper;
103     m_frame->d->rootTextureMapperLayer->setTextureMapper(m_frame->d->textureMapper.get());
104 }
105
106 TextureMapperLayerClientQt::~TextureMapperLayerClientQt()
107 {
108     m_frame->d->rootTextureMapperLayer = 0;
109 }
110
111 void TextureMapperLayerClientQt::syncRootLayer()
112 {
113     m_rootGraphicsLayer->syncCompositingStateForThisLayerOnly();
114 }
115
116 TextureMapperLayer* TextureMapperLayerClientQt::rootLayer()
117 {
118     return toTextureMapperLayer(m_rootGraphicsLayer.get());
119 }
120
121
122 void PageClientQWidget::setRootGraphicsLayer(GraphicsLayer* layer)
123 {
124     if (layer) {
125         TextureMapperLayerClient = adoptPtr(new TextureMapperLayerClientQt(page->mainFrame(), layer));
126         TextureMapperLayerClient->setTextureMapper(TextureMapper::create());
127         TextureMapperLayerClient->syncRootLayer();
128         return;
129     }
130     TextureMapperLayerClient.clear();
131 }
132
133 void PageClientQWidget::markForSync(bool scheduleSync)
134 {
135     if (syncTimer.isActive())
136         return;
137     syncTimer.startOneShot(0);
138 }
139
140 void PageClientQWidget::syncLayers(Timer<PageClientQWidget>*)
141 {
142     if (TextureMapperLayerClient)
143         TextureMapperLayerClient->syncRootLayer();
144     QWebFramePrivate::core(page->mainFrame())->view()->syncCompositingStateIncludingSubframes();
145     if (!TextureMapperLayerClient)
146         return;
147     if (TextureMapperLayerClient->rootLayer()->descendantsOrSelfHaveRunningAnimations() && !syncTimer.isActive())
148         syncTimer.startOneShot(1.0 / 60.0);
149     update(view->rect());
150 }
151 #endif
152
153 void PageClientQWidget::scroll(int dx, int dy, const QRect& rectToScroll)
154 {
155     view->scroll(qreal(dx), qreal(dy), rectToScroll);
156 }
157
158 void PageClientQWidget::update(const QRect & dirtyRect)
159 {
160     view->update(dirtyRect);
161 }
162
163 void PageClientQWidget::setInputMethodEnabled(bool enable)
164 {
165     view->setAttribute(Qt::WA_InputMethodEnabled, enable);
166 }
167
168 bool PageClientQWidget::inputMethodEnabled() const
169 {
170     return view->testAttribute(Qt::WA_InputMethodEnabled);
171 }
172
173 void PageClientQWidget::setInputMethodHints(Qt::InputMethodHints hints)
174 {
175     view->setInputMethodHints(hints);
176 }
177
178 PageClientQWidget::~PageClientQWidget()
179 {
180 }
181
182 #ifndef QT_NO_CURSOR
183 QCursor PageClientQWidget::cursor() const
184 {
185     return view->cursor();
186 }
187
188 void PageClientQWidget::updateCursor(const QCursor& cursor)
189 {
190     view->setCursor(cursor);
191 }
192 #endif
193
194 QPalette PageClientQWidget::palette() const
195 {
196     return view->palette();
197 }
198
199 int PageClientQWidget::screenNumber() const
200 {
201 #if defined(Q_WS_X11)
202     return view->x11Info().screen();
203 #endif
204     return 0;
205 }
206
207 QWidget* PageClientQWidget::ownerWidget() const
208 {
209     return view;
210 }
211
212 QRect PageClientQWidget::geometryRelativeToOwnerWidget() const
213 {
214     return view->geometry();
215 }
216
217 QObject* PageClientQWidget::pluginParent() const
218 {
219     return view;
220 }
221
222 QStyle* PageClientQWidget::style() const
223 {
224     return view->style();
225 }
226
227 QRectF PageClientQWidget::windowRect() const
228 {
229     return QRectF(view->window()->geometry());
230 }
231
232 void PageClientQWidget::setWidgetVisible(Widget* widget, bool visible)
233 {
234     QWidget* qtWidget = qobject_cast<QWidget*>(widget->platformWidget());
235     if (!qtWidget)
236         return;
237     qtWidget->setVisible(visible);
238 }
239
240 #if ENABLE(WEBGL)
241 void PageClientQWidget::createPlatformGraphicsContext3D(PlatformGraphicsContext3D* context,
242                                                         PlatformGraphicsSurface3D* surface)
243 {
244     createPlatformGraphicsContext3DFromWidget(view, context, surface);
245 }
246 #endif
247
248 #if !defined(QT_NO_GRAPHICSVIEW)
249 PageClientQGraphicsWidget::~PageClientQGraphicsWidget()
250 {
251     delete overlay;
252 #if USE(ACCELERATED_COMPOSITING) && !USE(TEXTURE_MAPPER)
253     if (!rootGraphicsLayer)
254         return;
255     // we don't need to delete the root graphics layer. The lifecycle is managed in GraphicsLayerQt.cpp.
256     rootGraphicsLayer.data()->setParentItem(0);
257     view->scene()->removeItem(rootGraphicsLayer.data());
258 #endif
259 }
260
261 void PageClientQGraphicsWidget::scroll(int dx, int dy, const QRect& rectToScroll)
262 {
263     view->scroll(qreal(dx), qreal(dy), rectToScroll);
264 }
265
266 void PageClientQGraphicsWidget::update(const QRect& dirtyRect)
267 {
268     view->update(dirtyRect);
269
270     createOrDeleteOverlay();
271     if (overlay)
272         overlay->update(QRectF(dirtyRect));
273 #if USE(ACCELERATED_COMPOSITING) && !USE(TEXTURE_MAPPER)
274     syncLayers();
275 #endif
276 }
277
278 void PageClientQGraphicsWidget::createOrDeleteOverlay()
279 {
280     // We don't use an overlay with TextureMapper. Instead, the overlay is drawn inside QWebFrame.
281 #if !USE(TEXTURE_MAPPER)
282     bool useOverlay = false;
283     if (!viewResizesToContents) {
284 #if USE(ACCELERATED_COMPOSITING)
285         useOverlay = useOverlay || rootGraphicsLayer;
286 #endif
287 #if USE(TILED_BACKING_STORE)
288         useOverlay = useOverlay || QWebFramePrivate::core(page->mainFrame())->tiledBackingStore();
289 #endif
290     }
291     if (useOverlay == !!overlay)
292         return;
293
294     if (useOverlay) {
295         overlay = new QGraphicsItemOverlay(view, page);
296         overlay->setZValue(OverlayZValue);
297     } else {
298         // Changing the overlay might be done inside paint events.
299         overlay->deleteLater();
300         overlay = 0;
301     }
302 #endif // !USE(TEXTURE_MAPPER)
303 }
304
305 #if USE(ACCELERATED_COMPOSITING)
306 void PageClientQGraphicsWidget::syncLayers()
307 {
308 #if USE(TEXTURE_MAPPER)
309     if (TextureMapperLayerClient)
310         TextureMapperLayerClient->syncRootLayer();
311 #endif
312
313     QWebFramePrivate::core(page->mainFrame())->view()->syncCompositingStateIncludingSubframes();
314
315 #if USE(TEXTURE_MAPPER)
316     if (!TextureMapperLayerClient)
317         return;
318
319     if (TextureMapperLayerClient->rootLayer()->descendantsOrSelfHaveRunningAnimations() && !syncTimer.isActive())
320         syncTimer.startOneShot(1.0 / 60.0);
321     update(view->boundingRect().toAlignedRect());
322 #endif
323 }
324
325 #if USE(TEXTURE_MAPPER)
326 void PageClientQGraphicsWidget::setRootGraphicsLayer(GraphicsLayer* layer)
327 {
328     if (layer) {
329         TextureMapperLayerClient = adoptPtr(new TextureMapperLayerClientQt(page->mainFrame(), layer));
330 #if USE(TEXTURE_MAPPER_GL)
331         QGraphicsView* graphicsView = view->scene()->views()[0];
332         if (graphicsView && graphicsView->viewport() && graphicsView->viewport()->inherits("QGLWidget")) {
333             TextureMapperLayerClient->setTextureMapper(TextureMapper::create(TextureMapper::OpenGLMode));
334             return;
335         }
336 #endif
337         TextureMapperLayerClient->setTextureMapper(TextureMapper::create());
338         return;
339     }
340     TextureMapperLayerClient.clear();
341 }
342 #else
343 void PageClientQGraphicsWidget::setRootGraphicsLayer(GraphicsLayer* layer)
344 {
345     if (rootGraphicsLayer) {
346         rootGraphicsLayer.data()->setParentItem(0);
347         view->scene()->removeItem(rootGraphicsLayer.data());
348         QWebFramePrivate::core(page->mainFrame())->view()->syncCompositingStateIncludingSubframes();
349     }
350
351     rootGraphicsLayer = layer ? layer->platformLayer() : 0;
352
353     if (rootGraphicsLayer) {
354         rootGraphicsLayer.data()->setParentItem(view);
355         rootGraphicsLayer.data()->setZValue(RootGraphicsLayerZValue);
356     }
357     createOrDeleteOverlay();
358 }
359 #endif
360
361 void PageClientQGraphicsWidget::markForSync(bool scheduleSync)
362 {
363     if (syncTimer.isActive())
364         return;
365     syncTimer.startOneShot(0);
366 }
367
368 #endif
369
370 #if USE(TILED_BACKING_STORE)
371 void PageClientQGraphicsWidget::updateTiledBackingStoreScale()
372 {
373     WebCore::TiledBackingStore* backingStore = QWebFramePrivate::core(page->mainFrame())->tiledBackingStore();
374     if (!backingStore)
375         return;
376     backingStore->setContentsScale(view->scale());
377 }
378 #endif
379
380 void PageClientQGraphicsWidget::setInputMethodEnabled(bool enable)
381 {
382     view->setFlag(QGraphicsItem::ItemAcceptsInputMethod, enable);
383 }
384
385 bool PageClientQGraphicsWidget::inputMethodEnabled() const
386 {
387     return view->flags() & QGraphicsItem::ItemAcceptsInputMethod;
388 }
389
390 void PageClientQGraphicsWidget::setInputMethodHints(Qt::InputMethodHints hints)
391 {
392     view->setInputMethodHints(hints);
393 }
394
395 #ifndef QT_NO_CURSOR
396 QCursor PageClientQGraphicsWidget::cursor() const
397 {
398     return view->cursor();
399 }
400
401 void PageClientQGraphicsWidget::updateCursor(const QCursor& cursor)
402 {
403     view->setCursor(cursor);
404 }
405 #endif
406
407 QPalette PageClientQGraphicsWidget::palette() const
408 {
409     return view->palette();
410 }
411
412 int PageClientQGraphicsWidget::screenNumber() const
413 {
414 #if defined(Q_WS_X11)
415     if (QGraphicsScene* scene = view->scene()) {
416         const QList<QGraphicsView*> views = scene->views();
417
418         if (!views.isEmpty())
419             return views.at(0)->x11Info().screen();
420     }
421 #endif
422
423     return 0;
424 }
425
426 QWidget* PageClientQGraphicsWidget::ownerWidget() const
427 {
428     if (QGraphicsScene* scene = view->scene()) {
429         const QList<QGraphicsView*> views = scene->views();
430         return views.value(0);
431     }
432     return 0;
433 }
434
435 QRect PageClientQGraphicsWidget::geometryRelativeToOwnerWidget() const
436 {
437     if (!view->scene())
438         return QRect();
439
440     QList<QGraphicsView*> views = view->scene()->views();
441     if (views.isEmpty())
442         return QRect();
443
444     QGraphicsView* graphicsView = views.at(0);
445     return graphicsView->mapFromScene(view->boundingRect()).boundingRect();
446 }
447
448 #if USE(TILED_BACKING_STORE)
449 QRectF PageClientQGraphicsWidget::graphicsItemVisibleRect() const
450 {
451     if (!view->scene())
452         return QRectF();
453
454     QList<QGraphicsView*> views = view->scene()->views();
455     if (views.isEmpty())
456         return QRectF();
457
458     QGraphicsView* graphicsView = views.at(0);
459     int xOffset = graphicsView->horizontalScrollBar()->value();
460     int yOffset = graphicsView->verticalScrollBar()->value();
461     return view->mapRectFromScene(QRectF(QPointF(xOffset, yOffset), graphicsView->viewport()->size()));
462 }
463 #endif
464
465 QObject* PageClientQGraphicsWidget::pluginParent() const
466 {
467     return view;
468 }
469
470 QStyle* PageClientQGraphicsWidget::style() const
471 {
472     return view->style();
473 }
474
475 void PageClientQGraphicsWidget::setWidgetVisible(Widget*, bool)
476 {
477     // Doesn't make sense, does it?
478 }
479
480 QRectF PageClientQGraphicsWidget::windowRect() const
481 {
482     if (!view->scene())
483         return QRectF();
484
485     // The sceneRect is a good approximation of the size of the application, independent of the view.
486     return view->scene()->sceneRect();
487 }
488 #endif // QT_NO_GRAPHICSVIEW
489
490 #if ENABLE(WEBGL)
491 void PageClientQGraphicsWidget::createPlatformGraphicsContext3D(PlatformGraphicsContext3D* context,
492                                                                 PlatformGraphicsSurface3D* surface)
493 {
494     createPlatformGraphicsContext3DFromWidget(ownerWidget(), context, surface);
495 }
496 #endif
497
498 } // namespace WebCore