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; }
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"; }
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; }
/* * 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; }
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; }
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 ); }
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 ); }
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; }
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 ); }
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; }
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; }
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 ); }