initial import
[vuplus_webkit] / 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 USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER)
31 #include "TextureMapperQt.h"
32 #include "texmap/TextureMapperNode.h"
33
34 #if USE(TEXTURE_MAPPER_GL)
35 #include "opengl/TextureMapperGL.h"
36 #endif
37 #endif
38
39 namespace WebCore {
40
41 #if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER)
42 TextureMapperNodeClientQt::TextureMapperNodeClientQt(QWebFrame* frame, GraphicsLayer* layer)
43     : m_frame(frame)
44     , m_rootGraphicsLayer(GraphicsLayer::create(0))
45 {
46     m_frame->d->rootTextureMapperNode = rootNode();
47     m_rootGraphicsLayer->addChild(layer);
48     m_rootGraphicsLayer->setDrawsContent(false);
49     m_rootGraphicsLayer->setMasksToBounds(false);
50     m_rootGraphicsLayer->setSize(IntSize(1, 1));
51 }
52
53 void TextureMapperNodeClientQt::setTextureMapper(const PassOwnPtr<TextureMapper>& textureMapper)
54 {
55     m_frame->d->textureMapper = textureMapper;
56     m_frame->d->rootTextureMapperNode->setTextureMapper(m_frame->d->textureMapper.get());
57 }
58
59 TextureMapperNodeClientQt::~TextureMapperNodeClientQt()
60 {
61     m_frame->d->rootTextureMapperNode = 0;
62 }
63
64 void TextureMapperNodeClientQt::syncRootLayer()
65 {
66     m_rootGraphicsLayer->syncCompositingStateForThisLayerOnly();
67 }
68
69 TextureMapperNode* TextureMapperNodeClientQt::rootNode()
70 {
71     return toTextureMapperNode(m_rootGraphicsLayer.get());
72 }
73
74
75 void PageClientQWidget::setRootGraphicsLayer(GraphicsLayer* layer)
76 {
77     if (layer) {
78         textureMapperNodeClient = adoptPtr(new TextureMapperNodeClientQt(page->mainFrame(), layer));
79         textureMapperNodeClient->setTextureMapper(adoptPtr(new TextureMapperQt));
80         textureMapperNodeClient->syncRootLayer();
81         return;
82     }
83     textureMapperNodeClient.clear();
84 }
85
86 void PageClientQWidget::markForSync(bool scheduleSync)
87 {
88     syncTimer.startOneShot(0);
89 }
90
91 void PageClientQWidget::syncLayers(Timer<PageClientQWidget>*)
92 {
93     if (textureMapperNodeClient)
94         textureMapperNodeClient->syncRootLayer();
95     QWebFramePrivate::core(page->mainFrame())->view()->syncCompositingStateIncludingSubframes();
96     if (!textureMapperNodeClient)
97         return;
98     if (textureMapperNodeClient->rootNode()->descendantsOrSelfHaveRunningAnimations())
99         syncTimer.startOneShot(1.0 / 60.0);
100     update(view->rect());
101 }
102 #endif
103
104 void PageClientQWidget::scroll(int dx, int dy, const QRect& rectToScroll)
105 {
106     view->scroll(qreal(dx), qreal(dy), rectToScroll);
107 }
108
109 void PageClientQWidget::update(const QRect & dirtyRect)
110 {
111     view->update(dirtyRect);
112 }
113
114 void PageClientQWidget::setInputMethodEnabled(bool enable)
115 {
116     view->setAttribute(Qt::WA_InputMethodEnabled, enable);
117 }
118
119 bool PageClientQWidget::inputMethodEnabled() const
120 {
121     return view->testAttribute(Qt::WA_InputMethodEnabled);
122 }
123
124 void PageClientQWidget::setInputMethodHints(Qt::InputMethodHints hints)
125 {
126     view->setInputMethodHints(hints);
127 }
128
129 PageClientQWidget::~PageClientQWidget()
130 {
131 }
132
133 #ifndef QT_NO_CURSOR
134 QCursor PageClientQWidget::cursor() const
135 {
136     return view->cursor();
137 }
138
139 void PageClientQWidget::updateCursor(const QCursor& cursor)
140 {
141     view->setCursor(cursor);
142 }
143 #endif
144
145 QPalette PageClientQWidget::palette() const
146 {
147     return view->palette();
148 }
149
150 int PageClientQWidget::screenNumber() const
151 {
152 #if defined(Q_WS_X11)
153     return view->x11Info().screen();
154 #endif
155     return 0;
156 }
157
158 QWidget* PageClientQWidget::ownerWidget() const
159 {
160     return view;
161 }
162
163 QRect PageClientQWidget::geometryRelativeToOwnerWidget() const
164 {
165     return view->geometry();
166 }
167
168 QObject* PageClientQWidget::pluginParent() const
169 {
170     return view;
171 }
172
173 QStyle* PageClientQWidget::style() const
174 {
175     return view->style();
176 }
177
178 QRectF PageClientQWidget::windowRect() const
179 {
180     return QRectF(view->window()->geometry());
181 }
182
183 #if !defined(QT_NO_GRAPHICSVIEW)
184 PageClientQGraphicsWidget::~PageClientQGraphicsWidget()
185 {
186     delete overlay;
187 #if USE(ACCELERATED_COMPOSITING) && !USE(TEXTURE_MAPPER)
188     if (!rootGraphicsLayer)
189         return;
190     // we don't need to delete the root graphics layer. The lifecycle is managed in GraphicsLayerQt.cpp.
191     rootGraphicsLayer.data()->setParentItem(0);
192     view->scene()->removeItem(rootGraphicsLayer.data());
193 #endif
194 }
195
196 void PageClientQGraphicsWidget::scroll(int dx, int dy, const QRect& rectToScroll)
197 {
198     view->scroll(qreal(dx), qreal(dy), rectToScroll);
199 }
200
201 void PageClientQGraphicsWidget::update(const QRect& dirtyRect)
202 {
203     view->update(dirtyRect);
204
205     createOrDeleteOverlay();
206     if (overlay)
207         overlay->update(QRectF(dirtyRect));
208 #if USE(ACCELERATED_COMPOSITING) && !USE(TEXTURE_MAPPER)
209     syncLayers();
210 #endif
211 }
212
213 void PageClientQGraphicsWidget::createOrDeleteOverlay()
214 {
215     // We don't use an overlay with TextureMapper. Instead, the overlay is drawn inside QWebFrame.
216 #if !USE(TEXTURE_MAPPER)
217     bool useOverlay = false;
218     if (!viewResizesToContents) {
219 #if USE(ACCELERATED_COMPOSITING)
220         useOverlay = useOverlay || rootGraphicsLayer;
221 #endif
222 #if ENABLE(TILED_BACKING_STORE)
223         useOverlay = useOverlay || QWebFramePrivate::core(page->mainFrame())->tiledBackingStore();
224 #endif
225     }
226     if (useOverlay == !!overlay)
227         return;
228
229     if (useOverlay) {
230         overlay = new QGraphicsItemOverlay(view, page);
231         overlay->setZValue(OverlayZValue);
232     } else {
233         // Changing the overlay might be done inside paint events.
234         overlay->deleteLater();
235         overlay = 0;
236     }
237 #endif // !USE(TEXTURE_MAPPER)
238 }
239
240 #if USE(ACCELERATED_COMPOSITING)
241 void PageClientQGraphicsWidget::syncLayers()
242 {
243 #if USE(TEXTURE_MAPPER)
244     if (textureMapperNodeClient)
245         textureMapperNodeClient->syncRootLayer();
246 #endif
247
248     QWebFramePrivate::core(page->mainFrame())->view()->syncCompositingStateIncludingSubframes();
249
250 #if USE(TEXTURE_MAPPER)
251     if (!textureMapperNodeClient)
252         return;
253
254     if (textureMapperNodeClient->rootNode()->descendantsOrSelfHaveRunningAnimations())
255         syncTimer.startOneShot(1.0 / 60.0);
256     update(view->boundingRect().toAlignedRect());
257     if (!shouldSync)
258         return;
259     shouldSync = false;
260 #endif
261 }
262
263 #if USE(TEXTURE_MAPPER)
264 void PageClientQGraphicsWidget::setRootGraphicsLayer(GraphicsLayer* layer)
265 {
266     if (layer) {
267         textureMapperNodeClient = adoptPtr(new TextureMapperNodeClientQt(page->mainFrame(), layer));
268 #if USE(TEXTURE_MAPPER_GL)
269         QGraphicsView* graphicsView = view->scene()->views()[0];
270         if (graphicsView && graphicsView->viewport() && graphicsView->viewport()->inherits("QGLWidget")) {
271             textureMapperNodeClient->setTextureMapper(TextureMapperGL::create());
272             return;
273         }
274 #endif
275         textureMapperNodeClient->setTextureMapper(TextureMapperQt::create());
276         return;
277     }
278     textureMapperNodeClient.clear();
279 }
280 #else
281 void PageClientQGraphicsWidget::setRootGraphicsLayer(GraphicsLayer* layer)
282 {
283     if (rootGraphicsLayer) {
284         rootGraphicsLayer.data()->setParentItem(0);
285         view->scene()->removeItem(rootGraphicsLayer.data());
286         QWebFramePrivate::core(page->mainFrame())->view()->syncCompositingStateIncludingSubframes();
287     }
288
289     rootGraphicsLayer = layer ? layer->platformLayer() : 0;
290
291     if (rootGraphicsLayer) {
292         rootGraphicsLayer.data()->setParentItem(view);
293         rootGraphicsLayer.data()->setZValue(RootGraphicsLayerZValue);
294     }
295     createOrDeleteOverlay();
296 }
297 #endif
298
299 void PageClientQGraphicsWidget::markForSync(bool scheduleSync)
300 {
301     shouldSync = true;
302     syncTimer.startOneShot(0);
303 }
304
305 #endif
306
307 #if ENABLE(TILED_BACKING_STORE)
308 void PageClientQGraphicsWidget::updateTiledBackingStoreScale()
309 {
310     WebCore::TiledBackingStore* backingStore = QWebFramePrivate::core(page->mainFrame())->tiledBackingStore();
311     if (!backingStore)
312         return;
313     backingStore->setContentsScale(view->scale());
314 }
315 #endif
316
317 void PageClientQGraphicsWidget::setInputMethodEnabled(bool enable)
318 {
319     view->setFlag(QGraphicsItem::ItemAcceptsInputMethod, enable);
320 }
321
322 bool PageClientQGraphicsWidget::inputMethodEnabled() const
323 {
324     return view->flags() & QGraphicsItem::ItemAcceptsInputMethod;
325 }
326
327 void PageClientQGraphicsWidget::setInputMethodHints(Qt::InputMethodHints hints)
328 {
329     view->setInputMethodHints(hints);
330 }
331
332 #ifndef QT_NO_CURSOR
333 QCursor PageClientQGraphicsWidget::cursor() const
334 {
335     return view->cursor();
336 }
337
338 void PageClientQGraphicsWidget::updateCursor(const QCursor& cursor)
339 {
340     view->setCursor(cursor);
341 }
342 #endif
343
344 QPalette PageClientQGraphicsWidget::palette() const
345 {
346     return view->palette();
347 }
348
349 int PageClientQGraphicsWidget::screenNumber() const
350 {
351 #if defined(Q_WS_X11)
352     if (QGraphicsScene* scene = view->scene()) {
353         const QList<QGraphicsView*> views = scene->views();
354
355         if (!views.isEmpty())
356             return views.at(0)->x11Info().screen();
357     }
358 #endif
359
360     return 0;
361 }
362
363 QWidget* PageClientQGraphicsWidget::ownerWidget() const
364 {
365     if (QGraphicsScene* scene = view->scene()) {
366         const QList<QGraphicsView*> views = scene->views();
367         return views.value(0);
368     }
369     return 0;
370 }
371
372 QRect PageClientQGraphicsWidget::geometryRelativeToOwnerWidget() const
373 {
374     if (!view->scene())
375         return QRect();
376
377     QList<QGraphicsView*> views = view->scene()->views();
378     if (views.isEmpty())
379         return QRect();
380
381     QGraphicsView* graphicsView = views.at(0);
382     return graphicsView->mapFromScene(view->boundingRect()).boundingRect();
383 }
384
385 #if ENABLE(TILED_BACKING_STORE)
386 QRectF PageClientQGraphicsWidget::graphicsItemVisibleRect() const
387 {
388     if (!view->scene())
389         return QRectF();
390
391     QList<QGraphicsView*> views = view->scene()->views();
392     if (views.isEmpty())
393         return QRectF();
394
395     QGraphicsView* graphicsView = views.at(0);
396     int xOffset = graphicsView->horizontalScrollBar()->value();
397     int yOffset = graphicsView->verticalScrollBar()->value();
398     return view->mapRectFromScene(QRectF(QPointF(xOffset, yOffset), graphicsView->viewport()->size()));
399 }
400 #endif
401
402 QObject* PageClientQGraphicsWidget::pluginParent() const
403 {
404     return view;
405 }
406
407 QStyle* PageClientQGraphicsWidget::style() const
408 {
409     return view->style();
410 }
411
412 QRectF PageClientQGraphicsWidget::windowRect() const
413 {
414     if (!view->scene())
415         return QRectF();
416
417     // The sceneRect is a good approximation of the size of the application, independent of the view.
418     return view->scene()->sceneRect();
419 }
420 #endif // QT_NO_GRAPHICSVIEW
421
422 } // namespace WebCore