summaryrefslogtreecommitdiff
path: root/Source/WebKit2/WebProcess/WebPage/gtk/AcceleratedSurfaceX11.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebKit2/WebProcess/WebPage/gtk/AcceleratedSurfaceX11.cpp')
-rw-r--r--Source/WebKit2/WebProcess/WebPage/gtk/AcceleratedSurfaceX11.cpp154
1 files changed, 154 insertions, 0 deletions
diff --git a/Source/WebKit2/WebProcess/WebPage/gtk/AcceleratedSurfaceX11.cpp b/Source/WebKit2/WebProcess/WebPage/gtk/AcceleratedSurfaceX11.cpp
new file mode 100644
index 000000000..665e25789
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/gtk/AcceleratedSurfaceX11.cpp
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2012-2016 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "AcceleratedSurfaceX11.h"
+
+#if USE(REDIRECTED_XCOMPOSITE_WINDOW)
+
+#include "WebPage.h"
+#include <WebCore/PlatformDisplayX11.h>
+#include <WebCore/RefPtrCairo.h>
+#include <X11/Xlib.h>
+#include <X11/extensions/Xcomposite.h>
+#include <cairo-xlib.h>
+#include <gdk/gdkx.h>
+#include <wtf/RunLoop.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+std::unique_ptr<AcceleratedSurfaceX11> AcceleratedSurfaceX11::create(WebPage& webPage)
+{
+ if (!downcast<PlatformDisplayX11>(PlatformDisplay::sharedDisplay()).supportsXComposite())
+ return nullptr;
+ return std::unique_ptr<AcceleratedSurfaceX11>(new AcceleratedSurfaceX11(webPage));
+}
+
+static GdkVisual* defaultVisual()
+{
+ if (GdkVisual* visual = gdk_screen_get_rgba_visual(gdk_screen_get_default()))
+ return visual;
+ return gdk_screen_get_system_visual(gdk_screen_get_default());
+}
+
+AcceleratedSurfaceX11::AcceleratedSurfaceX11(WebPage& webPage)
+ : AcceleratedSurface(webPage)
+ , m_display(downcast<PlatformDisplayX11>(PlatformDisplay::sharedDisplay()).native())
+{
+ Screen* screen = DefaultScreenOfDisplay(m_display);
+
+ ASSERT(downcast<PlatformDisplayX11>(PlatformDisplay::sharedDisplay()).native() == m_display);
+
+ GdkVisual* visual = defaultVisual();
+ XUniqueColormap colormap(XCreateColormap(m_display, RootWindowOfScreen(screen), GDK_VISUAL_XVISUAL(visual), AllocNone));
+
+ XSetWindowAttributes windowAttributes;
+ windowAttributes.override_redirect = True;
+ windowAttributes.colormap = colormap.get();
+
+ // CWBorderPixel must be present when the depth doesn't match the parent's one.
+ // See http://cgit.freedesktop.org/xorg/xserver/tree/dix/window.c?id=xorg-server-1.16.0#n703.
+ windowAttributes.border_pixel = 0;
+
+ m_parentWindow = XCreateWindow(m_display,
+ RootWindowOfScreen(screen),
+ -1, -1, 1, 1,
+ 0,
+ gdk_visual_get_depth(visual),
+ InputOutput,
+ GDK_VISUAL_XVISUAL(visual),
+ CWOverrideRedirect | CWColormap | CWBorderPixel,
+ &windowAttributes);
+ XMapWindow(m_display, m_parentWindow.get());
+
+ windowAttributes.event_mask = StructureNotifyMask;
+ windowAttributes.override_redirect = False;
+
+ // Create the window of at last 1x1 since X doesn't allow to create empty windows.
+ m_window = XCreateWindow(m_display,
+ m_parentWindow.get(),
+ 0, 0,
+ std::max(1, m_size.width()),
+ std::max(1, m_size.height()),
+ 0,
+ CopyFromParent,
+ InputOutput,
+ CopyFromParent,
+ CWEventMask,
+ &windowAttributes);
+ XMapWindow(m_display, m_window.get());
+
+ while (1) {
+ XEvent event;
+ XWindowEvent(m_display, m_window.get(), StructureNotifyMask, &event);
+ if (event.type == MapNotify && event.xmap.window == m_window.get())
+ break;
+ }
+ XSelectInput(m_display, m_window.get(), NoEventMask);
+ XCompositeRedirectWindow(m_display, m_window.get(), CompositeRedirectManual);
+ createPixmap();
+}
+
+AcceleratedSurfaceX11::~AcceleratedSurfaceX11()
+{
+ ASSERT(m_display);
+ ASSERT(m_window);
+ ASSERT(m_parentWindow);
+
+ // Explicitly reset these because we need to ensure it happens in this order.
+ m_window.reset();
+ m_parentWindow.reset();
+}
+
+void AcceleratedSurfaceX11::createPixmap()
+{
+ m_pixmap = XCompositeNameWindowPixmap(m_display, m_window.get());
+ RefPtr<cairo_surface_t> surface = adoptRef(cairo_xlib_surface_create(m_display, m_pixmap.get(), GDK_VISUAL_XVISUAL(defaultVisual()), m_size.width(), m_size.height()));
+ RefPtr<cairo_t> cr = adoptRef(cairo_create(surface.get()));
+ cairo_set_operator(cr.get(), CAIRO_OPERATOR_CLEAR);
+ cairo_paint(cr.get());
+ XSync(m_display, False);
+}
+
+bool AcceleratedSurfaceX11::resize(const IntSize& size)
+{
+ if (!AcceleratedSurface::resize(size))
+ return false;
+
+ // Resize the window to at last 1x1 since X doesn't allow to create empty windows.
+ XResizeWindow(m_display, m_window.get(), std::max(1, m_size.width()), std::max(1, m_size.height()));
+ XFlush(m_display);
+
+ // Release the previous pixmap later to give some time to the UI process to update.
+ RunLoop::main().dispatchAfter(std::chrono::seconds(5), [pixmap = WTFMove(m_pixmap)] { });
+ createPixmap();
+ return true;
+}
+
+} // namespace WebCore
+
+#endif // USE(REDIRECTED_XCOMPOSITE_WINDOW)