From 7fe60435bce6595a9c58a9bfd8244d74b5320e96 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Tue, 15 Jan 2013 08:46:13 +0100 Subject: Import DirectFB141_2k11R3_beta5 --- Source/DirectFB/systems/sdl/sdl.c | 396 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 396 insertions(+) create mode 100755 Source/DirectFB/systems/sdl/sdl.c (limited to 'Source/DirectFB/systems/sdl/sdl.c') diff --git a/Source/DirectFB/systems/sdl/sdl.c b/Source/DirectFB/systems/sdl/sdl.c new file mode 100755 index 0000000..8ecc4ca --- /dev/null +++ b/Source/DirectFB/systems/sdl/sdl.c @@ -0,0 +1,396 @@ +/* + (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org) + (c) Copyright 2000-2004 Convergence (integrated media) GmbH + + All rights reserved. + + Written by Denis Oliver Kropp , + Andreas Hundt , + Sven Neumann , + Ville Syrjälä and + Claudio Ciccani . + + 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 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., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include + +#include +#include +#include + +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include + +#include "sdl.h" +#include "primary.h" + +#include + +DFB_CORE_SYSTEM( sdl ) + + +DFBSDL *dfb_sdl = NULL; +CoreDFB *dfb_sdl_core = NULL; + +extern const SurfacePoolFuncs sdlSurfacePoolFuncs; + +static DFBResult dfb_fbdev_read_modes( void ); + + +static void +system_get_info( CoreSystemInfo *info ) +{ + info->type = CORE_SDL; + info->caps = CSCAPS_ACCELERATION; + + snprintf( info->name, DFB_CORE_SYSTEM_INFO_NAME_LENGTH, "SDL" ); +} + +static DFBResult +system_initialize( CoreDFB *core, void **data ) +{ + char *driver; + CoreScreen *screen; + + D_ASSERT( dfb_sdl == NULL ); + + dfb_sdl = (DFBSDL*) SHCALLOC( dfb_core_shmpool(core), 1, sizeof(DFBSDL) ); + if (!dfb_sdl) { + D_ERROR( "DirectFB/SDL: Couldn't allocate shared memory!\n" ); + return D_OOSHM(); + } + + dfb_sdl_core = core; + + dfb_fbdev_read_modes(); /* use same mode list as a fake */ + + driver = getenv( "SDL_VIDEODRIVER" ); + if (driver && !strcasecmp( driver, "directfb" )) { + D_INFO( "DirectFB/SDL: SDL_VIDEODRIVER is 'directfb', unsetting it.\n" ); + unsetenv( "SDL_VIDEODRIVER" ); + } + + /* Initialize SDL */ + if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) { + D_ERROR( "DirectFB/SDL: Couldn't initialize SDL: %s\n", SDL_GetError() ); + + SHFREE( dfb_core_shmpool(core), dfb_sdl ); + dfb_sdl = NULL; + + return DFB_INIT; + } + + fusion_skirmish_init( &dfb_sdl->lock, "SDL System", dfb_core_world(core) ); + + fusion_call_init( &dfb_sdl->call, dfb_sdl_call_handler, NULL, dfb_core_world(core) ); + + screen = dfb_screens_register( NULL, NULL, &sdlPrimaryScreenFuncs ); + + dfb_layers_register( screen, NULL, &sdlPrimaryLayerFuncs ); + + fusion_arena_add_shared_field( dfb_core_arena( core ), "sdl", dfb_sdl ); + + dfb_surface_pool_initialize( core, &sdlSurfacePoolFuncs, &dfb_sdl->sdl_pool ); + + *data = dfb_sdl; + + return DFB_OK; +} + +static DFBResult +system_join( CoreDFB *core, void **data ) +{ + void *ret; + CoreScreen *screen; + + D_ASSERT( dfb_sdl == NULL ); + + fusion_arena_get_shared_field( dfb_core_arena( core ), "sdl", &ret ); + + dfb_sdl = ret; + dfb_sdl_core = core; + + screen = dfb_screens_register( NULL, NULL, &sdlPrimaryScreenFuncs ); + + dfb_layers_register( screen, NULL, &sdlPrimaryLayerFuncs ); + + dfb_surface_pool_join( core, dfb_sdl->sdl_pool, &sdlSurfacePoolFuncs ); + + *data = dfb_sdl; + + return DFB_OK; +} + +static DFBResult +system_shutdown( bool emergency ) +{ + FusionSHMPoolShared *pool; + + D_ASSERT( dfb_sdl != NULL ); + + /* Stop update thread. */ + if (dfb_sdl->update.thread) { + if (!emergency) { + dfb_sdl->update.quit = true; + + pthread_cond_signal( &dfb_sdl->update.cond ); + + direct_thread_join( dfb_sdl->update.thread ); + } + + direct_thread_destroy( dfb_sdl->update.thread ); + } + + dfb_surface_pool_destroy( dfb_sdl->sdl_pool ); + + fusion_call_destroy( &dfb_sdl->call ); + + fusion_skirmish_prevail( &dfb_sdl->lock ); + + SDL_Quit(); + + fusion_skirmish_destroy( &dfb_sdl->lock ); + + pool = dfb_core_shmpool(dfb_sdl_core); + + while (dfb_sdl->modes) { + VideoMode *next = dfb_sdl->modes->next; + + SHFREE( pool, dfb_sdl->modes ); + + dfb_sdl->modes = next; + } + + SHFREE( pool, dfb_sdl ); + dfb_sdl = NULL; + dfb_sdl_core = NULL; + + return DFB_OK; +} + +static DFBResult +system_leave( bool emergency ) +{ + D_ASSERT( dfb_sdl != NULL ); + + dfb_sdl = NULL; + dfb_sdl_core = NULL; + + return DFB_OK; +} + +static DFBResult +system_suspend( void ) +{ + return DFB_UNIMPLEMENTED; +} + +static DFBResult +system_resume( void ) +{ + return DFB_UNIMPLEMENTED; +} + +static volatile void * +system_map_mmio( unsigned int offset, + int length ) +{ + return NULL; +} + +static void +system_unmap_mmio( volatile void *addr, + int length ) +{ +} + +static int +system_get_accelerator( void ) +{ + return -1; +} + +static VideoMode * +system_get_modes( void ) +{ + return dfb_sdl->modes; +} + +static VideoMode * +system_get_current_mode( void ) +{ + return NULL; +} + +static DFBResult +system_thread_init( void ) +{ + return DFB_OK; +} + +static bool +system_input_filter( CoreInputDevice *device, + DFBInputEvent *event ) +{ + return false; +} + +static unsigned long +system_video_memory_physical( unsigned int offset ) +{ + return 0; +} + +static void * +system_video_memory_virtual( unsigned int offset ) +{ + return NULL; +} + +static unsigned int +system_videoram_length( void ) +{ + return 0; +} + +static unsigned long +system_aux_memory_physical( unsigned int offset ) +{ + return 0; +} + +static void * +system_aux_memory_virtual( unsigned int offset ) +{ + return NULL; +} + +static unsigned int +system_auxram_length( void ) +{ + return 0; +} + +static void +system_get_busid( int *ret_bus, int *ret_dev, int *ret_func ) +{ + return; +} + +static void +system_get_deviceid( unsigned int *ret_vendor_id, + unsigned int *ret_device_id ) +{ + return; +} + + +/* + * parses video modes in /etc/fb.modes and stores them in dfb_fbdev->shared->modes + * (to be replaced by DirectFB's own config system + */ +static DFBResult dfb_fbdev_read_modes( void ) +{ + FILE *fp; + char line[80],label[32],value[16]; + int geometry=0, timings=0; + int dummy; + VideoMode temp_mode; + VideoMode *m = dfb_sdl->modes; + + if (!(fp = fopen("/etc/fb.modes","r"))) + return errno2result( errno ); + + while (fgets(line,79,fp)) { + if (sscanf(line, "mode \"%31[^\"]\"",label) == 1) { + memset( &temp_mode, 0, sizeof(VideoMode) ); + geometry = 0; + timings = 0; + while (fgets(line,79,fp) && !(strstr(line,"endmode"))) { + if (5 == sscanf(line," geometry %d %d %d %d %d", &temp_mode.xres, &temp_mode.yres, &dummy, &dummy, &temp_mode.bpp)) { + geometry = 1; + } + else if (7 == sscanf(line," timings %d %d %d %d %d %d %d", &temp_mode.pixclock, &temp_mode.left_margin, &temp_mode.right_margin, + &temp_mode.upper_margin, &temp_mode.lower_margin, &temp_mode.hsync_len, &temp_mode.vsync_len)) { + timings = 1; + } + else if (1 == sscanf(line, " hsync %15s",value) && 0 == strcasecmp(value,"high")) { + temp_mode.hsync_high = 1; + } + else if (1 == sscanf(line, " vsync %15s",value) && 0 == strcasecmp(value,"high")) { + temp_mode.vsync_high = 1; + } + else if (1 == sscanf(line, " csync %15s",value) && 0 == strcasecmp(value,"high")) { + temp_mode.csync_high = 1; + } + else if (1 == sscanf(line, " laced %15s",value) && 0 == strcasecmp(value,"true")) { + temp_mode.laced = 1; + } + else if (1 == sscanf(line, " double %15s",value) && 0 == strcasecmp(value,"true")) { + temp_mode.doubled = 1; + } + else if (1 == sscanf(line, " gsync %15s",value) && 0 == strcasecmp(value,"true")) { + temp_mode.sync_on_green = 1; + } + else if (1 == sscanf(line, " extsync %15s",value) && 0 == strcasecmp(value,"true")) { + temp_mode.external_sync = 1; + } + else if (1 == sscanf(line, " bcast %15s",value) && 0 == strcasecmp(value,"true")) { + temp_mode.broadcast = 1; + } + } + if (geometry && timings) { + if (!m) { + dfb_sdl->modes = SHCALLOC( dfb_core_shmpool(dfb_sdl_core), 1, sizeof(VideoMode) ); + m = dfb_sdl->modes; + } + else { + m->next = SHCALLOC( dfb_core_shmpool(dfb_sdl_core), 1, sizeof(VideoMode) ); + m = m->next; + } + direct_memcpy (m, &temp_mode, sizeof(VideoMode)); + D_DEBUG( "DirectFB/FBDev: %20s %4dx%4d %s%s\n", label, temp_mode.xres, temp_mode.yres, + temp_mode.laced ? "interlaced " : "", temp_mode.doubled ? "doublescan" : "" ); + } + } + } + + fclose (fp); + + return DFB_OK; +} + -- cgit