src/video/wayland/SDL_waylandvideo.c
changeset 8104 2e4f1bd21196
parent 8082 5b83ad3f01ac
child 8116 f7c2f71251e5
equal deleted inserted replaced
8103:d4a88c49247e 8104:2e4f1bd21196
    17   2. Altered source versions must be plainly marked as such, and must not be
    17   2. Altered source versions must be plainly marked as such, and must not be
    18      misrepresented as being the original software.
    18      misrepresented as being the original software.
    19   3. This notice may not be removed or altered from any source distribution.
    19   3. This notice may not be removed or altered from any source distribution.
    20 */
    20 */
    21 
    21 
    22 #include "SDL_config.h"
    22 #include "../../SDL_internal.h"
    23 
    23 
    24 #include "SDL_video.h"
    24 #include "SDL_video.h"
    25 #include "SDL_mouse.h"
    25 #include "SDL_mouse.h"
       
    26 #include "SDL_stdinc.h"
    26 #include "../../events/SDL_events_c.h"
    27 #include "../../events/SDL_events_c.h"
    27 
    28 
    28 #include "SDL_waylandvideo.h"
    29 #include "SDL_waylandvideo.h"
    29 #include "SDL_waylandevents_c.h"
    30 #include "SDL_waylandevents_c.h"
    30 #include "SDL_waylandwindow.h"
    31 #include "SDL_waylandwindow.h"
    33 #include "SDL_waylandtouch.h"
    34 #include "SDL_waylandtouch.h"
    34 
    35 
    35 #include <fcntl.h>
    36 #include <fcntl.h>
    36 #include <xkbcommon/xkbcommon.h>
    37 #include <xkbcommon/xkbcommon.h>
    37 
    38 
       
    39 #include "SDL_waylanddyn.h"
       
    40 #include <wayland-util.h>
       
    41 
    38 #define WAYLANDVID_DRIVER_NAME "wayland"
    42 #define WAYLANDVID_DRIVER_NAME "wayland"
    39 
    43 
    40 struct wayland_mode {
    44 struct wayland_mode {
    41     SDL_DisplayMode mode;
    45     SDL_DisplayMode mode;
    42     struct wl_list link;
    46     struct wl_list link;
    57 /* Wayland driver bootstrap functions */
    61 /* Wayland driver bootstrap functions */
    58 static int
    62 static int
    59 Wayland_Available(void)
    63 Wayland_Available(void)
    60 {
    64 {
    61     struct wl_display *display = NULL;
    65     struct wl_display *display = NULL;
    62 
    66     if (SDL_WAYLAND_LoadSymbols()) {
    63     display = wl_display_connect(NULL);
    67         display = WAYLAND_wl_display_connect(NULL);
    64     if (display != NULL) {
    68         if (display != NULL) {
    65         wl_display_disconnect(display);
    69             WAYLAND_wl_display_disconnect(display);
       
    70         }
       
    71         SDL_WAYLAND_UnloadSymbols();
    66     }
    72     }
    67 
    73 
    68     return (display != NULL);
    74     return (display != NULL);
    69 }
    75 }
    70 
    76 
    71 static void
    77 static void
    72 Wayland_DeleteDevice(SDL_VideoDevice *device)
    78 Wayland_DeleteDevice(SDL_VideoDevice *device)
    73 {
    79 {
    74     SDL_free(device);
    80     SDL_free(device);
       
    81     SDL_WAYLAND_UnloadSymbols();
    75 }
    82 }
    76 
    83 
    77 static SDL_VideoDevice *
    84 static SDL_VideoDevice *
    78 Wayland_CreateDevice(int devindex)
    85 Wayland_CreateDevice(int devindex)
    79 {
    86 {
    80     SDL_VideoDevice *device;
    87     SDL_VideoDevice *device;
       
    88     
       
    89     if (!SDL_WAYLAND_LoadSymbols()) {
       
    90         return NULL;
       
    91     }
    81 
    92 
    82     /* Initialize all variables that we clean on shutdown */
    93     /* Initialize all variables that we clean on shutdown */
    83     device = SDL_calloc(1, sizeof(SDL_VideoDevice));
    94     device = SDL_calloc(1, sizeof(SDL_VideoDevice));
    84     if (!device) {
    95     if (!device) {
    85         SDL_OutOfMemory();
    96         SDL_OutOfMemory();
   131         if (mode->mode.w == m.w && mode->mode.h == m.h &&
   142         if (mode->mode.w == m.w && mode->mode.h == m.h &&
   132 	    mode->mode.refresh_rate == m.refresh_rate)
   143 	    mode->mode.refresh_rate == m.refresh_rate)
   133 	    return;
   144 	    return;
   134 
   145 
   135     /* Add new mode to the list */
   146     /* Add new mode to the list */
   136     mode = SDL_calloc(1, sizeof *mode);
   147     mode = (struct wayland_mode *) SDL_calloc(1, sizeof *mode);
   137 
   148 
   138     if (!mode)
   149     if (!mode)
   139 	return;
   150 	return;
   140 
   151 
   141     mode->mode = m;
   152     mode->mode = m;
   142     wl_list_insert(&d->modes_list, &mode->link);
   153     WAYLAND_wl_list_insert(&d->modes_list, &mode->link);
   143 }
   154 }
   144 
   155 
   145 static void
   156 static void
   146 display_handle_geometry(void *data,
   157 display_handle_geometry(void *data,
   147                         struct wl_output *output,
   158                         struct wl_output *output,
   225 static void
   236 static void
   226 display_handle_global(void *data, struct wl_registry *registry, uint32_t id,
   237 display_handle_global(void *data, struct wl_registry *registry, uint32_t id,
   227 					const char *interface, uint32_t version)
   238 					const char *interface, uint32_t version)
   228 {
   239 {
   229     SDL_VideoData *d = data;
   240     SDL_VideoData *d = data;
   230 
   241     
   231     if (strcmp(interface, "wl_compositor") == 0) {
   242     if (strcmp(interface, "wl_compositor") == 0) {
   232         d->compositor = wl_registry_bind(d->registry, id, &wl_compositor_interface, 1);
   243         d->compositor = wl_registry_bind(d->registry, id, &wl_compositor_interface, 1);
   233     } else if (strcmp(interface, "wl_output") == 0) {
   244     } else if (strcmp(interface, "wl_output") == 0) {
   234         d->output = wl_registry_bind(d->registry, id, &wl_output_interface, 1);
   245         d->output = wl_registry_bind(d->registry, id, &wl_output_interface, 1);
   235         wl_output_add_listener(d->output, &output_listener, d);
   246         wl_output_add_listener(d->output, &output_listener, d);
   237         Wayland_display_add_input(d, id);
   248         Wayland_display_add_input(d, id);
   238     } else if (strcmp(interface, "wl_shell") == 0) {
   249     } else if (strcmp(interface, "wl_shell") == 0) {
   239         d->shell = wl_registry_bind(d->registry, id, &wl_shell_interface, 1);
   250         d->shell = wl_registry_bind(d->registry, id, &wl_shell_interface, 1);
   240     } else if (strcmp(interface, "wl_shm") == 0) {
   251     } else if (strcmp(interface, "wl_shm") == 0) {
   241         d->shm = wl_registry_bind(registry, id, &wl_shm_interface, 1);
   252         d->shm = wl_registry_bind(registry, id, &wl_shm_interface, 1);
   242         d->cursor_theme = wl_cursor_theme_load(NULL, 32, d->shm);
   253         d->cursor_theme = WAYLAND_wl_cursor_theme_load(NULL, 32, d->shm);
   243         d->default_cursor = wl_cursor_theme_get_cursor(d->cursor_theme, "left_ptr");
   254         d->default_cursor = WAYLAND_wl_cursor_theme_get_cursor(d->cursor_theme, "left_ptr");
   244         wl_shm_add_listener(d->shm, &shm_listener, d);
   255         wl_shm_add_listener(d->shm, &shm_listener, d);
   245     
   256     
   246 #ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
   257 #ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
   247     } else if (strcmp(interface, "qt_touch_extension") == 0) {
   258     } else if (strcmp(interface, "qt_touch_extension") == 0) {
   248         Wayland_touch_create(d, id);
   259         Wayland_touch_create(d, id);
   263 
   274 
   264 int
   275 int
   265 Wayland_VideoInit(_THIS)
   276 Wayland_VideoInit(_THIS)
   266 {
   277 {
   267     SDL_VideoData *data;
   278     SDL_VideoData *data;
   268 
   279     SDL_VideoDisplay display;
       
   280     SDL_DisplayMode mode;
       
   281     int i;
       
   282     
   269     data = malloc(sizeof *data);
   283     data = malloc(sizeof *data);
   270     if (data == NULL)
   284     if (data == NULL)
   271         return 0;
   285         return 0;
   272     memset(data, 0, sizeof *data);
   286     memset(data, 0, sizeof *data);
   273 
   287 
   274     _this->driverdata = data;
   288     _this->driverdata = data;
   275 
   289 
   276     wl_list_init(&data->modes_list);
   290     WAYLAND_wl_list_init(&data->modes_list);
   277     
   291     
   278     data->display = wl_display_connect(NULL);
   292     data->display = WAYLAND_wl_display_connect(NULL);
   279     if (data->display == NULL) {
   293     if (data->display == NULL) {
   280         SDL_SetError("Failed to connect to a Wayland display");
   294         SDL_SetError("Failed to connect to a Wayland display");
   281         return 0;
   295         return 0;
   282     }
   296     }
   283 
   297 
   284     data->registry = wl_display_get_registry(data->display);
   298     data->registry = wl_display_get_registry(data->display);
       
   299    
       
   300     if ( data->registry == NULL) {
       
   301         SDL_SetError("Failed to get the Wayland registry");
       
   302         return 0;
       
   303     }
       
   304     
   285     wl_registry_add_listener(data->registry, &registry_listener, data);
   305     wl_registry_add_listener(data->registry, &registry_listener, data);
   286 
   306 
   287     while (data->screen_allocation.width == 0)
   307     for (i=0; i < 100; i++) {
   288         wl_display_dispatch(data->display);
   308         if (data->screen_allocation.width != 0 || WAYLAND_wl_display_get_error(data->display) != 0) {
   289 
   309             break;
   290     data->xkb_context = xkb_context_new(0);
   310         }
       
   311         WAYLAND_wl_display_dispatch(data->display);
       
   312     }
       
   313     
       
   314     if (data->screen_allocation.width == 0) {
       
   315         SDL_SetError("Failed while waiting for screen allocation: %d ", WAYLAND_wl_display_get_error(data->display));
       
   316         return 0;
       
   317     }
       
   318 
       
   319     data->xkb_context = WAYLAND_xkb_context_new(0);
   291     if (!data->xkb_context) {
   320     if (!data->xkb_context) {
   292         SDL_SetError("Failed to create XKB context");
   321         SDL_SetError("Failed to create XKB context");
   293         return 0;
   322         return 0;
   294     }
   323     }
   295 
       
   296     SDL_VideoDisplay display;
       
   297     SDL_DisplayMode mode;
       
   298 
   324 
   299     /* Use a fake 32-bpp desktop mode */
   325     /* Use a fake 32-bpp desktop mode */
   300     mode.format = SDL_PIXELFORMAT_RGB888;
   326     mode.format = SDL_PIXELFORMAT_RGB888;
   301     mode.w = data->screen_allocation.width;
   327     mode.w = data->screen_allocation.width;
   302     mode.h = data->screen_allocation.height;
   328     mode.h = data->screen_allocation.height;
   309     display.driverdata = NULL;
   335     display.driverdata = NULL;
   310     SDL_AddVideoDisplay(&display);
   336     SDL_AddVideoDisplay(&display);
   311 
   337 
   312     Wayland_InitMouse ();
   338     Wayland_InitMouse ();
   313 
   339 
   314     wayland_schedule_write(data);
   340     WAYLAND_wl_display_flush(data->display);
   315 
   341 
   316     return 0;
   342     return 0;
   317 }
   343 }
   318 
   344 
   319 static void
   345 static void
   361         wl_output_destroy(data->output);
   387         wl_output_destroy(data->output);
   362 
   388 
   363     Wayland_display_destroy_input(data);
   389     Wayland_display_destroy_input(data);
   364 
   390 
   365     if (data->xkb_context) {
   391     if (data->xkb_context) {
   366         xkb_context_unref(data->xkb_context);
   392         WAYLAND_xkb_context_unref(data->xkb_context);
   367         data->xkb_context = NULL;
   393         data->xkb_context = NULL;
   368     }
   394     }
   369 #ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
   395 #ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
   370     if (data->windowmanager)
   396     if (data->windowmanager)
   371         qt_windowmanager_destroy(data->windowmanager);
   397         qt_windowmanager_destroy(data->windowmanager);
   378 
   404 
   379     if (data->shm)
   405     if (data->shm)
   380         wl_shm_destroy(data->shm);
   406         wl_shm_destroy(data->shm);
   381 
   407 
   382     if (data->cursor_theme)
   408     if (data->cursor_theme)
   383         wl_cursor_theme_destroy(data->cursor_theme);
   409         WAYLAND_wl_cursor_theme_destroy(data->cursor_theme);
   384 
   410 
   385     if (data->shell)
   411     if (data->shell)
   386         wl_shell_destroy(data->shell);
   412         wl_shell_destroy(data->shell);
   387 
   413 
   388     if (data->compositor)
   414     if (data->compositor)
   389         wl_compositor_destroy(data->compositor);
   415         wl_compositor_destroy(data->compositor);
   390 
   416 
   391     if (data->display) {
   417     if (data->display) {
   392         wl_display_flush(data->display);
   418         WAYLAND_wl_display_flush(data->display);
   393         wl_display_disconnect(data->display);
   419         WAYLAND_wl_display_disconnect(data->display);
   394     }
   420     }
   395     
   421     
   396     wl_list_for_each_safe(m, t, &data->modes_list, link) {
   422     wl_list_for_each_safe(m, t, &data->modes_list, link) {
   397         wl_list_remove(&m->link);
   423         WAYLAND_wl_list_remove(&m->link);
   398         free(m);
   424         free(m);
   399     }
   425     }
   400 
   426 
   401 
   427 
   402     free(data);
   428     free(data);