diff options
author | Michael Natterer <mitch@gimp.org> | 2009-09-17 11:38:14 +0200 |
---|---|---|
committer | Michael Natterer <mitch@gimp.org> | 2009-09-17 11:38:14 +0200 |
commit | 659776ce35b4894c5217325978aa48a79689d669 (patch) | |
tree | 48f0271ce16133d26f3024b1d63cd6130ea06412 /gdk | |
parent | 8251d6da8a17ae3cc8ec668b4722b05a92a5c2e2 (diff) | |
download | gtk+-659776ce35b4894c5217325978aa48a79689d669.tar.gz |
Fix gdk_device_get_history() for the core pointer
When filtering out the events for "window" from the events we got for
our "impl_window", don't forget to adjust the returned number of
events because it might be smaller than what XGetMotionEvents has
returned, and free coords we allocated too much. Also if we filtered
away *all* events, return FALSE and get rid of the allocated history
entirely. Together fixes all sorts of mishehavior when painting in
GIMP, from coords going wild to plain crashes and infinite loops.
Diffstat (limited to 'gdk')
-rw-r--r-- | gdk/x11/gdkinput.c | 28 |
1 files changed, 23 insertions, 5 deletions
diff --git a/gdk/x11/gdkinput.c b/gdk/x11/gdkinput.c index c33f09c9e4..6c3cdbb0ea 100644 --- a/gdk/x11/gdkinput.c +++ b/gdk/x11/gdkinput.c @@ -266,7 +266,6 @@ gdk_device_get_history (GdkDevice *device, GdkWindow *impl_window; gboolean result = FALSE; int tmp_n_events = 0; - int i, j; g_return_val_if_fail (GDK_WINDOW_IS_X11 (window), FALSE); @@ -284,9 +283,12 @@ gdk_device_get_history (GdkDevice *device, if (xcoords) { GdkWindowObject *priv = (GdkWindowObject *)window; + int i, j; + coords = _gdk_device_allocate_history (device, tmp_n_events); j = 0; - for (i=0; i<tmp_n_events; i++) + + for (i = 0; i < tmp_n_events; i++) { if (impl_coord_in_window (window, xcoords[i].x, xcoords[i].y)) { @@ -299,16 +301,32 @@ gdk_device_get_history (GdkDevice *device, XFree (xcoords); - result = TRUE; + /* free the events we allocated too much */ + for (i = j; i < tmp_n_events; i++) + { + g_free (coords[i]); + coords[i] = NULL; + } + + tmp_n_events = j; + + if (tmp_n_events > 0) + { + result = TRUE; + } + else + { + gdk_device_free_history (coords, tmp_n_events); + coords = NULL; + } } - else - result = FALSE; } else result = _gdk_device_get_history (device, window, start, stop, &coords, &tmp_n_events); if (n_events) *n_events = tmp_n_events; + if (events) *events = coords; else if (coords) |