summaryrefslogtreecommitdiff
path: root/Source/DirectFB/src/misc/conf.c
diff options
context:
space:
mode:
Diffstat (limited to 'Source/DirectFB/src/misc/conf.c')
-rwxr-xr-xSource/DirectFB/src/misc/conf.c1947
1 files changed, 1947 insertions, 0 deletions
diff --git a/Source/DirectFB/src/misc/conf.c b/Source/DirectFB/src/misc/conf.c
new file mode 100755
index 0000000..5772ba9
--- /dev/null
+++ b/Source/DirectFB/src/misc/conf.c
@@ -0,0 +1,1947 @@
+/*
+ (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 <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ 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 <config.h>
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <directfb.h>
+#include <directfb_util.h>
+
+#include <direct/conf.h>
+#include <direct/log.h>
+#include <direct/mem.h>
+#include <direct/memcpy.h>
+#include <direct/messages.h>
+#include <direct/util.h>
+
+#include <fusion/conf.h>
+#include <fusion/vector.h>
+
+#include <voodoo/conf.h>
+
+#include <core/coretypes.h>
+#include <core/surface.h>
+#include <core/layers.h>
+
+#include <gfx/convert.h>
+
+#include <misc/conf.h>
+
+D_DEBUG_DOMAIN( DirectFB_Config, "DirectFB/Config", "Runtime configuration options for DirectFB" );
+
+DFBConfig *dfb_config = NULL;
+
+static const char *config_usage =
+ "DirectFB version " DIRECTFB_VERSION "\n"
+ "\n"
+ " --dfb-help Output DirectFB usage information and exit\n"
+ " --dfb:<option>[,<option>]... Pass options to DirectFB (see below)\n"
+ "\n"
+ "DirectFB options:\n"
+ "\n"
+ " system=<system> Specify the system (FBDev, SDL, etc.)\n"
+ " fbdev=<device> Open <device> instead of /dev/fb0\n"
+ " busid=<id> Specify the bus location of the graphics card (default 1:0:0)\n"
+ " mode=<width>x<height> Set the default resolution\n"
+ " scaled=<width>x<height> Scale the window to this size for 'force-windowed' apps\n"
+ " depth=<pixeldepth> Set the default pixel depth\n"
+ " pixelformat=<pixelformat> Set the default pixel format\n"
+ " surface-shmpool-size=<kb> Set the size of the shared memory pool used\n"
+ " for shared system memory surfaces.\n"
+ " session=<num> Select multi app world (zero based, -1 = new)\n"
+ " remote=<host>[:<session>] Select remote session to connect to\n"
+ " primary-layer=<id> Select an alternative primary layer\n"
+ " primary-only Tell application only about the primary layer\n"
+ " [no-]banner Show DirectFB Banner on startup\n"
+ " [no-]surface-sentinel Enable surface sentinels at the end of chunks in video memory\n"
+ " force-windowed Primary surface always is a window\n"
+ " force-desktop Primary surface is the desktop background\n"
+ " [no-]hardware Enable/disable hardware acceleration\n"
+ " [no-]software Enable/disable software fallbacks\n"
+ " [no-]software-warn Show warnings when doing/dropping software operations\n"
+ " [no-]software-trace Show every stage of the software rendering pipeline\n"
+ " [no-]dma Enable DMA acceleration\n"
+ " [no-]sync Do `sync()' (default=no)\n"
+#ifdef USE_MMX
+ " [no-]mmx Enable mmx support\n"
+#endif
+ " [no-]agp[=<mode>] Enable AGP support\n"
+ " [no-]thrifty-surface-buffers Free sysmem instance on xfer to video memory\n"
+ " font-format=<pixelformat> Set the preferred font format\n"
+ " [no-]font-premult Enable/disable premultiplied glyph images in ARGB format\n"
+ " [no-]deinit-check Enable deinit check at exit\n"
+ " block-all-signals Block all signals\n"
+ " [no-]vt-switch Allocate/switch to a new VT\n"
+ " vt-num=<num> Use given VT instead of current/new one\n"
+ " [no-]vt-switching Allow Ctrl+Alt+<F?> (EXPERIMENTAL)\n"
+ " [no-]graphics-vt Put terminal into graphics mode\n"
+ " [no-]vt Use VT handling code at all?\n"
+ " mouse-source=<device> Mouse device for serial mouse\n"
+ " [no-]mouse-gpm-source Enable mouse input repeated by GPM\n"
+ " [no-]motion-compression Mouse motion event compression\n"
+ " mouse-protocol=<protocol> Mouse protocol\n"
+ " [no-]lefty Swap left and right mouse buttons\n"
+ " [no-]capslock-meta Map the CapsLock key to Meta\n"
+ " linux-input-ir-only Ignore all non-IR Linux Input devices\n"
+ " [no-]linux-input-grab Grab Linux Input devices?\n"
+ " [no-]cursor Never create a cursor or handle it\n"
+ " [no-]cursor-updates Never show a cursor, but still handle it\n"
+ " wm=<wm> Window manager module ('default' or 'unique')\n"
+ " init-layer=<id> Initialize layer with ID (following layer- options apply)\n"
+ " layer-size=<width>x<height> Set the pixel resolution\n"
+ " layer-format=<pixelformat> Set the pixel format\n"
+ " layer-depth=<pixeldepth> Set the pixel depth\n"
+ " layer-buffer-mode=(auto|triple|backvideo|backsystem|frontonly|windows)\n"
+ " layer-bg-none Disable background clear\n"
+ " layer-bg-color=AARRGGBB Use background color (hex)\n"
+ " layer-bg-color-index=<index> Use background color index (decimal)\n"
+ " layer-bg-image=<filename> Use background image\n"
+ " layer-bg-tile=<filename> Use tiled background image\n"
+ " layer-src-key=AARRGGBB Enable color keying (hex)\n"
+ " layer-palette-<index>=AARRGGBB Set palette entry at index (hex)\n"
+ " layer-rotate=<degree> Set the layer rotation for double buffer mode (0,90,180,270)\n"
+ " [no-]smooth-upscale Enable/disable smooth upscaling per default\n"
+ " [no-]smooth-downscale Enable/disable smooth downscaling per default\n"
+ " [no-]translucent-windows Allow translucent windows\n"
+ " [no-]decorations Enable window decorations (if supported by wm)\n"
+ " [no-]startstop Issue StartDrawing/StopDrawing to driver\n"
+ " [no-]autoflip-window Auto flip non-flipping windowed primary surfaces\n"
+ " [no-]discard-repeat-events Discard repeat events (option per application)\n"
+ " videoram-limit=<amount> Limit amount of Video RAM in kb\n"
+ " agpmem-limit=<amount> Limit amount of AGP memory in kb\n"
+ " screenshot-dir=<directory> Dump screen content on <Print> key presses\n"
+ " video-phys=<hexaddress> Physical start of video memory (devmem system)\n"
+ " video-length=<bytes> Length of video memory (devmem system)\n"
+ " mmio-phys=<hexaddress> Physical start of MMIO area (devmem system)\n"
+ " mmio-length=<bytes> Length of MMIO area (devmem system)\n"
+ " accelerator=<id> Accelerator ID selecting graphics driver (devmem system)\n"
+ "\n"
+ " [no-]matrox-sgram Use Matrox SGRAM features\n"
+ " [no-]matrox-crtc2 Experimental Matrox CRTC2 support\n"
+ " matrox-tv-standard=(pal|ntsc|pal-60)\n"
+ " Matrox TV standard (default=pal)\n"
+ " matrox-cable-type=(composite|scart-rgb|scart-composite)\n"
+ " Matrox cable type (default=composite)\n"
+ " h3600-device=<device> Use this device for the H3600 TS driver\n"
+ " mut-device=<device> Use this device for the MuTouch driver\n"
+ " zytronic-device=<device> Use this device for the Zytronic driver\n"
+ " elo-device=<device> Use this device for the Elo driver\n"
+ " penmount-device=<device> Use this device for the PenMount driver\n"
+ " linux-input-devices=<device>[[,<device>]...]\n"
+ " Use these devices for the Linux Input driver\n"
+ " tslib-devices=<device>[[,<device>]...]\n"
+ " Use these devices for the tslib driver\n"
+ " unichrome-revision=<rev> Override unichrome hardware revision\n"
+ " i8xx_overlay_pipe_b Redirect videolayer to pixelpipe B\n"
+ " include=<config file> Include the specified file, relative to the current file\n"
+ " flip-notify-max-latency=<ms> Set maximum FlipNotify latency (ms from Flip til Notify)\n"
+ "\n"
+ " Window surface swapping policy:\n"
+ " window-surface-policy=(auto|videohigh|videolow|systemonly|videoonly)\n"
+ " auto: DirectFB decides depending on hardware.\n"
+ " videohigh: Swapping system/video with high priority.\n"
+ " videolow: Swapping system/video with low priority.\n"
+ " systemonly: Window surface is always stored in system memory.\n"
+ " videoonly: Window surface is always stored in video memory.\n"
+ "\n"
+ " Desktop buffer mode:\n"
+ " desktop-buffer-mode=(auto|triple|backvideo|backsystem|frontonly|windows)\n"
+ " auto: DirectFB decides depending on hardware.\n"
+ " triple: Triple buffering (video only).\n"
+ " backvideo: Front and back buffer are video only.\n"
+ " backsystem: Back buffer is system only.\n"
+ " frontonly: There is no back buffer.\n"
+ " windows: Special mode with window buffers directly displayed.\n"
+ "\n"
+ " Force synchronization of vertical retrace:\n"
+ " vsync-after: Wait for the vertical retrace after flipping.\n"
+ " vsync-none: disable polling for vertical retrace.\n"
+ "\n";
+
+/**********************************************************************************************************************/
+
+/* serial mouse device names */
+#define DEV_NAME "/dev/mouse"
+#define DEV_NAME_GPM "/dev/gpmdata"
+
+/**********************************************************************************************************************/
+
+DFBSurfacePixelFormat
+dfb_config_parse_pixelformat( const char *format )
+{
+ int i;
+ size_t length = strlen(format);
+
+ for (i=0; dfb_pixelformat_names[i].format != DSPF_UNKNOWN; i++) {
+ if (!strcasecmp( format, dfb_pixelformat_names[i].name ))
+ return dfb_pixelformat_names[i].format;
+ }
+
+ for (i=0; dfb_pixelformat_names[i].format != DSPF_UNKNOWN; i++) {
+ if (!strncasecmp( format, dfb_pixelformat_names[i].name, length ))
+ return dfb_pixelformat_names[i].format;
+ }
+
+ return DSPF_UNKNOWN;
+}
+
+/**********************************************************************************************************************/
+
+static void
+print_config_usage( void )
+{
+ fprintf( stderr, "%s%s%s", config_usage, fusion_config_usage, direct_config_usage );
+}
+
+static DFBResult
+parse_args( const char *args )
+{
+ char *buf = alloca( strlen(args) + 1 );
+
+ strcpy( buf, args );
+
+ while (buf && buf[0]) {
+ DFBResult ret;
+ char *value;
+ char *next;
+
+ if ((next = strchr( buf, ',' )) != NULL)
+ *next++ = '\0';
+
+ if (strcmp (buf, "help") == 0) {
+ print_config_usage();
+ exit(1);
+ }
+
+ if (strcmp (buf, "memcpy=help") == 0) {
+ direct_print_memcpy_routines();
+ exit(1);
+ }
+
+ if ((value = strchr( buf, '=' )) != NULL)
+ *value++ = '\0';
+
+ ret = dfb_config_set( buf, value );
+ switch (ret) {
+ case DFB_OK:
+ break;
+ case DFB_UNSUPPORTED:
+ D_ERROR( "DirectFB/Config: Unknown option '%s'!\n", buf );
+ break;
+ default:
+ return ret;
+ }
+
+ buf = next;
+ }
+
+ return DFB_OK;
+}
+
+static void config_values_parse( FusionVector *vector, const char *arg )
+{
+ char *values = D_STRDUP( arg );
+ char *s = values;
+ char *r, *p = NULL;
+
+ if (!values) {
+ D_OOM();
+ return;
+ }
+
+ while ((r = strtok_r( s, ",", &p ))) {
+ direct_trim( &r );
+
+ r = D_STRDUP( r );
+ if (!r)
+ D_OOM();
+ else
+ fusion_vector_add( vector, r );
+
+ s = NULL;
+ }
+
+ D_FREE( values );
+}
+
+static void config_values_free( FusionVector *vector )
+{
+ char *value;
+ int i;
+
+ fusion_vector_foreach (value, i, *vector)
+ D_FREE( value );
+
+ fusion_vector_destroy( vector );
+ fusion_vector_init( vector, 2, NULL );
+}
+
+static int config_read_cmdline( char *cmdbuf, int size, FILE *f )
+{
+ int ret = 0;
+ int len = 0;
+
+ ret = fread( cmdbuf, 1, 1, f );
+
+ /* empty dividing 0 */
+ if( ret==1 && *cmdbuf==0 ) {
+ ret = fread( cmdbuf, 1, 1, f );
+ }
+
+ while(ret==1 && len<(size-1)) {
+ len++;
+ ret = fread( ++cmdbuf, 1, 1, f );
+ if( *cmdbuf == 0 )
+ break;
+ }
+
+ if( len ) {
+ cmdbuf[len]=0;
+ }
+
+ return len != 0;
+}
+
+/*
+ * The following function isn't used because the configuration should
+ * only go away if the application is completely terminated. In that case
+ * the memory is freed anyway.
+ */
+
+#if 0
+static void config_cleanup( void )
+{
+ if (!dfb_config) {
+ D_BUG("config_cleanup() called with no config allocated!");
+ return;
+ }
+
+ if (dfb_config->fb_device)
+ D_FREE( dfb_config->fb_device );
+
+ if (dfb_config->layer_bg_filename)
+ D_FREE( dfb_config->layer_bg_filename );
+
+ D_FREE( dfb_config );
+ dfb_config = NULL;
+}
+#endif
+
+/*
+ * allocates config and fills it with defaults
+ */
+static void config_allocate( void )
+{
+ int i;
+
+ if (dfb_config)
+ return;
+
+ dfb_config = (DFBConfig*) calloc( 1, sizeof(DFBConfig) );
+
+ for (i=0; i<D_ARRAY_SIZE(dfb_config->layers); i++) {
+ dfb_config->layers[i].src_key_index = -1;
+
+ dfb_config->layers[i].background.color.a = 0;
+ dfb_config->layers[i].background.color.r = 0;
+ dfb_config->layers[i].background.color.g = 0;
+ dfb_config->layers[i].background.color.b = 0;
+ dfb_config->layers[i].background.color_index = -1;
+ dfb_config->layers[i].background.mode = DLBM_COLOR;
+ }
+
+ dfb_config->layers[0].init = true;
+ dfb_config->layers[0].background.color.a = 0xff;
+ dfb_config->layers[0].background.color.r = 0xc0;
+ dfb_config->layers[0].background.color.g = 0xb0;
+ dfb_config->layers[0].background.color.b = 0x90;
+ dfb_config->layers[0].stacking = (1 << DWSC_UPPER) |
+ (1 << DWSC_MIDDLE) |
+ (1 << DWSC_LOWER);
+
+
+ dfb_config->pci.bus = 1;
+ dfb_config->pci.dev = 0;
+ dfb_config->pci.func = 0;
+
+ dfb_config->banner = true;
+ dfb_config->deinit_check = true;
+ dfb_config->mmx = true;
+ dfb_config->vt = true;
+ dfb_config->vt_switch = true;
+ dfb_config->vt_num = -1;
+ dfb_config->vt_switching = true;
+ dfb_config->kd_graphics = true;
+ dfb_config->translucent_windows = true;
+ dfb_config->font_premult = true;
+ dfb_config->mouse_motion_compression = false;
+ dfb_config->mouse_gpm_source = false;
+ dfb_config->mouse_source = D_STRDUP( DEV_NAME );
+ dfb_config->linux_input_grab = false;
+ dfb_config->window_policy = -1;
+ dfb_config->buffer_mode = -1;
+ dfb_config->wm = D_STRDUP( "default" );
+ dfb_config->decorations = true;
+ dfb_config->unichrome_revision = -1;
+ dfb_config->dma = false;
+ dfb_config->agp = 0;
+ dfb_config->matrox_tv_std = DSETV_PAL;
+ dfb_config->i8xx_overlay_pipe_b = false;
+ dfb_config->surface_shmpool_size = 64 * 1024 * 1024;
+ dfb_config->keep_accumulators = 1024;
+ dfb_config->font_format = DSPF_A8;
+ dfb_config->flip_notify_max_latency = 0;
+
+ /* default to fbdev */
+ dfb_config->system = D_STRDUP( "FBDev" );
+
+ /* default to no-vt-switch if we don't have root privileges */
+ if (geteuid())
+ dfb_config->vt_switch = false;
+
+ fusion_vector_init( &dfb_config->linux_input_devices, 2, NULL );
+ fusion_vector_init( &dfb_config->tslib_devices, 2, NULL );
+}
+
+const char *dfb_config_usage( void )
+{
+ return config_usage;
+}
+
+DFBResult dfb_config_set( const char *name, const char *value )
+{
+ if (strcmp (name, "system" ) == 0) {
+ if (value) {
+ if (dfb_config->system)
+ D_FREE( dfb_config->system );
+ dfb_config->system = D_STRDUP( value );
+ }
+ else {
+ D_ERROR("DirectFB/Config 'system': No system specified!\n");
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "wm" ) == 0) {
+ if (value) {
+ if (dfb_config->wm)
+ D_FREE( dfb_config->wm );
+ dfb_config->wm = D_STRDUP( value );
+ }
+ else {
+ D_ERROR("DirectFB/Config 'wm': No window manager specified!\n");
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "fbdev" ) == 0) {
+ if (value) {
+ if (dfb_config->fb_device)
+ D_FREE( dfb_config->fb_device );
+ dfb_config->fb_device = D_STRDUP( value );
+ }
+ else {
+ D_ERROR("DirectFB/Config 'fbdev': No device name specified!\n");
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "busid") == 0 || strcmp (name, "pci-id") == 0) {
+ if (value) {
+ int bus, dev, func;
+
+ if (sscanf( value, "%d:%d:%d", &bus, &dev, &func ) != 3) {
+ D_ERROR( "DirectFB/Config 'busid': Could not parse busid!\n");
+ return DFB_INVARG;
+ }
+
+ dfb_config->pci.bus = bus;
+ dfb_config->pci.dev = dev;
+ dfb_config->pci.func = func;
+ }
+ } else
+ if (strcmp (name, "screenshot-dir" ) == 0) {
+ if (value) {
+ if (dfb_config->screenshot_dir)
+ D_FREE( dfb_config->screenshot_dir );
+ dfb_config->screenshot_dir = D_STRDUP( value );
+ }
+ else {
+ D_ERROR("DirectFB/Config 'screenshot-dir': No directory name specified!\n");
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "scaled" ) == 0) {
+ if (value) {
+ int width, height;
+
+ if (sscanf( value, "%dx%d", &width, &height ) < 2) {
+ D_ERROR("DirectFB/Config 'scaled': Could not parse size!\n");
+ return DFB_INVARG;
+ }
+
+ dfb_config->scaled.width = width;
+ dfb_config->scaled.height = height;
+ }
+ else {
+ D_ERROR("DirectFB/Config 'scaled': No size specified!\n");
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "primary-layer" ) == 0) {
+ if (value) {
+ int id;
+
+ if (sscanf( value, "%d", &id ) < 1) {
+ D_ERROR("DirectFB/Config 'primary-layer': Could not parse id!\n");
+ return DFB_INVARG;
+ }
+
+ dfb_config->primary_layer = id;
+ }
+ else {
+ D_ERROR("DirectFB/Config 'primary-layer': No id specified!\n");
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "primary-only" ) == 0) {
+ dfb_config->primary_only = true;
+ } else
+ if (strcmp (name, "font-format" ) == 0) {
+ if (value) {
+ DFBSurfacePixelFormat format;
+
+ format = dfb_config_parse_pixelformat( value );
+ if (format == DSPF_UNKNOWN) {
+ D_ERROR("DirectFB/Config 'font-format': Could not parse format!\n");
+ return DFB_INVARG;
+ }
+
+ dfb_config->font_format = format;
+ }
+ else {
+ D_ERROR("DirectFB/Config 'font-format': No format specified!\n");
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "font-premult" ) == 0) {
+ dfb_config->font_premult = true;
+ } else
+ if (strcmp (name, "no-font-premult" ) == 0) {
+ dfb_config->font_premult = false;
+ } else
+ if (!strcmp( name, "surface-shmpool-size" )) {
+ if (value) {
+ int size_kb;
+
+ if (sscanf( value, "%d", &size_kb ) < 1) {
+ D_ERROR( "DirectFB/Config '%s': Could not parse value!\n", name);
+ return DFB_INVARG;
+ }
+
+ dfb_config->surface_shmpool_size = size_kb * 1024;
+ }
+ else {
+ D_ERROR( "DirectFB/Config '%s': No value specified!\n", name );
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "session" ) == 0) {
+ if (value) {
+ int session;
+
+ if (sscanf( value, "%d", &session ) < 1) {
+ D_ERROR("DirectFB/Config 'session': Could not parse value!\n");
+ return DFB_INVARG;
+ }
+
+ dfb_config->session = session;
+ }
+ else {
+ D_ERROR("DirectFB/Config 'session': No value specified!\n");
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "remote" ) == 0) {
+ if (value) {
+ char *colon;
+
+ colon = strchr( value, ':' );
+ if (colon) {
+ int len = (long) colon - (long) value;
+ int port = 0;
+
+ if (direct_sscanf( colon + 1, "%d", &port ) < 1) {
+ D_ERROR("DirectFB/Config 'remote': "
+ "Could not parse value (format is <host>[:<port>])!\n");
+ return DFB_INVARG;
+ }
+
+ if (dfb_config->remote.host)
+ D_FREE( dfb_config->remote.host );
+
+ dfb_config->remote.host = D_MALLOC( len+1 );
+ dfb_config->remote.session = port;
+
+ direct_snputs( dfb_config->remote.host, value, len+1 );
+ }
+ else {
+ if (dfb_config->remote.host)
+ D_FREE( dfb_config->remote.host );
+
+ dfb_config->remote.host = D_STRDUP( value );
+ dfb_config->remote.session = 0;
+ }
+ }
+ else {
+ if (dfb_config->remote.host)
+ D_FREE( dfb_config->remote.host );
+
+ dfb_config->remote.host = D_STRDUP( "" );
+ dfb_config->remote.session = 0;
+ }
+ } else
+ if (strcmp (name, "videoram-limit" ) == 0) {
+ if (value) {
+ int limit;
+
+ if (sscanf( value, "%d", &limit ) < 1) {
+ D_ERROR("DirectFB/Config 'videoram-limit': Could not parse value!\n");
+ return DFB_INVARG;
+ }
+
+ if (limit < 0)
+ limit = 0;
+
+ dfb_config->videoram_limit = limit << 10;
+ }
+ else {
+ D_ERROR("DirectFB/Config 'videoram-limit': No value specified!\n");
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "keep-accumulators" ) == 0) {
+ if (value) {
+ int limit;
+
+ if (sscanf( value, "%d", &limit ) < 1) {
+ D_ERROR("DirectFB/Config '%s': Could not parse value!\n", name);
+ return DFB_INVARG;
+ }
+
+ dfb_config->keep_accumulators = limit;
+ }
+ else {
+ D_ERROR("DirectFB/Config '%s': No value specified!\n", name);
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "banner" ) == 0) {
+ dfb_config->banner = true;
+ } else
+ if (strcmp (name, "no-banner" ) == 0) {
+ dfb_config->banner = false;
+ } else
+ if (strcmp (name, "surface-sentinel" ) == 0) {
+ dfb_config->surface_sentinel = true;
+ } else
+ if (strcmp (name, "no-surface-sentinel" ) == 0) {
+ dfb_config->surface_sentinel = false;
+ } else
+ if (strcmp (name, "force-windowed" ) == 0) {
+ dfb_config->force_windowed = true;
+ } else
+ if (strcmp (name, "force-desktop" ) == 0) {
+ dfb_config->force_desktop = true;
+ } else
+ if (strcmp (name, "hardware" ) == 0) {
+ dfb_config->software_only = false;
+ } else
+ if (strcmp (name, "no-hardware" ) == 0) {
+ dfb_config->software_only = true;
+ } else
+ if (strcmp (name, "software" ) == 0) {
+ dfb_config->hardware_only = false;
+ } else
+ if (strcmp (name, "no-software" ) == 0) {
+ dfb_config->hardware_only = true;
+ } else
+ if (strcmp (name, "software-warn" ) == 0) {
+ dfb_config->software_warn = true;
+ } else
+ if (strcmp (name, "no-software-warn" ) == 0) {
+ dfb_config->software_warn = false;
+ } else
+ if (strcmp (name, "software-trace" ) == 0) {
+ dfb_config->software_trace = true;
+ } else
+ if (strcmp (name, "no-software-trace" ) == 0) {
+ dfb_config->software_trace = false;
+ } else
+ if (strcmp (name, "warn" ) == 0 || strcmp (name, "no-warn" ) == 0) {
+ /* Enable/disable all at once by default. */
+ DFBConfigWarnFlags flags = DMT_ALL;
+
+ /* Find out the specific message type being configured. */
+ if (value) {
+ char *opt = strchr( value, ':' );
+
+ if (opt)
+ opt++;
+
+ if (!strncmp( value, "create-surface", 14 )) {
+ flags = DCWF_CREATE_SURFACE;
+
+ if (opt)
+ sscanf( opt, "%dx%d",
+ &dfb_config->warn.create_surface.min_size.w,
+ &dfb_config->warn.create_surface.min_size.h );
+ } else
+ if (!strncmp( value, "create-window", 13 )) {
+ flags = DCWF_CREATE_WINDOW;
+ } else
+ if (!strncmp( value, "allocate-buffer", 15 )) {
+ flags = DCWF_ALLOCATE_BUFFER;
+
+ if (opt)
+ sscanf( opt, "%dx%d",
+ &dfb_config->warn.allocate_buffer.min_size.w,
+ &dfb_config->warn.allocate_buffer.min_size.h );
+ }
+ else {
+ D_ERROR( "DirectFB/Config '%s': Unknown warning type '%s'!\n", name, value );
+ return DFB_INVARG;
+ }
+ }
+
+ /* Set/clear the corresponding flag in the configuration. */
+ if (name[0] == 'w')
+ dfb_config->warn.flags |= flags;
+ else
+ dfb_config->warn.flags &= ~flags;
+ } else
+ if (strcmp (name, "dma" ) == 0) {
+ dfb_config->dma = true;
+ } else
+ if (strcmp (name, "no-dma" ) == 0) {
+ dfb_config->dma = false;
+ } else
+ if (strcmp (name, "mmx" ) == 0) {
+ dfb_config->mmx = true;
+ } else
+ if (strcmp (name, "no-mmx" ) == 0) {
+ dfb_config->mmx = false;
+ } else
+ if (strcmp (name, "agp" ) == 0) {
+ if (value) {
+ int mode;
+
+ if (sscanf( value, "%d", &mode ) < 1 || mode < 0 || mode > 8) {
+ D_ERROR( "DirectFB/Config 'agp': "
+ "invalid agp mode '%s'!\n", value );
+ return DFB_INVARG;
+ }
+
+ dfb_config->agp = mode;
+ }
+ else {
+ dfb_config->agp = 8; /* maximum possible */
+ }
+ } else
+ if (strcmp (name, "thrifty-surface-buffers" ) == 0) {
+ dfb_config->thrifty_surface_buffers = true;
+ } else
+ if (strcmp (name, "no-thrifty-surface-buffers" ) == 0) {
+ dfb_config->thrifty_surface_buffers = false;
+ } else
+ if (strcmp (name, "no-agp" ) == 0) {
+ dfb_config->agp = 0;
+ } else
+ if (strcmp (name, "agpmem-limit" ) == 0) {
+ if (value) {
+ int limit;
+
+ if (sscanf( value, "%d", &limit ) < 1) {
+ D_ERROR( "DirectFB/Config 'agpmem-limit': "
+ "Could not parse value!\n" );
+ return DFB_INVARG;
+ }
+
+ if (limit < 0)
+ limit = 0;
+
+ dfb_config->agpmem_limit = limit << 10;
+ }
+ else {
+ D_ERROR("DirectFB/Config 'agpmem-limit': No value specified!\n");
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "vt" ) == 0) {
+ dfb_config->vt = true;
+ } else
+ if (strcmp (name, "no-vt" ) == 0) {
+ dfb_config->vt = false;
+ } else
+ if (strcmp (name, "block-all-signals" ) == 0) {
+ dfb_config->block_all_signals = true;
+ } else
+ if (strcmp (name, "deinit-check" ) == 0) {
+ dfb_config->deinit_check = true;
+ } else
+ if (strcmp (name, "no-deinit-check" ) == 0) {
+ dfb_config->deinit_check = false;
+ } else
+ if (strcmp (name, "cursor" ) == 0) {
+ dfb_config->no_cursor = false;
+ } else
+ if (strcmp (name, "no-cursor" ) == 0) {
+ dfb_config->no_cursor = true;
+ } else
+ if (strcmp (name, "cursor-updates" ) == 0) {
+ dfb_config->no_cursor_updates = false;
+ } else
+ if (strcmp (name, "no-cursor-updates" ) == 0) {
+ dfb_config->no_cursor_updates = true;
+ } else
+ if (strcmp (name, "linux-input-ir-only" ) == 0) {
+ dfb_config->linux_input_ir_only = true;
+ } else
+ if (strcmp (name, "linux-input-grab" ) == 0) {
+ dfb_config->linux_input_grab = true;
+ } else
+ if (strcmp (name, "no-linux-input-grab" ) == 0) {
+ dfb_config->linux_input_grab = false;
+ } else
+ if (strcmp (name, "motion-compression" ) == 0) {
+ dfb_config->mouse_motion_compression = true;
+ } else
+ if (strcmp (name, "no-motion-compression" ) == 0) {
+ dfb_config->mouse_motion_compression = false;
+ } else
+ if (strcmp (name, "mouse-protocol" ) == 0) {
+ if (value) {
+ dfb_config->mouse_protocol = D_STRDUP( value );
+ }
+ else {
+ D_ERROR( "DirectFB/Config: No mouse protocol specified!\n" );
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "mouse-source" ) == 0) {
+ if (value) {
+ D_FREE( dfb_config->mouse_source );
+ dfb_config->mouse_source = D_STRDUP( value );
+ }
+ else {
+ D_ERROR( "DirectFB/Config: No mouse source specified!\n" );
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "mouse-gpm-source" ) == 0) {
+ dfb_config->mouse_gpm_source = true;
+ D_FREE( dfb_config->mouse_source );
+ dfb_config->mouse_source = D_STRDUP( DEV_NAME_GPM );
+ } else
+ if (strcmp (name, "no-mouse-gpm-source" ) == 0) {
+ dfb_config->mouse_gpm_source = false;
+ D_FREE( dfb_config->mouse_source );
+ dfb_config->mouse_source = D_STRDUP( DEV_NAME );
+ } else
+ if (strcmp (name, "smooth-upscale" ) == 0) {
+ dfb_config->render_options |= DSRO_SMOOTH_UPSCALE;
+ } else
+ if (strcmp (name, "no-smooth-upscale" ) == 0) {
+ dfb_config->render_options &= ~DSRO_SMOOTH_UPSCALE;
+ } else
+ if (strcmp (name, "smooth-downscale" ) == 0) {
+ dfb_config->render_options |= DSRO_SMOOTH_DOWNSCALE;
+ } else
+ if (strcmp (name, "no-smooth-downscale" ) == 0) {
+ dfb_config->render_options &= ~DSRO_SMOOTH_DOWNSCALE;
+ } else
+ if (strcmp (name, "translucent-windows" ) == 0) {
+ dfb_config->translucent_windows = true;
+ } else
+ if (strcmp (name, "no-translucent-windows" ) == 0) {
+ dfb_config->translucent_windows = false;
+ } else
+ if (strcmp (name, "decorations" ) == 0) {
+ dfb_config->decorations = true;
+ } else
+ if (strcmp (name, "no-decorations" ) == 0) {
+ dfb_config->decorations = false;
+ } else
+ if (strcmp (name, "startstop" ) == 0) {
+ dfb_config->startstop = true;
+ } else
+ if (strcmp (name, "no-startstop" ) == 0) {
+ dfb_config->startstop = false;
+ } else
+ if (strcmp (name, "autoflip-window" ) == 0) {
+ dfb_config->autoflip_window = true;
+ } else
+ if (strcmp (name, "no-autoflip-window" ) == 0) {
+ dfb_config->autoflip_window = false;
+ } else
+ if (strcmp (name, "discard-repeat-events" ) == 0) {
+ dfb_config->discard_repeat_events = true;
+ } else
+ if (strcmp (name, "no-discard-repeat-events" ) == 0) {
+ dfb_config->discard_repeat_events = false;
+ } else
+ if (strcmp (name, "vsync-none" ) == 0) {
+ dfb_config->pollvsync_none = true;
+ } else
+ if (strcmp (name, "vsync-after" ) == 0) {
+ dfb_config->pollvsync_after = true;
+ } else
+ if (strcmp (name, "vt-switch" ) == 0) {
+ dfb_config->vt_switch = true;
+ } else
+ if (strcmp (name, "no-vt-switch" ) == 0) {
+ dfb_config->vt_switch = false;
+ } else
+ if (strcmp (name, "vt-num" ) == 0) {
+ if (value) {
+ int vt_num;
+
+ if (sscanf( value, "%d", &vt_num ) < 1) {
+ D_ERROR("DirectFB/Config 'vt-num': Could not parse value!\n");
+ return DFB_INVARG;
+ }
+
+ dfb_config->vt_num = vt_num;
+ }
+ else {
+ D_ERROR("DirectFB/Config 'vt-num': No value specified!\n");
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "vt-switching" ) == 0) {
+ dfb_config->vt_switching = true;
+ } else
+ if (strcmp (name, "no-vt-switching" ) == 0) {
+ dfb_config->vt_switching = false;
+ } else
+ if (strcmp (name, "graphics-vt" ) == 0) {
+ dfb_config->kd_graphics = true;
+ } else
+ if (strcmp (name, "no-graphics-vt" ) == 0) {
+ dfb_config->kd_graphics = false;
+ } else
+ if (strcmp (name, "window-surface-policy" ) == 0) {
+ if (value) {
+ if (strcmp( value, "auto" ) == 0) {
+ dfb_config->window_policy = -1;
+ } else
+ if (strcmp( value, "videohigh" ) == 0) {
+ dfb_config->window_policy = CSP_VIDEOHIGH;
+ } else
+ if (strcmp( value, "videolow" ) == 0) {
+ dfb_config->window_policy = CSP_VIDEOLOW;
+ } else
+ if (strcmp( value, "systemonly" ) == 0) {
+ dfb_config->window_policy = CSP_SYSTEMONLY;
+ } else
+ if (strcmp( value, "videoonly" ) == 0) {
+ dfb_config->window_policy = CSP_VIDEOONLY;
+ }
+ else {
+ D_ERROR( "DirectFB/Config: "
+ "Unknown window surface policy `%s'!\n", value );
+ return DFB_INVARG;
+ }
+ }
+ else {
+ D_ERROR( "DirectFB/Config: "
+ "No window surface policy specified!\n" );
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "init-layer" ) == 0) {
+ if (value) {
+ int id;
+
+ if (sscanf( value, "%d", &id ) < 1) {
+ D_ERROR("DirectFB/Config '%s': Could not parse id!\n", name);
+ return DFB_INVARG;
+ }
+
+ if (id < 0 || id > D_ARRAY_SIZE(dfb_config->layers)) {
+ D_ERROR("DirectFB/Config '%s': ID %d out of bounds!\n", name, id);
+ return DFB_INVARG;
+ }
+
+ dfb_config->layers[id].init = true;
+
+ dfb_config->config_layer = &dfb_config->layers[id];
+ }
+ else {
+ D_ERROR("DirectFB/Config '%s': No id specified!\n", name);
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "no-init-layer" ) == 0) {
+ if (value) {
+ int id;
+
+ if (sscanf( value, "%d", &id ) < 1) {
+ D_ERROR("DirectFB/Config '%s': Could not parse id!\n", name);
+ return DFB_INVARG;
+ }
+
+ if (id < 0 || id > D_ARRAY_SIZE(dfb_config->layers)) {
+ D_ERROR("DirectFB/Config '%s': ID %d out of bounds!\n", name, id);
+ return DFB_INVARG;
+ }
+
+ dfb_config->layers[id].init = false;
+
+ dfb_config->config_layer = &dfb_config->layers[id];
+ }
+ else
+ dfb_config->layers[0].init = false;
+ } else
+ if (strcmp (name, "mode" ) == 0 || strcmp (name, "layer-size" ) == 0) {
+ DFBConfigLayer *conf = dfb_config->config_layer;
+
+ if (value) {
+ int width, height;
+
+ if (sscanf( value, "%dx%d", &width, &height ) < 2) {
+ D_ERROR("DirectFB/Config '%s': Could not parse width and height!\n", name);
+ return DFB_INVARG;
+ }
+
+ if (conf == &dfb_config->layers[0]) {
+ dfb_config->mode.width = width;
+ dfb_config->mode.height = height;
+ }
+
+ conf->config.width = width;
+ conf->config.height = height;
+
+ conf->config.flags |= DLCONF_WIDTH | DLCONF_HEIGHT;
+ }
+ else {
+ D_ERROR("DirectFB/Config '%s': No width and height specified!\n", name);
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "depth" ) == 0 || strcmp (name, "layer-depth" ) == 0) {
+ DFBConfigLayer *conf = dfb_config->config_layer;
+
+ if (value) {
+ int depth;
+
+ if (sscanf( value, "%d", &depth ) < 1) {
+ D_ERROR("DirectFB/Config '%s': Could not parse value!\n", name);
+ return DFB_INVARG;
+ }
+
+ if (conf == &dfb_config->layers[0]) {
+ dfb_config->mode.depth = depth;
+ }
+
+ conf->config.pixelformat = dfb_pixelformat_for_depth( depth );
+ conf->config.flags |= DLCONF_PIXELFORMAT;
+ }
+ else {
+ D_ERROR("DirectFB/Config '%s': No value specified!\n", name);
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "pixelformat" ) == 0 || strcmp (name, "layer-format" ) == 0) {
+ DFBConfigLayer *conf = dfb_config->config_layer;
+
+ if (value) {
+ DFBSurfacePixelFormat format;
+
+ format = dfb_config_parse_pixelformat( value );
+ if (format == DSPF_UNKNOWN) {
+ D_ERROR("DirectFB/Config '%s': Could not parse format!\n", name);
+ return DFB_INVARG;
+ }
+
+ if (conf == &dfb_config->layers[0])
+ dfb_config->mode.format = format;
+
+ conf->config.pixelformat = format;
+ conf->config.flags |= DLCONF_PIXELFORMAT;
+ }
+ else {
+ D_ERROR("DirectFB/Config '%s': No format specified!\n", name);
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "desktop-buffer-mode" ) == 0 || strcmp (name, "layer-buffer-mode" ) == 0) {
+ DFBConfigLayer *conf = dfb_config->config_layer;
+
+ if (value) {
+ if (strcmp( value, "auto" ) == 0) {
+ conf->config.flags &= ~DLCONF_BUFFERMODE;
+ } else
+ if (strcmp( value, "triple" ) == 0) {
+ conf->config.buffermode = DLBM_TRIPLE;
+ conf->config.flags |= DLCONF_BUFFERMODE;
+ } else
+ if (strcmp( value, "backvideo" ) == 0) {
+ conf->config.buffermode = DLBM_BACKVIDEO;
+ conf->config.flags |= DLCONF_BUFFERMODE;
+ } else
+ if (strcmp( value, "backsystem" ) == 0) {
+ conf->config.buffermode = DLBM_BACKSYSTEM;
+ conf->config.flags |= DLCONF_BUFFERMODE;
+ } else
+ if (strcmp( value, "frontonly" ) == 0) {
+ conf->config.buffermode = DLBM_FRONTONLY;
+ conf->config.flags |= DLCONF_BUFFERMODE;
+ } else
+ if (strcmp( value, "windows" ) == 0) {
+ conf->config.buffermode = DLBM_WINDOWS;
+ conf->config.flags |= DLCONF_BUFFERMODE;
+ } else {
+ D_ERROR( "DirectFB/Config '%s': Unknown mode '%s'!\n", name, value );
+ return DFB_INVARG;
+ }
+ }
+ else {
+ D_ERROR( "DirectFB/Config '%s': No buffer mode specified!\n", name );
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "layer-src-key" ) == 0) {
+ DFBConfigLayer *conf = dfb_config->config_layer;
+
+ if (value) {
+ char *error;
+ u32 argb;
+
+ argb = strtoul( value, &error, 16 );
+
+ if (*error) {
+ D_ERROR( "DirectFB/Config '%s': Error in color '%s'!\n", name, error );
+ return DFB_INVARG;
+ }
+
+ conf->src_key.b = argb & 0xFF;
+ argb >>= 8;
+ conf->src_key.g = argb & 0xFF;
+ argb >>= 8;
+ conf->src_key.r = argb & 0xFF;
+ argb >>= 8;
+ conf->src_key.a = argb & 0xFF;
+
+ conf->config.options |= DLOP_SRC_COLORKEY;
+ conf->config.flags |= DLCONF_OPTIONS;
+ }
+ else {
+ D_ERROR( "DirectFB/Config '%s': No color specified!\n", name );
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "layer-src-key-index" ) == 0) {
+ DFBConfigLayer *conf = dfb_config->config_layer;
+
+ if (value) {
+ char *error;
+ u32 index;
+
+ index = strtoul( value, &error, 10 );
+
+ if (*error) {
+ D_ERROR( "DirectFB/Config '%s': Error in index '%s'!\n", name, error );
+ return DFB_INVARG;
+ }
+
+ conf->src_key_index = index;
+ conf->config.options |= DLOP_SRC_COLORKEY;
+ conf->config.flags |= DLCONF_OPTIONS;
+ }
+ else {
+ D_ERROR( "DirectFB/Config '%s': No index specified!\n", name );
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "bg-none" ) == 0 || strcmp (name, "layer-bg-none" ) == 0) {
+ DFBConfigLayer *conf = dfb_config->config_layer;
+
+ conf->background.mode = DLBM_DONTCARE;
+ } else
+ if (strcmp (name, "bg-image" ) == 0 || strcmp (name, "bg-tile" ) == 0 ||
+ strcmp (name, "layer-bg-image" ) == 0 || strcmp (name, "layer-bg-tile" ) == 0)
+ {
+ DFBConfigLayer *conf = dfb_config->config_layer;
+
+ if (value) {
+ if (conf->background.filename)
+ D_FREE( conf->background.filename );
+
+ conf->background.filename = D_STRDUP( value );
+ conf->background.mode = strcmp (name, "bg-tile" ) ? DLBM_IMAGE : DLBM_TILE;
+ }
+ else {
+ D_ERROR( "DirectFB/Config '%s': No filename specified!\n", name );
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "bg-color" ) == 0 || strcmp (name, "layer-bg-color" ) == 0) {
+ DFBConfigLayer *conf = dfb_config->config_layer;
+
+ if (value) {
+ char *error;
+ u32 argb;
+
+ argb = strtoul( value, &error, 16 );
+
+ if (*error) {
+ D_ERROR( "DirectFB/Config '%s': Error in color '%s'!\n", name, error );
+ return DFB_INVARG;
+ }
+
+ conf->background.color.b = argb & 0xFF;
+ argb >>= 8;
+ conf->background.color.g = argb & 0xFF;
+ argb >>= 8;
+ conf->background.color.r = argb & 0xFF;
+ argb >>= 8;
+ conf->background.color.a = argb & 0xFF;
+
+ conf->background.color_index = -1;
+ conf->background.mode = DLBM_COLOR;
+ }
+ else {
+ D_ERROR( "DirectFB/Config '%s': No color specified!\n", name );
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "layer-bg-color-index" ) == 0) {
+ DFBConfigLayer *conf = dfb_config->config_layer;
+
+ if (value) {
+ char *error;
+ u32 index;
+
+ index = strtoul( value, &error, 10 );
+
+ if (*error) {
+ D_ERROR( "DirectFB/Config '%s': Error in index '%s'!\n", name, error );
+ return DFB_INVARG;
+ }
+
+ conf->background.color_index = index;
+ conf->background.mode = DLBM_COLOR;
+ }
+ else {
+ D_ERROR( "DirectFB/Config '%s': No index specified!\n", name );
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "layer-stacking" ) == 0) {
+ DFBConfigLayer *conf = dfb_config->config_layer;
+
+ if (value) {
+ char *stackings = D_STRDUP( value );
+ char *p = NULL, *r, *s = stackings;
+
+ conf->stacking = 0;
+
+ while ((r = strtok_r( s, ",", &p ))) {
+ direct_trim( &r );
+
+ if (!strcmp( r, "lower" ))
+ conf->stacking |= (1 << DWSC_LOWER);
+ else if (!strcmp( r, "middle" ))
+ conf->stacking |= (1 << DWSC_MIDDLE);
+ else if (!strcmp( r, "upper" ))
+ conf->stacking |= (1 << DWSC_UPPER);
+ else {
+ D_ERROR( "DirectFB/Config '%s': Unknown class '%s'!\n", name, r );
+ D_FREE( stackings );
+ return DFB_INVARG;
+ }
+
+ s = NULL;
+ }
+
+ D_FREE( stackings );
+ }
+ else {
+ D_ERROR( "DirectFB/Config '%s': Missing value!\n", name );
+ return DFB_INVARG;
+ }
+ } else
+ if (strncmp (name, "layer-palette-", 14 ) == 0) {
+ int index;
+ char *error;
+ DFBConfigLayer *conf = dfb_config->config_layer;
+
+ index = strtoul( name + 14, &error, 10 );
+
+ if (*error) {
+ D_ERROR( "DirectFB/Config '%s': Error in index '%s'!\n", name, error );
+ return DFB_INVARG;
+ }
+
+ if (index < 0 || index > 255) {
+ D_ERROR("DirectFB/Config '%s': Index %d out of bounds!\n", name, index);
+ return DFB_INVARG;
+ }
+
+ if (value) {
+ char *error;
+ u32 argb;
+
+ argb = strtoul( value, &error, 16 );
+
+ if (*error) {
+ D_ERROR( "DirectFB/Config '%s': Error in color '%s'!\n", name, error );
+ return DFB_INVARG;
+ }
+
+ if (!conf->palette) {
+ conf->palette = D_CALLOC( 256, sizeof(DFBColor) );
+ if (!conf->palette)
+ return D_OOM();
+ }
+
+ conf->palette[index].a = (argb & 0xFF000000) >> 24;
+ conf->palette[index].r = (argb & 0xFF0000) >> 16;
+ conf->palette[index].g = (argb & 0xFF00) >> 8;
+ conf->palette[index].b = (argb & 0xFF);
+
+ conf->palette_set = true;
+ }
+ else {
+ D_ERROR( "DirectFB/Config '%s': No color specified!\n", name );
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "layer-rotate" ) == 0) {
+ DFBConfigLayer *conf = dfb_config->config_layer;
+
+ if (value) {
+ int rotate;
+
+ if (sscanf( value, "%d", &rotate ) < 1) {
+ D_ERROR("DirectFB/Config '%s': Could not parse value!\n", name);
+ return DFB_INVARG;
+ }
+
+ if (rotate != 0 && rotate != 90 && rotate != 180 && rotate != 270) {
+ D_ERROR("DirectFB/Config '%s': Only 0, 90, 180 or 270 supported!\n", name);
+ return DFB_UNSUPPORTED;
+ }
+
+ conf->rotate = rotate;
+ }
+ else {
+ D_ERROR("DirectFB/Config '%s': No value specified!\n", name);
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "video-phys" ) == 0) {
+ if (value) {
+ char *error;
+ unsigned long phys;
+
+ phys = strtoul( value, &error, 16 );
+
+ if (*error) {
+ D_ERROR( "DirectFB/Config '%s': Error in hex value '%s'!\n", name, error );
+ return DFB_INVARG;
+ }
+
+ dfb_config->video_phys = phys;
+ }
+ else {
+ D_ERROR( "DirectFB/Config '%s': No value specified!\n", name );
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "video-length" ) == 0) {
+ if (value) {
+ char *error;
+ unsigned long length;
+
+ length = strtoul( value, &error, 10 );
+
+ if (*error) {
+ D_ERROR( "DirectFB/Config '%s': Error in value '%s'!\n", name, error );
+ return DFB_INVARG;
+ }
+
+ dfb_config->video_length = length;
+ }
+ else {
+ D_ERROR( "DirectFB/Config '%s': No value specified!\n", name );
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "mmio-phys" ) == 0) {
+ if (value) {
+ char *error;
+ unsigned long phys;
+
+ phys = strtoul( value, &error, 16 );
+
+ if (*error) {
+ D_ERROR( "DirectFB/Config '%s': Error in hex value '%s'!\n", name, error );
+ return DFB_INVARG;
+ }
+
+ dfb_config->mmio_phys = phys;
+ }
+ else {
+ D_ERROR( "DirectFB/Config '%s': No value specified!\n", name );
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "mmio-length" ) == 0) {
+ if (value) {
+ char *error;
+ unsigned long length;
+
+ length = strtoul( value, &error, 10 );
+
+ if (*error) {
+ D_ERROR( "DirectFB/Config '%s': Error in value '%s'!\n", name, error );
+ return DFB_INVARG;
+ }
+
+ dfb_config->mmio_length = length;
+ }
+ else {
+ D_ERROR( "DirectFB/Config '%s': No value specified!\n", name );
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "accelerator" ) == 0) {
+ if (value) {
+ char *error;
+ unsigned long accel;
+
+ accel = strtoul( value, &error, 10 );
+
+ if (*error) {
+ D_ERROR( "DirectFB/Config '%s': Error in value '%s'!\n", name, error );
+ return DFB_INVARG;
+ }
+
+ dfb_config->accelerator = accel;
+ }
+ else {
+ D_ERROR( "DirectFB/Config '%s': No value specified!\n", name );
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "matrox-tv-standard" ) == 0) {
+ if (value) {
+ if (strcmp( value, "pal-60" ) == 0) {
+ dfb_config->matrox_tv_std = DSETV_PAL_60;
+ } else
+ if (strcmp( value, "pal" ) == 0) {
+ dfb_config->matrox_tv_std = DSETV_PAL;
+ } else
+ if (strcmp( value, "ntsc" ) == 0) {
+ dfb_config->matrox_tv_std = DSETV_NTSC;
+ } else {
+ D_ERROR( "DirectFB/Config: Unknown TV standard "
+ "'%s'!\n", value );
+ return DFB_INVARG;
+ }
+ }
+ else {
+ D_ERROR( "DirectFB/Config: "
+ "No TV standard specified!\n" );
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "matrox-cable-type" ) == 0) {
+ if (value) {
+ if (strcmp( value, "composite" ) == 0) {
+ dfb_config->matrox_cable = 0;
+ } else
+ if (strcmp( value, "scart-rgb" ) == 0) {
+ dfb_config->matrox_cable = 1;
+ } else
+ if (strcmp( value, "scart-composite" ) == 0) {
+ dfb_config->matrox_cable = 2;
+ } else {
+ D_ERROR( "DirectFB/Config: Unknown cable type "
+ "'%s'!\n", value );
+ return DFB_INVARG;
+ }
+ }
+ else {
+ D_ERROR( "DirectFB/Config: "
+ "No cable type specified!\n" );
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "matrox-sgram" ) == 0) {
+ dfb_config->matrox_sgram = true;
+ } else
+ if (strcmp (name, "matrox-crtc2" ) == 0) {
+ dfb_config->matrox_crtc2 = true;
+ } else
+ if (strcmp (name, "no-matrox-sgram" ) == 0) {
+ dfb_config->matrox_sgram = false;
+ } else
+ if (strcmp (name, "sync" ) == 0) {
+ dfb_config->sync = true;
+ } else
+ if (strcmp (name, "no-sync" ) == 0) {
+ dfb_config->sync = false;
+ } else
+ if (strcmp (name, "lefty" ) == 0) {
+ dfb_config->lefty = true;
+ } else
+ if (strcmp (name, "no-lefty" ) == 0) {
+ dfb_config->lefty = false;
+ } else
+ if (strcmp (name, "capslock-meta" ) == 0) {
+ dfb_config->capslock_meta = true;
+ } else
+ if (strcmp (name, "no-capslock-meta" ) == 0) {
+ dfb_config->capslock_meta = false;
+ } else
+ if (strcmp (name, "h3600-device" ) == 0) {
+ if (value) {
+ if (dfb_config->h3600_device)
+ D_FREE( dfb_config->h3600_device );
+
+ dfb_config->h3600_device = D_STRDUP( value );
+ }
+ else {
+ D_ERROR( "DirectFB/Config: No H3600 TS device specified!\n" );
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "mut-device" ) == 0) {
+ if (value) {
+ if (dfb_config->mut_device)
+ D_FREE( dfb_config->mut_device );
+
+ dfb_config->mut_device = D_STRDUP( value );
+ }
+ else {
+ D_ERROR( "DirectFB/Config: No MuTouch device specified!\n" );
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "zytronic-device" ) == 0) {
+ if (value) {
+ if (dfb_config->zytronic_device)
+ D_FREE( dfb_config->zytronic_device );
+
+ dfb_config->zytronic_device = D_STRDUP( value );
+ }
+ else {
+ D_ERROR( "DirectFB/Config: No Zytronic device specified!\n" );
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "elo-device" ) == 0) {
+ if (value) {
+ if (dfb_config->elo_device)
+ D_FREE( dfb_config->elo_device );
+
+ dfb_config->elo_device = D_STRDUP( value );
+ }
+ else {
+ D_ERROR( "DirectFB/Config: No Elo device specified!\n" );
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "penmount-device" ) == 0) {
+ if (value) {
+ if (dfb_config->penmount_device)
+ D_FREE( dfb_config->penmount_device );
+
+ dfb_config->penmount_device = D_STRDUP( value );
+ }
+ else {
+ D_ERROR( "DirectFB/Config: No PenMount device specified!\n" );
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "linux-input-devices" ) == 0) {
+ if (value) {
+ config_values_free( &dfb_config->linux_input_devices );
+ config_values_parse( &dfb_config->linux_input_devices, value );
+ }
+ else {
+ D_ERROR( "DirectFB/Config: Missing value for linux-input-devices!\n" );
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "tslib-devices" ) == 0) {
+ if (value) {
+ config_values_free( &dfb_config->tslib_devices );
+ config_values_parse( &dfb_config->tslib_devices, value );
+ }
+ else {
+ D_ERROR( "DirectFB/Config: Missing value for tslib-devices!\n" );
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "unichrome-revision" ) == 0) {
+ if (value) {
+ int rev;
+
+ if (sscanf( value, "%d", &rev ) < 1) {
+ D_ERROR("DirectFB/Config 'unichrome-revision': Could not parse revision!\n");
+ return DFB_INVARG;
+ }
+
+ dfb_config->unichrome_revision = rev;
+ }
+ else {
+ D_ERROR("DirectFB/Config 'unichrome-revision': No revision specified!\n");
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "i8xx_overlay_pipe_b") == 0) {
+ dfb_config->i8xx_overlay_pipe_b = true;
+ } else
+ if (strcmp (name, "window-cursor-invisible") == 0) {
+ dfb_config->default_cursor_flags = DWCF_INVISIBLE;
+ } else
+ if (strcmp (name, "max-axis-rate" ) == 0) {
+ if (value) {
+ unsigned int rate;
+
+ if (sscanf( value, "%u", &rate ) < 1) {
+ D_ERROR("DirectFB/Config '%s': Could not parse value!\n", name);
+ return DFB_INVARG;
+ }
+
+ dfb_config->max_axis_rate = rate;
+ }
+ else {
+ D_ERROR("DirectFB/Config '%s': No value specified!\n", name);
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "include") == 0) {
+ if( value ) {
+ DFBResult ret;
+ ret = dfb_config_read( value );
+ if( ret )
+ return ret;
+ }
+ else {
+ D_ERROR("DirectFB/Config 'include': No include file specified!\n");
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "flip-notify-max-latency" ) == 0) {
+ if (value) {
+ char *error;
+ unsigned long latency;
+
+ latency = strtoul( value, &error, 10 );
+
+ if (*error) {
+ D_ERROR( "DirectFB/Config '%s': Error in value '%s'!\n", name, error );
+ return DFB_INVARG;
+ }
+
+ dfb_config->flip_notify_max_latency = latency;
+ }
+ else {
+ D_ERROR( "DirectFB/Config '%s': No value specified!\n", name );
+ return DFB_INVARG;
+ }
+ } else
+ if (voodoo_config_set( name, value ) && fusion_config_set( name, value ) && direct_config_set( name, value ))
+ return DFB_UNSUPPORTED;
+
+ return DFB_OK;
+}
+
+DFBResult dfb_config_init( int *argc, char *(*argv[]) )
+{
+ DFBResult ret;
+ int i;
+ char *home = getenv( "HOME" );
+ char *prog = NULL;
+ char *session;
+ char *dfbargs;
+ char cmdbuf[1024];
+
+ if (dfb_config)
+ return DFB_OK;
+
+ config_allocate();
+
+ /* Read system settings. */
+ ret = dfb_config_read( SYSCONFDIR"/directfbrc" );
+ if (ret && ret != DFB_IO)
+ return ret;
+
+ /* Read user settings. */
+ if (home) {
+ int len = strlen(home) + strlen("/.directfbrc") + 1;
+ char buf[len];
+
+ snprintf( buf, len, "%s/.directfbrc", home );
+
+ ret = dfb_config_read( buf );
+ if (ret && ret != DFB_IO)
+ return ret;
+ }
+
+ /* Get application name. */
+ if (argc && *argc && argv && *argv) {
+ prog = strrchr( (*argv)[0], '/' );
+
+ if (prog)
+ prog++;
+ else
+ prog = (*argv)[0];
+ }
+ else {
+ /* if we didn't receive argc/argv we try the proc system */
+ FILE *f;
+ int len;
+
+ f = fopen( "/proc/self/cmdline", "r" );
+ if (f) {
+ len = fread( cmdbuf, 1, 1023, f );
+ if (len) {
+ cmdbuf[len] = 0; /* in case of no arguments, or long program name */
+ prog = strrchr( cmdbuf, '/' );
+ if (prog)
+ prog++;
+ else
+ prog = cmdbuf;
+ }
+ fprintf(stderr,"commandline read: %s\n", prog );
+ fclose( f );
+ }
+ }
+
+ /* Strip lt- prefix. */
+ if (prog) {
+ if (prog[0] == 'l' && prog[1] == 't' && prog[2] == '-')
+ prog += 3;
+ }
+
+ /* Read global application settings. */
+ if (prog && prog[0]) {
+ int len = strlen( SYSCONFDIR"/directfbrc." ) + strlen(prog) + 1;
+ char buf[len];
+
+ snprintf( buf, len, SYSCONFDIR"/directfbrc.%s", prog );
+
+ ret = dfb_config_read( buf );
+ if (ret && ret != DFB_IO)
+ return ret;
+ }
+
+ /* Read user application settings. */
+ if (home && prog && prog[0]) {
+ int len = strlen(home) + strlen("/.directfbrc.") + strlen(prog) + 1;
+ char buf[len];
+
+ snprintf( buf, len, "%s/.directfbrc.%s", home, prog );
+
+ ret = dfb_config_read( buf );
+ if (ret && ret != DFB_IO)
+ return ret;
+ }
+
+ /* Read settings from environment variable. */
+ dfbargs = getenv( "DFBARGS" );
+ if (dfbargs) {
+ ret = parse_args( dfbargs );
+ if (ret)
+ return ret;
+ }
+
+ /* Active session is used if present, only command line can override. */
+ session = getenv( "DIRECTFB_SESSION" );
+ if (session)
+ dfb_config_set( "session", session );
+
+ /* Read settings from command line. */
+ if (argc && argv) {
+ for (i = 1; i < *argc; i++) {
+
+ if (strcmp ((*argv)[i], "--dfb-help") == 0) {
+ print_config_usage();
+ exit(1);
+ }
+
+ if (strncmp ((*argv)[i], "--dfb:", 6) == 0) {
+ ret = parse_args( (*argv)[i] + 6 );
+ if (ret)
+ return ret;
+
+ (*argv)[i] = NULL;
+ }
+ }
+
+ for (i = 1; i < *argc; i++) {
+ int k;
+
+ for (k = i; k < *argc; k++)
+ if ((*argv)[k] != NULL)
+ break;
+
+ if (k > i) {
+ int j;
+
+ k -= i;
+
+ for (j = i + k; j < *argc; j++)
+ (*argv)[j-k] = (*argv)[j];
+
+ *argc -= k;
+ }
+ }
+ }
+ else if (prog) {
+ /* we have prog, so we try again the proc filesystem */
+ FILE *f;
+ int len;
+
+ len = strlen( cmdbuf );
+ f = fopen( "/proc/self/cmdline", "r" );
+ if (f) {
+ len = fread( cmdbuf, 1, len, f ); /* skip arg 0 */
+ while( config_read_cmdline( cmdbuf, 1024, f ) ) {
+ fprintf(stderr,"commandline read: %s\n", cmdbuf );
+ if (strcmp (cmdbuf, "--dfb-help") == 0) {
+ print_config_usage();
+ exit(1);
+ }
+
+ if (strncmp (cmdbuf, "--dfb:", 6) == 0) {
+ ret = parse_args( cmdbuf + 6 );
+ if (ret) {
+ fclose( f );
+ return ret;
+ }
+ }
+ }
+ fclose( f );
+ }
+ }
+
+ if (!dfb_config->vt_switch)
+ dfb_config->kd_graphics = true;
+
+ return DFB_OK;
+}
+
+DFBResult dfb_config_read( const char *filename )
+{
+ DFBResult ret = DFB_OK;
+ char line[400];
+ FILE *f;
+
+ char *slash = 0;
+ char *cwd = 0;
+
+ config_allocate();
+
+ dfb_config->config_layer = &dfb_config->layers[0];
+
+ f = fopen( filename, "r" );
+ if (!f) {
+ D_DEBUG_AT( DirectFB_Config, "Unable to open config file `%s'!\n", filename );
+ return DFB_IO;
+ } else {
+ D_DEBUG_AT( DirectFB_Config, "Parsing config file '%s'.\n", filename );
+ }
+
+ /* store/restore the cwd (needed for the "include" command */
+ slash = strrchr( filename, '/' );
+ if( slash ) {
+ cwd = getcwd(0,0);
+ if( !cwd )
+ return D_OOM();
+
+ /* must copy filename for path, due to const'ness */
+ char nwd[strlen(filename)];
+ strcpy( nwd, filename );
+ nwd[slash-filename] = 0;
+ chdir( nwd );
+
+ D_DEBUG_AT( DirectFB_Config, "changing configuration lookup directory to '%s'.\n", nwd );
+ }
+
+ while (fgets( line, 400, f )) {
+ char *name = line;
+ char *comment = strchr( line, '#');
+ char *value;
+
+ if (comment) {
+ *comment = 0;
+ }
+
+ value = strchr( line, '=' );
+
+ if (value) {
+ *value++ = 0;
+ direct_trim( &value );
+ }
+
+ direct_trim( &name );
+
+ if (!*name || *name == '#')
+ continue;
+
+ ret = dfb_config_set( name, value );
+ if (ret) {
+ if (ret == DFB_UNSUPPORTED) {
+ D_ERROR( "DirectFB/Config: *********** In config file `%s': "
+ "Invalid option `%s'! ***********\n", filename, name );
+ ret = DFB_OK;
+ continue;
+ }
+ break;
+ }
+ }
+
+ fclose( f );
+
+ /* restore original cwd */
+ if( cwd ) {
+ chdir( cwd );
+ free( cwd );
+ }
+
+ return ret;
+}
+