2 * Copyright (C) 2011-2013 Team XBMC
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with XBMC; see the file COPYING. If not, see
17 * <http://www.gnu.org/licenses/>.
23 #include <boost/bind.hpp>
24 #include <boost/function.hpp>
25 #include <boost/scoped_ptr.hpp>
27 #include <wayland-client.h>
29 #include "guilib/Resolution.h"
30 #include "guilib/gui3d.h"
32 #include "windowing/DllWaylandClient.h"
33 #include "windowing/DllXKBCommon.h"
36 #include "Compositor.h"
42 #include "windowing/WaylandProtocol.h"
43 #include "XBMCConnection.h"
49 class XBMCConnection::Private :
50 public IWaylandRegistration
54 Private(IDllWaylandClient &clientLibrary,
55 IDllXKBCommon &xkbCommonLibrary,
56 EventInjector &eventInjector);
59 IDllWaylandClient &m_clientLibrary;
60 IDllXKBCommon &m_xkbCommonLibrary;
62 EventInjector &m_eventInjector;
64 boost::scoped_ptr<Display> m_display;
65 boost::scoped_ptr<Registry> m_registry;
66 boost::scoped_ptr<Compositor> m_compositor;
67 boost::scoped_ptr<Shell> m_shell;
69 /* Synchronization logic - these variables should not be touched
70 * outside the scope of WaitForSynchronize() */
72 boost::scoped_ptr<Callback> synchronizeCallback;
74 /* Synchronization entry point - call this function to issue a
75 * wl_display.sync request to the server. All this does is cause
76 * the server to send back an event that acknowledges the receipt
77 * of the request. However, it is useful in a number of circumstances
78 * - all request processing in wayland is sequential and guarunteed
79 * to be in the same order as requests were made. That means that
80 * once the event is received from the server, it is guarunteed
81 * that all requests made prior to the sync request have finished
82 * processing on the server and events have been issued to us. */
83 void WaitForSynchronize();
85 /* Callback function for synchronize event, do not call directly */
88 bool OnCompositorAvailable(struct wl_compositor *);
89 bool OnShellAvailable(struct wl_shell *);
90 bool OnSeatAvailable(struct wl_seat *);
91 bool OnOutputAvailable(struct wl_output *);
96 namespace xw = xbmc::wayland;
98 /* Creating a new xbmc::wayland::XBMCConnection effectively creates
99 * a new xbmc::wayland::Display object, which in turn will connect
100 * to the running wayland compositor and encapsulate the return value
101 * from the client library. Then it creates a new
102 * xbmc::wayland::Registry object which is responsible for managing
103 * all of the global objects on the wayland connection that we might
104 * want to use. On creation of this object, a request is sent to
105 * the compositor to send back an event for every available global
106 * object. Once we know which objects exist, we can easily
109 * The WaitForSynchronize call at the end of the constructor is
110 * important. Once we make a request to the server for all of the
111 * available global objects, we need to know what they all are
112 * by the time this constructor finishes running so that the
113 * object will be complete. The only way to do that is to know
114 * when our wl_registry.add_listener request has finished processing
115 * on both the server and client side
117 xw::XBMCConnection::Private::Private(IDllWaylandClient &clientLibrary,
118 IDllXKBCommon &xkbCommonLibrary,
119 EventInjector &eventInjector) :
120 m_clientLibrary(clientLibrary),
121 m_xkbCommonLibrary(xkbCommonLibrary),
122 m_eventInjector(eventInjector),
123 m_display(new xw::Display(clientLibrary)),
124 m_registry(new xw::Registry(clientLibrary,
125 m_display->GetWlDisplay(),
128 /* Tell CWinEvents what our display is. That way
129 * CWinEvents::MessagePump is now able to dispatch events from
130 * the display whenever it is called */
131 (*m_eventInjector.setDisplay)(&clientLibrary,
132 m_display->GetWlDisplay());
134 WaitForSynchronize();
137 xw::XBMCConnection::Private::~Private()
139 (*m_eventInjector.destroyDisplay)();
142 xw::XBMCConnection::XBMCConnection(IDllWaylandClient &clientLibrary,
143 IDllXKBCommon &xkbCommonLibrary,
144 EventInjector &eventInjector) :
145 priv(new Private (clientLibrary, xkbCommonLibrary, eventInjector))
149 /* A defined destructor is required such that
150 * boost::scoped_ptr<Private>::~scoped_ptr is generated here */
151 xw::XBMCConnection::~XBMCConnection()
155 /* These are all registry callbacks. Once an object becomes available
156 * (generally speaking at construction time) then we need to
157 * create an internal representation for it so that we can use it
159 bool xw::XBMCConnection::Private::OnCompositorAvailable(struct wl_compositor *c)
161 m_compositor.reset(new xw::Compositor(m_clientLibrary, c));
165 bool xw::XBMCConnection::Private::OnShellAvailable(struct wl_shell *s)
167 m_shell.reset(new xw::Shell(m_clientLibrary, s));
171 bool xw::XBMCConnection::Private::OnSeatAvailable(struct wl_seat *s)
176 void xw::XBMCConnection::Private::WaitForSynchronize()
178 boost::function<void(uint32_t)> func(boost::bind(&Private::Synchronize,
181 synchronized = false;
182 synchronizeCallback.reset(new xw::Callback(m_clientLibrary,
185 while (!synchronized)
186 (*m_eventInjector.messagePump)();
189 void xw::XBMCConnection::Private::Synchronize()
192 synchronizeCallback.reset();
196 xw::XBMCConnection::CurrentResolution(RESOLUTION_INFO &res) const
200 res.fRefreshRate = 60;
201 res.dwFlags = D3DPRESENTFLAG_PROGRESSIVE;
203 res.bFullScreen = true;
204 res.iSubtitles = static_cast<int>(0.965 * res.iHeight);
205 res.fPixelRatio = 1.0f;
206 res.iScreenWidth = res.iWidth;
207 res.iScreenHeight = res.iHeight;
208 res.strMode.Format("%dx%d @ %.2fp",
215 xw::XBMCConnection::PreferredResolution(RESOLUTION_INFO &res) const
217 CurrentResolution(res);
221 xw::XBMCConnection::AvailableResolutions(std::vector<RESOLUTION_INFO> &res) const
223 RESOLUTION_INFO resolution;
224 CurrentResolution(resolution);
225 res.push_back(resolution);
228 EGLNativeDisplayType *
229 xw::XBMCConnection::NativeDisplay() const
231 return priv->m_display->GetEGLNativeDisplay();
234 const boost::scoped_ptr<xw::Compositor> &
235 xw::XBMCConnection::GetCompositor() const
237 return priv->m_compositor;
240 const boost::scoped_ptr<xw::Shell> &
241 xw::XBMCConnection::GetShell() const
243 return priv->m_shell;