src/video/wayland/SDL_waylandmouse.c
author Sam Lantinga
Thu, 01 Sep 2016 01:26:56 -0700
changeset 10304 ee83e0b4a36f
parent 10154 fae27a079fcb
child 10604 27d0fb08d755
permissions -rw-r--r--
wayland: Add support for relative mouse mode, by Jonas Ådahl <jadahl@gmail.com>

Generate the C protocol files from the protocol XML files installed by
wayland-protocols, and use them to implement support for relative pointer
motions and pointer locking.

Note that at the time, the protocol is unstable and may change in the future.
Any future breaking changes will, however, fail gracefully and result in no
regressions compared to before this patch.
gabomdq@8062
     1
/*
gabomdq@8062
     2
  Simple DirectMedia Layer
slouken@9998
     3
  Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
gabomdq@8062
     4
gabomdq@8062
     5
  This software is provided 'as-is', without any express or implied
gabomdq@8062
     6
  warranty.  In no event will the authors be held liable for any damages
gabomdq@8062
     7
  arising from the use of this software.
gabomdq@8062
     8
gabomdq@8062
     9
  Permission is granted to anyone to use this software for any purpose,
gabomdq@8062
    10
  including commercial applications, and to alter it and redistribute it
gabomdq@8062
    11
  freely, subject to the following restrictions:
gabomdq@8062
    12
gabomdq@8062
    13
  1. The origin of this software must not be misrepresented; you must not
gabomdq@8062
    14
     claim that you wrote the original software. If you use this software
gabomdq@8062
    15
     in a product, an acknowledgment in the product documentation would be
gabomdq@8062
    16
     appreciated but is not required.
gabomdq@8062
    17
  2. Altered source versions must be plainly marked as such, and must not be
gabomdq@8062
    18
     misrepresented as being the original software.
gabomdq@8062
    19
  3. This notice may not be removed or altered from any source distribution.
gabomdq@8062
    20
*/
gabomdq@8062
    21
icculus@8116
    22
#include "../../SDL_internal.h"
icculus@8116
    23
icculus@8116
    24
#if SDL_VIDEO_DRIVER_WAYLAND
icculus@8116
    25
gabomdq@8062
    26
#ifndef _GNU_SOURCE
gabomdq@8062
    27
#define _GNU_SOURCE
gabomdq@8062
    28
#endif
gabomdq@8062
    29
gabomdq@8062
    30
#include <sys/types.h>
gabomdq@8062
    31
#include <sys/mman.h>
gabomdq@8062
    32
#include <fcntl.h>
gabomdq@8062
    33
#include <unistd.h>
gabomdq@8062
    34
#include <stdlib.h>
gabomdq@8062
    35
#include <limits.h>
gabomdq@8062
    36
gabomdq@8062
    37
#include "../SDL_sysvideo.h"
gabomdq@8062
    38
gabomdq@8062
    39
#include "SDL_mouse.h"
gabomdq@8062
    40
#include "../../events/SDL_mouse_c.h"
gabomdq@8062
    41
#include "SDL_waylandvideo.h"
gabomdq@8062
    42
#include "SDL_waylandevents_c.h"
gabomdq@8062
    43
gabomdq@8104
    44
#include "SDL_waylanddyn.h"
gabomdq@8104
    45
#include "wayland-cursor.h"
gabomdq@8104
    46
gabomdq@8062
    47
#include "SDL_assert.h"
gabomdq@8062
    48
gabomdq@8062
    49
gabomdq@8062
    50
typedef struct {
gabomdq@8062
    51
    struct wl_buffer   *buffer;
gabomdq@8062
    52
    struct wl_surface  *surface;
gabomdq@8062
    53
gabomdq@8062
    54
    int                hot_x, hot_y;
slouken@8711
    55
    int                w, h;
gabomdq@8062
    56
gabomdq@8062
    57
    /* Either a preloaded cursor, or one we created ourselves */
gabomdq@8062
    58
    struct wl_cursor   *cursor;
gabomdq@8062
    59
    void               *shm_data;
gabomdq@8062
    60
} Wayland_CursorData;
gabomdq@8062
    61
gabomdq@8062
    62
static int
gabomdq@8062
    63
wayland_create_tmp_file(off_t size)
gabomdq@8062
    64
{
gabomdq@8062
    65
    static const char template[] = "/sdl-shared-XXXXXX";
gabomdq@8062
    66
    char *xdg_path;
gabomdq@8062
    67
    char tmp_path[PATH_MAX];
gabomdq@8062
    68
    int fd;
gabomdq@8062
    69
gabomdq@8062
    70
    xdg_path = SDL_getenv("XDG_RUNTIME_DIR");
gabomdq@8062
    71
    if (!xdg_path) {
gabomdq@8062
    72
        return -1;
gabomdq@8062
    73
    }
gabomdq@8062
    74
gabomdq@8062
    75
    SDL_strlcpy(tmp_path, xdg_path, PATH_MAX);
gabomdq@8062
    76
    SDL_strlcat(tmp_path, template, PATH_MAX);
gabomdq@8062
    77
gabomdq@8062
    78
    fd = mkostemp(tmp_path, O_CLOEXEC);
gabomdq@8062
    79
    if (fd < 0)
gabomdq@8062
    80
        return -1;
gabomdq@8062
    81
gabomdq@8062
    82
    if (ftruncate(fd, size) < 0) {
gabomdq@8062
    83
        close(fd);
gabomdq@8062
    84
        return -1;
gabomdq@8062
    85
    }
gabomdq@8062
    86
gabomdq@8062
    87
    return fd;
gabomdq@8062
    88
}
gabomdq@8062
    89
gabomdq@8062
    90
static void
gabomdq@8062
    91
mouse_buffer_release(void *data, struct wl_buffer *buffer)
gabomdq@8062
    92
{
gabomdq@8062
    93
}
gabomdq@8062
    94
gabomdq@8062
    95
static const struct wl_buffer_listener mouse_buffer_listener = {
gabomdq@8062
    96
    mouse_buffer_release
gabomdq@8062
    97
};
gabomdq@8062
    98
gabomdq@8062
    99
static int
gabomdq@8062
   100
create_buffer_from_shm(Wayland_CursorData *d,
gabomdq@8062
   101
                       int width,
gabomdq@8062
   102
                       int height,
gabomdq@8062
   103
                       uint32_t format)
gabomdq@8062
   104
{
gabomdq@8062
   105
    SDL_VideoDevice *vd = SDL_GetVideoDevice();
gabomdq@8062
   106
    SDL_VideoData *data = (SDL_VideoData *) vd->driverdata;
icculus@8721
   107
    struct wl_shm_pool *shm_pool;
gabomdq@8062
   108
gabomdq@8062
   109
    int stride = width * 4;
gabomdq@8062
   110
    int size = stride * height;
gabomdq@8062
   111
gabomdq@8062
   112
    int shm_fd;
gabomdq@8062
   113
gabomdq@8062
   114
    shm_fd = wayland_create_tmp_file(size);
gabomdq@8062
   115
    if (shm_fd < 0)
gabomdq@8062
   116
    {
philipp@10130
   117
        return SDL_SetError("Creating mouse cursor buffer failed.");
gabomdq@8062
   118
    }
gabomdq@8062
   119
gabomdq@8062
   120
    d->shm_data = mmap(NULL,
gabomdq@8062
   121
                       size,
gabomdq@8062
   122
                       PROT_READ | PROT_WRITE,
gabomdq@8062
   123
                       MAP_SHARED,
gabomdq@8062
   124
                       shm_fd,
gabomdq@8062
   125
                       0);
ryomnktml@9136
   126
    if (d->shm_data == MAP_FAILED) {
gabomdq@8062
   127
        d->shm_data = NULL;
gabomdq@8062
   128
        close (shm_fd);
philipp@10130
   129
        return SDL_SetError("mmap() failed.");
gabomdq@8062
   130
    }
gabomdq@8062
   131
icculus@8721
   132
    shm_pool = wl_shm_create_pool(data->shm, shm_fd, size);
gabomdq@8062
   133
    d->buffer = wl_shm_pool_create_buffer(shm_pool,
gabomdq@8062
   134
                                          0,
gabomdq@8062
   135
                                          width,
gabomdq@8062
   136
                                          height,
gabomdq@8062
   137
                                          stride,
gabomdq@8062
   138
                                          format);
gabomdq@8062
   139
    wl_buffer_add_listener(d->buffer,
gabomdq@8062
   140
                           &mouse_buffer_listener,
gabomdq@8062
   141
                           d);
gabomdq@8062
   142
gabomdq@8062
   143
    wl_shm_pool_destroy (shm_pool);
gabomdq@8062
   144
    close (shm_fd);
gabomdq@8062
   145
gabomdq@8062
   146
    return 0;
gabomdq@8062
   147
}
gabomdq@8062
   148
gabomdq@8062
   149
static SDL_Cursor *
gabomdq@8062
   150
Wayland_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y)
gabomdq@8062
   151
{
gabomdq@8062
   152
    SDL_Cursor *cursor;
gabomdq@8062
   153
gabomdq@8062
   154
    cursor = calloc(1, sizeof (*cursor));
gabomdq@8062
   155
    if (cursor) {
gabomdq@8062
   156
        SDL_VideoDevice *vd = SDL_GetVideoDevice ();
gabomdq@8062
   157
        SDL_VideoData *wd = (SDL_VideoData *) vd->driverdata;
gabomdq@8062
   158
        Wayland_CursorData *data = calloc (1, sizeof (Wayland_CursorData));
philipp@10098
   159
        if (!data) {
philipp@10098
   160
            SDL_OutOfMemory();
philipp@10098
   161
            free(cursor);
philipp@10098
   162
            return NULL;
philipp@10098
   163
        }
gabomdq@8062
   164
        cursor->driverdata = (void *) data;
gabomdq@8062
   165
gabomdq@8062
   166
        /* Assume ARGB8888 */
gabomdq@8062
   167
        SDL_assert(surface->format->format == SDL_PIXELFORMAT_ARGB8888);
gabomdq@8062
   168
        SDL_assert(surface->pitch == surface->w * 4);
gabomdq@8062
   169
gabomdq@8062
   170
        /* Allocate shared memory buffer for this cursor */
gabomdq@8062
   171
        if (create_buffer_from_shm (data,
gabomdq@8062
   172
                                    surface->w,
gabomdq@8062
   173
                                    surface->h,
philipp@10114
   174
                                    WL_SHM_FORMAT_ARGB8888) < 0)
gabomdq@8062
   175
        {
gabomdq@8062
   176
            free (cursor->driverdata);
gabomdq@8062
   177
            free (cursor);
gabomdq@8062
   178
            return NULL;
gabomdq@8062
   179
        }
gabomdq@8062
   180
gabomdq@8062
   181
        SDL_memcpy(data->shm_data,
gabomdq@8062
   182
                   surface->pixels,
gabomdq@8062
   183
                   surface->h * surface->pitch);
gabomdq@8062
   184
gabomdq@8062
   185
        data->surface = wl_compositor_create_surface(wd->compositor);
gabomdq@8135
   186
        wl_surface_set_user_data(data->surface, NULL);
gabomdq@8062
   187
gabomdq@8062
   188
        data->hot_x = hot_x;
gabomdq@8062
   189
        data->hot_y = hot_y;
slouken@8711
   190
        data->w = surface->w;
slouken@8711
   191
        data->h = surface->h;
philipp@10098
   192
    } else {
philipp@10098
   193
        SDL_OutOfMemory();
gabomdq@8062
   194
    }
gabomdq@8062
   195
gabomdq@8062
   196
    return cursor;
gabomdq@8062
   197
}
gabomdq@8062
   198
gabomdq@8062
   199
static SDL_Cursor *
gabomdq@8062
   200
CreateCursorFromWlCursor(SDL_VideoData *d, struct wl_cursor *wlcursor)
gabomdq@8062
   201
{
gabomdq@8062
   202
    SDL_Cursor *cursor;
gabomdq@8062
   203
gabomdq@8062
   204
    cursor = calloc(1, sizeof (*cursor));
gabomdq@8062
   205
    if (cursor) {
gabomdq@8062
   206
        Wayland_CursorData *data = calloc (1, sizeof (Wayland_CursorData));
philipp@10098
   207
        if (!data) {
philipp@10098
   208
            SDL_OutOfMemory();
philipp@10098
   209
            free(cursor);
philipp@10098
   210
            return NULL;
philipp@10098
   211
        }
gabomdq@8062
   212
        cursor->driverdata = (void *) data;
gabomdq@8062
   213
slouken@8711
   214
        data->buffer = WAYLAND_wl_cursor_image_get_buffer(wlcursor->images[0]);
gabomdq@8062
   215
        data->surface = wl_compositor_create_surface(d->compositor);
gabomdq@8135
   216
        wl_surface_set_user_data(data->surface, NULL);
gabomdq@8062
   217
        data->hot_x = wlcursor->images[0]->hotspot_x;
gabomdq@8062
   218
        data->hot_y = wlcursor->images[0]->hotspot_y;
slouken@8711
   219
        data->w = wlcursor->images[0]->width;
slouken@8711
   220
        data->h = wlcursor->images[0]->height;
gabomdq@8062
   221
        data->cursor= wlcursor;
gabomdq@8062
   222
    } else {
gabomdq@8062
   223
        SDL_OutOfMemory ();
gabomdq@8062
   224
    }
gabomdq@8062
   225
gabomdq@8062
   226
    return cursor;
gabomdq@8062
   227
}
gabomdq@8062
   228
gabomdq@8062
   229
static SDL_Cursor *
gabomdq@8062
   230
Wayland_CreateDefaultCursor()
gabomdq@8062
   231
{
gabomdq@8062
   232
    SDL_VideoDevice *device = SDL_GetVideoDevice();
gabomdq@8062
   233
    SDL_VideoData *data = device->driverdata;
gabomdq@8062
   234
gabomdq@8062
   235
    return CreateCursorFromWlCursor (data,
gabomdq@8104
   236
                                     WAYLAND_wl_cursor_theme_get_cursor(data->cursor_theme,
gabomdq@8062
   237
                                                                "left_ptr"));
gabomdq@8062
   238
}
gabomdq@8062
   239
gabomdq@8062
   240
static SDL_Cursor *
gabomdq@8062
   241
Wayland_CreateSystemCursor(SDL_SystemCursor id)
gabomdq@8062
   242
{
gabomdq@8062
   243
    SDL_VideoDevice *vd = SDL_GetVideoDevice();
gabomdq@8062
   244
    SDL_VideoData *d = vd->driverdata;
gabomdq@8062
   245
gabomdq@8062
   246
    struct wl_cursor *cursor = NULL;
gabomdq@8062
   247
gabomdq@8062
   248
    switch(id)
gabomdq@8062
   249
    {
gabomdq@8062
   250
    default:
gabomdq@8062
   251
        SDL_assert(0);
gabomdq@8062
   252
        return NULL;
gabomdq@8062
   253
    case SDL_SYSTEM_CURSOR_ARROW:
gabomdq@8104
   254
        cursor = WAYLAND_wl_cursor_theme_get_cursor(d->cursor_theme, "left_ptr");
gabomdq@8062
   255
        break;
gabomdq@8062
   256
    case SDL_SYSTEM_CURSOR_IBEAM:
gabomdq@8104
   257
        cursor = WAYLAND_wl_cursor_theme_get_cursor(d->cursor_theme, "xterm");
gabomdq@8062
   258
        break;
gabomdq@8062
   259
    case SDL_SYSTEM_CURSOR_WAIT:
slouken@8710
   260
        cursor = WAYLAND_wl_cursor_theme_get_cursor(d->cursor_theme, "watch");
gabomdq@8062
   261
        break;
gabomdq@8062
   262
    case SDL_SYSTEM_CURSOR_CROSSHAIR:
gabomdq@8104
   263
        cursor = WAYLAND_wl_cursor_theme_get_cursor(d->cursor_theme, "hand1");
gabomdq@8062
   264
        break;
gabomdq@8062
   265
    case SDL_SYSTEM_CURSOR_WAITARROW:
slouken@8710
   266
        cursor = WAYLAND_wl_cursor_theme_get_cursor(d->cursor_theme, "watch");
gabomdq@8062
   267
        break;
gabomdq@8062
   268
    case SDL_SYSTEM_CURSOR_SIZENWSE:
gabomdq@8104
   269
        cursor = WAYLAND_wl_cursor_theme_get_cursor(d->cursor_theme, "hand1");
gabomdq@8062
   270
        break;
gabomdq@8062
   271
    case SDL_SYSTEM_CURSOR_SIZENESW:
gabomdq@8104
   272
        cursor = WAYLAND_wl_cursor_theme_get_cursor(d->cursor_theme, "hand1");
gabomdq@8062
   273
        break;
gabomdq@8062
   274
    case SDL_SYSTEM_CURSOR_SIZEWE:
gabomdq@8104
   275
        cursor = WAYLAND_wl_cursor_theme_get_cursor(d->cursor_theme, "hand1");
gabomdq@8062
   276
        break;
gabomdq@8062
   277
    case SDL_SYSTEM_CURSOR_SIZENS:
gabomdq@8104
   278
        cursor = WAYLAND_wl_cursor_theme_get_cursor(d->cursor_theme, "hand1");
gabomdq@8062
   279
        break;
gabomdq@8062
   280
    case SDL_SYSTEM_CURSOR_SIZEALL:
gabomdq@8104
   281
        cursor = WAYLAND_wl_cursor_theme_get_cursor(d->cursor_theme, "hand1");
gabomdq@8062
   282
        break;
gabomdq@8062
   283
    case SDL_SYSTEM_CURSOR_NO:
gabomdq@8104
   284
        cursor = WAYLAND_wl_cursor_theme_get_cursor(d->cursor_theme, "xterm");
gabomdq@8062
   285
        break;
gabomdq@8062
   286
    case SDL_SYSTEM_CURSOR_HAND:
gabomdq@8104
   287
        cursor = WAYLAND_wl_cursor_theme_get_cursor(d->cursor_theme, "hand1");
gabomdq@8062
   288
        break;
gabomdq@8062
   289
    }
gabomdq@8062
   290
icculus@8721
   291
    return CreateCursorFromWlCursor(d, cursor);
gabomdq@8062
   292
}
gabomdq@8062
   293
gabomdq@8062
   294
static void
gabomdq@8062
   295
Wayland_FreeCursor(SDL_Cursor *cursor)
gabomdq@8062
   296
{
icculus@8721
   297
    Wayland_CursorData *d;
icculus@8721
   298
gabomdq@8062
   299
    if (!cursor)
gabomdq@8062
   300
        return;
gabomdq@8062
   301
icculus@8721
   302
    d = cursor->driverdata;
gabomdq@8062
   303
gabomdq@8062
   304
    /* Probably not a cursor we own */
gabomdq@8062
   305
    if (!d)
gabomdq@8062
   306
        return;
gabomdq@8062
   307
slouken@8711
   308
    if (d->buffer && !d->cursor)
gabomdq@8062
   309
        wl_buffer_destroy(d->buffer);
gabomdq@8062
   310
gabomdq@8062
   311
    if (d->surface)
gabomdq@8062
   312
        wl_surface_destroy(d->surface);
gabomdq@8062
   313
gabomdq@8062
   314
    /* Not sure what's meant to happen to shm_data */
gabomdq@8062
   315
    free (cursor->driverdata);
gabomdq@8062
   316
    SDL_free(cursor);
gabomdq@8062
   317
}
gabomdq@8062
   318
gabomdq@8062
   319
static int
gabomdq@8062
   320
Wayland_ShowCursor(SDL_Cursor *cursor)
gabomdq@8062
   321
{
gabomdq@8062
   322
    SDL_VideoDevice *vd = SDL_GetVideoDevice();
gabomdq@8062
   323
    SDL_VideoData *d = vd->driverdata;
gabomdq@8062
   324
gabomdq@8062
   325
    struct wl_pointer *pointer = d->pointer;
gabomdq@8062
   326
gabomdq@8062
   327
    if (!pointer)
gabomdq@8062
   328
        return -1;
gabomdq@8062
   329
gabomdq@8062
   330
    if (cursor)
gabomdq@8062
   331
    {
gabomdq@8062
   332
        Wayland_CursorData *data = cursor->driverdata;
gabomdq@8062
   333
gabomdq@8062
   334
        wl_pointer_set_cursor (pointer, 0,
gabomdq@8062
   335
                               data->surface,
gabomdq@8062
   336
                               data->hot_x,
gabomdq@8062
   337
                               data->hot_y);
philipp@10113
   338
        wl_surface_attach(data->surface, data->buffer, 0, 0);
philipp@10113
   339
        wl_surface_damage(data->surface, 0, 0, data->w, data->h);
philipp@10113
   340
        wl_surface_commit(data->surface);
gabomdq@8062
   341
    }
gabomdq@8062
   342
    else
gabomdq@8062
   343
    {
gabomdq@8062
   344
        wl_pointer_set_cursor (pointer, 0,
gabomdq@8062
   345
                               NULL,
gabomdq@8062
   346
                               0,
gabomdq@8062
   347
                               0);
gabomdq@8062
   348
    }
gabomdq@8062
   349
    
gabomdq@8062
   350
    return 0;
gabomdq@8062
   351
}
gabomdq@8062
   352
gabomdq@8062
   353
static void
gabomdq@8062
   354
Wayland_WarpMouse(SDL_Window *window, int x, int y)
gabomdq@8062
   355
{
gabomdq@8062
   356
    SDL_Unsupported();
slouken@8815
   357
}
slouken@8815
   358
icculus@9807
   359
static int
slouken@8815
   360
Wayland_WarpMouseGlobal(int x, int y)
slouken@8815
   361
{
icculus@9807
   362
    return SDL_Unsupported();
gabomdq@8062
   363
}
gabomdq@8062
   364
gabomdq@8062
   365
static int
gabomdq@8062
   366
Wayland_SetRelativeMouseMode(SDL_bool enabled)
gabomdq@8062
   367
{
slouken@10304
   368
    SDL_VideoDevice *vd = SDL_GetVideoDevice();
slouken@10304
   369
    SDL_VideoData *data = (SDL_VideoData *) vd->driverdata;
slouken@10304
   370
slouken@10304
   371
    if (enabled)
slouken@10304
   372
        return Wayland_input_lock_pointer(data->input);
slouken@10304
   373
    else
slouken@10304
   374
        return Wayland_input_unlock_pointer(data->input);
gabomdq@8062
   375
}
gabomdq@8062
   376
gabomdq@8062
   377
void
gabomdq@8062
   378
Wayland_InitMouse(void)
gabomdq@8062
   379
{
gabomdq@8062
   380
    SDL_Mouse *mouse = SDL_GetMouse();
gabomdq@8062
   381
gabomdq@8062
   382
    mouse->CreateCursor = Wayland_CreateCursor;
gabomdq@8062
   383
    mouse->CreateSystemCursor = Wayland_CreateSystemCursor;
gabomdq@8062
   384
    mouse->ShowCursor = Wayland_ShowCursor;
gabomdq@8062
   385
    mouse->FreeCursor = Wayland_FreeCursor;
gabomdq@8062
   386
    mouse->WarpMouse = Wayland_WarpMouse;
slouken@8815
   387
    mouse->WarpMouseGlobal = Wayland_WarpMouseGlobal;
gabomdq@8062
   388
    mouse->SetRelativeMouseMode = Wayland_SetRelativeMouseMode;
gabomdq@8062
   389
gabomdq@8062
   390
    SDL_SetDefaultCursor(Wayland_CreateDefaultCursor());
gabomdq@8062
   391
}
gabomdq@8062
   392
gabomdq@8062
   393
void
gabomdq@8062
   394
Wayland_FiniMouse(void)
gabomdq@8062
   395
{
gabomdq@8062
   396
    /* This effectively assumes that nobody else
gabomdq@8062
   397
     * touches SDL_Mouse which is effectively
gabomdq@8062
   398
     * a singleton */
gabomdq@8062
   399
gabomdq@8062
   400
    SDL_Mouse *mouse = SDL_GetMouse();
gabomdq@8062
   401
gabomdq@8062
   402
    /* Free the current cursor if not the same pointer as
gabomdq@8062
   403
     * the default cursor */
gabomdq@8062
   404
    if (mouse->def_cursor != mouse->cur_cursor)
gabomdq@8062
   405
        Wayland_FreeCursor (mouse->cur_cursor);
gabomdq@8062
   406
gabomdq@8062
   407
    Wayland_FreeCursor (mouse->def_cursor);
gabomdq@8062
   408
    mouse->def_cursor = NULL;
gabomdq@8062
   409
    mouse->cur_cursor = NULL;
gabomdq@8062
   410
gabomdq@8062
   411
    mouse->CreateCursor =  NULL;
gabomdq@8062
   412
    mouse->CreateSystemCursor = NULL;
gabomdq@8062
   413
    mouse->ShowCursor = NULL;
gabomdq@8062
   414
    mouse->FreeCursor = NULL;
gabomdq@8062
   415
    mouse->WarpMouse = NULL;
gabomdq@8062
   416
    mouse->SetRelativeMouseMode = NULL;
gabomdq@8062
   417
}
icculus@8116
   418
#endif  /* SDL_VIDEO_DRIVER_WAYLAND */