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/>.
24 #include <wayland-client.h>
26 #include "windowing/DllWaylandClient.h"
27 #include "windowing/WaylandProtocol.h"
30 namespace xw = xbmc::wayland;
32 /* We only support version 1 of this interface, the other
33 * struct members are impliedly set to NULL */
34 const wl_output_listener xw::Output::m_listener =
36 Output::GeometryCallback,
40 xw::Output::Output(IDllWaylandClient &clientLibrary,
41 struct wl_output *output) :
42 m_clientLibrary(clientLibrary),
48 protocol::AddListenerOnWaylandObject(m_clientLibrary,
51 reinterpret_cast<void *>(this));
56 protocol::DestroyWaylandObject(m_clientLibrary,
61 xw::Output::GetWlOutput()
66 /* It is a precondition violation to use CurrentMode() and
67 * PreferredMode() before output modes have arrived yet, use
68 * a synchronization function to ensure that this is the case */
69 const xw::Output::ModeGeometry &
70 xw::Output::CurrentMode()
73 throw std::logic_error("No current mode has been set by the server"
79 const xw::Output::ModeGeometry &
80 xw::Output::PreferredMode()
83 throw std::logic_error("No preferred mode has been set by the "
89 const std::vector <xw::Output::ModeGeometry> &
90 xw::Output::AllModes()
95 const xw::Output::PhysicalGeometry &
96 xw::Output::Geometry()
102 xw::Output::ScaleFactor()
104 return m_scaleFactor;
108 xw::Output::GeometryCallback(void *data,
109 struct wl_output *output,
112 int32_t physicalWidth,
113 int32_t physicalHeight,
114 int32_t subpixelArrangement,
119 return static_cast<xw::Output *>(data)->Geometry(x,
130 xw::Output::ModeCallback(void *data,
131 struct wl_output *output,
137 return static_cast<xw::Output *>(data)->Mode(flags,
144 xw::Output::DoneCallback(void *data,
145 struct wl_output *output)
147 return static_cast<xw::Output *>(data)->Done();
151 xw::Output::ScaleCallback(void *data,
152 struct wl_output *output,
155 return static_cast<xw::Output *>(data)->Scale(factor);
158 /* This function is called when the output geometry is determined.
160 * The output geometry represents the actual geometry of the monitor.
161 * As it is per-output, there is only one geometry.
164 xw::Output::Geometry(int32_t x,
166 int32_t physicalWidth,
167 int32_t physicalHeight,
168 int32_t subpixelArrangement,
175 m_geometry.physicalWidth = physicalWidth;
176 m_geometry.physicalHeight = physicalHeight;
177 m_geometry.subpixelArrangement =
178 static_cast<enum wl_output_subpixel>(subpixelArrangement);
179 m_geometry.outputTransformation =
180 static_cast<enum wl_output_transform>(transform);
183 /* This function is called when a new mode is available on this output
184 * or a mode's state changes.
186 * It is possible that the same mode can change its state, so we will
187 * not add it twice. Instead, we will determine if the mode is the
188 * same one, but its flags have been updated and if so, update
189 * the pointers to modes having those flags.
192 xw::Output::Mode(uint32_t flags,
197 xw::Output::ModeGeometry *update = NULL;
199 for (std::vector<ModeGeometry>::iterator it = m_modes.begin();
203 if (it->width == width &&
204 it->height == height &&
205 it->refresh == refresh)
212 enum wl_output_mode outputFlags =
213 static_cast<enum wl_output_mode>(flags);
217 /* New output created */
218 m_modes.push_back(ModeGeometry());
219 ModeGeometry &next(m_modes.back());
222 next.height = height;
223 next.refresh = refresh;
228 /* We may get a mode notification for a new or
229 * or existing mode. In both cases we need to
230 * update the current and preferred modes */
231 if (outputFlags & WL_OUTPUT_MODE_CURRENT)
233 if (outputFlags & WL_OUTPUT_MODE_PREFERRED)
234 m_preferred = update;
242 /* This function is called whenever the scaling factor for this
243 * output changes. It there for clients to support HiDPI displays,
244 * although unused as of present */
246 xw::Output::Scale(int32_t factor)
248 m_scaleFactor = factor;