src/video/wayland/SDL_waylandvideo.c
author Gabriel Jacobo <gabomdq@gmail.com>
Thu, 09 Jan 2014 13:56:21 -0300
changeset 8104 2e4f1bd21196
parent 8082 5b83ad3f01ac
child 8116 f7c2f71251e5
permissions -rw-r--r--
Dynamic loading support for Wayland
gabomdq@8062
     1
/*
gabomdq@8062
     2
  Simple DirectMedia Layer
gabomdq@8062
     3
  Copyright (C) 1997-2013 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
gabomdq@8104
    22
#include "../../SDL_internal.h"
gabomdq@8062
    23
gabomdq@8062
    24
#include "SDL_video.h"
gabomdq@8062
    25
#include "SDL_mouse.h"
gabomdq@8104
    26
#include "SDL_stdinc.h"
gabomdq@8062
    27
#include "../../events/SDL_events_c.h"
gabomdq@8062
    28
gabomdq@8062
    29
#include "SDL_waylandvideo.h"
gabomdq@8062
    30
#include "SDL_waylandevents_c.h"
gabomdq@8062
    31
#include "SDL_waylandwindow.h"
gabomdq@8062
    32
#include "SDL_waylandopengles.h"
gabomdq@8062
    33
#include "SDL_waylandmouse.h"
gabomdq@8082
    34
#include "SDL_waylandtouch.h"
gabomdq@8062
    35
gabomdq@8062
    36
#include <fcntl.h>
gabomdq@8062
    37
#include <xkbcommon/xkbcommon.h>
gabomdq@8062
    38
gabomdq@8104
    39
#include "SDL_waylanddyn.h"
gabomdq@8104
    40
#include <wayland-util.h>
gabomdq@8104
    41
gabomdq@8062
    42
#define WAYLANDVID_DRIVER_NAME "wayland"
gabomdq@8062
    43
gabomdq@8062
    44
struct wayland_mode {
gabomdq@8062
    45
    SDL_DisplayMode mode;
gabomdq@8062
    46
    struct wl_list link;
gabomdq@8062
    47
};
gabomdq@8062
    48
gabomdq@8062
    49
/* Initialization/Query functions */
gabomdq@8062
    50
static int
gabomdq@8062
    51
Wayland_VideoInit(_THIS);
gabomdq@8062
    52
gabomdq@8062
    53
static void
gabomdq@8062
    54
Wayland_GetDisplayModes(_THIS, SDL_VideoDisplay *sdl_display);
gabomdq@8062
    55
static int
gabomdq@8062
    56
Wayland_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode);
gabomdq@8062
    57
gabomdq@8062
    58
static void
gabomdq@8062
    59
Wayland_VideoQuit(_THIS);
gabomdq@8062
    60
gabomdq@8062
    61
/* Wayland driver bootstrap functions */
gabomdq@8062
    62
static int
gabomdq@8062
    63
Wayland_Available(void)
gabomdq@8062
    64
{
gabomdq@8062
    65
    struct wl_display *display = NULL;
gabomdq@8104
    66
    if (SDL_WAYLAND_LoadSymbols()) {
gabomdq@8104
    67
        display = WAYLAND_wl_display_connect(NULL);
gabomdq@8104
    68
        if (display != NULL) {
gabomdq@8104
    69
            WAYLAND_wl_display_disconnect(display);
gabomdq@8104
    70
        }
gabomdq@8104
    71
        SDL_WAYLAND_UnloadSymbols();
gabomdq@8062
    72
    }
gabomdq@8062
    73
gabomdq@8062
    74
    return (display != NULL);
gabomdq@8062
    75
}
gabomdq@8062
    76
gabomdq@8062
    77
static void
gabomdq@8062
    78
Wayland_DeleteDevice(SDL_VideoDevice *device)
gabomdq@8062
    79
{
gabomdq@8062
    80
    SDL_free(device);
gabomdq@8104
    81
    SDL_WAYLAND_UnloadSymbols();
gabomdq@8062
    82
}
gabomdq@8062
    83
gabomdq@8062
    84
static SDL_VideoDevice *
gabomdq@8062
    85
Wayland_CreateDevice(int devindex)
gabomdq@8062
    86
{
gabomdq@8062
    87
    SDL_VideoDevice *device;
gabomdq@8104
    88
    
gabomdq@8104
    89
    if (!SDL_WAYLAND_LoadSymbols()) {
gabomdq@8104
    90
        return NULL;
gabomdq@8104
    91
    }
gabomdq@8062
    92
gabomdq@8062
    93
    /* Initialize all variables that we clean on shutdown */
gabomdq@8062
    94
    device = SDL_calloc(1, sizeof(SDL_VideoDevice));
gabomdq@8062
    95
    if (!device) {
gabomdq@8062
    96
        SDL_OutOfMemory();
gabomdq@8062
    97
        return NULL;
gabomdq@8062
    98
    }
gabomdq@8062
    99
gabomdq@8062
   100
    /* Set the function pointers */
gabomdq@8062
   101
    device->VideoInit = Wayland_VideoInit;
gabomdq@8062
   102
    device->VideoQuit = Wayland_VideoQuit;
gabomdq@8062
   103
    device->SetDisplayMode = Wayland_SetDisplayMode;
gabomdq@8062
   104
    device->GetDisplayModes = Wayland_GetDisplayModes;
gabomdq@8062
   105
    device->GetWindowWMInfo = Wayland_GetWindowWMInfo;
gabomdq@8062
   106
gabomdq@8062
   107
    device->PumpEvents = Wayland_PumpEvents;
gabomdq@8062
   108
gabomdq@8062
   109
    device->GL_SwapWindow = Wayland_GLES_SwapWindow;
gabomdq@8062
   110
    device->GL_GetSwapInterval = Wayland_GLES_GetSwapInterval;
gabomdq@8062
   111
    device->GL_SetSwapInterval = Wayland_GLES_SetSwapInterval;
gabomdq@8062
   112
    device->GL_MakeCurrent = Wayland_GLES_MakeCurrent;
gabomdq@8062
   113
    device->GL_CreateContext = Wayland_GLES_CreateContext;
gabomdq@8062
   114
    device->GL_LoadLibrary = Wayland_GLES_LoadLibrary;
gabomdq@8062
   115
    device->GL_UnloadLibrary = Wayland_GLES_UnloadLibrary;
gabomdq@8062
   116
    device->GL_GetProcAddress = Wayland_GLES_GetProcAddress;
gabomdq@8062
   117
    device->GL_DeleteContext = Wayland_GLES_DeleteContext;
gabomdq@8062
   118
gabomdq@8062
   119
    device->CreateWindow = Wayland_CreateWindow;
gabomdq@8062
   120
    device->ShowWindow = Wayland_ShowWindow;
gabomdq@8062
   121
    device->SetWindowFullscreen = Wayland_SetWindowFullscreen;
gabomdq@8062
   122
    device->SetWindowSize = Wayland_SetWindowSize;
gabomdq@8062
   123
    device->DestroyWindow = Wayland_DestroyWindow;
gabomdq@8062
   124
gabomdq@8062
   125
    device->free = Wayland_DeleteDevice;
gabomdq@8062
   126
gabomdq@8062
   127
    return device;
gabomdq@8062
   128
}
gabomdq@8062
   129
gabomdq@8062
   130
VideoBootStrap Wayland_bootstrap = {
gabomdq@8062
   131
    WAYLANDVID_DRIVER_NAME, "SDL Wayland video driver",
gabomdq@8062
   132
    Wayland_Available, Wayland_CreateDevice
gabomdq@8062
   133
};
gabomdq@8062
   134
gabomdq@8062
   135
static void
gabomdq@8062
   136
wayland_add_mode(SDL_VideoData *d, SDL_DisplayMode m)
gabomdq@8062
   137
{
gabomdq@8062
   138
    struct wayland_mode *mode;
gabomdq@8062
   139
gabomdq@8062
   140
    /* Check for duplicate mode */
gabomdq@8062
   141
    wl_list_for_each(mode, &d->modes_list, link)
gabomdq@8062
   142
        if (mode->mode.w == m.w && mode->mode.h == m.h &&
gabomdq@8062
   143
	    mode->mode.refresh_rate == m.refresh_rate)
gabomdq@8062
   144
	    return;
gabomdq@8062
   145
gabomdq@8062
   146
    /* Add new mode to the list */
gabomdq@8104
   147
    mode = (struct wayland_mode *) SDL_calloc(1, sizeof *mode);
gabomdq@8062
   148
gabomdq@8062
   149
    if (!mode)
gabomdq@8062
   150
	return;
gabomdq@8062
   151
gabomdq@8062
   152
    mode->mode = m;
gabomdq@8104
   153
    WAYLAND_wl_list_insert(&d->modes_list, &mode->link);
gabomdq@8062
   154
}
gabomdq@8062
   155
gabomdq@8062
   156
static void
gabomdq@8062
   157
display_handle_geometry(void *data,
gabomdq@8062
   158
                        struct wl_output *output,
gabomdq@8062
   159
                        int x, int y,
gabomdq@8062
   160
                        int physical_width,
gabomdq@8062
   161
                        int physical_height,
gabomdq@8062
   162
                        int subpixel,
gabomdq@8062
   163
                        const char *make,
gabomdq@8062
   164
                        const char *model,
gabomdq@8062
   165
                        int transform)
gabomdq@8062
   166
gabomdq@8062
   167
{
gabomdq@8062
   168
    SDL_VideoData *d = data;
gabomdq@8062
   169
gabomdq@8062
   170
    d->screen_allocation.x = x;
gabomdq@8062
   171
    d->screen_allocation.y = y;
gabomdq@8062
   172
}
gabomdq@8062
   173
gabomdq@8062
   174
static void
gabomdq@8062
   175
display_handle_mode(void *data,
gabomdq@8062
   176
                    struct wl_output *wl_output,
gabomdq@8062
   177
                    uint32_t flags,
gabomdq@8062
   178
                    int width,
gabomdq@8062
   179
                    int height,
gabomdq@8062
   180
                    int refresh)
gabomdq@8062
   181
{
gabomdq@8062
   182
    SDL_VideoData *d = data;
gabomdq@8062
   183
    SDL_DisplayMode mode;
gabomdq@8062
   184
gabomdq@8062
   185
    SDL_zero(mode);
gabomdq@8062
   186
    mode.w = width;
gabomdq@8062
   187
    mode.h = height;
gabomdq@8062
   188
    mode.refresh_rate = refresh / 1000;
gabomdq@8062
   189
gabomdq@8062
   190
    wayland_add_mode(d, mode);
gabomdq@8062
   191
gabomdq@8062
   192
    if (flags & WL_OUTPUT_MODE_CURRENT) {
gabomdq@8062
   193
        d->screen_allocation.width = width;
gabomdq@8062
   194
        d->screen_allocation.height = height;
gabomdq@8062
   195
    }
gabomdq@8062
   196
}
gabomdq@8062
   197
gabomdq@8062
   198
static const struct wl_output_listener output_listener = {
gabomdq@8062
   199
    display_handle_geometry,
gabomdq@8062
   200
    display_handle_mode
gabomdq@8062
   201
};
gabomdq@8062
   202
gabomdq@8062
   203
static void
gabomdq@8062
   204
shm_handle_format(void *data,
gabomdq@8062
   205
                  struct wl_shm *shm,
gabomdq@8062
   206
                  uint32_t format)
gabomdq@8062
   207
{
gabomdq@8062
   208
    SDL_VideoData *d = data;
gabomdq@8062
   209
gabomdq@8062
   210
    d->shm_formats |= (1 << format);
gabomdq@8062
   211
}
gabomdq@8062
   212
gabomdq@8062
   213
static const struct wl_shm_listener shm_listener = {
gabomdq@8062
   214
    shm_handle_format
gabomdq@8062
   215
};
gabomdq@8062
   216
gabomdq@8082
   217
#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
gabomdq@8082
   218
static void
gabomdq@8082
   219
windowmanager_hints(void *data, struct qt_windowmanager *qt_windowmanager,
gabomdq@8082
   220
        int32_t show_is_fullscreen)
gabomdq@8082
   221
{
gabomdq@8082
   222
}
gabomdq@8082
   223
gabomdq@8082
   224
static void
gabomdq@8082
   225
windowmanager_quit(void *data, struct qt_windowmanager *qt_windowmanager)
gabomdq@8082
   226
{
gabomdq@8082
   227
    SDL_SendQuit();
gabomdq@8082
   228
}
gabomdq@8082
   229
gabomdq@8082
   230
static const struct qt_windowmanager_listener windowmanager_listener = {
gabomdq@8082
   231
    windowmanager_hints,
gabomdq@8082
   232
    windowmanager_quit,
gabomdq@8082
   233
};
gabomdq@8082
   234
#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
gabomdq@8082
   235
gabomdq@8062
   236
static void
gabomdq@8062
   237
display_handle_global(void *data, struct wl_registry *registry, uint32_t id,
gabomdq@8062
   238
					const char *interface, uint32_t version)
gabomdq@8062
   239
{
gabomdq@8062
   240
    SDL_VideoData *d = data;
gabomdq@8104
   241
    
gabomdq@8062
   242
    if (strcmp(interface, "wl_compositor") == 0) {
gabomdq@8062
   243
        d->compositor = wl_registry_bind(d->registry, id, &wl_compositor_interface, 1);
gabomdq@8062
   244
    } else if (strcmp(interface, "wl_output") == 0) {
gabomdq@8062
   245
        d->output = wl_registry_bind(d->registry, id, &wl_output_interface, 1);
gabomdq@8062
   246
        wl_output_add_listener(d->output, &output_listener, d);
gabomdq@8062
   247
    } else if (strcmp(interface, "wl_seat") == 0) {
gabomdq@8062
   248
        Wayland_display_add_input(d, id);
gabomdq@8062
   249
    } else if (strcmp(interface, "wl_shell") == 0) {
gabomdq@8062
   250
        d->shell = wl_registry_bind(d->registry, id, &wl_shell_interface, 1);
gabomdq@8062
   251
    } else if (strcmp(interface, "wl_shm") == 0) {
gabomdq@8062
   252
        d->shm = wl_registry_bind(registry, id, &wl_shm_interface, 1);
gabomdq@8104
   253
        d->cursor_theme = WAYLAND_wl_cursor_theme_load(NULL, 32, d->shm);
gabomdq@8104
   254
        d->default_cursor = WAYLAND_wl_cursor_theme_get_cursor(d->cursor_theme, "left_ptr");
gabomdq@8062
   255
        wl_shm_add_listener(d->shm, &shm_listener, d);
gabomdq@8082
   256
    
gabomdq@8082
   257
#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
gabomdq@8082
   258
    } else if (strcmp(interface, "qt_touch_extension") == 0) {
gabomdq@8082
   259
        Wayland_touch_create(d, id);
gabomdq@8082
   260
    } else if (strcmp(interface, "qt_surface_extension") == 0) {
gabomdq@8082
   261
        d->surface_extension = wl_registry_bind(registry, id,
gabomdq@8082
   262
                &qt_surface_extension_interface, 1);
gabomdq@8082
   263
    } else if (strcmp(interface, "qt_windowmanager") == 0) {
gabomdq@8082
   264
        d->windowmanager = wl_registry_bind(registry, id,
gabomdq@8082
   265
                &qt_windowmanager_interface, 1);
gabomdq@8082
   266
        qt_windowmanager_add_listener(d->windowmanager, &windowmanager_listener, d);
gabomdq@8082
   267
#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
gabomdq@8062
   268
    }
gabomdq@8062
   269
}
gabomdq@8062
   270
gabomdq@8062
   271
static const struct wl_registry_listener registry_listener = {
gabomdq@8062
   272
	display_handle_global
gabomdq@8062
   273
};
gabomdq@8062
   274
gabomdq@8062
   275
int
gabomdq@8062
   276
Wayland_VideoInit(_THIS)
gabomdq@8062
   277
{
gabomdq@8062
   278
    SDL_VideoData *data;
gabomdq@8104
   279
    SDL_VideoDisplay display;
gabomdq@8104
   280
    SDL_DisplayMode mode;
gabomdq@8104
   281
    int i;
gabomdq@8104
   282
    
gabomdq@8062
   283
    data = malloc(sizeof *data);
gabomdq@8062
   284
    if (data == NULL)
gabomdq@8062
   285
        return 0;
gabomdq@8062
   286
    memset(data, 0, sizeof *data);
gabomdq@8062
   287
gabomdq@8062
   288
    _this->driverdata = data;
gabomdq@8062
   289
gabomdq@8104
   290
    WAYLAND_wl_list_init(&data->modes_list);
gabomdq@8062
   291
    
gabomdq@8104
   292
    data->display = WAYLAND_wl_display_connect(NULL);
gabomdq@8062
   293
    if (data->display == NULL) {
gabomdq@8062
   294
        SDL_SetError("Failed to connect to a Wayland display");
gabomdq@8062
   295
        return 0;
gabomdq@8062
   296
    }
gabomdq@8062
   297
gabomdq@8062
   298
    data->registry = wl_display_get_registry(data->display);
gabomdq@8104
   299
   
gabomdq@8104
   300
    if ( data->registry == NULL) {
gabomdq@8104
   301
        SDL_SetError("Failed to get the Wayland registry");
gabomdq@8104
   302
        return 0;
gabomdq@8104
   303
    }
gabomdq@8104
   304
    
gabomdq@8062
   305
    wl_registry_add_listener(data->registry, &registry_listener, data);
gabomdq@8062
   306
gabomdq@8104
   307
    for (i=0; i < 100; i++) {
gabomdq@8104
   308
        if (data->screen_allocation.width != 0 || WAYLAND_wl_display_get_error(data->display) != 0) {
gabomdq@8104
   309
            break;
gabomdq@8104
   310
        }
gabomdq@8104
   311
        WAYLAND_wl_display_dispatch(data->display);
gabomdq@8104
   312
    }
gabomdq@8104
   313
    
gabomdq@8104
   314
    if (data->screen_allocation.width == 0) {
gabomdq@8104
   315
        SDL_SetError("Failed while waiting for screen allocation: %d ", WAYLAND_wl_display_get_error(data->display));
gabomdq@8104
   316
        return 0;
gabomdq@8104
   317
    }
gabomdq@8062
   318
gabomdq@8104
   319
    data->xkb_context = WAYLAND_xkb_context_new(0);
gabomdq@8062
   320
    if (!data->xkb_context) {
gabomdq@8062
   321
        SDL_SetError("Failed to create XKB context");
gabomdq@8062
   322
        return 0;
gabomdq@8062
   323
    }
gabomdq@8062
   324
gabomdq@8062
   325
    /* Use a fake 32-bpp desktop mode */
gabomdq@8062
   326
    mode.format = SDL_PIXELFORMAT_RGB888;
gabomdq@8062
   327
    mode.w = data->screen_allocation.width;
gabomdq@8062
   328
    mode.h = data->screen_allocation.height;
gabomdq@8062
   329
    mode.refresh_rate = 0;
gabomdq@8062
   330
    mode.driverdata = NULL;
gabomdq@8062
   331
    wayland_add_mode(data, mode);
gabomdq@8062
   332
    SDL_zero(display);
gabomdq@8062
   333
    display.desktop_mode = mode;
gabomdq@8062
   334
    display.current_mode = mode;
gabomdq@8062
   335
    display.driverdata = NULL;
gabomdq@8062
   336
    SDL_AddVideoDisplay(&display);
gabomdq@8062
   337
gabomdq@8062
   338
    Wayland_InitMouse ();
gabomdq@8062
   339
gabomdq@8104
   340
    WAYLAND_wl_display_flush(data->display);
gabomdq@8062
   341
gabomdq@8062
   342
    return 0;
gabomdq@8062
   343
}
gabomdq@8062
   344
gabomdq@8062
   345
static void
gabomdq@8062
   346
Wayland_GetDisplayModes(_THIS, SDL_VideoDisplay *sdl_display)
gabomdq@8062
   347
{
gabomdq@8062
   348
    SDL_VideoData *data = _this->driverdata;
gabomdq@8062
   349
    SDL_DisplayMode mode;
gabomdq@8062
   350
    struct wayland_mode *m;
gabomdq@8062
   351
gabomdq@8062
   352
    Wayland_PumpEvents(_this);
gabomdq@8062
   353
gabomdq@8062
   354
    wl_list_for_each(m, &data->modes_list, link) {
gabomdq@8062
   355
        m->mode.format = SDL_PIXELFORMAT_RGB888;
gabomdq@8062
   356
        SDL_AddDisplayMode(sdl_display, &m->mode);
gabomdq@8062
   357
        m->mode.format = SDL_PIXELFORMAT_RGBA8888;
gabomdq@8062
   358
        SDL_AddDisplayMode(sdl_display, &m->mode);
gabomdq@8062
   359
    }
gabomdq@8062
   360
gabomdq@8062
   361
    mode.w = data->screen_allocation.width;
gabomdq@8062
   362
    mode.h = data->screen_allocation.height;
gabomdq@8062
   363
    mode.refresh_rate = 0;
gabomdq@8062
   364
    mode.driverdata = NULL;
gabomdq@8062
   365
gabomdq@8062
   366
    mode.format = SDL_PIXELFORMAT_RGB888;
gabomdq@8062
   367
    SDL_AddDisplayMode(sdl_display, &mode);
gabomdq@8062
   368
    mode.format = SDL_PIXELFORMAT_RGBA8888;
gabomdq@8062
   369
    SDL_AddDisplayMode(sdl_display, &mode);
gabomdq@8062
   370
}
gabomdq@8062
   371
gabomdq@8062
   372
static int
gabomdq@8062
   373
Wayland_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode)
gabomdq@8062
   374
{
gabomdq@8062
   375
    return 0;
gabomdq@8062
   376
}
gabomdq@8062
   377
gabomdq@8062
   378
void
gabomdq@8062
   379
Wayland_VideoQuit(_THIS)
gabomdq@8062
   380
{
gabomdq@8062
   381
    SDL_VideoData *data = _this->driverdata;
gabomdq@8062
   382
    struct wayland_mode *t, *m;
gabomdq@8062
   383
gabomdq@8062
   384
    Wayland_FiniMouse ();
gabomdq@8062
   385
gabomdq@8062
   386
    if (data->output)
gabomdq@8062
   387
        wl_output_destroy(data->output);
gabomdq@8062
   388
gabomdq@8062
   389
    Wayland_display_destroy_input(data);
gabomdq@8062
   390
gabomdq@8062
   391
    if (data->xkb_context) {
gabomdq@8104
   392
        WAYLAND_xkb_context_unref(data->xkb_context);
gabomdq@8062
   393
        data->xkb_context = NULL;
gabomdq@8062
   394
    }
gabomdq@8082
   395
#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
gabomdq@8082
   396
    if (data->windowmanager)
gabomdq@8082
   397
        qt_windowmanager_destroy(data->windowmanager);
gabomdq@8082
   398
gabomdq@8082
   399
    if (data->surface_extension)
gabomdq@8082
   400
        qt_surface_extension_destroy(data->surface_extension);
gabomdq@8082
   401
gabomdq@8082
   402
    Wayland_touch_destroy(data);
gabomdq@8082
   403
#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
gabomdq@8062
   404
gabomdq@8062
   405
    if (data->shm)
gabomdq@8062
   406
        wl_shm_destroy(data->shm);
gabomdq@8062
   407
gabomdq@8062
   408
    if (data->cursor_theme)
gabomdq@8104
   409
        WAYLAND_wl_cursor_theme_destroy(data->cursor_theme);
gabomdq@8062
   410
gabomdq@8062
   411
    if (data->shell)
gabomdq@8062
   412
        wl_shell_destroy(data->shell);
gabomdq@8062
   413
gabomdq@8062
   414
    if (data->compositor)
gabomdq@8062
   415
        wl_compositor_destroy(data->compositor);
gabomdq@8062
   416
gabomdq@8062
   417
    if (data->display) {
gabomdq@8104
   418
        WAYLAND_wl_display_flush(data->display);
gabomdq@8104
   419
        WAYLAND_wl_display_disconnect(data->display);
gabomdq@8062
   420
    }
gabomdq@8062
   421
    
gabomdq@8062
   422
    wl_list_for_each_safe(m, t, &data->modes_list, link) {
gabomdq@8104
   423
        WAYLAND_wl_list_remove(&m->link);
gabomdq@8062
   424
        free(m);
gabomdq@8062
   425
    }
gabomdq@8062
   426
gabomdq@8062
   427
gabomdq@8062
   428
    free(data);
gabomdq@8062
   429
    _this->driverdata = NULL;
gabomdq@8062
   430
}
gabomdq@8062
   431
gabomdq@8062
   432
/* vi: set ts=4 sw=4 expandtab: */