From a8575a8b4dc6f3678654dd3b72ece6d6f58632fa Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 12 Apr 2011 21:16:15 +0200 Subject: [PATCH] winex11: Add infrastructure for managing the extra data of generic extension events. --- configure | 12 ++++++++++++ configure.ac | 2 +- dlls/winex11.drv/event.c | 32 ++++++++++++++++++++++++++------ dlls/winex11.drv/x11drv.h | 3 +++ dlls/winex11.drv/x11drv_main.c | 13 +++++++++++++ dlls/winex11.drv/xrandr.c | 4 +--- dlls/winex11.drv/xrender.c | 2 -- include/config.h.in | 3 +++ 8 files changed, 59 insertions(+), 12 deletions(-) diff --git a/configure b/configure index 76ecd552d6e..8e8d044e8b0 100755 --- a/configure +++ b/configure @@ -8732,6 +8732,18 @@ cat >>confdefs.h <<_ACEOF _ACEOF +fi +ac_fn_c_check_member "$LINENO" "XEvent" "xcookie" "ac_cv_member_XEvent_xcookie" "#ifdef HAVE_X11_XLIB_H +#include +#endif +" +if test "x$ac_cv_member_XEvent_xcookie" = x""yes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_XEVENT_XCOOKIE 1 +_ACEOF + + fi diff --git a/configure.ac b/configure.ac index 21c8d8552f4..e82d193455a 100644 --- a/configure.ac +++ b/configure.ac @@ -1045,7 +1045,7 @@ then [libxcomposite ${notice_platform}development files not found, Xcomposite won't be supported.]) dnl *** Check for XICCallback struct - AC_CHECK_MEMBERS([XICCallback.callback],,, + AC_CHECK_MEMBERS([XICCallback.callback, XEvent.xcookie],,, [#ifdef HAVE_X11_XLIB_H #include #endif]) diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index 474e2881106..a05e9066132 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -86,6 +86,9 @@ extern BOOL ximInComposeMode; #define XEMBED_UNREGISTER_ACCELERATOR 13 #define XEMBED_ACTIVATE_ACCELERATOR 14 +Bool (*pXGetEventData)( Display *display, XEvent /*XGenericEventCookie*/ *event ) = NULL; +void (*pXFreeEventData)( Display *display, XEvent /*XGenericEventCookie*/ *event ) = NULL; + /* Event handlers */ static void X11DRV_FocusIn( HWND hwnd, XEvent *event ); static void X11DRV_FocusOut( HWND hwnd, XEvent *event ); @@ -140,8 +143,6 @@ static x11drv_event_handler handlers[MAX_EVENT_HANDLERS] = NULL /* 35 GenericEvent */ }; - - static const char * event_names[MAX_EVENT_HANDLERS] = { NULL, NULL, "KeyPress", "KeyRelease", "ButtonPress", "ButtonRelease", @@ -152,13 +153,29 @@ static const char * event_names[MAX_EVENT_HANDLERS] = "CirculateNotify", "CirculateRequest", "PropertyNotify", "SelectionClear", "SelectionRequest", "SelectionNotify", "ColormapNotify", "ClientMessage", "MappingNotify", "GenericEvent" }; + /* return the name of an X event */ static const char *dbgstr_event( int type ) { - if (type < MAX_EVENT_HANDLERS && event_names[type]) return event_names[type - KeyPress]; + if (type < MAX_EVENT_HANDLERS && event_names[type]) return event_names[type]; return wine_dbg_sprintf( "Unknown event %d", type ); } +static inline void get_event_data( XEvent *event ) +{ +#if defined(GenericEvent) && defined(HAVE_XEVENT_XCOOKIE) + if (event->xany.type != GenericEvent) return; + if (!pXGetEventData || !pXGetEventData( event->xany.display, event )) event->xcookie.data = NULL; +#endif +} + +static inline void free_event_data( XEvent *event ) +{ +#if defined(GenericEvent) && defined(HAVE_XEVENT_XCOOKIE) + if (event->xany.type != GenericEvent) return; + if (event->xcookie.data) pXFreeEventData( event->xany.display, event ); +#endif +} /*********************************************************************** * X11DRV_register_event_handler @@ -333,22 +350,25 @@ static int process_events( Display *display, Bool (*filter)(Display*, XEvent*,XP else continue; /* filtered, ignore it */ } + get_event_data( &event ); if (prev_event.type) action = merge_events( &prev_event, &event ); switch( action ) { - case MERGE_DISCARD: /* discard prev, keep new */ - prev_event = event; - break; case MERGE_HANDLE: /* handle prev, keep new */ call_event_handler( display, &prev_event ); + /* fall through */ + case MERGE_DISCARD: /* discard prev, keep new */ + free_event_data( &prev_event ); prev_event = event; break; case MERGE_KEEP: /* handle new, keep prev for future merging */ call_event_handler( display, &event ); + free_event_data( &event ); break; } } if (prev_event.type) call_event_handler( display, &prev_event ); + free_event_data( &prev_event ); XFlush( gdi_display ); wine_tsx11_unlock(); if (count) TRACE( "processed %d events\n", count ); diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index a06de4fae54..5f6c5cf8c80 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -729,6 +729,9 @@ extern void X11DRV_SelectionRequest( HWND hWnd, XEvent *event ); extern void X11DRV_SelectionClear( HWND hWnd, XEvent *event ); extern void X11DRV_MappingNotify( HWND hWnd, XEvent *event ); +extern Bool (*pXGetEventData)( Display *display, XEvent /*XGenericEventCookie*/ *event ); +extern void (*pXFreeEventData)( Display *display, XEvent /*XGenericEventCookie*/ *event ); + extern DWORD EVENT_x11_time_to_win32_time(Time time); /* X11 driver private messages, must be in the range 0x80001000..0x80001fff */ diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c index 473b61f3d67..9ac20c35bd4 100644 --- a/dlls/winex11.drv/x11drv_main.c +++ b/dlls/winex11.drv/x11drv_main.c @@ -529,7 +529,20 @@ sym_not_found: */ static BOOL process_attach(void) { + char error[1024]; Display *display; + void *libx11 = wine_dlopen( SONAME_LIBX11, RTLD_NOW|RTLD_GLOBAL, error, sizeof(error) ); + + if (!libx11) + { + ERR( "failed to load %s: %s\n", SONAME_LIBX11, error ); + return FALSE; + } + pXGetEventData = wine_dlsym( libx11, "XGetEventData", NULL, 0 ); + pXFreeEventData = wine_dlsym( libx11, "XFreeEventData", NULL, 0 ); +#ifdef SONAME_LIBXEXT + wine_dlopen( SONAME_LIBXEXT, RTLD_NOW|RTLD_GLOBAL, NULL, 0 ); +#endif setup_options(); diff --git a/dlls/winex11.drv/xrandr.c b/dlls/winex11.drv/xrandr.c index c313bab8d00..0aea4631ca3 100644 --- a/dlls/winex11.drv/xrandr.c +++ b/dlls/winex11.drv/xrandr.c @@ -71,9 +71,7 @@ static int load_xrandr(void) { int r = 0; - if (wine_dlopen(SONAME_LIBX11, RTLD_NOW|RTLD_GLOBAL, NULL, 0) && - wine_dlopen(SONAME_LIBXEXT, RTLD_NOW|RTLD_GLOBAL, NULL, 0) && - wine_dlopen(SONAME_LIBXRENDER, RTLD_NOW|RTLD_GLOBAL, NULL, 0) && + if (wine_dlopen(SONAME_LIBXRENDER, RTLD_NOW|RTLD_GLOBAL, NULL, 0) && (xrandr_handle = wine_dlopen(SONAME_LIBXRANDR, RTLD_NOW, NULL, 0))) { diff --git a/dlls/winex11.drv/xrender.c b/dlls/winex11.drv/xrender.c index 33e420aac32..52e7f250b02 100644 --- a/dlls/winex11.drv/xrender.c +++ b/dlls/winex11.drv/xrender.c @@ -346,8 +346,6 @@ void X11DRV_XRender_Init(void) int event_base, i; if (client_side_with_render && - wine_dlopen(SONAME_LIBX11, RTLD_NOW|RTLD_GLOBAL, NULL, 0) && - wine_dlopen(SONAME_LIBXEXT, RTLD_NOW|RTLD_GLOBAL, NULL, 0) && (xrender_handle = wine_dlopen(SONAME_LIBXRENDER, RTLD_NOW, NULL, 0))) { diff --git a/include/config.h.in b/include/config.h.in index b7460cc0008..19a6b48ee47 100644 --- a/include/config.h.in +++ b/include/config.h.in @@ -1118,6 +1118,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_X11_XUTIL_H +/* Define to 1 if `xcookie' is a member of `XEvent'. */ +#undef HAVE_XEVENT_XCOOKIE + /* Define to 1 if `callback' is a member of `XICCallback'. */ #undef HAVE_XICCALLBACK_CALLBACK