winex11: Add infrastructure for managing the extra data of generic extension events.

This commit is contained in:
Alexandre Julliard 2011-04-12 21:16:15 +02:00
parent e5c3883c92
commit a8575a8b4d
8 changed files with 59 additions and 12 deletions

12
configure vendored
View File

@ -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 <X11/Xlib.h>
#endif
"
if test "x$ac_cv_member_XEvent_xcookie" = x""yes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_XEVENT_XCOOKIE 1
_ACEOF
fi

View File

@ -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 <X11/Xlib.h>
#endif])

View File

@ -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 );

View File

@ -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 */

View File

@ -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();

View File

@ -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)))
{

View File

@ -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)))
{

View File

@ -1118,6 +1118,9 @@
/* Define to 1 if you have the <X11/Xutil.h> 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