1/*
2 * Copyright (C) 2015 Igalia S.L
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27#include "PlatformDisplayX11.h"
28
29#include "GLContext.h"
30
31#if PLATFORM(X11)
32#include <X11/Xlib.h>
33#include <X11/extensions/Xcomposite.h>
34#if PLATFORM(GTK)
35#include <X11/extensions/Xdamage.h>
36#endif
37
38#if USE(EGL)
39#include <EGL/egl.h>
40#include <EGL/eglext.h>
41#endif
42
43namespace WebCore {
44
45std::unique_ptr<PlatformDisplay> PlatformDisplayX11::create()
46{
47 Display* display = XOpenDisplay(getenv("DISPLAY"));
48 if (!display)
49 return nullptr;
50
51 return std::unique_ptr<PlatformDisplayX11>(new PlatformDisplayX11(display, NativeDisplayOwned::Yes));
52}
53
54std::unique_ptr<PlatformDisplay> PlatformDisplayX11::create(Display* display)
55{
56 return std::unique_ptr<PlatformDisplayX11>(new PlatformDisplayX11(display, NativeDisplayOwned::No));
57}
58
59PlatformDisplayX11::PlatformDisplayX11(Display* display, NativeDisplayOwned displayOwned)
60 : PlatformDisplay(displayOwned)
61 , m_display(display)
62{
63}
64
65PlatformDisplayX11::~PlatformDisplayX11()
66{
67#if USE(EGL) || USE(GLX)
68 // Clear the sharing context before releasing the display.
69 m_sharingGLContext = nullptr;
70#endif
71 if (m_nativeDisplayOwned == NativeDisplayOwned::Yes)
72 XCloseDisplay(m_display);
73}
74
75#if USE(EGL)
76void PlatformDisplayX11::initializeEGLDisplay()
77{
78#if defined(EGL_KHR_platform_x11)
79 const char* extensions = eglQueryString(nullptr, EGL_EXTENSIONS);
80 if (GLContext::isExtensionSupported(extensions, "EGL_KHR_platform_base")) {
81 if (auto* getPlatformDisplay = reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC>(eglGetProcAddress("eglGetPlatformDisplay")))
82 m_eglDisplay = getPlatformDisplay(EGL_PLATFORM_X11_KHR, m_display, nullptr);
83 } else if (GLContext::isExtensionSupported(extensions, "EGL_EXT_platform_base")) {
84 if (auto* getPlatformDisplay = reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC>(eglGetProcAddress("eglGetPlatformDisplayEXT")))
85 m_eglDisplay = getPlatformDisplay(EGL_PLATFORM_X11_KHR, m_display, nullptr);
86 } else
87#endif
88 m_eglDisplay = eglGetDisplay(m_display);
89
90 PlatformDisplay::initializeEGLDisplay();
91}
92#endif // USE(EGL)
93
94bool PlatformDisplayX11::supportsXComposite() const
95{
96 if (!m_supportsXComposite) {
97 if (m_display) {
98 int eventBase, errorBase;
99 m_supportsXComposite = XCompositeQueryExtension(m_display, &eventBase, &errorBase);
100 } else
101 m_supportsXComposite = false;
102 }
103 return m_supportsXComposite.value();
104}
105
106bool PlatformDisplayX11::supportsXDamage(Optional<int>& damageEventBase, Optional<int>& damageErrorBase) const
107{
108 if (!m_supportsXDamage) {
109 m_supportsXDamage = false;
110#if PLATFORM(GTK)
111 if (m_display) {
112 int eventBase, errorBase;
113 m_supportsXDamage = XDamageQueryExtension(m_display, &eventBase, &errorBase);
114 if (m_supportsXDamage.value()) {
115 m_damageEventBase = eventBase;
116 m_damageErrorBase = errorBase;
117 }
118 }
119#endif
120 }
121
122 damageEventBase = m_damageEventBase;
123 damageErrorBase = m_damageErrorBase;
124 return m_supportsXDamage.value();
125}
126
127} // namespace WebCore
128
129#endif // PLATFORM(X11)
130
131