about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-03-07 17:31:40 +0100
committerptitSeb <sebastien.chev@gmail.com>2024-03-07 17:31:40 +0100
commit7165ff7b840a7b4de13111b7d17e482d8e6cef9d (patch)
treeb7ab437b5b7736f46d81d31ee72ed40c22f13d7a /src
parent81d906fd3b6ed25a81665d839ceef2d88f4a74f9 (diff)
downloadbox64-7165ff7b840a7b4de13111b7d17e482d8e6cef9d.tar.gz
box64-7165ff7b840a7b4de13111b7d17e482d8e6cef9d.zip
More work on X11 wrapping, allowing gtk to run fully emulated
Diffstat (limited to 'src')
-rw-r--r--src/include/bridge.h2
-rw-r--r--src/tools/bridge.c10
-rw-r--r--src/tools/gtkclass.c2
-rw-r--r--src/wrapped/generated/functions_list.txt6
-rw-r--r--src/wrapped/generated/wrappedcairotypes.h5
-rw-r--r--src/wrapped/generated/wrappedlibx11types.h2
-rw-r--r--src/wrapped/generated/wrapper.c2
-rw-r--r--src/wrapped/generated/wrapper.h1
-rw-r--r--src/wrapped/wrappedcairo.c53
-rw-r--r--src/wrapped/wrappedcairo_private.h6
-rw-r--r--src/wrapped/wrappedgobject2.c6
-rw-r--r--src/wrapped/wrappedlibx11.c258
-rw-r--r--src/wrapped/wrappedlibx11_private.h2
-rw-r--r--src/wrapped/wrappedlibxext_private.h2
-rw-r--r--src/wrapped/wrappedpulse.c4
15 files changed, 322 insertions, 39 deletions
diff --git a/src/include/bridge.h b/src/include/bridge.h
index 1197ac77..a01a5b67 100644
--- a/src/include/bridge.h
+++ b/src/include/bridge.h
@@ -13,7 +13,7 @@ void FreeBridge(bridge_t** bridge);
 uintptr_t AddBridge(bridge_t* bridge, wrapper_t w, void* fnc, int N, const char* name);
 uintptr_t CheckBridged(bridge_t* bridge, void* fnc);
 uintptr_t AddCheckBridge(bridge_t* bridge, wrapper_t w, void* fnc, int N, const char* name);
-uintptr_t AddAutomaticBridge(x64emu_t* emu, bridge_t* bridge, wrapper_t w, void* fnc, int N, const char* name);
+uintptr_t AddAutomaticBridge(bridge_t* bridge, wrapper_t w, void* fnc, int N, const char* name);
 void* GetNativeFnc(uintptr_t fnc);
 void* GetNativeFncOrFnc(uintptr_t fnc);
 
diff --git a/src/tools/bridge.c b/src/tools/bridge.c
index fd53c255..cdc0e307 100644
--- a/src/tools/bridge.c
+++ b/src/tools/bridge.c
@@ -141,10 +141,8 @@ uintptr_t AddCheckBridge(bridge_t* bridge, wrapper_t w, void* fnc, int N, const
     return ret;
 }
 
-uintptr_t AddAutomaticBridge(x64emu_t* emu, bridge_t* bridge, wrapper_t w, void* fnc, int N, const char* name)
+uintptr_t AddAutomaticBridge(bridge_t* bridge, wrapper_t w, void* fnc, int N, const char* name)
 {
-    (void)emu;
-
     if(!fnc)
         return 0;
     uintptr_t ret = CheckBridged(bridge, fnc);
@@ -153,11 +151,7 @@ uintptr_t AddAutomaticBridge(x64emu_t* emu, bridge_t* bridge, wrapper_t w, void*
     if(!hasAlternate(fnc)) {
         printf_log(LOG_DEBUG, "Adding AutomaticBridge for %p to %p\n", fnc, (void*)ret);
         addAlternate(fnc, (void*)ret);
-        #ifdef DYNAREC
-        // now, check if dynablock at native address exist
-        if(box64_dynarec)
-            DBAlternateBlock(emu, (uintptr_t)fnc, ret, 0);  // function wrapping is exclusive to 64bits on box64
-        #endif
+
     }
     return ret;
 }
diff --git a/src/tools/gtkclass.c b/src/tools/gtkclass.c
index d9700a7e..185b7326 100644
--- a/src/tools/gtkclass.c
+++ b/src/tools/gtkclass.c
@@ -206,7 +206,7 @@ static void autobridge_##NAME##_##A(wrapper_t W, void* fct)         \
         return;                                                     \
     Dl_info info;                                                   \
     if(dladdr(fct, &info))                                          \
-        AddAutomaticBridge(thread_get_emu(), my_bridge, W, fct, 0, #NAME "_" #A); \
+        AddAutomaticBridge(my_bridge, W, fct, 0, #NAME "_" #A); \
 }
 
 #define WRAPPER(A, NAME, RET, DEF, FMT, ...)        \
diff --git a/src/wrapped/generated/functions_list.txt b/src/wrapped/generated/functions_list.txt
index 915205ef..ae47954f 100644
--- a/src/wrapped/generated/functions_list.txt
+++ b/src/wrapped/generated/functions_list.txt
@@ -1182,6 +1182,7 @@
 #() pFELpA
 #() pFEpii
 #() pFEpip
+#() pFEpuL
 #() pFEppi
 #() pFEppp
 #() pFEppV
@@ -3099,6 +3100,9 @@ wrappedbz2:
 wrappedcairo:
 - pFp:
   - cairo_xcb_device_get_connection
+- iFpppp:
+  - cairo_set_user_data
+  - cairo_surface_set_user_data
 wrappedcairogobject:
 wrappedcap:
 wrappedcrashhandler:
@@ -4805,6 +4809,8 @@ wrappedlibx11:
   - XESetError
   - XESetEventToWire
   - XESetWireToEvent
+- pFpuL:
+  - _XGetRequest
 - iFpppp:
   - XCheckIfEvent
   - XIfEvent
diff --git a/src/wrapped/generated/wrappedcairotypes.h b/src/wrapped/generated/wrappedcairotypes.h
index 20cdd188..4020471b 100644
--- a/src/wrapped/generated/wrappedcairotypes.h
+++ b/src/wrapped/generated/wrappedcairotypes.h
@@ -12,8 +12,11 @@
 #endif
 
 typedef void* (*pFp_t)(void*);
+typedef int32_t (*iFpppp_t)(void*, void*, void*, void*);
 
 #define SUPER() ADDED_FUNCTIONS() \
-	GO(cairo_xcb_device_get_connection, pFp_t)
+	GO(cairo_xcb_device_get_connection, pFp_t) \
+	GO(cairo_set_user_data, iFpppp_t) \
+	GO(cairo_surface_set_user_data, iFpppp_t)
 
 #endif // __wrappedcairoTYPES_H_
diff --git a/src/wrapped/generated/wrappedlibx11types.h b/src/wrapped/generated/wrappedlibx11types.h
index 127162a1..f712ce53 100644
--- a/src/wrapped/generated/wrappedlibx11types.h
+++ b/src/wrapped/generated/wrappedlibx11types.h
@@ -20,6 +20,7 @@ typedef void* (*pFpp_t)(void*, void*);
 typedef void* (*pFpV_t)(void*, ...);
 typedef int32_t (*iFppp_t)(void*, void*, void*);
 typedef void* (*pFpip_t)(void*, int32_t, void*);
+typedef void* (*pFpuL_t)(void*, uint32_t, uintptr_t);
 typedef int32_t (*iFpppp_t)(void*, void*, void*, void*);
 typedef int32_t (*iFppppp_t)(void*, void*, void*, void*, void*);
 typedef int32_t (*iFpppppp_t)(void*, void*, void*, void*, void*, void*);
@@ -47,6 +48,7 @@ typedef void* (*pFppiiuuuipii_t)(void*, void*, int32_t, int32_t, uint32_t, uint3
 	GO(XESetError, pFpip_t) \
 	GO(XESetEventToWire, pFpip_t) \
 	GO(XESetWireToEvent, pFpip_t) \
+	GO(_XGetRequest, pFpuL_t) \
 	GO(XCheckIfEvent, iFpppp_t) \
 	GO(XIfEvent, iFpppp_t) \
 	GO(XPeekIfEvent, iFpppp_t) \
diff --git a/src/wrapped/generated/wrapper.c b/src/wrapped/generated/wrapper.c
index 573b2a47..cec390a4 100644
--- a/src/wrapped/generated/wrapper.c
+++ b/src/wrapped/generated/wrapper.c
@@ -1220,6 +1220,7 @@ typedef void* (*pFELpV_t)(x64emu_t*, uintptr_t, void*, void*);
 typedef void* (*pFELpA_t)(x64emu_t*, uintptr_t, void*, void*);
 typedef void* (*pFEpii_t)(x64emu_t*, void*, int32_t, int32_t);
 typedef void* (*pFEpip_t)(x64emu_t*, void*, int32_t, void*);
+typedef void* (*pFEpuL_t)(x64emu_t*, void*, uint32_t, uintptr_t);
 typedef void* (*pFEppi_t)(x64emu_t*, void*, void*, int32_t);
 typedef void* (*pFEppp_t)(x64emu_t*, void*, void*, void*);
 typedef void* (*pFEppV_t)(x64emu_t*, void*, void*, void*);
@@ -4297,6 +4298,7 @@ void pFELpV(x64emu_t *emu, uintptr_t fcn) { pFELpV_t fn = (pFELpV_t)fcn; R_RAX=(
 void pFELpA(x64emu_t *emu, uintptr_t fcn) { pFELpA_t fn = (pFELpA_t)fcn; R_RAX=(uintptr_t)fn(emu, (uintptr_t)R_RDI, (void*)R_RSI, (void*)R_RDX); }
 void pFEpii(x64emu_t *emu, uintptr_t fcn) { pFEpii_t fn = (pFEpii_t)fcn; R_RAX=(uintptr_t)fn(emu, (void*)R_RDI, (int32_t)R_RSI, (int32_t)R_RDX); }
 void pFEpip(x64emu_t *emu, uintptr_t fcn) { pFEpip_t fn = (pFEpip_t)fcn; R_RAX=(uintptr_t)fn(emu, (void*)R_RDI, (int32_t)R_RSI, (void*)R_RDX); }
+void pFEpuL(x64emu_t *emu, uintptr_t fcn) { pFEpuL_t fn = (pFEpuL_t)fcn; R_RAX=(uintptr_t)fn(emu, (void*)R_RDI, (uint32_t)R_RSI, (uintptr_t)R_RDX); }
 void pFEppi(x64emu_t *emu, uintptr_t fcn) { pFEppi_t fn = (pFEppi_t)fcn; R_RAX=(uintptr_t)fn(emu, (void*)R_RDI, (void*)R_RSI, (int32_t)R_RDX); }
 void pFEppp(x64emu_t *emu, uintptr_t fcn) { pFEppp_t fn = (pFEppp_t)fcn; R_RAX=(uintptr_t)fn(emu, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX); }
 void pFEppV(x64emu_t *emu, uintptr_t fcn) { pFEppV_t fn = (pFEppV_t)fcn; R_RAX=(uintptr_t)fn(emu, (void*)R_RDI, (void*)R_RSI, (void*)(R_RSP + 8)); }
diff --git a/src/wrapped/generated/wrapper.h b/src/wrapped/generated/wrapper.h
index 255f6563..39a36aab 100644
--- a/src/wrapped/generated/wrapper.h
+++ b/src/wrapped/generated/wrapper.h
@@ -1220,6 +1220,7 @@ void pFELpV(x64emu_t *emu, uintptr_t fnc);
 void pFELpA(x64emu_t *emu, uintptr_t fnc);
 void pFEpii(x64emu_t *emu, uintptr_t fnc);
 void pFEpip(x64emu_t *emu, uintptr_t fnc);
+void pFEpuL(x64emu_t *emu, uintptr_t fnc);
 void pFEppi(x64emu_t *emu, uintptr_t fnc);
 void pFEppp(x64emu_t *emu, uintptr_t fnc);
 void pFEppV(x64emu_t *emu, uintptr_t fnc);
diff --git a/src/wrapped/wrappedcairo.c b/src/wrapped/wrappedcairo.c
index f2d1e72c..77c4fc2e 100644
--- a/src/wrapped/wrappedcairo.c
+++ b/src/wrapped/wrappedcairo.c
@@ -25,10 +25,59 @@ const char* cairoName = "libcairo.so.2";
 
 #include "wrappercallback.h"
 
-#include "wrappedlib_init.h"
+#define SUPER() \
+GO(0)   \
+GO(1)   \
+GO(2)   \
+GO(3)   \
+GO(4)
 
+// destroy ...
+#define GO(A)   \
+static uintptr_t my_destroy_fct_##A = 0;        \
+static void my_destroy_##A(void* a)             \
+{                                               \
+    RunFunctionFmt(my_destroy_fct_##A, "p", a); \
+}
+SUPER()
+#undef GO
+static void* find_destroy_Fct(void* fct)
+{
+    if(!fct) return fct;
+    if(GetNativeFnc((uintptr_t)fct))  return GetNativeFnc((uintptr_t)fct);
+    #define GO(A) if(my_destroy_fct_##A == (uintptr_t)fct) return my_destroy_##A;
+    SUPER()
+    #undef GO
+    #define GO(A) if(my_destroy_fct_##A == 0) {my_destroy_fct_##A = (uintptr_t)fct; return my_destroy_##A; }
+    SUPER()
+    #undef GO
+    printf_log(LOG_NONE, "Warning, no more slot for cairo destroy callback\n");
+    return NULL;
+}
+static void* reverse_destroy_Fct(void* fct)
+{
+    if(!fct) return fct;
+    if(CheckBridged(my_lib->w.bridge, fct))
+        return (void*)CheckBridged(my_lib->w.bridge, fct);
+    #define GO(A) if(my_destroy_##A == fct) return (void*)my_destroy_fct_##A;
+    SUPER()
+    #undef GO
+    return (void*)AddBridge(my_lib->w.bridge, pFpii, fct, 0, NULL);
+}
 
 EXPORT void* my_cairo_xcb_device_get_connection(x64emu_t* emu, void* a)
 {
     return add_xcb_connection(my->cairo_xcb_device_get_connection(a));
-}
\ No newline at end of file
+}
+
+EXPORT int my_cairo_surface_set_user_data(x64emu_t* emu, void* surf, void* key, void* data, void* d)
+{
+    return my->cairo_surface_set_user_data(surf, key, data, find_destroy_Fct(d));
+}
+
+EXPORT int my_cairo_set_user_data(x64emu_t* emu, void* cr, void* key, void* data, void* d)
+{
+    return my->cairo_set_user_data(cr, key, data, find_destroy_Fct(d));
+}
+
+#include "wrappedlib_init.h"
\ No newline at end of file
diff --git a/src/wrapped/wrappedcairo_private.h b/src/wrapped/wrappedcairo_private.h
index f094ba48..d069a240 100644
--- a/src/wrapped/wrappedcairo_private.h
+++ b/src/wrapped/wrappedcairo_private.h
@@ -286,7 +286,7 @@ GO(cairo_set_source_rgb, vFpddd)
 GO(cairo_set_source_rgba, vFpdddd)
 GO(cairo_set_source_surface, vFppdd)
 GO(cairo_set_tolerance, vFpd)
-//GOM(cairo_set_user_data, iFEpppp)
+GOM(cairo_set_user_data, iFEpppp)
 GO(cairo_show_glyphs, vFppi)
 GO(cairo_show_page, vFp)
 GO(cairo_show_text, vFpp)
@@ -332,7 +332,7 @@ GO(cairo_surface_set_device_offset, vFpdd)
 GO(cairo_surface_set_device_scale, vFpdd)
 GO(cairo_surface_set_fallback_resolution, vFpdd)
 //GOM(cairo_surface_set_mime_data, iFEpppLpp)
-//GOM(cairo_surface_set_user_data, iFEpppp)
+GOM(cairo_surface_set_user_data, iFEpppp)
 GO(cairo_surface_show_page, vFp)
 GO(cairo_surface_status, uFp)
 GO(cairo_surface_supports_mime_type, iFpp)
@@ -380,7 +380,7 @@ GO(cairo_xcb_surface_set_size, vFpii)
 GO(cairo_xlib_device_debug_cap_xrender_version, vFpii)
 GO(cairo_xlib_device_debug_get_precision, iFp)
 GO(cairo_xlib_device_debug_set_precision, vFpi)
-//GO(cairo_xlib_surface_create, 
+GO(cairo_xlib_surface_create, pFpppii)
 GO(cairo_xlib_surface_create_for_bitmap, pFpLpii)
 GO(cairo_xlib_surface_create_with_xrender_format, pFpLppii)
 //GO(cairo_xlib_surface_get_depth, 
diff --git a/src/wrapped/wrappedgobject2.c b/src/wrapped/wrappedgobject2.c
index 95a731d6..a29588fd 100644
--- a/src/wrapped/wrappedgobject2.c
+++ b/src/wrapped/wrappedgobject2.c
@@ -138,7 +138,7 @@ static void signal_delete(my_signal_t* sig, void* b)
 
 static void addGObject2Alternate(library_t* lib)
 {
-    #define GO(A, W) AddAutomaticBridge(thread_get_emu(), lib->w.bridge, W, dlsym(lib->w.lib, #A), 0, #A)
+    #define GO(A, W) AddAutomaticBridge(lib->w.bridge, W, dlsym(lib->w.lib, #A), 0, #A)
     GO(g_cclosure_marshal_VOID__VOID,               vFppuppp);
     GO(g_cclosure_marshal_VOID__BOOLEAN,            vFppuppp);
     GO(g_cclosure_marshal_VOID__UCHAR,              vFppuppp);
@@ -184,7 +184,7 @@ static void addGObject2Alternate(library_t* lib)
     GO(g_cclosure_marshal_BOOLEAN__FLAGSv,          vFpppppip);
     GO(g_cclosure_marshal_BOOLEAN__BOXED_BOXEDv,    vFpppppip);
     #undef GO
-    #define GO(A, W) AddAutomaticBridge(thread_get_emu(), lib->w.bridge, W, A, 0, #A)
+    #define GO(A, W) AddAutomaticBridge(lib->w.bridge, W, A, 0, #A)
     GO(signal_cb, iFpppp);
     GO(signal_cb_swapped, iFpppp);
     GO(signal_cb_5, iFppppp);
@@ -359,7 +359,7 @@ static void* findMarshalFct(void* fct)
     #define GO(A) if(my_marshal_fct_##A == (uintptr_t)fct) return my_marshal_##A;
     SUPER()
     #undef GO
-    #define GO(A) if(my_marshal_fct_##A == 0) {AddAutomaticBridge(thread_get_emu(), my_lib->w.bridge, vFppuppp, my_marshal_##A, 0, #A); my_marshal_fct_##A = (uintptr_t)fct; return my_marshal_##A; }
+    #define GO(A) if(my_marshal_fct_##A == 0) {AddAutomaticBridge(my_lib->w.bridge, vFppuppp, my_marshal_##A, 0, #A); my_marshal_fct_##A = (uintptr_t)fct; return my_marshal_##A; }
     SUPER()
     #undef GO
     printf_log(LOG_NONE, "Warning, no more slot for gobject Closure Marshal callback\n");
diff --git a/src/wrapped/wrappedlibx11.c b/src/wrapped/wrappedlibx11.c
index 90f6e662..9f3880e7 100644
--- a/src/wrapped/wrappedlibx11.c
+++ b/src/wrapped/wrappedlibx11.c
@@ -491,6 +491,223 @@ static void* findXUnlockDisplayFct(void* fct)
     printf_log(LOG_NONE, "Warning, no more slot for libX11 XUnlockDisplay callback\n");
     return NULL;
 }
+// XImage function wrappers
+// create_image
+#define GO(A)   \
+static uintptr_t my_create_image_fct_##A = 0;                                                                                   \
+static void* my_create_image_##A(void* a, void* b, uint32_t c, int d, int e, void* f, uint32_t g, uint32_t h, int i, int j)     \
+{                                                                                                                               \
+    return (void*)RunFunctionFmt(my_create_image_fct_##A, "ppuiipuuii", a, b, c, d, e, f, g, h, i, j);                          \
+}
+SUPER()
+#undef GO
+static void* find_create_image_Fct(void* fct)
+{
+    if(!fct) return fct;
+    if(GetNativeFnc((uintptr_t)fct))  return GetNativeFnc((uintptr_t)fct);
+    #define GO(A) if(my_create_image_fct_##A == (uintptr_t)fct) return my_create_image_##A;
+    SUPER()
+    #undef GO
+    #define GO(A) if(my_create_image_fct_##A == 0) {my_create_image_fct_##A = (uintptr_t)fct; return my_create_image_##A; }
+    SUPER()
+    #undef GO
+    printf_log(LOG_NONE, "Warning, no more slot for libX11 create_image callback\n");
+    return NULL;
+}
+static void* reverse_create_image_Fct(library_t* lib, void* fct)
+{
+    if(!fct) return fct;
+    if(CheckBridged(lib->w.bridge, fct))
+        return (void*)CheckBridged(lib->w.bridge, fct);
+    #define GO(A) if(my_create_image_##A == fct) return (void*)my_create_image_fct_##A;
+    SUPER()
+    #undef GO
+    return (void*)AddAutomaticBridge(lib->w.bridge, pFppuiipuuii, fct, 0, NULL);
+}
+// destroy_image
+#define GO(A)   \
+static uintptr_t my_destroy_image_fct_##A = 0;                      \
+static int my_destroy_image_##A(void* a)                            \
+{                                                                   \
+    return (int)RunFunctionFmt(my_destroy_image_fct_##A, "p", a);   \
+}
+SUPER()
+#undef GO
+static void* find_destroy_image_Fct(void* fct)
+{
+    if(!fct) return fct;
+    if(GetNativeFnc((uintptr_t)fct))  return GetNativeFnc((uintptr_t)fct);
+    #define GO(A) if(my_destroy_image_fct_##A == (uintptr_t)fct) return my_destroy_image_##A;
+    SUPER()
+    #undef GO
+    #define GO(A) if(my_destroy_image_fct_##A == 0) {my_destroy_image_fct_##A = (uintptr_t)fct; return my_destroy_image_##A; }
+    SUPER()
+    #undef GO
+    printf_log(LOG_NONE, "Warning, no more slot for libX11 destroy_image callback\n");
+    return NULL;
+}
+static void* reverse_destroy_image_Fct(library_t* lib, void* fct)
+{
+    if(!fct) return fct;
+    if(CheckBridged(lib->w.bridge, fct))
+        return (void*)CheckBridged(lib->w.bridge, fct);
+    #define GO(A) if(my_destroy_image_##A == fct) return (void*)my_destroy_image_fct_##A;
+    SUPER()
+    #undef GO
+    return (void*)AddAutomaticBridge(lib->w.bridge, iFp, fct, 0, NULL);
+}
+// get_pixel
+#define GO(A)   \
+static uintptr_t my_get_pixel_fct_##A = 0;                                      \
+static unsigned long my_get_pixel_##A(void* a, int b, int c)                    \
+{                                                                               \
+    return (unsigned long)RunFunctionFmt(my_get_pixel_fct_##A, "pii", a, b, c); \
+}
+SUPER()
+#undef GO
+static void* find_get_pixel_Fct(void* fct)
+{
+    if(!fct) return fct;
+    if(GetNativeFnc((uintptr_t)fct))  return GetNativeFnc((uintptr_t)fct);
+    #define GO(A) if(my_get_pixel_fct_##A == (uintptr_t)fct) return my_get_pixel_##A;
+    SUPER()
+    #undef GO
+    #define GO(A) if(my_get_pixel_fct_##A == 0) {my_get_pixel_fct_##A = (uintptr_t)fct; return my_get_pixel_##A; }
+    SUPER()
+    #undef GO
+    printf_log(LOG_NONE, "Warning, no more slot for libX11 get_pixel callback\n");
+    return NULL;
+}
+static void* reverse_get_pixel_Fct(library_t* lib, void* fct)
+{
+    if(!fct) return fct;
+    if(CheckBridged(lib->w.bridge, fct))
+        return (void*)CheckBridged(lib->w.bridge, fct);
+    #define GO(A) if(my_get_pixel_##A == fct) return (void*)my_get_pixel_fct_##A;
+    SUPER()
+    #undef GO
+    return (void*)AddAutomaticBridge(lib->w.bridge, LFpii, fct, 0, NULL);
+}
+// put_pixel
+#define GO(A)   \
+static uintptr_t my_put_pixel_fct_##A = 0;                                  \
+static int my_put_pixel_##A(void* a, int b, int c,unsigned long d)          \
+{                                                                           \
+    return (int)RunFunctionFmt(my_put_pixel_fct_##A, "piiL", a, b, c, d);   \
+}
+SUPER()
+#undef GO
+static void* find_put_pixel_Fct(void* fct)
+{
+    if(!fct) return fct;
+    if(GetNativeFnc((uintptr_t)fct))  return GetNativeFnc((uintptr_t)fct);
+    #define GO(A) if(my_put_pixel_fct_##A == (uintptr_t)fct) return my_put_pixel_##A;
+    SUPER()
+    #undef GO
+    #define GO(A) if(my_put_pixel_fct_##A == 0) {my_put_pixel_fct_##A = (uintptr_t)fct; return my_put_pixel_##A; }
+    SUPER()
+    #undef GO
+    printf_log(LOG_NONE, "Warning, no more slot for libX11 put_pixel callback\n");
+    return NULL;
+}
+static void* reverse_put_pixel_Fct(library_t* lib, void* fct)
+{
+    if(!fct) return fct;
+    if(CheckBridged(lib->w.bridge, fct))
+        return (void*)CheckBridged(lib->w.bridge, fct);
+    #define GO(A) if(my_put_pixel_##A == fct) return (void*)my_put_pixel_fct_##A;
+    SUPER()
+    #undef GO
+    return (void*)AddAutomaticBridge(lib->w.bridge, iFpiiL, fct, 0, NULL);
+}
+// sub_image
+#define GO(A)   \
+static uintptr_t my_sub_image_fct_##A = 0;                                      \
+static void* my_sub_image_##A(void* a, int b, int c, uint32_t d, uint32_t e)    \
+{                                                                               \
+    return (void*)RunFunctionFmt(my_sub_image_fct_##A, "piiuu", a, b, c, d, e); \
+}
+SUPER()
+#undef GO
+static void* find_sub_image_Fct(void* fct)
+{
+    if(!fct) return fct;
+    if(GetNativeFnc((uintptr_t)fct))  return GetNativeFnc((uintptr_t)fct);
+    #define GO(A) if(my_sub_image_fct_##A == (uintptr_t)fct) return my_sub_image_##A;
+    SUPER()
+    #undef GO
+    #define GO(A) if(my_sub_image_fct_##A == 0) {my_sub_image_fct_##A = (uintptr_t)fct; return my_sub_image_##A; }
+    SUPER()
+    #undef GO
+    printf_log(LOG_NONE, "Warning, no more slot for libX11 sub_image callback\n");
+    return NULL;
+}
+static void* reverse_sub_image_Fct(library_t* lib, void* fct)
+{
+    if(!fct) return fct;
+    if(CheckBridged(lib->w.bridge, fct))
+        return (void*)CheckBridged(lib->w.bridge, fct);
+    #define GO(A) if(my_sub_image_##A == fct) return (void*)my_sub_image_fct_##A;
+    SUPER()
+    #undef GO
+    return (void*)AddAutomaticBridge(lib->w.bridge, pFpiiuu, fct, 0, NULL);
+}
+// add_pixel
+#define GO(A)   \
+static uintptr_t my_add_pixel_fct_##A = 0;                          \
+static int my_add_pixel_##A(void* a, long b)                        \
+{                                                                   \
+    return (int)RunFunctionFmt(my_add_pixel_fct_##A, "pl", a, b);   \
+}
+SUPER()
+#undef GO
+static void* find_add_pixel_Fct(void* fct)
+{
+    if(!fct) return fct;
+    if(GetNativeFnc((uintptr_t)fct))  return GetNativeFnc((uintptr_t)fct);
+    #define GO(A) if(my_add_pixel_fct_##A == (uintptr_t)fct) return my_add_pixel_##A;
+    SUPER()
+    #undef GO
+    #define GO(A) if(my_add_pixel_fct_##A == 0) {my_add_pixel_fct_##A = (uintptr_t)fct; return my_add_pixel_##A; }
+    SUPER()
+    #undef GO
+    printf_log(LOG_NONE, "Warning, no more slot for libX11 add_pixel callback\n");
+    return NULL;
+}
+static void* reverse_add_pixel_Fct(library_t* lib, void* fct)
+{
+    if(!fct) return fct;
+    if(CheckBridged(lib->w.bridge, fct))
+        return (void*)CheckBridged(lib->w.bridge, fct);
+    #define GO(A) if(my_add_pixel_##A == fct) return (void*)my_add_pixel_fct_##A;
+    SUPER()
+    #undef GO
+    return (void*)AddAutomaticBridge(lib->w.bridge, iFpl, fct, 0, NULL);
+}
+// end of XImage functions callbacks
+// async_handler
+#define GO(A)   \
+static uintptr_t my_async_handler_fct_##A = 0;                                      \
+static int my_async_handler_##A(void* a, void* b, void* c, int d, void* e)          \
+{                                                                                   \
+    return (int)RunFunctionFmt(my_async_handler_fct_##A, "pppip", a, b, c, d, e);   \
+}
+SUPER()
+#undef GO
+static void* find_async_handler_Fct(void* fct)
+{
+    if(!fct) return fct;
+    if(GetNativeFnc((uintptr_t)fct))  return GetNativeFnc((uintptr_t)fct);
+    #define GO(A) if(my_async_handler_fct_##A == (uintptr_t)fct) return my_async_handler_##A;
+    SUPER()
+    #undef GO
+    #define GO(A) if(my_async_handler_fct_##A == 0) {my_async_handler_fct_##A = (uintptr_t)fct; return my_async_handler_##A; }
+    SUPER()
+    #undef GO
+    printf_log(LOG_NONE, "Warning, no more slot for libX11 async_handler callback\n");
+    return NULL;
+}
+
 #undef SUPER
 
 void* my_XCreateImage(x64emu_t* emu, void* disp, void* vis, uint32_t depth, int32_t fmt, int32_t off
@@ -1045,17 +1262,13 @@ void BridgeImageFunc(x64emu_t *emu, XImage *img)
     bridge_t* system = emu->context->system;
 
     #define GO(A, W) \
-    fnc = CheckBridged(system, img->f.A); \
-    if(!fnc) fnc = AddAutomaticBridge(emu, system, W, img->f.A, 0, #A); \
-    img->f.A = (W##_t)fnc;
-
-    uintptr_t fnc;
+    img->f.A = (W##_t)reverse_##A##_Fct(my_lib, img->f.A);
 
     GO(create_image, pFppuiipuuii)
     GO(destroy_image, iFp)
     GO(get_pixel, LFpii)
     GO(put_pixel, iFpiiL)
-    GO(sub_image, sub_image_wrapper)
+    GO(sub_image, pFpiiuu)
     GO(add_pixel, iFpl)
     #undef GO
 }
@@ -1063,18 +1276,14 @@ void BridgeImageFunc(x64emu_t *emu, XImage *img)
 void UnbridgeImageFunc(x64emu_t *emu, XImage *img)
 {
     (void)emu;
-    #define GO(A, W) \
-    fnc = GetNativeFnc((uintptr_t)img->f.A); \
-    if(fnc) \
-        img->f.A = (W##_t)fnc;
-
-    void* fnc;
+    #define GO(A, W)                            \
+    img->f.A = (W##_t)find_##A##_Fct(img->f.A);
 
     GO(create_image, pFppuiipuuii)
     GO(destroy_image, iFp)
     GO(get_pixel, LFpii)
     GO(put_pixel, iFpiiL)
-    GO(sub_image, sub_image_wrapper)
+    GO(sub_image, pFpiiuu)
     GO(add_pixel, iFpl)
     #undef GO
 }
@@ -1140,7 +1349,7 @@ EXPORT void* my_XGetSubImage(x64emu_t* emu, void* disp, void* drawable
 
     UnbridgeImageFunc(emu, (XImage*)image);
     XImage *img = my->XGetSubImage(disp, drawable, x, y, w, h, plane, fmt, image, dst_x, dst_y);
-    if(img)
+    if(img && img!=image)
         BridgeImageFunc(emu, img);
 
     BridgeImageFunc(emu, (XImage*)image);
@@ -1397,12 +1606,12 @@ EXPORT void* my_XOpenDisplay(x64emu_t* emu, void* d)
     #define GO(A, W)\
     if(dpy->A)      \
         if(!CheckBridged(system, dpy->A)) \
-            AddAutomaticBridge(emu, system, W, dpy->A, 0, #A); \
+            AddAutomaticBridge(system, W, dpy->A, 0, #A); \
 
     #define GO2(A, B, W) \
     if(dpy->A && dpy->A->B)  \
         if(!CheckBridged(system, dpy->A->B)) \
-            AddAutomaticBridge(emu, system, W, dpy->A->B, 0, #B "_" #A); \
+            AddAutomaticBridge(system, W, dpy->A->B, 0, #B "_" #A); \
 
 
     GO2(free_funcs, atoms, vFp)
@@ -1438,6 +1647,23 @@ EXPORT void* my_XOpenDisplay(x64emu_t* emu, void* d)
     return ret;
 }
 
+EXPORT void* my__XGetRequest(x64emu_t* emu, my_XDisplay_t* dpy, int type, size_t len)
+{
+    // check if asynchandler needs updated wrapping
+    struct my_XInternalAsync * p = dpy->async_handlers;
+    while(p) {
+        if(GetNativeFnc((uintptr_t)p->handler)!=p->handler) {
+            // needs wrapping and autobridge!
+            void* new_handler = find_async_handler_Fct(p->handler);
+            AddAutomaticBridge(my_lib->w.bridge, iFpppip, new_handler, 0, "async_handler");
+            p->handler = new_handler;
+        }
+        p = p->next;
+    }
+
+    return my->_XGetRequest(dpy, type, len);
+}
+
 #define CUSTOM_INIT                 \
     if(box64_x11threads) my->XInitThreads();
 
diff --git a/src/wrapped/wrappedlibx11_private.h b/src/wrapped/wrappedlibx11_private.h
index 7b9c0434..a382161f 100644
--- a/src/wrapped/wrappedlibx11_private.h
+++ b/src/wrapped/wrappedlibx11_private.h
@@ -409,7 +409,7 @@ GO(XGetOMValues, pFp)
 GO(dummy_XGetPixel, LFpii)     // for the wrapper
 GO(XGetPointerControl, iFpppp)
 GO(XGetPointerMapping, iFppi)
-GO(_XGetRequest, pFpuL)
+GOM(_XGetRequest, pFEpuL)
 GO(XGetRGBColormaps, iFpLppL)
 //GO(_XGetScanlinePad, 
 GO(XGetScreenSaver, iFppppp)
diff --git a/src/wrapped/wrappedlibxext_private.h b/src/wrapped/wrappedlibxext_private.h
index 2e2ac8ea..7d981068 100644
--- a/src/wrapped/wrappedlibxext_private.h
+++ b/src/wrapped/wrappedlibxext_private.h
@@ -121,7 +121,7 @@ GO(XSyncSetPriority, iFpui)
 //GO(XSyncValueHigh32, 
 //GO(XSyncValueIsNegative, 
 //GO(XSyncValueIsPositive, 
-//GO(XSyncValueIsZero, 
+GO(XSyncValueIsZero, iFp)
 //GO(XSyncValueLessOrEqual, 
 //GO(XSyncValueLessThan, 
 //GO(XSyncValueLow32, 
diff --git a/src/wrapped/wrappedpulse.c b/src/wrapped/wrappedpulse.c
index a6090c38..cbdb538f 100644
--- a/src/wrapped/wrappedpulse.c
+++ b/src/wrapped/wrappedpulse.c
@@ -1052,7 +1052,7 @@ static void UpdateautobridgeMainloopAPI(x64emu_t* emu, bridge_t* bridge, my_pa_m
     if(!api) {
         return;
     }
-    #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);}
+    #define GO(A, W) if(api->A!=my_mainloop_api.A) {api->A=find_##A##_Fct(api->A); AddAutomaticBridge(bridge, W, api->A, 0, NULL);}
     GO(io_new, pFpiipp);
     GO(io_enable, vFpi);
     GO(io_free, vFp);
@@ -1076,7 +1076,7 @@ static void autobridgeMainloopAPI(x64emu_t* emu, bridge_t* bridge, my_pa_mainloo
     if(!api) {
         return;
     }
-    #define GO(A, W) if(api->A) AddAutomaticBridge(emu, bridge, W, api->A, 0, NULL)
+    #define GO(A, W) if(api->A) AddAutomaticBridge(bridge, W, api->A, 0, NULL)
     GO(io_new, pFpiipp);
     GO(io_enable, vFpi);
     GO(io_free, vFp);