SDL  2.0
SDL_rpivideo.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
4 
5  This software is provided 'as-is', without any express or implied
6  warranty. In no event will the authors be held liable for any damages
7  arising from the use of this software.
8 
9  Permission is granted to anyone to use this software for any purpose,
10  including commercial applications, and to alter it and redistribute it
11  freely, subject to the following restrictions:
12 
13  1. The origin of this software must not be misrepresented; you must not
14  claim that you wrote the original software. If you use this software
15  in a product, an acknowledgment in the product documentation would be
16  appreciated but is not required.
17  2. Altered source versions must be plainly marked as such, and must not be
18  misrepresented as being the original software.
19  3. This notice may not be removed or altered from any source distribution.
20 */
21 
22 #include "../../SDL_internal.h"
23 
24 #if SDL_VIDEO_DRIVER_RPI
25 
26 /* References
27  * http://elinux.org/RPi_VideoCore_APIs
28  * https://github.com/raspberrypi/firmware/blob/master/opt/vc/src/hello_pi/hello_triangle/triangle.c
29  * http://cgit.freedesktop.org/wayland/weston/tree/src/rpi-renderer.c
30  * http://cgit.freedesktop.org/wayland/weston/tree/src/compositor-rpi.c
31  */
32 
33 /* SDL internals */
34 #include "../SDL_sysvideo.h"
35 #include "SDL_version.h"
36 #include "SDL_syswm.h"
37 #include "SDL_loadso.h"
38 #include "SDL_events.h"
39 #include "../../events/SDL_mouse_c.h"
40 #include "../../events/SDL_keyboard_c.h"
41 
42 #ifdef SDL_INPUT_LINUXEV
43 #include "../../core/linux/SDL_evdev.h"
44 #endif
45 
46 /* RPI declarations */
47 #include "SDL_rpivideo.h"
48 #include "SDL_rpievents_c.h"
49 #include "SDL_rpiopengles.h"
50 #include "SDL_rpimouse.h"
51 
52 static int
53 RPI_Available(void)
54 {
55  return 1;
56 }
57 
58 static void
59 RPI_Destroy(SDL_VideoDevice * device)
60 {
61  /* SDL_VideoData *phdata = (SDL_VideoData *) device->driverdata; */
62 
63  if (device->driverdata != NULL) {
64  device->driverdata = NULL;
65  }
66 }
67 
68 static SDL_VideoDevice *
69 RPI_Create()
70 {
71  SDL_VideoDevice *device;
72  SDL_VideoData *phdata;
73 
74  /* Initialize SDL_VideoDevice structure */
75  device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
76  if (device == NULL) {
78  return NULL;
79  }
80 
81  /* Initialize internal data */
82  phdata = (SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData));
83  if (phdata == NULL) {
85  SDL_free(device);
86  return NULL;
87  }
88 
89  device->driverdata = phdata;
90 
91  /* Setup amount of available displays and current display */
92  device->num_displays = 0;
93 
94  /* Set device free function */
95  device->free = RPI_Destroy;
96 
97  /* Setup all functions which we can handle */
98  device->VideoInit = RPI_VideoInit;
99  device->VideoQuit = RPI_VideoQuit;
102  device->CreateWindow = RPI_CreateWindow;
108  device->ShowWindow = RPI_ShowWindow;
109  device->HideWindow = RPI_HideWindow;
110  device->RaiseWindow = RPI_RaiseWindow;
126 
127  device->PumpEvents = RPI_PumpEvents;
128 
129  return device;
130 }
131 
132 VideoBootStrap RPI_bootstrap = {
133  "RPI",
134  "RPI Video Driver",
135  RPI_Available,
136  RPI_Create
137 };
138 
139 /*****************************************************************************/
140 /* SDL Video and Display initialization/handling functions */
141 /*****************************************************************************/
142 int
144 {
145  SDL_VideoDisplay display;
146  SDL_DisplayMode current_mode;
148  uint32_t w,h;
149 
150  /* Initialize BCM Host */
151  bcm_host_init();
152 
153  SDL_zero(current_mode);
154 
155  if (graphics_get_display_size( 0, &w, &h) < 0) {
156  return -1;
157  }
158 
159  current_mode.w = w;
160  current_mode.h = h;
161  /* FIXME: Is there a way to tell the actual refresh rate? */
162  current_mode.refresh_rate = 60;
163  /* 32 bpp for default */
164  current_mode.format = SDL_PIXELFORMAT_ABGR8888;
165 
166  current_mode.driverdata = NULL;
167 
168  SDL_zero(display);
169  display.desktop_mode = current_mode;
170  display.current_mode = current_mode;
171 
172  /* Allocate display internal data */
173  data = (SDL_DisplayData *) SDL_calloc(1, sizeof(SDL_DisplayData));
174  if (data == NULL) {
175  return SDL_OutOfMemory();
176  }
177 
178  data->dispman_display = vc_dispmanx_display_open( 0 /* LCD */);
179 
180  display.driverdata = data;
181 
182  SDL_AddVideoDisplay(&display);
183 
184 #ifdef SDL_INPUT_LINUXEV
185  SDL_EVDEV_Init();
186 #endif
187 
189 
190  return 1;
191 }
192 
193 void
195 {
196 #ifdef SDL_INPUT_LINUXEV
197  SDL_EVDEV_Quit();
198 #endif
199 }
200 
201 void
203 {
204  /* Only one display mode available, the current one */
205  SDL_AddDisplayMode(display, &display->current_mode);
206 }
207 
208 int
210 {
211  return 0;
212 }
213 
214 int
216 {
217  SDL_WindowData *wdata;
218  SDL_VideoDisplay *display;
219  SDL_DisplayData *displaydata;
220  VC_RECT_T dst_rect;
221  VC_RECT_T src_rect;
222  VC_DISPMANX_ALPHA_T dispman_alpha;
223  DISPMANX_UPDATE_HANDLE_T dispman_update;
224 
225  /* Disable alpha, otherwise the app looks composed with whatever dispman is showing (X11, console,etc) */
226  dispman_alpha.flags = DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS;
227  dispman_alpha.opacity = 0xFF;
228  dispman_alpha.mask = 0;
229 
230  /* Allocate window internal data */
231  wdata = (SDL_WindowData *) SDL_calloc(1, sizeof(SDL_WindowData));
232  if (wdata == NULL) {
233  return SDL_OutOfMemory();
234  }
235  display = SDL_GetDisplayForWindow(window);
236  displaydata = (SDL_DisplayData *) display->driverdata;
237 
238  /* Windows have one size for now */
239  window->w = display->desktop_mode.w;
240  window->h = display->desktop_mode.h;
241 
242  /* OpenGL ES is the law here, buddy */
243  window->flags |= SDL_WINDOW_OPENGL;
244 
245  /* Create a dispman element and associate a window to it */
246  dst_rect.x = 0;
247  dst_rect.y = 0;
248  dst_rect.width = window->w;
249  dst_rect.height = window->h;
250 
251  src_rect.x = 0;
252  src_rect.y = 0;
253  src_rect.width = window->w << 16;
254  src_rect.height = window->h << 16;
255 
256  dispman_update = vc_dispmanx_update_start( 0 );
257  wdata->dispman_window.element = vc_dispmanx_element_add ( dispman_update, displaydata->dispman_display, SDL_RPI_VIDEOLAYER /* layer */, &dst_rect, 0/*src*/, &src_rect, DISPMANX_PROTECTION_NONE, &dispman_alpha /*alpha*/, 0/*clamp*/, 0/*transform*/);
258  wdata->dispman_window.width = window->w;
259  wdata->dispman_window.height = window->h;
260  vc_dispmanx_update_submit_sync( dispman_update );
261 
262  if (!_this->egl_data) {
263  if (SDL_GL_LoadLibrary(NULL) < 0) {
264  return -1;
265  }
266  }
267  wdata->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) &wdata->dispman_window);
268 
269  if (wdata->egl_surface == EGL_NO_SURFACE) {
270  return SDL_SetError("Could not create GLES window surface");
271  }
272 
273  /* Setup driver data for this window */
274  window->driverdata = wdata;
275 
276  /* One window, it always has focus */
277  SDL_SetMouseFocus(window);
278  SDL_SetKeyboardFocus(window);
279 
280  /* Window has been successfully created */
281  return 0;
282 }
283 
284 void
286 {
287  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
288  if(data) {
289 #if SDL_VIDEO_OPENGL_EGL
290  if (data->egl_surface != EGL_NO_SURFACE) {
291  SDL_EGL_DestroySurface(_this, data->egl_surface);
292  }
293 #endif
294  SDL_free(data);
295  window->driverdata = NULL;
296  }
297 }
298 
299 int
300 RPI_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
301 {
302  return -1;
303 }
304 
305 void
307 {
308 }
309 void
311 {
312 }
313 void
315 {
316 }
317 void
319 {
320 }
321 void
323 {
324 }
325 void
327 {
328 }
329 void
331 {
332 }
333 void
335 {
336 }
337 void
339 {
340 }
341 void
343 {
344 }
345 void
346 RPI_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
347 {
348 
349 }
350 
351 /*****************************************************************************/
352 /* SDL Window Manager function */
353 /*****************************************************************************/
354 SDL_bool
355 RPI_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info)
356 {
357  if (info->version.major <= SDL_MAJOR_VERSION) {
358  return SDL_TRUE;
359  } else {
360  SDL_SetError("application not compiled with SDL %d.%d\n",
362  return SDL_FALSE;
363  }
364 
365  /* Failed to get window manager information */
366  return SDL_FALSE;
367 }
368 
369 #endif /* SDL_VIDEO_DRIVER_RPI */
370 
371 /* vi: set ts=4 sw=4 expandtab: */
#define SDL_RPI_VIDEOLAYER
Definition: SDL_rpivideo.h:53
#define SDL_MINOR_VERSION
Definition: SDL_version.h:61
void RPI_DestroyWindow(_THIS, SDL_Window *window)
void RPI_RestoreWindow(_THIS, SDL_Window *window)
void(* RestoreWindow)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:208
void * RPI_GLES_GetProcAddress(_THIS, const char *proc)
void SDL_SetKeyboardFocus(SDL_Window *window)
Definition: SDL_keyboard.c:612
int RPI_CreateWindowFrom(_THIS, SDL_Window *window, const void *data)
void RPI_SetWindowTitle(_THIS, SDL_Window *window)
void RPI_SetWindowGrab(_THIS, SDL_Window *window, SDL_bool grabbed)
int RPI_GLES_LoadLibrary(_THIS, const char *path)
#define SDL_MAJOR_VERSION
Definition: SDL_version.h:60
int(* CreateWindowFrom)(_THIS, SDL_Window *window, const void *data)
Definition: SDL_sysvideo.h:196
SDL_Window * window
void(* free)(_THIS)
Definition: SDL_sysvideo.h:345
void RPI_GLES_UnloadLibrary(_THIS)
void RPI_GetDisplayModes(_THIS, SDL_VideoDisplay *display)
A collection of pixels used in software blitting.
Definition: SDL_surface.h:69
int(* GL_SetSwapInterval)(_THIS, int interval)
Definition: SDL_sysvideo.h:240
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1967
int RPI_GLES_MakeCurrent(_THIS, SDL_Window *window, SDL_GLContext context)
void(* ShowWindow)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:203
The structure that defines a display mode.
Definition: SDL_video.h:53
SDL_version version
Definition: SDL_syswm.h:183
Uint8 major
Definition: SDL_version.h:53
void(* SetWindowSize)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:200
void RPI_RaiseWindow(_THIS, SDL_Window *window)
int RPI_GLES_GetSwapInterval(_THIS)
void RPI_MaximizeWindow(_THIS, SDL_Window *window)
void SDL_SetMouseFocus(SDL_Window *window)
Definition: SDL_mouse.c:103
void(* GL_SwapWindow)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:242
#define SDL_GL_LoadLibrary
int SDL_AddVideoDisplay(const SDL_VideoDisplay *display)
Definition: SDL_video.c:593
int(* GL_LoadLibrary)(_THIS, const char *path)
Definition: SDL_sysvideo.h:234
int RPI_VideoInit(_THIS)
int(* SetDisplayMode)(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode)
Definition: SDL_sysvideo.h:189
void RPI_SetWindowIcon(_THIS, SDL_Window *window, SDL_Surface *icon)
static SDL_VideoDevice * _this
Definition: SDL_video.c:114
SDL_bool
Definition: SDL_stdinc.h:126
void(* HideWindow)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:204
void(* RaiseWindow)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:205
void * SDL_calloc(size_t nmemb, size_t size)
SDL_bool(* GetWindowWMInfo)(_THIS, SDL_Window *window, struct SDL_SysWMinfo *info)
Definition: SDL_sysvideo.h:227
SDL_GLContext(* GL_CreateContext)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:237
#define _THIS
void RPI_PumpEvents(_THIS)
int(* GL_MakeCurrent)(_THIS, SDL_Window *window, SDL_GLContext context)
Definition: SDL_sysvideo.h:238
void SDL_free(void *mem)
EGL_DISPMANX_WINDOW_T dispman_window
Definition: SDL_rpivideo.h:47
void * driverdata
Definition: SDL_video.h:59
void RPI_HideWindow(_THIS, SDL_Window *window)
void RPI_SetWindowSize(_THIS, SDL_Window *window)
SDL_DisplayMode current_mode
Definition: SDL_sysvideo.h:127
GLenum mode
void(* DestroyWindow)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:214
void RPI_GLES_DeleteContext(_THIS, SDL_GLContext context)
#define SDL_zero(x)
Definition: SDL_stdinc.h:355
void(* SetWindowIcon)(_THIS, SDL_Window *window, SDL_Surface *icon)
Definition: SDL_sysvideo.h:198
DISPMANX_DISPLAY_HANDLE_T dispman_display
Definition: SDL_rpivideo.h:41
void RPI_VideoQuit(_THIS)
void(* GL_UnloadLibrary)(_THIS)
Definition: SDL_sysvideo.h:236
void(* GetDisplayModes)(_THIS, SDL_VideoDisplay *display)
Definition: SDL_sysvideo.h:181
#define NULL
Definition: begin_code.h:143
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
void RPI_GLES_SwapWindow(_THIS, SDL_Window *window)
SDL_DisplayMode desktop_mode
Definition: SDL_sysvideo.h:126
unsigned int uint32_t
void(* VideoQuit)(_THIS)
Definition: SDL_sysvideo.h:161
void RPI_ShowWindow(_THIS, SDL_Window *window)
void RPI_MinimizeWindow(_THIS, SDL_Window *window)
#define SDL_SetError
int RPI_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode)
SDL_VideoDisplay * SDL_GetDisplayForWindow(SDL_Window *window)
Definition: SDL_video.c:1039
void(* SetWindowPosition)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:199
int(* CreateWindow)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:195
The type used to identify a window.
Definition: SDL_sysvideo.h:71
SDL_GLContext RPI_GLES_CreateContext(_THIS, SDL_Window *window)
void(* MinimizeWindow)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:207
int RPI_CreateWindow(_THIS, SDL_Window *window)
SDL_bool SDL_AddDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode *mode)
Definition: SDL_video.c:709
int(* VideoInit)(_THIS)
Definition: SDL_sysvideo.h:155
GLubyte GLubyte GLubyte GLubyte w
void * driverdata
Definition: SDL_sysvideo.h:106
void(* GL_DeleteContext)(_THIS, SDL_GLContext context)
Definition: SDL_sysvideo.h:243
Uint32 format
Definition: SDL_video.h:55
void(* SetWindowTitle)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:197
int(* GL_GetSwapInterval)(_THIS)
Definition: SDL_sysvideo.h:241
void(* MaximizeWindow)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:206
Uint32 flags
Definition: SDL_sysvideo.h:81
SDL_bool RPI_GetWindowWMInfo(_THIS, SDL_Window *window, struct SDL_SysWMinfo *info)
void RPI_SetWindowPosition(_THIS, SDL_Window *window)
void(* SetWindowGrab)(_THIS, SDL_Window *window, SDL_bool grabbed)
Definition: SDL_sysvideo.h:213
void RPI_InitMouse(_THIS)
GLfloat GLfloat GLfloat GLfloat h
void *(* GL_GetProcAddress)(_THIS, const char *proc)
Definition: SDL_sysvideo.h:235
EGLSurface egl_surface
void(* PumpEvents)(_THIS)
Definition: SDL_sysvideo.h:249
int RPI_GLES_SetSwapInterval(_THIS, int interval)