X11: Add option to run X11 backend in root window.
[gfxprim.git] / libs / backends / GP_SDL.c
blob392361979cb61151206b7e8052c1f928f66faf0c
1 /*****************************************************************************
2 * This file is part of gfxprim library. *
3 * *
4 * Gfxprim is free software; you can redistribute it and/or *
5 * modify it under the terms of the GNU Lesser General Public *
6 * License as published by the Free Software Foundation; either *
7 * version 2.1 of the License, or (at your option) any later version. *
8 * *
9 * Gfxprim is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
12 * Lesser General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU Lesser General Public *
15 * License along with gfxprim; if not, write to the Free Software *
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
17 * Boston, MA 02110-1301 USA *
18 * *
19 * Copyright (C) 2009-2010 Jiri "BlueBear" Dluhos *
20 * <jiri.bluebear.dluhos@gmail.com> *
21 * *
22 * Copyright (C) 2009-2012 Cyril Hrubis <metan@ucw.cz> *
23 * *
24 *****************************************************************************/
26 #include "../../config.h"
28 #ifdef HAVE_LIBSDL
30 #include "core/GP_Debug.h"
31 #include "input/GP_InputDriverSDL.h"
32 #include "GP_Backend.h"
33 #include "GP_SDL.h"
35 #include <SDL/SDL.h>
36 #include <SDL/SDL_mutex.h>
38 static SDL_Surface *sdl_surface;
39 static SDL_mutex *mutex;
40 static GP_Context context;
42 static uint32_t sdl_flags = SDL_SWSURFACE;
44 /* Backend API funcitons */
46 static void sdl_flip(struct GP_Backend *self __attribute__((unused)))
48 SDL_mutexP(mutex);
50 SDL_Flip(sdl_surface);
51 context.pixels = sdl_surface->pixels;
53 SDL_mutexV(mutex);
56 static void sdl_update_rect(struct GP_Backend *self __attribute__((unused)),
57 GP_Coord x0, GP_Coord y0, GP_Coord x1, GP_Coord y1)
59 SDL_mutexP(mutex);
62 * SDL_UpdateRect() with all x0, y0, x1 and y1 zero updates whole
63 * screen we avoid such behavior as it will break other backends.
65 if (x1 != 0 && y1 != 0)
66 SDL_UpdateRect(sdl_surface, x0, y0,
67 GP_ABS(x1 - x0) + 1, GP_ABS(y1 - y0) + 1);
69 SDL_mutexV(mutex);
72 static void sdl_poll(struct GP_Backend *self __attribute__((unused)))
74 SDL_Event ev;
76 SDL_mutexP(mutex);
78 while (SDL_PollEvent(&ev))
79 GP_InputDriverSDLEventPut(&ev);
81 SDL_mutexV(mutex);
84 int context_from_surface(GP_Context *context, SDL_Surface *surf)
86 /* sanity checks on the SDL surface */
87 if (surf->format->BytesPerPixel == 0) {
88 GP_DEBUG(1, "ERROR: Surface->BytesPerPixel == 0");
89 return 1;
92 if (surf->format->BytesPerPixel > 4) {
93 GP_DEBUG(1, "ERROR: Surface->BytesPerPixel > 4");
94 return 1;
97 enum GP_PixelType pixeltype = GP_PixelRGBMatch(surf->format->Rmask,
98 surf->format->Gmask,
99 surf->format->Bmask,
100 surf->format->Ashift,
101 surf->format->BitsPerPixel);
103 if (pixeltype == GP_PIXEL_UNKNOWN)
104 return 1;
106 /* basic structure and size */
107 context->pixels = surf->pixels;
108 context->bpp = 8 * surf->format->BytesPerPixel;
109 context->pixel_type = pixeltype;
110 context->bytes_per_row = surf->pitch;
111 context->w = surf->w;
112 context->h = surf->h;
114 return 0;
117 static int sdl_set_attributes(struct GP_Backend *self __attribute__((unused)),
118 uint32_t w, uint32_t h,
119 const char *caption)
121 SDL_mutexP(mutex);
123 if (caption != NULL)
124 SDL_WM_SetCaption(caption, caption);
126 if (w != 0 && h != 0) {
127 sdl_surface = SDL_SetVideoMode(w, h, 0, sdl_flags);
128 context_from_surface(&context, sdl_surface);
131 SDL_mutexV(mutex);
133 return 0;
136 static void sdl_exit(struct GP_Backend *self __attribute__((unused)));
138 static struct GP_Backend backend = {
139 .name = "SDL",
140 .context = NULL,
141 .Flip = sdl_flip,
142 .UpdateRect = sdl_update_rect,
143 .SetAttributes = sdl_set_attributes,
144 .Exit = sdl_exit,
145 .fd_list = NULL,
146 .Poll = sdl_poll,
149 static void sdl_exit(struct GP_Backend *self __attribute__((unused)))
151 SDL_mutexP(mutex);
153 SDL_Quit();
155 SDL_DestroyMutex(mutex);
157 backend.context = NULL;
160 GP_Backend *GP_BackendSDLInit(GP_Size w, GP_Size h, uint8_t bpp, uint8_t flags,
161 const char *caption)
163 /* SDL not yet initalized */
164 if (backend.context == NULL) {
165 if (SDL_Init(SDL_INIT_VIDEO)) {
166 GP_DEBUG(1, "ERROR: SDL_Init: %s", SDL_GetError());
167 return NULL;
170 if (flags & GP_SDL_FULLSCREEN)
171 sdl_flags |= SDL_FULLSCREEN;
173 if (flags & GP_SDL_RESIZABLE)
174 sdl_flags |= SDL_RESIZABLE;
176 sdl_surface = SDL_SetVideoMode(w, h, bpp, sdl_flags);
178 if (caption != NULL)
179 SDL_WM_SetCaption(caption, caption);
181 if (sdl_surface == NULL) {
182 GP_DEBUG(1, "ERROR: SDL_SetVideoMode: %s", SDL_GetError());
183 SDL_Quit();
184 return NULL;
187 mutex = SDL_CreateMutex();
189 if (context_from_surface(&context, sdl_surface)) {
190 GP_DEBUG(1, "ERROR: Failed to match pixel_type");
191 SDL_Quit();
192 return NULL;
195 backend.context = &context;
198 return &backend;
201 #else
203 #include "GP_Backend.h"
205 GP_Backend *GP_BackendSDLInit(GP_Size w __attribute__((unused)),
206 GP_Size h __attribute__((unused)),
207 uint8_t bpp __attribute__((unused)),
208 uint8_t flags __attribute__((unused)),
209 const char *caption __attribute__((unused)))
211 return NULL;
214 #endif /* HAVE_LIBSDL */