Upto: Table of Contents of full book "Programming Wayland Clients"

This project hasn't been updated since mid-2017. Wayland has moved on since then, so the information here may be out of date, and there is no guarantee the programs still work.

SDL

SDL (Simple DirectMedia Layer) is a cross-platform multimedia framework. It has suport fro Wayland since version 2.0.2.

Resources

Installing

Writing SDL applications requires the RPM package SDL2-devel under Fedora and libsdl2-dev under Ubuntu.

A simple SDL application

To demonstrate SDL and Wayland we don't need a complex application, just a simple window will do. The following application draws a window and exits after 10 seconds window.c:

/* From http://lazyfoo.net/tutorials/SDL/01_hello_SDL/index2.php */

#include <SDL.h>
#include <stdio.h>

//Screen dimension constants
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;

int main( int argc, char* args[] )
{
    //The window we'll be rendering to
    SDL_Window* window = NULL;
    
    //The surface contained by the window
    SDL_Surface* screenSurface = NULL;

    //Initialize SDL
    if( SDL_Init( SDL_INIT_VIDEO ) < 0 )
    {
        printf( "SDL could not initialize! SDL_Error: %s\n", SDL_GetError() );
    }
    else
    {
        //Create window
        window = SDL_CreateWindow( "SDL Tutorial", SDL_WINDOWPOS_UNDEFINED,
				   SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH,
				   SCREEN_HEIGHT, SDL_WINDOW_SHOWN );
        if( window == NULL )
        {
            printf( "Window could not be created! SDL_Error: %s\n", SDL_GetError() );
        }
       else
        {
            //Get window surface
            screenSurface = SDL_GetWindowSurface( window );

            //Fill the surface white
            SDL_FillRect( screenSurface, NULL, SDL_MapRGB( screenSurface->format, 0xFF, 0xFF, 0xFF ) );
            
            //Update the surface
            SDL_UpdateWindowSurface( window );

            //Wait ten seconds
            SDL_Delay( 10000 );
        }
    }
    //Destroy window
    SDL_DestroyWindow( window );

    //Quit SDL subsystems
    SDL_Quit();

    return 0;
}


      

It can be built using the Makefile

CFLAGS = $(shell pkg-config --cflags sdl2)
LDLIBS= $(shell pkg-config --libs sdl2)

EXE = window wayland_info

all: $(EXE)


      

Running under X or Wayland

The default is to run under X:

        
          ./window
        
      
runs as an X application with an X window. To run under Wayland, set the environment variable SDL_VIDEODRIVER:
        
          SDL_VIDEODRIVER=wayland ./window
        
      
This runs as a Wayland application, native on Fedora, in Weston on Ubuntu.

Getting a wayland surface

If you need to get a Wayland surface this is done by getting the system structure SDL_GetWindowWMInfo. This contains a union of information for different backends. For Wayland, the relevant calls are given in the program wayland_info.c

#include "SDL.h"
#include "SDL_syswm.h"
#include <wayland-client.h>

int main(int argc, char *argv[]) {
  SDL_Window* window;
  SDL_SysWMinfo info;

  SDL_Init(0);

  window = SDL_CreateWindow("", 0, 0, 0, 0, SDL_WINDOW_HIDDEN);

   if (SDL_GetWindowWMInfo(window,&info)) {
    /* success */
    if (info.subsystem == SDL_SYSWM_WAYLAND) {
      printf("Is Wayland\n");
      
      struct wl_display* display = info.info.wl.display;
      struct wl_surface* surface = info.info.wl.surface;
      struct wl_shell_surface* shell_surface = info.info.wl.shell_surface;
      // and do whatever you want with the Wayland stuff
    } else {
      printf("Not a Wayland system\n");
    }
   } else {
     printf("Failed to get WM info\n");
   }
}


      

Conclusion

Building SDL applications for Wayland is straightforward: without any changes to the source code, run the executable with the environment variable SDL_VIDEODRIVER set to wayland. Access to the Wayland display and applications's Wayland surface is straightforward.


Copyright © Jan Newmarch, jan@newmarch.name

If you like this book, please contribute using Flattr
or donate using PayPal