Example #1
0
static void
SetFullscreen(_THIS, SDL_Window * window, struct wl_output *output)
{
    const SDL_VideoData *viddata = (const SDL_VideoData *) _this->driverdata;
    SDL_WindowData *wind = window->driverdata;

    if (viddata->shell.xdg) {
        if (output) {
            xdg_toplevel_set_fullscreen(wind->shell_surface.xdg.roleobj.toplevel, output);
        } else {
            xdg_toplevel_unset_fullscreen(wind->shell_surface.xdg.roleobj.toplevel);
        }
    } else if (viddata->shell.zxdg) {
        if (output) {
            zxdg_toplevel_v6_set_fullscreen(wind->shell_surface.zxdg.roleobj.toplevel, output);
        } else {
            zxdg_toplevel_v6_unset_fullscreen(wind->shell_surface.zxdg.roleobj.toplevel);
        }
    } else {
        if (output) {
            wl_shell_surface_set_fullscreen(wind->shell_surface.wl,
                                            WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,
                                            0, output);
        } else {
            wl_shell_surface_set_toplevel(wind->shell_surface.wl);
        }
    }

    WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display );
}
Example #2
0
    void create_surface(struct display *display)
    {
      EGLBoolean ret;

      display->surface = wl_compositor_create_surface(display->compositor);
      display->shell_surface = wl_shell_get_shell_surface(display->shell,
                     display->surface);

      wl_shell_surface_add_listener(display->shell_surface,
                  &shell_surface_listener, display);

      display->native = wl_egl_window_create(display->surface, 1, 1);

      display->egl_surface =
        eglCreateWindowSurface((EGLDisplay) display->egl.dpy, display->egl.conf, (EGLNativeWindowType) display->native, NULL);

      wl_shell_surface_set_title(display->shell_surface, "projection");

      ret = eglMakeCurrent(display->egl.dpy, display->egl_surface,
               display->egl_surface, display->egl.ctx);
      assert(ret == EGL_TRUE);

      struct wl_callback *callback;

      display->configured = 0;

      wl_shell_surface_set_fullscreen(display->shell_surface,
        WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, 0, NULL);

      callback = wl_display_sync(display->display);
      wl_callback_add_listener(callback, &configure_callback_listener, display);
    }
Example #3
0
static GLFWbool createShellSurface(_GLFWwindow* window)
{
    window->wl.shellSurface = wl_shell_get_shell_surface(_glfw.wl.shell,
                                                         window->wl.surface);
    if (!window->wl.shellSurface)
        return GLFW_FALSE;

    wl_shell_surface_add_listener(window->wl.shellSurface,
                                  &shellSurfaceListener,
                                  window);

    if (window->wl.title)
        wl_shell_surface_set_title(window->wl.shellSurface, window->wl.title);

    if (window->monitor)
    {
        wl_shell_surface_set_fullscreen(
            window->wl.shellSurface,
            WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,
            0,
            window->monitor->wl.output);
    }
    else if (window->wl.maximized)
    {
        wl_shell_surface_set_maximized(window->wl.shellSurface, NULL);
    }
    else
    {
        wl_shell_surface_set_toplevel(window->wl.shellSurface);
    }

    wl_surface_commit(window->wl.surface);

    return GLFW_TRUE;
}
Example #4
0
static void
set_fullscreen(struct window *window, int fullscreen)
{
	struct wl_callback *callback;

	window->fullscreen = fullscreen;
	window->configured = 0;

	if (fullscreen) {
		wl_shell_surface_set_fullscreen(window->shell_surface,
						WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,
						0, NULL);
		callback = wl_display_sync(window->display->display);
		wl_callback_add_listener(callback,
					 &configure_callback_listener,
					 window);

	} else {
		wl_shell_surface_set_toplevel(window->shell_surface);
		handle_configure(window, window->shell_surface, 0,
				 window->window_size.width,
				 window->window_size.height);
		window->configured = 1;
	}
}
Example #5
0
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)
    {
        wl_shell_surface_set_fullscreen(
            window->wl.shell_surface,
            WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,
            0,
            wndconfig->monitor->wl.output);
    }
    else
    {
        wl_shell_surface_set_toplevel(window->wl.shell_surface);
    }

    return GL_TRUE;
}
static void
create_window (GstWaylandSink * sink, struct display *display, int width,
    int height)
{
  struct window *window;

  if (sink->window)
    return;

  g_mutex_lock (&sink->wayland_lock);

  window = malloc (sizeof *window);
  window->display = display;
  window->width = width;
  window->height = height;
  window->redraw_pending = FALSE;

  window->surface = wl_compositor_create_surface (display->compositor);

  window->shell_surface = wl_shell_get_shell_surface (display->shell,
      window->surface);

  g_return_if_fail (window->shell_surface);

  wl_shell_surface_add_listener (window->shell_surface,
      &shell_surface_listener, window);

  wl_shell_surface_set_toplevel (window->shell_surface);
  wl_shell_surface_set_fullscreen (window->shell_surface,
      WL_SHELL_SURFACE_FULLSCREEN_METHOD_SCALE, 0, NULL);

  sink->window = window;

  g_mutex_unlock (&sink->wayland_lock);
}
static gboolean
gst_mfx_window_wayland_set_fullscreen (GstMfxWindow * window,
    gboolean fullscreen)
{
  GstMfxWindowWaylandPrivate *const priv =
      GST_MFX_WINDOW_WAYLAND_GET_PRIVATE (window);

  if (!priv->is_shown) {
    priv->fullscreen_on_show = fullscreen;
    return TRUE;
  }

  if (!fullscreen)
    wl_shell_surface_set_toplevel (priv->shell_surface);
  else {
#ifdef USE_WESTON_4_0
    if (priv->wp_viewport)
      wp_viewport_set_destination (priv->wp_viewport,
	window->width, window->height);
#else
    wl_shell_surface_set_fullscreen (priv->shell_surface,
        WL_SHELL_SURFACE_FULLSCREEN_METHOD_SCALE, 0, NULL);
#endif
  }

  return TRUE;
}
Example #8
0
void wlf_SetWindowFullscreen(wlfContext* wlfc, wlfWindow* window, BOOL fullscreen)
{
	if (fullscreen)
	{
		wl_shell_surface_set_fullscreen(window->shell_surface, WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, 0, NULL);
		window->fullscreen = TRUE;
	}
}
	void  XdevLWindowWayland::show() {
		if(m_fullScreen) {
			wl_shell_surface_set_fullscreen(m_shellSurface, WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, 0, nullptr);
		} else {
			wl_shell_surface_set_toplevel(m_shellSurface);
		}
		wl_display_flush(display);
	}
	void XdevLWindowWayland::setFullscreen(xdl_bool state) {
		m_fullScreen = state;
		if(state) {
			wl_shell_surface_set_fullscreen(m_shellSurface, WL_SHELL_SURFACE_FULLSCREEN_METHOD_SCALE, 0, nullptr);
		} else {
			wl_shell_surface_set_toplevel(m_shellSurface);
		}
		wl_display_flush(display);
	}
Example #11
0
static int Control(vout_window_t *wnd, int cmd, va_list ap)
{
    vout_window_sys_t *sys = wnd->sys;
    struct wl_display *display = wnd->display.wl;

    switch (cmd)
    {
        case VOUT_WINDOW_SET_STATE:
            return VLC_EGENERIC;
        case VOUT_WINDOW_SET_SIZE:
        {
            unsigned width = va_arg (ap, unsigned);
            unsigned height = va_arg (ap, unsigned);

            vlc_mutex_lock(&sys->lock);
            sys->top_width = width;
            sys->top_height = height;

            if (!sys->fullscreen)
                vout_window_ReportSize(wnd, width, height);
            vlc_mutex_unlock(&sys->lock);
            break;
        }
        case VOUT_WINDOW_SET_FULLSCREEN:
        {
            bool fs = va_arg(ap, int);

            if (fs && sys->output != NULL)
            {
                wl_shell_surface_set_fullscreen(sys->shell_surface, 1, 0,
                                                sys->output);
                vlc_mutex_lock(&sys->lock);
                sys->fullscreen = true;
                vout_window_ReportSize(wnd, sys->fs_width, sys->fs_height);
                vlc_mutex_unlock(&sys->lock);
            }
            else
            {
                wl_shell_surface_set_toplevel(sys->shell_surface);

                vlc_mutex_lock(&sys->lock);
                sys->fullscreen = false;
                vout_window_ReportSize(wnd, sys->top_width, sys->top_height);
                vlc_mutex_unlock(&sys->lock);
            }
            break;
        }

        default:
            msg_Err(wnd, "request %d not implemented", cmd);
            return VLC_EGENERIC;
    }

    wl_display_flush(display);
    return VLC_SUCCESS;
}
Example #12
0
void
gst_wl_window_ensure_fullscreen (GstWlWindow * window, gboolean fullscreen)
{
  if (!window)
    return;

  if (fullscreen)
    wl_shell_surface_set_fullscreen (window->shell_surface,
        WL_SHELL_SURFACE_FULLSCREEN_METHOD_SCALE, 0, NULL);
  else
    wl_shell_surface_set_toplevel (window->shell_surface);
}
Example #13
0
void Wayland_ShowWindow(_THIS, SDL_Window *window)
{
    SDL_WindowData *wind = window->driverdata;

    if (window->flags & SDL_WINDOW_FULLSCREEN)
        wl_shell_surface_set_fullscreen(wind->shell_surface,
                                        WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,
                                        0, NULL);
    else
        wl_shell_surface_set_toplevel(wind->shell_surface);

    WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display );
}
Example #14
0
void
Wayland_SetWindowFullscreen(_THIS, SDL_Window * window,
                            SDL_VideoDisplay * _display, SDL_bool fullscreen)
{
    SDL_WindowData *wind = window->driverdata;

    if (fullscreen)
        wl_shell_surface_set_fullscreen(wind->shell_surface,
                                        WL_SHELL_SURFACE_FULLSCREEN_METHOD_SCALE,
                                        0, NULL);
    else
        wl_shell_surface_set_toplevel(wind->shell_surface);

    WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display );
}
Example #15
0
static void
toggle_fullscreen(bool fullscreen)
{
	GLWin.fullscreen = fullscreen;

	if (fullscreen) {
		wl_shell_surface_set_fullscreen(GLWin.wl_shell_surface,
						WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,
						0, nullptr);
	} else {
		wl_shell_surface_set_toplevel(GLWin.wl_shell_surface);
		handle_configure(nullptr, GLWin.wl_shell_surface, 0,
				 GLWin.window_size.width,
				 GLWin.window_size.height);
	}
}
static void
clutter_stage_wayland_set_fullscreen (ClutterStageWindow *stage_window,
                                      gboolean            fullscreen)
{
    ClutterStageWayland *stage_wayland = CLUTTER_STAGE_WAYLAND (stage_window);
    ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
    ClutterBackend *backend = CLUTTER_BACKEND (stage_cogl->backend);
    ClutterBackendWayland *backend_wayland = CLUTTER_BACKEND_WAYLAND (backend);
    ClutterActor *stage = _clutter_stage_window_get_wrapper (stage_window);

    stage_wayland->fullscreen = fullscreen;

    if (!stage_wayland->wayland_shell_surface) /* Not realized yet */
        return;

    if (fullscreen)
    {
        _clutter_stage_update_state (stage_cogl->wrapper,
                                     0,
                                     CLUTTER_STAGE_STATE_FULLSCREEN);

        /* FIXME: In future versions of the Wayland protocol we'll get a
         * configure with the dimensions we can use - but for now we have to
         * use the dimensions from the output's mode
         */
        clutter_actor_set_size (stage,
                                backend_wayland->output_width,
                                backend_wayland->output_height);

        /* FIXME: And we must force a redraw so that new sized buffer gets
         * attached
         */
        _clutter_stage_window_redraw (stage_window);
        wl_shell_surface_set_fullscreen (stage_wayland->wayland_shell_surface,
                                         WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,
                                         0,
                                         NULL);
    }
    else
    {
        _clutter_stage_update_state (stage_cogl->wrapper,
                                     CLUTTER_STAGE_STATE_FULLSCREEN,
                                     0);

        wl_shell_surface_set_toplevel (stage_wayland->wayland_shell_surface);
    }
}
Example #17
0
static int
client_main(void)
{
   struct client_test client;
   client_test_create(&client, "fullscreen", 320, 320);
   surface_create(&client);
   shell_surface_create(&client);
   client_test_roundtrip(&client);
   client_test_roundtrip(&client);

   struct output *o;
   assert((o = chck_iter_pool_get(&client.outputs, 0)));
   wl_shell_surface_set_fullscreen(client.view.ssurface, 0, 0, o->output);
   wl_surface_commit(client.view.surface);
   while (wl_display_dispatch(client.display) != -1);
   return client_test_end(&client);
}
Example #18
0
static bool gfx_ctx_wl_set_video_mode(void *data,
      unsigned width, unsigned height,
      bool fullscreen)
{
   EGLint egl_attribs[16];
   EGLint *attr = NULL;
   gfx_ctx_wayland_data_t *wl = (gfx_ctx_wayland_data_t*)data;

   egl_install_sighandlers();

   attr = egl_fill_attribs(wl, egl_attribs);

   wl->width = width ? width : DEFAULT_WINDOWED_WIDTH;
   wl->height = height ? height : DEFAULT_WINDOWED_HEIGHT;

   wl->surface = wl_compositor_create_surface(wl->compositor);
   wl->win = wl_egl_window_create(wl->surface, wl->width, wl->height);
   wl->shell_surf = wl_shell_get_shell_surface(wl->shell, wl->surface);

   wl_shell_surface_add_listener(wl->shell_surf, &shell_surface_listener, NULL);
   wl_shell_surface_set_toplevel(wl->shell_surf);
   wl_shell_surface_set_class(wl->shell_surf, "RetroArch");
   wl_shell_surface_set_title(wl->shell_surf, "RetroArch");

   if (!egl_create_context(wl, (attr != egl_attribs) ? egl_attribs : NULL))
   {
      egl_report_error();
      goto error;
   }

   if (!egl_create_surface(wl, (EGLNativeWindowType)wl->win))
      goto error;

   egl_set_swap_interval(wl, wl->egl.interval);

   if (fullscreen)
      wl_shell_surface_set_fullscreen(wl->shell_surf, WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, 0, NULL);

   flush_wayland_fd(wl);
   return true;

error:
   gfx_ctx_wl_destroy(data);
   return false;
}
Example #19
0
bool
NativeStateWayland::create_window(WindowProperties const& properties)
{
    struct my_output *output = 0;
    if (!display_->outputs.empty()) output = display_->outputs.at(0);
    window_ = new struct my_window();
    window_->properties = properties;
    window_->surface = wl_compositor_create_surface(display_->compositor);
    if (window_->properties.fullscreen && output) {
        window_->native = wl_egl_window_create(window_->surface,
                                               output->width, output->height);
        window_->properties.width = output->width;
        window_->properties.height = output->height;
    } else {
        window_->native = wl_egl_window_create(window_->surface,
                                               properties.width, properties.height);
    }

    window_->opaque_reqion = wl_compositor_create_region(display_->compositor);
    wl_region_add(window_->opaque_reqion, 0, 0,
                  window_->properties.width,
                  window_->properties.height);
    wl_surface_set_opaque_region(window_->surface, window_->opaque_reqion);

    window_->shell_surface = wl_shell_get_shell_surface(display_->shell,
                                                        window_->surface);

    if (window_->shell_surface) {
        wl_shell_surface_add_listener(window_->shell_surface,
                                      &shell_surface_listener_, this);
    }

    wl_shell_surface_set_title(window_->shell_surface, "glmark2");

    if (window_->properties.fullscreen) {
        wl_shell_surface_set_fullscreen(window_->shell_surface,
                                        WL_SHELL_SURFACE_FULLSCREEN_METHOD_DRIVER,
                                        output->refresh, output->output);
    } else {
        wl_shell_surface_set_toplevel(window_->shell_surface);
    }

    return true;
}
Example #20
0
static void
toggle_fullscreen(bool fullscreen)
{
	GLWin.fullscreen = fullscreen;
	GLWin.configured = false;

	if (fullscreen) {
		wl_shell_surface_set_fullscreen(GLWin.wl_shell_surface,
						WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,
						0, NULL);
	} else {
		wl_shell_surface_set_toplevel(GLWin.wl_shell_surface);
		handle_configure(NULL, GLWin.wl_shell_surface, 0,
				 GLWin.window_size.width,
				 GLWin.window_size.height);
	}

	setup_callback_listener();
}
Example #21
0
static int fghToggleFullscreen(void)
{
    SFG_Window* win = fgStructure.CurrentWindow;

    if ( ! win->State.IsFullscreen )
    {
      win->State.pWState.OldWidth = win->State.Width;
      win->State.pWState.OldHeight = win->State.Height;
      wl_shell_surface_set_fullscreen( win->Window.pContext.shsurface,
                                       WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,
                                       0, NULL );
    }
    else
    {
      fgPlatformReshapeWindow( win, win->State.pWState.OldWidth,
                                    win->State.pWState.OldHeight );
      wl_shell_surface_set_toplevel( win->Window.pContext.shsurface );
    }

    return 0;
}
static gboolean
gst_vaapi_window_wayland_set_fullscreen (GstVaapiWindow * window,
        gboolean fullscreen)
{
    GstVaapiWindowWaylandPrivate *const priv =
        GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window);

    if (!priv->is_shown) {
        priv->fullscreen_on_show = fullscreen;
        return TRUE;
    }

    if (!fullscreen)
        wl_shell_surface_set_toplevel (priv->shell_surface);
    else {
        wl_shell_surface_set_fullscreen (priv->shell_surface,
                                         WL_SHELL_SURFACE_FULLSCREEN_METHOD_SCALE, 0, NULL);
    }

    return TRUE;
}
static gboolean
gst_vaapi_window_wayland_create(
    GstVaapiWindow *window,
    guint          *width,
    guint          *height
)
{
    GstVaapiWindowWaylandPrivate * const priv =
        GST_VAAPI_WINDOW_WAYLAND(window)->priv;
    GstVaapiDisplayWaylandPrivate * const priv_display =
        GST_VAAPI_OBJECT_DISPLAY_WAYLAND(window)->priv;

    GST_DEBUG("create window, size %ux%u", *width, *height);

    g_return_val_if_fail(priv_display->compositor != NULL, FALSE);
    g_return_val_if_fail(priv_display->shell != NULL, FALSE);

    priv->surface = wl_compositor_create_surface(priv_display->compositor);
    if (!priv->surface)
        return FALSE;

    priv->shell_surface =
        wl_shell_get_shell_surface(priv_display->shell, priv->surface);
    if (!priv->shell_surface)
        return FALSE;

    wl_shell_surface_add_listener(priv->shell_surface,
                                  &shell_surface_listener, priv);
    wl_shell_surface_set_toplevel(priv->shell_surface);
    wl_shell_surface_set_fullscreen(
        priv->shell_surface,
        WL_SHELL_SURFACE_FULLSCREEN_METHOD_SCALE,
        0,
        NULL
    );

    priv->redraw_pending = FALSE;
    return TRUE;
}
Example #24
0
void fgPlatformOpenWindow( SFG_Window* window, const char* title,
                           GLboolean positionUse, int x, int y,
                           GLboolean sizeUse, int w, int h,
                           GLboolean gameMode, GLboolean isSubWindow )
{
    /* Save the display mode if we are creating a menu window */
    if( window->IsMenu && ( ! fgStructure.MenuContext ) )
        fgState.DisplayMode = GLUT_DOUBLE | GLUT_RGB ;

    fghChooseConfig( &window->Window.pContext.egl.Config );

    if( ! window->Window.pContext.egl.Config )
    {
        /*
         * The "fghChooseConfig" returned a null meaning that the visual
         * context is not available.
         * Try a couple of variations to see if they will work.
         */
        if( fgState.DisplayMode & GLUT_MULTISAMPLE )
        {
            fgState.DisplayMode &= ~GLUT_MULTISAMPLE ;
            fghChooseConfig( &window->Window.pContext.egl.Config );
            fgState.DisplayMode |= GLUT_MULTISAMPLE;
        }
    }

    FREEGLUT_INTERNAL_ERROR_EXIT( window->Window.pContext.egl.Config != NULL,
                                  "EGL configuration with necessary capabilities "
                                  "not found", "fgOpenWindow" );

    if( ! positionUse )
        x = y = -1; /* default window position */
    if( ! sizeUse )
        w = h = 300; /* default window size */

    /*  Create the cursor  */
   window->Window.pContext.cursor = wl_cursor_theme_get_cursor(
                                      fgDisplay.pDisplay.cursor_theme,
                                      "left_ptr" ); 
   window->Window.pContext.cursor_surface = wl_compositor_create_surface(
                                              fgDisplay.pDisplay.compositor );

    /*  Create the main surface  */
    window->Window.pContext.surface = wl_compositor_create_surface(
                                        fgDisplay.pDisplay.compositor );

    /*  Create the shell surface with respects to the parent/child tree  */
    window->Window.pContext.shsurface = wl_shell_get_shell_surface(
                                          fgDisplay.pDisplay.shell,
                                           window->Window.pContext.surface );
    wl_shell_surface_add_listener( window->Window.pContext.shsurface,
                                   &fghShSurfaceListener, window );

    if( title)
      wl_shell_surface_set_title( window->Window.pContext.shsurface, title );

    if( gameMode )
    {
        window->State.IsFullscreen = GL_TRUE;
        wl_shell_surface_set_fullscreen( window->Window.pContext.shsurface,
                                         WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,
                                         0, NULL );
    }
    else if( !isSubWindow && !window->IsMenu )
    {
        wl_shell_surface_set_toplevel( window->Window.pContext.shsurface );
    }
    else
    {
        wl_shell_surface_set_transient( window->Window.pContext.shsurface,
                                        window->Parent->Window.pContext.surface,
                                        x, y, 0 );
    }

    /*  Create the Wl_EGL_Window  */
    window->Window.Context = fghCreateNewContext( window );
    window->Window.pContext.egl_window = wl_egl_window_create( 
                                           window->Window.pContext.surface,
                                           w, h);
    window->Window.pContext.egl.Surface = eglCreateWindowSurface( 
                              fgDisplay.pDisplay.egl.Display,
                              window->Window.pContext.egl.Config,
                              (EGLNativeWindowType)window->Window.pContext.egl_window,
                              NULL );
    eglMakeCurrent( fgDisplay.pDisplay.egl.Display, window->Window.pContext.egl.Surface,
                    window->Window.pContext.egl.Surface, window->Window.Context );

   window->Window.pContext.pointer_button_pressed = GL_FALSE;
}
Example #25
0
static bool gfx_ctx_wl_set_video_mode(void *data,
      video_frame_info_t *video_info,
      unsigned width, unsigned height,
      bool fullscreen)
{
#ifdef HAVE_EGL
   EGLint egl_attribs[16];
   EGLint *attr              = egl_fill_attribs(
         (gfx_ctx_wayland_data_t*)data, egl_attribs);
#endif
   gfx_ctx_wayland_data_t *wl = (gfx_ctx_wayland_data_t*)data;

   wl->width                  = width  ? width  : DEFAULT_WINDOWED_WIDTH;
   wl->height                 = height ? height : DEFAULT_WINDOWED_HEIGHT;

   wl->surface                = wl_compositor_create_surface(wl->compositor);

   wl_surface_set_buffer_scale(wl->surface, wl->buffer_scale);

   switch (wl_api)
   {
      case GFX_CTX_OPENGL_API:
      case GFX_CTX_OPENGL_ES_API:
      case GFX_CTX_OPENVG_API:
#ifdef HAVE_EGL
         wl->win        = wl_egl_window_create(wl->surface, wl->width, wl->height);
#endif
         break;
      case GFX_CTX_NONE:
      default:
         break;
   }
   wl->shell_surf = wl_shell_get_shell_surface(wl->shell, wl->surface);

   wl_shell_surface_add_listener(wl->shell_surf, &shell_surface_listener, wl);
   wl_shell_surface_set_toplevel(wl->shell_surf);
   wl_shell_surface_set_class(wl->shell_surf, "RetroArch");
   wl_shell_surface_set_title(wl->shell_surf, "RetroArch");

   switch (wl_api)
   {
      case GFX_CTX_OPENGL_API:
      case GFX_CTX_OPENGL_ES_API:
      case GFX_CTX_OPENVG_API:
#ifdef HAVE_EGL

         if (!egl_create_context(&wl->egl, (attr != egl_attribs) ? egl_attribs : NULL))
         {
            egl_report_error();
            goto error;
         }

         if (!egl_create_surface(&wl->egl, (EGLNativeWindowType)wl->win))
            goto error;
         egl_set_swap_interval(&wl->egl, wl->egl.interval);
#endif
         break;
      case GFX_CTX_NONE:
      default:
         break;
   }

   if (fullscreen)
      wl_shell_surface_set_fullscreen(wl->shell_surf,
            WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, 0, NULL);

   flush_wayland_fd(&wl->input);

   switch (wl_api)
   {
      case GFX_CTX_VULKAN_API:
         wl_display_roundtrip(wl->input.dpy);

#ifdef HAVE_VULKAN
         if (!vulkan_surface_create(&wl->vk, VULKAN_WSI_WAYLAND,
                  wl->input.dpy, wl->surface, 
                  wl->width, wl->height, wl->swap_interval))
            goto error;
#endif
         break;
      case GFX_CTX_NONE:
      default:
         break;
   }

   if (fullscreen)
   {
      wl->cursor.visible = false;
      gfx_ctx_wl_show_mouse(wl, false);
   }
   else
      wl->cursor.visible = true;

   return true;

error:
   gfx_ctx_wl_destroy(data);
   return false;
}