Esempio n. 1
0
DirectResult
DirectResultTypeRegister( DirectResultType *type )
{
     DirectResult ret;

     D_DEBUG_AT( Direct_Result, "%s( %p )\n", __FUNCTION__, type );

     D_ASSERT( type != NULL );

     D_DEBUG_AT( Direct_Result, "  -> refs    %d\n", type->refs );
     D_DEBUG_AT( Direct_Result, "  -> base    0x%08x\n", type->base );
     D_DEBUG_AT( Direct_Result, "  -> strings %p\n", type->result_strings );
     D_DEBUG_AT( Direct_Result, "  -> count   %u\n", type->result_count );

     D_ASSERT( type->result_count > 0 );
     D_ASSERT( type->result_count <= D_RESULT_TYPE_SPACE );

     D_DEBUG_AT( Direct_Result, "  => %s\n", type->result_strings[0] );

     ret = direct_mutex_lock( &result_mutex );
     if (ret)
          return ret;

     if (direct_hash_lookup( &result_types, type->base )) {
          D_ASSERT( direct_hash_lookup( &result_types, type->base ) == type );

          D_MAGIC_ASSERT( type, DirectResultType );

          D_ASSERT( type->refs > 0 );

          type->refs++;
     }
     else {
          D_ASSERT( type->refs == 0 );

          D_MAGIC_SET( type, DirectResultType );

          ret = direct_hash_insert( &result_types, type->base, (void*) type );
          if (ret)
               D_MAGIC_CLEAR( type );
          else
               type->refs = 1;
     }

     direct_mutex_unlock( &result_mutex );

     return ret;
}
Esempio n. 2
0
const char *
DirectResultString( DirectResult result )
{
     DirectResult      ret;
     DirectResultType *type;

     if (result) {
          ret = direct_mutex_lock( &result_mutex );
          if (ret)
               return NULL;

          type = direct_hash_lookup( &result_types, D_RESULT_TYPE( result ) );

          direct_mutex_unlock( &result_mutex );

          if (type) {
               unsigned int index = D_RESULT_INDEX( result );

               D_MAGIC_ASSERT( type, DirectResultType );

               D_ASSERT( type->refs > 0 );

               if (index < type->result_count)
                    return type->result_strings[index];

               return type->result_strings[0];
          }

          return "UNKNOWN RESULT TYPE";
     }

     return "OK";
}
Esempio n. 3
0
DirectResult
voodoo_manager_lookup_local( VoodooManager     *manager,
                             VoodooInstanceID   instance_id,
                             void             **ret_dispatcher,
                             void             **ret_real )
{
     VoodooInstance *instance;

     D_MAGIC_ASSERT( manager, VoodooManager );
     D_ASSERT( instance_id != VOODOO_INSTANCE_NONE );
     D_ASSERT( ret_dispatcher != NULL || ret_real != NULL );

     pthread_mutex_lock( &manager->instances.lock );

     instance = direct_hash_lookup( manager->instances.local, instance_id );

     pthread_mutex_unlock( &manager->instances.lock );

     if (!instance)
          return DR_NOSUCHINSTANCE;

     if (ret_dispatcher)
          *ret_dispatcher = instance->proxy;

     if (ret_real)
          *ret_real = instance->real;

     return DR_OK;
}
Esempio n. 4
0
/*
 * Open the device, fill out information about it,
 * allocate and fill private data, start input thread.
 * Called during initialization, resuming or taking over mastership.
 */
static DFBResult
driver_open_device( CoreInputDevice  *device,
                    unsigned int      number,
                    InputDeviceInfo  *info,
                    void            **driver_data )
{
     InputHubDeviceNode *node;

     D_DEBUG_AT( Input_Hub, "%s( ID %u )\n", __FUNCTION__, number );

     node = direct_hash_lookup( m_nodes, number );
     if (!node) {
          D_BUG( "did not find device (ID %u)", number );
          return DFB_BUG;
     }

     info->prefered_id = number;
     info->desc        = node->description;

     node->device = device;

     *driver_data = (void*)(long) (number + 1);

     return DFB_OK;
}
Esempio n. 5
0
static DFBResult
x11DeallocateBuffer( CoreSurfacePool       *pool,
                     void                  *pool_data,
                     void                  *pool_local,
                     CoreSurfaceBuffer     *buffer,
                     CoreSurfaceAllocation *allocation,
                     void                  *alloc_data )
{
     x11AllocationData *alloc  = alloc_data;
     x11PoolLocalData  *local  = pool_local;
     DFBX11            *x11    = local->x11;
     DFBX11Shared      *shared = x11->shared;
     void              *addr;

     D_DEBUG_AT( X11_Surfaces, "%s()\n", __FUNCTION__ );

     D_MAGIC_ASSERT( pool, CoreSurfacePool );

     CORE_SURFACE_ALLOCATION_ASSERT( allocation );

     switch (alloc->type) {
          case X11_ALLOC_PIXMAP:
          case X11_ALLOC_WINDOW:
               if (allocation->type & CSTF_PREALLOCATED) {
                    // don't delete
               }
               else
                    XFreePixmap( x11->display, alloc->xid );
               break;

          case X11_ALLOC_IMAGE:
               x11ImageDestroy( x11, &alloc->image );

               // FIXME: also detach in other processes! (e.g. via reactor)
               addr = direct_hash_lookup( local->hash, alloc->image.seginfo.shmid );
               if (addr) {
                    x11ImageDetach( &alloc->image, addr );

                    direct_hash_remove( local->hash, alloc->image.seginfo.shmid );
               }
               break;

          case X11_ALLOC_SHM:
               if (alloc->ptr)
                    SHFREE( shared->data_shmpool, alloc->ptr );
               break;

          default:
               D_BUG( "unexpected allocation type %d\n", alloc->type );
               return DFB_BUG;
     }

     return DFB_OK;
}
Esempio n. 6
0
void
direct_perf_count( DirectPerfCounterInstallation *installation, int diff )
{
     DirectPerfCounter *counter;

     D_ASSERT( installation != NULL );

     direct_mutex_lock( &counter_lock );

     if (installation->counter_id == 0) {
          counter = D_CALLOC( 1, sizeof(DirectPerfCounter) );
          if (!counter) {
               direct_mutex_unlock( &counter_lock );
               D_OOM();
               return;
          }

          installation->counter_id = ++counter_ids;
          D_ASSERT( installation->counter_id != 0 );
          D_ASSERT( installation->counter_id != ~0 );   // FIXME: can there be more than 4 billion counters?

          direct_snputs( counter->name, installation->name, sizeof(counter->name) );

          counter->reset_on_dump = installation->reset_on_dump;

          direct_hash_insert( &counter_hash, installation->counter_id, counter );
     }
     else {
          counter = direct_hash_lookup( &counter_hash, installation->counter_id );
          if (!counter) {
               direct_mutex_unlock( &counter_lock );
               D_BUG( "unknown performance counter installation (%lu)", installation->counter_id );
               return;
          }
     }

     counter->count += diff;

     if (!counter->start)
          counter->start = direct_clock_get_time( DIRECT_CLOCK_SESSION );

     direct_mutex_unlock( &counter_lock );
}
Esempio n. 7
0
static void
InputHub_DeviceRemove( void             *ctx,
                       DFBInputDeviceID  device_id )
{
     InputHubDeviceNode *node;

     D_DEBUG_AT( Input_Hub, "%s( ID %u )\n", __FUNCTION__, device_id );

     node = direct_hash_lookup( m_nodes, device_id );
     if (node) {
          dfb_input_remove_device( device_id, m_driver );

          direct_hash_remove( m_nodes, device_id );

          D_FREE( node );
     }
     else
          D_WARN( "don't have device (ID %u)", device_id );
}
Esempio n. 8
0
DirectResult
DirectResultTypeUnregister( DirectResultType *type )
{
     DirectResult ret;

     D_DEBUG_AT( Direct_Result, "%s( %p )\n", __FUNCTION__, type );

     D_MAGIC_ASSERT( type, DirectResultType );

     D_DEBUG_AT( Direct_Result, "  -> refs    %d\n", type->refs );
     D_DEBUG_AT( Direct_Result, "  -> base    0x%08x\n", type->base );
     D_DEBUG_AT( Direct_Result, "  -> strings %p\n", type->result_strings );
     D_DEBUG_AT( Direct_Result, "  -> count   %u\n", type->result_count );

     D_ASSERT( type->result_count > 0 );
     D_ASSERT( type->result_count <= D_RESULT_TYPE_SPACE );

     D_DEBUG_AT( Direct_Result, "  => %s\n", type->result_strings[0] );


     ret = direct_mutex_lock( &result_mutex );
     if (ret)
          return ret;

     D_ASSERT( type->refs > 0 );

     D_ASSERT( direct_hash_lookup( &result_types, type->base ) == type );

     if (! --(type->refs)) {
          D_MAGIC_CLEAR( type );

          ret = direct_hash_remove( &result_types, type->base );
     }

     direct_mutex_unlock( &result_mutex );

     return ret;
}
Esempio n. 9
0
static void
InputHub_DeviceAdd( void                            *ctx,
                    DFBInputDeviceID                 device_id,
                    const DFBInputDeviceDescription *desc )
{
     DirectResult        ret;
     InputHubDeviceNode *node;

     D_DEBUG_AT( Input_Hub, "%s( ID %u, '%s' )\n", __FUNCTION__, device_id, desc->name );

     node = direct_hash_lookup( m_nodes, device_id );
     if (!node) {
          node = D_CALLOC( 1, sizeof(InputHubDeviceNode) );
          if (!node) {
               D_OOM();
               return;
          }

          node->device_id   = device_id;
          node->description = *desc;

          ret = direct_hash_insert( m_nodes, device_id, node );
          if (ret) {
               D_FREE( node );
               return;
          }

          ret = dfb_input_create_device( device_id, m_core, m_driver );
          if (ret) {
               direct_hash_remove( m_nodes, device_id );
               D_FREE( node );
               return;
          }
     }
     else
          D_WARN( "already have device (ID %u)", device_id );
}
Esempio n. 10
0
static void
InputHub_EventDispatch( void                *ctx,
                        DFBInputDeviceID     device_id,
                        const DFBInputEvent *event )
{
     InputHubDeviceNode *node;

     D_DEBUG_AT( Input_Hub, "%s( ID %u, %s )\n", __FUNCTION__, device_id, dfb_input_event_type_name(event->type) );

     node = direct_hash_lookup( m_nodes, device_id );
     if (node) {
          if (node->device) {
               DFBInputEvent event_copy = *event;

               D_DEBUG_AT( Input_Hub, "  -> found device %p (ID %u)\n", node->device, dfb_input_device_id(node->device) );
          
               dfb_input_dispatch( node->device, &event_copy );
          }
          else
               D_WARN( "inactive device (ID %u)", device_id );
     }
     else
          D_WARN( "unknown device (ID %u)", device_id );
}
static DFBResult
x11DeallocateBuffer( CoreSurfacePool       *pool,
                     void                  *pool_data,
                     void                  *pool_local,
                     CoreSurfaceBuffer     *buffer,
                     CoreSurfaceAllocation *allocation,
                     void                  *alloc_data )
{
     x11AllocationData *alloc  = alloc_data;
     x11PoolLocalData  *local  = pool_local;
     DFBX11            *x11    = local->x11;
     DFBX11Shared      *shared = x11->shared;
     void              *addr;

     D_DEBUG_AT( X11_Surfaces, "%s()\n", __FUNCTION__ );

     D_MAGIC_ASSERT( pool, CoreSurfacePool );

     CORE_SURFACE_ALLOCATION_ASSERT( allocation );

     // FIXME: also detach in other processes! (e.g. via reactor)
     addr = direct_hash_lookup( local->hash, alloc->image.seginfo.shmid );
     if (addr) {
          x11ImageDetach( &alloc->image, addr );

          direct_hash_remove( local->hash, alloc->image.seginfo.shmid );
     }

     if (alloc->real)
          return x11ImageDestroy( x11, &alloc->image );

     if (alloc->ptr)
          SHFREE( shared->data_shmpool, alloc->ptr );

     return DFB_OK;
}
Esempio n. 12
0
DirectResult
voodoo_manager_lookup_remote( VoodooManager     *manager,
                              VoodooInstanceID   instance_id,
                              void             **ret_requestor )
{
     VoodooInstance *instance;

     D_MAGIC_ASSERT( manager, VoodooManager );
     D_ASSERT( instance_id != VOODOO_INSTANCE_NONE );
     D_ASSERT( ret_requestor != NULL );

     pthread_mutex_lock( &manager->instances.lock );

     instance = direct_hash_lookup( manager->instances.remote, instance_id );

     pthread_mutex_unlock( &manager->instances.lock );

     if (!instance)
          return DR_NOSUCHINSTANCE;

     *ret_requestor = instance->proxy;

     return DR_OK;
}
static DFBResult
x11Lock( CoreSurfacePool       *pool,
         void                  *pool_data,
         void                  *pool_local,
         CoreSurfaceAllocation *allocation,
         void                  *alloc_data,
         CoreSurfaceBufferLock *lock )
{
     DFBResult          ret;
     x11PoolLocalData  *local  = pool_local;
     x11AllocationData *alloc  = alloc_data;
     DFBX11            *x11    = local->x11;
     DFBX11Shared      *shared = x11->shared;

     D_DEBUG_AT( X11_Surfaces, "%s( %p )\n", __FUNCTION__, allocation );

     D_MAGIC_ASSERT( pool, CoreSurfacePool );
     D_MAGIC_ASSERT( allocation, CoreSurfaceAllocation );
     D_MAGIC_ASSERT( lock, CoreSurfaceBufferLock );

     D_ASSERT( local->hash != NULL );

     pthread_mutex_lock( &local->lock );

     if (alloc->real) {
          void *addr = direct_hash_lookup( local->hash, alloc->image.seginfo.shmid );

          if (!addr) {
               ret = x11ImageAttach( &alloc->image, &addr );
               if (ret) {
                    D_DERROR( ret, "X11/Surfaces: x11ImageAttach() failed!\n" );
                    pthread_mutex_unlock( &local->lock );
                    return ret;
               }

               direct_hash_insert( local->hash, alloc->image.seginfo.shmid, addr );

               /* FIXME: When to remove/detach? */
          }

          lock->addr   = addr;
          lock->handle = &alloc->image;
     }
     else {
          if (!alloc->ptr) {
               D_DEBUG_AT( X11_Surfaces, "  -> allocating memory in data_shmpool (%d bytes)\n", allocation->size );

               alloc->ptr = SHCALLOC( shared->data_shmpool, 1, allocation->size );
               if (!alloc->ptr) {
                    pthread_mutex_unlock( &local->lock );
                    return D_OOSHM();
               }
          }

          lock->addr = alloc->ptr;
     }

     lock->pitch = alloc->pitch;

     pthread_mutex_unlock( &local->lock );

     return DFB_OK;
}
Esempio n. 14
0
static void
handle_request( VoodooManager        *manager,
                VoodooRequestMessage *request )
{
     DirectResult    ret;
     VoodooInstance *instance;

     D_MAGIC_ASSERT( manager, VoodooManager );
     D_ASSERT( request != NULL );
     D_ASSERT( request->header.size >= sizeof(VoodooRequestMessage) );
     D_ASSERT( request->header.type == VMSG_REQUEST );

     D_DEBUG( "Voodoo/Dispatch: Handling REQUEST message %llu to %u::%u %s%s(%d bytes).\n",
              (unsigned long long)request->header.serial, request->instance, request->method,
              (request->flags & VREQ_RESPOND) ? "[RESPONDING] " : "",
              (request->flags & VREQ_ASYNC) ? "[ASYNC] " : "",
              request->header.size );

     pthread_mutex_lock( &manager->instances.lock );

     instance = direct_hash_lookup( manager->instances.local, request->instance );
     if (!instance) {
          pthread_mutex_unlock( &manager->instances.lock );

          D_ERROR( "Voodoo/Dispatch: "
                   "Requested instance %u doesn't exist (anymore)!\n", request->instance );

          if (request->flags & VREQ_RESPOND)
               voodoo_manager_respond( manager, request->header.serial,
                                       DR_NOSUCHINSTANCE, VOODOO_INSTANCE_NONE,
                                       VMBT_NONE );

          return;
     }

     if (request->flags & VREQ_ASYNC) {
          pthread_t             thread;
          DispatchAsyncContext *context;

          context = D_MALLOC( sizeof(DispatchAsyncContext) + request->header.size );
          if (!context) {
               D_WARN( "out of memory" );
               pthread_mutex_unlock( &manager->instances.lock );
               return;
          }

          context->manager  = manager;
          context->instance = instance;
          context->request  = (VoodooRequestMessage*) (context + 1);

          direct_memcpy( context->request, request, request->header.size );

          pthread_create( &thread, NULL, dispatch_async_thread, context );
          pthread_detach( thread );
     }
     else {
          ret = instance->dispatch( instance->proxy, instance->real, manager, request );

          if (ret && (request->flags & VREQ_RESPOND))
               voodoo_manager_respond( manager, request->header.serial,
                                       ret, VOODOO_INSTANCE_NONE,
                                       VMBT_NONE );
     }

     pthread_mutex_unlock( &manager->instances.lock );
}