summaryrefslogtreecommitdiff
path: root/Source/DirectFB/proxy/dispatcher/idirectfb_dispatcher.c
diff options
context:
space:
mode:
Diffstat (limited to 'Source/DirectFB/proxy/dispatcher/idirectfb_dispatcher.c')
-rwxr-xr-xSource/DirectFB/proxy/dispatcher/idirectfb_dispatcher.c1305
1 files changed, 1305 insertions, 0 deletions
diff --git a/Source/DirectFB/proxy/dispatcher/idirectfb_dispatcher.c b/Source/DirectFB/proxy/dispatcher/idirectfb_dispatcher.c
new file mode 100755
index 0000000..e42fb72
--- /dev/null
+++ b/Source/DirectFB/proxy/dispatcher/idirectfb_dispatcher.c
@@ -0,0 +1,1305 @@
+/*
+ (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 <stdio.h>
+#include <stdlib.h>
+
+#include <directfb.h>
+
+#include <direct/debug.h>
+#include <direct/interface.h>
+#include <direct/list.h>
+#include <direct/mem.h>
+#include <direct/memcpy.h>
+#include <direct/messages.h>
+#include <direct/thread.h>
+#include <direct/util.h>
+
+#include <idirectfb.h>
+
+#include <voodoo/conf.h>
+#include <voodoo/interface.h>
+#include <voodoo/manager.h>
+#include <voodoo/message.h>
+
+#include "idirectfb_dispatcher.h"
+
+static DFBResult Probe( void );
+static DFBResult Construct( IDirectFB *thiz,
+ VoodooManager *manager,
+ VoodooInstanceID *ret_instance );
+
+#include <direct/interface_implementation.h>
+
+DIRECT_INTERFACE_IMPLEMENTATION( IDirectFB, Dispatcher )
+
+
+/**************************************************************************************************/
+
+typedef struct {
+ DirectLink link;
+
+ VoodooInstanceID instance;
+ IDirectFBDataBuffer *requestor;
+} DataBufferEntry;
+
+/*
+ * private data struct of IDirectFB_Dispatcher
+ */
+typedef struct {
+ int ref; /* reference counter */
+
+ IDirectFB *real;
+
+ CoreDFB *core;
+
+ VoodooInstanceID self; /* The instance of this dispatcher itself. */
+
+ DirectLink *data_buffers; /* list of known data buffers */
+} IDirectFB_Dispatcher_data;
+
+/**************************************************************************************************/
+
+static void
+IDirectFB_Dispatcher_Destruct( IDirectFB *thiz )
+{
+ DirectLink *l, *n;
+ IDirectFB_Dispatcher_data *data = thiz->priv;
+
+ D_DEBUG( "%s (%p)\n", __FUNCTION__, thiz );
+
+ direct_list_foreach_safe (l, n, data->data_buffers) {
+ DataBufferEntry *entry = (DataBufferEntry*) l;
+
+ entry->requestor->Release( entry->requestor );
+
+ D_FREE( entry );
+ }
+
+ data->real->Release( data->real );
+
+ DIRECT_DEALLOCATE_INTERFACE( thiz );
+}
+
+/**************************************************************************************************/
+
+static DirectResult
+IDirectFB_Dispatcher_AddRef( IDirectFB *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Dispatcher)
+
+ data->ref++;
+
+ return DFB_OK;
+}
+
+static DirectResult
+IDirectFB_Dispatcher_Release( IDirectFB *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Dispatcher)
+
+ if (--data->ref == 0)
+ IDirectFB_Dispatcher_Destruct( thiz );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFB_Dispatcher_SetCooperativeLevel( IDirectFB *thiz,
+ DFBCooperativeLevel level )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Dispatcher)
+
+
+
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFB_Dispatcher_GetDeviceDescription( IDirectFB *thiz,
+ DFBGraphicsDeviceDescription *ret_desc )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Dispatcher)
+
+ if (!ret_desc)
+ return DFB_INVARG;
+
+
+
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFB_Dispatcher_EnumVideoModes( IDirectFB *thiz,
+ DFBVideoModeCallback callbackfunc,
+ void *callbackdata )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Dispatcher)
+
+ if (!callbackfunc)
+ return DFB_INVARG;
+
+
+
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFB_Dispatcher_SetVideoMode( IDirectFB *thiz,
+ int width,
+ int height,
+ int bpp )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Dispatcher)
+
+
+
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFB_Dispatcher_CreateSurface( IDirectFB *thiz,
+ const DFBSurfaceDescription *desc,
+ IDirectFBSurface **interface_ptr )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Dispatcher)
+
+ if (!desc || !interface_ptr)
+ return DFB_INVARG;
+
+
+
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFB_Dispatcher_CreatePalette( IDirectFB *thiz,
+ const DFBPaletteDescription *desc,
+ IDirectFBPalette **interface_ptr )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Dispatcher)
+
+ if (!interface_ptr)
+ return DFB_INVARG;
+
+
+
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFB_Dispatcher_EnumScreens( IDirectFB *thiz,
+ DFBScreenCallback callbackfunc,
+ void *callbackdata )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Dispatcher)
+
+ if (!callbackfunc)
+ return DFB_INVARG;
+
+
+
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFB_Dispatcher_GetScreen( IDirectFB *thiz,
+ DFBScreenID id,
+ IDirectFBScreen **interface_ptr )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Dispatcher)
+
+ if (!interface_ptr)
+ return DFB_INVARG;
+
+
+
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFB_Dispatcher_EnumDisplayLayers( IDirectFB *thiz,
+ DFBDisplayLayerCallback callbackfunc,
+ void *callbackdata )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Dispatcher)
+
+ if (!callbackfunc)
+ return DFB_INVARG;
+
+
+
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFB_Dispatcher_GetDisplayLayer( IDirectFB *thiz,
+ DFBDisplayLayerID id,
+ IDirectFBDisplayLayer **interface_ptr )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Dispatcher)
+
+ if (!interface_ptr)
+ return DFB_INVARG;
+
+
+
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFB_Dispatcher_EnumInputDevices( IDirectFB *thiz,
+ DFBInputDeviceCallback callbackfunc,
+ void *callbackdata )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Dispatcher)
+
+ if (!callbackfunc)
+ return DFB_INVARG;
+
+
+
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFB_Dispatcher_GetInputDevice( IDirectFB *thiz,
+ DFBInputDeviceID id,
+ IDirectFBInputDevice **interface_ptr )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Dispatcher)
+
+ if (!interface_ptr)
+ return DFB_INVARG;
+
+
+
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFB_Dispatcher_CreateEventBuffer( IDirectFB *thiz,
+ IDirectFBEventBuffer **interface_ptr)
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Dispatcher)
+
+ if (!interface_ptr)
+ return DFB_INVARG;
+
+
+
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFB_Dispatcher_CreateInputEventBuffer( IDirectFB *thiz,
+ DFBInputDeviceCapabilities caps,
+ DFBBoolean global,
+ IDirectFBEventBuffer **interface_ptr)
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Dispatcher)
+
+ if (!interface_ptr)
+ return DFB_INVARG;
+
+
+
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFB_Dispatcher_CreateImageProvider( IDirectFB *thiz,
+ const char *filename,
+ IDirectFBImageProvider **interface_ptr )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Dispatcher)
+
+ /* Check arguments */
+ if (!filename || !interface_ptr)
+ return DFB_INVARG;
+
+
+
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFB_Dispatcher_CreateVideoProvider( IDirectFB *thiz,
+ const char *filename,
+ IDirectFBVideoProvider **interface_ptr )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Dispatcher)
+
+ /* Check arguments */
+ if (!interface_ptr || !filename)
+ return DFB_INVARG;
+
+
+
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFB_Dispatcher_CreateFont( IDirectFB *thiz,
+ const char *filename,
+ const DFBFontDescription *desc,
+ IDirectFBFont **interface_ptr )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Dispatcher)
+
+ /* Check arguments */
+ if (!interface_ptr)
+ return DFB_INVARG;
+
+
+
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFB_Dispatcher_CreateDataBuffer( IDirectFB *thiz,
+ const DFBDataBufferDescription *desc,
+ IDirectFBDataBuffer **interface_ptr )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Dispatcher)
+
+ if (!interface_ptr)
+ return DFB_INVARG;
+
+
+
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFB_Dispatcher_SetClipboardData( IDirectFB *thiz,
+ const char *mime_type,
+ const void *data,
+ unsigned int size,
+ struct timeval *timestamp )
+{
+ if (!mime_type || !data || !size)
+ return DFB_INVARG;
+
+
+
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFB_Dispatcher_GetClipboardData( IDirectFB *thiz,
+ char **mime_type,
+ void **clip_data,
+ unsigned int *size )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Dispatcher)
+
+ if (!mime_type && !clip_data && !size)
+ return DFB_INVARG;
+
+
+
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFB_Dispatcher_GetClipboardTimeStamp( IDirectFB *thiz,
+ struct timeval *timestamp )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Dispatcher)
+
+ if (!timestamp)
+ return DFB_INVARG;
+
+
+
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFB_Dispatcher_Suspend( IDirectFB *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Dispatcher)
+
+
+
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFB_Dispatcher_Resume( IDirectFB *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Dispatcher)
+
+
+
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFB_Dispatcher_WaitIdle( IDirectFB *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Dispatcher)
+
+
+
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFB_Dispatcher_WaitForSync( IDirectFB *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Dispatcher)
+
+
+
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFB_Dispatcher_GetInterface( IDirectFB *thiz,
+ const char *type,
+ const char *implementation,
+ void *arg,
+ void **interface_ptr )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Dispatcher)
+
+
+
+ return DFB_UNIMPLEMENTED;
+}
+
+/**************************************************************************************************/
+
+static DirectResult
+Dispatch_Release( IDirectFB *thiz, IDirectFB *real,
+ VoodooManager *manager, VoodooRequestMessage *msg )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Dispatcher)
+
+ return voodoo_manager_unregister_local( manager, data->self );
+}
+
+static DirectResult
+Dispatch_SetCooperativeLevel( IDirectFB *thiz, IDirectFB *real,
+ VoodooManager *manager, VoodooRequestMessage *msg )
+{
+ DirectResult ret;
+ DFBCooperativeLevel level;
+ VoodooMessageParser parser;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Dispatcher)
+
+ VOODOO_PARSER_BEGIN( parser, msg );
+ VOODOO_PARSER_GET_INT( parser, level );
+ VOODOO_PARSER_END( parser );
+
+ ret = real->SetCooperativeLevel( real, level );
+
+ return voodoo_manager_respond( manager, true, msg->header.serial,
+ ret, VOODOO_INSTANCE_NONE,
+ VMBT_NONE );
+}
+
+static DirectResult
+Dispatch_GetDeviceDescription( IDirectFB *thiz, IDirectFB *real,
+ VoodooManager *manager, VoodooRequestMessage *msg )
+{
+ DirectResult ret;
+ DFBGraphicsDeviceDescription desc;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Dispatcher)
+
+ ret = real->GetDeviceDescription( real, &desc );
+ if (ret)
+ return ret;
+
+ return voodoo_manager_respond( manager, true, msg->header.serial,
+ DFB_OK, VOODOO_INSTANCE_NONE,
+ VMBT_DATA, sizeof(DFBGraphicsDeviceDescription), &desc,
+ VMBT_NONE );
+}
+
+static DirectResult
+Dispatch_SetVideoMode( IDirectFB *thiz, IDirectFB *real,
+ VoodooManager *manager, VoodooRequestMessage *msg )
+{
+ DirectResult ret;
+ VoodooMessageParser parser;
+ int width;
+ int height;
+ int bpp;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Dispatcher)
+
+ VOODOO_PARSER_BEGIN( parser, msg );
+ VOODOO_PARSER_GET_INT( parser, width );
+ VOODOO_PARSER_GET_INT( parser, height );
+ VOODOO_PARSER_GET_INT( parser, bpp );
+ VOODOO_PARSER_END( parser );
+
+ ret = real->SetVideoMode( real, width, height, bpp );
+
+ return voodoo_manager_respond( manager, true, msg->header.serial,
+ ret, VOODOO_INSTANCE_NONE,
+ VMBT_NONE );
+}
+
+#define MAX_MODES 128
+
+typedef struct {
+ int num;
+ IDirectFB_Dispatcher_EnumVideoModes_Item items[MAX_MODES];
+} EnumVideoModes_Context;
+
+static DFBEnumerationResult
+EnumVideoModes_Callback( int width,
+ int height,
+ int bpp,
+ void *callbackdata )
+{
+ int index;
+ EnumVideoModes_Context *context = callbackdata;
+
+ if (context->num == MAX_MODES) {
+ D_WARN( "maximum number of %d modes reached", MAX_MODES );
+ return DFENUM_CANCEL;
+ }
+
+ index = context->num++;
+
+ context->items[index].width = width;
+ context->items[index].height = height;
+ context->items[index].bpp = bpp;
+
+ return DFENUM_OK;
+}
+
+static DirectResult
+Dispatch_EnumVideoModes( IDirectFB *thiz, IDirectFB *real,
+ VoodooManager *manager, VoodooRequestMessage *msg )
+{
+ DirectResult ret;
+ EnumVideoModes_Context context = { 0 };
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Dispatcher)
+
+ ret = real->EnumVideoModes( real, EnumVideoModes_Callback, &context );
+ if (ret)
+ return ret;
+
+ return voodoo_manager_respond( manager, true, msg->header.serial,
+ DFB_OK, VOODOO_INSTANCE_NONE,
+ VMBT_INT, context.num,
+ VMBT_DATA, context.num * sizeof(IDirectFB_Dispatcher_EnumVideoModes_Item), context.items,
+ VMBT_NONE );
+}
+
+static DirectResult
+Dispatch_CreateEventBuffer( IDirectFB *thiz, IDirectFB *real,
+ VoodooManager *manager, VoodooRequestMessage *msg )
+{
+ DirectResult ret;
+ IDirectFBEventBuffer *buffer;
+ VoodooInstanceID instance;
+ VoodooMessageParser parser;
+ void *requestor;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Dispatcher)
+
+ VOODOO_PARSER_BEGIN( parser, msg );
+ VOODOO_PARSER_GET_ID( parser, instance );
+ VOODOO_PARSER_END( parser );
+
+ ret = real->CreateEventBuffer( real, &buffer );
+ if (ret)
+ return ret;
+
+ ret = voodoo_construct_requestor( manager, "IDirectFBEventBuffer",
+ instance, buffer, &requestor );
+
+ buffer->Release( buffer );
+
+ return ret;
+}
+
+static DirectResult
+Dispatch_CreateInputEventBuffer( IDirectFB *thiz, IDirectFB *real,
+ VoodooManager *manager, VoodooRequestMessage *msg )
+{
+ DirectResult ret;
+ IDirectFBEventBuffer *buffer;
+ VoodooInstanceID instance;
+ DFBInputDeviceCapabilities caps;
+ DFBBoolean global;
+ VoodooMessageParser parser;
+ void *requestor;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Dispatcher)
+
+ VOODOO_PARSER_BEGIN( parser, msg );
+ VOODOO_PARSER_GET_ID( parser, instance );
+ VOODOO_PARSER_GET_INT( parser, caps );
+ VOODOO_PARSER_GET_INT( parser, global );
+ VOODOO_PARSER_END( parser );
+
+ ret = real->CreateInputEventBuffer( real, caps, global, &buffer );
+ if (ret)
+ return ret;
+
+ ret = voodoo_construct_requestor( manager, "IDirectFBEventBuffer",
+ instance, buffer, &requestor );
+
+ buffer->Release( buffer );
+
+ return ret;
+}
+
+static DirectResult
+Dispatch_CreateImageProvider( IDirectFB *thiz, IDirectFB *real,
+ VoodooManager *manager, VoodooRequestMessage *msg )
+{
+ DirectResult ret;
+ DirectLink *l;
+ VoodooMessageParser parser;
+ VoodooInstanceID instance;
+ IDirectFBImageProvider *provider;
+ IDirectFBDataBuffer *buffer = NULL;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Dispatcher)
+
+ VOODOO_PARSER_BEGIN( parser, msg );
+ VOODOO_PARSER_GET_ID( parser, instance );
+ VOODOO_PARSER_END( parser );
+
+ if (1) {
+ ret = voodoo_manager_check_allocation( manager, 0x100000 /*FIXME*/ );
+ if (ret) {
+ D_ERROR( "Allocation not permitted!\n" );
+ return ret;
+ }
+ }
+
+ direct_list_foreach (l, data->data_buffers) {
+ DataBufferEntry *entry = (DataBufferEntry*) l;
+
+ if (entry->instance == instance) {
+ buffer = entry->requestor;
+ break;
+ }
+ }
+
+ ret = buffer->CreateImageProvider( buffer, &provider );
+ if (ret)
+ return ret;
+
+ ret = voodoo_construct_dispatcher( manager, "IDirectFBImageProvider",
+ provider, data->self, NULL, &instance, NULL );
+ if (ret) {
+ provider->Release( provider );
+ return ret;
+ }
+
+ return voodoo_manager_respond( manager, true, msg->header.serial,
+ DFB_OK, instance,
+ VMBT_NONE );
+}
+
+static DirectResult
+Dispatch_CreateSurface( IDirectFB *thiz, IDirectFB *real,
+ VoodooManager *manager, VoodooRequestMessage *msg )
+{
+ DirectResult ret;
+ DFBSurfaceDescription desc;
+ IDirectFBSurface *surface;
+ VoodooInstanceID instance;
+ VoodooMessageParser parser;
+ bool force_system = (voodoo_config->resource_id != 0);
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Dispatcher)
+
+ VOODOO_PARSER_BEGIN( parser, msg );
+ VOODOO_PARSER_READ_DFBSurfaceDescription( parser, desc );
+ VOODOO_PARSER_END( parser );
+
+ if (1) {
+ unsigned int w = 256, h = 256, b = 2, size;
+
+ if (desc.flags & DSDESC_WIDTH)
+ w = desc.width;
+
+ if (desc.flags & DSDESC_HEIGHT)
+ h = desc.height;
+
+ if (desc.flags & DSDESC_PIXELFORMAT)
+ b = DFB_BYTES_PER_PIXEL( desc.pixelformat ) ? DFB_BYTES_PER_PIXEL( desc.pixelformat ) : 2;
+
+ size = w * h * b;
+
+ D_INFO( "Checking creation of %u kB surface\n", size / 1024 );
+
+ if (voodoo_config->surface_max && voodoo_config->surface_max < size) {
+ D_ERROR( "Allocation of %u kB surface not permitted (limit %u kB)\n",
+ size / 1024, voodoo_config->surface_max / 1024 );
+ return DR_LIMITEXCEEDED;
+ }
+
+ ret = voodoo_manager_check_allocation( manager, size );
+ if (ret) {
+ D_ERROR( "Allocation not permitted!\n" );
+ return ret;
+ }
+ }
+
+ if (voodoo_config->resource_id) {
+ if (desc.flags & DSDESC_RESOURCE_ID) {
+ if (desc.resource_id == voodoo_config->resource_id) {
+ force_system = false;
+ }
+ }
+ }
+
+ if (force_system) {
+ DFBSurfaceDescription sd = desc;
+
+ if (sd.flags & DSDESC_CAPS) {
+ sd.caps &= ~DSCAPS_VIDEOONLY;
+ sd.caps |= DSCAPS_SYSTEMONLY;
+ }
+ else {
+ sd.flags |= DSDESC_CAPS;
+ sd.caps = DSCAPS_SYSTEMONLY;
+ }
+
+ ret = real->CreateSurface( real, &sd, &surface );
+ }
+ else if (desc.flags & (DSDESC_PALETTE | DSDESC_PREALLOCATED)) {
+ DFBSurfaceDescription sd = desc;
+ sd.flags &= ~(DSDESC_PALETTE | DSDESC_PREALLOCATED);
+
+ ret = real->CreateSurface( real, &sd, &surface );
+ }
+ else {
+ ret = real->CreateSurface( real, &desc, &surface );
+ }
+ if (ret)
+ return ret;
+
+ ret = voodoo_construct_dispatcher( manager, "IDirectFBSurface",
+ surface, data->self, NULL, &instance, NULL );
+ if (ret) {
+ surface->Release( surface );
+ return ret;
+ }
+
+ return voodoo_manager_respond( manager, true, msg->header.serial,
+ DFB_OK, instance,
+ VMBT_NONE );
+}
+
+typedef struct {
+ int num;
+ IDirectFB_Dispatcher_EnumScreens_Item items[MAX_SCREENS];
+} EnumScreens_Context;
+
+static DFBEnumerationResult
+EnumScreens_Callback( DFBScreenID screen_id,
+ DFBScreenDescription desc,
+ void *callbackdata )
+{
+ int index;
+ EnumScreens_Context *context = callbackdata;
+
+ if (context->num == MAX_SCREENS) {
+ D_WARN( "maximum number of %d screens reached", MAX_SCREENS );
+ return DFENUM_CANCEL;
+ }
+
+ index = context->num++;
+
+ context->items[index].screen_id = screen_id;
+ context->items[index].desc = desc;
+
+ return DFENUM_OK;
+}
+
+static DirectResult
+Dispatch_EnumScreens( IDirectFB *thiz, IDirectFB *real,
+ VoodooManager *manager, VoodooRequestMessage *msg )
+{
+ DirectResult ret;
+ EnumScreens_Context context = { 0 };
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Dispatcher)
+
+ ret = real->EnumScreens( real, EnumScreens_Callback, &context );
+ if (ret)
+ return ret;
+
+ return voodoo_manager_respond( manager, true, msg->header.serial,
+ DFB_OK, VOODOO_INSTANCE_NONE,
+ VMBT_INT, context.num,
+ VMBT_DATA, context.num * sizeof(IDirectFB_Dispatcher_EnumScreens_Item), context.items,
+ VMBT_NONE );
+}
+
+static DirectResult
+Dispatch_GetDisplayLayer( IDirectFB *thiz, IDirectFB *real,
+ VoodooManager *manager, VoodooRequestMessage *msg )
+{
+ DirectResult ret;
+ DFBDisplayLayerID id;
+ IDirectFBDisplayLayer *layer;
+ VoodooInstanceID instance;
+ VoodooMessageParser parser;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Dispatcher)
+
+ VOODOO_PARSER_BEGIN( parser, msg );
+ VOODOO_PARSER_GET_ID( parser, id );
+ VOODOO_PARSER_END( parser );
+
+ if (voodoo_config->layer_mask && !(voodoo_config->layer_mask & (1 << id))) {
+ D_ERROR( "Layer with id %u not allowed!\n", id );
+ return DR_ACCESSDENIED;
+ }
+
+ ret = real->GetDisplayLayer( real, id, &layer );
+ if (ret)
+ return ret;
+
+ ret = voodoo_construct_dispatcher( manager, "IDirectFBDisplayLayer",
+ layer, data->self, NULL, &instance, NULL );
+ if (ret) {
+ layer->Release( layer );
+ return ret;
+ }
+
+ return voodoo_manager_respond( manager, true, msg->header.serial,
+ DFB_OK, instance,
+ VMBT_NONE );
+}
+
+#define MAX_INPUT_DEVICES 64
+
+typedef struct {
+ int num;
+ IDirectFB_Dispatcher_EnumInputDevices_Item items[MAX_INPUT_DEVICES];
+} EnumInputDevices_Context;
+
+static DFBEnumerationResult
+EnumInputDevices_Callback( DFBInputDeviceID device_id,
+ DFBInputDeviceDescription desc,
+ void *callbackdata )
+{
+ int index;
+ EnumInputDevices_Context *context = callbackdata;
+
+ if (context->num == MAX_INPUT_DEVICES) {
+ D_WARN( "maximum number of %d input devices reached", MAX_INPUT_DEVICES );
+ return DFENUM_CANCEL;
+ }
+
+ index = context->num++;
+
+ context->items[index].device_id = device_id;
+ context->items[index].desc = desc;
+
+ return DFENUM_OK;
+}
+
+static DirectResult
+Dispatch_EnumInputDevices( IDirectFB *thiz, IDirectFB *real,
+ VoodooManager *manager, VoodooRequestMessage *msg )
+{
+ DirectResult ret;
+ EnumInputDevices_Context context = { 0 };
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Dispatcher)
+
+ ret = real->EnumInputDevices( real, EnumInputDevices_Callback, &context );
+ if (ret)
+ return ret;
+
+ return voodoo_manager_respond( manager, true, msg->header.serial,
+ DFB_OK, VOODOO_INSTANCE_NONE,
+ VMBT_INT, context.num,
+ VMBT_DATA, context.num * sizeof(IDirectFB_Dispatcher_EnumInputDevices_Item), context.items,
+ VMBT_NONE );
+}
+
+static DirectResult
+Dispatch_GetInputDevice( IDirectFB *thiz, IDirectFB *real,
+ VoodooManager *manager, VoodooRequestMessage *msg )
+{
+ DirectResult ret;
+ DFBScreenID device_id;
+ IDirectFBInputDevice *device;
+ VoodooInstanceID instance;
+ VoodooMessageParser parser;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Dispatcher)
+
+ VOODOO_PARSER_BEGIN( parser, msg );
+ VOODOO_PARSER_GET_ID( parser, device_id );
+ VOODOO_PARSER_END( parser );
+
+ ret = real->GetInputDevice( real, device_id, &device );
+ if (ret)
+ return ret;
+
+ ret = voodoo_construct_dispatcher( manager, "IDirectFBInputDevice",
+ device, data->self, NULL, &instance, NULL );
+ if (ret) {
+ device->Release( device );
+ return ret;
+ }
+
+ return voodoo_manager_respond( manager, true, msg->header.serial,
+ DFB_OK, instance,
+ VMBT_NONE );
+}
+
+static DirectResult
+Dispatch_GetScreen( IDirectFB *thiz, IDirectFB *real,
+ VoodooManager *manager, VoodooRequestMessage *msg )
+{
+ DirectResult ret;
+ DFBScreenID screen_id;
+ IDirectFBScreen *screen;
+ VoodooInstanceID instance;
+ VoodooMessageParser parser;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Dispatcher)
+
+ VOODOO_PARSER_BEGIN( parser, msg );
+ VOODOO_PARSER_GET_ID( parser, screen_id );
+ VOODOO_PARSER_END( parser );
+
+ ret = real->GetScreen( real, screen_id, &screen );
+ if (ret)
+ return ret;
+
+ ret = voodoo_construct_dispatcher( manager, "IDirectFBScreen",
+ screen, data->self, NULL, &instance, NULL );
+ if (ret) {
+ screen->Release( screen );
+ return ret;
+ }
+
+ return voodoo_manager_respond( manager, true, msg->header.serial,
+ DFB_OK, instance,
+ VMBT_NONE );
+}
+
+static DirectResult
+Dispatch_CreateFont( IDirectFB *thiz, IDirectFB *real,
+ VoodooManager *manager, VoodooRequestMessage *msg )
+{
+ DirectResult ret;
+ DirectLink *l;
+ VoodooMessageParser parser;
+ VoodooInstanceID instance;
+ IDirectFBFont *font;
+ IDirectFBDataBuffer *buffer = NULL;
+ const DFBFontDescription *desc;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Dispatcher)
+
+ VOODOO_PARSER_BEGIN( parser, msg );
+ VOODOO_PARSER_GET_ID( parser, instance );
+ VOODOO_PARSER_GET_DATA( parser, desc );
+ VOODOO_PARSER_END( parser );
+
+ direct_list_foreach (l, data->data_buffers) {
+ DataBufferEntry *entry = (DataBufferEntry*) l;
+
+ if (entry->instance == instance) {
+ buffer = entry->requestor;
+ break;
+ }
+ }
+
+ if (1) {
+ unsigned int size;
+
+ buffer->GetLength( buffer, &size );
+
+ ret = voodoo_manager_check_allocation( manager, size );
+ if (ret) {
+ D_ERROR( "Allocation not permitted!\n" );
+ return ret;
+ }
+ }
+
+ ret = buffer->CreateFont( buffer, desc, &font );
+ if (ret)
+ return ret;
+
+ ret = voodoo_construct_dispatcher( manager, "IDirectFBFont",
+ font, data->self, NULL, &instance, NULL );
+ if (ret) {
+ font->Release( font );
+ return ret;
+ }
+
+ return voodoo_manager_respond( manager, true, msg->header.serial,
+ DFB_OK, instance,
+ VMBT_NONE );
+}
+
+static DirectResult
+Dispatch_CreateDataBuffer( IDirectFB *thiz, IDirectFB *real,
+ VoodooManager *manager, VoodooRequestMessage *msg )
+{
+ DirectResult ret;
+ IDirectFBDataBuffer *requestor;
+ VoodooMessageParser parser;
+ VoodooInstanceID instance;
+ DataBufferEntry *entry;
+ void *ptr;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Dispatcher)
+
+ VOODOO_PARSER_BEGIN( parser, msg );
+ VOODOO_PARSER_GET_ID( parser, instance );
+ VOODOO_PARSER_END( parser );
+
+ ret = voodoo_construct_requestor( manager, "IDirectFBDataBuffer",
+ instance, data->real, &ptr );
+ if (ret)
+ return ret;
+
+ requestor = ptr;
+
+ entry = D_CALLOC( 1, sizeof(DataBufferEntry) );
+ if (!entry) {
+ D_WARN( "out of memory" );
+ requestor->Release( requestor );
+ return DFB_NOSYSTEMMEMORY;
+ }
+
+ entry->instance = instance;
+ entry->requestor = requestor;
+
+ entry->requestor->AddRef( entry->requestor );
+
+ direct_list_prepend( &data->data_buffers, &entry->link );
+
+ return DFB_OK;
+}
+
+static DirectResult
+Dispatch_WaitIdle( IDirectFB *thiz, IDirectFB *real,
+ VoodooManager *manager, VoodooRequestMessage *msg )
+{
+ DirectResult ret;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Dispatcher)
+
+ ret = real->WaitIdle( real );
+
+ return voodoo_manager_respond( manager, true, msg->header.serial,
+ ret, VOODOO_INSTANCE_NONE,
+ VMBT_NONE );
+}
+
+static DirectResult
+Dispatch_GetInterface( IDirectFB *thiz, IDirectFB *real,
+ VoodooManager *manager, VoodooRequestMessage *msg )
+{
+ DirectResult ret;
+ VoodooMessageParser parser;
+ const char *type;
+ IAny *interface_ptr;
+ VoodooInstanceID instance;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Dispatcher)
+
+ VOODOO_PARSER_BEGIN( parser, msg );
+ VOODOO_PARSER_GET_STRING( parser, type );
+ VOODOO_PARSER_END( parser );
+
+ ret = real->GetInterface( real, type, NULL, NULL, (void**) &interface_ptr );
+ if (ret)
+ return ret;
+
+ ret = voodoo_construct_dispatcher( manager, type, interface_ptr, data->self, NULL, &instance, NULL );
+ if (ret) {
+ interface_ptr->Release( interface_ptr );
+ return ret;
+ }
+
+ return voodoo_manager_respond( manager, true, msg->header.serial,
+ ret, instance,
+ VMBT_NONE );
+}
+
+static DirectResult
+Dispatch( void *dispatcher, void *real, VoodooManager *manager, VoodooRequestMessage *msg )
+{
+ D_DEBUG( "IDirectFB/Dispatcher: "
+ "Handling request for instance %u with method %u...\n", msg->instance, msg->method );
+
+ switch (msg->method) {
+ case IDIRECTFB_METHOD_ID_Release:
+ return Dispatch_Release( dispatcher, real, manager, msg );
+
+ case IDIRECTFB_METHOD_ID_SetCooperativeLevel:
+ return Dispatch_SetCooperativeLevel( dispatcher, real, manager, msg );
+
+ case IDIRECTFB_METHOD_ID_GetDeviceDescription:
+ return Dispatch_GetDeviceDescription( dispatcher, real, manager, msg );
+
+ case IDIRECTFB_METHOD_ID_SetVideoMode:
+ return Dispatch_SetVideoMode( dispatcher, real, manager, msg );
+
+ case IDIRECTFB_METHOD_ID_EnumVideoModes:
+ return Dispatch_EnumVideoModes( dispatcher, real, manager, msg );
+
+ case IDIRECTFB_METHOD_ID_CreateSurface:
+ return Dispatch_CreateSurface( dispatcher, real, manager, msg );
+
+ case IDIRECTFB_METHOD_ID_EnumScreens:
+ return Dispatch_EnumScreens( dispatcher, real, manager, msg );
+
+ case IDIRECTFB_METHOD_ID_GetScreen:
+ return Dispatch_GetScreen( dispatcher, real, manager, msg );
+
+ case IDIRECTFB_METHOD_ID_GetDisplayLayer:
+ return Dispatch_GetDisplayLayer( dispatcher, real, manager, msg );
+
+ case IDIRECTFB_METHOD_ID_EnumInputDevices:
+ return Dispatch_EnumInputDevices( dispatcher, real, manager, msg );
+
+ case IDIRECTFB_METHOD_ID_GetInputDevice:
+ return Dispatch_GetInputDevice( dispatcher, real, manager, msg );
+
+ case IDIRECTFB_METHOD_ID_CreateEventBuffer:
+ return Dispatch_CreateEventBuffer( dispatcher, real, manager, msg );
+
+ case IDIRECTFB_METHOD_ID_CreateInputEventBuffer:
+ return Dispatch_CreateInputEventBuffer( dispatcher, real, manager, msg );
+
+ case IDIRECTFB_METHOD_ID_CreateImageProvider:
+ return Dispatch_CreateImageProvider( dispatcher, real, manager, msg );
+
+ case IDIRECTFB_METHOD_ID_CreateFont:
+ return Dispatch_CreateFont( dispatcher, real, manager, msg );
+
+ case IDIRECTFB_METHOD_ID_CreateDataBuffer:
+ return Dispatch_CreateDataBuffer( dispatcher, real, manager, msg );
+
+ case IDIRECTFB_METHOD_ID_WaitIdle:
+ return Dispatch_WaitIdle( dispatcher, real, manager, msg );
+
+ case IDIRECTFB_METHOD_ID_GetInterface:
+ return Dispatch_GetInterface( dispatcher, real, manager, msg );
+ }
+
+ return DFB_NOSUCHMETHOD;
+}
+
+/**************************************************************************************************/
+
+static DFBResult
+Probe()
+{
+ /* This implementation has to be loaded explicitly. */
+ return DFB_UNSUPPORTED;
+}
+
+/*
+ * Constructor
+ *
+ * Fills in function pointers and intializes data structure.
+ */
+static DFBResult
+Construct( IDirectFB *thiz, VoodooManager *manager, VoodooInstanceID *ret_instance )
+{
+ DFBResult ret;
+ IDirectFB *real;
+ VoodooInstanceID instance;
+
+ DIRECT_ALLOCATE_INTERFACE_DATA(thiz, IDirectFB_Dispatcher)
+
+ ret = DirectFBCreate( &real );
+ if (ret) {
+ DIRECT_DEALLOCATE_INTERFACE( thiz );
+ return ret;
+ }
+
+ ret = voodoo_manager_register_local( manager, VOODOO_INSTANCE_NONE, thiz, real, Dispatch, &instance );
+ if (ret) {
+ real->Release( real );
+ DIRECT_DEALLOCATE_INTERFACE( thiz );
+ return ret;
+ }
+
+ *ret_instance = instance;
+
+ data->ref = 1;
+ data->real = real;
+ data->core = ((IDirectFB_data*)(real->priv))->core;
+ data->self = instance;
+
+ thiz->AddRef = IDirectFB_Dispatcher_AddRef;
+ thiz->Release = IDirectFB_Dispatcher_Release;
+ thiz->SetCooperativeLevel = IDirectFB_Dispatcher_SetCooperativeLevel;
+ thiz->GetDeviceDescription = IDirectFB_Dispatcher_GetDeviceDescription;
+ thiz->EnumVideoModes = IDirectFB_Dispatcher_EnumVideoModes;
+ thiz->SetVideoMode = IDirectFB_Dispatcher_SetVideoMode;
+ thiz->CreateSurface = IDirectFB_Dispatcher_CreateSurface;
+ thiz->CreatePalette = IDirectFB_Dispatcher_CreatePalette;
+ thiz->EnumScreens = IDirectFB_Dispatcher_EnumScreens;
+ thiz->GetScreen = IDirectFB_Dispatcher_GetScreen;
+ thiz->EnumDisplayLayers = IDirectFB_Dispatcher_EnumDisplayLayers;
+ thiz->GetDisplayLayer = IDirectFB_Dispatcher_GetDisplayLayer;
+ thiz->EnumInputDevices = IDirectFB_Dispatcher_EnumInputDevices;
+ thiz->GetInputDevice = IDirectFB_Dispatcher_GetInputDevice;
+ thiz->CreateEventBuffer = IDirectFB_Dispatcher_CreateEventBuffer;
+ thiz->CreateInputEventBuffer = IDirectFB_Dispatcher_CreateInputEventBuffer;
+ thiz->CreateImageProvider = IDirectFB_Dispatcher_CreateImageProvider;
+ thiz->CreateVideoProvider = IDirectFB_Dispatcher_CreateVideoProvider;
+ thiz->CreateFont = IDirectFB_Dispatcher_CreateFont;
+ thiz->CreateDataBuffer = IDirectFB_Dispatcher_CreateDataBuffer;
+ thiz->SetClipboardData = IDirectFB_Dispatcher_SetClipboardData;
+ thiz->GetClipboardData = IDirectFB_Dispatcher_GetClipboardData;
+ thiz->GetClipboardTimeStamp = IDirectFB_Dispatcher_GetClipboardTimeStamp;
+ thiz->Suspend = IDirectFB_Dispatcher_Suspend;
+ thiz->Resume = IDirectFB_Dispatcher_Resume;
+ thiz->WaitIdle = IDirectFB_Dispatcher_WaitIdle;
+ thiz->WaitForSync = IDirectFB_Dispatcher_WaitForSync;
+ thiz->GetInterface = IDirectFB_Dispatcher_GetInterface;
+
+ return DFB_OK;
+}
+