Alexandre Julliard : winex11: Add support for merging redundant events, and use it for ConfigureNotify and MotionNotify.
Alexandre Julliard
julliard at winehq.org
Tue Mar 11 10:51:48 CDT 2008
Module: wine
Branch: master
Commit: 0118e0d0f10fb61abcfeb5100b206b94594d4493
URL: http://source.winehq.org/git/wine.git/?a=commit;h=0118e0d0f10fb61abcfeb5100b206b94594d4493
Author: Alexandre Julliard <julliard at winehq.org>
Date: Tue Mar 11 12:11:35 2008 +0100
winex11: Add support for merging redundant events, and use it for ConfigureNotify and MotionNotify.
---
dlls/winex11.drv/event.c | 100 ++++++++++++++++++++++++++++++++++++++--------
1 files changed, 83 insertions(+), 17 deletions(-)
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c
index cdd0853..c531410 100644
--- a/dlls/winex11.drv/event.c
+++ b/dlls/winex11.drv/event.c
@@ -241,39 +241,105 @@ static Bool filter_event( Display *display, XEvent *event, char *arg )
}
+enum event_merge_action
+{
+ MERGE_DISCARD, /* discard the old event */
+ MERGE_HANDLE, /* handle the old event */
+ MERGE_KEEP /* keep the old event for future merging */
+};
+
+/***********************************************************************
+ * merge_events
+ *
+ * Try to merge 2 consecutive events.
+ */
+static enum event_merge_action merge_events( XEvent *prev, XEvent *next )
+{
+ if (prev->xany.window != next->xany.window) return MERGE_HANDLE;
+ switch (prev->type)
+ {
+ case ConfigureNotify:
+ if (prev->xany.window != next->xany.window) break;
+ switch (next->type)
+ {
+ case ConfigureNotify:
+ TRACE( "discarding duplicate ConfigureNotify for window %lx\n", prev->xany.window );
+ return MERGE_DISCARD;
+ case Expose:
+ case PropertyNotify:
+ return MERGE_KEEP;
+ }
+ break;
+ case MotionNotify:
+ if (next->type == MotionNotify)
+ {
+ TRACE( "discarding duplicate MotionNotify for window %lx\n", prev->xany.window );
+ return MERGE_DISCARD;
+ }
+ break;
+ }
+ return MERGE_HANDLE;
+}
+
+
+/***********************************************************************
+ * call_event_handler
+ */
+static inline void call_event_handler( Display *display, XEvent *event )
+{
+ HWND hwnd;
+ x11drv_event_handler handler;
+
+ if (!(handler = find_handler( event->type )))
+ {
+ TRACE( "%s for win %lx, ignoring\n", dbgstr_event( event->type ), event->xany.window );
+ return; /* no handler, ignore it */
+ }
+
+ if (XFindContext( display, event->xany.window, winContext, (char **)&hwnd ) != 0)
+ hwnd = 0; /* not for a registered window */
+ if (!hwnd && event->xany.window == root_window) hwnd = GetDesktopWindow();
+
+ TRACE( "%s for hwnd/window %p/%lx\n",
+ dbgstr_event( event->type ), hwnd, event->xany.window );
+ wine_tsx11_unlock();
+ handler( hwnd, event );
+ wine_tsx11_lock();
+}
+
+
/***********************************************************************
* process_events
*/
static int process_events( Display *display, Bool (*filter)(), ULONG_PTR arg )
{
- XEvent event;
- HWND hwnd;
+ XEvent event, prev_event;
int count = 0;
- x11drv_event_handler handler;
+ enum event_merge_action action = MERGE_DISCARD;
+ prev_event.type = 0;
wine_tsx11_lock();
while (XCheckIfEvent( display, &event, filter, (char *)arg ))
{
count++;
if (XFilterEvent( &event, None )) continue; /* filtered, ignore it */
-
- if (!(handler = find_handler( event.type )))
+ if (prev_event.type) action = merge_events( &prev_event, &event );
+ switch( action )
{
- TRACE( "%s for win %lx, ignoring\n", dbgstr_event( event.type ), event.xany.window );
- continue; /* no handler, ignore it */
+ case MERGE_DISCARD: /* discard prev, keep new */
+ prev_event = event;
+ break;
+ case MERGE_HANDLE: /* handle prev, keep new */
+ call_event_handler( display, &prev_event );
+ prev_event = event;
+ break;
+ case MERGE_KEEP: /* handle new, keep prev for future merging */
+ call_event_handler( display, &event );
+ break;
}
-
- if (XFindContext( display, event.xany.window, winContext, (char **)&hwnd ) != 0)
- hwnd = 0; /* not for a registered window */
- if (!hwnd && event.xany.window == root_window) hwnd = GetDesktopWindow();
-
- wine_tsx11_unlock();
- TRACE( "%s for hwnd/window %p/%lx\n",
- dbgstr_event( event.type ), hwnd, event.xany.window );
- handler( hwnd, &event );
- wine_tsx11_lock();
}
XFlush( gdi_display );
+ if (prev_event.type) call_event_handler( display, &prev_event );
wine_tsx11_unlock();
if (count) TRACE( "processed %d events\n", count );
return count;
More information about the wine-cvs
mailing list