[cosmetic] cleanup copyright headers
[vuplus_xbmc] / xbmc / windowing / egl / wayland / Output.cpp
1 /*
2  *      Copyright (C) 2011-2013 Team XBMC
3  *      http://xbmc.org
4  *
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)
8  *  any later version.
9  *
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.
14  *
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/>.
18  *
19  */
20 #include <sstream>
21 #include <iostream>
22 #include <stdexcept>
23
24 #include <wayland-client.h>
25
26 #include "windowing/DllWaylandClient.h"
27 #include "windowing/WaylandProtocol.h"
28 #include "Output.h"
29
30 namespace xw = xbmc::wayland;
31
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 = 
35 {
36   Output::GeometryCallback,
37   Output::ModeCallback
38 };
39
40 xw::Output::Output(IDllWaylandClient &clientLibrary,
41                    struct wl_output *output) :
42   m_clientLibrary(clientLibrary),
43   m_output(output),
44   m_scaleFactor(1.0),
45   m_current(NULL),
46   m_preferred(NULL)
47 {
48   protocol::AddListenerOnWaylandObject(m_clientLibrary,
49                                        m_output,
50                                        &m_listener,
51                                        reinterpret_cast<void *>(this));
52 }
53
54 xw::Output::~Output()
55 {
56   protocol::DestroyWaylandObject(m_clientLibrary,
57                                  m_output);
58 }
59
60 struct wl_output *
61 xw::Output::GetWlOutput()
62 {
63   return m_output;
64 }
65
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()
71 {
72   if (!m_current)
73     throw std::logic_error("No current mode has been set by the server"
74                            " yet");
75   
76   return *m_current;
77 }
78
79 const xw::Output::ModeGeometry &
80 xw::Output::PreferredMode()
81 {
82   if (!m_preferred)
83     throw std::logic_error("No preferred mode has been set by the "
84                            " server yet");
85
86   return *m_preferred;
87 }
88
89 const std::vector <xw::Output::ModeGeometry> &
90 xw::Output::AllModes()
91 {
92   return m_modes;
93 }
94
95 const xw::Output::PhysicalGeometry &
96 xw::Output::Geometry()
97 {
98   return m_geometry;
99 }
100
101 uint32_t
102 xw::Output::ScaleFactor()
103 {
104   return m_scaleFactor;
105 }
106
107 void
108 xw::Output::GeometryCallback(void *data,
109                              struct wl_output *output,
110                              int32_t x,
111                              int32_t y,
112                              int32_t physicalWidth,
113                              int32_t physicalHeight,
114                              int32_t subpixelArrangement,
115                              const char *make,
116                              const char *model,
117                              int32_t transform)
118 {
119   return static_cast<xw::Output *>(data)->Geometry(x,
120                                                    y,
121                                                    physicalWidth,
122                                                    physicalHeight,
123                                                    subpixelArrangement,
124                                                    make,
125                                                    model,
126                                                    transform);
127 }
128
129 void
130 xw::Output::ModeCallback(void *data,
131                          struct wl_output *output,
132                          uint32_t flags,
133                          int32_t width,
134                          int32_t height,
135                          int32_t refresh)
136 {
137   return static_cast<xw::Output *>(data)->Mode(flags,
138                                                width,
139                                                height,
140                                                refresh);
141 }
142
143 void
144 xw::Output::DoneCallback(void *data,
145                          struct wl_output *output)
146 {
147   return static_cast<xw::Output *>(data)->Done();
148 }
149
150 void
151 xw::Output::ScaleCallback(void *data,
152                           struct wl_output *output,
153                           int32_t factor)
154 {
155   return static_cast<xw::Output *>(data)->Scale(factor);
156 }
157
158 /* This function is called when the output geometry is determined.
159  * 
160  * The output geometry represents the actual geometry of the monitor.
161  * As it is per-output, there is only one geometry.
162  */
163 void
164 xw::Output::Geometry(int32_t x,
165                      int32_t y,
166                      int32_t physicalWidth,
167                      int32_t physicalHeight,
168                      int32_t subpixelArrangement,
169                      const char *make,
170                      const char *model,
171                      int32_t transform)
172 {
173   m_geometry.x = x;
174   m_geometry.y = y;
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);
181 }
182
183 /* This function is called when a new mode is available on this output
184  * or a mode's state changes.
185  * 
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.
190  */
191 void
192 xw::Output::Mode(uint32_t flags,
193                  int32_t width,
194                  int32_t height,
195                  int32_t refresh)
196 {
197   xw::Output::ModeGeometry *update = NULL;
198   
199   for (std::vector<ModeGeometry>::iterator it = m_modes.begin();
200        it != m_modes.end();
201        ++it)
202   { 
203     if (it->width == width &&
204         it->height == height &&
205         it->refresh == refresh)
206     {
207       update = &(*it);
208       break;
209     }
210   }
211   
212   enum wl_output_mode outputFlags =
213     static_cast<enum wl_output_mode>(flags);
214   
215   if (!update)
216   {
217     /* New output created */
218     m_modes.push_back(ModeGeometry());
219     ModeGeometry &next(m_modes.back());
220     
221     next.width = width;
222     next.height = height;
223     next.refresh = refresh;
224     
225     update = &next;
226   }
227   
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)
232     m_current = update;
233   if (outputFlags & WL_OUTPUT_MODE_PREFERRED)
234     m_preferred = update;
235 }
236
237 void
238 xw::Output::Done()
239 {
240 }
241
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 */
245 void
246 xw::Output::Scale(int32_t factor)
247 {
248   m_scaleFactor = factor;
249 }