summaryrefslogtreecommitdiff
path: root/Source/DirectFB/proxy/requestor/idirectfb_requestor.c
diff options
context:
space:
mode:
Diffstat (limited to 'Source/DirectFB/proxy/requestor/idirectfb_requestor.c')
-rwxr-xr-xSource/DirectFB/proxy/requestor/idirectfb_requestor.c1045
1 files changed, 1045 insertions, 0 deletions
diff --git a/Source/DirectFB/proxy/requestor/idirectfb_requestor.c b/Source/DirectFB/proxy/requestor/idirectfb_requestor.c
new file mode 100755
index 0000000..5e0796c
--- /dev/null
+++ b/Source/DirectFB/proxy/requestor/idirectfb_requestor.c
@@ -0,0 +1,1045 @@
+/*
+ (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 <directfb.h>
+
+#include <direct/interface.h>
+#include <direct/mem.h>
+#include <direct/memcpy.h>
+#include <direct/messages.h>
+#include <direct/util.h>
+
+#include <voodoo/client.h>
+#include <voodoo/interface.h>
+#include <voodoo/manager.h>
+
+#include <misc/conf.h>
+
+#include <input/idirectfbinputbuffer.h>
+#include <media/idirectfbdatabuffer.h>
+
+#include <idirectfb.h>
+#include <idirectfb_dispatcher.h>
+
+
+static DFBResult Probe( void );
+static DFBResult Construct( IDirectFB *thiz, const char *host, int session );
+
+#include <direct/interface_implementation.h>
+
+DIRECT_INTERFACE_IMPLEMENTATION( IDirectFB, Requestor )
+
+
+/**************************************************************************************************/
+
+/*
+ * private data struct of IDirectFB_Requestor
+ */
+typedef struct {
+ int ref; /* reference counter */
+
+ VoodooClient *client;
+ VoodooManager *manager;
+
+ VoodooInstanceID instance;
+
+ DFBCooperativeLevel level; /* current cooperative level */
+} IDirectFB_Requestor_data;
+
+/**************************************************************************************************/
+
+static void
+IDirectFB_Requestor_Destruct( IDirectFB *thiz )
+{
+ IDirectFB_Requestor_data *data = thiz->priv;
+
+ D_DEBUG( "%s (%p)\n", __FUNCTION__, thiz );
+
+ voodoo_manager_request( data->manager, data->instance,
+ IDIRECTFB_METHOD_ID_Release, VREQ_NONE, NULL,
+ VMBT_NONE );
+
+ voodoo_client_destroy( data->client );
+
+ DIRECT_DEALLOCATE_INTERFACE( thiz );
+}
+
+/**************************************************************************************************/
+
+static DirectResult
+IDirectFB_Requestor_AddRef( IDirectFB *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Requestor)
+
+ data->ref++;
+
+ return DFB_OK;
+}
+
+static DirectResult
+IDirectFB_Requestor_Release( IDirectFB *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Requestor)
+
+ if (--data->ref == 0)
+ IDirectFB_Requestor_Destruct( thiz );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFB_Requestor_SetCooperativeLevel( IDirectFB *thiz,
+ DFBCooperativeLevel level )
+{
+ DirectResult ret;
+ VoodooResponseMessage *response;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Requestor)
+
+ if (level == data->level)
+ return DFB_OK;
+
+ switch (level) {
+ case DFSCL_NORMAL:
+ break;
+
+ case DFSCL_FULLSCREEN:
+ case DFSCL_EXCLUSIVE:
+ if (dfb_config->force_windowed || dfb_config->force_desktop)
+ return DFB_ACCESSDENIED;
+
+ break;
+
+ default:
+ return DFB_INVARG;
+ }
+
+ ret = voodoo_manager_request( data->manager, data->instance,
+ IDIRECTFB_METHOD_ID_SetCooperativeLevel, VREQ_RESPOND, &response,
+ VMBT_INT, level,
+ VMBT_NONE );
+ if (ret)
+ return ret;
+
+ ret = response->result;
+ if (ret == DR_OK)
+ data->level = level;
+
+ voodoo_manager_finish_request( data->manager, response );
+
+ return ret;
+}
+
+static DFBResult
+IDirectFB_Requestor_GetDeviceDescription( IDirectFB *thiz,
+ DFBGraphicsDeviceDescription *ret_desc )
+{
+ DirectResult ret;
+ VoodooResponseMessage *response;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Requestor)
+
+ ret = voodoo_manager_request( data->manager, data->instance,
+ IDIRECTFB_METHOD_ID_GetDeviceDescription, VREQ_RESPOND, &response,
+ VMBT_NONE );
+ if (ret)
+ return ret;
+
+ ret = response->result;
+ if (ret == DR_OK) {
+ VoodooMessageParser parser;
+
+ VOODOO_PARSER_BEGIN( parser, response );
+ VOODOO_PARSER_READ_DATA( parser, ret_desc, sizeof(DFBGraphicsDeviceDescription) );
+ VOODOO_PARSER_END( parser );
+ }
+
+ voodoo_manager_finish_request( data->manager, response );
+
+ return ret;
+}
+
+static DFBResult
+IDirectFB_Requestor_EnumVideoModes( IDirectFB *thiz,
+ DFBVideoModeCallback callbackfunc,
+ void *callbackdata )
+{
+ DirectResult ret;
+ VoodooResponseMessage *response;
+ VoodooMessageParser parser;
+ int i, num;
+ IDirectFB_Dispatcher_EnumVideoModes_Item *items;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Requestor)
+
+ if (!callbackfunc)
+ return DFB_INVARG;
+
+ ret = voodoo_manager_request( data->manager, data->instance,
+ IDIRECTFB_METHOD_ID_EnumVideoModes, VREQ_RESPOND, &response,
+ VMBT_NONE );
+ if (ret)
+ return ret;
+
+ ret = response->result;
+ if (ret) {
+ voodoo_manager_finish_request( data->manager, response );
+ return ret;
+ }
+
+ VOODOO_PARSER_BEGIN( parser, response );
+ VOODOO_PARSER_GET_INT( parser, num );
+
+ items = D_MALLOC( sizeof(*items) * num );
+ if (items)
+ VOODOO_PARSER_READ_DATA( parser, items, sizeof(*items) * num );
+ else
+ ret = D_OOM();
+
+ VOODOO_PARSER_END( parser );
+
+ voodoo_manager_finish_request( data->manager, response );
+
+ if (items) {
+ for (i=0; i<num; i++) {
+ if (callbackfunc( items[i].width, items[i].height, items[i].bpp, callbackdata ) == DFENUM_CANCEL)
+ break;
+ }
+
+ D_FREE( items );
+ }
+
+ return ret;
+}
+
+static DFBResult
+IDirectFB_Requestor_SetVideoMode( IDirectFB *thiz,
+ int width,
+ int height,
+ int bpp )
+{
+ DirectResult ret;
+ VoodooResponseMessage *response;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Requestor)
+
+ if (width < 1 || height < 1 || bpp < 1)
+ return DFB_INVARG;
+
+ ret = voodoo_manager_request( data->manager, data->instance,
+ IDIRECTFB_METHOD_ID_SetVideoMode, VREQ_RESPOND, &response,
+ VMBT_INT, width,
+ VMBT_INT, height,
+ VMBT_INT, bpp,
+ VMBT_NONE );
+ if (ret)
+ return ret;
+
+ ret = response->result;
+
+ voodoo_manager_finish_request( data->manager, response );
+
+ return ret;
+}
+
+static DFBResult
+IDirectFB_Requestor_CreateSurface( IDirectFB *thiz,
+ const DFBSurfaceDescription *real_desc,
+ IDirectFBSurface **ret_interface )
+{
+ DirectResult ret;
+ VoodooResponseMessage *response;
+ VoodooInstanceID instance_id;
+ DFBSurfaceDescription desc;
+ DFBSurfaceCapabilities caps = DSCAPS_NONE;
+ void *interface_ptr = NULL;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Requestor)
+
+ if (!real_desc || !ret_interface)
+ return DFB_INVARG;
+
+ direct_memcpy( &desc, real_desc, sizeof(DFBSurfaceDescription) );
+
+ if (desc.flags & (DSDESC_PALETTE | DSDESC_PREALLOCATED))
+ D_ONCE( "DSDESC_PALETTE and DSDESC_PREALLOCATED not supported yet" );
+
+ if (desc.flags & DSDESC_CAPS)
+ caps = desc.caps;
+
+ if (caps & DSCAPS_PRIMARY) {
+ if (!(desc.flags & DSDESC_WIDTH) && dfb_config->mode.width) {
+ desc.flags |= DSDESC_WIDTH;
+ desc.width = dfb_config->mode.width;
+ }
+
+ if (!(desc.flags & DSDESC_HEIGHT) && dfb_config->mode.height) {
+ desc.flags |= DSDESC_HEIGHT;
+ desc.height = dfb_config->mode.height;
+ }
+ }
+
+ if (!(desc.flags & DSDESC_PIXELFORMAT) && dfb_config->mode.format != DSPF_UNKNOWN) {
+ desc.flags |= DSDESC_PIXELFORMAT;
+ desc.pixelformat = dfb_config->mode.format;
+ }
+
+ if (!(desc.flags & DSDESC_RESOURCE_ID)) {
+ desc.flags |= DSDESC_RESOURCE_ID;
+ desc.resource_id = 1100;
+ }
+
+ D_INFO( "IDirectFB_Requestor_CreateSurface: Using resource ID %lu\n", desc.resource_id );
+
+ ret = voodoo_manager_request( data->manager, data->instance,
+ IDIRECTFB_METHOD_ID_CreateSurface, VREQ_RESPOND, &response,
+ VMBT_DFBSurfaceDescription( desc ),
+ VMBT_NONE );
+ if (ret)
+ return ret;
+
+ /* Copy and finish as we do our next request in surface constructor already! */
+ instance_id = response->instance;
+
+ voodoo_manager_finish_request( data->manager, response );
+
+ ret = response->result;
+ if (ret == DR_OK)
+ ret = voodoo_construct_requestor( data->manager, "IDirectFBSurface",
+ instance_id, thiz, &interface_ptr );
+
+ *ret_interface = interface_ptr;
+
+ return ret;
+}
+
+static DFBResult
+IDirectFB_Requestor_CreatePalette( IDirectFB *thiz,
+ const DFBPaletteDescription *desc,
+ IDirectFBPalette **interface_ptr )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Requestor)
+
+ if (!interface_ptr)
+ return DFB_INVARG;
+
+ D_UNIMPLEMENTED();
+
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFB_Requestor_EnumScreens( IDirectFB *thiz,
+ DFBScreenCallback callbackfunc,
+ void *callbackdata )
+{
+ DirectResult ret;
+ VoodooResponseMessage *response;
+ VoodooMessageParser parser;
+ int i, num;
+ IDirectFB_Dispatcher_EnumScreens_Item *items;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Requestor)
+
+ if (!callbackfunc)
+ return DFB_INVARG;
+
+ ret = voodoo_manager_request( data->manager, data->instance,
+ IDIRECTFB_METHOD_ID_EnumScreens, VREQ_RESPOND, &response,
+ VMBT_NONE );
+ if (ret)
+ return ret;
+
+ ret = response->result;
+ if (ret) {
+ voodoo_manager_finish_request( data->manager, response );
+ return ret;
+ }
+
+ VOODOO_PARSER_BEGIN( parser, response );
+ VOODOO_PARSER_GET_INT( parser, num );
+
+ items = D_MALLOC( sizeof(*items) * num );
+ if (items)
+ VOODOO_PARSER_READ_DATA( parser, items, sizeof(*items) * num );
+ else
+ ret = D_OOM();
+
+ VOODOO_PARSER_END( parser );
+
+ voodoo_manager_finish_request( data->manager, response );
+
+ if (items) {
+ for (i=0; i<num; i++) {
+ if (callbackfunc( items[i].screen_id, items[i].desc, callbackdata ) == DFENUM_CANCEL)
+ break;
+ }
+
+ D_FREE( items );
+ }
+
+ return ret;
+}
+
+static DFBResult
+IDirectFB_Requestor_GetScreen( IDirectFB *thiz,
+ DFBScreenID id,
+ IDirectFBScreen **ret_interface )
+{
+ DirectResult ret;
+ VoodooResponseMessage *response;
+ void *interface_ptr = NULL;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Requestor)
+
+ if (!ret_interface)
+ return DFB_INVARG;
+ ret = voodoo_manager_request( data->manager, data->instance,
+ IDIRECTFB_METHOD_ID_GetScreen, VREQ_RESPOND, &response,
+ VMBT_ID, id,
+ VMBT_NONE );
+ if (ret)
+ return ret;
+
+ ret = response->result;
+ if (ret == DR_OK)
+ ret = voodoo_construct_requestor( data->manager, "IDirectFBScreen",
+ response->instance, thiz, &interface_ptr );
+
+ voodoo_manager_finish_request( data->manager, response );
+
+ *ret_interface = interface_ptr;
+
+ return ret;
+}
+
+static DFBResult
+IDirectFB_Requestor_EnumDisplayLayers( IDirectFB *thiz,
+ DFBDisplayLayerCallback callbackfunc,
+ void *callbackdata )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Requestor)
+
+ if (!callbackfunc)
+ return DFB_INVARG;
+
+ D_UNIMPLEMENTED();
+
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFB_Requestor_GetDisplayLayer( IDirectFB *thiz,
+ DFBDisplayLayerID id,
+ IDirectFBDisplayLayer **ret_interface )
+{
+ DirectResult ret;
+ VoodooResponseMessage *response;
+ void *interface_ptr = NULL;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Requestor)
+
+ if (!ret_interface)
+ return DFB_INVARG;
+
+ ret = voodoo_manager_request( data->manager, data->instance,
+ IDIRECTFB_METHOD_ID_GetDisplayLayer, VREQ_RESPOND, &response,
+ VMBT_ID, id,
+ VMBT_NONE );
+ if (ret)
+ return ret;
+
+ ret = response->result;
+ if (ret == DR_OK)
+ ret = voodoo_construct_requestor( data->manager, "IDirectFBDisplayLayer",
+ response->instance, thiz, &interface_ptr );
+
+ voodoo_manager_finish_request( data->manager, response );
+
+ *ret_interface = interface_ptr;
+
+ return ret;
+}
+
+static DFBResult
+IDirectFB_Requestor_EnumInputDevices( IDirectFB *thiz,
+ DFBInputDeviceCallback callbackfunc,
+ void *callbackdata )
+{
+ DirectResult ret;
+ VoodooResponseMessage *response;
+ VoodooMessageParser parser;
+ int i, num;
+ IDirectFB_Dispatcher_EnumInputDevices_Item *items;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Requestor)
+
+ if (!callbackfunc)
+ return DFB_INVARG;
+
+ ret = voodoo_manager_request( data->manager, data->instance,
+ IDIRECTFB_METHOD_ID_EnumInputDevices, VREQ_RESPOND, &response,
+ VMBT_NONE );
+ if (ret)
+ return ret;
+
+ if (response->result) {
+ voodoo_manager_finish_request( data->manager, response );
+ return response->result;
+ }
+
+ VOODOO_PARSER_BEGIN( parser, response );
+ VOODOO_PARSER_GET_INT( parser, num );
+
+ items = D_MALLOC( sizeof(*items) * num );
+ if (items)
+ VOODOO_PARSER_READ_DATA( parser, items, sizeof(*items) * num );
+ else
+ ret = D_OOM();
+
+ VOODOO_PARSER_END( parser );
+
+ voodoo_manager_finish_request( data->manager, response );
+
+ if (items) {
+ for (i=0; i<num; i++) {
+ if (callbackfunc( items[i].device_id, items[i].desc, callbackdata ) == DFENUM_CANCEL)
+ break;
+ }
+
+ D_FREE( items );
+ }
+
+ return ret;
+}
+
+static DFBResult
+IDirectFB_Requestor_GetInputDevice( IDirectFB *thiz,
+ DFBInputDeviceID id,
+ IDirectFBInputDevice **ret_interface )
+{
+ DirectResult ret;
+ VoodooResponseMessage *response;
+ void *interface_ptr = NULL;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Requestor)
+
+ if (!ret_interface)
+ return DFB_INVARG;
+
+ ret = voodoo_manager_request( data->manager, data->instance,
+ IDIRECTFB_METHOD_ID_GetInputDevice, VREQ_RESPOND, &response,
+ VMBT_ID, id,
+ VMBT_NONE );
+ if (ret)
+ return ret;
+
+ ret = response->result;
+ if (ret == DR_OK)
+ ret = voodoo_construct_requestor( data->manager, "IDirectFBInputDevice",
+ response->instance, thiz, &interface_ptr );
+
+ voodoo_manager_finish_request( data->manager, response );
+
+ *ret_interface = interface_ptr;
+
+ return ret;
+}
+
+static DFBResult
+IDirectFB_Requestor_CreateEventBuffer( IDirectFB *thiz,
+ IDirectFBEventBuffer **ret_interface)
+{
+ DFBResult ret;
+ IDirectFBEventBuffer *buffer;
+ IDirectFBEventBuffer *dispatcher;
+ VoodooInstanceID instance;
+ void *ptr;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Requestor)
+
+ if (!ret_interface)
+ return DFB_INVARG;
+
+ /* Create the real interface. */
+ DIRECT_ALLOCATE_INTERFACE( buffer, IDirectFBEventBuffer );
+
+ IDirectFBEventBuffer_Construct( buffer, NULL, NULL );
+
+ /* Create the dispatcher. */
+ ret = voodoo_construct_dispatcher( data->manager, "IDirectFBEventBuffer", buffer,
+ data->instance, NULL, &instance, &ptr );
+ if (ret) {
+ buffer->Release( buffer );
+ return ret;
+ }
+
+ dispatcher = ptr;
+
+ /* Send the request including the instance ID of the dispatcher. */
+ ret = voodoo_manager_request( data->manager, data->instance,
+ IDIRECTFB_METHOD_ID_CreateEventBuffer, VREQ_NONE, NULL,
+ VMBT_ID, instance,
+ VMBT_NONE );
+ if (ret) {
+ dispatcher->Release( dispatcher );
+ return ret;
+ }
+
+ /* Return the dispatcher interface. */
+ *ret_interface = dispatcher;
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFB_Requestor_CreateInputEventBuffer( IDirectFB *thiz,
+ DFBInputDeviceCapabilities caps,
+ DFBBoolean global,
+ IDirectFBEventBuffer **ret_interface)
+{
+ DFBResult ret;
+ IDirectFBEventBuffer *buffer;
+ IDirectFBEventBuffer *dispatcher;
+ VoodooInstanceID instance;
+ void *ptr;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Requestor)
+
+ if (!ret_interface)
+ return DFB_INVARG;
+
+ /* Create the real interface. */
+ DIRECT_ALLOCATE_INTERFACE( buffer, IDirectFBEventBuffer );
+
+ IDirectFBEventBuffer_Construct( buffer, NULL, NULL );
+
+ /* Create the dispatcher. */
+ ret = voodoo_construct_dispatcher( data->manager, "IDirectFBEventBuffer", buffer,
+ data->instance, NULL, &instance, &ptr );
+ if (ret) {
+ buffer->Release( buffer );
+ return ret;
+ }
+
+ dispatcher = ptr;
+
+ /* Send the request including the instance ID of the dispatcher. */
+ ret = voodoo_manager_request( data->manager, data->instance,
+ IDIRECTFB_METHOD_ID_CreateInputEventBuffer, VREQ_NONE, NULL,
+ VMBT_ID, instance,
+ VMBT_INT, caps,
+ VMBT_INT, global,
+ VMBT_NONE );
+ if (ret) {
+ dispatcher->Release( dispatcher );
+ return ret;
+ }
+
+ /* Return the dispatcher interface. */
+ *ret_interface = dispatcher;
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFB_Requestor_CreateImageProvider( IDirectFB *thiz,
+ const char *filename,
+ IDirectFBImageProvider **ret_interface )
+{
+ DFBResult ret;
+ DFBDataBufferDescription desc;
+ IDirectFBDataBuffer *buffer;
+ IDirectFBImageProvider *provider;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Requestor)
+
+ /* Check arguments */
+ if (!filename || !ret_interface)
+ return DFB_INVARG;
+
+ /* Create a data buffer. */
+ desc.flags = DBDESC_FILE;
+ desc.file = filename;
+
+ ret = thiz->CreateDataBuffer( thiz, &desc, &buffer );
+ if (ret)
+ return ret;
+
+ /* Create (probing) the image provider. */
+ ret = buffer->CreateImageProvider( buffer, &provider );
+ if (ret) {
+ buffer->Release( buffer );
+ return ret;
+ }
+
+ /* We don't need it anymore, image provider has its own reference. */
+ buffer->Release( buffer );
+
+ /* Return the new provider. */
+ *ret_interface = provider;
+
+ return ret;
+}
+
+static DFBResult
+IDirectFB_Requestor_CreateVideoProvider( IDirectFB *thiz,
+ const char *filename,
+ IDirectFBVideoProvider **interface_ptr )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Requestor)
+
+ /* Check arguments */
+ if (!interface_ptr || !filename)
+ return DFB_INVARG;
+
+ D_UNIMPLEMENTED();
+
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFB_Requestor_CreateFont( IDirectFB *thiz,
+ const char *filename,
+ const DFBFontDescription *desc,
+ IDirectFBFont **ret_interface )
+{
+ DFBResult ret;
+ DFBDataBufferDescription bdesc;
+ IDirectFBDataBuffer *buffer;
+ IDirectFBFont *font;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Requestor)
+
+ /* Check arguments */
+ if (!filename || !ret_interface)
+ return DFB_INVARG;
+
+ /* Create a data buffer. */
+ bdesc.flags = DBDESC_FILE;
+ bdesc.file = filename;
+
+ ret = thiz->CreateDataBuffer( thiz, &bdesc, &buffer );
+ if (ret)
+ return ret;
+
+ /* Create (probing) the font. */
+ ret = buffer->CreateFont( buffer, desc, &font );
+ if (ret) {
+ buffer->Release( buffer );
+ return ret;
+ }
+
+ /* We don't need it anymore, font has its own reference. */
+ buffer->Release( buffer );
+
+ /* Return the new font. */
+ *ret_interface = font;
+
+ return ret;
+}
+
+static DFBResult
+IDirectFB_Requestor_CreateDataBuffer( IDirectFB *thiz,
+ const DFBDataBufferDescription *desc,
+ IDirectFBDataBuffer **ret_interface )
+{
+ DFBResult ret;
+ IDirectFBDataBuffer *buffer;
+ IDirectFBDataBuffer *dispatcher;
+ VoodooInstanceID instance;
+ void *ptr;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Requestor)
+
+ if (!ret_interface)
+ return DFB_INVARG;
+
+ /* Create the real interface. */
+ if (!desc) {
+ DIRECT_ALLOCATE_INTERFACE( buffer, IDirectFBDataBuffer );
+
+ ret = IDirectFBDataBuffer_Streamed_Construct( buffer, NULL );
+ }
+ else if (desc->flags & DBDESC_FILE) {
+ if (!desc->file)
+ return DFB_INVARG;
+
+ DIRECT_ALLOCATE_INTERFACE( buffer, IDirectFBDataBuffer );
+
+ ret = IDirectFBDataBuffer_File_Construct( buffer, desc->file, NULL );
+ }
+ else if (desc->flags & DBDESC_MEMORY) {
+ if (!desc->memory.data || !desc->memory.length)
+ return DFB_INVARG;
+
+ DIRECT_ALLOCATE_INTERFACE( buffer, IDirectFBDataBuffer );
+
+ ret = IDirectFBDataBuffer_Memory_Construct( buffer,
+ desc->memory.data,
+ desc->memory.length,
+ NULL );
+ }
+ else
+ return DFB_INVARG;
+
+ if (ret)
+ return ret;
+
+ /* Create the dispatcher. */
+ ret = voodoo_construct_dispatcher( data->manager, "IDirectFBDataBuffer",
+ buffer, data->instance, thiz, &instance, &ptr );
+ if (ret) {
+ buffer->Release( buffer );
+ return ret;
+ }
+
+ dispatcher = ptr;
+
+ /* Send the request including the instance ID of the dispatcher. */
+ ret = voodoo_manager_request( data->manager, data->instance,
+ IDIRECTFB_METHOD_ID_CreateDataBuffer, VREQ_NONE, NULL,
+ VMBT_ID, instance,
+ VMBT_NONE );
+ if (ret) {
+ dispatcher->Release( dispatcher );
+ return ret;
+ }
+
+ /* Return the dispatcher(!) interface. */
+ *ret_interface = dispatcher;
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFB_Requestor_SetClipboardData( IDirectFB *thiz,
+ const char *mime_type,
+ const void *data,
+ unsigned int size,
+ struct timeval *timestamp )
+{
+ if (!mime_type || !data || !size)
+ return DFB_INVARG;
+
+ D_UNIMPLEMENTED();
+
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFB_Requestor_GetClipboardData( IDirectFB *thiz,
+ char **mime_type,
+ void **clip_data,
+ unsigned int *size )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Requestor)
+
+ if (!mime_type && !clip_data && !size)
+ return DFB_INVARG;
+
+ D_UNIMPLEMENTED();
+
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFB_Requestor_GetClipboardTimeStamp( IDirectFB *thiz,
+ struct timeval *timestamp )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Requestor)
+
+ if (!timestamp)
+ return DFB_INVARG;
+
+ D_UNIMPLEMENTED();
+
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFB_Requestor_Suspend( IDirectFB *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Requestor)
+
+ D_UNIMPLEMENTED();
+
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFB_Requestor_Resume( IDirectFB *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Requestor)
+
+ D_UNIMPLEMENTED();
+
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFB_Requestor_WaitIdle( IDirectFB *thiz )
+{
+ DirectResult ret;
+ VoodooResponseMessage *response;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Requestor)
+
+ ret = voodoo_manager_request( data->manager, data->instance,
+ IDIRECTFB_METHOD_ID_WaitIdle, VREQ_RESPOND, &response,
+ VMBT_NONE );
+ if (ret)
+ return ret;
+
+ ret = response->result;
+
+ voodoo_manager_finish_request( data->manager, response );
+
+ return ret;
+}
+
+static DFBResult
+IDirectFB_Requestor_WaitForSync( IDirectFB *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Requestor)
+
+ D_UNIMPLEMENTED();
+
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFB_Requestor_GetInterface( IDirectFB *thiz,
+ const char *type,
+ const char *implementation,
+ void *arg,
+ void **ret_interface )
+{
+ DirectResult ret;
+ VoodooResponseMessage *response;
+ void *interface_ptr = NULL;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB_Requestor)
+
+ if (!type || !ret_interface)
+ return DFB_INVARG;
+
+ if (implementation || arg)
+ return DFB_UNSUPPORTED;
+
+ ret = voodoo_manager_request( data->manager, data->instance,
+ IDIRECTFB_METHOD_ID_GetInterface, VREQ_RESPOND, &response,
+ VMBT_STRING, type,
+ VMBT_NONE );
+ if (ret)
+ return ret;
+
+ ret = response->result;
+ if (ret == DR_OK)
+ ret = voodoo_construct_requestor( data->manager, type, response->instance, thiz, &interface_ptr );
+
+ voodoo_manager_finish_request( data->manager, response );
+
+ *ret_interface = interface_ptr;
+
+ return ret;
+}
+
+/**************************************************************************************************/
+
+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, const char *host, int port )
+{
+ DFBResult ret;
+
+ DIRECT_ALLOCATE_INTERFACE_DATA(thiz, IDirectFB_Requestor)
+
+ data->ref = 1;
+ data->level = DFSCL_NORMAL;
+
+ ret = voodoo_client_create( host, port, &data->client );
+ if (ret) {
+ DIRECT_DEALLOCATE_INTERFACE( thiz );
+ return ret;
+ }
+
+ data->manager = voodoo_client_manager( data->client );
+
+ ret = voodoo_manager_super( data->manager, "IDirectFB", &data->instance );
+ if (ret) {
+ voodoo_client_destroy( data->client );
+ DIRECT_DEALLOCATE_INTERFACE( thiz );
+ return ret;
+ }
+
+ thiz->AddRef = IDirectFB_Requestor_AddRef;
+ thiz->Release = IDirectFB_Requestor_Release;
+ thiz->SetCooperativeLevel = IDirectFB_Requestor_SetCooperativeLevel;
+ thiz->GetDeviceDescription = IDirectFB_Requestor_GetDeviceDescription;
+ thiz->EnumVideoModes = IDirectFB_Requestor_EnumVideoModes;
+ thiz->SetVideoMode = IDirectFB_Requestor_SetVideoMode;
+ thiz->CreateSurface = IDirectFB_Requestor_CreateSurface;
+ thiz->CreatePalette = IDirectFB_Requestor_CreatePalette;
+ thiz->EnumScreens = IDirectFB_Requestor_EnumScreens;
+ thiz->GetScreen = IDirectFB_Requestor_GetScreen;
+ thiz->EnumDisplayLayers = IDirectFB_Requestor_EnumDisplayLayers;
+ thiz->GetDisplayLayer = IDirectFB_Requestor_GetDisplayLayer;
+ thiz->EnumInputDevices = IDirectFB_Requestor_EnumInputDevices;
+ thiz->GetInputDevice = IDirectFB_Requestor_GetInputDevice;
+ thiz->CreateEventBuffer = IDirectFB_Requestor_CreateEventBuffer;
+ thiz->CreateInputEventBuffer = IDirectFB_Requestor_CreateInputEventBuffer;
+ thiz->CreateImageProvider = IDirectFB_Requestor_CreateImageProvider;
+ thiz->CreateVideoProvider = IDirectFB_Requestor_CreateVideoProvider;
+ thiz->CreateFont = IDirectFB_Requestor_CreateFont;
+ thiz->CreateDataBuffer = IDirectFB_Requestor_CreateDataBuffer;
+ thiz->SetClipboardData = IDirectFB_Requestor_SetClipboardData;
+ thiz->GetClipboardData = IDirectFB_Requestor_GetClipboardData;
+ thiz->GetClipboardTimeStamp = IDirectFB_Requestor_GetClipboardTimeStamp;
+ thiz->Suspend = IDirectFB_Requestor_Suspend;
+ thiz->Resume = IDirectFB_Requestor_Resume;
+ thiz->WaitIdle = IDirectFB_Requestor_WaitIdle;
+ thiz->WaitForSync = IDirectFB_Requestor_WaitForSync;
+ thiz->GetInterface = IDirectFB_Requestor_GetInterface;
+
+ return DFB_OK;
+}
+