/* (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 "idirectfb_dispatcher.h" #include "idirectfbdatabuffer_dispatcher.h" static DFBResult Probe( void ); static DFBResult Construct( IDirectFBDataBuffer *thiz, IDirectFBDataBuffer *real, VoodooManager *manager, VoodooInstanceID super, void *arg, VoodooInstanceID *ret_instance ); #include DIRECT_INTERFACE_IMPLEMENTATION( IDirectFBDataBuffer, Dispatcher ) /**************************************************************************************************/ /* * private data struct of IDirectFBDataBuffer_Dispatcher */ typedef struct { IDirectFBDataBuffer_data base; IDirectFBDataBuffer *real; VoodooInstanceID self; /* The instance of this dispatcher itself. */ VoodooInstanceID super; /* The instance of the super interface. */ VoodooManager *manager; IDirectFB *idirectfb; } IDirectFBDataBuffer_Dispatcher_data; /**************************************************************************************************/ static void IDirectFBDataBuffer_Dispatcher_Destruct( IDirectFBDataBuffer *thiz ) { IDirectFBDataBuffer_Dispatcher_data *data = thiz->priv; D_DEBUG( "%s (%p)\n", __FUNCTION__, thiz ); data->real->Release( data->real ); IDirectFBDataBuffer_Destruct( thiz ); } /**************************************************************************************************/ static DirectResult IDirectFBDataBuffer_Dispatcher_AddRef( IDirectFBDataBuffer *thiz ) { DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer_Dispatcher) data->base.ref++; return DFB_OK; } static DirectResult IDirectFBDataBuffer_Dispatcher_Release( IDirectFBDataBuffer *thiz ) { DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer_Dispatcher) if (--data->base.ref == 0) IDirectFBDataBuffer_Dispatcher_Destruct( thiz ); return DFB_OK; } static DFBResult IDirectFBDataBuffer_Dispatcher_Flush( IDirectFBDataBuffer *thiz ) { DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer_Dispatcher) return data->real->Flush( data->real ); } static DFBResult IDirectFBDataBuffer_Dispatcher_Finish( IDirectFBDataBuffer *thiz ) { DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer_Dispatcher) return data->real->Finish( data->real ); } static DFBResult IDirectFBDataBuffer_Dispatcher_SeekTo( IDirectFBDataBuffer *thiz, unsigned int offset ) { DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer_Dispatcher) return data->real->SeekTo( data->real, offset ); } static DFBResult IDirectFBDataBuffer_Dispatcher_GetPosition( IDirectFBDataBuffer *thiz, unsigned int *offset ) { DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer_Dispatcher) return data->real->GetPosition( data->real, offset ); } static DFBResult IDirectFBDataBuffer_Dispatcher_GetLength( IDirectFBDataBuffer *thiz, unsigned int *length ) { DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer_Dispatcher) return data->real->GetLength( data->real, length ); } static DFBResult IDirectFBDataBuffer_Dispatcher_WaitForData( IDirectFBDataBuffer *thiz, unsigned int length ) { DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer_Dispatcher) return data->real->WaitForData( data->real, length ); } static DFBResult IDirectFBDataBuffer_Dispatcher_WaitForDataWithTimeout( IDirectFBDataBuffer *thiz, unsigned int length, unsigned int seconds, unsigned int milli_seconds ) { DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer_Dispatcher) return data->real->WaitForDataWithTimeout( data->real, length, seconds, milli_seconds ); } static DFBResult IDirectFBDataBuffer_Dispatcher_GetData( IDirectFBDataBuffer *thiz, unsigned int length, void *dest, unsigned int *read ) { DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer_Dispatcher) return data->real->GetData( data->real, length, dest, read ); } static DFBResult IDirectFBDataBuffer_Dispatcher_PeekData( IDirectFBDataBuffer *thiz, unsigned int length, int offset, void *dest, unsigned int *read ) { DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer_Dispatcher) return data->real->PeekData( data->real, length, offset, dest, read ); } static DFBResult IDirectFBDataBuffer_Dispatcher_HasData( IDirectFBDataBuffer *thiz ) { DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer_Dispatcher) return data->real->HasData( data->real ); } static DFBResult IDirectFBDataBuffer_Dispatcher_PutData( IDirectFBDataBuffer *thiz, const void *source, unsigned int length ) { DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer_Dispatcher) return data->real->PutData( data->real, source, length ); } static DFBResult IDirectFBDataBuffer_Dispatcher_CreateImageProvider( IDirectFBDataBuffer *thiz, IDirectFBImageProvider **ret_interface ) { DirectResult ret; VoodooResponseMessage *response; void *interface_ptr = NULL; DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer_Dispatcher) if (!ret_interface) return DFB_INVARG; ret = voodoo_manager_request( data->manager, data->super, IDIRECTFB_METHOD_ID_CreateImageProvider, VREQ_RESPOND | VREQ_ASYNC, &response, VMBT_ID, data->self, VMBT_NONE ); if (ret) return ret; ret = response->result; if (ret == DR_OK) ret = voodoo_construct_requestor( data->manager, "IDirectFBImageProvider", response->instance, thiz, &interface_ptr ); voodoo_manager_finish_request( data->manager, response ); *ret_interface = interface_ptr; return ret; } static DFBResult IDirectFBDataBuffer_Dispatcher_CreateVideoProvider( IDirectFBDataBuffer *thiz, IDirectFBVideoProvider **ret_interface ) { DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer_Dispatcher) if (!ret_interface) return DFB_INVARG; return DFB_UNIMPLEMENTED; } static DFBResult IDirectFBDataBuffer_Dispatcher_CreateFont( IDirectFBDataBuffer *thiz, const DFBFontDescription *desc, IDirectFBFont **ret_interface ) { DirectResult ret; VoodooResponseMessage *response; void *interface_ptr = NULL; DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer_Dispatcher) if (!ret_interface) return DFB_INVARG; ret = voodoo_manager_request( data->manager, data->super, IDIRECTFB_METHOD_ID_CreateFont, VREQ_RESPOND | VREQ_ASYNC, &response, VMBT_ID, data->self, VMBT_DATA, sizeof(DFBFontDescription), desc, VMBT_NONE ); if (ret) return ret; ret = response->result; if (ret == DR_OK) ret = voodoo_construct_requestor( data->manager, "IDirectFBFont", response->instance, thiz, &interface_ptr ); voodoo_manager_finish_request( data->manager, response ); *ret_interface = interface_ptr; return ret; } /**************************************************************************************************/ static DirectResult Dispatch_Release( IDirectFBDataBuffer *thiz, IDirectFBDataBuffer *real, VoodooManager *manager, VoodooRequestMessage *msg ) { DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer_Dispatcher) return voodoo_manager_unregister_local( manager, data->self ); } static DirectResult Dispatch_Flush( IDirectFBDataBuffer *thiz, IDirectFBDataBuffer *real, VoodooManager *manager, VoodooRequestMessage *msg ) { DirectResult ret; DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer_Dispatcher) ret = real->Flush( real ); return voodoo_manager_respond( manager, true, msg->header.serial, ret, VOODOO_INSTANCE_NONE, VMBT_NONE ); } static DirectResult Dispatch_Finish( IDirectFBDataBuffer *thiz, IDirectFBDataBuffer *real, VoodooManager *manager, VoodooRequestMessage *msg ) { DirectResult ret; DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer_Dispatcher) ret = real->Finish( real ); return voodoo_manager_respond( manager, true, msg->header.serial, ret, VOODOO_INSTANCE_NONE, VMBT_NONE ); } static DirectResult Dispatch_SeekTo( IDirectFBDataBuffer *thiz, IDirectFBDataBuffer *real, VoodooManager *manager, VoodooRequestMessage *msg ) { DirectResult ret; VoodooMessageParser parser; unsigned int offset; DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer_Dispatcher) VOODOO_PARSER_BEGIN( parser, msg ); VOODOO_PARSER_GET_UINT( parser, offset ); VOODOO_PARSER_END( parser ); ret = real->SeekTo( real, offset ); return voodoo_manager_respond( manager, true, msg->header.serial, ret, VOODOO_INSTANCE_NONE, VMBT_NONE ); } static DirectResult Dispatch_GetPosition( IDirectFBDataBuffer *thiz, IDirectFBDataBuffer *real, VoodooManager *manager, VoodooRequestMessage *msg ) { DirectResult ret; unsigned int offset; DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer_Dispatcher) ret = real->GetPosition( real, &offset ); if (ret) return ret; return voodoo_manager_respond( manager, true, msg->header.serial, DFB_OK, VOODOO_INSTANCE_NONE, VMBT_UINT, offset, VMBT_NONE ); } static DirectResult Dispatch_GetLength( IDirectFBDataBuffer *thiz, IDirectFBDataBuffer *real, VoodooManager *manager, VoodooRequestMessage *msg ) { DirectResult ret; unsigned int length; DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer_Dispatcher) ret = real->GetLength( real, &length ); if (ret) return ret; return voodoo_manager_respond( manager, true, msg->header.serial, DFB_OK, VOODOO_INSTANCE_NONE, VMBT_UINT, length, VMBT_NONE ); } static DirectResult Dispatch_WaitForData( IDirectFBDataBuffer *thiz, IDirectFBDataBuffer *real, VoodooManager *manager, VoodooRequestMessage *msg ) { DirectResult ret; VoodooMessageParser parser; unsigned int length; DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer_Dispatcher) VOODOO_PARSER_BEGIN( parser, msg ); VOODOO_PARSER_GET_UINT( parser, length ); VOODOO_PARSER_END( parser ); ret = real->WaitForData( real, length ); return voodoo_manager_respond( manager, true, msg->header.serial, ret, VOODOO_INSTANCE_NONE, VMBT_NONE ); } static DirectResult Dispatch_WaitForDataWithTimeout( IDirectFBDataBuffer *thiz, IDirectFBDataBuffer *real, VoodooManager *manager, VoodooRequestMessage *msg ) { DirectResult ret; VoodooMessageParser parser; unsigned int length; unsigned int seconds; unsigned int milli_seconds; DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer_Dispatcher) VOODOO_PARSER_BEGIN( parser, msg ); VOODOO_PARSER_GET_UINT( parser, length ); VOODOO_PARSER_GET_UINT( parser, seconds ); VOODOO_PARSER_GET_UINT( parser, milli_seconds ); VOODOO_PARSER_END( parser ); ret = real->WaitForDataWithTimeout( real, length, seconds, milli_seconds ); return voodoo_manager_respond( manager, true, msg->header.serial, ret, VOODOO_INSTANCE_NONE, VMBT_NONE ); } static DirectResult Dispatch_GetData( IDirectFBDataBuffer *thiz, IDirectFBDataBuffer *real, VoodooManager *manager, VoodooRequestMessage *msg ) { DirectResult ret; VoodooMessageParser parser; unsigned int length; unsigned int read; void *tmp; DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer_Dispatcher) VOODOO_PARSER_BEGIN( parser, msg ); VOODOO_PARSER_GET_UINT( parser, length ); VOODOO_PARSER_END( parser ); if (length > 16384) length = 16384; tmp = D_MALLOC( length ); if (!tmp) return D_OOM(); ret = real->GetData( real, length, tmp, &read ); if (ret) { D_FREE( tmp ); return ret; } ret = voodoo_manager_respond( manager, true, msg->header.serial, ret, VOODOO_INSTANCE_NONE, VMBT_UINT, read, VMBT_DATA, read, tmp, VMBT_NONE ); D_FREE( tmp ); return ret; } static DirectResult Dispatch_PeekData( IDirectFBDataBuffer *thiz, IDirectFBDataBuffer *real, VoodooManager *manager, VoodooRequestMessage *msg ) { DirectResult ret; VoodooMessageParser parser; unsigned int length; int offset; unsigned int read; void *tmp; DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer_Dispatcher) VOODOO_PARSER_BEGIN( parser, msg ); VOODOO_PARSER_GET_UINT( parser, length ); VOODOO_PARSER_GET_INT( parser, offset ); VOODOO_PARSER_END( parser ); if (length > 16384) length = 16384; tmp = D_MALLOC( length ); if (!tmp) return D_OOM(); ret = real->PeekData( real, length, offset, tmp, &read ); if (ret) { D_FREE( tmp ); return ret; } ret = voodoo_manager_respond( manager, true, msg->header.serial, ret, VOODOO_INSTANCE_NONE, VMBT_UINT, read, VMBT_DATA, read, tmp, VMBT_NONE ); D_FREE( tmp ); return ret; } static DirectResult Dispatch_HasData( IDirectFBDataBuffer *thiz, IDirectFBDataBuffer *real, VoodooManager *manager, VoodooRequestMessage *msg ) { DirectResult ret; DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer_Dispatcher) ret = real->HasData( real ); return voodoo_manager_respond( manager, true, msg->header.serial, ret, VOODOO_INSTANCE_NONE, VMBT_NONE ); } static DirectResult Dispatch_PutData( IDirectFBDataBuffer *thiz, IDirectFBDataBuffer *real, VoodooManager *manager, VoodooRequestMessage *msg ) { DirectResult ret; VoodooMessageParser parser; unsigned int length; const void *source; DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer_Dispatcher) VOODOO_PARSER_BEGIN( parser, msg ); VOODOO_PARSER_GET_UINT( parser, length ); VOODOO_PARSER_GET_DATA( parser, source ); VOODOO_PARSER_END( parser ); ret = real->PutData( real, source, length ); return voodoo_manager_respond( manager, true, msg->header.serial, ret, VOODOO_INSTANCE_NONE, VMBT_NONE ); } static DirectResult Dispatch( void *dispatcher, void *real, VoodooManager *manager, VoodooRequestMessage *msg ) { D_DEBUG( "IDirectFBDataBuffer/Dispatcher: " "Handling request for instance %u with method %u...\n", msg->instance, msg->method ); switch (msg->method) { case IDIRECTFBDATABUFFER_METHOD_ID_Release: return Dispatch_Release( dispatcher, real, manager, msg ); case IDIRECTFBDATABUFFER_METHOD_ID_Flush: return Dispatch_Flush( dispatcher, real, manager, msg ); case IDIRECTFBDATABUFFER_METHOD_ID_Finish: return Dispatch_Finish( dispatcher, real, manager, msg ); case IDIRECTFBDATABUFFER_METHOD_ID_SeekTo: return Dispatch_SeekTo( dispatcher, real, manager, msg ); case IDIRECTFBDATABUFFER_METHOD_ID_GetPosition: return Dispatch_GetPosition( dispatcher, real, manager, msg ); case IDIRECTFBDATABUFFER_METHOD_ID_GetLength: return Dispatch_GetLength( dispatcher, real, manager, msg ); case IDIRECTFBDATABUFFER_METHOD_ID_WaitForData: return Dispatch_WaitForData( dispatcher, real, manager, msg ); case IDIRECTFBDATABUFFER_METHOD_ID_WaitForDataWithTimeout: return Dispatch_WaitForDataWithTimeout( dispatcher, real, manager, msg ); case IDIRECTFBDATABUFFER_METHOD_ID_GetData: return Dispatch_GetData( dispatcher, real, manager, msg ); case IDIRECTFBDATABUFFER_METHOD_ID_PeekData: return Dispatch_PeekData( dispatcher, real, manager, msg ); case IDIRECTFBDATABUFFER_METHOD_ID_HasData: return Dispatch_HasData( dispatcher, real, manager, msg ); case IDIRECTFBDATABUFFER_METHOD_ID_PutData: return Dispatch_PutData( dispatcher, real, manager, msg ); } return DFB_NOSUCHMETHOD; } /**************************************************************************************************/ static DFBResult Probe() { /* This implementation has to be loaded explicitly. */ return DFB_UNSUPPORTED; } static DFBResult Construct( IDirectFBDataBuffer *thiz, IDirectFBDataBuffer *real, VoodooManager *manager, VoodooInstanceID super, void *arg, VoodooInstanceID *ret_instance ) { DFBResult ret; VoodooInstanceID instance; DIRECT_ALLOCATE_INTERFACE_DATA(thiz, IDirectFBDataBuffer_Dispatcher) ret = IDirectFBDataBuffer_Construct( thiz, NULL, NULL ); if (ret) return ret; ret = voodoo_manager_register_local( manager, VOODOO_INSTANCE_NONE, thiz, real, Dispatch, &instance ); if (ret) { IDirectFBDataBuffer_Destruct( thiz ); return ret; } *ret_instance = instance; data->real = real; data->self = instance; data->super = super; data->manager = manager; data->idirectfb = arg; thiz->AddRef = IDirectFBDataBuffer_Dispatcher_AddRef; thiz->Release = IDirectFBDataBuffer_Dispatcher_Release; thiz->Flush = IDirectFBDataBuffer_Dispatcher_Flush; thiz->Finish = IDirectFBDataBuffer_Dispatcher_Finish; thiz->SeekTo = IDirectFBDataBuffer_Dispatcher_SeekTo; thiz->GetPosition = IDirectFBDataBuffer_Dispatcher_GetPosition; thiz->GetLength = IDirectFBDataBuffer_Dispatcher_GetLength; thiz->WaitForData = IDirectFBDataBuffer_Dispatcher_WaitForData; thiz->WaitForDataWithTimeout = IDirectFBDataBuffer_Dispatcher_WaitForDataWithTimeout; thiz->GetData = IDirectFBDataBuffer_Dispatcher_GetData; thiz->PeekData = IDirectFBDataBuffer_Dispatcher_PeekData; thiz->HasData = IDirectFBDataBuffer_Dispatcher_HasData; thiz->PutData = IDirectFBDataBuffer_Dispatcher_PutData; thiz->CreateImageProvider = IDirectFBDataBuffer_Dispatcher_CreateImageProvider; thiz->CreateVideoProvider = IDirectFBDataBuffer_Dispatcher_CreateVideoProvider; thiz->CreateFont = IDirectFBDataBuffer_Dispatcher_CreateFont; return DFB_OK; }