blob: 437dafc82fd22ecbf06047a3c28689ebe02236d2 [file] [log] [blame]
/*
* Copyright (C) 2011,2014 Igalia S.L.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "config.h"
#include "BackingStoreBackendCairoX11.h"
#if USE(CAIRO) && PLATFORM(X11)
#include "CairoUtilities.h"
#include <cairo-xlib.h>
namespace WebCore {
BackingStoreBackendCairoX11::BackingStoreBackendCairoX11(unsigned long rootWindowID, Visual* visual, int depth, const IntSize& size, float deviceScaleFactor)
: BackingStoreBackendCairo(size)
{
IntSize scaledSize = size;
scaledSize.scale(deviceScaleFactor);
auto* display = downcast<PlatformDisplayX11>(PlatformDisplay::sharedDisplay()).native();
m_pixmap = XCreatePixmap(display, rootWindowID, scaledSize.width(), scaledSize.height(), depth);
m_gc.reset(XCreateGC(display, m_pixmap.get(), 0, nullptr));
m_surface = adoptRef(cairo_xlib_surface_create(display, m_pixmap.get(), visual, scaledSize.width(), scaledSize.height()));
cairoSurfaceSetDeviceScale(m_surface.get(), deviceScaleFactor, deviceScaleFactor);
}
BackingStoreBackendCairoX11::~BackingStoreBackendCairoX11()
{
// The pixmap needs to exist when the surface is destroyed, so begin by clearing it.
m_surface = nullptr;
}
void BackingStoreBackendCairoX11::scroll(const IntRect& scrollRect, const IntSize& scrollOffset)
{
IntRect targetRect = scrollRect;
targetRect.move(scrollOffset);
targetRect.intersect(scrollRect);
if (targetRect.isEmpty())
return;
double xScale, yScale;
cairoSurfaceGetDeviceScale(m_surface.get(), xScale, yScale);
ASSERT(xScale == yScale);
IntSize scaledScrollOffset = scrollOffset;
targetRect.scale(xScale);
scaledScrollOffset.scale(xScale, yScale);
cairo_surface_flush(m_surface.get());
XCopyArea(downcast<PlatformDisplayX11>(PlatformDisplay::sharedDisplay()).native(), m_pixmap.get(), m_pixmap.get(), m_gc.get(),
targetRect.x() - scaledScrollOffset.width(), targetRect.y() - scaledScrollOffset.height(),
targetRect.width(), targetRect.height(), targetRect.x(), targetRect.y());
cairo_surface_mark_dirty_rectangle(m_surface.get(), targetRect.x(), targetRect.y(), targetRect.width(), targetRect.height());
}
} // namespace WebCore
#endif // USE(CAIRO) && PLATFORM(X11)