src/video/wayland/SDL_waylandwindow.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
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
     4 
     5   This software is provided 'as-is', without any express or implied
     6   warranty.  In no event will the authors be held liable for any damages
     7   arising from the use of this software.
     8 
     9   Permission is granted to anyone to use this software for any purpose,
    10   including commercial applications, and to alter it and redistribute it
    11   freely, subject to the following restrictions:
    12 
    13   1. The origin of this software must not be misrepresented; you must not
    14      claim that you wrote the original software. If you use this software
    15      in a product, an acknowledgment in the product documentation would be
    16      appreciated but is not required.
    17   2. Altered source versions must be plainly marked as such, and must not be
    18      misrepresented as being the original software.
    19   3. This notice may not be removed or altered from any source distribution.
    20 */
    21 
    22 #include "../../SDL_internal.h"
    23 
    24 #include "../SDL_sysvideo.h"
    25 #include "../../events/SDL_windowevents_c.h"
    26 #include "../SDL_egl_c.h"
    27 #include "SDL_waylandwindow.h"
    28 #include "SDL_waylandvideo.h"
    29 #include "SDL_waylandtouch.h"
    30 
    31 static void
    32 handle_ping(void *data, struct wl_shell_surface *shell_surface,
    33             uint32_t serial)
    34 {
    35     wl_shell_surface_pong(shell_surface, serial);
    36 }
    37 
    38 static void
    39 handle_configure(void *data, struct wl_shell_surface *shell_surface,
    40                  uint32_t edges, int32_t width, int32_t height)
    41 {
    42 }
    43 
    44 static void
    45 handle_popup_done(void *data, struct wl_shell_surface *shell_surface)
    46 {
    47 }
    48 
    49 static const struct wl_shell_surface_listener shell_surface_listener = {
    50     handle_ping,
    51     handle_configure,
    52     handle_popup_done
    53 };
    54 
    55 #ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
    56 static void
    57 handle_onscreen_visibility(void *data,
    58         struct qt_extended_surface *qt_extended_surface, int32_t visible)
    59 {
    60 }
    61 
    62 static void
    63 handle_set_generic_property(void *data,
    64         struct qt_extended_surface *qt_extended_surface, const char *name,
    65         struct wl_array *value)
    66 {
    67 }
    68 
    69 static void
    70 handle_close(void *data, struct qt_extended_surface *qt_extended_surface)
    71 {
    72     SDL_WindowData *window = (SDL_WindowData *)data;
    73     SDL_SendWindowEvent(window->sdlwindow, SDL_WINDOWEVENT_CLOSE, 0, 0);
    74 }
    75 
    76 static const struct qt_extended_surface_listener extended_surface_listener = {
    77     handle_onscreen_visibility,
    78     handle_set_generic_property,
    79     handle_close,
    80 };
    81 #endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
    82 
    83 SDL_bool
    84 Wayland_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
    85 {
    86     SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
    87 
    88     info->info.wl.display = data->waylandData->display;
    89     info->info.wl.surface = data->surface;
    90     info->info.wl.shell_surface = data->shell_surface;
    91     info->subsystem = SDL_SYSWM_WAYLAND;
    92 
    93     return SDL_TRUE;
    94 }
    95 
    96 void Wayland_ShowWindow(_THIS, SDL_Window *window)
    97 {
    98     SDL_WindowData *wind = window->driverdata;
    99 
   100     if (window->flags & SDL_WINDOW_FULLSCREEN)
   101         wl_shell_surface_set_fullscreen(wind->shell_surface,
   102                                         WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,
   103                                         0, NULL);
   104     else
   105         wl_shell_surface_set_toplevel(wind->shell_surface);
   106 
   107     WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display );
   108 }
   109 
   110 void
   111 Wayland_SetWindowFullscreen(_THIS, SDL_Window * window,
   112                             SDL_VideoDisplay * _display, SDL_bool fullscreen)
   113 {
   114     SDL_WindowData *wind = window->driverdata;
   115 
   116     if (fullscreen)
   117         wl_shell_surface_set_fullscreen(wind->shell_surface,
   118                                         WL_SHELL_SURFACE_FULLSCREEN_METHOD_SCALE,
   119                                         0, NULL);
   120     else
   121         wl_shell_surface_set_toplevel(wind->shell_surface);
   122 
   123     WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display );
   124 }
   125 
   126 int Wayland_CreateWindow(_THIS, SDL_Window *window)
   127 {
   128     SDL_WindowData *data;
   129     SDL_VideoData *c;
   130     struct wl_region *region;
   131 
   132     data = calloc(1, sizeof *data);
   133     if (data == NULL)
   134         return 0;
   135 
   136     c = _this->driverdata;
   137     window->driverdata = data;
   138 
   139     if (!(window->flags & SDL_WINDOW_OPENGL)) {
   140         SDL_GL_LoadLibrary(NULL);
   141         window->flags |= SDL_WINDOW_OPENGL;
   142     }
   143 
   144     if (window->x == SDL_WINDOWPOS_UNDEFINED) {
   145         window->x = 0;
   146     }
   147     if (window->y == SDL_WINDOWPOS_UNDEFINED) {
   148         window->y = 0;
   149     }
   150 
   151     data->waylandData = c;
   152     data->sdlwindow = window;
   153 
   154     data->surface =
   155         wl_compositor_create_surface(c->compositor);
   156     wl_surface_set_user_data(data->surface, data);
   157     data->shell_surface = wl_shell_get_shell_surface(c->shell,
   158                                                      data->surface);
   159 #ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH    
   160     if (c->surface_extension) {
   161         data->extended_surface = qt_surface_extension_get_extended_surface(
   162                 c->surface_extension, data->surface);
   163     }
   164 #endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
   165     data->egl_window = WAYLAND_wl_egl_window_create(data->surface,
   166                                             window->w, window->h);
   167 
   168     /* Create the GLES window surface */
   169     data->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) data->egl_window);
   170     
   171     if (data->egl_surface == EGL_NO_SURFACE) {
   172         SDL_SetError("failed to create a window surface");
   173         return -1;
   174     }
   175 
   176     if (data->shell_surface) {
   177         wl_shell_surface_set_user_data(data->shell_surface, data);
   178         wl_shell_surface_add_listener(data->shell_surface,
   179                                       &shell_surface_listener, data);
   180     }
   181 
   182 #ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
   183     if (data->extended_surface) {
   184         qt_extended_surface_set_user_data(data->extended_surface, data);
   185         qt_extended_surface_add_listener(data->extended_surface,
   186                                          &extended_surface_listener, data);
   187     }
   188 #endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
   189 
   190     region = wl_compositor_create_region(c->compositor);
   191     wl_region_add(region, 0, 0, window->w, window->h);
   192     wl_surface_set_opaque_region(data->surface, region);
   193     wl_region_destroy(region);
   194 
   195     WAYLAND_wl_display_flush(c->display);
   196 
   197     return 0;
   198 }
   199 
   200 void Wayland_SetWindowSize(_THIS, SDL_Window * window)
   201 {
   202     SDL_VideoData *data = _this->driverdata;
   203     SDL_WindowData *wind = window->driverdata;
   204     struct wl_region *region;
   205 
   206     WAYLAND_wl_egl_window_resize(wind->egl_window, window->w, window->h, 0, 0);
   207 
   208     region =wl_compositor_create_region(data->compositor);
   209     wl_region_add(region, 0, 0, window->w, window->h);
   210     wl_surface_set_opaque_region(wind->surface, region);
   211     wl_region_destroy(region);
   212 }
   213 
   214 void Wayland_DestroyWindow(_THIS, SDL_Window *window)
   215 {
   216     SDL_VideoData *data = _this->driverdata;
   217     SDL_WindowData *wind = window->driverdata;
   218 
   219     window->driverdata = NULL;
   220 
   221     if (data) {
   222         SDL_EGL_DestroySurface(_this, wind->egl_surface);
   223         WAYLAND_wl_egl_window_destroy(wind->egl_window);
   224 
   225         if (wind->shell_surface)
   226             wl_shell_surface_destroy(wind->shell_surface);
   227 
   228 #ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
   229         if (wind->extended_surface)
   230             qt_extended_surface_destroy(wind->extended_surface);
   231 #endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
   232         wl_surface_destroy(wind->surface);
   233 
   234         SDL_free(wind);
   235         WAYLAND_wl_display_flush(data->display);
   236     }
   237 }
   238 
   239 /* vi: set ts=4 sw=4 expandtab: */