about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/wrapped/wrappedpulse.c576
1 files changed, 312 insertions, 264 deletions
diff --git a/src/wrapped/wrappedpulse.c b/src/wrapped/wrappedpulse.c
index 2a398a41..7d782f29 100644
--- a/src/wrapped/wrappedpulse.c
+++ b/src/wrapped/wrappedpulse.c
@@ -66,11 +66,7 @@ typedef void (*vFipippV_t)(int, void*, int, void*, void*, void*);
 
 // TODO: change that static for a map ptr2ptr?
 static my_pa_mainloop_api_t my_mainloop_api = {0};
-static my_pa_mainloop_api_t my_mainloop_native = {0};
-static int mainloop_inited = 0;
-static my_pa_mainloop_api_t* my_mainloop_ref = NULL;
-static my_pa_mainloop_api_t* my_mainloop_orig = NULL;
-
+static void UpdateautobridgeMainloopAPI(x64emu_t* emu, bridge_t* bridge, my_pa_mainloop_api_t* api);
 
 // utility functions
 #define SUPER() \
@@ -136,12 +132,12 @@ static void* findFreeAPIFct(void* fct)
     return NULL;
 }
 
-#define GO(A)   \
-static uintptr_t my_io_event_fct_##A = 0;   \
+#define GO(A)                                                                                       \
+static uintptr_t my_io_event_fct_##A = 0;                                                           \
 static void my_io_event_##A(my_pa_mainloop_api_t* api, void* e, int fd, int events, void* data)     \
-{                                       \
-    if(api==my_mainloop_orig) api=my_mainloop_ref;                  \
-    RunFunctionFmt(my_io_event_fct_##A, "ppiip", api, e, fd, events, data);  \
+{                                                                                                   \
+    UpdateautobridgeMainloopAPI(thread_get_emu(), my_lib->w.bridge, api);                           \
+    RunFunctionFmt(my_io_event_fct_##A, "ppiip", api, e, fd, events, data);                         \
 }
 SUPER()
 #undef GO
@@ -159,12 +155,12 @@ static void* findIOEventFct(void* fct)
     return NULL;
 }
 
-#define GO(A)   \
-static uintptr_t my_time_event_fct_##A = 0;   \
+#define GO(A)                                                                               \
+static uintptr_t my_time_event_fct_##A = 0;                                                 \
 static void my_time_event_##A(my_pa_mainloop_api_t* api, void* e, void* tv, void* data)     \
-{                                       \
-    if(api==my_mainloop_orig) api=my_mainloop_ref;                  \
-    RunFunctionFmt(my_time_event_fct_##A, "pppp", api, e, tv, data);  \
+{                                                                                           \
+    UpdateautobridgeMainloopAPI(thread_get_emu(), my_lib->w.bridge, api);                   \
+    RunFunctionFmt(my_time_event_fct_##A, "pppp", api, e, tv, data);                        \
 }
 SUPER()
 #undef GO
@@ -183,12 +179,12 @@ static void* findTimeEventFct(void* fct)
     return NULL;
 }
 
-#define GO(A)   \
-static uintptr_t my_defer_event_fct_##A = 0;   \
-static void my_defer_event_##A(my_pa_mainloop_api_t* api, void* e, void* data)     \
-{                                       \
-    if(api==my_mainloop_orig) api=my_mainloop_ref;                  \
-    RunFunctionFmt(my_defer_event_fct_##A, "ppp", api, e, data);  \
+#define GO(A)                                                                       \
+static uintptr_t my_defer_event_fct_##A = 0;                                        \
+static void my_defer_event_##A(my_pa_mainloop_api_t* api, void* e, void* data)      \
+{                                                                                   \
+    UpdateautobridgeMainloopAPI(thread_get_emu(), my_lib->w.bridge, api);           \
+    RunFunctionFmt(my_defer_event_fct_##A, "ppp", api, e, data);                    \
 }
 SUPER()
 #undef GO
@@ -233,8 +229,8 @@ static void* find_poll_Fct(void* fct)
 static uintptr_t my_signal_fct_##A = 0;   \
 static void my_signal_##A(my_pa_mainloop_api_t* api, void* e, int sig, void *data)  \
 {                                                                                   \
-    if(api==my_mainloop_orig) api=my_mainloop_ref;                                  \
-    RunFunctionFmt(my_signal_fct_##A, "ppip", api, e, sig, data);               \
+    UpdateautobridgeMainloopAPI(thread_get_emu(), my_lib->w.bridge, api);           \
+    RunFunctionFmt(my_signal_fct_##A, "ppip", api, e, sig, data);                   \
 }
 SUPER()
 #undef GO
@@ -256,8 +252,8 @@ static void* find_signal_Fct(void* fct)
 static uintptr_t my_signal_destroy_fct_##A = 0;   \
 static void my_signal_destroy_##A(my_pa_mainloop_api_t* api, void* e, void *data)   \
 {                                                                                   \
-    if(api==my_mainloop_orig) api=my_mainloop_ref;                                  \
-    RunFunctionFmt(my_signal_destroy_fct_##A, "ppp", api, e, data);            \
+    UpdateautobridgeMainloopAPI(thread_get_emu(), my_lib->w.bridge, api);           \
+    RunFunctionFmt(my_signal_destroy_fct_##A, "ppp", api, e, data);                 \
 }
 SUPER()
 #undef GO
@@ -696,11 +692,11 @@ static void* find_card_info_Fct(void* fct)
     return NULL;
 }
 // source_output_info
-#define GO(A)                                                      \
+#define GO(A)                                                               \
 static uintptr_t my_source_output_info_fct_##A = 0;                         \
 static void my_source_output_info_##A(void* a, void* b, int c, void* d)     \
-{                                                                  \
-    RunFunctionFmt(my_source_output_info_fct_##A, "ppip", a, b, c, d);  \
+{                                                                           \
+    RunFunctionFmt(my_source_output_info_fct_##A, "ppip", a, b, c, d);      \
 }
 SUPER()
 #undef GO
@@ -722,7 +718,7 @@ static void* find_source_output_info_Fct(void* fct)
 static uintptr_t my_device_restore_subscribe_fct_##A = 0;                           \
 static void my_device_restore_subscribe_##A(void* a, int b, uint32_t c, void* d)    \
 {                                                                                   \
-    RunFunctionFmt(my_device_restore_subscribe_fct_##A, "piup", a, b, c, d);    \
+    RunFunctionFmt(my_device_restore_subscribe_fct_##A, "piup", a, b, c, d);        \
 }
 SUPER()
 #undef GO
@@ -740,12 +736,12 @@ static void* find_device_restore_subscribe_Fct(void* fct)
     return NULL;
 }
 // mainloop_once
-#define GO(A)                                               \
-static uintptr_t my_mainloop_once_fct_##A = 0;              \
-static void my_mainloop_once_##A(void* api, void* b)        \
-{                                                           \
-    if(api==my_mainloop_orig) api=my_mainloop_ref;          \
-    RunFunctionFmt(my_mainloop_once_fct_##A, "pp", api, b); \
+#define GO(A)                                                               \
+static uintptr_t my_mainloop_once_fct_##A = 0;                              \
+static void my_mainloop_once_##A(void* api, void* b)                        \
+{                                                                           \
+    UpdateautobridgeMainloopAPI(thread_get_emu(), my_lib->w.bridge, api);   \
+    RunFunctionFmt(my_mainloop_once_fct_##A, "pp", api, b);                 \
 }
 SUPER()
 #undef GO
@@ -762,267 +758,325 @@ static void* find_mainloop_once_Fct(void* fct)
     printf_log(LOG_NONE, "Warning, no more slot for pulse audio mainloop_once callback\n");
     return NULL;
 }
-
-#undef SUPER
-
-
-// Mainloop functions
-//  but first, all cb from the pa_mainloop_api (serioulsy, how many callback and callback inside callback there is in pulse audio?!!!)
-
-// Native version of the mailoop_api. Called from x64 space
-
-static void* native_io_new(void* api, int fd, int events, void* cb, void *data)
-{
-    if(api==my_mainloop_ref) api=my_mainloop_orig;    // need native version
-    // need to wrap the callback!
-    void* c = findIOEventFct(cb);
-    return ((pFpiipp_t)my_mainloop_native.io_new)(api, fd, events, c, data);
+// io_new
+#define GO(A)                                                                                                                                           \
+static uintptr_t my_io_new_fct_##A = 0;                                                                                                                 \
+static void* my_io_new_##A(void* api, int fd, int events, void* cb, void* data)                                                                         \
+{                                                                                                                                                       \
+    return (void*)RunFunctionFmt(my_io_new_fct_##A, "piipp", api, fd, events, AddCheckBridge(my_lib->w.bridge, vFppiip, cb, 0, "my_io_new_cb"),data);   \
 }
-static void native_io_enable(void* e, int events)
+SUPER()
+#undef GO
+static void* find_io_new_Fct(void* fct)
 {
-    return ((vFpi_t)my_mainloop_native.io_enable)(e, events);
+    if(!fct) return fct;
+    if(GetNativeFnc((uintptr_t)fct))  return GetNativeFnc((uintptr_t)fct);
+    #define GO(A) if(my_io_new_fct_##A == (uintptr_t)fct) return my_io_new_##A;
+    SUPER()
+    #undef GO
+    #define GO(A) if(my_io_new_fct_##A == 0) {my_io_new_fct_##A = (uintptr_t)fct; return my_io_new_##A; }
+    SUPER()
+    #undef GO
+    printf_log(LOG_NONE, "Warning, no more slot for pulse audio io_new callback\n");
+    return NULL;
 }
-static void native_io_free(void* e)
-{
-    return ((vFp_t)my_mainloop_native.io_free)(e);
+// io_enable
+#define GO(A)                                                   \
+static uintptr_t my_io_enable_fct_##A = 0;                      \
+static void* my_io_enable_##A(void* api, int events)            \
+{                                                               \
+    RunFunctionFmt(my_io_enable_fct_##A, "pi", api, events);    \
 }
-static void native_io_set_destroy(void* e, void* cb)
+SUPER()
+#undef GO
+static void* find_io_enable_Fct(void* fct)
 {
-    // need to wrap the callback!
-    void* c = findFreeAPIFct(cb);
-    return ((vFpp_t)my_mainloop_native.io_set_destroy)(e, c);
+    if(!fct) return fct;
+    if(GetNativeFnc((uintptr_t)fct))  return GetNativeFnc((uintptr_t)fct);
+    #define GO(A) if(my_io_enable_fct_##A == (uintptr_t)fct) return my_io_enable_##A;
+    SUPER()
+    #undef GO
+    #define GO(A) if(my_io_enable_fct_##A == 0) {my_io_enable_fct_##A = (uintptr_t)fct; return my_io_enable_##A; }
+    SUPER()
+    #undef GO
+    printf_log(LOG_NONE, "Warning, no more slot for pulse audio io_enable callback\n");
+    return NULL;
 }
-
-static void* native_time_new(void* api, void* tv, void* cb, void* data)
-{
-    if(api==my_mainloop_ref) api=my_mainloop_orig;    // need native version
-    // need to wrap the callback!
-    void* c = findTimeEventFct(cb);
-    return ((pFpppp_t)my_mainloop_native.time_new)(api, tv, c, data);
+// io_free
+#define GO(A)                                   \
+static uintptr_t my_io_free_fct_##A = 0;        \
+static void* my_io_free_##A(void* e)            \
+{                                               \
+    RunFunctionFmt(my_io_free_fct_##A, "p", e); \
 }
-static void native_time_restart(void* e, void* tv)
+SUPER()
+#undef GO
+static void* find_io_free_Fct(void* fct)
 {
-    return ((vFpp_t)my_mainloop_native.time_restart)(e, tv);
+    if(!fct) return fct;
+    if(GetNativeFnc((uintptr_t)fct))  return GetNativeFnc((uintptr_t)fct);
+    #define GO(A) if(my_io_free_fct_##A == (uintptr_t)fct) return my_io_free_##A;
+    SUPER()
+    #undef GO
+    #define GO(A) if(my_io_free_fct_##A == 0) {my_io_free_fct_##A = (uintptr_t)fct; return my_io_free_##A; }
+    SUPER()
+    #undef GO
+    printf_log(LOG_NONE, "Warning, no more slot for pulse audio io_free callback\n");
+    return NULL;
 }
-static void native_time_free(void* e)
-{
-    return ((vFp_t)my_mainloop_native.time_free)(e);
+// io_set_destroy
+#define GO(A)                                                                                                                   \
+static uintptr_t my_io_set_destroy_fct_##A = 0;                                                                                 \
+static void my_io_set_destroy_##A(void* e, void* cb)                                                                            \
+{                                                                                                                               \
+    RunFunctionFmt(my_io_set_destroy_fct_##A, "pp", e, AddCheckBridge(my_lib->w.bridge, vFppp, cb, 0, "my_io_set_destroy_cb")); \
 }
-static void native_time_set_destroy(void* e, void* cb)
+SUPER()
+#undef GO
+static void* find_io_set_destroy_Fct(void* fct)
 {
-    // need to wrap the callback!
-    void* c = findFreeAPIFct(cb);
-    return ((vFpp_t)my_mainloop_native.time_set_destroy)(e, c);
+    if(!fct) return fct;
+    if(GetNativeFnc((uintptr_t)fct))  return GetNativeFnc((uintptr_t)fct);
+    #define GO(A) if(my_io_set_destroy_fct_##A == (uintptr_t)fct) return my_io_set_destroy_##A;
+    SUPER()
+    #undef GO
+    #define GO(A) if(my_io_set_destroy_fct_##A == 0) {my_io_set_destroy_fct_##A = (uintptr_t)fct; return my_io_set_destroy_##A; }
+    SUPER()
+    #undef GO
+    printf_log(LOG_NONE, "Warning, no more slot for pulse audio io_set_destroy callback\n");
+    return NULL;
 }
-
-static void* native_defer_new(void* api, void* cb, void* data)
-{
-    if(api==my_mainloop_ref) api=my_mainloop_orig;    // need native version
-    // need to wrap the callback!
-    void* c = findDeferEventFct(cb);
-    return ((pFppp_t)my_mainloop_native.defer_new)(api, c, data);
+// time_new
+#define GO(A)                                                                                                                                   \
+static uintptr_t my_time_new_fct_##A = 0;                                                                                                       \
+static void* my_time_new_##A(void* api, void* t, void* cb, void* data)                                                                          \
+{                                                                                                                                               \
+    return (void*)RunFunctionFmt(my_time_new_fct_##A, "pppp", api, t, AddCheckBridge(my_lib->w.bridge, vFpppp, cb, 0, "my_time_new_cb"), data); \
 }
-static void native_defer_enable(void* e, int b)
+SUPER()
+#undef GO
+static void* find_time_new_Fct(void* fct)
 {
-    return ((vFpi_t)my_mainloop_native.defer_enable)(e, b);
+    if(!fct) return fct;
+    if(GetNativeFnc((uintptr_t)fct))  return GetNativeFnc((uintptr_t)fct);
+    #define GO(A) if(my_time_new_fct_##A == (uintptr_t)fct) return my_time_new_##A;
+    SUPER()
+    #undef GO
+    #define GO(A) if(my_time_new_fct_##A == 0) {my_time_new_fct_##A = (uintptr_t)fct; return my_time_new_##A; }
+    SUPER()
+    #undef GO
+    printf_log(LOG_NONE, "Warning, no more slot for pulse audio time_new callback\n");
+    return NULL;
 }
-static void native_defer_free(void* e)
-{
-    return ((vFp_t)my_mainloop_native.defer_free)(e);
+// time_restart
+#define GO(A)                                               \
+static uintptr_t my_time_restart_fct_##A = 0;               \
+static void* my_time_restart_##A(void* e, void* t)          \
+{                                                           \
+    RunFunctionFmt(my_time_restart_fct_##A, "pp", e, t);    \
 }
-static void native_defer_set_destroy(void* e, void* cb)
+SUPER()
+#undef GO
+static void* find_time_restart_Fct(void* fct)
 {
-    // need to wrap the callback!
-    void* c = findFreeAPIFct(cb);
-    return ((vFpp_t)my_mainloop_native.defer_set_destroy)(e, c);
+    if(!fct) return fct;
+    if(GetNativeFnc((uintptr_t)fct))  return GetNativeFnc((uintptr_t)fct);
+    #define GO(A) if(my_time_restart_fct_##A == (uintptr_t)fct) return my_time_restart_##A;
+    SUPER()
+    #undef GO
+    #define GO(A) if(my_time_restart_fct_##A == 0) {my_time_restart_fct_##A = (uintptr_t)fct; return my_time_restart_##A; }
+    SUPER()
+    #undef GO
+    printf_log(LOG_NONE, "Warning, no more slot for pulse audio time_restart callback\n");
+    return NULL;
 }
-
-static void native_quit(void* api, int retval)
-{
-    if(api==my_mainloop_ref) api=my_mainloop_orig;    // need native version
-    return ((vFpi_t)my_mainloop_native.quit)(api, retval);
+// time_free
+#define GO(A)                                       \
+static uintptr_t my_time_free_fct_##A = 0;          \
+static void* my_time_free_##A(void* e)              \
+{                                                   \
+    RunFunctionFmt(my_time_free_fct_##A, "p", e);   \
 }
-
-// Emulated version. Called from native space (meh, crossing stuff are hard to follow)
-static void* my_io_new(void* api, int fd, int events, void* cb, void *userdata)
+SUPER()
+#undef GO
+static void* find_time_free_Fct(void* fct)
 {
-    uintptr_t b = (uintptr_t)cb;
-    void* fnc = GetNativeFnc((uintptr_t)my_mainloop_ref->io_new);
-    if(fnc) {
-        if(fnc==native_io_new) fnc=my_mainloop_native.io_new;
-        if(api==my_mainloop_ref) api=my_mainloop_orig;    // need native version
-        return ((pFpiipp_t)fnc)(api, fd, events, cb, userdata);
-    }
-
-    bridge_t* bridge = my_lib->w.bridge;
-    if(cb)
-        b = AddCheckBridge(bridge, vFppiip, cb, 0, NULL);
-    if(api==my_mainloop_orig) api=my_mainloop_ref;    // need emulated version
-    return (void*)RunFunctionFmt((uintptr_t)my_mainloop_ref->io_new, "piipp", api, fd, events, b, userdata);
+    if(!fct) return fct;
+    if(GetNativeFnc((uintptr_t)fct))  return GetNativeFnc((uintptr_t)fct);
+    #define GO(A) if(my_time_free_fct_##A == (uintptr_t)fct) return my_time_free_##A;
+    SUPER()
+    #undef GO
+    #define GO(A) if(my_time_free_fct_##A == 0) {my_time_free_fct_##A = (uintptr_t)fct; return my_time_free_##A; }
+    SUPER()
+    #undef GO
+    printf_log(LOG_NONE, "Warning, no more slot for pulse audio time_free callback\n");
+    return NULL;
 }
-static void my_io_enable(void* e, int events)
-{
-    void* fnc = GetNativeFnc((uintptr_t)my_mainloop_ref->io_enable);
-    if(fnc==native_io_enable) fnc=my_mainloop_native.io_enable;
-    if(fnc)
-        return ((vFpi_t)fnc)(e, events);
-
-    RunFunctionFmt((uintptr_t)my_mainloop_ref->io_enable, "pi", e, events);
+// time_set_destroy
+#define GO(A)                                                                                                                   \
+static uintptr_t my_time_set_destroy_fct_##A = 0;                                                                               \
+static void my_time_set_destroy_##A(void* e, void* cb)                                                                          \
+{                                                                                                                               \
+    RunFunctionFmt(my_time_set_destroy_fct_##A, "pp", e, AddCheckBridge(my_lib->w.bridge, vFppp, cb, 0, "my_time_set_destroy_cb")); \
 }
-static void my_io_free(void* e)
+SUPER()
+#undef GO
+static void* find_time_set_destroy_Fct(void* fct)
 {
-    void* fnc = GetNativeFnc((uintptr_t)my_mainloop_ref->io_free);
-    if(fnc==native_io_free) fnc=my_mainloop_native.io_free;
-    if(fnc)
-        return ((vFp_t)fnc)(e);
-
-    RunFunctionFmt((uintptr_t)my_mainloop_ref->io_free, "p", e);
+    if(!fct) return fct;
+    if(GetNativeFnc((uintptr_t)fct))  return GetNativeFnc((uintptr_t)fct);
+    #define GO(A) if(my_time_set_destroy_fct_##A == (uintptr_t)fct) return my_time_set_destroy_##A;
+    SUPER()
+    #undef GO
+    #define GO(A) if(my_time_set_destroy_fct_##A == 0) {my_time_set_destroy_fct_##A = (uintptr_t)fct; return my_time_set_destroy_##A; }
+    SUPER()
+    #undef GO
+    printf_log(LOG_NONE, "Warning, no more slot for pulse audio time_set_destroy callback\n");
+    return NULL;
 }
-static void my_io_set_destroy(void* e, void* cb)
-{
-    void* fnc = GetNativeFnc((uintptr_t)my_mainloop_ref->io_set_destroy);
-    if(fnc==native_io_set_destroy) fnc=my_mainloop_native.io_set_destroy;
-    if(fnc)
-        return ((vFpp_t)fnc)(e, cb);
-
-    bridge_t* bridge = my_lib->w.bridge;
-    uintptr_t b = 0;
-    if(cb) {
-        b = CheckBridged(bridge, cb);
-        if(!b)
-            b = AddBridge(bridge, vFppp, cb, 0, NULL);
-    }
-    RunFunctionFmt((uintptr_t)my_mainloop_ref->io_set_destroy, "pp", e, b);
+// defer_new
+#define GO(A)                                                                                                                                   \
+static uintptr_t my_defer_new_fct_##A = 0;                                                                                                      \
+static void* my_defer_new_##A(void* api, void* cb, void* data)                                                                                  \
+{                                                                                                                                               \
+    return (void*)RunFunctionFmt(my_defer_new_fct_##A, "ppp", api, AddCheckBridge(my_lib->w.bridge, vFpppp, cb, 0, "my_defer_new_cb"), data);   \
 }
-
-static void* my_time_new(void* api, void* tv, void* cb, void* data)
+SUPER()
+#undef GO
+static void* find_defer_new_Fct(void* fct)
 {
-    uintptr_t b = (uintptr_t)cb;
-    void* fnc = GetNativeFnc((uintptr_t)my_mainloop_ref->time_new);
-    if(fnc) {
-        if(fnc==native_time_new) fnc=my_mainloop_native.time_new;
-        if(api==my_mainloop_ref) api=my_mainloop_orig;    // need native version
-        return ((pFpppp_t)fnc)(api, tv, (void*)b, data);
-    }
-
-    // need to bridge the callback!
-    bridge_t* bridge = my_lib->w.bridge;
-    if(cb)
-        b = AddCheckBridge(bridge, vFpppp, cb, 0, NULL);
-    if(api==my_mainloop_orig) api=my_mainloop_ref;    // need emulated version
-    return (void*)RunFunctionFmt((uintptr_t)my_mainloop_ref->time_new, "pppp", api, tv, b, data);
+    if(!fct) return fct;
+    if(GetNativeFnc((uintptr_t)fct))  return GetNativeFnc((uintptr_t)fct);
+    #define GO(A) if(my_defer_new_fct_##A == (uintptr_t)fct) return my_defer_new_##A;
+    SUPER()
+    #undef GO
+    #define GO(A) if(my_defer_new_fct_##A == 0) {my_defer_new_fct_##A = (uintptr_t)fct; return my_defer_new_##A; }
+    SUPER()
+    #undef GO
+    printf_log(LOG_NONE, "Warning, no more slot for pulse audio defer_new callback\n");
+    return NULL;
 }
-static void my_time_restart(void* e, void* tv)
-{
-    void* fnc = GetNativeFnc((uintptr_t)my_mainloop_ref->time_restart);
-    if(fnc==native_time_restart) fnc=my_mainloop_native.time_restart;
-    if(fnc)
-        return ((vFpp_t)fnc)(e, tv);
-
-    RunFunctionFmt((uintptr_t)my_mainloop_ref->time_restart, "pp", e, tv);
+// defer_enable
+#define GO(A)                                               \
+static uintptr_t my_defer_enable_fct_##A = 0;               \
+static void* my_defer_enable_##A(void* e, int b)            \
+{                                                           \
+    RunFunctionFmt(my_defer_enable_fct_##A, "pi", e, b);    \
 }
-static void my_time_free(void* e)
+SUPER()
+#undef GO
+static void* find_defer_enable_Fct(void* fct)
 {
-    void* fnc = GetNativeFnc((uintptr_t)my_mainloop_ref->time_free);
-    if(fnc==native_time_free) fnc=my_mainloop_native.time_free;
-    if(fnc)
-        return ((vFp_t)fnc)(e);
-
-    RunFunctionFmt((uintptr_t)my_mainloop_ref->time_free, "p", e);
+    if(!fct) return fct;
+    if(GetNativeFnc((uintptr_t)fct))  return GetNativeFnc((uintptr_t)fct);
+    #define GO(A) if(my_defer_enable_fct_##A == (uintptr_t)fct) return my_defer_enable_##A;
+    SUPER()
+    #undef GO
+    #define GO(A) if(my_defer_enable_fct_##A == 0) {my_defer_enable_fct_##A = (uintptr_t)fct; return my_defer_enable_##A; }
+    SUPER()
+    #undef GO
+    printf_log(LOG_NONE, "Warning, no more slot for pulse audio defer_enable callback\n");
+    return NULL;
 }
-static void my_time_set_destroy(void* e, void* cb)
-{
-    void* fnc = GetNativeFnc((uintptr_t)my_mainloop_ref->time_set_destroy);
-    if(fnc==native_time_set_destroy) fnc=my_mainloop_native.time_set_destroy;
-    if(fnc)
-        return ((vFpp_t)fnc)(e, cb);
-
-    bridge_t* bridge = my_lib->w.bridge;
-    uintptr_t b = 0;
-    if(cb)
-            b = AddCheckBridge(bridge, vFppp, cb, 0, NULL);
-    RunFunctionFmt((uintptr_t)my_mainloop_ref->time_set_destroy, "pp", e, b);
+// defer_free
+#define GO(A)                                       \
+static uintptr_t my_defer_free_fct_##A = 0;         \
+static void* my_defer_free_##A(void* e)             \
+{                                                   \
+    RunFunctionFmt(my_defer_free_fct_##A, "p", e);  \
 }
-
-static void* my_defer_new(void* api, void* cb, void* data)
+SUPER()
+#undef GO
+static void* find_defer_free_Fct(void* fct)
 {
-    uintptr_t b = (uintptr_t)cb;
-    static void* old_defer_new = NULL;
-    static void* old_fnc = NULL;
-    void* fnc = NULL;
-    if(old_defer_new == my_mainloop_ref->defer_new)
-        fnc = old_fnc;
-    else {
-        old_fnc = fnc = GetNativeFnc((uintptr_t)my_mainloop_ref->defer_new);
-        old_defer_new = my_mainloop_ref->defer_new;
-    }
-    if(fnc) {
-        if(api==my_mainloop_ref) api=my_mainloop_orig;    // need native version
-        if(fnc==native_defer_new) fnc=my_mainloop_native.defer_new;
-        return ((pFppp_t)fnc)(api, cb, data);
-    }
-
-    // need to bridge the callback!
-    bridge_t* bridge = my_lib->w.bridge;
-    if(cb) {
-        b = CheckBridged(bridge, cb);
-        if(!b)
-            b = AddBridge(bridge, vFppp, cb, 0, NULL);
-    }
-    if(api==my_mainloop_orig) api=my_mainloop_ref;    // need emulated version
-    return (void*)RunFunctionFmt((uintptr_t)my_mainloop_ref->defer_new, "ppp", api, b, data);
+    if(!fct) return fct;
+    if(GetNativeFnc((uintptr_t)fct))  return GetNativeFnc((uintptr_t)fct);
+    #define GO(A) if(my_defer_free_fct_##A == (uintptr_t)fct) return my_defer_free_##A;
+    SUPER()
+    #undef GO
+    #define GO(A) if(my_defer_free_fct_##A == 0) {my_defer_free_fct_##A = (uintptr_t)fct; return my_defer_free_##A; }
+    SUPER()
+    #undef GO
+    printf_log(LOG_NONE, "Warning, no more slot for pulse audio defer_free callback\n");
+    return NULL;
 }
-static void my_defer_enable(void* e, int b)
-{
-    void* fnc = GetNativeFnc((uintptr_t)my_mainloop_ref->defer_enable);
-    if(fnc==native_defer_enable) fnc=my_mainloop_native.defer_enable;
-    if(fnc)
-        return ((vFpi_t)fnc)(e, b);
-
-    RunFunctionFmt((uintptr_t)my_mainloop_ref->defer_enable, "pi", e, b);
+// defer_set_destroy
+#define GO(A)                                                                                                                           \
+static uintptr_t my_defer_set_destroy_fct_##A = 0;                                                                                      \
+static void my_defer_set_destroy_##A(void* e, void* cb)                                                                                 \
+{                                                                                                                                       \
+    RunFunctionFmt(my_defer_set_destroy_fct_##A, "pp", e, AddCheckBridge(my_lib->w.bridge, vFppp, cb, 0, "my_defer_set_destroy_cb"));   \
 }
-static void my_defer_free(void* e)
+SUPER()
+#undef GO
+static void* find_defer_set_destroy_Fct(void* fct)
 {
-    void* fnc = GetNativeFnc((uintptr_t)my_mainloop_ref->defer_free);
-    if(fnc==native_defer_free) fnc=my_mainloop_native.defer_free;
-    if(fnc)
-        return ((vFp_t)fnc)(e);
-
-    RunFunctionFmt((uintptr_t)my_mainloop_ref->defer_free, "p", e);
+    if(!fct) return fct;
+    if(GetNativeFnc((uintptr_t)fct))  return GetNativeFnc((uintptr_t)fct);
+    #define GO(A) if(my_defer_set_destroy_fct_##A == (uintptr_t)fct) return my_defer_set_destroy_##A;
+    SUPER()
+    #undef GO
+    #define GO(A) if(my_defer_set_destroy_fct_##A == 0) {my_defer_set_destroy_fct_##A = (uintptr_t)fct; return my_defer_set_destroy_##A; }
+    SUPER()
+    #undef GO
+    printf_log(LOG_NONE, "Warning, no more slot for pulse audio defer_set_destroy callback\n");
+    return NULL;
 }
-static void my_defer_set_destroy(void* e, void* cb)
+// quit
+#define GO(A)                                           \
+static uintptr_t my_quit_fct_##A = 0;                   \
+static void* my_quit_##A(void* e, int retval)           \
+{                                                       \
+    RunFunctionFmt(my_quit_fct_##A, "pi", e, retval);   \
+}
+SUPER()
+#undef GO
+static void* find_quit_Fct(void* fct)
 {
-    void* fnc = GetNativeFnc((uintptr_t)my_mainloop_ref->defer_set_destroy);
-    if(fnc==native_defer_set_destroy) fnc=my_mainloop_native.defer_set_destroy;
-    if(fnc)
-        return ((vFpp_t)fnc)(e, cb);
-
-    bridge_t* bridge = my_lib->w.bridge;
-    uintptr_t b = 0;
-    if(cb)
-        b = AddCheckBridge(bridge, vFppp, cb, 0, NULL);
-    RunFunctionFmt((uintptr_t)my_mainloop_ref->defer_set_destroy, "pp", e, b);
+    if(!fct) return fct;
+    if(GetNativeFnc((uintptr_t)fct))  return GetNativeFnc((uintptr_t)fct);
+    #define GO(A) if(my_quit_fct_##A == (uintptr_t)fct) return my_quit_##A;
+    SUPER()
+    #undef GO
+    #define GO(A) if(my_quit_fct_##A == 0) {my_quit_fct_##A = (uintptr_t)fct; return my_quit_##A; }
+    SUPER()
+    #undef GO
+    printf_log(LOG_NONE, "Warning, no more slot for pulse audio quit callback\n");
+    return NULL;
 }
 
-static void my_quit(void* api, int retval)
+#undef SUPER
+
+static void UpdateautobridgeMainloopAPI(x64emu_t* emu, bridge_t* bridge, my_pa_mainloop_api_t* api)
 {
-    void* fnc = GetNativeFnc((uintptr_t)my_mainloop_ref->quit);
-    if(fnc) {
-        if(fnc==native_quit) fnc=my_mainloop_native.quit;
-        if(api==my_mainloop_ref) api=my_mainloop_orig;    // need native version
-        return ((vFpi_t)fnc)(api, retval);
+    if(!api) {
+        return;
     }
-
-    if(api==my_mainloop_orig) api=my_mainloop_ref;    // need emulated version
-    RunFunctionFmt((uintptr_t)my_mainloop_ref->quit, "pi", api, retval);
+    #define GO(A, W) if(api->A!=my_mainloop_api.A) {api->A=find_##A##_Fct(api->A); AddAutomaticBridge(emu, bridge, W, api->A, 0, NULL);}
+    GO(io_new, pFpiipp);
+    GO(io_enable, vFpi);
+    GO(io_free, vFp);
+    GO(io_set_destroy, vFpp);
+    GO(time_new, pFpppp);
+    GO(time_restart, vFpp);
+    GO(time_free, vFp);
+    GO(time_set_destroy, vFpp);
+    GO(defer_new, pFppp);
+    GO(defer_enable, vFpi);
+    GO(defer_free, vFp);
+    GO(defer_set_destroy, vFpp);
+    GO(quit, vFpi);
+    #undef GO
+    memcpy(&my_mainloop_api, api, sizeof(my_mainloop_api));
+    return;
 }
 
-static void bridgeMainloopAPI(bridge_t* bridge, my_pa_mainloop_api_t* api)
+static void autobridgeMainloopAPI(x64emu_t* emu, bridge_t* bridge, my_pa_mainloop_api_t* api)
 {
     if(!api) {
         return;
     }
-    #define GO(A, W) my_mainloop_native.A = api->A; if(api->A) {my_mainloop_api.A = (void*)AddCheckBridge(bridge, W, native_##A, 0, NULL); api->A=my_##A;} else my_mainloop_api.A = NULL
+    #define GO(A, W) if(api->A) AddAutomaticBridge(emu, bridge, W, api->A, 0, NULL)
     GO(io_new, pFpiipp);
     GO(io_enable, vFpi);
     GO(io_free, vFp);
@@ -1037,9 +1091,7 @@ static void bridgeMainloopAPI(bridge_t* bridge, my_pa_mainloop_api_t* api)
     GO(defer_set_destroy, vFpp);
     GO(quit, vFpi);
     #undef GO
-    my_mainloop_api.data = api->data;
-    my_mainloop_orig = api;
-    my_mainloop_ref = &my_mainloop_api;
+    memcpy(&my_mainloop_api, api, sizeof(my_mainloop_api));
     return;
 }
 /*static my_pa_mainloop_api_t* backMainloopAPI(my_pa_mainloop_api_t* mainloop)
@@ -1057,45 +1109,41 @@ static void bridgeMainloopAPI(bridge_t* bridge, my_pa_mainloop_api_t* api)
 EXPORT void my_pa_mainloop_free(x64emu_t* emu, void* mainloop)
 {
     my->pa_mainloop_free(mainloop);
-    mainloop_inited = 0;
-    /*my_mainloop_ref =*/ my_mainloop_orig = NULL;
 }
 EXPORT void* my_pa_mainloop_get_api(x64emu_t* emu, void* mainloop)
 {
     my_pa_mainloop_api_t* api = my->pa_mainloop_get_api(mainloop);
-    bridgeMainloopAPI(my_lib->w.bridge, api);
-    return my_mainloop_ref;
+    autobridgeMainloopAPI(emu, my_lib->w.bridge, api);
+    return api;
 }
 
 EXPORT void my_pa_threaded_mainloop_free(x64emu_t* emu, void* mainloop)
 {
     my->pa_threaded_mainloop_free(mainloop);
-    mainloop_inited = 0;
-    /*my_mainloop_ref =*/ my_mainloop_orig = NULL;
 }
 EXPORT void* my_pa_threaded_mainloop_get_api(x64emu_t* emu, void* mainloop)
 {
     my_pa_mainloop_api_t* api = my->pa_threaded_mainloop_get_api(mainloop);
-    bridgeMainloopAPI(my_lib->w.bridge, api);
-    return my_mainloop_ref;
+    autobridgeMainloopAPI(emu, my_lib->w.bridge, api);
+    return api;
 }
 
 // Context functions
 EXPORT void* my_pa_context_new(x64emu_t* emu, my_pa_mainloop_api_t* mainloop, void* name)
 {
-    if(mainloop==my_mainloop_ref) mainloop=my_mainloop_orig;    // need native version
+    UpdateautobridgeMainloopAPI(emu, my_lib->w.bridge, mainloop);
     return my->pa_context_new(mainloop, name);
 }
 
 EXPORT void* my_pa_context_new_with_proplist(x64emu_t* emu, my_pa_mainloop_api_t* mainloop, void* name, void* proplist)
 {
-    if(mainloop==my_mainloop_ref) mainloop=my_mainloop_orig;    // need native version
+    UpdateautobridgeMainloopAPI(emu, my_lib->w.bridge, mainloop);
     return my->pa_context_new_with_proplist(mainloop, name, proplist);
 }
 
 EXPORT int my_pa_signal_init(x64emu_t* emu, my_pa_mainloop_api_t* mainloop)
 {
-    if(mainloop==my_mainloop_ref) mainloop=my_mainloop_orig;    // need native version
+    UpdateautobridgeMainloopAPI(emu, my_lib->w.bridge, mainloop);
     return my->pa_signal_init(mainloop);
 }
 
@@ -1523,7 +1571,7 @@ EXPORT void* my_pa_context_rttime_new(x64emu_t* emu, void* c, uint64_t usec, voi
 
 EXPORT void my_pa_mainloop_api_once(x64emu_t* emu, void* mainloop, void* cb, void* data)
 {
-    if(mainloop==my_mainloop_ref) mainloop=my_mainloop_orig;    // need native version    
+    UpdateautobridgeMainloopAPI(emu, my_lib->w.bridge, mainloop);
     my->pa_mainloop_api_once(mainloop, find_mainloop_once_Fct(cb), data);
 }