• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //========================================================================
2 // GLFW 3.2 Wayland - www.glfw.org
3 //------------------------------------------------------------------------
4 // Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>
5 //
6 // This software is provided 'as-is', without any express or implied
7 // warranty. In no event will the authors be held liable for any damages
8 // arising from the use of this software.
9 //
10 // Permission is granted to anyone to use this software for any purpose,
11 // including commercial applications, and to alter it and redistribute it
12 // freely, subject to the following restrictions:
13 //
14 // 1. The origin of this software must not be misrepresented; you must not
15 //    claim that you wrote the original software. If you use this software
16 //    in a product, an acknowledgment in the product documentation would
17 //    be appreciated but is not required.
18 //
19 // 2. Altered source versions must be plainly marked as such, and must not
20 //    be misrepresented as being the original software.
21 //
22 // 3. This notice may not be removed or altered from any source
23 //    distribution.
24 //
25 //========================================================================
26 
27 #include "internal.h"
28 
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <errno.h>
33 
34 
35 struct _GLFWvidmodeWayland
36 {
37     GLFWvidmode         base;
38     uint32_t            flags;
39 };
40 
geometry(void * data,struct wl_output * output,int32_t x,int32_t y,int32_t physicalWidth,int32_t physicalHeight,int32_t subpixel,const char * make,const char * model,int32_t transform)41 static void geometry(void* data,
42                      struct wl_output* output,
43                      int32_t x,
44                      int32_t y,
45                      int32_t physicalWidth,
46                      int32_t physicalHeight,
47                      int32_t subpixel,
48                      const char* make,
49                      const char* model,
50                      int32_t transform)
51 {
52     struct _GLFWmonitor *monitor = data;
53 
54     monitor->wl.x = x;
55     monitor->wl.y = y;
56     monitor->widthMM = physicalWidth;
57     monitor->heightMM = physicalHeight;
58 }
59 
mode(void * data,struct wl_output * output,uint32_t flags,int32_t width,int32_t height,int32_t refresh)60 static void mode(void* data,
61                  struct wl_output* output,
62                  uint32_t flags,
63                  int32_t width,
64                  int32_t height,
65                  int32_t refresh)
66 {
67     struct _GLFWmonitor *monitor = data;
68     _GLFWvidmodeWayland mode = { { 0 }, };
69 
70     mode.base.width = width;
71     mode.base.height = height;
72     mode.base.refreshRate = refresh / 1000;
73     mode.flags = flags;
74 
75     if (monitor->wl.modesCount + 1 >= monitor->wl.modesSize)
76     {
77         int size = monitor->wl.modesSize * 2;
78         _GLFWvidmodeWayland* modes =
79             realloc(monitor->wl.modes,
80                     size * sizeof(_GLFWvidmodeWayland));
81         monitor->wl.modes = modes;
82         monitor->wl.modesSize = size;
83     }
84 
85     monitor->wl.modes[monitor->wl.modesCount++] = mode;
86 }
87 
done(void * data,struct wl_output * output)88 static void done(void* data,
89                  struct wl_output* output)
90 {
91     struct _GLFWmonitor *monitor = data;
92 
93     monitor->wl.done = GLFW_TRUE;
94 }
95 
scale(void * data,struct wl_output * output,int32_t factor)96 static void scale(void* data,
97                   struct wl_output* output,
98                   int32_t factor)
99 {
100     struct _GLFWmonitor *monitor = data;
101 
102     monitor->wl.scale = factor;
103 }
104 
105 static const struct wl_output_listener output_listener = {
106     geometry,
107     mode,
108     done,
109     scale,
110 };
111 
112 
113 //////////////////////////////////////////////////////////////////////////
114 //////                       GLFW internal API                      //////
115 //////////////////////////////////////////////////////////////////////////
116 
_glfwAddOutputWayland(uint32_t name,uint32_t version)117 void _glfwAddOutputWayland(uint32_t name, uint32_t version)
118 {
119     _GLFWmonitor *monitor;
120     struct wl_output *output;
121     char name_str[80];
122 
123     memset(name_str, 0, sizeof(name_str));
124     snprintf(name_str, 79, "wl_output@%u", name);
125 
126     if (version < 2)
127     {
128         _glfwInputError(GLFW_PLATFORM_ERROR,
129                         "Wayland: Unsupported output interface version");
130         return;
131     }
132 
133     monitor = _glfwAllocMonitor(name_str, 0, 0);
134 
135     output = wl_registry_bind(_glfw.wl.registry,
136                               name,
137                               &wl_output_interface,
138                               2);
139     if (!output)
140     {
141         _glfwFreeMonitor(monitor);
142         return;
143     }
144 
145     monitor->wl.modes = calloc(4, sizeof(_GLFWvidmodeWayland));
146     monitor->wl.modesSize = 4;
147 
148     monitor->wl.scale = 1;
149 
150     monitor->wl.output = output;
151     wl_output_add_listener(output, &output_listener, monitor);
152 
153     if (_glfw.wl.monitorsCount + 1 >= _glfw.wl.monitorsSize)
154     {
155         _GLFWmonitor** monitors = _glfw.wl.monitors;
156         int size = _glfw.wl.monitorsSize * 2;
157 
158         monitors = realloc(monitors, size * sizeof(_GLFWmonitor*));
159 
160         _glfw.wl.monitors = monitors;
161         _glfw.wl.monitorsSize = size;
162     }
163 
164     _glfw.wl.monitors[_glfw.wl.monitorsCount++] = monitor;
165 }
166 
167 
168 //////////////////////////////////////////////////////////////////////////
169 //////                       GLFW platform API                      //////
170 //////////////////////////////////////////////////////////////////////////
171 
_glfwPlatformGetMonitors(int * count)172 _GLFWmonitor** _glfwPlatformGetMonitors(int* count)
173 {
174     _GLFWmonitor** monitors;
175     _GLFWmonitor* monitor;
176     int i, monitorsCount = _glfw.wl.monitorsCount;
177 
178     if (_glfw.wl.monitorsCount == 0)
179         goto err;
180 
181     monitors = calloc(monitorsCount, sizeof(_GLFWmonitor*));
182 
183     for (i = 0; i < monitorsCount; i++)
184     {
185         _GLFWmonitor* origMonitor = _glfw.wl.monitors[i];
186         monitor = calloc(1, sizeof(_GLFWmonitor));
187 
188         monitor->modes =
189             _glfwPlatformGetVideoModes(origMonitor,
190                                        &origMonitor->wl.modesCount);
191         *monitor = *_glfw.wl.monitors[i];
192         monitors[i] = monitor;
193     }
194 
195     *count = monitorsCount;
196     return monitors;
197 
198 err:
199     *count = 0;
200     return NULL;
201 }
202 
_glfwPlatformIsSameMonitor(_GLFWmonitor * first,_GLFWmonitor * second)203 GLFWbool _glfwPlatformIsSameMonitor(_GLFWmonitor* first, _GLFWmonitor* second)
204 {
205     return first->wl.output == second->wl.output;
206 }
207 
_glfwPlatformGetMonitorPos(_GLFWmonitor * monitor,int * xpos,int * ypos)208 void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
209 {
210     if (xpos)
211         *xpos = monitor->wl.x;
212     if (ypos)
213         *ypos = monitor->wl.y;
214 }
215 
_glfwPlatformGetVideoModes(_GLFWmonitor * monitor,int * found)216 GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found)
217 {
218     GLFWvidmode *modes;
219     int i, modesCount = monitor->wl.modesCount;
220 
221     modes = calloc(modesCount, sizeof(GLFWvidmode));
222 
223     for (i = 0;  i < modesCount;  i++)
224         modes[i] = monitor->wl.modes[i].base;
225 
226     *found = modesCount;
227     return modes;
228 }
229 
_glfwPlatformGetVideoMode(_GLFWmonitor * monitor,GLFWvidmode * mode)230 void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
231 {
232     int i;
233 
234     for (i = 0;  i < monitor->wl.modesCount;  i++)
235     {
236         if (monitor->wl.modes[i].flags & WL_OUTPUT_MODE_CURRENT)
237         {
238             *mode = monitor->wl.modes[i].base;
239             return;
240         }
241     }
242 }
243 
_glfwPlatformGetGammaRamp(_GLFWmonitor * monitor,GLFWgammaramp * ramp)244 void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
245 {
246     // TODO
247     _glfwInputError(GLFW_PLATFORM_ERROR,
248                     "Wayland: Gamma ramp getting not supported yet");
249 }
250 
_glfwPlatformSetGammaRamp(_GLFWmonitor * monitor,const GLFWgammaramp * ramp)251 void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
252 {
253     // TODO
254     _glfwInputError(GLFW_PLATFORM_ERROR,
255                     "Wayland: Gamma ramp setting not supported yet");
256 }
257 
258 
259 //////////////////////////////////////////////////////////////////////////
260 //////                        GLFW native API                       //////
261 //////////////////////////////////////////////////////////////////////////
262 
glfwGetWaylandMonitor(GLFWmonitor * handle)263 GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* handle)
264 {
265     _GLFWmonitor* monitor = (_GLFWmonitor*) handle;
266     _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
267     return monitor->wl.output;
268 }
269 
270