DFBResult
ICore_Real::ClipboardGet(
                    char                                      *ret_mime_type,
                    u32                                       *ret_mime_type_size,
                    char                                      *ret_data,
                    u32                                       *ret_data_size
)
{
    DFBResult     ret;
    char         *mime_type;
    void         *data;
    unsigned int  data_size;

    D_DEBUG_AT( DirectFB_CoreDFB, "ICore_Real::%s()\n", __FUNCTION__ );

    ret = dfb_clipboard_get( (DFBClipboardCore*) DFB_CORE( core, CLIPBOARD ), &mime_type, &data, &data_size );
    if (ret)
         return ret;

    direct_memcpy( ret_mime_type, mime_type, strlen(mime_type) + 1 );
    *ret_mime_type_size = strlen(mime_type) + 1;

    direct_memcpy( ret_data, data, data_size );
    *ret_data_size = data_size;

    free( data );
    free( mime_type );

    return DFB_OK;
}
Esempio n. 2
0
void
dfb_state_set_rop_pattern( CardState             *state,
                           const u32             *pattern,
                           DFBSurfacePatternMode  pattern_mode )
{
     D_MAGIC_ASSERT( state, CardState );

     D_ASSERT( pattern != NULL );

     switch (pattern_mode) {
          case DSPM_8_8_MONO:
               if (state->rop_pattern_mode != pattern_mode || memcmp( state->rop_pattern, pattern, sizeof(u32) * 8*8/32 )) {
                    direct_memcpy( state->rop_pattern, pattern, sizeof(u32) * 8*8/32 );

                    state->rop_pattern_mode = pattern_mode;

                    state->modified |= SMF_ROP_PATTERN;
               }
               break;

          case DSPM_32_32_MONO:
               if (state->rop_pattern_mode != pattern_mode || memcmp( state->rop_pattern, pattern, sizeof(u32) * 32*32/32 )) {
                    direct_memcpy( state->rop_pattern, pattern, sizeof(u32) * 32*32/32 );

                    state->rop_pattern_mode = pattern_mode;

                    state->modified |= SMF_ROP_PATTERN;
               }
               break;

          default:
               D_BUG( "unknown pattern mode %d", pattern_mode );
     }
}
Esempio n. 3
0
char *
direct_dbg_strdup( const char* file, int line, const char *func, const char *string )
{
     void          *mem;
     unsigned long *val;
     size_t         bytes = string ? direct_strlen( string ) + 1 : 1;

     D_DEBUG_AT( Direct_Mem, "  +"_ZUn(6)" bytes [%s:%d in %s()] <- \"%30s\"\n", bytes, file, line, func, string );

     if (direct_config->debugmem) {
          MemDesc *desc;

          mem = direct_malloc( bytes + sizeof(MemDesc) );

          D_DEBUG_AT( Direct_Mem, "  '-> %p\n", mem );

          if (!mem)
               return NULL;

          desc = fill_mem_desc( mem, bytes, func, file, line, direct_trace_copy_buffer(NULL) );

          direct_mutex_lock( &alloc_lock );

          direct_hash_insert( &alloc_hash, (unsigned long) desc->mem, desc );

          direct_mutex_unlock( &alloc_lock );

          if (string)
               direct_memcpy( desc->mem, string, bytes );
          else
               *(u8*)desc->mem = 0;

          return desc->mem;
     }


     mem = direct_malloc( bytes + DISABLED_OFFSET );

     D_DEBUG_AT( Direct_Mem, "  '-> %p\n", mem );

     if (!mem)
          return NULL;

     val    = mem;
     val[0] = ~0;

     if (string)
          direct_memcpy( (char*) mem + DISABLED_OFFSET, string, bytes );
     else
          *((u8*)mem + DISABLED_OFFSET) = 0;

     return (char*) mem + DISABLED_OFFSET;
}
Esempio n. 4
0
DFBResult
ICore_Requestor::ClipboardSet(
                    const char                                *mime_type,
                    u32                                        mime_type_size,
                    const char                                *data,
                    u32                                        data_size,
                    u64                                        timestamp_us
)
{
    DFBResult           ret = DFB_OK;
    char        args_static[FLUXED_ARGS_BYTES];
    char        return_args_static[FLUXED_ARGS_BYTES];
    CoreDFBClipboardSet       *args = (CoreDFBClipboardSet*) args_alloc( args_static, sizeof(CoreDFBClipboardSet) + mime_type_size * sizeof(char) + data_size * sizeof(char) );
    CoreDFBClipboardSetReturn *return_args;

    if (!args)
        return (DFBResult) D_OOM();

    return_args = (CoreDFBClipboardSetReturn*) args_alloc( return_args_static, sizeof(CoreDFBClipboardSetReturn) );

    if (!return_args) {
        args_free( args_static, args );
        return (DFBResult) D_OOM();
    }

    D_DEBUG_AT( DirectFB_CoreDFB, "ICore_Requestor::%s()\n", __FUNCTION__ );


    args->mime_type_size = mime_type_size;
    args->data_size = data_size;
    args->timestamp_us = timestamp_us;
    direct_memcpy( (char*) (args + 1), mime_type, mime_type_size * sizeof(char) );
    direct_memcpy( (char*) (args + 1) + mime_type_size * sizeof(char), data, data_size * sizeof(char) );

    ret = (DFBResult) CoreDFB_Call( obj, FCEF_NONE, CoreDFB_ClipboardSet, args, sizeof(CoreDFBClipboardSet) + mime_type_size * sizeof(char) + data_size * sizeof(char), return_args, sizeof(CoreDFBClipboardSetReturn), NULL );
    if (ret) {
        D_DERROR( ret, "%s: CoreDFB_Call( CoreDFB_ClipboardSet ) failed!\n", __FUNCTION__ );
        goto out;
    }

    if (return_args->result) {
        /*D_DERROR( return_args->result, "%s: CoreDFB_ClipboardSet failed!\n", __FUNCTION__ );*/
        ret = return_args->result;
        goto out;
    }



out:
    args_free( return_args_static, return_args );
    args_free( args_static, args );
    return ret;
}
Esempio n. 5
0
DFBResult
ICore_Requestor::ClipboardGet(
                    char                                      *ret_mime_type,
                    u32                                       *ret_mime_type_size,
                    char                                      *ret_data,
                    u32                                       *ret_data_size
)
{
    DFBResult           ret = DFB_OK;
    char        args_static[FLUXED_ARGS_BYTES];
    char        return_args_static[FLUXED_ARGS_BYTES];
    CoreDFBClipboardGet       *args = (CoreDFBClipboardGet*) args_alloc( args_static, sizeof(CoreDFBClipboardGet) );
    CoreDFBClipboardGetReturn *return_args;

    if (!args)
        return (DFBResult) D_OOM();

    return_args = (CoreDFBClipboardGetReturn*) args_alloc( return_args_static, sizeof(CoreDFBClipboardGetReturn) + MAX_CLIPBOARD_MIME_TYPE_SIZE * sizeof(char) + MAX_CLIPBOARD_DATA_SIZE * sizeof(char) );

    if (!return_args) {
        args_free( args_static, args );
        return (DFBResult) D_OOM();
    }

    D_DEBUG_AT( DirectFB_CoreDFB, "ICore_Requestor::%s()\n", __FUNCTION__ );



    ret = (DFBResult) CoreDFB_Call( obj, FCEF_NONE, CoreDFB_ClipboardGet, args, sizeof(CoreDFBClipboardGet), return_args, sizeof(CoreDFBClipboardGetReturn) + MAX_CLIPBOARD_MIME_TYPE_SIZE * sizeof(char) + MAX_CLIPBOARD_DATA_SIZE * sizeof(char), NULL );
    if (ret) {
        D_DERROR( ret, "%s: CoreDFB_Call( CoreDFB_ClipboardGet ) failed!\n", __FUNCTION__ );
        goto out;
    }

    if (return_args->result) {
        /*D_DERROR( return_args->result, "%s: CoreDFB_ClipboardGet failed!\n", __FUNCTION__ );*/
        ret = return_args->result;
        goto out;
    }

    *ret_mime_type_size = return_args->mime_type_size;
    *ret_data_size = return_args->data_size;
    direct_memcpy( ret_mime_type, (char*) (return_args + 1), return_args->mime_type_size * sizeof(char) );
    direct_memcpy( ret_data, (char*) (return_args + 1) + return_args->mime_type_size * sizeof(char), return_args->data_size * sizeof(char) );


out:
    args_free( return_args_static, return_args );
    args_free( args_static, args );
    return ret;
}
Esempio n. 6
0
static DFBResult
dfb_rtd_update_screen( CoreDFB *core, DFBRegion *region )
{
     int        ret;
     DFBRegion *tmp = NULL;

     if (dfb_core_is_master( core ))
          return dfb_rtd_update_screen_handler( region );

     if (region) {
          if (!fusion_is_shared( dfb_core_world(core), region )) {
               tmp = SHMALLOC( dfb_core_shmpool(core), sizeof(DFBRegion) );
               if (!tmp)
                    return D_OOSHM();

               direct_memcpy( tmp, region, sizeof(DFBRegion) );
          }
     }

     fusion_call_execute( &dfb_rtd->call, FCEF_NONE, RTD_UPDATE_SCREEN,
                          tmp ? tmp : region, &ret );

     if (tmp)
          SHFREE( dfb_core_shmpool(core), tmp );

     return DFB_OK;
}
Esempio n. 7
0
void
sawman_dispatch_tier_update( SaWMan             *sawman,
                             SaWManTier         *tier,
                             bool                right_eye,
                             const DFBRegion    *updates,
                             unsigned int        num_updates )
{
     SaWManListenerCallData data;

     data.call        = SWMLC_TIER_UPDATE;
     data.stereo_eye  = right_eye ? DSSE_RIGHT : DSSE_LEFT;
     data.layer_id    = tier->layer_id;
     data.num_updates = num_updates;

     D_ASSERT( num_updates <= D_ARRAY_SIZE(data.updates) );

     direct_memcpy( data.updates, updates, num_updates * sizeof(DFBRegion) );

     fusion_reactor_dispatch( sawman->reactor, &data, true, NULL );

     if (!right_eye) {
          unsigned int i;

          for (i=0; i<num_updates; i++)
               tier->performance.pixels += (updates[i].x2 - updates[i].x1 + 1) * (updates[i].y2 - updates[i].y1 + 1);

          tier->performance.updates++;
     }
}
Esempio n. 8
0
static DFBResult
dfb_rtd_set_video_mode( CoreDFB *core, CoreLayerRegionConfig *config )
{
     int                    ret;
     CoreLayerRegionConfig *tmp = NULL;

     D_ASSERT( config != NULL );

     if (dfb_core_is_master( core ))
          return dfb_rtd_set_video_mode_handler( config );

     if (!fusion_is_shared( dfb_core_world(core), config )) {
          tmp = SHMALLOC( dfb_core_shmpool(core), sizeof(CoreLayerRegionConfig) );
          if (!tmp)
               return D_OOSHM();

          direct_memcpy( tmp, config, sizeof(CoreLayerRegionConfig) );
     }

     fusion_call_execute( &dfb_rtd->call, FCEF_NONE, RTD_SET_VIDEO_MODE,
                          tmp ? tmp : config, &ret );

     if (tmp)
          SHFREE( dfb_core_shmpool(core), tmp );

     return ret;
}
Esempio n. 9
0
DFBResult
ICoreSlave_Requestor__PutData( CoreSlave *obj,
                    void*                                      address,
                    u32                                        bytes,
                    const u8                                  *data
)
{
    DFBResult           ret;
    CoreSlavePutData       *args = (CoreSlavePutData*) alloca( sizeof(CoreSlavePutData) + bytes * sizeof(u8) );
    CoreSlavePutDataReturn *return_args = (CoreSlavePutDataReturn*) alloca( sizeof(CoreSlavePutDataReturn) );

    D_DEBUG_AT( DirectFB_CoreSlave, "ICoreSlave_Requestor::%s()\n", __FUNCTION__ );


    args->address = address;
    args->bytes = bytes;
    direct_memcpy( (char*) (args + 1), data, bytes * sizeof(u8) );

    ret = (DFBResult) CoreSlave_Call( obj, FCEF_NONE, _CoreSlave_PutData, args, sizeof(CoreSlavePutData) + bytes * sizeof(u8), return_args, sizeof(CoreSlavePutDataReturn), NULL );
    if (ret) {
        D_DERROR( ret, "%s: CoreSlave_Call( CoreSlave_PutData ) failed!\n", __FUNCTION__ );
        return ret;
    }

    if (return_args->result) {
         /*D_DERROR( return_args->result, "%s: CoreSlave_PutData failed!\n", __FUNCTION__ );*/
         return return_args->result;
    }


    return DFB_OK;
}
Esempio n. 10
0
DFBResult
dfb_state_set_index_translation( CardState *state,
                                 const int *indices,
                                 int        num_indices )
{
     D_MAGIC_ASSERT( state, CardState );

     D_ASSERT( indices != NULL || num_indices == 0 );

     dfb_state_lock( state );

     if (state->num_translation != num_indices) {
          int *new_trans = D_REALLOC( state->index_translation,
                                      num_indices * sizeof(int) );

          D_ASSERT( num_indices || new_trans == NULL );

          if (num_indices && !new_trans) {
               dfb_state_unlock( state );
               return D_OOM();
          }

          state->index_translation = new_trans;
          state->num_translation   = num_indices;
     }

     if (num_indices)
          direct_memcpy( state->index_translation, indices, num_indices * sizeof(int) );

     state->modified |= SMF_INDEX_TRANSLATION;

     dfb_state_unlock( state );

     return DFB_OK;
}
Esempio n. 11
0
DFBResult
dfb_clipboard_set( DFBClipboardCore *core,
                   const char       *mime_type,
                   const void       *data,
                   unsigned int      size,
                   struct timeval   *timestamp )
{
     DFBClipboardCoreShared *shared;

     char *new_mime;
     void *new_data;

     D_MAGIC_ASSERT( core, DFBClipboardCore );
     D_ASSERT( mime_type != NULL );
     D_ASSERT( data != NULL );
     D_ASSERT( size > 0 );

     shared = core->shared;

     D_MAGIC_ASSERT( shared, DFBClipboardCoreShared );

     new_mime = SHSTRDUP( shared->shmpool, mime_type );
     if (!new_mime)
          return D_OOSHM();

     new_data = SHMALLOC( shared->shmpool, size );
     if (!new_data) {
          SHFREE( shared->shmpool, new_mime );
          return D_OOSHM();
     }

     direct_memcpy( new_data, data, size );

     if (fusion_skirmish_prevail( &shared->lock )) {
          SHFREE( shared->shmpool, new_data );
          SHFREE( shared->shmpool, new_mime );
          return DFB_FUSION;
     }

     if (shared->data)
          SHFREE( shared->shmpool, shared->data );

     if (shared->mime_type)
          SHFREE( shared->shmpool, shared->mime_type );

     shared->mime_type = new_mime;
     shared->data      = new_data;
     shared->size      = size;

     gettimeofday( &shared->timestamp, NULL );

     if (timestamp)
          *timestamp = shared->timestamp;

     fusion_skirmish_dismiss( &shared->lock );

     return DFB_OK;
}
Esempio n. 12
0
static inline void
write_blocks( void *dst, VoodooMessageBlockType type, va_list args )
{
     u32 *d32 = dst;

     while (type != VMBT_NONE) {
          u32   arg = 0;
          u32   len = 0;
          void *ptr = NULL;

          switch (type) {
               case VMBT_ID:
               case VMBT_INT:
               case VMBT_UINT:
                    len = 4;
                    arg = va_arg( args, u32 );
                    break;
               case VMBT_DATA:
                    len = va_arg( args, int );
                    ptr = va_arg( args, void * );
                    break;
               case VMBT_ODATA:
                    len = va_arg( args, int );
                    ptr = va_arg( args, void * );
                    if (!ptr)
                         len = 0;
                    break;
               case VMBT_STRING:
                    ptr = va_arg( args, char * );
                    len = strlen( ptr ) + 1;
                    break;
               default:
                    D_BREAK( "unknown message block type" );
          }

          /* Write block type and length. */
          d32[0] = type;
          d32[1] = len;

          /* Write block content. */
          if (ptr)
               direct_memcpy( &d32[2], ptr, len );
          else if (len) {
               D_ASSERT( len == 4 );

               d32[2] = arg;
          }

          /* Advance message data pointer. */
          d32 += 2 + (VOODOO_MSG_ALIGN(len) >> 2);

          /* Fetch next message block type. */
          type = va_arg( args, VoodooMessageBlockType );
     }

     /* Write terminator. */
     d32[0] = VMBT_NONE;
}
Esempio n. 13
0
static inline void MuTSendPacket(int file, char *packet, unsigned char len)
{
     unsigned char tmp_packet[MuT_PACKET_SIZE];

     direct_memcpy (&tmp_packet[1], packet, len);
     *tmp_packet = MuT_LEAD_BYTE;
     tmp_packet[len + 1] = MuT_TRAIL_BYTE;
     write (file, tmp_packet, len + 2);
}
Esempio n. 14
0
DFBResult
IPalette_Requestor::SetEntriesYUV(
                    const DFBColorYUV                         *colors,
                    u32                                        num,
                    u32                                        offset
)
{
    DFBResult           ret = DFB_OK;
    char        args_static[FLUXED_ARGS_BYTES];
    char        return_args_static[FLUXED_ARGS_BYTES];
    CorePaletteSetEntriesYUV       *args = (CorePaletteSetEntriesYUV*) args_alloc( args_static, sizeof(CorePaletteSetEntriesYUV) + num * sizeof(DFBColorYUV) );
    CorePaletteSetEntriesYUVReturn *return_args;

    if (!args)
        return (DFBResult) D_OOM();

    return_args = (CorePaletteSetEntriesYUVReturn*) args_alloc( return_args_static, sizeof(CorePaletteSetEntriesYUVReturn) );

    if (!return_args) {
        args_free( args_static, args );
        return (DFBResult) D_OOM();
    }

    D_DEBUG_AT( DirectFB_CorePalette, "IPalette_Requestor::%s()\n", __FUNCTION__ );

    D_ASSERT( colors != NULL );

    args->num = num;
    args->offset = offset;
    direct_memcpy( (char*) (args + 1), colors, num * sizeof(DFBColorYUV) );

    ret = (DFBResult) CorePalette_Call( obj, FCEF_NONE, CorePalette_SetEntriesYUV, args, sizeof(CorePaletteSetEntriesYUV) + num * sizeof(DFBColorYUV), return_args, sizeof(CorePaletteSetEntriesYUVReturn), NULL );
    if (ret) {
        D_DERROR( ret, "%s: CorePalette_Call( CorePalette_SetEntriesYUV ) failed!\n", __FUNCTION__ );
        goto out;
    }

    if (return_args->result) {
        /*D_DERROR( return_args->result, "%s: CorePalette_SetEntriesYUV failed!\n", __FUNCTION__ );*/
        ret = return_args->result;
        goto out;
    }



out:
    args_free( return_args_static, return_args );
    args_free( args_static, args );
    return ret;
}
Esempio n. 15
0
DFBResult
ICore_Requestor::AllowSurface(
                    CoreSurface                               *surface,
                    const char                                *executable,
                    u32                                        executable_length
)
{
    DFBResult           ret = DFB_OK;
    char        args_static[FLUXED_ARGS_BYTES];
    char        return_args_static[FLUXED_ARGS_BYTES];
    CoreDFBAllowSurface       *args = (CoreDFBAllowSurface*) args_alloc( args_static, sizeof(CoreDFBAllowSurface) + executable_length * sizeof(char) );
    CoreDFBAllowSurfaceReturn *return_args;

    if (!args)
        return (DFBResult) D_OOM();

    return_args = (CoreDFBAllowSurfaceReturn*) args_alloc( return_args_static, sizeof(CoreDFBAllowSurfaceReturn) );

    if (!return_args) {
        args_free( args_static, args );
        return (DFBResult) D_OOM();
    }

    D_DEBUG_AT( DirectFB_CoreDFB, "ICore_Requestor::%s()\n", __FUNCTION__ );

    D_ASSERT( surface != NULL );

    args->surface_id = CoreSurface_GetID( surface );
    args->executable_length = executable_length;
    direct_memcpy( (char*) (args + 1), executable, executable_length * sizeof(char) );

    ret = (DFBResult) CoreDFB_Call( obj, FCEF_NONE, CoreDFB_AllowSurface, args, sizeof(CoreDFBAllowSurface) + executable_length * sizeof(char), return_args, sizeof(CoreDFBAllowSurfaceReturn), NULL );
    if (ret) {
        D_DERROR( ret, "%s: CoreDFB_Call( CoreDFB_AllowSurface ) failed!\n", __FUNCTION__ );
        goto out;
    }

    if (return_args->result) {
        /*D_DERROR( return_args->result, "%s: CoreDFB_AllowSurface failed!\n", __FUNCTION__ );*/
        ret = return_args->result;
        goto out;
    }



out:
    args_free( return_args_static, return_args );
    args_free( args_static, args );
    return ret;
}
Esempio n. 16
0
void
dfb_state_set_src_colormatrix( CardState *state,
                               const s32 *matrix )
{
     D_MAGIC_ASSERT( state, CardState );

     D_ASSERT( matrix != NULL );

     if (memcmp( state->src_colormatrix, matrix, sizeof(state->src_colormatrix) )) {
          direct_memcpy( state->src_colormatrix, matrix, sizeof(state->src_colormatrix) );

          state->modified |= SMF_SRC_COLORMATRIX;
     }
}
Esempio n. 17
0
/* Get neatly aligned memory, initializing or
   growing the heap info table as necessary. */
static void *
morecore( shmalloc_heap *heap, size_t size )
{
     void *result;
     shmalloc_info *newinfo, *oldinfo;
     size_t newsize;

     D_DEBUG_AT( Fusion_SHMHeap, "%s( %p, %zu )\n", __FUNCTION__, heap, size );

     D_MAGIC_ASSERT( heap, shmalloc_heap );

     result = align( heap, size );
     if (result == NULL)
          return NULL;

     /* Check if we need to grow the info table.  */
     if ((size_t) BLOCK ((char *) result + size) > heap->heapsize) {
          newsize = heap->heapsize;

          while ((size_t) BLOCK ((char *) result + size) > newsize)
               newsize *= 2;

          newinfo = (shmalloc_info *) align( heap, newsize * sizeof (shmalloc_info) );
          if (newinfo == NULL) {
               __shmalloc_brk( heap, -size );
               return NULL;
          }

          direct_memcpy( newinfo, heap->heapinfo,
                         heap->heapsize * sizeof (shmalloc_info) );

          memset (newinfo + heap->heapsize,
                  0, (newsize - heap->heapsize) * sizeof (shmalloc_info));

          oldinfo = heap->heapinfo;

          newinfo[BLOCK (oldinfo)].busy.type = 0;
          newinfo[BLOCK (oldinfo)].busy.info.size = BLOCKIFY (heap->heapsize * sizeof (shmalloc_info));

          heap->heapinfo = newinfo;

          _fusion_shfree( heap, oldinfo );

          heap->heapsize = newsize;
     }

     heap->heaplimit = BLOCK ((char *) result + size);

     return result;
}
Esempio n. 18
0
void
dfb_state_set_src_convolution( CardState                  *state,
                               const DFBConvolutionFilter *filter )
{
     D_MAGIC_ASSERT( state, CardState );

     D_ASSERT( filter != NULL );

     if (memcmp( &state->src_convolution, filter, sizeof(state->src_convolution) )) {
          direct_memcpy( &state->src_convolution, filter, sizeof(state->src_convolution) );

          state->modified |= SMF_SRC_CONVOLUTION;
     }
}
Esempio n. 19
0
static DFBResult
allocate_transfer( CoreSurfacePoolBridge    *bridge,
                   CoreSurfaceBuffer        *buffer,
                   CoreSurfaceAllocation    *from,
                   CoreSurfaceAllocation    *to,
                   const DFBRectangle       *rects,
                   unsigned int              num_rects,
                   CoreSurfacePoolTransfer **ret_transfer )
{
     CoreSurfacePoolTransfer *transfer;
     unsigned int             alloc_size;

     D_MAGIC_ASSERT( bridge, CoreSurfacePoolBridge );
     D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
     CORE_SURFACE_ALLOCATION_ASSERT( from );
     CORE_SURFACE_ALLOCATION_ASSERT( to );
     D_ASSERT( rects != NULL );
     D_ASSERT( num_rects > 0 );
     D_ASSERT( ret_transfer != NULL );

     alloc_size = sizeof(CoreSurfacePoolTransfer) + num_rects * sizeof(DFBRectangle) + bridge->transfer_data_size;

     transfer = SHCALLOC( bridge->shmpool, 1, alloc_size );
     if (!transfer)
          return D_OOSHM();
          
     transfer->bridge = bridge;
     transfer->buffer = buffer;
     transfer->from   = from;
     transfer->to     = to;

     transfer->rects  = (DFBRectangle*)(transfer + 1);

     if (bridge->transfer_data_size)
          transfer->data = transfer->rects + num_rects;

     transfer->num_rects = num_rects;

     direct_memcpy( transfer->rects, rects, num_rects * sizeof(DFBRectangle) );

     D_MAGIC_SET( transfer, CoreSurfacePoolTransfer );

     *ret_transfer = transfer;

     return DFB_OK;
}
Esempio n. 20
0
void
dfb_state_set_matrix( CardState *state,
                      const s32 *matrix )
{
     D_MAGIC_ASSERT( state, CardState );

     D_ASSERT( matrix != NULL );

     if (memcmp( state->matrix, matrix, sizeof(state->matrix) )) {
          direct_memcpy( state->matrix, matrix, sizeof(state->matrix) );
          
          state->affine_matrix = (matrix[6] == 0x00000 && 
                                  matrix[7] == 0x00000 &&
                                  matrix[8] == 0x10000);

          state->modified |= SMF_MATRIX;
     }
}
Esempio n. 21
0
static void
filter_event(TS_EVENT *ts_event)
{
     int dx, dy;
     static int lastx = 0, lasty = 0;
     static int lastb = 0;
     static int evcnt = 0;
     static int event_index = 0;

     /* Increment the buffer index and the count of items in the buffer. */
     if(++evcnt > config.numevents) evcnt = config.numevents;
     if(++event_index == config.numevents) event_index = 0;

     /* If the pen has just been pressed down, reset the counters. */
     if(ts_event->pressure > config.zthresh) {
          if(!lastb) {
               lastb = 1;
               evcnt = 1;
               event_index = 0;
          }
     } else lastb = 0;

     /* Store this event in the circular buffer. */
     direct_memcpy(&event_buffer[event_index], ts_event, sizeof(TS_EVENT));

     /* Don't try to average and filter if we only have one reading. */
     if(evcnt > 1) {
          /* Average the closest values */
          ts_event->y = avg_events(0, evcnt);
          ts_event->x = avg_events(1, evcnt);

          /* Ignore movements which are below the minimum threshold */
          dx = ts_event->x - lastx;
          if(dx < 0) dx = -dx;
          if(dx < config.jthresh) ts_event->x = lastx;
          dy = ts_event->y - lasty;
          if(dy < 0) dy = -dy;
          if(dy < config.jthresh) ts_event->y = lasty;
     }

     /* Remember the values we are returning. */
     lastx = ts_event->x;
     lasty = ts_event->y;
}
Esempio n. 22
0
static inline bool ensure_capacity( FusionVector *vector )
{
     D_MAGIC_ASSERT( vector, FusionVector );
     D_ASSERT( vector->capacity > 0 );

     if (!vector->elements) {
          if (vector->pool)
               vector->elements = SHMALLOC( vector->pool, vector->capacity * sizeof(void*) );
          else
               vector->elements = D_MALLOC( vector->capacity * sizeof(void*) );

          if (!vector->elements)
               return false;
     }
     else if (vector->count == vector->capacity) {
          void *elements;
          void *oldelements = vector->elements;
          int   capacity    = vector->capacity << 1;

          if (vector->pool)
               elements = SHMALLOC( vector->pool, capacity * sizeof(void*) );
          else
               elements = D_MALLOC( capacity * sizeof(void*) );

          if (!elements)
               return false;

          direct_memcpy( elements, vector->elements,
                         vector->count * sizeof(void*) );

          vector->elements = elements;
          vector->capacity = capacity;

          if (vector->pool)
               SHFREE( vector->pool, oldelements );
          else
               D_FREE( oldelements );
     }

     return true;
}
Esempio n. 23
0
/*
 * Render a filled rectangle using the current hardware state.
 */
bool
vmwareBlit( void *drv, void *dev, DFBRectangle *srect, int dx, int dy )
{
     VMWareDeviceData *vdev = (VMWareDeviceData*) dev;
     void             *dst  = vdev->dst_addr + dy * vdev->dst_pitch +
                              DFB_BYTES_PER_LINE(vdev->dst_format, dx);
     void             *src  = vdev->src_addr + srect->y * vdev->src_pitch +
                              DFB_BYTES_PER_LINE(vdev->src_format, srect->x);

     D_DEBUG_AT( VMWare_2D, "%s( %d,%d-%dx%d -> %d, %d )\n", __FUNCTION__,
                 DFB_RECTANGLE_VALS( srect ), dx, dy );

     while (srect->h--) {
          direct_memcpy( dst, src, srect->w * vdev->dst_bpp );

          dst += vdev->dst_pitch;
          src += vdev->src_pitch;
     }

     return true;
}
Esempio n. 24
0
DFBResult
dfb_clipboard_get( DFBClipboardCore  *core,
                   char             **mime_type,
                   void             **data,
                   unsigned int      *size )
{
     DFBClipboardCoreShared *shared;

     D_MAGIC_ASSERT( core, DFBClipboardCore );

     shared = core->shared;

     D_MAGIC_ASSERT( shared, DFBClipboardCoreShared );

     if (fusion_skirmish_prevail( &shared->lock ))
          return DFB_FUSION;

     if (!shared->mime_type || !shared->data) {
          fusion_skirmish_dismiss( &shared->lock );
          return DFB_BUFFEREMPTY;
     }

     if (mime_type)
          *mime_type = strdup( shared->mime_type );

     if (data) {
          *data = malloc( shared->size );
          direct_memcpy( *data, shared->data, shared->size );
     }

     if (size)
          *size = shared->size;

     fusion_skirmish_dismiss( &shared->lock );

     return DFB_OK;
}
Esempio n. 25
0
DFBResult dfb_surfacemanager_assure_system( SurfaceManager *manager,
                                            SurfaceBuffer  *buffer )
{
     CoreSurface *surface = buffer->surface;

     D_MAGIC_ASSERT( manager, SurfaceManager );

     if (buffer->policy == CSP_VIDEOONLY) {
          D_BUG( "surface_manager_assure_system() called on video only surface" );
          return DFB_BUG;
     }

     if (buffer->system.health == CSH_STORED)
          return DFB_OK;
     else if (buffer->video.health == CSH_STORED) {
          int   i;
          char *src = dfb_system_video_memory_virtual( buffer->video.offset );
          char *dst = buffer->system.addr;

          /* from video_access_by_software() in surface.c */
          if (buffer->video.access & VAF_HARDWARE_WRITE) {
               dfb_gfxcard_sync();
               buffer->video.access &= ~VAF_HARDWARE_WRITE;
          }
          buffer->video.access |= VAF_SOFTWARE_READ;

          for (i=0; i<surface->height; i++) {
               direct_memcpy( dst, src, DFB_BYTES_PER_LINE(buffer->format, surface->width) );
               src += buffer->video.pitch;
               dst += buffer->system.pitch;
          }

          if (buffer->format == DSPF_YV12 || buffer->format == DSPF_I420) {
               for (i=0; i<surface->height; i++) {
                    direct_memcpy( dst, src, DFB_BYTES_PER_LINE(buffer->format,
                                                                surface->width / 2) );
                    src += buffer->video.pitch  / 2;
                    dst += buffer->system.pitch / 2;
               }
          }
          else if (buffer->format == DSPF_NV12 || buffer->format == DSPF_NV21) {
               for (i=0; i<surface->height/2; i++) {
                    direct_memcpy( dst, src, DFB_BYTES_PER_LINE(buffer->format,
                                                                surface->width) );
                    src += buffer->video.pitch;
                    dst += buffer->system.pitch;
               }
          }
          else if (buffer->format == DSPF_NV16) {
               for (i=0; i<surface->height; i++) {
                    direct_memcpy( dst, src, DFB_BYTES_PER_LINE(buffer->format,
                                                                surface->width) );
                    src += buffer->video.pitch;
                    dst += buffer->system.pitch;
               }
          }

          buffer->system.health = CSH_STORED;

          dfb_surface_notify_listeners( surface, CSNF_SYSTEM );

          return DFB_OK;
     }

     D_BUG( "no valid surface instance" );
     return DFB_BUG;
}
Esempio n. 26
0
DFBResult dfb_surfacemanager_assure_video( SurfaceManager *manager,
                                           SurfaceBuffer  *buffer )
{
     DFBResult    ret;
     CoreSurface *surface = buffer->surface;

     D_MAGIC_ASSERT( manager, SurfaceManager );

     if (manager->suspended)
          return DFB_NOVIDEOMEMORY;

     switch (buffer->video.health) {
          case CSH_STORED:
               if (buffer->video.chunk)
                    buffer->video.chunk->tolerations = 0;

               return DFB_OK;

          case CSH_INVALID:
               ret = dfb_surfacemanager_allocate( manager, buffer );
               if (ret)
                    return ret;

               /* FALL THROUGH, because after successful allocation
                  the surface health is CSH_RESTORE */

          case CSH_RESTORE:
               if (buffer->system.health != CSH_STORED)
                    D_BUG( "system/video instances both not stored!" );

               if (buffer->flags & SBF_WRITTEN) {
                    int   i;
                    char *src = buffer->system.addr;
                    char *dst = dfb_system_video_memory_virtual( buffer->video.offset );

                    for (i=0; i<surface->height; i++) {
                         direct_memcpy( dst, src,
                                        DFB_BYTES_PER_LINE(buffer->format, surface->width) );
                         src += buffer->system.pitch;
                         dst += buffer->video.pitch;
                    }

                    if (buffer->format == DSPF_YV12 || buffer->format == DSPF_I420) {
                         for (i=0; i<surface->height; i++) {
                              direct_memcpy( dst, src, DFB_BYTES_PER_LINE(buffer->format,
                                                                          surface->width / 2) );
                              src += buffer->system.pitch / 2;
                              dst += buffer->video.pitch  / 2;
                         }
                    }
                    else if (buffer->format == DSPF_NV12 || buffer->format == DSPF_NV21) {
                         for (i=0; i<surface->height/2; i++) {
                              direct_memcpy( dst, src, DFB_BYTES_PER_LINE(buffer->format,
                                                                          surface->width) );
                              src += buffer->system.pitch;
                              dst += buffer->video.pitch;
                         }
                    }
                    else if (buffer->format == DSPF_NV16) {
                         for (i=0; i<surface->height; i++) {
                              direct_memcpy( dst, src, DFB_BYTES_PER_LINE(buffer->format,
                                                                          surface->width) );
                              src += buffer->system.pitch;
                              dst += buffer->video.pitch;
                         }
                    }
               }

               buffer->video.health             = CSH_STORED;
               buffer->video.chunk->tolerations = 0;

               dfb_surface_notify_listeners( surface, CSNF_VIDEO );

               return DFB_OK;

          default:
               break;
     }

     D_BUG( "unknown video instance health" );
     return DFB_BUG;
}
Esempio n. 27
0
DirectResult
fusion_call_execute3(FusionCall          *call,
                     FusionCallExecFlags  flags,
                     int                  call_arg,
                     void                *ptr,
                     unsigned int         length,
                     void                *ret_ptr,
                     unsigned int         ret_size,
                     unsigned int        *ret_length)
{
     FusionWorld *world;
     CallTLS     *call_tls;

     D_DEBUG_AT( Fusion_Call, "%s( %p, flags 0x%x, arg %d, ptr %p, length %u, ret_ptr %p, ret_size %u )\n",
                 __FUNCTION__, call, flags, call_arg, ptr, length, ret_ptr, ret_size );

     if (ret_size > FUSION_CALL_RETURN_DATA_MAX)
          return DR_LIMITEXCEEDED;

     D_ASSERT( call != NULL );

//     if (!call->handler)
//          return DR_DESTROYED;

#if D_DEBUG_ENABLED
     if (direct_log_domain_check( &Fusion_Call )) // avoid call to direct_trace_lookup_symbol_at
          D_DEBUG_AT( Fusion_Call, "  -> %s\n", direct_trace_lookup_symbol_at( call->handler3 ) );
#endif

     world = _fusion_world( call->shared );

     call_tls = Call_GetTLS( world );

     if (call->fusion_id == fusion_id( world ) &&
         (!(flags & FCEF_NODIRECT) || (call_tls->dispatcher)))
     {
          FusionCallHandlerResult result;
          unsigned int            execute_length;

          D_ASSERT( call->handler3 != NULL );

          result = call->handler3( call->fusion_id, call_arg, ptr, length, call->ctx, 0, ret_ptr, ret_size, &execute_length );

          if (result != FCHR_RETURN)
               D_WARN( "local call handler returned FCHR_RETAIN, need FCEF_NODIRECT" );

          if (ret_length)
               *ret_length = execute_length;
     }
     else {
          FusionCallExecute3  execute;
          DirectResult        ret   = DR_OK;

          // check whether we can cache this call
          if (flags & FCEF_QUEUE && fusion_config->call_bin_max_num > 0) {
               D_ASSERT( flags & FCEF_ONEWAY );

               if (call_tls->bins_data_len + length > fusion_config->call_bin_max_data) {
                    ret = fusion_world_flush_calls( world, 0 );
                    if (ret)
                         return ret;
               }

               call_tls->bins[call_tls->bins_num].call_id    = call->call_id;
               call_tls->bins[call_tls->bins_num].call_arg   = call_arg;
               call_tls->bins[call_tls->bins_num].ptr        = NULL;
               call_tls->bins[call_tls->bins_num].length     = length;
               call_tls->bins[call_tls->bins_num].ret_ptr    = ret_ptr;
               call_tls->bins[call_tls->bins_num].ret_length = ret_size;
               call_tls->bins[call_tls->bins_num].flags      = flags | FCEF_FOLLOW;

               if (length > 0) {
                    call_tls->bins[call_tls->bins_num].ptr = &call_tls->bins_data[call_tls->bins_data_len];
                    direct_memcpy( &call_tls->bins_data[call_tls->bins_data_len], ptr, length );
                    call_tls->bins_data_len += length;
               }

               call_tls->bins_num++;

               if (call_tls->bins_num == 1)
                    call_tls->bins_create_ts = direct_clock_get_millis();
               else if (call_tls->bins_num >= fusion_config->call_bin_max_num || direct_clock_get_millis() - call_tls->bins_create_ts >= EXECUTE3_BIN_FLUSH_MILLIS)
                    ret = fusion_world_flush_calls( world, 0 );    

               return ret;
          }

          ret = fusion_world_flush_calls( world, 1 );

          execute.call_id    = call->call_id;
          execute.call_arg   = call_arg;
          execute.ptr        = ptr;
          execute.length     = length;
          execute.ret_ptr    = ret_ptr;
          execute.ret_length = ret_size;
          execute.flags      = flags | FCEF_RESUMABLE;
          execute.serial     = 0;

          D_DEBUG_AT( Fusion_Call, "  -> ptr %p, length %u\n", ptr, length );

          while (ioctl( world->fusion_fd, FUSION_CALL_EXECUTE3, &execute )) {
               switch (errno) {
                    case EINTR:
                         continue;
                    case EINVAL:
                         D_ERROR ("Fusion/Call: invalid call (id 0x%08x)\n", call->call_id);
                         return DR_INVARG;
                    case EIDRM:
                         return DR_DESTROYED;
                    default:
                         break;
               }

               D_PERROR ("FUSION_CALL_EXECUTE3 (call id 0x%08x, creator %lu)", call->call_id, call->fusion_id );

               return DR_FAILURE;
          }

          if (ret_length)
               *ret_length = execute.ret_length;
     }

     return DR_OK;
}
Esempio n. 28
0
/*
 * parses video modes in /etc/fb.modes and stores them in dfb_fbdev->shared->modes
 * (to be replaced by DirectFB's own config system
 */
static DFBResult dfb_fbdev_read_modes( void )
{
     FILE *fp;
     char line[80],label[32],value[16];
     int geometry=0, timings=0;
     int dummy;
     VideoMode temp_mode;
     VideoMode *m = dfb_sdl->modes;

     if (!(fp = fopen("/etc/fb.modes","r")))
          return errno2result( errno );

     while (fgets(line,79,fp)) {
          if (sscanf(line, "mode \"%31[^\"]\"",label) == 1) {
               memset( &temp_mode, 0, sizeof(VideoMode) );
               geometry = 0;
               timings = 0;
               while (fgets(line,79,fp) && !(strstr(line,"endmode"))) {
                    if (5 == sscanf(line," geometry %d %d %d %d %d", &temp_mode.xres, &temp_mode.yres, &dummy, &dummy, &temp_mode.bpp)) {
                         geometry = 1;
                    }
                    else if (7 == sscanf(line," timings %d %d %d %d %d %d %d", &temp_mode.pixclock, &temp_mode.left_margin,  &temp_mode.right_margin,
                                         &temp_mode.upper_margin, &temp_mode.lower_margin, &temp_mode.hsync_len,    &temp_mode.vsync_len)) {
                         timings = 1;
                    }
                    else if (1 == sscanf(line, " hsync %15s",value) && 0 == strcasecmp(value,"high")) {
                         temp_mode.hsync_high = 1;
                    }
                    else if (1 == sscanf(line, " vsync %15s",value) && 0 == strcasecmp(value,"high")) {
                         temp_mode.vsync_high = 1;
                    }
                    else if (1 == sscanf(line, " csync %15s",value) && 0 == strcasecmp(value,"high")) {
                         temp_mode.csync_high = 1;
                    }
                    else if (1 == sscanf(line, " laced %15s",value) && 0 == strcasecmp(value,"true")) {
                         temp_mode.laced = 1;
                    }
                    else if (1 == sscanf(line, " double %15s",value) && 0 == strcasecmp(value,"true")) {
                         temp_mode.doubled = 1;
                    }
                    else if (1 == sscanf(line, " gsync %15s",value) && 0 == strcasecmp(value,"true")) {
                         temp_mode.sync_on_green = 1;
                    }
                    else if (1 == sscanf(line, " extsync %15s",value) && 0 == strcasecmp(value,"true")) {
                         temp_mode.external_sync = 1;
                    }
                    else if (1 == sscanf(line, " bcast %15s",value) && 0 == strcasecmp(value,"true")) {
                         temp_mode.broadcast = 1;
                    }
               }
               if (geometry && timings) {
                    if (!m) {
                         dfb_sdl->modes = SHCALLOC( dfb_core_shmpool(dfb_sdl_core), 1, sizeof(VideoMode) );
                         m = dfb_sdl->modes;
                    }
                    else {
                         m->next = SHCALLOC( dfb_core_shmpool(dfb_sdl_core), 1, sizeof(VideoMode) );
                         m = m->next;
                    }
                    direct_memcpy (m, &temp_mode, sizeof(VideoMode));
                    D_DEBUG( "DirectFB/FBDev: %20s %4dx%4d  %s%s\n", label, temp_mode.xres, temp_mode.yres,
                              temp_mode.laced ? "interlaced " : "", temp_mode.doubled ? "doublescan" : "" );
               }
          }
     }

     fclose (fp);

     return DFB_OK;
}
Esempio n. 29
0
DFBResult
dfb_surface_write_buffer( CoreSurface            *surface,
                          CoreSurfaceBufferRole   role,
                          const void             *source,
                          int                     pitch,
                          const DFBRectangle     *prect )
{
     DFBResult              ret;
     int                    bytes;
     DFBRectangle           rect;
     DFBSurfacePixelFormat  format;
     CoreSurfaceAllocation *allocation;

     D_MAGIC_ASSERT( surface, CoreSurface );
     D_ASSERT( pitch > 0 || source == NULL );
     DFB_RECTANGLE_ASSERT_IF( prect );

     D_DEBUG_AT( Core_Surface, "%s( %p, %p [%d] )\n", __FUNCTION__, surface, source, pitch );

     /* Determine area. */
     rect.x = 0;
     rect.y = 0;
     rect.w = surface->config.size.w;
     rect.h = surface->config.size.h;

     if (prect) {
          if (!dfb_rectangle_intersect( &rect, prect )) {
               D_DEBUG_AT( Core_Surface, "  -> no intersection!\n" );
               return DFB_INVAREA;
          }

          if (!DFB_RECTANGLE_EQUAL( rect, *prect )) {
               D_DEBUG_AT( Core_Surface, "  -> got clipped to %d,%d-%dx%d!\n", DFB_RECTANGLE_VALS(&rect) );
               return DFB_INVAREA;
          }
     }

     /* Calculate bytes per read line. */
     format = surface->config.format;
     bytes  = DFB_BYTES_PER_LINE( format, rect.w );

     D_DEBUG_AT( Core_Surface, "  -> %d,%d - %dx%d (%s)\n", DFB_RECTANGLE_VALS(&rect),
                 dfb_pixelformat_name( format ) );

     ret = CoreSurface_PreLockBuffer2( surface, role, CSAID_CPU, CSAF_WRITE, false, &allocation );
     if (ret)
          return ret;

     D_MAGIC_ASSERT( allocation, CoreSurfaceAllocation );

     D_DEBUG_AT( Core_Surface, "  -> PreLockBuffer returned allocation %p (%s)\n", allocation, allocation->pool->desc.name );

     /* Try writing to allocation directly... */
     ret = source ? dfb_surface_pool_write( allocation->pool, allocation, source, pitch, &rect ) : DFB_UNSUPPORTED;
     if (ret) {
          /* ...otherwise use fallback method via locking if possible. */
          if (allocation->access[CSAID_CPU] & CSAF_WRITE) {
               int                   y;
               int                   bytes;
               DFBSurfacePixelFormat format;
               CoreSurfaceBufferLock lock;

               /* Calculate bytes per written line. */
               format = surface->config.format;
               bytes  = DFB_BYTES_PER_LINE( format, rect.w );

               /* Lock the allocation. */
               dfb_surface_buffer_lock_init( &lock, CSAID_CPU, CSAF_WRITE );

               ret = dfb_surface_pool_lock( allocation->pool, allocation, &lock );
               if (ret) {
                    D_DERROR( ret, "Core/SurfBuffer: Locking allocation failed! [%s]\n",
                              allocation->pool->desc.name );
                    dfb_surface_buffer_lock_deinit( &lock );
                    dfb_surface_allocation_unref( allocation );
                    return ret;
               }

               /* Move to start of write. */
               lock.addr += DFB_BYTES_PER_LINE( format, rect.x ) + rect.y * lock.pitch;

               /* Copy the data. */
               for (y=0; y<rect.h; y++) {
                    if (source) {
                         direct_memcpy( lock.addr, source, bytes );

                         source += pitch;
                    }
                    else
                         memset( lock.addr, 0, bytes );

                    lock.addr += lock.pitch;
               }

               /* Unlock the allocation. */
               ret = dfb_surface_pool_unlock( allocation->pool, allocation, &lock );
               if (ret)
                    D_DERROR( ret, "Core/SurfBuffer: Unlocking allocation failed! [%s]\n", allocation->pool->desc.name );

               dfb_surface_buffer_lock_deinit( &lock );
          }
     }

     dfb_surface_allocation_unref( allocation );

     return DFB_OK;
}
Esempio n. 30
0
DFBResult
dfb_surface_read_buffer( CoreSurface            *surface,
                         CoreSurfaceBufferRole   role,
                         void                   *destination,
                         int                     pitch,
                         const DFBRectangle     *prect )
{
     DFBResult              ret;
     int                    y;
     int                    bytes;
     DFBRectangle           rect;
     DFBSurfacePixelFormat  format;
     CoreSurfaceAllocation *allocation;

     D_MAGIC_ASSERT( surface, CoreSurface );
     D_ASSERT( destination != NULL );
     D_ASSERT( pitch > 0 );
     DFB_RECTANGLE_ASSERT_IF( prect );

     D_DEBUG_AT( Core_Surface, "%s( %p, %p [%d] )\n", __FUNCTION__, surface, destination, pitch );

     /* Determine area. */
     rect.x = 0;
     rect.y = 0;
     rect.w = surface->config.size.w;
     rect.h = surface->config.size.h;

     if (prect && (!dfb_rectangle_intersect( &rect, prect ) || !DFB_RECTANGLE_EQUAL( rect, *prect )))
          return DFB_INVAREA;

     /* Calculate bytes per read line. */
     format = surface->config.format;
     bytes  = DFB_BYTES_PER_LINE( format, rect.w );

     D_DEBUG_AT( Core_Surface, "  -> %d,%d - %dx%d (%s)\n", DFB_RECTANGLE_VALS(&rect),
                 dfb_pixelformat_name( format ) );

     ret = CoreSurface_PreLockBuffer2( surface, role, CSAID_CPU, CSAF_READ, false, &allocation );
     if (ret == DFB_NOALLOCATION) {
          for (y=0; y<rect.h; y++) {
               memset( destination, 0, bytes );

               destination += pitch;
          }

          return DFB_OK;
     }
     if (ret)
          return ret;

     D_MAGIC_ASSERT( allocation, CoreSurfaceAllocation );

     D_DEBUG_AT( Core_Surface, "  -> PreLockBuffer returned allocation %p (%s)\n", allocation, allocation->pool->desc.name );

     /* Try reading from allocation directly... */
     ret = dfb_surface_pool_read( allocation->pool, allocation, destination, pitch, &rect );
     if (ret) {
          /* ...otherwise use fallback method via locking if possible. */
          if (allocation->access[CSAID_CPU] & CSAF_READ) {
               CoreSurfaceBufferLock lock;

               /* Lock the allocation. */
               dfb_surface_buffer_lock_init( &lock, CSAID_CPU, CSAF_READ );

               ret = dfb_surface_pool_lock( allocation->pool, allocation, &lock );
               if (ret) {
                    D_DERROR( ret, "Core/SurfBuffer: Locking allocation failed! [%s]\n",
                              allocation->pool->desc.name );
                    dfb_surface_buffer_lock_deinit( &lock );
                    dfb_surface_allocation_unref( allocation );
                    return ret;
               }

               /* Move to start of read. */
               lock.addr += DFB_BYTES_PER_LINE( format, rect.x ) + rect.y * lock.pitch;

               /* Copy the data. */
               for (y=0; y<rect.h; y++) {
                    direct_memcpy( destination, lock.addr, bytes );

                    destination += pitch;
                    lock.addr   += lock.pitch;
               }

               /* Unlock the allocation. */
               ret = dfb_surface_pool_unlock( allocation->pool, allocation, &lock );
               if (ret)
                    D_DERROR( ret, "Core/SurfBuffer: Unlocking allocation failed! [%s]\n", allocation->pool->desc.name );

               dfb_surface_buffer_lock_deinit( &lock );
          }
     }

     dfb_surface_allocation_unref( allocation );

     return DFB_OK;
}