2 * Copyright (C) 2011, Igalia S.L.
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.
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.
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
20 #include "WidgetBackingStore.h"
24 #include "GtkVersioning.h"
25 #include "RefPtrCairo.h"
27 #include <cairo/cairo-xlib.h>
28 #include <cairo/cairo.h>
33 class WidgetBackingStorePrivate {
34 WTF_MAKE_NONCOPYABLE(WidgetBackingStorePrivate);
35 WTF_MAKE_FAST_ALLOCATED;
41 RefPtr<cairo_surface_t> m_surface;
43 static PassOwnPtr<WidgetBackingStorePrivate> create(GtkWidget* widget, const IntSize& size)
45 return adoptPtr(new WidgetBackingStorePrivate(widget, size));
48 ~WidgetBackingStorePrivate()
50 XFreePixmap(m_display, m_pixmap);
51 XFreeGC(m_display, m_gc);
55 // We keep two copies of the surface here, which will double the memory usage, but increase
56 // scrolling performance since we do not have to keep reallocating a memory region during
57 // quick scrolling requests.
58 WidgetBackingStorePrivate(GtkWidget* widget, const IntSize& size)
60 GdkVisual* visual = gtk_widget_get_visual(widget);
61 GdkScreen* screen = gdk_visual_get_screen(visual);
62 m_display = GDK_SCREEN_XDISPLAY(screen);
63 m_pixmap = XCreatePixmap(m_display,
64 GDK_WINDOW_XID(gdk_screen_get_root_window(screen)),
65 size.width(), size.height(),
66 gdk_visual_get_depth(visual));
67 m_gc = XCreateGC(m_display, m_pixmap, 0, 0);
69 m_surface = adoptRef(cairo_xlib_surface_create(m_display, m_pixmap,
70 GDK_VISUAL_XVISUAL(visual),
71 size.width(), size.height()));
75 PassOwnPtr<WidgetBackingStore> WidgetBackingStore::create(GtkWidget* widget, const IntSize& size)
77 return adoptPtr(new WidgetBackingStore(widget, size));
80 WidgetBackingStore::WidgetBackingStore(GtkWidget* widget, const IntSize& size)
81 : m_private(WidgetBackingStorePrivate::create(widget, size))
85 WidgetBackingStore::~WidgetBackingStore()
89 cairo_surface_t* WidgetBackingStore::cairoSurface()
91 return m_private->m_surface.get();
94 void WidgetBackingStore::scroll(const IntRect& scrollRect, const IntSize& scrollOffset)
96 IntRect targetRect(scrollRect);
97 targetRect.move(scrollOffset);
98 targetRect.shiftMaxXEdgeTo(targetRect.maxX() - scrollOffset.width());
99 targetRect.shiftMaxYEdgeTo(targetRect.maxY() - scrollOffset.height());
100 if (targetRect.isEmpty())
103 XCopyArea(m_private->m_display, m_private->m_pixmap, m_private->m_pixmap, m_private->m_gc,
104 targetRect.x() - scrollOffset.width(), targetRect.y() - scrollOffset.height(),
105 targetRect.width(), targetRect.height(),
106 targetRect.x(), targetRect.y());
109 } // namespace WebCore