summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjoel@teichroeb.net <none@none>2010-12-06 10:58:43 -0800
committerBenjamin Franzke <benjaminfranzke@googlemail.com>2012-02-28 08:29:07 +0100
commita7df2b521e786001c737ed44b4b667802237e450 (patch)
tree2057271a3006c67c7a27fd0d2a0c713842f1b39b
parentf18dd535801bcb50a63d932cfe3826a3aa15fdf0 (diff)
Started on the wayland platform
-rw-r--r--src/video/wayland/SDL_waylandevents.c39
-rw-r--r--src/video/wayland/SDL_waylandevents_c.h28
-rw-r--r--src/video/wayland/SDL_waylandgl.c191
-rw-r--r--src/video/wayland/SDL_waylandgl.h15
-rw-r--r--src/video/wayland/SDL_waylandrender.c349
-rw-r--r--src/video/wayland/SDL_waylandrender_c.h28
-rw-r--r--src/video/wayland/SDL_waylandvideo.c265
-rw-r--r--src/video/wayland/SDL_waylandvideo.h60
-rw-r--r--src/video/wayland/SDL_waylandwindow.c70
-rw-r--r--src/video/wayland/SDL_waylandwindow.h28
10 files changed, 1073 insertions, 0 deletions
diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c
new file mode 100644
index 00000000..1219ae47
--- /dev/null
+++ b/src/video/wayland/SDL_waylandevents.c
@@ -0,0 +1,39 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2010 Sam Lantinga
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+ Sam Lantinga
+ slouken@libsdl.org
+*/
+#include "SDL_config.h"
+
+/* Being a null driver, there's no event stream. We just define stubs for
+ most of the API. */
+
+#include "../../events/SDL_sysevents.h"
+#include "../../events/SDL_events_c.h"
+
+#include "SDL_waylandvideo.h"
+#include "SDL_waylandevents_c.h"
+
+void
+Wayland_PumpEvents(_THIS)
+{
+ /* do nothing. */
+}
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/src/video/wayland/SDL_waylandevents_c.h b/src/video/wayland/SDL_waylandevents_c.h
new file mode 100644
index 00000000..92ce0ad2
--- /dev/null
+++ b/src/video/wayland/SDL_waylandevents_c.h
@@ -0,0 +1,28 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2010 Sam Lantinga
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+ Sam Lantinga
+ slouken@libsdl.org
+*/
+#include "SDL_config.h"
+
+#include "SDL_waylandvideo.h"
+
+extern void Wayland_PumpEvents(_THIS);
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/src/video/wayland/SDL_waylandgl.c b/src/video/wayland/SDL_waylandgl.c
new file mode 100644
index 00000000..f1c4ad21
--- /dev/null
+++ b/src/video/wayland/SDL_waylandgl.c
@@ -0,0 +1,191 @@
+#include "SDL_config.h"
+
+#include "SDL_waylandgl.h"
+#include "SDL_waylandwindow.h"
+
+
+void Wayland_GL_SwapWindow(_THIS, SDL_Window * window)
+{
+ printf("Wayland_GL_SwapWindow\n");
+ SDL_WaylandWindow *data = window->driverdata;
+ data->current ^= 1;
+
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER,
+ GL_COLOR_ATTACHMENT0,
+ GL_RENDERBUFFER,
+ data->rbo[data->current]);
+
+ wl_surface_attach(data->surface,
+ data->buffer[data->current ^ 1]);
+ wl_surface_damage(data->surface, 0, 0,
+ window->w, window->h);
+}
+
+int
+Wayland_GL_MakeCurrent(_THIS, SDL_Window *window, SDL_GLContext context)
+{
+ printf("Wayland_GL_MakeCurrent\n");
+ SDL_WaylandData *data = _this->driverdata;
+ SDL_WaylandWindow *wind = (SDL_WaylandWindow *) window->driverdata;
+ if (!eglMakeCurrent(data->edpy,EGL_NO_SURFACE,
+ EGL_NO_SURFACE,wind->context)) {
+ SDL_SetError("Unable to make EGL context current");
+ return -1;
+ }
+
+ return 1;
+}
+
+int
+Wayland_GL_LoadLibrary(_THIS, const char *path)
+{
+/* void *handle;
+ int dlopen_flags;
+
+ SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
+
+ if (_this->gles_data->egl_active) {
+ SDL_SetError("OpenGL ES context already created");
+ return -1;
+ }
+#ifdef RTLD_GLOBAL
+ dlopen_flags = RTLD_LAZY | RTLD_GLOBAL;
+#else
+ dlopen_flags = RTLD_LAZY;
+#endif
+ handle = dlopen(path, dlopen_flags);
+ /* Catch the case where the application isn't linked with EGL *//*
+ if ((dlsym(handle, "eglChooseConfig") == NULL) && (path == NULL)) {
+
+ dlclose(handle);
+ path = getenv("SDL_VIDEO_GL_DRIVER");
+ if (path == NULL) {
+ path = DEFAULT_OPENGL;
+ }
+ handle = dlopen(path, dlopen_flags);
+ }
+
+ if (handle == NULL) {
+ SDL_SetError("Could not load OpenGL ES/EGL library");
+ return -1;
+ }
+
+ /* Unload the old driver and reset the pointers *//*
+ Wayland_GL_UnloadLibrary(_this);
+
+
+
+ _this->gles_data->egl_display =
+ _this->gles_data->eglGetDisplay((NativeDisplayType) data->display);
+
+ if (!_this->gles_data->egl_display) {
+ SDL_SetError("Could not get EGL display");
+ return -1;
+ }
+
+ if (eglInitialize(_this->gles_data->egl_display, NULL,
+ NULL) != EGL_TRUE) {
+ SDL_SetError("Could not initialize EGL");
+ return -1;
+ }
+
+ _this->gl_config.dll_handle = handle;
+ _this->gl_config.driver_loaded = 1;
+
+ if (path) {
+ strncpy(_this->gl_config.driver_path, path,
+ sizeof(_this->gl_config.driver_path) - 1);
+ } else {
+ strcpy(_this->gl_config.driver_path, "");
+ }*/
+ SDL_WaylandData *data = _this->driverdata;
+
+ data->edpy = eglGetDRMDisplayMESA(data->drm_fd);
+
+ int major, minor;
+ if (!eglInitialize(data->edpy, &major, &minor)) {
+ fprintf(stderr, "failed to initialize display\n");
+ return -1;
+ }
+
+/* if (!eglBindAPI(EGL_OPENGL_ES_API)) {
+ fprintf(stderr, "failed to bind EGL_OPENGL_ES_API\n");
+ return -1;
+ }
+
+ data->context = eglCreateContext(data->edpy, NULL,
+ EGL_NO_CONTEXT, context_attribs);
+ if (data->context == NULL) {
+ fprintf(stderr, "failed to create context\n");
+ return -1;
+ }
+
+ if (!eglMakeCurrent(data->edpy, EGL_NO_SURFACE,
+ EGL_NO_SURFACE, data->context)) {
+ fprintf(stderr, "failed to make context current\n");
+ return -1;
+ }*/
+ return 0;
+}
+
+void
+Wayland_GL_UnloadLibrary(_THIS)
+{
+ /*if (_this->gl_config.driver_loaded) {
+ _this->gles_data->eglTerminate(_this->gles_data->egl_display);
+
+ dlclose(_this->gl_config.dll_handle);
+
+ _this->gles_data->eglGetProcAddress = NULL;
+ _this->gles_data->eglChooseConfig = NULL;
+ _this->gles_data->eglCreateContext = NULL;
+ _this->gles_data->eglCreateWindowSurface = NULL;
+ _this->gles_data->eglDestroyContext = NULL;
+ _this->gles_data->eglDestroySurface = NULL;
+ _this->gles_data->eglMakeCurrent = NULL;
+ _this->gles_data->eglSwapBuffers = NULL;
+ _this->gles_data->eglGetDisplay = NULL;
+ _this->gles_data->eglTerminate = NULL;
+
+ _this->gl_config.dll_handle = NULL;
+ _this->gl_config.driver_loaded = 0;
+ }*/
+}
+
+SDL_GLContext
+Wayland_GL_CreateContext(_THIS, SDL_Window * window)
+{
+ SDL_WaylandData *data = _this->driverdata;
+ SDL_WaylandWindow *wind = (SDL_WaylandWindow *) window->driverdata;
+ //Display *display = data->videodata->display;
+
+
+ static const EGLint context_attribs[] = {
+ EGL_CONTEXT_CLIENT_VERSION, 2,
+ EGL_NONE
+ };
+ wind->context = eglCreateContext(data->edpy, NULL, EGL_NO_CONTEXT, context_attribs);
+
+
+ if (wind->context == EGL_NO_CONTEXT) {
+ SDL_SetError("Could not create EGL context");
+ return NULL;
+ }
+
+ //data->egl_active = 1;
+
+
+ return 1;
+}
+
+int
+Wayland_GL_SetSwapInterval(_THIS, int interval)
+{
+ return 0;
+}
+
+int
+Wayland_GL_GetSwapInterval(_THIS)
+{
+ return 0;
+}
diff --git a/src/video/wayland/SDL_waylandgl.h b/src/video/wayland/SDL_waylandgl.h
new file mode 100644
index 00000000..b566cbf5
--- /dev/null
+++ b/src/video/wayland/SDL_waylandgl.h
@@ -0,0 +1,15 @@
+#include "SDL_config.h"
+
+#ifndef _SDL_waylandgl_h
+#define _SDL_waylandgl_h
+#include "SDL_waylandwindow.h"
+#include </home/joel/install/include/wayland-client-protocol.h>
+
+void Wayland_GL_SwapWindow(_THIS, SDL_Window * window);
+int Wayland_GL_GetSwapInterval(_THIS);
+int Wayland_GL_SetSwapInterval(_THIS, int interval);
+int Wayland_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context);
+SDL_GLContext Wayland_GL_CreateContext(_THIS, SDL_Window * window);
+int Wayland_GL_LoadLibrary(_THIS, const char *path);
+void Wayland_GL_UnloadLibrary(_THIS);
+#endif
diff --git a/src/video/wayland/SDL_waylandrender.c b/src/video/wayland/SDL_waylandrender.c
new file mode 100644
index 00000000..15476779
--- /dev/null
+++ b/src/video/wayland/SDL_waylandrender.c
@@ -0,0 +1,349 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2010 Sam Lantinga
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+ Sam Lantinga
+ slouken@libsdl.org
+*/
+#include "SDL_config.h"
+
+#include "SDL_video.h"
+#include "../SDL_sysvideo.h"
+#include "../SDL_yuv_sw_c.h"
+#include "../SDL_renderer_sw.h"
+
+
+/* SDL surface based renderer implementation */
+
+static SDL_Renderer *SDL_Wayland_CreateRenderer(SDL_Window * window,
+ Uint32 flags);
+static int SDL_Wayland_RenderDrawPoints(SDL_Renderer * renderer,
+ const SDL_Point * points, int count);
+static int SDL_Wayland_RenderDrawLines(SDL_Renderer * renderer,
+ const SDL_Point * points, int count);
+static int SDL_Wayland_RenderDrawRects(SDL_Renderer * renderer,
+ const SDL_Rect ** rects, int count);
+static int SDL_Wayland_RenderFillRects(SDL_Renderer * renderer,
+ const SDL_Rect ** rects, int count);
+static int SDL_Wayland_RenderCopy(SDL_Renderer * renderer,
+ SDL_Texture * texture,
+ const SDL_Rect * srcrect,
+ const SDL_Rect * dstrect);
+static int SDL_Wayland_RenderReadPixels(SDL_Renderer * renderer,
+ const SDL_Rect * rect,
+ Uint32 format,
+ void * pixels, int pitch);
+static int SDL_Wayland_RenderWritePixels(SDL_Renderer * renderer,
+ const SDL_Rect * rect,
+ Uint32 format,
+ const void * pixels, int pitch);
+static void SDL_Wayland_RenderPresent(SDL_Renderer * renderer);
+static void SDL_Wayland_DestroyRenderer(SDL_Renderer * renderer);
+static int *SDL_Wayland_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
+
+SDL_RenderDriver SDL_Wayland_RenderDriver = {
+ SDL_Wayland_CreateRenderer,
+ {
+ "Wayland",
+ (SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTCOPY |
+ SDL_RENDERER_PRESENTFLIP2 | SDL_RENDERER_PRESENTFLIP3 |
+ SDL_RENDERER_PRESENTDISCARD),
+ }
+};
+
+typedef struct
+{
+ int current_screen;
+ SDL_Surface *screens[3];
+} SDL_Wayland_RenderData;
+
+SDL_Renderer *
+SDL_Wayland_CreateRenderer(SDL_Window * window, Uint32 flags)
+{
+ SDL_VideoDisplay *display = window->display;
+ SDL_DisplayMode *displayMode = &display->current_mode;
+ SDL_Renderer *renderer;
+ SDL_Wayland_RenderData *data;
+ int i, n;
+ int bpp;
+ Uint32 Rmask, Gmask, Bmask, Amask;
+
+ if (!SDL_PixelFormatEnumToMasks
+ (displayMode->format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) {
+ SDL_SetError("Unknown display format");
+ return NULL;
+ }
+
+ renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
+ if (!renderer) {
+ SDL_OutOfMemory();
+ return NULL;
+ }
+
+ data = (SDL_Wayland_RenderData *) SDL_malloc(sizeof(*data));
+ if (!data) {
+ SDL_Wayland_DestroyRenderer(renderer);
+ SDL_OutOfMemory();
+ return NULL;
+ }
+ SDL_zerop(data);
+
+ renderer->RenderDrawPoints = SDL_Wayland_RenderDrawPoints;
+ renderer->RenderDrawLines = SDL_Wayland_RenderDrawLines;
+ renderer->RenderDrawRects = SDL_Wayland_RenderDrawRects;
+ renderer->RenderFillRects = SDL_Wayland_RenderFillRects;
+ renderer->RenderCopy = SDL_Wayland_RenderCopy;
+ renderer->RenderReadPixels = SDL_Wayland_RenderReadPixels;
+ renderer->RenderWritePixels = SDL_Wayland_RenderWritePixels;
+ renderer->RenderPresent = SDL_Wayland_RenderPresent;
+ renderer->DestroyRenderer = SDL_Wayland_DestroyRenderer;
+ //renderer->CreateTexture = SDL_Wayland_CreateTexture;
+ renderer->info.name = SDL_Wayland_RenderDriver.info.name;
+ renderer->info.flags = 0;
+ renderer->window = window;
+ renderer->driverdata = data;
+ Setup_SoftwareRenderer(renderer);
+
+ if (flags & SDL_RENDERER_PRESENTFLIP2) {
+ renderer->info.flags |= SDL_RENDERER_PRESENTFLIP2;
+ n = 2;
+ } else if (flags & SDL_RENDERER_PRESENTFLIP3) {
+ renderer->info.flags |= SDL_RENDERER_PRESENTFLIP3;
+ n = 3;
+ } else {
+ renderer->info.flags |= SDL_RENDERER_PRESENTCOPY;
+ n = 1;
+ }
+ for (i = 0; i < n; ++i) {
+ data->screens[i] =
+ SDL_CreateRGBSurface(0, window->w, window->h, bpp, Rmask, Gmask,
+ Bmask, Amask);
+ if (!data->screens[i]) {
+ SDL_Wayland_DestroyRenderer(renderer);
+ return NULL;
+ }
+ SDL_SetSurfacePalette(data->screens[i], display->palette);
+ }
+ data->current_screen = 0;
+
+ return renderer;
+}
+
+static int
+SDL_Wayland_RenderDrawPoints(SDL_Renderer * renderer,
+ const SDL_Point * points, int count)
+{
+ SDL_Wayland_RenderData *data =
+ (SDL_Wayland_RenderData *) renderer->driverdata;
+ SDL_Surface *target = data->screens[data->current_screen];
+
+ if (renderer->blendMode == SDL_BLENDMODE_NONE ||
+ renderer->blendMode == SDL_BLENDMODE_MASK) {
+ Uint32 color = SDL_MapRGBA(target->format,
+ renderer->r, renderer->g, renderer->b,
+ renderer->a);
+
+ return SDL_DrawPoints(target, points, count, color);
+ } else {
+ return SDL_BlendPoints(target, points, count, renderer->blendMode,
+ renderer->r, renderer->g, renderer->b,
+ renderer->a);
+ }
+}
+
+static int
+SDL_Wayland_RenderDrawLines(SDL_Renderer * renderer,
+ const SDL_Point * points, int count)
+{
+ SDL_Wayland_RenderData *data =
+ (SDL_Wayland_RenderData *) renderer->driverdata;
+ SDL_Surface *target = data->screens[data->current_screen];
+
+ if (renderer->blendMode == SDL_BLENDMODE_NONE ||
+ renderer->blendMode == SDL_BLENDMODE_MASK) {
+ Uint32 color = SDL_MapRGBA(target->format,
+ renderer->r, renderer->g, renderer->b,
+ renderer->a);
+
+ return SDL_DrawLines(target, points, count, color);
+ } else {
+ return SDL_BlendLines(target, points, count, renderer->blendMode,
+ renderer->r, renderer->g, renderer->b,
+ renderer->a);
+ }
+}
+
+static int
+SDL_Wayland_RenderDrawRects(SDL_Renderer * renderer, const SDL_Rect ** rects,
+ int count)
+{
+ SDL_Wayland_RenderData *data =
+ (SDL_Wayland_RenderData *) renderer->driverdata;
+ SDL_Surface *target = data->screens[data->current_screen];
+
+ if (renderer->blendMode == SDL_BLENDMODE_NONE ||
+ renderer->blendMode == SDL_BLENDMODE_MASK) {
+ Uint32 color = SDL_MapRGBA(target->format,
+ renderer->r, renderer->g, renderer->b,
+ renderer->a);
+
+ return SDL_DrawRects(target, rects, count, color);
+ } else {
+ return SDL_BlendRects(target, rects, count,
+ renderer->blendMode,
+ renderer->r, renderer->g, renderer->b,
+ renderer->a);
+ }
+}
+
+static int
+SDL_Wayland_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects,
+ int count)
+{
+ SDL_Wayland_RenderData *data =
+ (SDL_Wayland_RenderData *) renderer->driverdata;
+ SDL_Surface *target = data->screens[data->current_screen];
+
+ if (renderer->blendMode == SDL_BLENDMODE_NONE ||
+ renderer->blendMode == SDL_BLENDMODE_MASK) {
+ Uint32 color = SDL_MapRGBA(target->format,
+ renderer->r, renderer->g, renderer->b,
+ renderer->a);
+
+ return SDL_FillRects(target, rects, count, color);
+ } else {
+ return SDL_BlendFillRects(target, rects, count,
+ renderer->blendMode,
+ renderer->r, renderer->g, renderer->b,
+ renderer->a);
+ }
+}
+
+static int
+SDL_Wayland_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
+ const SDL_Rect * srcrect, const SDL_Rect * dstrect)
+{
+ SDL_Wayland_RenderData *data =
+ (SDL_Wayland_RenderData *) renderer->driverdata;
+ SDL_Window *window = renderer->window;
+ SDL_VideoDisplay *display = window->display;
+
+ if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
+ SDL_Surface *target = data->screens[data->current_screen];
+ void *pixels =
+ (Uint8 *) target->pixels + dstrect->y * target->pitch +
+ dstrect->x * target->format->BytesPerPixel;
+ return SDL_SW_CopyYUVToRGB((SDL_SW_YUVTexture *) texture->driverdata,
+ srcrect, display->current_mode.format,
+ dstrect->w, dstrect->h, pixels,
+ target->pitch);
+ } else {
+ SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
+ SDL_Surface *target = data->screens[data->current_screen];
+ SDL_Rect real_srcrect = *srcrect;
+ SDL_Rect real_dstrect = *dstrect;
+
+ return SDL_LowerBlit(surface, &real_srcrect, target, &real_dstrect);
+ }
+}
+
+static int
+SDL_Wayland_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
+ Uint32 format, void * pixels, int pitch)
+{
+ SDL_Wayland_RenderData *data =
+ (SDL_Wayland_RenderData *) renderer->driverdata;
+ SDL_Window *window = renderer->window;
+ SDL_VideoDisplay *display = window->display;
+ SDL_Surface *screen = data->screens[data->current_screen];
+ Uint32 screen_format = display->current_mode.format;
+ Uint8 *screen_pixels = (Uint8 *) screen->pixels +
+ rect->y * screen->pitch +
+ rect->x * screen->format->BytesPerPixel;
+ int screen_pitch = screen->pitch;
+
+ return SDL_ConvertPixels(rect->w, rect->h,
+ screen_format, screen_pixels, screen_pitch,
+ format, pixels, pitch);
+}
+
+static int
+SDL_Wayland_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect,
+ Uint32 format, const void * pixels, int pitch)
+{
+ SDL_Wayland_RenderData *data =
+ (SDL_Wayland_RenderData *) renderer->driverdata;
+ SDL_Window *window = renderer->window;
+ SDL_VideoDisplay *display = window->display;
+ SDL_Surface *screen = data->screens[data->current_screen];
+ Uint32 screen_format = display->current_mode.format;
+ Uint8 *screen_pixels = (Uint8 *) screen->pixels +
+ rect->y * screen->pitch +
+ rect->x * screen->format->BytesPerPixel;
+ int screen_pitch = screen->pitch;
+
+ return SDL_ConvertPixels(rect->w, rect->h,
+ format, pixels, pitch,
+ screen_format, screen_pixels, screen_pitch);
+}
+
+static void
+SDL_Wayland_RenderPresent(SDL_Renderer * renderer)
+{
+ static int frame_number;
+ SDL_Wayland_RenderData *data =
+ (SDL_Wayland_RenderData *) renderer->driverdata;
+
+ /* Send the data to the display */
+ if (SDL_getenv("SDL_VIDEO_Wayland_SAVE_FRAMES")) {
+ char file[128];
+ SDL_snprintf(file, sizeof(file), "SDL_window%d-%8.8d.bmp",
+ renderer->window->id, ++frame_number);
+ SDL_SaveBMP(data->screens[data->current_screen], file);
+ }
+
+ /* Update the flipping chain, if any */
+ if (renderer->info.flags & SDL_RENDERER_PRESENTFLIP2) {
+ data->current_screen = (data->current_screen + 1) % 2;
+ } else if (renderer->info.flags & SDL_RENDERER_PRESENTFLIP3) {
+ data->current_screen = (data->current_screen + 1) % 3;
+ }
+}
+
+static int *SDL_Wayland_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
+{
+}
+
+static void
+SDL_Wayland_DestroyRenderer(SDL_Renderer * renderer)
+{
+ SDL_Wayland_RenderData *data =
+ (SDL_Wayland_RenderData *) renderer->driverdata;
+ int i;
+
+ if (data) {
+ for (i = 0; i < SDL_arraysize(data->screens); ++i) {
+ if (data->screens[i]) {
+ SDL_FreeSurface(data->screens[i]);
+ }
+ }
+ SDL_free(data);
+ }
+ SDL_free(renderer);
+}
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/src/video/wayland/SDL_waylandrender_c.h b/src/video/wayland/SDL_waylandrender_c.h
new file mode 100644
index 00000000..ca0da53e
--- /dev/null
+++ b/src/video/wayland/SDL_waylandrender_c.h
@@ -0,0 +1,28 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2010 Sam Lantinga
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+ Sam Lantinga
+ slouken@libsdl.org
+*/
+#include "SDL_config.h"
+
+/* SDL surface based renderer implementation */
+
+extern SDL_RenderDriver SDL_Wayland_RenderDriver;
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/src/video/wayland/SDL_waylandvideo.c b/src/video/wayland/SDL_waylandvideo.c
new file mode 100644
index 00000000..bfda5956
--- /dev/null
+++ b/src/video/wayland/SDL_waylandvideo.c
@@ -0,0 +1,265 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2010 Sam Lantinga
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+ Sam Lantinga
+ slouken@libsdl.org
+*/
+#include "SDL_config.h"
+
+
+#include <fcntl.h>
+#include "SDL_video.h"
+#include "SDL_mouse.h"
+#include "../SDL_sysvideo.h"
+#include "../SDL_pixels_c.h"
+#include "../../events/SDL_events_c.h"
+
+#include "SDL_waylandvideo.h"
+#include "SDL_waylandevents_c.h"
+#include "SDL_waylandrender_c.h"
+#include "SDL_waylandwindow.h"
+#include "SDL_waylandgl.h"
+
+
+#define WAYLANDVID_DRIVER_NAME "wayland"
+
+/* Initialization/Query functions */
+static int Wayland_VideoInit(_THIS);
+static int Wayland_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode);
+static void Wayland_VideoQuit(_THIS);
+
+
+/* Wayland driver bootstrap functions */
+
+static int
+Wayland_Available(void)
+{
+ const char *envr = SDL_getenv("SDL_VIDEODRIVER");
+ if ((envr) && (SDL_strcmp(envr, WAYLANDVID_DRIVER_NAME) == 0)) {
+ return (1);
+ }
+
+ return (0);
+}
+
+static void
+Wayland_DeleteDevice(SDL_VideoDevice * device)
+{
+ SDL_free(device);
+}
+
+static SDL_VideoDevice *
+Wayland_CreateDevice(int devindex)
+{
+ SDL_VideoDevice *device;
+
+ /* Initialize all variables that we clean on shutdown */
+ device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
+ if (!device) {
+ SDL_OutOfMemory();
+ if (device) {
+ SDL_free(device);
+ }
+ return (0);
+ }
+
+ /* Set the function pointers */
+ device->VideoInit = Wayland_VideoInit;
+ device->VideoQuit = Wayland_VideoQuit;
+ device->SetDisplayMode = Wayland_SetDisplayMode;
+ device->PumpEvents = Wayland_PumpEvents;
+
+ device->GL_SwapWindow = Wayland_GL_SwapWindow;
+ device->GL_GetSwapInterval = Wayland_GL_GetSwapInterval;
+ device->GL_SetSwapInterval = Wayland_GL_SetSwapInterval;
+ device->GL_MakeCurrent = Wayland_GL_MakeCurrent;
+ device->GL_CreateContext = Wayland_GL_CreateContext;
+ device->GL_LoadLibrary = Wayland_GL_LoadLibrary;
+ device->GL_UnloadLibrary = Wayland_GL_UnloadLibrary;
+
+
+
+ device->CreateWindow = Wayland_CreateWindow;
+
+
+ device->free = Wayland_DeleteDevice;
+
+ return device;
+}
+
+VideoBootStrap Wayland_bootstrap = {
+ WAYLANDVID_DRIVER_NAME, "SDL Wayland video driver",
+ Wayland_Available, Wayland_CreateDevice
+};
+
+static void
+display_handle_geometry(void *data,
+ struct wl_output *output,
+ int32_t width, int32_t height)
+{
+ SDL_WaylandData *d = data;
+
+ d->screen_allocation.x = 0;
+ d->screen_allocation.y = 0;
+ d->screen_allocation.width = width;
+ d->screen_allocation.height = height;
+}
+
+
+static const struct wl_output_listener output_listener = {
+ display_handle_geometry,
+};
+
+static void
+handle_configure(void *data, struct wl_shell *shell,
+ uint32_t time, uint32_t edges,
+ struct wl_surface *surface,
+ int32_t x, int32_t y, int32_t width, int32_t height)
+{
+
+}
+
+static const struct wl_shell_listener shell_listener = {
+ handle_configure,
+};
+
+
+static void
+drm_handle_device(void *data, struct wl_drm *drm, const char *device)
+{
+ SDL_WaylandData *c = data;
+
+ c->device_name = strdup(device);
+}
+
+static void drm_handle_authenticated(void *data, struct wl_drm *drm)
+{
+ SDL_WaylandData *c = data;
+
+ c->authenticated = 1;
+}
+
+static const struct wl_drm_listener drm_listener = {
+ drm_handle_device,
+ drm_handle_authenticated
+};
+
+
+static void
+display_handle_global(struct wl_display *display, uint32_t id,
+ const char *interface, uint32_t version, void *data)
+{
+ SDL_WaylandData *d = data;
+
+ if (strcmp(interface, "compositor") == 0) {
+ d->compositor = wl_compositor_create(display, id);
+ } else if (strcmp(interface, "output") == 0) {
+ d->output = wl_output_create(display, id);
+ wl_output_add_listener(d->output, &output_listener, d);
+ } else if (strcmp(interface, "input_device") == 0) {
+ //display_add_input(d, id);
+ } else if (strcmp(interface, "shell") == 0) {
+ d->shell = wl_shell_create(display, id);
+ wl_shell_add_listener(d->shell, &shell_listener, d);
+ } else if (strcmp(interface, "drm") == 0) {
+ d->drm = wl_drm_create(display, id);
+ wl_drm_add_listener(d->drm, &drm_listener, d);
+ }
+}
+
+
+
+int
+Wayland_VideoInit(_THIS)
+{
+ SDL_WaylandData *data;
+ data = malloc(sizeof *data);
+ if (data == NULL)
+ return 0;
+
+ _this->driverdata = data;
+
+ data->display = wl_display_connect(NULL);
+ if (data->display == NULL) {
+ fprintf(stderr, "failed to create display: %m\n");
+ return 0;
+ }
+
+ wl_display_add_global_listener(data->display,
+ display_handle_global, data);
+
+ wl_display_iterate(data->display, WL_DISPLAY_READABLE);
+
+ /*if (wayland_compositor_init_egl(c) < 0)
+ return NULL;*/
+
+ data->drm_fd = open (data->device_name, O_RDWR);
+ if (data->drm_fd < 0)
+ {
+ fprintf(stderr, "Failed to open drm device\n");
+
+ return 0;
+ }
+
+ int magic;
+ if (drmGetMagic (data->drm_fd, &magic))
+ {
+ fprintf(stderr, "Failed to get drm magic\n");
+
+ return 0;
+ }
+ wl_drm_authenticate (data->drm, magic);
+
+ wl_display_iterate (data->display, WL_DISPLAY_WRITABLE);
+ while (!data->authenticated)
+ wl_display_iterate (data->display, WL_DISPLAY_READABLE);
+
+
+
+
+
+ SDL_VideoDisplay display;
+ SDL_DisplayMode mode;
+
+ /* Use a fake 32-bpp desktop mode */
+ mode.format = SDL_PIXELFORMAT_RGB888;
+ mode.w = 1024;
+ mode.h = 768;
+ mode.refresh_rate = 0;
+ mode.driverdata = NULL;
+ SDL_zero(display);
+ display.desktop_mode = mode;
+ display.current_mode = mode;
+ display.driverdata = NULL;
+ SDL_AddVideoDisplay(&display);
+
+ return 0;
+}
+
+static int
+Wayland_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
+{
+ return 0;
+}
+
+void
+Wayland_VideoQuit(_THIS)
+{
+}
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/src/video/wayland/SDL_waylandvideo.h b/src/video/wayland/SDL_waylandvideo.h
new file mode 100644
index 00000000..29c747e4
--- /dev/null
+++ b/src/video/wayland/SDL_waylandvideo.h
@@ -0,0 +1,60 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2010 Sam Lantinga
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+ Sam Lantinga
+ slouken@libsdl.org
+*/
+#include "SDL_config.h"
+
+#ifndef _SDL_waylandvideo_h
+#define _SDL_waylandvideo_h
+
+#include "../SDL_sysvideo.h"
+#include </home/joel/install/include/wayland-client.h>
+#include </home/joel/install/include/wayland-client-protocol.h>
+#define GL_GLEXT_PROTOTYPES
+#define EGL_EGLEXT_PROTOTYPES
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GL/gl.h>
+
+
+typedef struct
+{
+ struct wl_display *display;
+ struct wl_compositor *compositor;
+ struct wl_drm *drm;
+ struct wl_output *output;
+ struct wl_shell *shell;
+
+ struct {
+ int32_t x, y, width, height;
+ } screen_allocation;
+
+ char *device_name;
+ int authenticated;
+
+ int drm_fd;
+
+ EGLDisplay edpy;
+
+} SDL_WaylandData;
+
+#endif /* _SDL_nullvideo_h */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c
new file mode 100644
index 00000000..3adf7fe5
--- /dev/null
+++ b/src/video/wayland/SDL_waylandwindow.c
@@ -0,0 +1,70 @@
+#include "SDL_config.h"
+
+#include "../SDL_sysvideo.h"
+#include "SDL_waylandwindow.h"
+#include "SDL_waylandvideo.h"
+
+
+
+int Wayland_CreateWindow(_THIS, SDL_Window * window)
+{
+ printf("window create\n");
+ SDL_WaylandWindow *data;
+ data = malloc(sizeof *data);
+ if (data == NULL)
+ return 0;
+ SDL_WaylandData *c;
+ c = _this->driverdata;
+ window->driverdata = data;
+ struct wl_visual *visual;
+ int i;
+ EGLint name, stride, attribs[] = {
+ EGL_WIDTH, 0,
+ EGL_HEIGHT, 0,
+ EGL_DRM_BUFFER_FORMAT_MESA, EGL_DRM_BUFFER_FORMAT_ARGB32_MESA,
+ EGL_DRM_BUFFER_USE_MESA, EGL_DRM_BUFFER_USE_SCANOUT_MESA,
+ EGL_NONE
+ };
+
+
+ data->surface =
+ wl_compositor_create_surface(c->compositor);
+ wl_surface_set_user_data(data->surface, data);
+
+ glGenRenderbuffers(2, data->rbo);
+ visual = wl_display_get_premultiplied_argb_visual(c->display);
+ for (i = 0; i < 2; i++) {
+ glBindRenderbuffer(GL_RENDERBUFFER, data->rbo[i]);
+
+ attribs[1] = window->w;
+ attribs[3] = window->h;
+ data->image[i] =
+ eglCreateDRMImageMESA(c->display, attribs);
+ glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER,
+ data->image[i]);
+ eglExportDRMImageMESA(c->display, data->image[i],
+ &name, NULL, &stride);
+ data->buffer[i] =
+ wl_drm_create_buffer(c->drm, name,
+ window->w, window->h,
+ stride, visual);
+ }
+
+ data->current = 0;
+ glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, data->image[0]);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER,
+ GL_COLOR_ATTACHMENT0,
+ GL_RENDERBUFFER,
+ data->rbo[data->current]);
+
+ wl_surface_attach(data->surface,
+ data->buffer[data->current]);
+ wl_surface_map(data->surface,
+ 0, 0,
+ window->w, window->h);
+ printf("window %d %d\n", window->w, window->h);
+
+ glClearColor(0, 0, 0, 0.5);
+
+ return 0;
+}
diff --git a/src/video/wayland/SDL_waylandwindow.h b/src/video/wayland/SDL_waylandwindow.h
new file mode 100644
index 00000000..6b8e4f6a
--- /dev/null
+++ b/src/video/wayland/SDL_waylandwindow.h
@@ -0,0 +1,28 @@
+#include "SDL_config.h"
+
+#ifndef _SDL_waylandwindow_h
+#define _SDL_waylandwindow_h
+
+#include "../SDL_sysvideo.h"
+
+#include "SDL_waylandvideo.h"
+
+typedef struct
+{
+ struct wl_surface *surface;
+ struct wl_buffer *buffer[2];
+
+ EGLImageKHR image[2];
+ GLuint rbo[2];
+ uint32_t fb_id[2];
+ uint32_t current;
+
+ EGLContext context;
+
+} SDL_WaylandWindow;
+
+extern int Wayland_CreateWindow(_THIS, SDL_Window * window);
+
+#endif /* _SDL_waylandwindow_h */
+
+/* vi: set ts=4 sw=4 expandtab: */