Ejemplo n.º 1
0
static ALCboolean pulse_load(void) //{{{
{
    ALCboolean ret = ALC_FALSE;
    if(!pa_handle)
    {
        pa_threaded_mainloop *loop;

#ifdef HAVE_DYNLOAD

#ifdef _WIN32
#define PALIB "libpulse-0.dll"
#elif defined(__APPLE__) && defined(__MACH__)
#define PALIB "libpulse.0.dylib"
#else
#define PALIB "libpulse.so.0"
#endif
        pa_handle = LoadLib(PALIB);
        if(!pa_handle)
            return ALC_FALSE;

#define LOAD_FUNC(x) do {                                                     \
    p##x = GetSymbol(pa_handle, #x);                                          \
    if(!(p##x)) {                                                             \
        CloseLib(pa_handle);                                                  \
        pa_handle = NULL;                                                     \
        return ALC_FALSE;                                                     \
    }                                                                         \
} while(0)
        LOAD_FUNC(pa_context_unref);
        LOAD_FUNC(pa_sample_spec_valid);
        LOAD_FUNC(pa_stream_drop);
        LOAD_FUNC(pa_strerror);
        LOAD_FUNC(pa_context_get_state);
        LOAD_FUNC(pa_stream_get_state);
        LOAD_FUNC(pa_threaded_mainloop_signal);
        LOAD_FUNC(pa_stream_peek);
        LOAD_FUNC(pa_threaded_mainloop_wait);
        LOAD_FUNC(pa_threaded_mainloop_unlock);
        LOAD_FUNC(pa_threaded_mainloop_in_thread);
        LOAD_FUNC(pa_context_new);
        LOAD_FUNC(pa_threaded_mainloop_stop);
        LOAD_FUNC(pa_context_disconnect);
        LOAD_FUNC(pa_threaded_mainloop_start);
        LOAD_FUNC(pa_threaded_mainloop_get_api);
        LOAD_FUNC(pa_context_set_state_callback);
        LOAD_FUNC(pa_stream_write);
        LOAD_FUNC(pa_xfree);
        LOAD_FUNC(pa_stream_connect_record);
        LOAD_FUNC(pa_stream_connect_playback);
        LOAD_FUNC(pa_stream_readable_size);
        LOAD_FUNC(pa_stream_writable_size);
        LOAD_FUNC(pa_stream_cork);
        LOAD_FUNC(pa_stream_is_suspended);
        LOAD_FUNC(pa_stream_get_device_name);
        LOAD_FUNC(pa_path_get_filename);
        LOAD_FUNC(pa_get_binary_name);
        LOAD_FUNC(pa_threaded_mainloop_free);
        LOAD_FUNC(pa_context_errno);
        LOAD_FUNC(pa_xmalloc);
        LOAD_FUNC(pa_stream_unref);
        LOAD_FUNC(pa_threaded_mainloop_accept);
        LOAD_FUNC(pa_stream_set_write_callback);
        LOAD_FUNC(pa_threaded_mainloop_new);
        LOAD_FUNC(pa_context_connect);
        LOAD_FUNC(pa_stream_set_buffer_attr);
        LOAD_FUNC(pa_stream_get_buffer_attr);
        LOAD_FUNC(pa_stream_get_sample_spec);
        LOAD_FUNC(pa_stream_get_time);
        LOAD_FUNC(pa_stream_set_read_callback);
        LOAD_FUNC(pa_stream_set_state_callback);
        LOAD_FUNC(pa_stream_set_moved_callback);
        LOAD_FUNC(pa_stream_set_underflow_callback);
        LOAD_FUNC(pa_stream_new);
        LOAD_FUNC(pa_stream_disconnect);
        LOAD_FUNC(pa_threaded_mainloop_lock);
        LOAD_FUNC(pa_channel_map_init_auto);
        LOAD_FUNC(pa_channel_map_parse);
        LOAD_FUNC(pa_channel_map_snprint);
        LOAD_FUNC(pa_channel_map_equal);
        LOAD_FUNC(pa_context_get_server_info);
        LOAD_FUNC(pa_context_get_sink_info_by_name);
        LOAD_FUNC(pa_context_get_sink_info_list);
        LOAD_FUNC(pa_context_get_source_info_list);
        LOAD_FUNC(pa_operation_get_state);
        LOAD_FUNC(pa_operation_unref);
#undef LOAD_FUNC
#define LOAD_OPTIONAL_FUNC(x) do {                                            \
    p##x = GetSymbol(pa_handle, #x);                                          \
} while(0)
#if PA_CHECK_VERSION(0,9,15)
        LOAD_OPTIONAL_FUNC(pa_channel_map_superset);
        LOAD_OPTIONAL_FUNC(pa_stream_set_buffer_attr_callback);
#endif
#if PA_CHECK_VERSION(0,9,16)
        LOAD_OPTIONAL_FUNC(pa_stream_begin_write);
#endif
#undef LOAD_OPTIONAL_FUNC

#else /* HAVE_DYNLOAD */
        pa_handle = (void*)0xDEADBEEF;
#endif

        if((loop=pa_threaded_mainloop_new()) &&
           pa_threaded_mainloop_start(loop) >= 0)
        {
            pa_context *context;

            pa_threaded_mainloop_lock(loop);
            context = connect_context(loop, AL_TRUE);
            if(context)
            {
                ret = ALC_TRUE;

                pa_context_disconnect(context);
                pa_context_unref(context);
            }
            pa_threaded_mainloop_unlock(loop);
            pa_threaded_mainloop_stop(loop);
        }
        if(loop)
            pa_threaded_mainloop_free(loop);

        if(!ret)
        {
#ifdef HAVE_DYNLOAD
            CloseLib(pa_handle);
#endif
            pa_handle = NULL;
        }
    }
    return ret;
} //}}}
void* pulse_load( void ) //{{{
{
	if ( !pa_handle )
	{
#ifdef _WIN32
		pa_handle = LoadLibrary( "libpulse-0.dll" );
#define LOAD_FUNC(x) do { \
    p##x = (typeof(p##x))GetProcAddress(pa_handle, #x); \
    if(!(p##x)) { \
        AL_PRINT("Could not load %s from libpulse-0.dll\n", #x); \
        FreeLibrary(pa_handle); \
        pa_handle = NULL; \
        return NULL; \
    } \
} while(0)
#define LOAD_OPTIONAL_FUNC(x) do { \
    p##x = (typeof(p##x))GetProcAddress(pa_handle, #x); \
} while(0)

#elif defined (HAVE_DLFCN_H)

		const char* err;
#if defined(__APPLE__) && defined(__MACH__)
		pa_handle = dlopen( "libpulse.0.dylib", RTLD_NOW );
#else
		pa_handle = dlopen( "libpulse.so.0", RTLD_NOW );
#endif
		dlerror();

#define LOAD_FUNC(x) do { \
    p##x = dlsym(pa_handle, #x); \
    if((err=dlerror()) != NULL) { \
        AL_PRINT("Could not load %s from libpulse: %s\n", #x, err); \
        dlclose(pa_handle); \
        pa_handle = NULL; \
        return NULL; \
    } \
} while(0)
#define LOAD_OPTIONAL_FUNC(x) do { \
    p##x = dlsym(pa_handle, #x); \
    if((err=dlerror()) != NULL) { \
        p##x = NULL; \
    } \
} while(0)

#else

		pa_handle = ( void* )0xDEADBEEF;
#define LOAD_FUNC(x) p##x = (x)
#define LOAD_OPTIONAL_FUNC(x) p##x = (x)

#endif

		if ( !pa_handle )
		{
			return NULL;
		}

		LOAD_FUNC( pa_context_unref );
		LOAD_FUNC( pa_sample_spec_valid );
		LOAD_FUNC( pa_stream_drop );
		LOAD_FUNC( pa_strerror );
		LOAD_FUNC( pa_context_get_state );
		LOAD_FUNC( pa_stream_get_state );
		LOAD_FUNC( pa_threaded_mainloop_signal );
		LOAD_FUNC( pa_stream_peek );
		LOAD_FUNC( pa_threaded_mainloop_wait );
		LOAD_FUNC( pa_threaded_mainloop_unlock );
		LOAD_FUNC( pa_threaded_mainloop_in_thread );
		LOAD_FUNC( pa_context_new );
		LOAD_FUNC( pa_threaded_mainloop_stop );
		LOAD_FUNC( pa_context_disconnect );
		LOAD_FUNC( pa_threaded_mainloop_start );
		LOAD_FUNC( pa_threaded_mainloop_get_api );
		LOAD_FUNC( pa_context_set_state_callback );
		LOAD_FUNC( pa_stream_write );
		LOAD_FUNC( pa_xfree );
		LOAD_FUNC( pa_stream_connect_record );
		LOAD_FUNC( pa_stream_connect_playback );
		LOAD_FUNC( pa_stream_readable_size );
		LOAD_FUNC( pa_stream_cork );
		LOAD_FUNC( pa_stream_is_suspended );
		LOAD_FUNC( pa_stream_get_device_name );
		LOAD_FUNC( pa_path_get_filename );
		LOAD_FUNC( pa_get_binary_name );
		LOAD_FUNC( pa_threaded_mainloop_free );
		LOAD_FUNC( pa_context_errno );
		LOAD_FUNC( pa_xmalloc );
		LOAD_FUNC( pa_stream_unref );
		LOAD_FUNC( pa_threaded_mainloop_accept );
		LOAD_FUNC( pa_stream_set_write_callback );
		LOAD_FUNC( pa_threaded_mainloop_new );
		LOAD_FUNC( pa_context_connect );
		LOAD_FUNC( pa_stream_set_buffer_attr );
		LOAD_FUNC( pa_stream_get_buffer_attr );
		LOAD_FUNC( pa_stream_get_sample_spec );
		LOAD_FUNC( pa_stream_set_read_callback );
		LOAD_FUNC( pa_stream_set_state_callback );
		LOAD_FUNC( pa_stream_set_moved_callback );
		LOAD_FUNC( pa_stream_new );
		LOAD_FUNC( pa_stream_disconnect );
		LOAD_FUNC( pa_threaded_mainloop_lock );
		LOAD_FUNC( pa_channel_map_init_auto );
		LOAD_FUNC( pa_channel_map_parse );
		LOAD_FUNC( pa_channel_map_snprint );
		LOAD_FUNC( pa_channel_map_equal );
		LOAD_FUNC( pa_context_get_server_info );
		LOAD_FUNC( pa_context_get_sink_info_by_name );
		LOAD_FUNC( pa_context_get_sink_info_list );
		LOAD_FUNC( pa_context_get_source_info_list );
		LOAD_FUNC( pa_operation_get_state );
		LOAD_FUNC( pa_operation_unref );
#if PA_CHECK_VERSION(0,9,15)
		LOAD_OPTIONAL_FUNC( pa_channel_map_superset );
		LOAD_OPTIONAL_FUNC( pa_stream_set_buffer_attr_callback );
#endif
#if PA_CHECK_VERSION(0,9,16)
		LOAD_OPTIONAL_FUNC( pa_stream_begin_write );
#endif

#undef LOAD_OPTIONAL_FUNC
#undef LOAD_FUNC
	}

	return pa_handle;
} //}}}