RedirectedXCompositeWindow::~RedirectedXCompositeWindow() { ASSERT(m_display); ASSERT(m_damage); ASSERT(m_window); ASSERT(m_parentWindow); xDamageNotifier().remove(m_window); XDamageDestroy(m_display, m_damage); XDestroyWindow(m_display, m_window); XDestroyWindow(m_display, m_parentWindow); cleanupPixmapAndPixmapSurface(); }
RedirectedXCompositeWindow::~RedirectedXCompositeWindow() { ASSERT(m_display); ASSERT(m_damage); ASSERT(m_window); ASSERT(m_parentWindow); xDamageNotifier().remove(m_window.get()); // Explicitly reset these because we need to ensure it happens in this order. m_damage.reset(); m_window.reset(); m_parentWindow.reset(); }
RedirectedXCompositeWindow::RedirectedXCompositeWindow(GdkWindow* parentWindow, std::function<void()> damageNotify) : m_display(GDK_DISPLAY_XDISPLAY(gdk_window_get_display(parentWindow))) , m_window(0) , m_parentWindow(0) , m_pixmap(0) , m_damage(0) , m_needsNewPixmapAfterResize(false) { Screen* screen = DefaultScreenOfDisplay(m_display); GdkVisual* visual = gdk_window_get_visual(parentWindow); Colormap colormap = XCreateColormap(m_display, RootWindowOfScreen(screen), GDK_VISUAL_XVISUAL(visual), AllocNone); // This is based on code from Chromium: src/content/common/gpu/image_transport_surface_linux.cc XSetWindowAttributes windowAttributes; windowAttributes.override_redirect = True; windowAttributes.colormap = colormap; // 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), WidthOfScreen(screen) + 1, 0, 1, 1, 0, gdk_visual_get_depth(visual), InputOutput, GDK_VISUAL_XVISUAL(visual), CWOverrideRedirect | CWColormap | CWBorderPixel, &windowAttributes); XMapWindow(m_display, m_parentWindow); 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, 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); XFreeColormap(m_display, colormap); xDamageNotifier().add(m_window, WTF::move(damageNotify)); while (1) { XEvent event; XWindowEvent(m_display, m_window, StructureNotifyMask, &event); if (event.type == MapNotify && event.xmap.window == m_window) break; } XSelectInput(m_display, m_window, NoEventMask); XCompositeRedirectWindow(m_display, m_window, CompositeRedirectManual); m_damage = XDamageCreate(m_display, m_window, XDamageReportNonEmpty); }
RedirectedXCompositeWindow::RedirectedXCompositeWindow(WebPageProxy& webPage, const IntSize& initialSize, std::function<void()>&& damageNotify) : m_webPage(webPage) , m_display(GDK_DISPLAY_XDISPLAY(gdk_window_get_display(gtk_widget_get_parent_window(webPage.viewWidget())))) , m_size(initialSize) { m_size.scale(m_webPage.deviceScaleFactor()); ASSERT(downcast<PlatformDisplayX11>(PlatformDisplay::sharedDisplay()).native() == m_display); Screen* screen = DefaultScreenOfDisplay(m_display); GdkVisual* visual = gdk_window_get_visual(gtk_widget_get_parent_window(webPage.viewWidget())); XUniqueColormap colormap(XCreateColormap(m_display, RootWindowOfScreen(screen), GDK_VISUAL_XVISUAL(visual), AllocNone)); // This is based on code from Chromium: src/content/common/gpu/image_transport_surface_linux.cc 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), WidthOfScreen(screen) + 1, 0, 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()); xDamageNotifier().add(m_window.get(), WTFMove(damageNotify)); 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); if (!m_size.isEmpty()) createNewPixampAndPixampSurface(); m_damage = XDamageCreate(m_display, m_window.get(), XDamageReportNonEmpty); }