summaryrefslogtreecommitdiff
path: root/Source/DirectFB/systems/x11/x11_surface_pool_bridge.c
diff options
context:
space:
mode:
Diffstat (limited to 'Source/DirectFB/systems/x11/x11_surface_pool_bridge.c')
-rwxr-xr-xSource/DirectFB/systems/x11/x11_surface_pool_bridge.c331
1 files changed, 331 insertions, 0 deletions
diff --git a/Source/DirectFB/systems/x11/x11_surface_pool_bridge.c b/Source/DirectFB/systems/x11/x11_surface_pool_bridge.c
new file mode 100755
index 0000000..ce2537e
--- /dev/null
+++ b/Source/DirectFB/systems/x11/x11_surface_pool_bridge.c
@@ -0,0 +1,331 @@
+/*
+ (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.
+*/
+
+//#define DIRECT_ENABLE_DEBUG
+
+#include <config.h>
+
+#include <direct/debug.h>
+#include <direct/hash.h>
+#include <direct/mem.h>
+
+#include <fusion/shmalloc.h>
+
+#include <core/surface_pool_bridge.h>
+
+#include "x11.h"
+#include "x11image.h"
+#include "glx_surface_pool.h"
+#include "x11_surface_pool.h"
+
+D_DEBUG_DOMAIN( X11_Bridge, "X11/Bridge", "X11 System Surface Pool Bridge" );
+
+/**********************************************************************************************************************/
+
+typedef struct {
+} x11PoolBridgeData;
+
+typedef struct {
+ DFBX11 *x11;
+ Display *display;
+} x11PoolBridgeLocalData;
+
+typedef struct {
+} x11PoolTransferData;
+
+/**********************************************************************************************************************/
+
+static int
+x11PoolBridgeDataSize( void )
+{
+ return sizeof(x11PoolBridgeData);
+}
+
+static int
+x11PoolBridgeLocalDataSize( void )
+{
+ return sizeof(x11PoolBridgeLocalData);
+}
+
+static int
+x11PoolTransferDataSize( void )
+{
+ return sizeof(x11PoolTransferData);
+}
+
+static DFBResult
+x11InitPoolBridge( CoreDFB *core,
+ CoreSurfacePoolBridge *bridge,
+ void *bridge_data,
+ void *bridge_local,
+ void *context,
+ CoreSurfacePoolBridgeDescription *ret_desc )
+{
+ x11PoolBridgeLocalData *local = bridge_local;
+ DFBX11 *x11 = context;
+
+ D_DEBUG_AT( X11_Bridge, "%s()\n", __FUNCTION__ );
+
+ D_MAGIC_ASSERT( bridge, CoreSurfacePoolBridge );
+ D_ASSERT( bridge_local != NULL );
+ D_ASSERT( context != NULL );
+ D_ASSERT( ret_desc != NULL );
+
+ local->x11 = x11;
+ local->display = x11->display;
+
+ ret_desc->caps = CSPBCAPS_NONE;
+
+ snprintf( ret_desc->name, DFB_SURFACE_POOL_BRIDGE_DESC_NAME_LENGTH, "X11 Pool Bridge" );
+
+ return DFB_OK;
+}
+
+static DFBResult
+x11JoinPoolBridge( CoreDFB *core,
+ CoreSurfacePoolBridge *bridge,
+ void *bridge_data,
+ void *bridge_local,
+ void *context )
+{
+ x11PoolBridgeLocalData *local = bridge_local;
+ DFBX11 *x11 = context;
+
+ D_DEBUG_AT( X11_Bridge, "%s()\n", __FUNCTION__ );
+
+ D_MAGIC_ASSERT( bridge, CoreSurfacePoolBridge );
+ D_ASSERT( bridge_local != NULL );
+ D_ASSERT( context != NULL );
+
+ local->x11 = x11;
+ local->display = x11->display;
+
+ return DFB_OK;
+}
+
+static DFBResult
+x11DestroyPoolBridge( CoreSurfacePoolBridge *bridge,
+ void *bridge_data,
+ void *bridge_local )
+{
+ D_DEBUG_AT( X11_Bridge, "%s()\n", __FUNCTION__ );
+
+ D_MAGIC_ASSERT( bridge, CoreSurfacePoolBridge );
+
+ return DFB_OK;
+}
+
+static DFBResult
+x11LeavePoolBridge( CoreSurfacePoolBridge *bridge,
+ void *bridge_data,
+ void *bridge_local )
+{
+ D_DEBUG_AT( X11_Bridge, "%s()\n", __FUNCTION__ );
+
+ D_MAGIC_ASSERT( bridge, CoreSurfacePoolBridge );
+
+ return DFB_OK;
+}
+
+static DFBResult
+x11CheckTransfer( CoreSurfacePoolBridge *bridge,
+ void *bridge_data,
+ void *bridge_local,
+ CoreSurfaceBuffer *buffer,
+ CoreSurfaceAllocation *from,
+ CoreSurfaceAllocation *to )
+{
+ x11PoolBridgeLocalData *local = bridge_local;
+ DFBX11 *x11 = local->x11;
+ DFBX11Shared *shared = x11->shared;
+
+ D_DEBUG_AT( X11_Bridge, "%s()\n", __FUNCTION__ );
+
+ if (from->pool == shared->x11image_pool && to->pool == shared->glx_pool) {
+ x11AllocationData *alloc = from->data;
+
+ if (alloc->real) {
+ /* ARGB does not work (BadMatch) */
+ if (buffer->format == DSPF_RGB32)
+ return DFB_OK;
+ }
+ }
+ else if (from->pool == shared->glx_pool && to->pool == shared->x11image_pool) {
+ x11AllocationData *alloc = to->data;
+
+ if (alloc->real) {
+ /* ARGB does not work (BadMatch) */
+ if (buffer->format == DSPF_RGB32)
+ return DFB_OK;
+ }
+ }
+
+ return DFB_UNSUPPORTED;
+}
+
+static DFBResult
+x11StartTransfer( CoreSurfacePoolBridge *bridge,
+ void *bridge_data,
+ void *bridge_local,
+ CoreSurfacePoolTransfer *transfer,
+ void *transfer_data )
+{
+ DFBResult ret;
+ int i;
+ CoreSurfaceBufferLock lock;
+ LocalPixmap *pixmap;
+ x11PoolBridgeLocalData *local = bridge_local;
+ DFBX11 *x11 = local->x11;
+ DFBX11Shared *shared = x11->shared;
+ CoreSurfaceAllocation *from = transfer->from;
+ CoreSurfaceAllocation *to = transfer->to;
+
+ D_DEBUG_AT( X11_Bridge, "%s()\n", __FUNCTION__ );
+
+ if (from->pool == shared->x11image_pool && to->pool == shared->glx_pool) {
+ x11AllocationData *alloc = from->data;
+
+ D_ASSERT( alloc->real );
+
+ dfb_surface_buffer_lock_init( &lock, CSAID_ANY, CSAF_WRITE );
+
+ ret = dfb_surface_pool_lock( to->pool, to, &lock );
+ if (ret) {
+ dfb_surface_buffer_lock_deinit( &lock );
+ return ret;
+ }
+
+ pixmap = lock.handle;
+ D_MAGIC_ASSERT( pixmap, LocalPixmap );
+
+
+ XLockDisplay( local->display );
+
+ for (i=0; i<transfer->num_rects; i++) {
+ const DFBRectangle *rect = &transfer->rects[i];
+
+ D_DEBUG_AT( X11_Bridge, " -> XCopyArea( %4d,%4d-%4dx%4d )\n", rect->x, rect->y, rect->w, rect->h );
+
+ XCopyArea( local->display, alloc->image.pixmap, pixmap->pixmap, pixmap->gc,
+ rect->x, rect->y, rect->w, rect->h, rect->x, rect->y );
+ }
+
+ XFlush( local->display );
+
+ XUnlockDisplay( local->display );
+
+
+ dfb_surface_pool_unlock( to->pool, to, &lock );
+
+ dfb_surface_buffer_lock_deinit( &lock );
+
+ return DFB_OK;
+ }
+
+ if (from->pool == shared->glx_pool && to->pool == shared->x11image_pool) {
+ x11AllocationData *alloc = to->data;
+
+ D_ASSERT( alloc->real );
+
+ dfb_surface_buffer_lock_init( &lock, CSAID_ANY, CSAF_READ );
+
+ ret = dfb_surface_pool_lock( from->pool, from, &lock );
+ if (ret) {
+ dfb_surface_buffer_lock_deinit( &lock );
+ return ret;
+ }
+
+ pixmap = lock.handle;
+ D_MAGIC_ASSERT( pixmap, LocalPixmap );
+
+
+ XLockDisplay( local->display );
+
+ glFinish();
+
+ for (i=0; i<transfer->num_rects; i++) {
+ const DFBRectangle *rect = &transfer->rects[i];
+
+ D_DEBUG_AT( X11_Bridge, " -> XCopyArea( %4d,%4d-%4dx%4d )\n", rect->x, rect->y, rect->w, rect->h );
+
+ XCopyArea( local->display, pixmap->pixmap, alloc->image.pixmap, alloc->image.gc,
+ rect->x, rect->y, rect->w, rect->h, rect->x, rect->y );
+ }
+
+ XFlush( local->display );
+
+ XUnlockDisplay( local->display );
+
+
+ dfb_surface_pool_unlock( from->pool, from, &lock );
+
+ dfb_surface_buffer_lock_deinit( &lock );
+
+ return DFB_OK;
+ }
+
+ return DFB_BUG;
+}
+
+static DFBResult
+x11FinishTransfer( CoreSurfacePoolBridge *bridge,
+ void *bridge_data,
+ void *bridge_local,
+ CoreSurfacePoolTransfer *transfer,
+ void *transfer_data )
+{
+ x11PoolBridgeLocalData *local = bridge_local;
+
+ D_DEBUG_AT( X11_Bridge, "%s()\n", __FUNCTION__ );
+
+ XLockDisplay( local->display );
+
+ XSync( local->display, False );
+
+ XUnlockDisplay( local->display );
+
+ return DFB_OK;
+}
+
+
+const SurfacePoolBridgeFuncs x11SurfacePoolBridgeFuncs = {
+ .PoolBridgeDataSize = x11PoolBridgeDataSize,
+ .PoolBridgeLocalDataSize = x11PoolBridgeLocalDataSize,
+ .PoolTransferDataSize = x11PoolTransferDataSize,
+
+ .InitPoolBridge = x11InitPoolBridge,
+ .JoinPoolBridge = x11JoinPoolBridge,
+ .DestroyPoolBridge = x11DestroyPoolBridge,
+ .LeavePoolBridge = x11LeavePoolBridge,
+
+ .CheckTransfer = x11CheckTransfer,
+
+ .StartTransfer = x11StartTransfer,
+ .FinishTransfer = x11FinishTransfer,
+};
+