wl_window.c 8.23 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
//========================================================================
// GLFW 3.1 Wayland - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
//    claim that you wrote the original software. If you use this software
//    in a product, an acknowledgment in the product documentation would
//    be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
//    be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
//    distribution.
//
//========================================================================

#include "internal.h"

#include <stdio.h>
#include <poll.h>
#include <GL/gl.h>
#include <wayland-egl.h>


Camilla Berglund's avatar
Camilla Berglund committed
35
36
37
static void handlePing(void* data,
                       struct wl_shell_surface* shellSurface,
                       uint32_t serial)
38
39
40
41
{
    wl_shell_surface_pong(shellSurface, serial);
}

Camilla Berglund's avatar
Camilla Berglund committed
42
43
44
45
46
static void handleConfigure(void* data,
                            struct wl_shell_surface* shellSurface,
                            uint32_t edges,
                            int32_t width,
                            int32_t height)
47
48
49
{
}

Camilla Berglund's avatar
Camilla Berglund committed
50
51
static void handlePopupDone(void* data,
                            struct wl_shell_surface* shellSurface)
52
53
54
55
56
57
58
59
60
61
62
63
{
}

static const struct wl_shell_surface_listener shellSurfaceListener = {
    handlePing,
    handleConfigure,
    handlePopupDone
};

static GLboolean createSurface(_GLFWwindow* window,
                               const _GLFWwndconfig* wndconfig)
{
64
65
    window->wl.surface = wl_compositor_create_surface(_glfw.wl.compositor);
    if (!window->wl.surface)
66
67
        return GL_FALSE;

68
69
70
71
    window->wl.native = wl_egl_window_create(window->wl.surface,
                                             wndconfig->width,
                                             wndconfig->height);
    if (!window->wl.native)
72
73
        return GL_FALSE;

74
75
76
    window->wl.shell_surface = wl_shell_get_shell_surface(_glfw.wl.shell,
                                                          window->wl.surface);
    if (!window->wl.shell_surface)
77
78
        return GL_FALSE;

79
    wl_shell_surface_add_listener(window->wl.shell_surface,
80
81
82
                                  &shellSurfaceListener,
                                  window);

83
84
    window->wl.width = wndconfig->width;
    window->wl.height = wndconfig->height;
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106

    return GL_TRUE;
}


//////////////////////////////////////////////////////////////////////////
//////                       GLFW platform API                      //////
//////////////////////////////////////////////////////////////////////////

int _glfwPlatformCreateWindow(_GLFWwindow* window,
                              const _GLFWwndconfig* wndconfig,
                              const _GLFWctxconfig* ctxconfig,
                              const _GLFWfbconfig* fbconfig)
{
    if (!_glfwCreateContext(window, ctxconfig, fbconfig))
        return GL_FALSE;

    if (!createSurface(window, wndconfig))
        return GL_FALSE;

    if (wndconfig->monitor)
    {
Camilla Berglund's avatar
Camilla Berglund committed
107
108
109
110
111
        wl_shell_surface_set_fullscreen(
            window->wl.shell_surface,
            WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,
            0,
            wndconfig->monitor->wl.output);
112
113
114
    }
    else
    {
115
        wl_shell_surface_set_toplevel(window->wl.shell_surface);
116
117
118
119
120
121
122
    }

    return GL_TRUE;
}

void _glfwPlatformDestroyWindow(_GLFWwindow* window)
{
123
124
    if (window->wl.native)
        wl_egl_window_destroy(window->wl.native);
125
126
127

    _glfwDestroyContext(window);

128
129
    if (window->wl.shell_surface)
        wl_shell_surface_destroy(window->wl.shell_surface);
130

131
132
    if (window->wl.surface)
        wl_surface_destroy(window->wl.surface);
133
134
135
136
}

void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
{
137
    wl_shell_surface_set_title(window->wl.shell_surface, title);
138
139
140
141
142
143
144
145
}

void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos)
{
    // A Wayland client is not aware of its position, so just warn and set it
    // to (0, 0)

    _glfwInputError(GLFW_PLATFORM_ERROR,
146
                    "Wayland: Window position retreival not supported");
147
148
149
150
151
152
153
154
155

    if (xpos)
        *xpos = 0;
    if (ypos)
        *ypos = 0;
}

void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos)
{
Camilla Berglund's avatar
Camilla Berglund committed
156
    // A Wayland client can not set its position, so just warn
157
158

    _glfwInputError(GLFW_PLATFORM_ERROR,
159
                    "Wayland: Window position setting not supported");
160
161
162
163
164
}

void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height)
{
    if (width)
165
        *width = window->wl.width;
166
    if (height)
167
        *height = window->wl.height;
168
169
170
171
}

void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
{
172
173
174
    wl_egl_window_resize(window->wl.native, width, height, 0, 0);
    window->wl.width = width;
    window->wl.height = height;
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
}

void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height)
{
    _glfwPlatformGetWindowSize(window, width, height);
}

void _glfwPlatformIconifyWindow(_GLFWwindow* window)
{
    // TODO
    fprintf(stderr, "_glfwPlatformIconifyWindow not implemented yet\n");
}

void _glfwPlatformRestoreWindow(_GLFWwindow* window)
{
    // TODO
    fprintf(stderr, "_glfwPlatformRestoreWindow not implemented yet\n");
}

void _glfwPlatformShowWindow(_GLFWwindow* window)
{
196
    wl_shell_surface_set_toplevel(window->wl.shell_surface);
197
198
199
200
}

void _glfwPlatformHideWindow(_GLFWwindow* window)
{
201
202
    wl_surface_attach(window->wl.surface, NULL, 0, 0);
    wl_surface_commit(window->wl.surface);
203
204
205
206
}

void _glfwPlatformPollEvents(void)
{
207
    struct wl_display* display = _glfw.wl.display;
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
    struct pollfd fds[] = {
        { wl_display_get_fd(display), POLLIN },
    };

    while (wl_display_prepare_read(display) != 0)
        wl_display_dispatch_pending(display);
    wl_display_flush(display);
    if (poll(fds, 1, 0) > 0)
    {
        wl_display_read_events(display);
        wl_display_dispatch_pending(display);
    }
    else
    {
        wl_display_cancel_read(display);
    }
}

void _glfwPlatformWaitEvents(void)
{
228
    struct wl_display* display = _glfw.wl.display;
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
    struct pollfd fds[] = {
        { wl_display_get_fd(display), POLLIN },
    };

    while (wl_display_prepare_read(display) != 0)
        wl_display_dispatch_pending(display);
    wl_display_flush(display);
    if (poll(fds, 1, -1) > 0)
    {
        wl_display_read_events(display);
        wl_display_dispatch_pending(display);
    }
    else
    {
        wl_display_cancel_read(display);
    }
}

void _glfwPlatformPostEmptyEvent(void)
{
249
    wl_display_sync(_glfw.wl.display);
250
251
252
253
}

void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y)
{
Camilla Berglund's avatar
Camilla Berglund committed
254
    // A Wayland client can not set the cursor position
255
    _glfwInputError(GLFW_PLATFORM_ERROR,
256
                    "Wayland: Cursor position setting not supported");
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
}

void _glfwPlatformApplyCursorMode(_GLFWwindow* window)
{
    fprintf(stderr, "_glfwPlatformApplyCursorMode not implemented yet\n");
    switch (window->cursorMode)
    {
        case GLFW_CURSOR_NORMAL:
            // TODO: enable showing cursor
            break;
        case GLFW_CURSOR_HIDDEN:
            // TODO: enable not showing cursor
            break;
        case GLFW_CURSOR_DISABLED:
            // TODO: enable pointer lock and hide cursor
            break;
    }
}
Camilla Berglund's avatar
Camilla Berglund committed
275

276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
                              const GLFWimage* image,
                              int xhot, int yhot)
{
    fprintf(stderr, "_glfwPlatformCreateCursor not implemented yet\n");
    return GL_FALSE;
}

void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
{
    fprintf(stderr, "_glfwPlatformDestroyCursor not implemented yet\n");
}

void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
{
    fprintf(stderr, "_glfwPlatformSetCursor not implemented yet\n");
}