CoreCleanup * dfb_core_cleanup_add( CoreDFB *core, CoreCleanupFunc func, void *data, bool emergency ) { CoreCleanup *cleanup; D_ASSUME( core != NULL ); if (!core) core = core_dfb; D_MAGIC_ASSERT( core, CoreDFB ); cleanup = D_CALLOC( 1, sizeof(CoreCleanup) ); cleanup->func = func; cleanup->data = data; cleanup->emergency = emergency; direct_list_prepend( &core->cleanups, &cleanup->link ); return cleanup; }
void DirectRegisterInterface( DirectInterfaceFuncs *funcs ) { DirectInterfaceImplementation *impl; impl = calloc( 1, sizeof(DirectInterfaceImplementation) ); impl->funcs = funcs; impl->type = funcs->GetType(); impl->implementation = funcs->GetImplementation(); direct_list_prepend( &implementations, &impl->link ); }
void DirectRegisterInterface( DirectInterfaceFuncs *funcs ) { DirectInterfaceImplementation *impl; D_DEBUG_AT( Direct_Interface, "%s( %p )\n", __FUNCTION__, funcs ); impl = D_CALLOC( 1, sizeof(DirectInterfaceImplementation) ); impl->funcs = funcs; impl->type = funcs->GetType(); impl->implementation = funcs->GetImplementation(); D_MAGIC_SET( impl, DirectInterfaceImplementation ); D_DEBUG_AT( Direct_Interface, " -> %s | %s\n", impl->type, impl->implementation ); pthread_mutex_lock( &implementations_mutex ); direct_list_prepend( &implementations, &impl->link ); pthread_mutex_unlock( &implementations_mutex ); }
DirectResult voodoo_client_create( const char *host, int port, VoodooClient **ret_client ) { DirectResult ret; VoodooPlayInfo info; VoodooClient *client; VoodooPlayer *player; char buf[100] = { 0 }; const char *hostname = host; bool raw = true; D_ASSERT( ret_client != NULL ); if (!host) host = ""; if (!port) port = 2323; D_DEBUG_AT( Voodoo_Client, "%s( '%s', %d )\n", __FUNCTION__, host, port ); if (port != 2323) { D_DEBUG_AT( Voodoo_Client, " -> port != 2323, using PACKET mode right away\n" ); raw = false; } direct_list_foreach (client, m_clients) { if (!strcmp( client->host, host ) && client->port == port) { D_INFO( "Voodoo/Client: Reconnecting to '%s', increasing ref count of existing connection!\n", host ); client->refs++; *ret_client = client; return DR_OK; } } /* * Get the player singleton */ ret = voodoo_player_create( NULL, &player ); if (ret) { D_DERROR( ret, "Voodoo/Client: Could not create the player!\n" ); return ret; } /* * If we got a hostname or address try to lookup the player info */ // FIXME: resolve first, not late in voodoo_link_init_connect if (hostname && hostname[0]) { ret = voodoo_player_lookup_by_address( player, hostname, &info ); if (ret == DR_OK) { if (info.flags & VPIF_PACKET) raw = false; } } else { /* * Start discovery and use first host visible */ ret = discover_host( player, NULL, &info, buf, sizeof(buf) ); if (ret == DR_OK) { if (info.flags & VPIF_PACKET) raw = false; hostname = buf; } } if (!hostname || !hostname[0]) { D_ERROR( "Voodoo/Client: Did not find any other player!\n" ); return DR_ITEMNOTFOUND; } /* Allocate client structure. */ client = D_CALLOC( 1, sizeof(VoodooClient) ); if (!client) return D_OOM(); raw = !voodoo_config->link_packet && (voodoo_config->link_raw || raw); /* Create a link to the other player. */ ret = voodoo_link_init_connect( &client->vl, hostname, port, raw ); if (ret) { D_DERROR( ret, "Voodoo/Client: Failed to initialize Voodoo Link!\n" ); D_FREE( client ); return ret; } D_INFO( "Voodoo/Client: Fetching player information...\n" ); if (raw) { // FIXME: send_discover_and_receive_info() only does RAW, but we don't need it for packet connection, yet VoodooPlayVersion version; VoodooPlayInfo info; ret = send_discover_and_receive_info( &client->vl, &version, &info ); if (ret) { D_DEBUG_AT( Voodoo_Client, " -> Failed to receive player info via TCP!\n" ); D_INFO( "Voodoo/Client: No player information from '%s', trying to discover via UDP!\n", host ); /* * Fallback to UDP discovery */ ret = discover_host( player, hostname, &info, buf, sizeof(buf) ); if (ret == DR_OK) { if (info.flags & VPIF_PACKET) raw = false; } } else { D_INFO( "Voodoo/Client: Connected to '%s' (%-15s) %s " "=%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x= " "(vendor: %s, model: %s)\n", info.name, host, (info.flags & VPIF_LEVEL2) ? "*" : " ", info.uuid[0], info.uuid[1], info.uuid[2], info.uuid[3], info.uuid[4], info.uuid[5], info.uuid[6], info.uuid[7], info.uuid[8], info.uuid[9], info.uuid[10], info.uuid[11], info.uuid[12], info.uuid[13], info.uuid[14], info.uuid[15], info.vendor, info.model ); if (raw && !voodoo_config->link_raw) { /* * Switch to packet mode? */ if (info.flags & VPIF_PACKET) raw = false; } } /* * Switch to packet mode? */ if (!raw) { D_INFO( "Voodoo/Client: Switching to packet mode!\n" ); client->vl.Close( &client->vl ); /* Create another link to the other player. */ ret = voodoo_link_init_connect( &client->vl, hostname, port, false ); if (ret) { D_DERROR( ret, "Voodoo/Client: Failed to initialize second Voodoo Link!\n" ); D_FREE( client ); return ret; } } } /* Create the manager. */ ret = voodoo_manager_create( &client->vl, client, NULL, &client->manager ); if (ret) { client->vl.Close( &client->vl ); D_FREE( client ); return ret; } client->refs = 1; client->host = D_STRDUP( host ); client->port = port; direct_list_prepend( &m_clients, &client->link ); /* Return the new client. */ *ret_client = client; D_DEBUG_AT( Voodoo_Client, " => client %p\n", client ); return DR_OK; }