1/* 2 * Copyright (C) 2011, 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 "WidgetBackingStoreGtkX11.h" 21 22#include "CairoUtilities.h" 23#include "GtkVersioning.h" 24#include "RefPtrCairo.h" 25#include <cairo-xlib.h> 26#include <cairo.h> 27#include <gdk/gdkx.h> 28 29namespace WebCore { 30 31PassOwnPtr<WidgetBackingStore> WidgetBackingStoreGtkX11::create(GtkWidget* widget, const IntSize& size, float deviceScaleFactor) 32{ 33 return adoptPtr(new WidgetBackingStoreGtkX11(widget, size, deviceScaleFactor)); 34} 35 36WidgetBackingStoreGtkX11::WidgetBackingStoreGtkX11(GtkWidget* widget, const IntSize& size, float deviceScaleFactor) 37 : WidgetBackingStore(size, deviceScaleFactor) 38{ 39 IntSize scaledSize = size; 40 scaledSize.scale(deviceScaleFactor); 41 42 GdkVisual* visual = gtk_widget_get_visual(widget); 43 GdkScreen* screen = gdk_visual_get_screen(visual); 44 m_display = GDK_SCREEN_XDISPLAY(screen); 45 m_pixmap = XCreatePixmap(m_display, GDK_WINDOW_XID(gdk_screen_get_root_window(screen)), 46 scaledSize.width(), scaledSize.height(), gdk_visual_get_depth(visual)); 47 m_gc = XCreateGC(m_display, m_pixmap, 0, 0); 48 49 m_surface = adoptRef(cairo_xlib_surface_create(m_display, m_pixmap, 50 GDK_VISUAL_XVISUAL(visual), scaledSize.width(), scaledSize.height())); 51 52 cairoSurfaceSetDeviceScale(m_surface.get(), deviceScaleFactor, deviceScaleFactor); 53} 54 55WidgetBackingStoreGtkX11::~WidgetBackingStoreGtkX11() 56{ 57 // The pixmap needs to exist when the surface is destroyed, so begin by clearing it. 58 m_surface.clear(); 59 XFreePixmap(m_display, m_pixmap); 60 XFreeGC(m_display, m_gc); 61} 62 63cairo_surface_t* WidgetBackingStoreGtkX11::cairoSurface() 64{ 65 return m_surface.get(); 66} 67 68void WidgetBackingStoreGtkX11::scroll(const IntRect& scrollRect, const IntSize& scrollOffset) 69{ 70 IntRect targetRect(scrollRect); 71 targetRect.move(scrollOffset); 72 targetRect.intersect(scrollRect); 73 if (targetRect.isEmpty()) 74 return; 75 76 targetRect.scale(m_deviceScaleFactor); 77 78 IntSize scaledScrollOffset = scrollOffset; 79 scaledScrollOffset.scale(m_deviceScaleFactor); 80 81 cairo_surface_flush(m_surface.get()); 82 XCopyArea(m_display, m_pixmap, m_pixmap, m_gc, 83 targetRect.x() - scaledScrollOffset.width(), targetRect.y() - scaledScrollOffset.height(), 84 targetRect.width(), targetRect.height(), 85 targetRect.x(), targetRect.y()); 86 cairo_surface_mark_dirty_rectangle(m_surface.get(), 87 targetRect.x(), targetRect.y(), 88 targetRect.width(), targetRect.height()); 89} 90 91} // namespace WebCore 92