1/*
2 * Copyright (C) 2011,2014 Igalia S.L.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser 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 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19#include "config.h"
20#include "BackingStoreBackendCairoX11.h"
21
22#if USE(CAIRO) && PLATFORM(X11)
23
24#include "CairoUtilities.h"
25#include <cairo-xlib.h>
26
27namespace WebCore {
28
29BackingStoreBackendCairoX11::BackingStoreBackendCairoX11(unsigned long rootWindowID, Visual* visual, int depth, const IntSize& size, float deviceScaleFactor)
30 : BackingStoreBackendCairo(size)
31{
32 IntSize scaledSize = size;
33 scaledSize.scale(deviceScaleFactor);
34
35 auto* display = downcast<PlatformDisplayX11>(PlatformDisplay::sharedDisplay()).native();
36 m_pixmap = XCreatePixmap(display, rootWindowID, scaledSize.width(), scaledSize.height(), depth);
37 m_gc.reset(XCreateGC(display, m_pixmap.get(), 0, nullptr));
38
39 m_surface = adoptRef(cairo_xlib_surface_create(display, m_pixmap.get(), visual, scaledSize.width(), scaledSize.height()));
40 cairoSurfaceSetDeviceScale(m_surface.get(), deviceScaleFactor, deviceScaleFactor);
41}
42
43BackingStoreBackendCairoX11::~BackingStoreBackendCairoX11()
44{
45 // The pixmap needs to exist when the surface is destroyed, so begin by clearing it.
46 m_surface = nullptr;
47}
48
49void BackingStoreBackendCairoX11::scroll(const IntRect& scrollRect, const IntSize& scrollOffset)
50{
51 IntRect targetRect = scrollRect;
52 targetRect.move(scrollOffset);
53 targetRect.intersect(scrollRect);
54 if (targetRect.isEmpty())
55 return;
56
57 double xScale, yScale;
58 cairoSurfaceGetDeviceScale(m_surface.get(), xScale, yScale);
59 ASSERT(xScale == yScale);
60
61 IntSize scaledScrollOffset = scrollOffset;
62 targetRect.scale(xScale);
63 scaledScrollOffset.scale(xScale, yScale);
64
65 cairo_surface_flush(m_surface.get());
66 XCopyArea(downcast<PlatformDisplayX11>(PlatformDisplay::sharedDisplay()).native(), m_pixmap.get(), m_pixmap.get(), m_gc.get(),
67 targetRect.x() - scaledScrollOffset.width(), targetRect.y() - scaledScrollOffset.height(),
68 targetRect.width(), targetRect.height(), targetRect.x(), targetRect.y());
69 cairo_surface_mark_dirty_rectangle(m_surface.get(), targetRect.x(), targetRect.y(), targetRect.width(), targetRect.height());
70}
71
72} // namespace WebCore
73
74#endif // USE(CAIRO) && PLATFORM(X11)
75