wl_window.c 8.78 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
50
51
52
    _GLFWwindow* window = data;
    _glfwInputFramebufferSize(window, width, height);
    _glfwInputWindowSize(window, width, height);
    _glfwPlatformSetWindowSize(window, width, height);
    _glfwInputWindowDamage(window);
53
54
}

Camilla Berglund's avatar
Camilla Berglund committed
55
56
static void handlePopupDone(void* data,
                            struct wl_shell_surface* shellSurface)
57
58
59
60
61
62
63
64
65
66
67
68
{
}

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

static GLboolean createSurface(_GLFWwindow* window,
                               const _GLFWwndconfig* wndconfig)
{
69
70
    window->wl.surface = wl_compositor_create_surface(_glfw.wl.compositor);
    if (!window->wl.surface)
71
72
        return GL_FALSE;

73
74
    wl_surface_set_user_data(window->wl.surface, window);

75
76
77
78
    window->wl.native = wl_egl_window_create(window->wl.surface,
                                             wndconfig->width,
                                             wndconfig->height);
    if (!window->wl.native)
79
80
        return GL_FALSE;

81
82
83
    window->wl.shell_surface = wl_shell_get_shell_surface(_glfw.wl.shell,
                                                          window->wl.surface);
    if (!window->wl.shell_surface)
84
85
        return GL_FALSE;

86
    wl_shell_surface_add_listener(window->wl.shell_surface,
87
88
89
                                  &shellSurfaceListener,
                                  window);

90
91
    window->wl.width = wndconfig->width;
    window->wl.height = wndconfig->height;
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113

    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
114
115
116
117
118
        wl_shell_surface_set_fullscreen(
            window->wl.shell_surface,
            WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,
            0,
            wndconfig->monitor->wl.output);
119
120
121
    }
    else
    {
122
        wl_shell_surface_set_toplevel(window->wl.shell_surface);
123
124
125
126
127
128
129
    }

    return GL_TRUE;
}

void _glfwPlatformDestroyWindow(_GLFWwindow* window)
{
130
131
    _glfwDestroyContext(window);

132
133
    if (window->wl.native)
        wl_egl_window_destroy(window->wl.native);
134

135
136
    if (window->wl.shell_surface)
        wl_shell_surface_destroy(window->wl.shell_surface);
137

138
139
    if (window->wl.surface)
        wl_surface_destroy(window->wl.surface);
140
141
142
143
}

void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
{
144
    wl_shell_surface_set_title(window->wl.shell_surface, title);
145
146
147
148
149
150
151
152
}

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,
153
                    "Wayland: Window position retreival not supported");
154
155
156
157
158
159
160
161
162

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

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

    _glfwInputError(GLFW_PLATFORM_ERROR,
166
                    "Wayland: Window position setting not supported");
167
168
169
170
171
}

void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height)
{
    if (width)
172
        *width = window->wl.width;
173
    if (height)
174
        *height = window->wl.height;
175
176
177
178
}

void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
{
179
180
181
    wl_egl_window_resize(window->wl.native, width, height, 0, 0);
    window->wl.width = width;
    window->wl.height = height;
182
183
184
185
186
187
188
}

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

189
190
191
192
193
194
195
196
void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
                                     int* left, int* top,
                                     int* right, int* bottom)
{
    // TODO
    fprintf(stderr, "_glfwPlatformGetWindowFrameSize not implemented yet\n");
}

197
198
199
200
201
202
203
204
205
206
207
208
209
210
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)
{
211
    wl_shell_surface_set_toplevel(window->wl.shell_surface);
212
213
214
215
}

void _glfwPlatformHideWindow(_GLFWwindow* window)
{
216
217
    wl_surface_attach(window->wl.surface, NULL, 0, 0);
    wl_surface_commit(window->wl.surface);
218
219
220
221
}

void _glfwPlatformPollEvents(void)
{
222
    struct wl_display* display = _glfw.wl.display;
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
    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)
{
243
    struct wl_display* display = _glfw.wl.display;
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
    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)
{
264
    wl_display_sync(_glfw.wl.display);
265
266
267
268
}

void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y)
{
Camilla Berglund's avatar
Camilla Berglund committed
269
    // A Wayland client can not set the cursor position
270
    _glfwInputError(GLFW_PLATFORM_ERROR,
271
                    "Wayland: Cursor position setting not supported");
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
}

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
290

291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
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");
}