SDL_rpivideo.c (10236B)
1/* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2014 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 52static int 53RPI_Available(void) 54{ 55 return 1; 56} 57 58static void 59RPI_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 68static SDL_VideoDevice * 69RPI_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) { 77 SDL_OutOfMemory(); 78 return NULL; 79 } 80 81 /* Initialize internal data */ 82 phdata = (SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData)); 83 if (phdata == NULL) { 84 SDL_OutOfMemory(); 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; 100 device->GetDisplayModes = RPI_GetDisplayModes; 101 device->SetDisplayMode = RPI_SetDisplayMode; 102 device->CreateWindow = RPI_CreateWindow; 103 device->CreateWindowFrom = RPI_CreateWindowFrom; 104 device->SetWindowTitle = RPI_SetWindowTitle; 105 device->SetWindowIcon = RPI_SetWindowIcon; 106 device->SetWindowPosition = RPI_SetWindowPosition; 107 device->SetWindowSize = RPI_SetWindowSize; 108 device->ShowWindow = RPI_ShowWindow; 109 device->HideWindow = RPI_HideWindow; 110 device->RaiseWindow = RPI_RaiseWindow; 111 device->MaximizeWindow = RPI_MaximizeWindow; 112 device->MinimizeWindow = RPI_MinimizeWindow; 113 device->RestoreWindow = RPI_RestoreWindow; 114 device->SetWindowGrab = RPI_SetWindowGrab; 115 device->DestroyWindow = RPI_DestroyWindow; 116 device->GetWindowWMInfo = RPI_GetWindowWMInfo; 117 device->GL_LoadLibrary = RPI_GLES_LoadLibrary; 118 device->GL_GetProcAddress = RPI_GLES_GetProcAddress; 119 device->GL_UnloadLibrary = RPI_GLES_UnloadLibrary; 120 device->GL_CreateContext = RPI_GLES_CreateContext; 121 device->GL_MakeCurrent = RPI_GLES_MakeCurrent; 122 device->GL_SetSwapInterval = RPI_GLES_SetSwapInterval; 123 device->GL_GetSwapInterval = RPI_GLES_GetSwapInterval; 124 device->GL_SwapWindow = RPI_GLES_SwapWindow; 125 device->GL_DeleteContext = RPI_GLES_DeleteContext; 126 127 device->PumpEvents = RPI_PumpEvents; 128 129 return device; 130} 131 132VideoBootStrap 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/*****************************************************************************/ 142int 143RPI_VideoInit(_THIS) 144{ 145 SDL_VideoDisplay display; 146 SDL_DisplayMode current_mode; 147 SDL_DisplayData *data; 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 188 RPI_InitMouse(_this); 189 190 return 1; 191} 192 193void 194RPI_VideoQuit(_THIS) 195{ 196#ifdef SDL_INPUT_LINUXEV 197 SDL_EVDEV_Quit(); 198#endif 199} 200 201void 202RPI_GetDisplayModes(_THIS, SDL_VideoDisplay * display) 203{ 204 /* Only one display mode available, the current one */ 205 SDL_AddDisplayMode(display, &display->current_mode); 206} 207 208int 209RPI_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) 210{ 211 return 0; 212} 213 214int 215RPI_CreateWindow(_THIS, SDL_Window * window) 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 284void 285RPI_DestroyWindow(_THIS, SDL_Window * window) 286{ 287 SDL_WindowData *data; 288 289 if(window->driverdata) { 290 data = (SDL_WindowData *) window->driverdata; 291 if (data->egl_surface != EGL_NO_SURFACE) { 292 SDL_EGL_DestroySurface(_this, data->egl_surface); 293 data->egl_surface = EGL_NO_SURFACE; 294 } 295 SDL_free(window->driverdata); 296 window->driverdata = NULL; 297 } 298} 299 300int 301RPI_CreateWindowFrom(_THIS, SDL_Window * window, const void *data) 302{ 303 return -1; 304} 305 306void 307RPI_SetWindowTitle(_THIS, SDL_Window * window) 308{ 309} 310void 311RPI_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon) 312{ 313} 314void 315RPI_SetWindowPosition(_THIS, SDL_Window * window) 316{ 317} 318void 319RPI_SetWindowSize(_THIS, SDL_Window * window) 320{ 321} 322void 323RPI_ShowWindow(_THIS, SDL_Window * window) 324{ 325} 326void 327RPI_HideWindow(_THIS, SDL_Window * window) 328{ 329} 330void 331RPI_RaiseWindow(_THIS, SDL_Window * window) 332{ 333} 334void 335RPI_MaximizeWindow(_THIS, SDL_Window * window) 336{ 337} 338void 339RPI_MinimizeWindow(_THIS, SDL_Window * window) 340{ 341} 342void 343RPI_RestoreWindow(_THIS, SDL_Window * window) 344{ 345} 346void 347RPI_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed) 348{ 349 350} 351 352/*****************************************************************************/ 353/* SDL Window Manager function */ 354/*****************************************************************************/ 355SDL_bool 356RPI_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info) 357{ 358 if (info->version.major <= SDL_MAJOR_VERSION) { 359 return SDL_TRUE; 360 } else { 361 SDL_SetError("application not compiled with SDL %d.%d\n", 362 SDL_MAJOR_VERSION, SDL_MINOR_VERSION); 363 return SDL_FALSE; 364 } 365 366 /* Failed to get window manager information */ 367 return SDL_FALSE; 368} 369 370#endif /* SDL_VIDEO_DRIVER_RPI */ 371 372/* vi: set ts=4 sw=4 expandtab: */